diff options
author | Jelle Zijlstra <jelle.zijlstra@gmail.com> | 2023-06-14 12:35:06 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-14 12:35:06 (GMT) |
commit | fc8037d84c5f886849a05ec993dd0f79a356d372 (patch) | |
tree | 7bc4cd546bc2c4e2c345f20247cd16eb27fbdcdc /Lib/typing.py | |
parent | ba516e70c6d156dc59dede35b6fc3db0151780a5 (diff) | |
download | cpython-fc8037d84c5f886849a05ec993dd0f79a356d372.zip cpython-fc8037d84c5f886849a05ec993dd0f79a356d372.tar.gz cpython-fc8037d84c5f886849a05ec993dd0f79a356d372.tar.bz2 |
gh-104873: Add typing.get_protocol_members and typing.is_protocol (#104878)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Diffstat (limited to 'Lib/typing.py')
-rw-r--r-- | Lib/typing.py | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/Lib/typing.py b/Lib/typing.py index a531e7d..4e6dc44 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -131,7 +131,9 @@ __all__ = [ 'get_args', 'get_origin', 'get_overloads', + 'get_protocol_members', 'get_type_hints', + 'is_protocol', 'is_typeddict', 'LiteralString', 'Never', @@ -3337,3 +3339,43 @@ def override[F: _Func](method: F, /) -> F: # read-only property, TypeError if it's a builtin class. pass return method + + +def is_protocol(tp: type, /) -> bool: + """Return True if the given type is a Protocol. + + Example:: + + >>> from typing import Protocol, is_protocol + >>> class P(Protocol): + ... def a(self) -> str: ... + ... b: int + >>> is_protocol(P) + True + >>> is_protocol(int) + False + """ + return ( + isinstance(tp, type) + and getattr(tp, '_is_protocol', False) + and tp != Protocol + ) + + +def get_protocol_members(tp: type, /) -> frozenset[str]: + """Return the set of members defined in a Protocol. + + Example:: + + >>> from typing import Protocol, get_protocol_members + >>> class P(Protocol): + ... def a(self) -> str: ... + ... b: int + >>> get_protocol_members(P) + frozenset({'a', 'b'}) + + Raise a TypeError for arguments that are not Protocols. + """ + if not is_protocol(tp): + raise TypeError(f'{tp!r} is not a Protocol') + return frozenset(tp.__protocol_attrs__) |