I've been wondering whether it would make sense to have a function in `inspect`
that returns the signature of a type, rather than the signature of a specific
callable object.
I'm not attached to any name for such a function, two ideas are
`inspect.signature_of` or `inspect.signature_of_type`.
## Context: the behavior of `inspect.signature`
The existing `inspect.signature` function specified in PEP 362 [0] returns the
call signature of a particular object, in other words given
```
class Dog:
def __init__(self, color: str):
self.color = color
def __call__(self, command: str):
print(command)
```
we will get
```
>>> import inspect
>>> inspect.signature(Dog)
<Signature (color: str)>
>>> inspect.signature(Dog("brown"))
<Signature (command: str)>
```
## Outline of the idea
In some cases it might be nice to be able to access the signature of an
instance of `Dog` given the type `Dog`, without actually needing to instantiate
it.
Moreover, there are some cases where it isn't even possible to get a callable
object, but it still might be nice to have access to an `inspect.Signature`
object:
- protocols cannot be instantiated. This is particularly relevant to getting
Signatures because of callback protocols [1]
- typing.Callable types describe a signature, but again can't be instantiated
If if we had a function to operate on types, it would treat normal classes as
if calling `inspect.signature` on the `__call__` method of an instance.
For callable types we'd want to do something similar, although this brings up
some issues:
- the existing Signature requires parameter names, but a `typing.Callable`
doesn't have any.
- One option would be to invent names `__0`, `__1,` etc. Otherwise we'd have
to make the name optional.
- it's not obvious how to support PEP 612 ParamSpecs, and even less obvious how
to support PEP 646 in full generality
I have some code snippets running through how simple cases might work, as well
as the edge cases I've thought of thus far:
https://gist.github.com/stroxler/4760cbc5e49df2295cd0b524328b1c73
I'm undecided about whether the edge cases are an indication that this idea
isn't worth considering.
It's worth noting that most of the edge cases involve PEP 612 / 646 generics
which are pretty rare.
## Why did I start thinking about this?
In discussions of PEP 677 [2], a few folks suggested using `inspect.Signature`
as inspiration for the runtime API (which we did).
This got me thinking that it might be nice for code that uses runtime types,
regardless of what we decide about PEP 677, to have an API that makes accessing
signature information from a type easier.
I don't personally have much need for this, but
- when I chatted with Carl Meyer from the static python team at Meta he thought
it could be handy
- I could imagine it being useful for tools like ML frameworks, which I've
worked on in the past, that interpret type annotations to auto-generate logic
--
[0] PEP 362 Function Signatures https://www.python.org/dev/peps/pep-0362/
[1] Callback protocols
https://mypy.readthedocs.io/en/stable/protocols.html#callback-protocols
[2] PEP 677 Callable Type Syntax https://www.python.org/dev/peps/pep-0677/
_______________________________________________
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/47NLKQZYYQL6LKA7BQWGFT4UZJOIAR4M/
Code of Conduct: http://python.org/psf/codeofconduct/