Skip to content

Commit fb992e8

Browse files
committed
Solve global variable error
1 parent d594cbc commit fb992e8

File tree

1 file changed

+71
-56
lines changed

1 file changed

+71
-56
lines changed

src/test_typing_extensions.py

Lines changed: 71 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)