summaryrefslogtreecommitdiffstats
path: root/Lib/typing.py
diff options
context:
space:
mode:
authorJelle Zijlstra <jelle.zijlstra@gmail.com>2023-06-14 12:35:06 (GMT)
committerGitHub <noreply@github.com>2023-06-14 12:35:06 (GMT)
commitfc8037d84c5f886849a05ec993dd0f79a356d372 (patch)
tree7bc4cd546bc2c4e2c345f20247cd16eb27fbdcdc /Lib/typing.py
parentba516e70c6d156dc59dede35b6fc3db0151780a5 (diff)
downloadcpython-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.py42
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__)