@@ -8944,7 +8944,147 @@ def test_pep_695_generics_with_future_annotations_nested_in_function(self):
8944
8944
set (results .generic_func .__type_params__ )
8945
8945
)
8946
8946
8947
- class TestEvaluateForwardRefs (BaseTestCase ):
8947
+
8948
+ class EvaluateForwardRefTests (BaseTestCase ):
8949
+ def test_evaluate_forward_ref (self ):
8950
+ int_ref = typing_extensions .ForwardRef ('int' )
8951
+ self .assertIs (typing_extensions .evaluate_forward_ref (int_ref ), int )
8952
+ self .assertIs (
8953
+ typing_extensions .evaluate_forward_ref (int_ref , type_params = ()),
8954
+ int ,
8955
+ )
8956
+ self .assertIs (
8957
+ typing_extensions .evaluate_forward_ref (int_ref , format = typing_extensions .Format .VALUE ),
8958
+ int ,
8959
+ )
8960
+ self .assertIs (
8961
+ typing_extensions .evaluate_forward_ref (
8962
+ int_ref , format = typing_extensions .Format .FORWARDREF ,
8963
+ ),
8964
+ int ,
8965
+ )
8966
+ self .assertEqual (
8967
+ typing_extensions .evaluate_forward_ref (
8968
+ int_ref , format = typing_extensions .Format .STRING ,
8969
+ ),
8970
+ 'int' ,
8971
+ )
8972
+
8973
+ def test_evaluate_forward_ref_undefined (self ):
8974
+ missing = typing_extensions .ForwardRef ('missing' )
8975
+ with self .assertRaises (NameError ):
8976
+ typing_extensions .evaluate_forward_ref (missing )
8977
+ self .assertIs (
8978
+ typing_extensions .evaluate_forward_ref (
8979
+ missing , format = typing_extensions .Format .FORWARDREF ,
8980
+ ),
8981
+ missing ,
8982
+ )
8983
+ self .assertEqual (
8984
+ typing_extensions .evaluate_forward_ref (
8985
+ missing , format = typing_extensions .Format .STRING ,
8986
+ ),
8987
+ "missing" ,
8988
+ )
8989
+
8990
+ def test_evaluate_forward_ref_nested (self ):
8991
+ ref = typing_extensions .ForwardRef ("Union[int, list['str']]" )
8992
+ ns = {"Union" : Union }
8993
+ if sys .version_info >= (3 , 11 ):
8994
+ expected = Union [int , list [str ]]
8995
+ else :
8996
+ expected = Union [int , list ['str' ]] # TODO: evaluate nested forward refs in Python < 3.11
8997
+ self .assertEqual (
8998
+ typing_extensions .evaluate_forward_ref (ref , globals = ns ),
8999
+ expected ,
9000
+ )
9001
+ self .assertEqual (
9002
+ typing_extensions .evaluate_forward_ref (
9003
+ ref , globals = ns , format = typing_extensions .Format .FORWARDREF
9004
+ ),
9005
+ expected ,
9006
+ )
9007
+ self .assertEqual (
9008
+ typing_extensions .evaluate_forward_ref (ref , format = typing_extensions .Format .STRING ),
9009
+ "Union[int, list['str']]" ,
9010
+ )
9011
+
9012
+ why = typing_extensions .ForwardRef ('"\' str\' "' )
9013
+ self .assertIs (typing_extensions .evaluate_forward_ref (why ), str )
9014
+
9015
+ @skipUnless (sys .version_info >= (3 , 10 ), "Relies on PEP 604" )
9016
+ def test_evaluate_forward_ref_nested_pep604 (self ):
9017
+ ref = typing_extensions .ForwardRef ("int | list['str']" )
9018
+ if sys .version_info >= (3 , 11 ):
9019
+ expected = int | list [str ]
9020
+ else :
9021
+ expected = int | list ['str' ] # TODO: evaluate nested forward refs in Python < 3.11
9022
+ self .assertEqual (
9023
+ typing_extensions .evaluate_forward_ref (ref ),
9024
+ expected ,
9025
+ )
9026
+ self .assertEqual (
9027
+ typing_extensions .evaluate_forward_ref (ref , format = typing_extensions .Format .FORWARDREF ),
9028
+ expected ,
9029
+ )
9030
+ self .assertEqual (
9031
+ typing_extensions .evaluate_forward_ref (ref , format = typing_extensions .Format .STRING ),
9032
+ "int | list['str']" ,
9033
+ )
9034
+
9035
+ def test_evaluate_forward_ref_none (self ):
9036
+ none_ref = typing_extensions .ForwardRef ('None' )
9037
+ self .assertIs (typing_extensions .evaluate_forward_ref (none_ref ), None )
9038
+
9039
+ def test_globals (self ):
9040
+ A = "str"
9041
+ ref = typing_extensions .ForwardRef ('list[A]' )
9042
+ with self .assertRaises (NameError ):
9043
+ typing_extensions .evaluate_forward_ref (ref )
9044
+ self .assertEqual (
9045
+ typing_extensions .evaluate_forward_ref (ref , globals = {'A' : A }),
9046
+ list [str ] if sys .version_info >= (3 , 11 ) else list ['str' ],
9047
+ )
9048
+
9049
+ def test_owner (self ):
9050
+ ref = typing_extensions .ForwardRef ("A" )
9051
+
9052
+ with self .assertRaises (NameError ):
9053
+ typing_extensions .evaluate_forward_ref (ref )
9054
+
9055
+ # We default to the globals of `owner`,
9056
+ # so it no longer raises `NameError`
9057
+ self .assertIs (
9058
+ typing_extensions .evaluate_forward_ref (ref , owner = Loop ), A
9059
+ )
9060
+
9061
+ @skipUnless (sys .version_info >= (3 , 14 ), "Not yet implemented in Python < 3.14" )
9062
+ def test_inherited_owner (self ):
9063
+ # owner passed to evaluate_forward_ref
9064
+ ref = typing_extensions .ForwardRef ("list['A']" )
9065
+ self .assertEqual (
9066
+ typing_extensions .evaluate_forward_ref (ref , owner = Loop ),
9067
+ list [A ],
9068
+ )
9069
+
9070
+ # owner set on the ForwardRef
9071
+ ref = typing_extensions .ForwardRef ("list['A']" , owner = Loop )
9072
+ self .assertEqual (
9073
+ typing_extensions .evaluate_forward_ref (ref ),
9074
+ list [A ],
9075
+ )
9076
+
9077
+ @skipUnless (sys .version_info >= (3 , 14 ), "Not yet implemented in Python < 3.14" )
9078
+ def test_partial_evaluation (self ):
9079
+ ref = typing_extensions .ForwardRef ("list[A]" )
9080
+ with self .assertRaises (NameError ):
9081
+ typing_extensions .evaluate_forward_ref (ref )
9082
+
9083
+ self .assertEqual (
9084
+ typing_extensions .evaluate_forward_ref (ref , format = typing_extensions .Format .FORWARDREF ),
9085
+ list [EqualToForwardRef ('A' )],
9086
+ )
9087
+
8948
9088
def test_global_constant (self ):
8949
9089
if sys .version_info [:3 ] > (3 , 10 , 0 ):
8950
9090
self .assertTrue (_FORWARD_REF_HAS_CLASS )
@@ -9107,30 +9247,17 @@ class Y(Generic[Tx]):
9107
9247
self .assertEqual (get_args (evaluated_ref3 ), (Z [str ],))
9108
9248
9109
9249
def test_invalid_special_forms (self ):
9110
- # tests _lax_type_check to raise errors the same way as the typing module.
9111
- # Regex capture "< class 'module.name'> and "module.name"
9112
- with self .assertRaisesRegex (
9113
- TypeError , r"Plain .*Protocol('>)? is not valid as type argument"
9114
- ):
9115
- evaluate_forward_ref (typing .ForwardRef ("Protocol" ), globals = vars (typing ))
9116
- with self .assertRaisesRegex (
9117
- TypeError , r"Plain .*Generic('>)? is not valid as type argument"
9118
- ):
9119
- evaluate_forward_ref (typing .ForwardRef ("Generic" ), globals = vars (typing ))
9120
- with self .assertRaisesRegex (TypeError , r"Plain typing(_extensions)?\.Final is not valid as type argument" ):
9121
- evaluate_forward_ref (typing .ForwardRef ("Final" ), globals = vars (typing ))
9122
- with self .assertRaisesRegex (TypeError , r"Plain typing(_extensions)?\.ClassVar is not valid as type argument" ):
9123
- evaluate_forward_ref (typing .ForwardRef ("ClassVar" ), globals = vars (typing ))
9250
+ for name in ("Protocol" , "Final" , "ClassVar" , "Generic" ):
9251
+ with self .subTest (name = name ):
9252
+ self .assertIs (
9253
+ evaluate_forward_ref (typing .ForwardRef (name ), globals = vars (typing )),
9254
+ getattr (typing , name ),
9255
+ )
9124
9256
if _FORWARD_REF_HAS_CLASS :
9125
9257
self .assertIs (evaluate_forward_ref (typing .ForwardRef ("Final" , is_class = True ), globals = vars (typing )), Final )
9126
9258
self .assertIs (evaluate_forward_ref (typing .ForwardRef ("ClassVar" , is_class = True ), globals = vars (typing )), ClassVar )
9127
- with self .assertRaisesRegex (TypeError , r"Plain typing(_extensions)?\.Final is not valid as type argument" ):
9128
- evaluate_forward_ref (typing .ForwardRef ("Final" , is_argument = False ), globals = vars (typing ))
9129
- with self .assertRaisesRegex (TypeError , r"Plain typing(_extensions)?\.ClassVar is not valid as type argument" ):
9130
- evaluate_forward_ref (typing .ForwardRef ("ClassVar" , is_argument = False ), globals = vars (typing ))
9131
- else :
9132
- self .assertIs (evaluate_forward_ref (typing .ForwardRef ("Final" , is_argument = False ), globals = vars (typing )), Final )
9133
- self .assertIs (evaluate_forward_ref (typing .ForwardRef ("ClassVar" , is_argument = False ), globals = vars (typing )), ClassVar )
9259
+ self .assertIs (evaluate_forward_ref (typing .ForwardRef ("Final" , is_argument = False ), globals = vars (typing )), Final )
9260
+ self .assertIs (evaluate_forward_ref (typing .ForwardRef ("ClassVar" , is_argument = False ), globals = vars (typing )), ClassVar )
9134
9261
9135
9262
9136
9263
class TestSentinels (BaseTestCase ):
0 commit comments