Skip to content

Commit ccf25a1

Browse files
authored
Merge branch '3.14' into backport-77bf4ba-3.14
2 parents f7887c9 + f3a6e8e commit ccf25a1

17 files changed

Lines changed: 121 additions & 186 deletions

Doc/library/base64.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,7 @@ Refer to the documentation of the individual functions for more information.
239239
*adobe* controls whether the input sequence is in Adobe Ascii85 format
240240
(i.e. is framed with <~ and ~>).
241241

242-
*ignorechars* should be a :term:`bytes-like object` or ASCII string
243-
containing characters to ignore
242+
*ignorechars* should be a byte string containing characters to ignore
244243
from the input. This should only contain whitespace characters, and by
245244
default contains all whitespace characters in ASCII.
246245

Doc/library/http.cookies.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,9 @@ The following example demonstrates how to use the :mod:`http.cookies` module.
292292
Set-Cookie: chips=ahoy
293293
Set-Cookie: vienna=finger
294294
>>> C = cookies.SimpleCookie()
295-
>>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
295+
>>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=;";')
296296
>>> print(C)
297-
Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
297+
Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=;"
298298
>>> C = cookies.SimpleCookie()
299299
>>> C["oreo"] = "doublestuff"
300300
>>> C["oreo"]["path"] = "/"

Doc/library/importlib.rst

Lines changed: 0 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -637,172 +637,6 @@ ABC hierarchy::
637637
itself does not end in ``__init__``.
638638

639639

640-
.. class:: ResourceReader
641-
642-
*Superseded by TraversableResources*
643-
644-
An :term:`abstract base class` to provide the ability to read
645-
*resources*.
646-
647-
From the perspective of this ABC, a *resource* is a binary
648-
artifact that is shipped within a package. Typically this is
649-
something like a data file that lives next to the ``__init__.py``
650-
file of the package. The purpose of this class is to help abstract
651-
out the accessing of such data files so that it does not matter if
652-
the package and its data file(s) are stored e.g. in a zip file
653-
versus on the file system.
654-
655-
For any of methods of this class, a *resource* argument is
656-
expected to be a :term:`path-like object` which represents
657-
conceptually just a file name. This means that no subdirectory
658-
paths should be included in the *resource* argument. This is
659-
because the location of the package the reader is for, acts as the
660-
"directory". Hence the metaphor for directories and file
661-
names is packages and resources, respectively. This is also why
662-
instances of this class are expected to directly correlate to
663-
a specific package (instead of potentially representing multiple
664-
packages or a module).
665-
666-
Loaders that wish to support resource reading are expected to
667-
provide a method called ``get_resource_reader(fullname)`` which
668-
returns an object implementing this ABC's interface. If the module
669-
specified by fullname is not a package, this method should return
670-
:const:`None`. An object compatible with this ABC should only be
671-
returned when the specified module is a package.
672-
673-
.. versionadded:: 3.7
674-
675-
.. deprecated-removed:: 3.12 3.14
676-
Use :class:`importlib.resources.abc.TraversableResources` instead.
677-
678-
.. method:: open_resource(resource)
679-
:abstractmethod:
680-
681-
Returns an opened, :term:`file-like object` for binary reading
682-
of the *resource*.
683-
684-
If the resource cannot be found, :exc:`FileNotFoundError` is
685-
raised.
686-
687-
.. method:: resource_path(resource)
688-
:abstractmethod:
689-
690-
Returns the file system path to the *resource*.
691-
692-
If the resource does not concretely exist on the file system,
693-
raise :exc:`FileNotFoundError`.
694-
695-
.. method:: is_resource(name)
696-
:abstractmethod:
697-
698-
Returns ``True`` if the named *name* is considered a resource.
699-
:exc:`FileNotFoundError` is raised if *name* does not exist.
700-
701-
.. method:: contents()
702-
:abstractmethod:
703-
704-
Returns an :term:`iterable` of strings over the contents of
705-
the package. Do note that it is not required that all names
706-
returned by the iterator be actual resources, e.g. it is
707-
acceptable to return names for which :meth:`is_resource` would
708-
be false.
709-
710-
Allowing non-resource names to be returned is to allow for
711-
situations where how a package and its resources are stored
712-
are known a priori and the non-resource names would be useful.
713-
For instance, returning subdirectory names is allowed so that
714-
when it is known that the package and resources are stored on
715-
the file system then those subdirectory names can be used
716-
directly.
717-
718-
The abstract method returns an iterable of no items.
719-
720-
721-
.. class:: Traversable
722-
723-
An object with a subset of :class:`pathlib.Path` methods suitable for
724-
traversing directories and opening files.
725-
726-
For a representation of the object on the file-system, use
727-
:meth:`importlib.resources.as_file`.
728-
729-
.. versionadded:: 3.9
730-
731-
.. deprecated-removed:: 3.12 3.14
732-
Use :class:`importlib.resources.abc.Traversable` instead.
733-
734-
.. attribute:: name
735-
736-
Abstract. The base name of this object without any parent references.
737-
738-
.. method:: iterdir()
739-
:abstractmethod:
740-
741-
Yield ``Traversable`` objects in ``self``.
742-
743-
.. method:: is_dir()
744-
:abstractmethod:
745-
746-
Return ``True`` if ``self`` is a directory.
747-
748-
.. method:: is_file()
749-
:abstractmethod:
750-
751-
Return ``True`` if ``self`` is a file.
752-
753-
.. method:: joinpath(child)
754-
:abstractmethod:
755-
756-
Return Traversable child in ``self``.
757-
758-
.. method:: __truediv__(child)
759-
:abstractmethod:
760-
761-
Return ``Traversable`` child in ``self``.
762-
763-
.. method:: open(mode='r', *args, **kwargs)
764-
:abstractmethod:
765-
766-
*mode* may be 'r' or 'rb' to open as text or binary. Return a handle
767-
suitable for reading (same as :attr:`pathlib.Path.open`).
768-
769-
When opening as text, accepts encoding parameters such as those
770-
accepted by :class:`io.TextIOWrapper`.
771-
772-
.. method:: read_bytes()
773-
774-
Read contents of ``self`` as bytes.
775-
776-
.. method:: read_text(encoding=None)
777-
778-
Read contents of ``self`` as text.
779-
780-
781-
.. class:: TraversableResources
782-
783-
An abstract base class for resource readers capable of serving
784-
the :meth:`importlib.resources.files` interface. Subclasses
785-
:class:`importlib.resources.abc.ResourceReader` and provides
786-
concrete implementations of the :class:`importlib.resources.abc.ResourceReader`'s
787-
abstract methods. Therefore, any loader supplying
788-
:class:`importlib.abc.TraversableResources` also supplies ResourceReader.
789-
790-
Loaders that wish to support resource reading are expected to
791-
implement this interface.
792-
793-
.. versionadded:: 3.9
794-
795-
.. deprecated-removed:: 3.12 3.14
796-
Use :class:`importlib.resources.abc.TraversableResources` instead.
797-
798-
.. method:: files()
799-
:abstractmethod:
800-
801-
Returns a :class:`importlib.resources.abc.Traversable` object for the loaded
802-
package.
803-
804-
805-
806640
:mod:`importlib.machinery` -- Importers and path hooks
807641
------------------------------------------------------
808642

Doc/library/inspect.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
524524

525525
.. versionchanged:: 3.13
526526
Functions wrapped in :func:`functools.partialmethod` now return ``True``
527-
if the wrapped function is a :term:`coroutine function`.
527+
if the wrapped function is a :term:`asynchronous generator` function.
528528

529529
.. function:: isasyncgen(object)
530530

Doc/whatsnew/3.7.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ new ABC for access to, opening, and reading *resources* inside packages.
604604
Resources are roughly similar to files inside packages, but they needn't
605605
be actual files on the physical file system. Module loaders can provide a
606606
:meth:`!get_resource_reader` function which returns
607-
a :class:`importlib.abc.ResourceReader` instance to support this
607+
a :class:`!importlib.abc.ResourceReader` instance to support this
608608
new API. Built-in file path loaders and zip file loaders both support this.
609609

610610
Contributed by Barry Warsaw and Brett Cannon in :issue:`32248`.
@@ -1043,7 +1043,7 @@ window are shown and hidden in the Options menu.
10431043
importlib
10441044
---------
10451045

1046-
The :class:`importlib.abc.ResourceReader` ABC was introduced to
1046+
The :class:`!importlib.abc.ResourceReader` ABC was introduced to
10471047
support the loading of resources from packages. See also
10481048
:ref:`whatsnew37_importlib_resources`.
10491049
(Contributed by Barry Warsaw, Brett Cannon in :issue:`32248`.)
@@ -2032,7 +2032,7 @@ both deprecated in Python 3.4 now emit :exc:`DeprecationWarning`.
20322032
(Contributed by Matthias Bussonnier in :issue:`29576`.)
20332033

20342034
The :class:`importlib.abc.ResourceLoader` ABC has been deprecated in
2035-
favour of :class:`importlib.abc.ResourceReader`.
2035+
favour of :class:`!importlib.abc.ResourceReader`.
20362036

20372037

20382038
locale

Lib/http/cookies.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@
8787
such trickeries do not confuse it.
8888
8989
>>> C = cookies.SimpleCookie()
90-
>>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
90+
>>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=;";')
9191
>>> print(C)
92-
Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
92+
Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=;"
9393
9494
Each element of the Cookie also supports all of the RFC 2109
9595
Cookie attributes. Here's an example which sets the Path
@@ -170,6 +170,15 @@ class CookieError(Exception):
170170
})
171171

172172
_is_legal_key = re.compile('[%s]+' % re.escape(_LegalChars)).fullmatch
173+
_control_character_re = re.compile(r'[\x00-\x1F\x7F]')
174+
175+
176+
def _has_control_character(*val):
177+
"""Detects control characters within a value.
178+
Supports any type, as header values can be any type.
179+
"""
180+
return any(_control_character_re.search(str(v)) for v in val)
181+
173182

174183
def _quote(str):
175184
r"""Quote a string for use in a cookie header.
@@ -294,12 +303,16 @@ def __setitem__(self, K, V):
294303
K = K.lower()
295304
if not K in self._reserved:
296305
raise CookieError("Invalid attribute %r" % (K,))
306+
if _has_control_character(K, V):
307+
raise CookieError(f"Control characters are not allowed in cookies {K!r} {V!r}")
297308
dict.__setitem__(self, K, V)
298309

299310
def setdefault(self, key, val=None):
300311
key = key.lower()
301312
if key not in self._reserved:
302313
raise CookieError("Invalid attribute %r" % (key,))
314+
if _has_control_character(key, val):
315+
raise CookieError("Control characters are not allowed in cookies %r %r" % (key, val,))
303316
return dict.setdefault(self, key, val)
304317

305318
def __eq__(self, morsel):
@@ -335,6 +348,9 @@ def set(self, key, val, coded_val):
335348
raise CookieError('Attempt to set a reserved key %r' % (key,))
336349
if not _is_legal_key(key):
337350
raise CookieError('Illegal key %r' % (key,))
351+
if _has_control_character(key, val, coded_val):
352+
raise CookieError(
353+
"Control characters are not allowed in cookies %r %r %r" % (key, val, coded_val,))
338354

339355
# It's a good key, so save it.
340356
self._key = key
@@ -488,7 +504,10 @@ def output(self, attrs=None, header="Set-Cookie:", sep="\015\012"):
488504
result = []
489505
items = sorted(self.items())
490506
for key, value in items:
491-
result.append(value.output(attrs, header))
507+
value_output = value.output(attrs, header)
508+
if _has_control_character(value_output):
509+
raise CookieError("Control characters are not allowed in cookies")
510+
result.append(value_output)
492511
return sep.join(result)
493512

494513
__str__ = output

Lib/idlelib/News3.txt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
1+
What's New in IDLE 3.14.z
2+
(since 3.14.0)
3+
Released after 2025-10-07
4+
=========================
5+
6+
7+
gh-143774: Better explain the operation of Format / Format Paragraph.
8+
Patch by Terry J. Reedy.
9+
10+
gh-139742: Colorize t-string prefixes for template strings in IDLE,
11+
as done for f-string prefixes. Patch by Anuradha Agrawal.
12+
113
What's New in IDLE 3.14.0
214
(since 3.13.0)
315
Released on 2025-10-07
416
=========================
517

6-
718
gh-129873: Simplify displaying the IDLE doc by only copying the text
819
section of idle.html to idlelib/help.html. Patch by Stan Ulbrych.
920

Lib/test/test_base64.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,19 @@ def test_a85decode_errors(self):
785785
self.assertRaises(ValueError, base64.a85decode, b'aaaay',
786786
foldspaces=True)
787787

788+
self.assertEqual(base64.a85decode(b"a b\nc", ignorechars=b" \n"),
789+
b'\xc9\x89')
790+
with self.assertRaises(ValueError):
791+
base64.a85decode(b"a b\nc", ignorechars=b"")
792+
with self.assertRaises(ValueError):
793+
base64.a85decode(b"a b\nc", ignorechars=b" ")
794+
with self.assertRaises(ValueError):
795+
base64.a85decode(b"a b\nc", ignorechars=b"\n")
796+
with self.assertRaises(TypeError):
797+
base64.a85decode(b"a b\nc", ignorechars=" \n")
798+
with self.assertRaises(TypeError):
799+
base64.a85decode(b"a b\nc", ignorechars=None)
800+
788801
def test_b85decode_errors(self):
789802
illegal = list(range(33)) + \
790803
list(b'"\',./:[\\]') + \

0 commit comments

Comments
 (0)