11"""
22Define names for built-in types that aren't directly accessible as a builtin.
33"""
4+
45import sys
56
67# Iterators in Python aren't a matter of type but of protocol. A large
@@ -52,17 +53,14 @@ def _m(self): pass
5253
5354try :
5455 raise TypeError
55- except TypeError :
56- tb = sys .exc_info ()[2 ]
57- TracebackType = type (tb )
58- FrameType = type (tb .tb_frame )
59- tb = None ; del tb
56+ except TypeError as exc :
57+ TracebackType = type (exc .__traceback__ )
58+ FrameType = type (exc .__traceback__ .tb_frame )
6059
61- # For Jython, the following two types are identical
6260GetSetDescriptorType = type (FunctionType .__code__ )
6361MemberDescriptorType = type (FunctionType .__globals__ )
6462
65- del sys , _f , _g , _C , _c , _ag # Not for export
63+ del sys , _f , _g , _C , _c , _ag , _cell_factory # Not for export
6664
6765
6866# Provide a PEP 3115 compliant mechanism for class creation
@@ -82,7 +80,7 @@ def resolve_bases(bases):
8280 updated = False
8381 shift = 0
8482 for i , base in enumerate (bases ):
85- if isinstance (base , type ) and not isinstance ( base , GenericAlias ) :
83+ if isinstance (base , type ):
8684 continue
8785 if not hasattr (base , "__mro_entries__" ):
8886 continue
@@ -146,6 +144,35 @@ def _calculate_meta(meta, bases):
146144 "of the metaclasses of all its bases" )
147145 return winner
148146
147+
148+ def get_original_bases (cls , / ):
149+ """Return the class's "original" bases prior to modification by `__mro_entries__`.
150+
151+ Examples::
152+
153+ from typing import TypeVar, Generic, NamedTuple, TypedDict
154+
155+ T = TypeVar("T")
156+ class Foo(Generic[T]): ...
157+ class Bar(Foo[int], float): ...
158+ class Baz(list[str]): ...
159+ Eggs = NamedTuple("Eggs", [("a", int), ("b", str)])
160+ Spam = TypedDict("Spam", {"a": int, "b": str})
161+
162+ assert get_original_bases(Bar) == (Foo[int], float)
163+ assert get_original_bases(Baz) == (list[str],)
164+ assert get_original_bases(Eggs) == (NamedTuple,)
165+ assert get_original_bases(Spam) == (TypedDict,)
166+ assert get_original_bases(int) == (object,)
167+ """
168+ try :
169+ return cls .__dict__ .get ("__orig_bases__" , cls .__bases__ )
170+ except AttributeError :
171+ raise TypeError (
172+ f"Expected an instance of type, not { type (cls ).__name__ !r} "
173+ ) from None
174+
175+
149176class DynamicClassAttribute :
150177 """Route attribute access on a class to __getattr__.
151178
@@ -158,7 +185,7 @@ class DynamicClassAttribute:
158185 attributes on the class with the same name. (Enum used this between Python
159186 versions 3.4 - 3.9 .)
160187
161- Subclass from this to use a different method of accessing virtual atributes
188+ Subclass from this to use a different method of accessing virtual attributes
162189 and still be treated properly by the inspect module. (Enum uses this since
163190 Python 3.10 .)
164191
@@ -305,4 +332,11 @@ def wrapped(*args, **kwargs):
305332NoneType = type (None )
306333NotImplementedType = type (NotImplemented )
307334
335+ def __getattr__ (name ):
336+ if name == 'CapsuleType' :
337+ import _socket
338+ return type (_socket .CAPI )
339+ raise AttributeError (f"module { __name__ !r} has no attribute { name !r} " )
340+
308341__all__ = [n for n in globals () if n [:1 ] != '_' ]
342+ __all__ += ['CapsuleType' ]
0 commit comments