classification
Title: Combining typing.get_type_hints and inspect.signature
Type: enhancement Stage:
Components: Versions: Python 3.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Jelle Zijlstra, dmontague, eric.snow, levkivskyi, yselivanov
Priority: normal Keywords:

Created on 2019-08-23 05:44 by dmontague, last changed 2021-05-03 01:04 by larry.

Messages (4)
msg350248 - (view) Author: (dmontague) Date: 2019-08-23 05:44
I am trying to obtain the output of `inspect.signature`, except with string-valued annotations converted to resolved type hints, similarly to `typing.get_type_hints`.

Is there a good way to do this currently? If not, might this be a good fit for the standard library?

---------------

The straightforward way I see to attempt this would be to call both `typing.get_type_hints` and `inspect.signature` on the callable, and then "merge" the results. However, as far as I can tell, that only works if the provided callable is a function or method (i.e., not a type or a callable class instance).

As an example, if I have an instance of a class with a `__call__` method, and the class was defined in a module with `from __future__ import annotations`, then calling `inspect.signature` on the instances will only return an `inspect.Signature` with type-unaware strings as the annotations for each `inspect.Parameter`. On the other hand, calling `get_type_hints` on the instance will return type hints for the class, rather than for its `__call__` method.

I wouldn't mind manually handling an edge case or two, but the logic used by `inspect.signature` to determine which function will be called seems relatively involved, and so I would ideally like to leverage this same logic while obtaining the type-resolved version signature for the callable.
msg350271 - (view) Author: Ivan Levkivskyi (levkivskyi) * (Python committer) Date: 2019-08-23 10:19
Somewhat related to https://bugs.python.org/issue37496
msg392725 - (view) Author: Jelle Zijlstra (Jelle Zijlstra) * (Python triager) Date: 2021-05-02 20:32
As of Python 3.10, thanks to Larry Hastings inspect.signature will have a new eval_str= parameter that lets you evaluate string annotations. This isn't quite what you're asking for, though, because typing.get_type_hints does more work than eval_str does. Still, it's similar enough that I'm inclined to close this issue.
msg392754 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2021-05-03 01:04
"Type hints" and "annotations" aren't the same thing.  And type hints are more opinionated about the values of annotations than would be appropriate for the inspect module.  For example, typing.get_type_hints() wraps strings with ForwardRef, turns None into NoneType, and it ignores objects with a "__no_type_check__" attribute.

So, I think it might be okay to *add* a *new* function to the typing module that was equivalent to inspect.signature() (and typing.signature() seems like a good name here).  I don't use type hints, so I don't have a strong opinion on that either way.  But you definitely shouldn't modify inspect.signature() so it produces type hints.
History
Date User Action Args
2021-05-03 01:04:40larrysetnosy: - larry
2021-05-03 01:04:25larrysetnosy: larry, eric.snow, yselivanov, levkivskyi, Jelle Zijlstra, dmontague
messages: + msg392754
2021-05-02 20:32:56Jelle Zijlstrasetnosy: + larry, Jelle Zijlstra
messages: + msg392725
2019-08-23 10:19:28levkivskyisetnosy: + eric.snow, yselivanov
messages: + msg350271
2019-08-23 05:44:01dmontaguecreate