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
__future__.annotations breaks inspect.signature() #87521
Comments
We have a pytest that boils down to the following:
(execute with I tried importing 3.10 annotations (so that we can get rid of quotes around the class containing The above passes on 3.7.9, 3.8.7 & 3.9.1, and if I uncomment the first line, it fails on those same versions. I expect |
Can you show the values of “expected” and “actual” for both the failures and successes? |
Sure thing. Putting the reproducing code in
|
@eric.smith, here's a summarized version. I hope it helps: def foo(x: str) -> str: ... In Python 3.7 - 3.9 with from __future__ import annotations, inspect.signature sees foo's parameter as: <Parameter "x: 'str'"> Without the future import (and also in Python 3.10): <Parameter "x: str"> The reason for the difference in 3.10 (IIRC) is that inspect.signature auto converts all strings to typing.ForwardRef internally and then resolves them. This is a result of PEP-563 becoming default (also mentioned here https://docs.python.org/3.10/whatsnew/3.10.html#pep-563-postponed-evaluation-of-annotations-becomes-default ) Prior to 3.10, the future import treats function annotations as strings and inspect.signature _doesn't_ convert them. I don't know of this is a bug or intentional. Especially considering what PEP-563 has to say: https://www.python.org/dev/peps/pep-0563/#resolving-type-hints-at-runtime @1ace, a possible workaround if you want full compatibility regardless of the future import is to use typing.get_type_hints: (The result doesn't change even with from __future__ import annotations. This also works from 3.7-3.10)
>>> from typing import get_type_hints
>>> get_type_hints(foo)
{'x': <class 'str'>, 'return': <class 'str'>} |
Sorry, I just realized you asked for the "success" value as well. For python 3.7-3.9 without the |
(... and I had the window open for too long and didn't notice Ken's reply before mine ^^') @kj: thanks for the workaround! it's good to be able to change our code and not have to depend on a yet-to-be-released patch on each python version :) That said, typing.get_type_hints() only returns the type hint, whereas our current test checks for other things (like the default value) which need to match (I think) for cython's use of |
I think this is all about: should inspect.signature() resolve string annotations into actual types (via get_type_hints, or whatever)? I don't use inspect much, so I can't offer an opinion there. |
3.7 only gets security fixes |
Python 3.10 will add an eval_str= argument to inspect.signature() that lets you evaluate string annotations. I don't think it makes sense to change anything in the bugfix branches, so I propose that this issue be closed. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: