> On 12 Oct 2021, at 00:09, Erik Demaine <[email protected]> wrote: > > Another possibility would be that functions can't be used as their types > directly, but need a casting operator like so: > > ``` > def add_converter(self, converter: typeof(data_to_table)) -> None: > self.converter = converter > ```
`type()` of any function is `types.FunctionType`. We also have
`typing.Type[Class]` which fortunately since 3.9 we can spell simply as
`type[Class]`, to annotate that we want the class itself, not an object of said
class.
I'm -1 to the idea of introducing a separate `typeof()`. The name is much too
familiar to the first two to avoid confusion.
Consider that a function is equivalent to an instance of a class with a
`__call__()` method of the same signature:
```
def data_to_table(d: Iterable[Mapping[str, float]], *, sort: bool = False,
reversed: bool = False) -> Table:
...
```
is equivalent to an object of type
```
class Converter:
def __call__(self, d: Iterable[Mapping[str, float]], *, sort: bool = False,
reversed: bool = False) -> Table:
...
```
In fact, Mypy already understands this equivalence: if you declare the
`Converter` class I'm showing above as a Protocol, you can successfully pass
`data_to_table` where a `Converter` instance is expected. Full example here:
https://gist.github.com/ambv/b46d0547decf2cb0cfdf379bb5f07d50
<https://gist.github.com/ambv/b46d0547decf2cb0cfdf379bb5f07d50>
My proposal is to enable using a function directly in a type annotation as a
shorthand for expressing such a Protocol. In other words to mean "any callable
with an equivalent signature". So that this:
```
class Stream:
def call_converter(self, converter: Converter) -> None:
converter(self.dicts, sort=True, reversed=True)
```
would be equivalent to this:
```
class Stream:
def call_converter(self, converter: data_to_table) -> None:
converter(self.dicts, sort=True, reversed=True)
```
I agree that in principle there would be some additional purity in having to
wrap the function annotation in some explicit type marker, like
`callable[data_to_table]` (yes, that would be my suggestion instead of `typeof`
since that would be specific to callables). However, in practice I think this
is unnecessary boilerplate because there is no useful meaning to a
`data_to_table` annotation different from `callable[data_to_table]`. So I'd
skip the boilerplate. After all, the thread is about introducing a
quality-of-life notation improvement.
- Ł
signature.asc
Description: Message signed with OpenPGP
_______________________________________________ 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/7DEAGCWI7VIN52WLMSBCDC4SFUYPW6GW/ Code of Conduct: http://python.org/psf/codeofconduct/
