diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 418f514995df3a9..9655db4f301a319 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -638,6 +638,11 @@ by setting ``color`` to ``False``:: ... help='an integer for the accumulator') >>> parser.parse_args(['--help']) +Note that when ``color=True``, colored output depends on both environment +variables and terminal capabilities. However, if ``color=False``, colored +output is always disabled, even if environment variables like ``FORCE_COLOR`` +are set. + .. versionadded:: 3.14 diff --git a/Lib/annotationlib.py b/Lib/annotationlib.py index 81886a0467d0018..16dbb128bc9293e 100644 --- a/Lib/annotationlib.py +++ b/Lib/annotationlib.py @@ -187,8 +187,11 @@ def evaluate( except Exception: if not is_forwardref_format: raise + + # All variables, in scoping order, should be checked before + # triggering __missing__ to create a _Stringifier. new_locals = _StringifierDict( - {**builtins.__dict__, **locals}, + {**builtins.__dict__, **globals, **locals}, globals=globals, owner=owner, is_class=self.__forward_is_class__, diff --git a/Lib/mailbox.py b/Lib/mailbox.py index b00d9e8634c7853..4a44642765cc9a4 100644 --- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -2090,8 +2090,6 @@ def closed(self): return False return self._file.closed - __class_getitem__ = classmethod(GenericAlias) - class _PartialFile(_ProxyFile): """A read-only wrapper of part of a file.""" diff --git a/Lib/test/test_annotationlib.py b/Lib/test/test_annotationlib.py index 8da4ff096e7593b..7b08f58bfb8ba21 100644 --- a/Lib/test/test_annotationlib.py +++ b/Lib/test/test_annotationlib.py @@ -1877,6 +1877,32 @@ def test_name_lookup_without_eval(self): self.assertEqual(exc.exception.name, "doesntexist") + def test_evaluate_undefined_generic(self): + # Test the codepath where have to eval() with undefined variables. + class C: + x: alias[int, undef] + + generic = get_annotations(C, format=Format.FORWARDREF)["x"].evaluate( + format=Format.FORWARDREF, + globals={"alias": dict} + ) + self.assertNotIsInstance(generic, ForwardRef) + self.assertIs(generic.__origin__, dict) + self.assertEqual(len(generic.__args__), 2) + self.assertIs(generic.__args__[0], int) + self.assertIsInstance(generic.__args__[1], ForwardRef) + + generic = get_annotations(C, format=Format.FORWARDREF)["x"].evaluate( + format=Format.FORWARDREF, + globals={"alias": Union}, + locals={"alias": dict} + ) + self.assertNotIsInstance(generic, ForwardRef) + self.assertIs(generic.__origin__, dict) + self.assertEqual(len(generic.__args__), 2) + self.assertIs(generic.__args__[0], int) + self.assertIsInstance(generic.__args__[1], ForwardRef) + def test_fwdref_invalid_syntax(self): fr = ForwardRef("if") with self.assertRaises(SyntaxError): diff --git a/Lib/test/test_genericalias.py b/Lib/test/test_genericalias.py index 4e08adaca05cdd4..9df9296e26ad5c9 100644 --- a/Lib/test/test_genericalias.py +++ b/Lib/test/test_genericalias.py @@ -17,7 +17,7 @@ from functools import partial, partialmethod, cached_property from graphlib import TopologicalSorter from logging import LoggerAdapter, StreamHandler -from mailbox import Mailbox, _PartialFile +from mailbox import Mailbox try: import ctypes except ImportError: @@ -117,7 +117,7 @@ class BaseTest(unittest.TestCase): Iterable, Iterator, Reversible, Container, Collection, - Mailbox, _PartialFile, + Mailbox, ContextVar, Token, Field, Set, MutableSet, diff --git a/Misc/NEWS.d/next/Library/2025-09-03-18-26-07.gh-issue-138425.cVE9Ho.rst b/Misc/NEWS.d/next/Library/2025-09-03-18-26-07.gh-issue-138425.cVE9Ho.rst new file mode 100644 index 000000000000000..328e5988cb0b511 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-09-03-18-26-07.gh-issue-138425.cVE9Ho.rst @@ -0,0 +1,2 @@ +Fix partial evaluation of :class:`annotationlib.ForwardRef` objects which rely +on names defined as globals. diff --git a/Misc/NEWS.d/next/Library/2025-10-31-16-25-13.gh-issue-140808.XBiQ4j.rst b/Misc/NEWS.d/next/Library/2025-10-31-16-25-13.gh-issue-140808.XBiQ4j.rst new file mode 100644 index 000000000000000..090f39c6e25fdfb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-10-31-16-25-13.gh-issue-140808.XBiQ4j.rst @@ -0,0 +1 @@ +The internal class ``mailbox._ProxyFile`` is no longer a parameterized generic.