128
128
'no_type_check_decorator' ,
129
129
]
130
130
131
- _OLD_PYPY_VERSION = sys .implementation .name == "pypy" and sys .version_info < (3 , 9 )
132
-
133
131
# for backward compatibility
134
132
PEP_560 = True
135
133
GenericMeta = type
@@ -955,6 +953,21 @@ def __round__(self, ndigits: int = 0) -> T_co:
955
953
pass
956
954
957
955
956
+ def _ensure_subclassable (mro_entries ):
957
+ def inner (func ):
958
+ if sys .implementation .name == "pypy" and sys .version_info < (3 , 9 ):
959
+ cls_dict = {
960
+ "__call__" : staticmethod (func ),
961
+ "__mro_entries__" : staticmethod (mro_entries )
962
+ }
963
+ t = type (func .__name__ , (), cls_dict )
964
+ return functools .update_wrapper (t (), func )
965
+ else :
966
+ func .__mro_entries__ = mro_entries
967
+ return func
968
+ return inner
969
+
970
+
958
971
if sys .version_info >= (3 , 13 ):
959
972
# The standard library TypedDict in Python 3.8 does not store runtime information
960
973
# about which (if any) keys are optional. See https://bugs.python.org/issue38834
@@ -1061,6 +1074,9 @@ def __subclasscheck__(cls, other):
1061
1074
1062
1075
__instancecheck__ = __subclasscheck__
1063
1076
1077
+ _TypedDict = type .__new__ (_TypedDictMeta , 'TypedDict' , (), {})
1078
+
1079
+ @_ensure_subclassable (lambda bases : (_TypedDict ,))
1064
1080
def TypedDict (__typename , __fields = _marker , * , total = True , ** kwargs ):
1065
1081
"""A simple typed namespace. At runtime it is equivalent to a plain dict.
1066
1082
@@ -1144,20 +1160,6 @@ class Point2D(TypedDict):
1144
1160
td .__orig_bases__ = (TypedDict ,)
1145
1161
return td
1146
1162
1147
- _TypedDict = type .__new__ (_TypedDictMeta , 'TypedDict' , (), {})
1148
-
1149
- if _OLD_PYPY_VERSION :
1150
- class _TypedDictType :
1151
- __call__ = staticmethod (TypedDict )
1152
-
1153
- def __mro_entries__ (self , bases ):
1154
- return (_TypedDict ,)
1155
-
1156
- TypedDict = _TypedDictType ()
1157
- functools .update_wrapper (TypedDict , TypedDict .__call__ )
1158
- else :
1159
- TypedDict .__mro_entries__ = lambda bases : (_TypedDict ,)
1160
-
1161
1163
if hasattr (typing , "_TypedDictMeta" ):
1162
1164
_TYPEDDICT_TYPES = (typing ._TypedDictMeta , _TypedDictMeta )
1163
1165
else :
@@ -2646,6 +2648,13 @@ def __new__(cls, typename, bases, ns):
2646
2648
nm_tpl .__init_subclass__ ()
2647
2649
return nm_tpl
2648
2650
2651
+ _NamedTuple = type .__new__ (_NamedTupleMeta , 'NamedTuple' , (), {})
2652
+
2653
+ def _namedtuple_mro_entries (bases ):
2654
+ assert NamedTuple in bases
2655
+ return (_NamedTuple ,)
2656
+
2657
+ @_ensure_subclassable (_namedtuple_mro_entries )
2649
2658
def NamedTuple (__typename , __fields = _marker , ** kwargs ):
2650
2659
"""Typed version of namedtuple.
2651
2660
@@ -2711,27 +2720,15 @@ class Employee(NamedTuple):
2711
2720
nt .__orig_bases__ = (NamedTuple ,)
2712
2721
return nt
2713
2722
2714
- _NamedTuple = type .__new__ (_NamedTupleMeta , 'NamedTuple' , (), {})
2715
-
2716
2723
# On 3.8+, alter the signature so that it matches typing.NamedTuple.
2717
2724
# The signature of typing.NamedTuple on >=3.8 is invalid syntax in Python 3.7,
2718
2725
# so just leave the signature as it is on 3.7.
2719
2726
if sys .version_info >= (3 , 8 ):
2720
- NamedTuple .__text_signature__ = '(typename, fields=None, /, **kwargs)'
2721
-
2722
- def _namedtuple_mro_entries (bases ):
2723
- assert NamedTuple in bases
2724
- return (_NamedTuple ,)
2725
-
2726
- if _OLD_PYPY_VERSION :
2727
- class _NamedTupleType :
2728
- __call__ = staticmethod (NamedTuple )
2729
- __mro_entries__ = staticmethod (_namedtuple_mro_entries )
2730
-
2731
- NamedTuple = _NamedTupleType ()
2732
- functools .update_wrapper (NamedTuple , NamedTuple .__call__ )
2733
- else :
2734
- NamedTuple .__mro_entries__ = _namedtuple_mro_entries
2727
+ new_signature = '(typename, fields=None, /, **kwargs)'
2728
+ if isinstance (NamedTuple , _types .FunctionType ):
2729
+ NamedTuple .__text_signature__ = new_signature
2730
+ else :
2731
+ NamedTuple .__call__ .__text_signature__ = new_signature
2735
2732
2736
2733
2737
2734
if hasattr (collections .abc , "Buffer" ):
0 commit comments