@@ -1805,28 +1805,31 @@ def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:
1805
1805
1806
1806
@_tp_cache
1807
1807
def __class_getitem__ (cls , params ):
1808
+ """Parameterizes a generic class.
1809
+
1810
+ At least, parameterizing a generic class is the *main* thing this method
1811
+ does. For example, for some generic class `Foo`, this is called when we
1812
+ do `Foo[int]` - there, with `cls=Foo` and `params=int`.
1813
+
1814
+ However, note that this method is also called when defining generic
1815
+ classes in the first place with `class Foo(Generic[T]): ...`.
1816
+ """
1808
1817
if not isinstance (params , tuple ):
1809
1818
params = (params ,)
1810
1819
1811
- try :
1812
- num_class_params = len (cls .__parameters__ )
1813
- except AttributeError :
1814
- only_class_parameter_is_typevartuple = False
1815
- else :
1816
- if (
1817
- num_class_params == 1
1818
- and isinstance (cls .__parameters__ [0 ], TypeVarTuple )
1819
- ):
1820
- only_class_parameter_is_typevartuple = True
1821
- else :
1822
- only_class_parameter_is_typevartuple = False
1823
-
1824
- if (
1825
- not params
1826
- and not (cls is Tuple or only_class_parameter_is_typevartuple )
1827
- ):
1828
- raise TypeError (
1829
- f"Parameter list to { cls .__qualname__ } [...] cannot be empty" )
1820
+ if not params :
1821
+ # We're only ok with `params` being empty if the class's only type
1822
+ # parameter is a `TypeVarTuple` (which can contain zero types).
1823
+ class_params = getattr (cls , "__parameters__" , None )
1824
+ only_class_parameter_is_typevartuple = (
1825
+ class_params is not None
1826
+ and len (class_params ) == 1
1827
+ and isinstance (class_params [0 ], TypeVarTuple )
1828
+ )
1829
+ if not only_class_parameter_is_typevartuple :
1830
+ raise TypeError (
1831
+ f"Parameter list to { cls .__qualname__ } [...] cannot be empty"
1832
+ )
1830
1833
1831
1834
params = tuple (_type_convert (p ) for p in params )
1832
1835
if cls in (Generic , Protocol ):
0 commit comments