8000 Merge branch 'main' of https://github.com/python/cpython into 131769-… · python/cpython@dad0229 · GitHub
[go: up one dir, main page]

Skip to content

Commit dad0229

Browse files
committed
Merge branch 'main' of https://github.com/python/cpython into 131769-wasi-pydebug
2 parents e7e3124 + b1aa515 commit dad0229

File tree

391 files changed

+17530
-3964
lines changed
  • test_tkinter
  • test_ttk
  • test_warnings
  • test_zoneinfo
  • tkinter
  • tomllib
  • unittest
  • urllib
  • venv
  • zipfile
  • zoneinfo
  • Misc
  • Modules
  • Some content is hidden

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

    391 files changed

    +17530
    -3964
    lines changed

    .github/CODEOWNERS

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -188,7 +188,7 @@ Include/internal/pycore_time.h @pganssle @abalkin
    188188

    189189
    # AST
    190190
    Python/ast.c @isidentical @JelleZijlstra @eclips4
    191-
    Python/ast_opt.c @isidentical @eclips4
    191+
    Python/ast_preprocess.c @isidentical @eclips4
    192192
    Parser/asdl.py @isidentical @JelleZijlstra @eclips4
    193193
    Parser/asdl_c.py @isidentical @JelleZijlstra @eclips4
    194194
    Lib/ast.py @isidentical @JelleZijlstra @eclips4

    .github/workflows/jit.yml

    Lines changed: 28 additions & 27 deletions
    Original file line numberDiff line numberDiff line change
    @@ -95,10 +95,10 @@ jobs:
    9595
    with:
    9696
    python-version: '3.11'
    9797

    98+
    # PCbuild downloads LLVM automatically:
    9899
    - name: Windows
    99100
    if: runner.os == 'Windows'
    100101
    run: |
    101-
    choco install llvm --allow-downgrade --no-progress --version ${{ matrix.llvm }}.1.0
    102102
    ./PCbuild/build.bat --experimental-jit ${{ matrix.debug && '-d' || '' }} -p ${{ matrix.architecture }}
    103103
    ./PCbuild/rt.bat ${{ matrix.debug && '-d' || '' }} -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3
    104104
    @@ -126,29 +126,30 @@ jobs:
    126126
    make all --jobs 4
    127127
    ./python -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3
    128128
    129-
    jit-with-disabled-gil:
    130-
    name: Free-Threaded (Debug)
    131-
    needs: interpreter
    132-
    runs-on: ubuntu-24.04
    133-
    timeout-minutes: 90
    134-
    strategy:
    135-
    fail-fast: false
    136-
    matrix:
    137-
    llvm:
    138-
    - 19
    139-
    steps:
    140-
    - uses: actions/checkout@v4
    141-
    with:
    142-
    persist-credentials: false
    143-
    - uses: actions/setup-python@v5
    144-
    with:
    145-
    python-version: '3.11'
    146-
    - name: Build with JIT enabled and GIL disabled
    147-
    run: |
    148-
    sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh ${{ matrix.llvm }}
    149-
    export PATH="$(llvm-config-${{ matrix.llvm }} --bindir):$PATH"
    150-
    ./configure --enable-experimental-jit --with-pydebug --disable-gil
    151-
    make all --jobs 4
    152-
    - name: Run tests
    153-
    run: |
    154-
    ./python -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3
    129+
    # XXX: GH-133171
    130+
    # jit-with-disabled-gil:
    131+
    # name: Free-Threaded (Debug)
    132+
    # needs: interpreter
    133+
    # runs-on: ubuntu-24.04
    134+
    # timeout-minutes: 90
    135+
    # strategy:
    136+
    # fail-fast: false
    137+
    # matrix:
    138+
    # llvm:
    139+
    # - 19
    140+
    # steps:
    141+
    # - uses: actions/checkout@v4
    142+
    # with:
    143+
    # persist-credentials: false
    144+
    # - uses: actions/setup-python@v5
    145+
    # with:
    146+
    # python-version: '3.11'
    147+
    # - name: Build with JIT enabled and GIL disabled
    148+
    # run: |
    149+
    # sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh ${{ matrix.llvm }}
    150+
    # export PATH="$(llvm-config-${{ matrix.llvm }} --bindir):$PATH"
    151+
    # ./configure --enable-experimental-jit --with-pydebug --disable-gil
    152+
    # make all --jobs 4
    153+
    # - name: Run tests
    154+
    # run: |
    155+
    # ./python -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3

    .github/workflows/reusable-context.yml

    Lines changed: 2 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -97,6 +97,8 @@ jobs:
    9797
    run: python Tools/build/compute-changes.py
    9898
    env:
    9999
    GITHUB_DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
    100+
    CCF_TARGET_REF: ${{ github.base_ref || github.event.repository.default_branch }}
    101+
    CCF_HEAD_REF: ${{ github.event.pull_request.head.sha || github.sha }}
    100102

    101103
    - name: Compute hash for config cache key
    102104
    id: config-hash

    .pre-commit-config.yaml

    Lines changed: 5 additions & 5 deletions
    Original file line numberDiff line numberDiff line change
    @@ -1,6 +1,6 @@
    11
    repos:
    22
    - repo: https://github.com/astral-sh/ruff-pre-commit
    3-
    rev: v0.11.6
    3+
    rev: v0.11.8
    44
    hooks:
    55
    - id: ruff
    66
    name: Run Ruff (lint) on Doc/
    @@ -22,14 +22,14 @@ repos:
    2222
    name: Run Ruff (format) on Doc/
    2323
    args: [--check]
    2424
    files: ^Doc/
    25+
    - id: ruff-format
    26+
    name: Run Ruff (format) on Tools/build/check_warnings.py
    27+
    args: [--check, --config=Tools/build/.ruff.toml]
    28+
    files: ^Tools/build/check_warnings.py
    2529

    2630
    - repo: https://github.com/psf/black-pre-commit-mirror
    2731
    rev: 25.1.0
    2832
    hooks:
    29-
    - id: black
    30-
    name: Run Black on Tools/build/check_warnings.py
    31-
    files: ^Tools/build/check_warnings.py
    32-
    args: [--line-length=79]
    3333
    - id: black
    3434
    name: Run Black on Tools/jit/
    3535
    files: ^Tools/jit/

    Doc/c-api/object.rst

    Lines changed: 50 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -613,6 +613,38 @@ Object Protocol
    613613
    614614
    .. versionadded:: 3.14
    615615
    616+
    .. c:function:: int PyUnstable_Object_IsUniqueReferencedTemporary(PyObject *obj)
    617+
    618+
    Check if *obj* is a unique temporary object.
    619+
    Returns ``1`` if *obj* is known to be a unique temporary object,
    620+
    and ``0`` otherwise. This function cannot fail, but the check is
    621+
    conservative, and may return ``0`` in some cases even if *obj* is a unique
    622+
    temporary object.
    623+
    624+
    If an object is a unique temporary, it is guaranteed that the current code
    625+
    has the only reference to the object. For arguments to C functions, this
    626+
    should be used instead of checking if the reference count is ``1``. Starting
    627+
    with Python 3.14, the interpreter internally avoids some reference count
    628+
    modifications when loading objects onto the operands stack by
    629+
    :term:`borrowing <borrowed reference>` references when possible, which means
    630+
    that a reference count of ``1`` by itself does not guarantee that a function
    631+
    argument uniquely referenced.
    632+
    633+
    In the example below, ``my_func`` is called with a unique temporary object
    634+
    as its argument::
    635+
    636+
    my_func([1, 2, 3])
    637+
    638+
    In the example below, ``my_func`` is **not** called with a unique temporary
    639+
    object as its argument, even if its refcount is ``1``::
    640+
    641+
    my_list = [1, 2, 3]
    642+
    my_func(my_list)
    643+
    644+
    See also the function :c:func:`Py_REFCNT`.
    645+
    646+
    .. versionadded:: 3.14
    647+
    616648
    .. c:function:: int PyUnstable_IsImmortal(PyObject *obj)
    617649
    618650
    This function returns non-zero if *obj* is :term:`immortal`, and zero
    @@ -705,3 +737,21 @@ Object Protocol
    705737
    caller must hold a :term:`strong reference` to *obj* when calling this.
    706738
    707739
    .. versionadded:: 3.14
    740+
    741+
    .. c:function:: int PyUnstable_Object_IsUniquelyReferenced(PyObject *op)
    742+
    743+
    Determine if *op* only has one reference.
    744+
    745+
    On GIL-enabled builds, this function is equivalent to
    746+
    :c:expr:`Py_REFCNT(op) == 1`.
    747+
    748+
    On a :term:`free threaded <free threading>` build, this checks if *op*'s
    749+
    :term:`reference count` is equal to one and additionally checks if *op*
    750+
    is only used by this thread. :c:expr:`Py_REFCNT(op) == 1` is **not**
    751+
    thread-safe on free threaded builds; prefer this function.
    752+
    753+
    The caller must hold an :term:`attached thread state`, despite the fact
    754+
    that this function doesn't call into the Python interpreter. This function
    755+
    cannot fail.
    756+
    757+
    .. versionadded:: 3.14

    Doc/c-api/refcounting.rst

    Lines changed: 9 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -23,6 +23,15 @@ of Python objects.
    2323
    2424
    Use the :c:func:`Py_SET_REFCNT()` function to set an object reference count.
    2525
    26+
    .. note::
    27+
    28+
    On :term:`free threaded <free threading>` builds of Python, returning 1
    29+
    isn't sufficient to determine if it's safe to treat *o* as having no
    30+
    access by other threads. Use :c:func:`PyUnstable_Object_IsUniquelyReferenced`
    31+
    for that instead.
    32+
    33+
    See also the function :c:func:`PyUnstable_Object_IsUniqueReferencedTemporary()`.
    34+
    2635
    .. versionchanged:: 3.10
    2736
    :c:func:`Py_REFCNT()` is changed to the inline static function.
    2837

    Doc/deprecations/index.rst

    Lines changed: 6 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -5,11 +5,17 @@ Deprecations
    55

    66
    .. include:: pending-removal-in-3.16.rst
    77

    8+
    .. include:: pending-removal-in-3.17.rst
    9+
    10+
    .. include:: pending-removal-in-3.19.rst
    11+
    812
    .. include:: pending-removal-in-future.rst
    913

    1014
    C API deprecations
    1115
    ------------------
    1216

    1317
    .. include:: c-api-pending-removal-in-3.15.rst
    1418

    19+
    .. include:: c-api-pending-removal-in-3.18.rst
    20+
    1521
    .. include:: c-api-pending-removal-in-future.rst

    Doc/deprecations/pending-removal-in-3.16.rst

    Lines changed: 6 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -61,6 +61,12 @@ Pending removal in Python 3.16
    6161
    * Calling the Python implementation of :func:`functools.reduce` with *function*
    6262
    or *sequence* as keyword arguments has been deprecated since Python 3.14.
    6363

    64+
    * :mod:`logging`:
    65+
    66+
    Support for custom logging handlers with the *strm* argument is deprecated
    67+
    and scheduled for removal in Python 3.16. Define handlers with the *stream*
    68+
    argument instead. (Contributed by Mariusz Felisiak in :gh:`115032`.)
    69+
    6470
    * :mod:`mimetypes`:
    6571

    6672
    * Valid extensions start with a '.' or are empty for
    Lines changed: 10 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -0,0 +1,10 @@
    1+
    Pending removal in Python 3.17
    2+
    ------------------------------
    3+
    4+
    * :mod:`typing`:
    5+
    6+
    - Before Python 3.14, old-style unions were implemented using the private class
    7+
    ``typing._UnionGenericAlias``. This class is no longer needed for the implementation,
    8+
    but it has been retained for backward compatibility, with removal scheduled for Python
    9+
    3.17. Users should use documented introspection helpers like :func:`typing.get_origin`
    10+
    and :func:`typing.get_args` instead of relying on private implementation details.
    Lines changed: 8 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -0,0 +1,8 @@
    1+
    Pending removal in Python 3.19
    2+
    ------------------------------
    3+
    4+
    * :mod:`ctypes`:
    5+
    6+
    * Implicitly switching to the MSVC-compatible struct layout by setting
    7+
    :attr:`~ctypes.Structure._pack_` but not :attr:`~ctypes.Structure._layout_`
    8+
    on non-Windows platforms.

    Doc/howto/regex.rst

    Lines changed: 4 additions & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -738,9 +738,12 @@ given location, they can obviously be matched an infinite number of times.
    738738
    different: ``\A`` still matches only at the beginning of the string, but ``^``
    739739
    may match at any location inside the string that follows a newline character.
    740740

    741-
    ``\Z``
    741+
    ``\z``
    742742
    Matches only at the end of the string.
    743743

    744+
    ``\Z``
    745+
    The same as ``\z``. For compatibility with old Python versions.
    746+
    744747
    ``\b``
    745748
    Word boundary. This is a zero-width assertion that matches only at the
    746749
    beginning or end of a word. A word is defined as a sequence of alphanumeric

    Doc/library/annotationlib.rst

    Lines changed: 91 additions & 13 deletions
    Original file line numberDiff line numberDiff line change
    @@ -40,7 +40,7 @@ The :func:`get_annotations` function is the main entry point for
    4040
    retrieving annotations. Given a function, class, or module, it returns
    4141
    an annotations dictionary in the requested format. This module also provides
    4242
    functionality for working directly with the :term:`annotate function`
    43-
    that is used to evaluate annotations, such as :func:`get_annotate_function`
    43+
    that is used to evaluate annotations, such as :func:`get_annotate_from_class_namespace`
    4444
    and :func:`call_annotate_function`, as well as the
    4545
    :func:`call_evaluate_function` function for working with
    4646
    :term:`evaluate functions <evaluate function>`.
    @@ -132,7 +132,7 @@ Classes
    132132

    133133
    Values are real annotation values (as per :attr:`Format.VALUE` format)
    134134
    for defined values, and :class:`ForwardRef` proxies for undefined
    135-
    values. Real objects may contain references to, :class:`ForwardRef`
    135+
    values. Real objects may contain references to :class:`ForwardRef`
    136136
    proxy objects.
    137137

    138138
    .. attribute:: STRING
    @@ -172,14 +172,21 @@ Classes
    172172
    :class:`~ForwardRef`. The string may not be exactly equiv 10000 alent
    173173
    to the original source.
    174174

    175-
    .. method:: evaluate(*, owner=None, globals=None, locals=None, type_params=None)
    175+
    .. method:: evaluate(*, owner=None, globals=None, locals=None, type_params=None, format=Format.VALUE)
    176176

    177177
    Evaluate the forward reference, returning its value.
    178178

    179-
    This may throw an exception, such as :exc:`NameError`, if the forward
    179+
    If the *format* argument is :attr:`~Format.VALUE` (the default),
    180+
    this method may throw an exception, such as :exc:`NameError`, if the forward
    180181
    reference refers to a name that cannot be resolved. The arguments to this
    181182
    method can be used to provide bindings for names that would otherwise
    182-
    be undefined.
    183+
    be undefined. If the *format* argument is :attr:`~Format.FORWARDREF`,
    184+
    the method will never throw an exception, but may return a :class:`~ForwardRef`
    185+
    instance. For example, if the forward reference object contains the code
    186+
    ``list[undefined]``, where ``undefined`` is a name that is not defined,
    187+
    evaluating it with the :attr:`~Format.FORWARDREF` format will return
    188+
    ``list[ForwardRef('undefined')]``. If the *format* argument is
    189+
    :attr:`~Format.STRING`, the method will return :attr:`~ForwardRef.__forward_arg__`.
    183190

    184191
    The *owner* parameter provides the preferred mechanism for passing scope
    185192
    information to this method. The owner of a :class:`~ForwardRef` is the
    @@ -300,15 +307,13 @@ Functions
    300307

    301308
    .. versionadded:: 3.14
    302309

    303-
    .. function:: get_annotate_function(obj)
    310+
    .. function:: get_annotate_from_class_namespace(namespace)
    304311

    305-
    Retrieve the :term:`annotate function` for *obj*. Return :const:`!None`
    306-
    if *obj* does not have an annotate function. *obj* may be a class, function,
    307-
    module, or a namespace dictionary for a class. The last case is useful during
    308-
    class creation, e.g. in the ``__new__`` method of a metaclass.
    309-
    310-
    This is usually equivalent to accessing the :attr:`~object.__annotate__`
    311-
    attribute of *obj*, but access through this public function is preferred.
    312+
    Retrieve the :term:`annotate function` from a class namespace dictionary *namespace*.
    313+
    Return :const:`!None` if the namespace does not contain an annotate function.
    314+
    This is primarily useful before the class has been fully created (e.g., in a metaclass);
    315+
    after the class exists, the annotate function can be retrieved with ``cls.__annotate__``.
    316+
    See :ref:`below <annotationlib-metaclass>` for an example using this function in a metaclass.
    312317

    313318
    .. versionadded:: 3.14
    314319

    @@ -407,3 +412,76 @@ Functions
    407412

    408413
    .. versionadded:: 3.14
    409414

    415+
    416+
    Recipes
    417+
    -------
    418+
    419+
    .. _annotationlib-metaclass:
    420+
    421+
    Using annotations in a metaclass
    422+
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    423+
    424+
    A :ref:`metaclass <metaclasses>` may want to inspect or even modify the annotations
    425+
    in a class body during class creation. Doing so requires retrieving annotations
    426+
    from the class namespace dictionary. For classes created with
    427+
    ``from __future__ import annotations``, the annotations will be in the ``__annotations__``
    428+
    key of the dictionary. For other classes with annotations,
    429+
    :func:`get_annotate_from_class_namespace` can be used to get the
    430+
    annotate function, and :func:`call_annotate_function` can be used to call it and
    431+
    retrieve the annotations. Using the :attr:`~Format.FORWARDREF` format will usually
    432+
    be best, because this allows the annotations to refer to names that cannot yet be
    433+
    resolved when the class is created.
    434+
    435+
    To modify the annotations, it is best to create a wrapper annotate function
    436+
    that calls the original annotate function, makes any necessary adjustments, and
    437+
    returns the result.
    438+
    439+
    Below is an example of a metaclass that filters out all :class:`typing.ClassVar`
    440+
    annotations from the class and puts them in a separate attribute:
    441+
    442+
    .. code-block:: python
    443+
    444+
    import annotationlib
    445+
    import typing
    446+
    447+
    class ClassVarSeparator(type):
    448+
    def __new__(mcls, name, bases, ns):
    449+
    if "__annotations__" in ns: # from __future__ import annotations
    450+
    annotations = ns["__annotations__"]
    451+
    classvar_keys = {
    452+
    key for key, value in annotations.items()
    453+
    # Use string comparison for simplicity; a more robust solution
    454+
    # could use annotationlib.ForwardRef.evaluate
    455+
    if value.startswith("ClassVar")
    456+
    }
    457+
    classvars = {key: annotations[key] for key in classvar_keys}
    458+
    ns["__annotations__"] = {
    459+
    key: value for key, value in annotations.items()
    460+
    if key not in classvar_keys
    461+
    }
    462+
    wrapped_annotate = None
    463+
    elif annotate := annotationlib.get_annotate_from_class_namespace(ns):
    464+
    annotations = annotationlib.call_annotate_function(
    465+
    annotate, format=annotationlib.Format.FORWARDREF
    466+
    )
    467+
    classvar_keys = {
    468+
    key for key, value in annotations.items()
    469+
    if typing.get_origin(value) is typing.ClassVar
    470+
    }
    471+
    classvars = {key: annotations[key] for key in classvar_keys}
    472+
    473+
    def wrapped_annotate(format):
    474+
    annos = annotationlib.call_annotate_function(annotate, format, owner=typ)
    475+
    return {key: value for key, value in annos.items() if key not in classvar_keys}
    476+
    477+
    else: # no annotations
    478+
    classvars = {}
    479+
    wrapped_annotate = None
    480+
    typ = super().__new__(mcls, name, bases, ns)
    481+
    482+
    if wrapped_annotate is not None:
    483+
    # Wrap the original __annotate__ with a wrapper that removes ClassVars
    484+
    typ.__annotate__ = wrapped_annotate
    485+
    typ.classvars = classvars # Store the ClassVars in a separate attribute
    486+
    return typ
    487+

    0 commit comments

    Comments
     (0)
    0