Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.4k
gh-104050: Add more type hints to Argument Clinic DSLParser()#106354
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
gh-104050: Add more type hints to Argument Clinic DSLParser()#106354
Uh oh!
There was an error while loading.Please reload this page.
Conversation
Add basic annotations to state_modulename_name()
erlend-aasland commentedJul 3, 2023 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
My basal typing skills are no longer sufficient; I need help! 😱 cc.@AlexWaygood Tools/clinic/clinic.py:4593: error: Incompatible types in assignment (expression has type "str | None", variable has type "str") [assignment]Tools/clinic/clinic.py:4617: error: Keywords must be strings [misc]Tools/clinic/clinic.py:4645: error: Incompatible types in assignment (expression has type "Function", variable has type "None") [assignment]Tools/clinic/clinic.py:4646: error: Argument "return_converter" to "Function" has incompatible type "CReturnConverter"; expected "Callable[..., CReturnConverter]" [arg-type]Tools/clinic/clinic.py:4654: error: "None" has no attribute "self_converter" [attr-defined]Tools/clinic/clinic.py:4654: error: Keywords must be strings [misc]Tools/clinic/clinic.py:4655: error: Argument 1 to "Parameter" has incompatible type "str | None"; expected "str" [arg-type]Tools/clinic/clinic.py:4655: error: Argument 2 to "Parameter" has incompatible type "Literal[_ParameterKind.POSITIONAL_ONLY]"; expected "str" [arg-type]Tools/clinic/clinic.py:4655: error: Argument "function" to "Parameter" has incompatible type "None"; expected "Function" [arg-type]Tools/clinic/clinic.py:4656: error: "None" has no attribute "parameters" [attr-defined]Tools/clinic/clinic.py:4659: error: Argument 1 to "next" of "DSLParser" has incompatible type "Callable[[str], None]"; expected "Callable[[str | None], None]" [arg-type]Found 11 errors in 1 file (checked 2 source files) These ghosts are now haunting me: cpython/Tools/clinic/clinic.py Line 4314 ind65b783
I'm tempted to use a cpython/Tools/clinic/clinic.py Lines 4591 to 4593 ind65b783
Unless there's a more typing idiomatic way, I'm inclined to simply do something like this: diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.pyindex b0e5142efa..c730688fbf 100755--- a/Tools/clinic/clinic.py+++ b/Tools/clinic/clinic.py@@ -4588,9 +4588,9 @@ def state_modulename_name(self, line: str | None) -> None: line, _, returns = line.partition('->')- full_name, _, c_basename = line.partition(' as ')- full_name = full_name.strip()- c_basename = c_basename.strip() or None+ left, _, right = line.partition(' as ')+ full_name = left.strip()+ c_basename = right.strip() or None if not is_legal_py_identifier(full_name): fail("Illegal function name:", full_name) |
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
This error is because the code does something equivalent to this: condition:boolifcondition:foo="foo"else:foo=None Iff you don't have a type annotation for a variable, then a type checker will by default infer the most specific type possible for an assignment. That means that in the first branch, mypy infers that the type of The solution is to give an explicit type annotation before the variable has been assigned in either branch, to force mypy to infer a broader type in both branches instead of inferring the most specific type possible: condition:boolfoo:str|Noneifcondition:foo="foo"else:foo=None |
I think mypy is flagging a real bug in the code here. The issue is this block of code here: cpython/Tools/clinic/clinic.py Lines 5033 to 5039 ind694f04
The function is annotated as return cpython/Tools/clinic/clinic.py Line 4617 ind694f04
The code as written, however, doesn't guarantee that all the keys in the |
AlexWaygood commentedJul 3, 2023 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Here's two possible ways of fixing this latent bug: (1) --- a/Tools/clinic/clinic.py+++ b/Tools/clinic/clinic.py@@ -5048,6 +5048,7 @@ def parse_converter(annotation: ast.expr | None) -> tuple[str, bool, KwargDict]: kwargs = { node.arg: eval_ast_expr(node.value, symbols) for node in annotation.keywords+ if isinstance(node.arg, str) } return name, False, kwargs case _: (2) --- a/Tools/clinic/clinic.py+++ b/Tools/clinic/clinic.py@@ -5045,10 +5045,11 @@ def parse_converter(annotation: ast.expr | None) -> tuple[str, bool, KwargDict]: return name, False, {} case ast.Call(func=ast.Name(name)): symbols = globals()- kwargs = {- node.arg: eval_ast_expr(node.value, symbols)- for node in annotation.keywords- }+ kwargs: dict[str, Any] = {}+ for node in annotation.keywords:+ if not isinstance(node.arg, str):+ raise TypeError("Unexpectedly found a keyword node with a non-str arg!")+ kwargs[node.arg] = eval_ast_expr(node.value, symbols) return name, False, kwargs case _: fail( You tell me which would be more correct here (or if another solution would be better than either of these)! |
It looks to me like the annotation for the --- a/Tools/clinic/clinic.py+++ b/Tools/clinic/clinic.py@@ -2448,7 +2448,7 @@ def __init__( cls: Class | None = None, c_basename: str | None = None, full_name: str | None = None,- return_converter: ReturnConverterType,+ return_converter: "CReturnConverter", return_annotation = inspect.Signature.empty, docstring: str | None = None, kind: str = CALLABLE, |
erlend-aasland commentedJul 3, 2023 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Good sleuthing! Let's fix bugs separately from adding annotations. I'll create an issue. EDIT: Createdgh-106359 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Looks good, just two questions
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
LGTM!
* main: (167 commits)pythongh-91053: make func watcher tests resilient to other func watchers (python#106286)pythongh-104050: Add more type hints to Argument Clinic DSLParser() (python#106354)pythongh-106359: Fix corner case bugs in Argument Clinic converter parser (python#106361)pythongh-104146: Remove unused attr 'parameter_indent' from clinic.DLParser (python#106358)pythongh-106320: Remove private _PyErr C API functions (python#106356)pythongh-104050: Annotate Argument Clinic DSLParser attributes (python#106357)pythongh-106320: Create pycore_modsupport.h header file (python#106355)pythongh-106320: Move _PyUnicodeWriter to the internal C API (python#106342)pythongh-61215: New mock to wait for multi-threaded events to happen (python#16094) Document PYTHONSAFEPATH along side -P (python#106122) Replace the esoteric term 'datum' when describing dict comprehensions (python#106119)pythongh-104050: Add more type hints to Argument Clinic DSLParser() (python#106343)pythongh-106320: _testcapi avoids private _PyUnicode_EqualToASCIIString() (python#106341)pythongh-106320: Add pycore_complexobject.h header file (python#106339)pythongh-106078: Move DecimalException to _decimal state (python#106301)pythongh-106320: Use _PyInterpreterState_GET() (python#106336)pythongh-106320: Remove private _PyInterpreterState functions (python#106335)pythongh-104922: Doc: add note about PY_SSIZE_T_CLEAN (python#106314)pythongh-106217: Truncate the issue body size of `new-bugs-announce-notifier` (python#106329)pythongh-104922: remove PY_SSIZE_T_CLEAN (python#106315) ...
Uh oh!
There was an error while loading.Please reload this page.
Add basic annotations to state_modulename_name()