From 9e5628ad68b768e2a8f0bcd3204b0027e238c45c Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Sun, 2 Nov 2025 22:56:59 +0100 Subject: [PATCH 1/3] gh-140808: Remove __class_getitem__ from mailbox._ProxyFile (#140838) Co-authored-by: Emma Smith --- Lib/mailbox.py | 2 -- Lib/test/test_genericalias.py | 4 ++-- .../Library/2025-10-31-16-25-13.gh-issue-140808.XBiQ4j.rst | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-10-31-16-25-13.gh-issue-140808.XBiQ4j.rst diff --git a/Lib/mailbox.py b/Lib/mailbox.py index b00d9e8634c785..4a44642765cc9a 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_genericalias.py b/Lib/test/test_genericalias.py index 4e08adaca05cdd..9df9296e26ad5c 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-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 00000000000000..090f39c6e25fdf --- /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. From 31de83d5e2e17f4e9a37e08b384bab916e1da7c1 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya <141550576+XChaitanyaX@users.noreply.github.com> Date: Mon, 3 Nov 2025 03:28:16 +0530 Subject: [PATCH 2/3] gh-140693: Improve `argparse` documentation about controlling color (#140737) --- Doc/library/argparse.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 418f514995df3a..9655db4f301a31 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 From e66f87ca73516efb4aec1f2f056d2a4efd73248a Mon Sep 17 00:00:00 2001 From: dr-carlos <77367421+dr-carlos@users.noreply.github.com> Date: Mon, 3 Nov 2025 09:45:47 +1030 Subject: [PATCH 3/3] gh-138425: Correctly partially evaluate global generics with undefined params in `ref.evaluate(format=Format.FORWARDREF)` (#138430) Co-authored-by: sobolevn --- Lib/annotationlib.py | 5 +++- Lib/test/test_annotationlib.py | 26 +++++++++++++++++++ ...-09-03-18-26-07.gh-issue-138425.cVE9Ho.rst | 2 ++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2025-09-03-18-26-07.gh-issue-138425.cVE9Ho.rst diff --git a/Lib/annotationlib.py b/Lib/annotationlib.py index 81886a0467d001..16dbb128bc9293 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/test/test_annotationlib.py b/Lib/test/test_annotationlib.py index 8da4ff096e7593..7b08f58bfb8ba2 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/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 00000000000000..328e5988cb0b51 --- /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.