@@ -2012,34 +2012,71 @@ def test_valid_uses(self):
20122012 P = ParamSpec ('P' )
20132013 T = TypeVar ('T' )
20142014 C1 = typing .Callable [P , int ]
2015+ # Callable in Python 3.5.2 might be bugged when collecting __args__.
2016+ # https://github.com/python/cpython/blob/91185fe0284a04162e0b3425b53be49bdbfad67d/Lib/typing.py#L1026
2017+ PY_3_5_2 = sys .version_info [:3 ] == (3 , 5 , 2 )
2018+ if not PY_3_5_2 :
2019+ self .assertEqual (C1 .__args__ , (P , int ))
2020+ self .assertEqual (C1 .__parameters__ , (P ,))
20152021 C2 = typing .Callable [P , T ]
2022+ if not PY_3_5_2 :
2023+ self .assertEqual (C2 .__args__ , (P , T ))
2024+ self .assertEqual (C2 .__parameters__ , (P , T ))
20162025
2017- # Note: no tests for Callable.__args__ and Callable.__parameters__ here
2018- # because pre-3.10 Callable sees ParamSpec as a plain list, not a
2019- # TypeVar.
20202026
20212027 # Test collections.abc.Callable too.
20222028 if sys .version_info [:2 ] >= (3 , 9 ):
2029+ # Note: no tests for Callable.__parameters__ here
2030+ # because types.GenericAlias Callable is hardcoded to search
2031+ # for tp_name "TypeVar" in C. This was changed in 3.10.
20232032 C3 = collections .abc .Callable [P , int ]
2033+ self .assertEqual (C3 .__args__ , (P , int ))
20242034 C4 = collections .abc .Callable [P , T ]
2035+ self .assertEqual (C4 .__args__ , (P , T ))
20252036
20262037 # ParamSpec instances should also have args and kwargs attributes.
2027- self .assertIn ('args' , dir (P ))
2028- self .assertIn ('kwargs' , dir (P ))
2038+ # Note: not in dir(P) because of __class__ hacks
2039+ self .assertTrue (hasattr (P , 'args' ))
2040+ self .assertTrue (hasattr (P , 'kwargs' ))
20292041
20302042 def test_args_kwargs (self ):
20312043 P = ParamSpec ('P' )
2032- self .assertIn ('args' , dir (P ))
2033- self .assertIn ('kwargs' , dir (P ))
2044+ # Note: not in dir(P) because of __class__ hacks
2045+ self .assertTrue (hasattr (P , 'args' ))
2046+ self .assertTrue (hasattr (P , 'kwargs' ))
20342047 self .assertIsInstance (P .args , ParamSpecArgs )
20352048 self .assertIsInstance (P .kwargs , ParamSpecKwargs )
20362049 self .assertIs (P .args .__origin__ , P )
20372050 self .assertIs (P .kwargs .__origin__ , P )
20382051 self .assertEqual (repr (P .args ), "P.args" )
20392052 self .assertEqual (repr (P .kwargs ), "P.kwargs" )
20402053
2041- # Note: ParamSpec doesn't work for pre-3.10 user-defined Generics due
2042- # to type checks inside Generic.
2054+ def test_user_generics (self ):
2055+ T = TypeVar ("T" )
2056+ P = ParamSpec ("P" )
2057+ P_2 = ParamSpec ("P_2" )
2058+
2059+ class X (Generic [T , P ]):
2060+ pass
2061+
2062+ G1 = X [int , P_2 ]
2063+ self .assertEqual (G1 .__args__ , (int , P_2 ))
2064+ self .assertEqual (G1 .__parameters__ , (P_2 ,))
2065+
2066+ G2 = X [int , Concatenate [int , P_2 ]]
2067+ self .assertEqual (G2 .__args__ , (int , Concatenate [int , P_2 ]))
2068+ self .assertEqual (G2 .__parameters__ , (P_2 ,))
2069+
2070+ # The following are some valid uses cases in PEP 612 that don't work:
2071+ # These do not work in 3.9, _type_check blocks the list and ellipsis.
2072+ # G3 = X[int, [int, bool]]
2073+ # G4 = X[int, ...]
2074+ # G5 = Z[[int, str, bool]]
2075+ # Not working because this is special-cased in 3.10.
2076+ # G6 = Z[int, str, bool]
2077+
2078+ class Z (Generic [P ]):
2079+ pass
20432080
20442081 def test_pickle (self ):
20452082 global P , P_co , P_contra
0 commit comments