Proposed new introspection helpers: typing.get_protocol_members and typing.is_protocol
I'm proposing to add two new introspection helpers to typing for Python 3.13 and to the next release of typing-extensions: - typing.get_protocol_members(cls) -> frozenset[str], returning the names of all members that the Protocol requires - typing.is_protocol(cls) -> bool, returning whether a class is a Protocol A draft implementation is in https://github.com/python/cpython/pull/104878. get_protocol_members() is useful because there is currently no public way to get all the members of a protocol: you have to iterate over the MRO and find all attributes and annotations, and then exclude a laundry list of internal attributes (e.g., https://github.com/quora/pyanalyze/blob/bd7f520adc2d8b098be657dfa514d1433bea... ). Similarly, figuring out whether a class is a Protocol or not currently requires checking the undocumented private `_is_protocol` field. Adding is_protocol() will remove the need to access this private field. Static type checkers would not be expected to provide special treatment for either of these new functions. I am interested in these because in my pyanalyze tool, which looks at runtime type annotation objects, I currently need to dive into typing internals to get Protocols to work correctly. To make my code more robust, I want to be able to use public typing APIs instead. I would like to hear any feedback on these proposed new APIs from other community members who use types at runtime. Similarly, if there are other areas where runtime type checkers currently feel the need to reach into typing internals, please bring it up so we can try to design an API covering your use case.
Am 05.06.23 um 16:34 schrieb Jelle Zijlstra:
I'm proposing to add two new introspection helpers to typing for Python 3.13 and to the next release of typing-extensions:
- typing.get_protocol_members(cls) -> frozenset[str], returning the names of all members that the Protocol requires - typing.is_protocol(cls) -> bool, returning whether a class is a Protocol
A draft implementation is in https://github.com/python/cpython/pull/104878.
get_protocol_members() is useful because there is currently no public way to get all the members of a protocol: you have to iterate over the MRO and find all attributes and annotations, and then exclude a laundry list of internal attributes (e.g., https://github.com/quora/pyanalyze/blob/bd7f520adc2d8b098be657dfa514d1433bea...).
Similarly, figuring out whether a class is a Protocol or not currently requires checking the undocumented private `_is_protocol` field. Adding is_protocol() will remove the need to access this private field.
Static type checkers would not be expected to provide special treatment for either of these new functions.
I am interested in these because in my pyanalyze tool, which looks at runtime type annotation objects, I currently need to dive into typing internals to get Protocols to work correctly. To make my code more robust, I want to be able to use public typing APIs instead.
I would like to hear any feedback on these proposed new APIs from other community members who use types at runtime. Similarly, if there are other areas where runtime type checkers currently feel the need to reach into typing internals, please bring it up so we can try to design an API covering your use case.
While I haven't had the need to inspect protocols at runtime yet, these functions look quite useful to me. Especially `get_protocol_members()` has the advantage of being future proof. Similarly, if I would need to check whether something is a protocol, I would feel uncomfortable checking an internal symbol like `_is_protocol`. And again this is future proof, as it's possible that there may be other ways to define protocols or protocol-like objects in the future. - Sebastian
participants (2)
-
Jelle Zijlstra
-
Sebastian Rittau