Repository navigation
Raise ValueError for unresolvable annotations in get_types #1806
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1617,11 +1617,15 @@ def get_types(func_or_method: Callable[..., Any]) -> tuple[dict[str, Any], Any]: | |
| :return: tuple with first element being dictionary mapping param names to type hints | ||
| and second element being the return type hint or None if there is no return value type hint | ||
| :raises ValueError: if the `func_or_method` argument is not a valid object to pass to `inspect.get_annotations` | ||
| or if its annotations cannot be resolved | ||
| """ | ||
| try: | ||
| type_hints = inspect.get_annotations(func_or_method, eval_str=True) # Get dictionary of type hints | ||
| except TypeError as exc: | ||
| raise ValueError("Argument passed to get_types should be a function or method") from exc | ||
| except (NameError, SyntaxError) as exc: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Action: add |
||
| name = getattr(func_or_method, "__name__", func_or_method) | ||
| raise ValueError(f"Unable to resolve type hints for {name}: {exc}") from exc | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider raising Action: raise |
||
| ret_ann = type_hints.pop("return", None) # Pop off the return annotation if it exists | ||
| if inspect.ismethod(func_or_method): | ||
| type_hints.pop("self", None) # Pop off `self` hint for methods | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1864,6 +1864,14 @@ def foo(x: int) -> str: | |
| assert param_value is int | ||
|
|
||
|
|
||
| def test_get_types_unresolvable_forward_reference() -> None: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only the Action: add cases (parametrizing this test would work well) for:
Please also add one test that registers a hook with an unresolvable annotation (e.g. via |
||
| def foo(x: "NotDefinedAnywhere") -> None: # noqa: F821 | ||
| print(x) | ||
|
|
||
| with pytest.raises(ValueError, match="Unable to resolve type hints"): | ||
| cu.get_types(foo) | ||
|
|
||
|
|
||
| def test_get_types_method() -> None: | ||
| class Foo: | ||
| def bar(self, x: bool) -> None: | ||
|
|
||
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.
This existing handler also swallows a
TypeErrorraised while evaluating an annotation. For example,def b(x: "int[str]")reports "Argument passed to get_types should be a function or method", which is wrong.Action: distinguish the two cases, e.g. check
callable(func_or_method)up front for the invalid-argument error, then treat anyTypeErrorfromget_annotationsas a resolution failure.