@@ -8131,23 +8131,24 @@ def __str__(self):
81318131 def __repr__ (self ) -> str :
81328132 return str (self )
81338133
8134- class X (_EasyStr ): pass
8134+ class X (_EasyStr ):
8135+ T_in_Y = object ()
81358136
8136- T_in_G = TypeVar ("T_in_G " )
8137- class Y (Generic [T_in_G ], _EasyStr ):
8137+ T_in_Y = TypeVar ("T_in_Y " )
8138+ class Y (Generic [T_in_Y ], _EasyStr ):
81388139 a = "X"
81398140 bT = "Y[T_nonlocal]"
81408141 alias = int
81418142
81428143 # workaround for type statement
8143- __type_params__ = (T_in_G ,)
8144- #Y.T_in_G = T_in_G
8144+ __type_params__ = (T_in_Y ,)
8145+ Y . T_in_Y = T_in_Y
81458146
81468147 # Assure that these are not in globals
81478148 assert X .__name__ not in globals ()
81488149 assert Y .__name__ not in globals ()
8149- assert Y .__type_params__ == ( T_in_G , )
8150- del T_in_G
8150+ self . assertEqual ( Y .__type_params__ , ( T_in_Y ,) )
8151+ del T_in_Y
81518152
81528153 minimal_locals = {
81538154 #"Y": Y,
@@ -8180,6 +8181,11 @@ class Y(Generic[T_in_G], _EasyStr):
81808181 Format .FORWARDREF : str ,
81818182 Format .STRING : "StrAlias" ,
81828183 },
8184+ Union [str , None , "str" ]: {
8185+ Format .VALUE : Optional [str ],
8186+ Format .FORWARDREF : Optional [str ],
8187+ Format .STRING : str (Union [str , None , "str" ]),
8188+ },
81838189 "X" : X ,
81848190 "Y[X]" : {
81858191 Format .VALUE : Y [X ],
@@ -8220,32 +8226,14 @@ class Y(Generic[T_in_G], _EasyStr):
82208226 ),
82218227 Format .STRING : """Y["Y['T']"]""" ,
82228228 },
8223- # {
8224- # "skip_if": {"localns": True, "format": Format.FORWARDREF},
8225- # Format.VALUE: (
8226- # Y[Y[T]]
8227- # if sys.version_info[:2] > (3, 8)
8228- # else "Skip: nested string not supported"
8229- # ),
8230- # Format.FORWARDREF: ForwardRef("Y[\"Y['T']\"]"),
8231- # Format.STRING: """Y["Y['T']"]""",
8232- # },
82338229 ],
82348230 "Y[Y[T_nonlocal]]" : [
82358231 {
82368232 "type_params" : T_local_type_params ,
8237- # "skip_if": {"localns": None, "format": Format.FORWARDREF},
82388233 Format .VALUE : Y [Y [T_local ]],
82398234 Format .FORWARDREF : Y [Y [T_local ]],
82408235 Format .STRING : "Y[Y[T_nonlocal]]" ,
82418236 },
8242- # {
8243- # "type_params": T_local_type_params,
8244- # "skip_if": {"localns": locals(), "format": Format.FORWARDREF},
8245- # Format.VALUE: Y[Y[T_local]],
8246- # Format.FORWARDREF: ForwardRef("Y[Y[T_nonlocal]]"),
8247- # Format.STRING: "Y[Y[T_nonlocal]]",
8248- # },
82498237 {
82508238 "type_params" : None ,
82518239 Format .VALUE : NameError ,
@@ -8291,7 +8279,7 @@ class Y(Generic[T_in_G], _EasyStr):
82918279 Format .STRING : "Y.bT" ,
82928280 },
82938281 ],
8294- # Special cases depending
8282+ # Special cases for _type_check
82958283 ClassVar [None ]: ClassVar [None ],
82968284 Final [None ]: Final [None ],
82978285 Protocol [T ]: Protocol [T ],
@@ -8316,37 +8304,56 @@ class Y(Generic[T_in_G], _EasyStr):
83168304 },
83178305 ]
83188306 if _FORWARD_REF_HAS_CLASS
8319- else Final # no errors here
8307+ else Final # will not raise error in older versions
83208308 ),
83218309 Generic : {
83228310 Format .VALUE : TypeError ,
83238311 Format .FORWARDREF : TypeError ,
83248312 Format .STRING : "Generic" ,
83258313 },
8326- Union [str , None , "str" ]: {
8327- Format .VALUE : Optional [str ],
8328- Format .FORWARDREF : Optional [str ],
8329- Format .STRING : str (Union [str , None , "str" ]),
8330- },
8331- "T_in_G" : [
8314+ "T_in_Y" : [
8315+ {
8316+ "owner" : None ,
8317+ "type_params" : Y .__type_params__ ,
8318+ Format .VALUE : Y .__type_params__ [0 ],
8319+ Format .FORWARDREF : Y .__type_params__ [0 ],
8320+ Format .STRING : "T_in_Y" ,
8321+ },
8322+ {
8323+ "owner" : None ,
8324+ "type_params" : None ,
8325+ Format .VALUE : NameError ,
8326+ Format .FORWARDREF : ForwardRef ("T_in_Y" ),
8327+ Format .STRING : "T_in_Y" ,
8328+ },
83328329 {
8330+ "owner" : Y ,
8331+ "type_params" : None ,
8332+ Format .VALUE : Y .__type_params__ [0 ],
8333+ Format .FORWARDREF : Y .__type_params__ [0 ],
8334+ Format .STRING : "T_in_Y" ,
8335+ },
8336+ {
8337+ "owner" : Y ,
83338338 "type_params" : Y .__type_params__ ,
83348339 Format .VALUE : Y .__type_params__ [0 ],
83358340 Format .FORWARDREF : Y .__type_params__ [0 ],
8336- Format .STRING : "T_in_G " ,
8341+ Format .STRING : "T_in_Y " ,
83378342 },
83388343 {
8344+ "owner" : X ,
83398345 "type_params" : None ,
83408346 Format .VALUE : NameError ,
8341- Format .FORWARDREF : ForwardRef ("T_in_G " ),
8342- Format .STRING : "T_in_G " ,
8347+ Format .FORWARDREF : ForwardRef ("T_in_Y " ),
8348+ Format .STRING : "T_in_Y " ,
83438349 },
83448350 ],
83458351 }
83468352
83478353 def _unroll_subcase (
83488354 annot , expected , format , is_argument , is_class , globalns , localns
83498355 ):
8356+ owner = expected .get ("owner" , None )
83508357 type_params = expected .get ("type_params" , None )
83518358 skip_if = expected .get ("skip_if" , False )
83528359 if format not in expected :
@@ -8369,6 +8376,7 @@ def _unroll_subcase(
83698376 globalns ,
83708377 localns ,
83718378 type_params ,
8379+ owner ,
83728380 )
83738381 def unroll_cases (cases , outer_locals ):
83748382 for (
@@ -8388,11 +8396,13 @@ def unroll_cases(cases, outer_locals):
83888396 # locals
83898397 (outer_locals , None ),
83908398 ):
8399+ owner = None
83918400 # Argument for ForwardRef
83928401 if isinstance (annot , type ):
83938402 annot = annot .__name__
83948403 else :
83958404 annot = str (annot )
8405+ # 3 cases for the different formats
83968406 if isinstance (expected , dict ):
83978407 case = _unroll_subcase (
83988408 annot ,
@@ -8405,6 +8415,7 @@ def unroll_cases(cases, outer_locals):
84058415 )
84068416 if case is not None :
84078417 yield case
8418+ # Multiple cases depending on other parameters
84088419 elif isinstance (expected , list ):
84098420 yield from filter (
84108421 None ,
@@ -8421,8 +8432,8 @@ def unroll_cases(cases, outer_locals):
84218432 for sub_expected in expected
84228433 ),
84238434 )
8435+ # Single value
84248436 else :
8425- # NOTE: only for non-dict inputs
84268437 # Change expected to TypeError if it will fail typing._type_check
84278438 if format != Format .STRING and not inspect .isclass (expected ):
84288439 invalid_generic_forms = (Generic , Protocol )
@@ -8444,8 +8455,9 @@ def unroll_cases(cases, outer_locals):
84448455 globalns ,
84458456 localns ,
84468457 type_params ,
8458+ owner ,
84478459 )
8448-
8460+ # Test cases
84498461 for (
84508462 annot ,
84518463 expected ,
@@ -8455,19 +8467,19 @@ def unroll_cases(cases, outer_locals):
84558467 globalns ,
84568468 localns ,
84578469 type_params ,
8470+ owner ,
84588471 ) in unroll_cases (cases , locals ()):
8459-
84608472 if _FORWARD_REF_HAS_CLASS :
84618473 ref = typing .ForwardRef (annot , is_argument = is_argument , is_class = is_class )
84628474 else :
84638475 ref = typing .ForwardRef (annot , is_argument = is_argument )
84648476 with self .subTest (
8477+ annot = annot ,
8478+ expected = expected ,
84658479 format = format ,
8466- ref = ref ,
84678480 is_argument = is_argument ,
84688481 is_class = is_class ,
84698482 type_params = type_params ,
8470- expected = expected ,
84718483 globals = bool (globalns ),
84728484 locals = bool (localns ),
84738485 ):
@@ -8507,7 +8519,7 @@ def unroll_cases(cases, outer_locals):
85078519 globals = globalns ,
85088520 format = format ,
85098521 type_params = type_params ,
8510- owner = None ,
8522+ owner = owner ,
85118523 )
85128524 continue
85138525 result = evaluate_forward_ref (
@@ -8516,37 +8528,40 @@ def unroll_cases(cases, outer_locals):
85168528 globals = globalns ,
85178529 format = format ,
85188530 type_params = type_params ,
8519- owner = None ,
8531+ owner = owner ,
85208532 )
85218533 self .assertEqual (result , expected )
85228534
8535+ def test_evaluate_with_type_params (self ):
8536+ # Use a T name that is not in globals
8537+ assert "Tx" not in globals ()
85238538 if not TYPING_3_12_0 :
8524- T = TypeVar ("T " )
8525- class Gen (Generic [T ]):
8539+ Tx = TypeVar ("Tx " )
8540+ class Gen (Generic [Tx ]):
85268541 alias = int
85278542 if not hasattr (Gen , "__type_params__" ):
8528- Gen .__type_params__ = (T ,)
8529- assert Gen .__type_params__ == (T ,)
8530- del T
8543+ Gen .__type_params__ = (Tx ,)
8544+ assert Gen .__type_params__ == (Tx ,)
8545+ del Tx
85318546 else :
85328547 ns = {}
85338548 exec (textwrap .dedent ("""
8534- class Gen[T ]:
8549+ class Gen[Tx ]:
85358550 alias = int
85368551 """ ), None , ns )
85378552 Gen = ns ["Gen" ]
85388553
85398554 with self .assertRaises (NameError ):
8540- evaluate_forward_ref (typing .ForwardRef ("T " ))
8555+ evaluate_forward_ref (typing .ForwardRef ("Tx " ))
85418556 with self .assertRaises (NameError ):
8542- evaluate_forward_ref (typing .ForwardRef ("T " ), type_params = ())
8557+ evaluate_forward_ref (typing .ForwardRef ("Tx " ), type_params = ())
85438558 with self .assertRaises (NameError ):
8544- evaluate_forward_ref (typing .ForwardRef ("T " ), owner = int )
8559+ evaluate_forward_ref (typing .ForwardRef ("Tx " ), owner = int )
85458560
8546- (T ,) = Gen .__type_params__
8547- self .assertIs (evaluate_forward_ref (typing .ForwardRef ("T " ), type_params = Gen .__type_params__ ), T )
8548- if TYPING_3_11_0 :
8549- self .assertIs (evaluate_forward_ref (typing .ForwardRef ("T " ), owner = Gen ), T )
8561+ (Tx ,) = Gen .__type_params__
8562+ self .assertIs (evaluate_forward_ref (typing .ForwardRef ("Tx " ), type_params = Gen .__type_params__ ), Tx )
8563+ # For this test its important that Tx is not a global variable, e.g. do not use T
8564+ self .assertIs (evaluate_forward_ref (typing .ForwardRef ("Tx " ), owner = Gen ), Tx )
85508565
85518566 with self .assertRaises (NameError ):
85528567 evaluate_forward_ref (typing .ForwardRef ("alias" ), type_params = Gen .__type_params__ )
0 commit comments