Skip to content

Commit 156b8b8

Browse files
Merge branch 'main' into gh-124748
2 parents a39fb51 + dd64e42 commit 156b8b8

File tree

60 files changed

+14863
-15067
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+14863
-15067
lines changed

.github/CODEOWNERS

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,8 +473,9 @@ Lib/test/test_functools.py @rhettinger
473473
Modules/_functoolsmodule.c @rhettinger
474474

475475
# Garbage collector
476-
Modules/gcmodule.c @pablogsal
477-
Doc/library/gc.rst @pablogsal
476+
Modules/gcmodule.c @pablogsal
477+
Doc/library/gc.rst @pablogsal
478+
InternalDocs/garbage_collector.md @pablogsal
478479

479480
# Gettext
480481
Doc/library/gettext.rst @tomasr8

.github/ISSUE_TEMPLATE/documentation.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ body:
88
> [!NOTE]
99
> Trivial changes (for example typos) don’t require an issue before opening a PR.
1010
- type: textarea
11+
id: description
1112
attributes:
1213
label: "Documentation"
13-
description: "A clear and concise description of the issue."
14+
description: "A clear and concise description of the issue. Include a link to the page."
1415
validations:
1516
required: true

.github/workflows/build.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,11 +242,18 @@ jobs:
242242
# BOLT currently crashes during instrumentation on aarch64
243243
- os: ubuntu-24.04-arm
244244
bolt: true
245+
include:
246+
# Enable CPU-intensive tests on ARM (default build only)
247+
- os: ubuntu-24.04-arm
248+
bolt: false
249+
free-threading: false
250+
test-opts: '-u cpu'
245251
uses: ./.github/workflows/reusable-ubuntu.yml
246252
with:
247253
bolt-optimizations: ${{ matrix.bolt }}
248254
free-threading: ${{ matrix.free-threading }}
249255
os: ${{ matrix.os }}
256+
test-opts: ${{ matrix.test-opts || '' }}
250257

251258
build-ubuntu-ssltests-openssl:
252259
name: 'Ubuntu SSL tests with OpenSSL'

.github/workflows/reusable-ubuntu.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ on:
1717
description: OS to run the job
1818
required: true
1919
type: string
20+
test-opts:
21+
description: Extra options to pass to the test runner via TESTOPTS
22+
required: false
23+
type: string
24+
default: ''
2025

2126
env:
2227
FORCE_COLOR: 1
@@ -111,4 +116,6 @@ jobs:
111116
run: sudo mount "$CPYTHON_RO_SRCDIR" -oremount,rw
112117
- name: Tests
113118
working-directory: ${{ env.CPYTHON_BUILDDIR }}
114-
run: xvfb-run make ci
119+
run: xvfb-run make ci EXTRATESTOPTS="${TEST_OPTS}"
120+
env:
121+
TEST_OPTS: ${{ inputs.test-opts }}

Doc/c-api/dict.rst

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
.. _dictobjects:
44

5-
Dictionary Objects
5+
Dictionary objects
66
------------------
77

88
.. index:: pair: object; dictionary
@@ -444,7 +444,7 @@ Dictionary Objects
444444
.. versionadded:: 3.12
445445
446446
447-
Dictionary View Objects
447+
Dictionary view objects
448448
^^^^^^^^^^^^^^^^^^^^^^^
449449
450450
.. c:function:: int PyDictViewSet_Check(PyObject *op)
@@ -490,7 +490,58 @@ Dictionary View Objects
490490
always succeeds.
491491
492492
493-
Ordered Dictionaries
493+
Frozen dictionary objects
494+
^^^^^^^^^^^^^^^^^^^^^^^^^
495+
496+
.. versionadded:: next
497+
498+
499+
.. c:var:: PyTypeObject PyFrozenDict_Type
500+
501+
This instance of :c:type:`PyTypeObject` represents the Python frozen
502+
dictionary type.
503+
This is the same object as :class:`frozendict` in the Python layer.
504+
505+
506+
.. c:function:: int PyAnyDict_Check(PyObject *p)
507+
508+
Return true if *p* is a :class:`dict` object, a :class:`frozendict` object,
509+
or an instance of a subtype of the :class:`!dict` or :class:`!frozendict`
510+
type.
511+
This function always succeeds.
512+
513+
514+
.. c:function:: int PyAnyDict_CheckExact(PyObject *p)
515+
516+
Return true if *p* is a :class:`dict` object or a :class:`frozendict` object,
517+
but not an instance of a subtype of the :class:`!dict` or
518+
:class:`!frozendict` type.
519+
This function always succeeds.
520+
521+
522+
.. c:function:: int PyFrozenDict_Check(PyObject *p)
523+
524+
Return true if *p* is a :class:`frozendict` object or an instance of a
525+
subtype of the :class:`!frozendict` type.
526+
This function always succeeds.
527+
528+
529+
.. c:function:: int PyFrozenDict_CheckExact(PyObject *p)
530+
531+
Return true if *p* is a :class:`frozendict` object, but not an instance of a
532+
subtype of the :class:`!frozendict` type.
533+
This function always succeeds.
534+
535+
536+
.. c:function:: PyObject* PyFrozenDict_New(PyObject *iterable)
537+
538+
Return a new :class:`frozendict` from an iterable, or ``NULL`` on failure
539+
with an exception set.
540+
541+
Create an empty dictionary if *iterable* is ``NULL``.
542+
543+
544+
Ordered dictionaries
494545
^^^^^^^^^^^^^^^^^^^^
495546
496547
Python's C API provides interface for :class:`collections.OrderedDict` from C.

Doc/conf.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,6 @@
227227
# Temporary undocumented names.
228228
# In future this list must be empty.
229229
nitpick_ignore += [
230-
# Do not error nit-picky mode builds when _SubParsersAction.add_parser cannot
231-
# be resolved, as the method is currently undocumented. For context, see
232-
# https://github.com/python/cpython/pull/103289.
233-
('py:meth', '_SubParsersAction.add_parser'),
234230
# Attributes/methods/etc. that definitely should be documented better,
235231
# but are deferred for now:
236232
('py:attr', '__wrapped__'),

Doc/improve-page-nojs.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
:orphan:
2+
3+
****************************
4+
Improve a documentation page
5+
****************************
6+
7+
.. This is the no-javascript version of this page. The one most people
8+
will see (with JavaScript enabled) is improve-page.rst. If you edit
9+
this page, please also edit that one, and vice versa.
10+
11+
.. only:: html and not epub
12+
13+
We are always interested to hear ideas about improvements to the documentation.
14+
15+
.. only:: translation
16+
17+
If the bug or suggested improvement concerns the translation of this
18+
documentation, open an issue or edit the page in
19+
`translation's repository <TRANSLATION_REPO_>`_ instead.
20+
21+
You have a few ways to ask questions or suggest changes:
22+
23+
- You can start a discussion about the page on the Python discussion forum.
24+
This link will start a topic in the Documentation category:
25+
`New Documentation topic <https://discuss.python.org/new-topic?category=documentation>`_.
26+
27+
- You can open an issue on the Python GitHub issue tracker. This link will
28+
create a new issue with the "docs" label:
29+
`New docs issue <https://github.com/python/cpython/issues/new?template=documentation.yml>`_.

Doc/improve-page.rst

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
:orphan:
2+
3+
****************************
4+
Improve a documentation page
5+
****************************
6+
7+
.. This is the JavaScript-enabled version of this page. Another version
8+
(for those with JavaScript disabled) is improve-page-nojs.rst. If you
9+
edit this page, please also edit that one, and vice versa.
10+
11+
.. only:: html and not epub
12+
13+
.. raw:: html
14+
15+
<script>
16+
function applyReplacements(text, params) {
17+
return text
18+
.replace(/PAGETITLE/g, params.get('pagetitle'))
19+
.replace(/PAGEURL/g, params.get('pageurl'))
20+
.replace(/PAGESOURCE/g, params.get('pagesource'));
21+
}
22+
23+
document.addEventListener('DOMContentLoaded', () => {
24+
const params = new URLSearchParams(window.location.search);
25+
const walker = document.createTreeWalker(
26+
document.body,
27+
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,
28+
null
29+
);
30+
31+
while (walker.nextNode()) {
32+
const node = walker.currentNode;
33+
34+
if (node.nodeType === Node.TEXT_NODE) {
35+
node.textContent = applyReplacements(node.textContent, params)
36+
} else if (node.nodeName === 'A' && node.href) {
37+
node.setAttribute('href', applyReplacements(node.getAttribute('href'), params));
38+
}
39+
}
40+
});
41+
</script>
42+
43+
We are always interested to hear ideas about improvements to the documentation.
44+
45+
You were reading "PAGETITLE" at `<PAGEURL>`_. The source for that page is on
46+
`GitHub <https://github.com/python/cpython/blob/main/Doc/PAGESOURCE?plain=1>`_.
47+
48+
.. only:: translation
49+
50+
If the bug or suggested improvement concerns the translation of this
51+
documentation, open an issue or edit the page in
52+
`translation's repository <TRANSLATION_REPO_>`_ instead.
53+
54+
You have a few ways to ask questions or suggest changes:
55+
56+
- You can start a discussion about the page on the Python discussion forum.
57+
This link will start a pre-populated topic:
58+
`Question about page "PAGETITLE" <https://discuss.python.org/new-topic?category=documentation&title=Question+about+page+%22PAGETITLE%22&body=About+the+page+at+PAGEURL%3A>`_.
59+
60+
- You can open an issue on the Python GitHub issue tracker. This link will
61+
create a new pre-populated issue:
62+
`Docs: problem with page "PAGETITLE" <https://github.com/python/cpython/issues/new?template=documentation.yml&title=Docs%3A+problem+with+page+%22PAGETITLE%22&description=The+page+at+PAGEURL+has+a+problem%3A>`_.
63+
64+
- You can `edit the page on GitHub <https://github.com/python/cpython/blob/main/Doc/PAGESOURCE?plain=1>`_
65+
to open a pull request and begin the contribution process.

Doc/library/datetime.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2534,8 +2534,8 @@ requires, and these work on all supported platforms.
25342534
| ``%d`` | Day of the month as a | 01, 02, ..., 31 | \(9) |
25352535
| | zero-padded decimal number. | | |
25362536
+-----------+--------------------------------+------------------------+-------+
2537-
| ``%D`` | Equivalent to ``%m/%d/%y``. | 11/10/2025 | \(9), |
2538-
| | | | \(0) |
2537+
| ``%D`` | Equivalent to ``%m/%d/%y``. | 11/28/25 | \(9) |
2538+
| | | | |
25392539
+-----------+--------------------------------+------------------------+-------+
25402540
| ``%e`` | The day of the month as a | ␣1, ␣2, ..., 31 | |
25412541
| | space-padded decimal number. | | |
@@ -2676,7 +2676,7 @@ differences between platforms in handling of unsupported format specifiers.
26762676
``%:z`` was added for :meth:`~.datetime.strftime`.
26772677

26782678
.. versionadded:: 3.15
2679-
``%:z`` and ``%F`` were added for :meth:`~.datetime.strptime`.
2679+
``%:z``, ``%F``, and ``%D`` were added for :meth:`~.datetime.strptime`.
26802680

26812681
Technical Detail
26822682
^^^^^^^^^^^^^^^^

Doc/library/stdtypes.rst

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5305,8 +5305,8 @@ frozenset, a temporary one is created from *elem*.
53055305

53065306
.. _typesmapping:
53075307

5308-
Mapping Types --- :class:`dict`
5309-
===============================
5308+
Mapping types --- :class:`!dict`, :class:`!frozendict`
5309+
======================================================
53105310

53115311
.. index::
53125312
pair: object; mapping
@@ -5317,8 +5317,9 @@ Mapping Types --- :class:`dict`
53175317
pair: built-in function; len
53185318

53195319
A :term:`mapping` object maps :term:`hashable` values to arbitrary objects.
5320-
Mappings are mutable objects. There is currently only one standard mapping
5321-
type, the :dfn:`dictionary`. (For other containers see the built-in
5320+
There are currently two standard mapping types, the :dfn:`dictionary` and
5321+
:class:`frozendict`.
5322+
(For other containers see the built-in
53225323
:class:`list`, :class:`set`, and :class:`tuple` classes, and the
53235324
:mod:`collections` module.)
53245325

@@ -5588,10 +5589,9 @@ can be used interchangeably to index the same dictionary entry.
55885589
Dictionaries are now reversible.
55895590

55905591

5591-
.. seealso::
5592-
:class:`types.MappingProxyType` can be used to create a read-only view
5593-
of a :class:`dict`.
5594-
5592+
.. seealso::
5593+
:class:`frozendict` and :class:`types.MappingProxyType` can be used to
5594+
create a read-only view of a :class:`dict`.
55955595

55965596
.. _thread-safety-dict:
55975597

@@ -5839,6 +5839,41 @@ An example of dictionary view usage::
58395839
500
58405840

58415841

5842+
Frozen dictionaries
5843+
-------------------
5844+
5845+
.. class:: frozendict(**kwargs)
5846+
frozendict(mapping, /, **kwargs)
5847+
frozendict(iterable, /, **kwargs)
5848+
5849+
Return a new frozen dictionary initialized from an optional positional
5850+
argument and a possibly empty set of keyword arguments.
5851+
5852+
A :class:`!frozendict` has a similar API to the :class:`dict` API, with the
5853+
following differences:
5854+
5855+
* :class:`!dict` has more methods than :class:`!frozendict`:
5856+
5857+
* :meth:`!__delitem__`
5858+
* :meth:`!__setitem__`
5859+
* :meth:`~dict.clear`
5860+
* :meth:`~dict.pop`
5861+
* :meth:`~dict.popitem`
5862+
* :meth:`~dict.setdefault`
5863+
* :meth:`~dict.update`
5864+
5865+
* A :class:`!frozendict` can be hashed with ``hash(frozendict)`` if all keys and
5866+
values can be hashed.
5867+
5868+
* ``frozendict |= other`` does not modify the :class:`!frozendict` in-place but
5869+
creates a new frozen dictionary.
5870+
5871+
:class:`!frozendict` is not a :class:`!dict` subclass but inherits directly
5872+
from ``object``.
5873+
5874+
.. versionadded:: next
5875+
5876+
58425877
.. _typecontextmanager:
58435878

58445879
Context Manager Types
@@ -6062,6 +6097,7 @@ list is non-exhaustive.
60626097
* :class:`list`
60636098
* :class:`dict`
60646099
* :class:`set`
6100+
* :class:`frozendict`
60656101
* :class:`frozenset`
60666102
* :class:`type`
60676103
* :class:`asyncio.Future`

0 commit comments

Comments
 (0)