resolve conflicts with GH-19611

This commit is contained in:
Domenico Ragusa 2020-05-28 18:46:28 +02:00
commit 6d721a0ee1
631 changed files with 57242 additions and 19049 deletions

View File

@ -8,18 +8,18 @@ Build Status
+ `Stable buildbots <http://buildbot.python.org/3.x.stable/>`_
- 3.9
+ `Stable buildbots <http://buildbot.python.org/3.9.stable/>`_
- 3.8
+ `Stable buildbots <http://buildbot.python.org/3.8.stable/>`_
- 3.7
+ `Stable buildbots <http://buildbot.python.org/3.7.stable/>`_
- 3.6
+ `Stable buildbots <http://buildbot.python.org/3.6.stable/>`_
- 2.7
+ `Stable buildbots <http://buildbot.python.org/2.7.stable/>`_
Thank You
---------

40
.github/problem-matchers/sphinx.json vendored Normal file
View File

@ -0,0 +1,40 @@
{
"problemMatcher": [
{
"owner": "sphinx-problem-matcher",
"pattern": [
{
"regexp": "^(.*):(\\d+):\\s+(\\w*):\\s+(.*)$",
"file": 1,
"line": 2,
"severity": 3,
"message": 4
}
]
},
{
"owner": "sphinx-problem-matcher-loose",
"pattern": [
{
"_comment": "A bit of a looser pattern, doesn't look for line numbers, just looks for file names relying on them to start with / and end with .rst",
"regexp": "(\/.*\\.rst):\\s+(\\w*):\\s+(.*)$",
"file": 1,
"severity": 2,
"message": 3
}
]
},
{
"owner": "sphinx-problem-matcher-loose-no-severity",
"pattern": [
{
"_comment": "Looks for file names ending with .rst and line numbers but without severity",
"regexp": "^(.*\\.rst):(\\d+):(.*)$",
"file": 1,
"line": 2,
"message": 3
}
]
}
]
}

View File

@ -1,33 +1,46 @@
name: Tests
# bpo-40548: "paths-ignore" is not used to skip documentation-only PRs, because
# it prevents to mark a job as mandatory. A PR cannot be merged if a job is
# mandatory but not scheduled because of "paths-ignore".
on:
push:
branches:
- master
- 3.9
- 3.8
- 3.7
paths-ignore:
- 'Doc/**'
- 'Misc/**'
- '**/*.md'
- '**/*.rst'
pull_request:
branches:
- master
- 3.9
- 3.8
- 3.7
paths-ignore:
- 'Doc/**'
- 'Misc/**'
- '**/*.md'
- '**/*.rst'
jobs:
check_source:
name: 'Check for source changes'
runs-on: ubuntu-latest
outputs:
run_tests: ${{ steps.check.outputs.run_tests }}
steps:
- uses: actions/checkout@v2
- name: Check for source changes
id: check
run: |
if [ -z "GITHUB_BASE_REF" ]; then
echo '::set-output name=run_tests::true'
else
git fetch origin $GITHUB_BASE_REF --depth=1
git diff --name-only origin/$GITHUB_BASE_REF... | grep -qvE '(\.rst$|^Doc|^Misc)' && echo '::set-output name=run_tests::true' || true
fi
build_win32:
name: 'Windows (x86)'
runs-on: windows-latest
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Build CPython
run: .\PCbuild\build.bat -e -p Win32
- name: Display build info
@ -38,8 +51,10 @@ jobs:
build_win_amd64:
name: 'Windows (x64)'
runs-on: windows-latest
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Build CPython
run: .\PCbuild\build.bat -e -p x64
- name: Display build info
@ -50,8 +65,10 @@ jobs:
build_macos:
name: 'macOS'
runs-on: macos-latest
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Configure CPython
run: ./configure --with-pydebug --with-openssl=/usr/local/opt/openssl --prefix=/opt/python-dev
- name: Build CPython
@ -64,10 +81,12 @@ jobs:
build_ubuntu:
name: 'Ubuntu'
runs-on: ubuntu-latest
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
env:
OPENSSL_VER: 1.1.1f
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Install Dependencies
run: sudo ./.github/workflows/posix-deps-apt.sh
- name: 'Restore OpenSSL build'

View File

@ -4,6 +4,7 @@ on:
push:
branches:
- master
- 3.9
- 3.8
- 3.7
paths:
@ -11,6 +12,7 @@ on:
pull_request:
branches:
- master
- 3.9
- 3.8
- 3.7
paths:
@ -21,7 +23,7 @@ jobs:
name: 'Windows (x86) Installer'
runs-on: windows-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Build CPython installer
run: .\Tools\msi\build.bat -x86
@ -29,6 +31,6 @@ jobs:
name: 'Windows (x64) Installer'
runs-on: windows-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Build CPython installer
run: .\Tools\msi\build.bat -x64

View File

@ -4,6 +4,7 @@ on:
push:
branches:
- master
- 3.9
- 3.8
- 3.7
paths-ignore:
@ -12,6 +13,7 @@ on:
#pull_request:
# branches:
# - master
# - 3.9
# - 3.8
# - 3.7
# paths-ignore:
@ -25,7 +27,7 @@ jobs:
env:
OPENSSL_VER: 1.1.1f
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Install Dependencies
run: sudo ./.github/workflows/posix-deps-apt.sh
- name: 'Restore OpenSSL build'
@ -48,6 +50,7 @@ jobs:
./python -m venv .venv
source ./.venv/bin/activate
python -m pip install -U coverage
python -m pip install -r Misc/requirements-test.txt
python -m test.pythoninfo
- name: 'Tests with coverage'
run: >
@ -73,7 +76,7 @@ jobs:
name: 'Ubuntu (C Coverage)'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Install Dependencies
run: sudo ./.github/workflows/posix-deps-apt.sh
- name: Configure CPython

View File

@ -4,6 +4,7 @@ on:
#push:
# branches:
# - master
# - 3.9
# - 3.8
# - 3.7
# paths:
@ -11,6 +12,7 @@ on:
pull_request:
branches:
- master
- 3.9
- 3.8
- 3.7
paths:
@ -22,7 +24,9 @@ jobs:
name: 'Docs'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Register Sphinx problem matcher
run: echo "::add-matcher::.github/problem-matchers/sphinx.json"
- name: 'Install Dependencies'
run: sudo ./.github/workflows/posix-deps-apt.sh && sudo apt-get install wamerican
- name: 'Configure CPython'
@ -32,7 +36,7 @@ jobs:
- name: 'Install build dependencies'
run: make -C Doc/ PYTHON=../python venv
- name: 'Build documentation'
run: xvfb-run make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W -j4" doctest suspicious html
run: xvfb-run make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W --keep-going -j4" doctest suspicious html
- name: 'Upload'
uses: actions/upload-artifact@v1
with:

View File

@ -87,6 +87,7 @@ matrix:
# Need a venv that can parse covered code.
- ./python -m venv venv
- ./venv/bin/python -m pip install -U coverage
- ./venv/bin/python -m pip install -r Misc/requirements-test.txt
- ./venv/bin/python -m test.pythoninfo
script:
# Skip tests that re-run the entire test suite.

View File

@ -144,7 +144,7 @@ Vectorcall Support API
However, the function ``PyVectorcall_NARGS`` should be used to allow
for future extensions.
This function is not part of the `limited API <stable>`_.
This function is not part of the :ref:`limited API <stable>`.
.. versionadded:: 3.8
@ -158,7 +158,7 @@ Vectorcall Support API
This is mostly useful to check whether or not *op* supports vectorcall,
which can be done by checking ``PyVectorcall_Function(op) != NULL``.
This function is not part of the `limited API <stable>`_.
This function is not part of the :ref:`limited API <stable>`.
.. versionadded:: 3.8
@ -172,7 +172,7 @@ Vectorcall Support API
It does not check the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag
and it does not fall back to ``tp_call``.
This function is not part of the `limited API <stable>`_.
This function is not part of the :ref:`limited API <stable>`.
.. versionadded:: 3.8
@ -256,7 +256,7 @@ please see individual documentation for details.
Return the result of the call on success, or raise an exception and return
*NULL* on failure.
This function is not part of the `limited API <stable>`_.
This function is not part of the :ref:`limited API <stable>`.
.. versionadded:: 3.9
@ -343,7 +343,7 @@ please see individual documentation for details.
Return the result of the call on success, or raise an exception and return
*NULL* on failure.
This function is not part of the `limited API <stable>`_.
This function is not part of the :ref:`limited API <stable>`.
.. versionadded:: 3.9
@ -357,7 +357,7 @@ please see individual documentation for details.
Return the result of the call on success, or raise an exception and return
*NULL* on failure.
This function is not part of the `limited API <stable>`_.
This function is not part of the :ref:`limited API <stable>`.
.. versionadded:: 3.9
@ -372,7 +372,7 @@ please see individual documentation for details.
Return the result of the call on success, or raise an exception and return
*NULL* on failure.
This function is not part of the `limited API <stable>`_.
This function is not part of the :ref:`limited API <stable>`.
.. versionadded:: 3.9
@ -388,7 +388,7 @@ please see individual documentation for details.
already has a dictionary ready to use for the keyword arguments,
but not a tuple for the positional arguments.
This function is not part of the `limited API <stable>`_.
This function is not part of the :ref:`limited API <stable>`.
.. versionadded:: 3.9
@ -410,7 +410,7 @@ please see individual documentation for details.
Return the result of the call on success, or raise an exception and return
*NULL* on failure.
This function is not part of the `limited API <stable>`_.
This function is not part of the :ref:`limited API <stable>`.
.. versionadded:: 3.9

View File

@ -1004,6 +1004,8 @@ Private provisional API:
* :c:member:`PyConfig._init_main`: if set to 0,
:c:func:`Py_InitializeFromConfig` stops at the "Core" initialization phase.
* :c:member:`PyConfig._isolated_interpreter`: if non-zero,
disallow threads, subprocesses and fork.
.. c:function:: PyStatus _Py_InitializeMain(void)

View File

@ -129,9 +129,8 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
single: OverflowError (built-in exception)
Return a C :c:type:`long` representation of *obj*. If *obj* is not an
instance of :c:type:`PyLongObject`, first call its :meth:`__index__` or
:meth:`__int__` method (if present) to convert it to a
:c:type:`PyLongObject`.
instance of :c:type:`PyLongObject`, first call its :meth:`__index__` method
(if present) to convert it to a :c:type:`PyLongObject`.
Raise :exc:`OverflowError` if the value of *obj* is out of range for a
:c:type:`long`.
@ -141,16 +140,15 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. versionchanged:: 3.8
Use :meth:`__index__` if available.
.. deprecated:: 3.8
Using :meth:`__int__` is deprecated.
.. versionchanged:: 3.10
This function will no longer use :meth:`__int__`.
.. c:function:: long PyLong_AsLongAndOverflow(PyObject *obj, int *overflow)
Return a C :c:type:`long` representation of *obj*. If *obj* is not an
instance of :c:type:`PyLongObject`, first call its :meth:`__index__` or
:meth:`__int__` method (if present) to convert it to a
:c:type:`PyLongObject`.
instance of :c:type:`PyLongObject`, first call its :meth:`__index__`
method (if present) to convert it to a :c:type:`PyLongObject`.
If the value of *obj* is greater than :const:`LONG_MAX` or less than
:const:`LONG_MIN`, set *\*overflow* to ``1`` or ``-1``, respectively, and
@ -162,8 +160,8 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. versionchanged:: 3.8
Use :meth:`__index__` if available.
.. deprecated:: 3.8
Using :meth:`__int__` is deprecated.
.. versionchanged:: 3.10
This function will no longer use :meth:`__int__`.
.. c:function:: long long PyLong_AsLongLong(PyObject *obj)
@ -172,9 +170,8 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
single: OverflowError (built-in exception)
Return a C :c:type:`long long` representation of *obj*. If *obj* is not an
instance of :c:type:`PyLongObject`, first call its :meth:`__index__` or
:meth:`__int__` method (if present) to convert it to a
:c:type:`PyLongObject`.
instance of :c:type:`PyLongObject`, first call its :meth:`__index__` method
(if present) to convert it to a :c:type:`PyLongObject`.
Raise :exc:`OverflowError` if the value of *obj* is out of range for a
:c:type:`long long`.
@ -184,16 +181,15 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. versionchanged:: 3.8
Use :meth:`__index__` if available.
.. deprecated:: 3.8
Using :meth:`__int__` is deprecated.
.. versionchanged:: 3.10
This function will no longer use :meth:`__int__`.
.. c:function:: long long PyLong_AsLongLongAndOverflow(PyObject *obj, int *overflow)
Return a C :c:type:`long long` representation of *obj*. If *obj* is not an
instance of :c:type:`PyLongObject`, first call its :meth:`__index__` or
:meth:`__int__` method (if present) to convert it to a
:c:type:`PyLongObject`.
instance of :c:type:`PyLongObject`, first call its :meth:`__index__` method
(if present) to convert it to a :c:type:`PyLongObject`.
If the value of *obj* is greater than :const:`LLONG_MAX` or less than
:const:`LLONG_MIN`, set *\*overflow* to ``1`` or ``-1``, respectively,
@ -207,8 +203,8 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. versionchanged:: 3.8
Use :meth:`__index__` if available.
.. deprecated:: 3.8
Using :meth:`__int__` is deprecated.
.. versionchanged:: 3.10
This function will no longer use :meth:`__int__`.
.. c:function:: Py_ssize_t PyLong_AsSsize_t(PyObject *pylong)
@ -278,10 +274,9 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: unsigned long PyLong_AsUnsignedLongMask(PyObject *obj)
Return a C :c:type:`unsigned long` representation of *obj*. If *obj*
is not an instance of :c:type:`PyLongObject`, first call its
:meth:`__index__` or :meth:`__int__` method (if present) to convert
it to a :c:type:`PyLongObject`.
Return a C :c:type:`unsigned long` representation of *obj*. If *obj* is not
an instance of :c:type:`PyLongObject`, first call its :meth:`__index__`
method (if present) to convert it to a :c:type:`PyLongObject`.
If the value of *obj* is out of range for an :c:type:`unsigned long`,
return the reduction of that value modulo ``ULONG_MAX + 1``.
@ -292,16 +287,16 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. versionchanged:: 3.8
Use :meth:`__index__` if available.
.. deprecated:: 3.8
Using :meth:`__int__` is deprecated.
.. versionchanged:: 3.10
This function will no longer use :meth:`__int__`.
.. c:function:: unsigned long long PyLong_AsUnsignedLongLongMask(PyObject *obj)
Return a C :c:type:`unsigned long long` representation of *obj*. If *obj*
is not an instance of :c:type:`PyLongObject`, first call its
:meth:`__index__` or :meth:`__int__` method (if present) to convert
it to a :c:type:`PyLongObject`.
:meth:`__index__` method (if present) to convert it to a
:c:type:`PyLongObject`.
If the value of *obj* is out of range for an :c:type:`unsigned long long`,
return the reduction of that value modulo ``ULLONG_MAX + 1``.
@ -312,8 +307,8 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. versionchanged:: 3.8
Use :meth:`__index__` if available.
.. deprecated:: 3.8
Using :meth:`__int__` is deprecated.
.. versionchanged:: 3.10
This function will no longer use :meth:`__int__`.
.. c:function:: double PyLong_AsDouble(PyObject *pylong)

View File

@ -256,6 +256,10 @@ Number Protocol
Returns the *o* converted to a Python int on success or ``NULL`` with a
:exc:`TypeError` exception raised on failure.
.. versionchanged:: 3.10
The result always has exact type :class:`int`. Previously, the result
could have been an instance of a subclass of ``int``.
.. c:function:: PyObject* PyNumber_ToBase(PyObject *n, int base)

View File

@ -62,12 +62,15 @@ the definition of all other Python objects.
See documentation of :c:type:`PyVarObject` above.
.. c:macro:: Py_TYPE(o)
.. c:function:: PyTypeObject* Py_TYPE(const PyObject *o)
This macro is used to access the :attr:`ob_type` member of a Python object.
It expands to::
Get the type of the Python object *o*.
(((PyObject*)(o))->ob_type)
Return a borrowed reference.
.. versionchanged:: 3.10
:c:func:`Py_TYPE()` is changed to the inline static function.
Use :c:func:`Py_SET_TYPE()` to set an object type.
.. c:function:: int Py_IS_TYPE(PyObject *o, PyTypeObject *type)
@ -85,13 +88,13 @@ the definition of all other Python objects.
.. versionadded:: 3.9
.. c:macro:: Py_REFCNT(o)
.. c:function:: Py_ssize_t Py_REFCNT(const PyObject *o)
This macro is used to access the :attr:`ob_refcnt` member of a Python
object.
It expands to::
Get the reference count of the Python object *o*.
(((PyObject*)(o))->ob_refcnt)
.. versionchanged:: 3.10
:c:func:`Py_REFCNT()` is changed to the inline static function.
Use :c:func:`Py_SET_REFCNT()` to set an object reference count.
.. c:function:: void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt)
@ -101,12 +104,13 @@ the definition of all other Python objects.
.. versionadded:: 3.9
.. c:macro:: Py_SIZE(o)
.. c:function:: Py_ssize_t Py_SIZE(const PyVarObject *o)
This macro is used to access the :attr:`ob_size` member of a Python object.
It expands to::
Get the size of the Python object *o*.
(((PyVarObject*)(o))->ob_size)
.. versionchanged:: 3.10
:c:func:`Py_SIZE()` is changed to the inline static function.
Use :c:func:`Py_SET_SIZE()` to set an object size.
.. c:function:: void Py_SET_SIZE(PyVarObject *o, Py_ssize_t size)
@ -147,23 +151,56 @@ Implementing functions and methods
value of the function as exposed in Python. The function must return a new
reference.
The function signature is::
PyObject *PyCFunction(PyObject *self,
PyObject *args);
.. c:type:: PyCFunctionWithKeywords
Type of the functions used to implement Python callables in C
with signature :const:`METH_VARARGS | METH_KEYWORDS`.
The function signature is::
PyObject *PyCFunctionWithKeywords(PyObject *self,
PyObject *args,
PyObject *kwargs);
.. c:type:: _PyCFunctionFast
Type of the functions used to implement Python callables in C
with signature :const:`METH_FASTCALL`.
The function signature is::
PyObject *_PyCFunctionFast(PyObject *self,
PyObject *const *args,
Py_ssize_t nargs);
.. c:type:: _PyCFunctionFastWithKeywords
Type of the functions used to implement Python callables in C
with signature :const:`METH_FASTCALL | METH_KEYWORDS`.
The function signature is::
PyObject *_PyCFunctionFastWithKeywords(PyObject *self,
PyObject *const *args,
Py_ssize_t nargs,
PyObject *kwnames);
.. c:type:: PyCMethod
Type of the functions used to implement Python callables in C
with signature :const:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS`.
The function signature is::
PyObject *PyCMethod(PyObject *self,
PyTypeObject *defining_class,
PyObject *const *args,
Py_ssize_t nargs,
PyObject *kwnames)
.. versionadded:: 3.9
.. c:type:: PyMethodDef
@ -197,9 +234,7 @@ The :attr:`ml_flags` field is a bitfield which can include the following flags.
The individual flags indicate either a calling convention or a binding
convention.
There are four basic calling conventions for positional arguments
and two of them can be combined with :const:`METH_KEYWORDS` to support
also keyword arguments. So there are a total of 6 calling conventions:
There are these calling conventions:
.. data:: METH_VARARGS
@ -250,6 +285,19 @@ also keyword arguments. So there are a total of 6 calling conventions:
.. versionadded:: 3.7
.. data:: METH_METHOD | METH_FASTCALL | METH_KEYWORDS
Extension of :const:`METH_FASTCALL | METH_KEYWORDS` supporting the *defining
class*, that is, the class that contains the method in question.
The defining class might be a superclass of ``Py_TYPE(self)``.
The method needs to be of type :c:type:`PyCMethod`, the same as for
``METH_FASTCALL | METH_KEYWORDS`` with ``defining_class`` argument added after
``self``.
.. versionadded:: 3.9
.. data:: METH_NOARGS
Methods without parameters don't need to check whether arguments are given if
@ -380,9 +428,11 @@ Accessing attributes of extension types
Heap allocated types (created using :c:func:`PyType_FromSpec` or similar),
``PyMemberDef`` may contain definitions for the special members
``__dictoffset__`` and ``__weaklistoffset__``, corresponding to
:c:member:`~PyTypeObject.tp_dictoffset` and
:c:member:`~PyTypeObject.tp_weaklistoffset` in type objects.
``__dictoffset__``, ``__weaklistoffset__`` and ``__vectorcalloffset__``,
corresponding to
:c:member:`~PyTypeObject.tp_dictoffset`,
:c:member:`~PyTypeObject.tp_weaklistoffset` and
:c:member:`~PyTypeObject.tp_vectorcall_offset` in type objects.
These must be defined with ``T_PYSSIZET`` and ``READONLY``, for example::
static PyMemberDef spam_type_members[] = {

View File

@ -109,6 +109,30 @@ Type Objects
.. versionadded:: 3.4
.. c:function:: PyObject* PyType_GetModule(PyTypeObject *type)
Return the module object associated with the given type when the type was
created using :c:func:`PyType_FromModuleAndSpec`.
If no module is associated with the given type, sets :py:class:`TypeError`
and returns ``NULL``.
.. versionadded:: 3.9
.. c:function:: void* PyType_GetModuleState(PyTypeObject *type)
Return the state of the module object associated with the given type.
This is a shortcut for calling :c:func:`PyModule_GetState()` on the result
of :c:func:`PyType_GetModule`.
If no module is associated with the given type, sets :py:class:`TypeError`
and returns ``NULL``.
If the *type* has an associated module but its state is ``NULL``,
returns ``NULL`` without setting an exception.
.. versionadded:: 3.9
Creating Heap-Allocated Types
.............................
@ -116,7 +140,7 @@ Creating Heap-Allocated Types
The following functions and structs are used to create
:ref:`heap types <heap-types>`.
.. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
.. c:function:: PyObject* PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
Creates and returns a heap type object from the *spec*
(:const:`Py_TPFLAGS_HEAPTYPE`).
@ -127,8 +151,18 @@ The following functions and structs are used to create
If *bases* is ``NULL``, the *Py_tp_base* slot is used instead.
If that also is ``NULL``, the new type derives from :class:`object`.
The *module* must be a module object or ``NULL``.
If not ``NULL``, the module is associated with the new type and can later be
retreived with :c:func:`PyType_GetModule`.
This function calls :c:func:`PyType_Ready` on the new type.
.. versionadded:: 3.9
.. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
Equivalent to ``PyType_FromModuleAndSpec(NULL, spec, bases)``.
.. versionadded:: 3.3
.. c:function:: PyObject* PyType_FromSpec(PyType_Spec *spec)
@ -194,6 +228,7 @@ The following functions and structs are used to create
* :c:member:`~PyTypeObject.tp_dictoffset`
(see :ref:`PyMemberDef <pymemberdef-offsets>`)
* :c:member:`~PyTypeObject.tp_vectorcall_offset`
(see :ref:`PyMemberDef <pymemberdef-offsets>`)
* :c:member:`~PyBufferProcs.bf_getbuffer`
* :c:member:`~PyBufferProcs.bf_releasebuffer`

View File

@ -1223,11 +1223,25 @@ and :c:type:`PyType_Type` effectively act as defaults.)
but the instance has no strong reference to the elements inside it, as they
are allowed to be removed even if the instance is still alive).
Note that :c:func:`Py_VISIT` requires the *visit* and *arg* parameters to
:c:func:`local_traverse` to have these specific names; don't name them just
anything.
Heap-allocated types (:const:`Py_TPFLAGS_HEAPTYPE`, such as those created
with :c:func:`PyType_FromSpec` and similar APIs) hold a reference to their
type. Their traversal function must therefore either visit
:c:func:`Py_TYPE(self) <Py_TYPE>`, or delegate this responsibility by
calling ``tp_traverse`` of another heap-allocated type (such as a
heap-allocated superclass).
If they do not, the type object may not be garbage-collected.
.. versionchanged:: 3.9
Heap-allocated types are expected to visit ``Py_TYPE(self)`` in
``tp_traverse``. In earlier versions of Python, due to
`bug 40217 <https://bugs.python.org/issue40217>`_, doing this
may lead to crashes in subclasses.
**Inheritance:**
Group: :const:`Py_TPFLAGS_HAVE_GC`, :attr:`tp_traverse`, :attr:`tp_clear`

View File

@ -14,7 +14,8 @@ sys.path.append(os.path.abspath('includes'))
# ---------------------
extensions = ['sphinx.ext.coverage', 'sphinx.ext.doctest',
'pyspecific', 'c_annotations', 'escape4chm']
'pyspecific', 'c_annotations', 'escape4chm',
'asdl_highlight']
doctest_global_setup = '''

View File

@ -651,7 +651,7 @@ Why doesn't Python have a "with" statement for attribute assignments?
---------------------------------------------------------------------
Python has a 'with' statement that wraps the execution of a block, calling code
on the entrance and exit from the block. Some language have a construct that
on the entrance and exit from the block. Some languages have a construct that
looks like this::
with obj:

View File

@ -353,7 +353,7 @@ Our program keeps growing in complexity::
args = parser.parse_args()
answer = args.square**2
if args.verbose:
print("the square of {} equals {}".format(args.square, answer))
print(f"the square of {args.square} equals {answer}")
else:
print(answer)
@ -387,9 +387,9 @@ multiple verbosity values, and actually get to use them::
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
print("the square of {} equals {}".format(args.square, answer))
print(f"the square of {args.square} equals {answer}")
elif args.verbosity == 1:
print("{}^2 == {}".format(args.square, answer))
print(f"{args.square}^2 == {answer}")
else:
print(answer)
@ -421,9 +421,9 @@ Let's fix it by restricting the values the ``--verbosity`` option can accept::
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
print("the square of {} equals {}".format(args.square, answer))
print(f"the square of {args.square} equals {answer}")
elif args.verbosity == 1:
print("{}^2 == {}".format(args.square, answer))
print(f"{args.square}^2 == {answer}")
else:
print(answer)
@ -461,9 +461,9 @@ verbosity argument (check the output of ``python --help``)::
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
print("the square of {} equals {}".format(args.square, answer))
print(f"the square of {args.square} equals {answer}")
elif args.verbosity == 1:
print("{}^2 == {}".format(args.square, answer))
print(f"{args.square}^2 == {answer}")
else:
print(answer)
@ -529,9 +529,9 @@ Let's fix::
# bugfix: replace == with >=
if args.verbosity >= 2:
print("the square of {} equals {}".format(args.square, answer))
print(f"the square of {args.square} equals {answer}")
elif args.verbosity >= 1:
print("{}^2 == {}".format(args.square, answer))
print(f"{args.square}^2 == {answer}")
else:
print(answer)
@ -566,9 +566,9 @@ Let's fix that bug::
args = parser.parse_args()
answer = args.square**2
if args.verbosity >= 2:
print("the square of {} equals {}".format(args.square, answer))
print(f"the square of {args.square} equals {answer}")
elif args.verbosity >= 1:
print("{}^2 == {}".format(args.square, answer))
print(f"{args.square}^2 == {answer}")
else:
print(answer)
@ -606,9 +606,9 @@ not just squares::
args = parser.parse_args()
answer = args.x**args.y
if args.verbosity >= 2:
print("{} to the power {} equals {}".format(args.x, args.y, answer))
print(f"{args.x} to the power {args.y} equals {answer}")
elif args.verbosity >= 1:
print("{}^{} == {}".format(args.x, args.y, answer))
print(f"{args.x}^{args.y} == {answer}")
else:
print(answer)
@ -645,9 +645,9 @@ to display *more* text instead::
args = parser.parse_args()
answer = args.x**args.y
if args.verbosity >= 2:
print("Running '{}'".format(__file__))
print(f"Running '{__file__}'")
if args.verbosity >= 1:
print("{}^{} == ".format(args.x, args.y), end="")
print(f"{args.x}^{args.y} == ", end="")
print(answer)
Output:
@ -688,9 +688,9 @@ which will be the opposite of the ``--verbose`` one::
if args.quiet:
print(answer)
elif args.verbose:
print("{} to the power {} equals {}".format(args.x, args.y, answer))
print(f"{args.x} to the power {args.y} equals {answer}")
else:
print("{}^{} == {}".format(args.x, args.y, answer))
print(f"{args.x}^{args.y} == {answer}")
Our program is now simpler, and we've lost some functionality for the sake of
demonstration. Anyways, here's the output:

View File

@ -319,7 +319,7 @@ inside-out.
In Python, you use ``socket.setblocking(False)`` to make it non-blocking. In C, it's
more complex, (for one thing, you'll need to choose between the BSD flavor
``O_NONBLOCK`` and the almost indistinguishable Posix flavor ``O_NDELAY``, which
``O_NONBLOCK`` and the almost indistinguishable POSIX flavor ``O_NDELAY``, which
is completely different from ``TCP_NODELAY``), but it's the exact same idea. You
do this after creating the socket, but before using it. (Actually, if you're
nuts, you can switch back and forth.)

View File

@ -961,19 +961,6 @@ values are:
usage: PROG [-h] foo [foo ...]
PROG: error: the following arguments are required: foo
.. _`argparse.REMAINDER`:
* ``argparse.REMAINDER``. All the remaining command-line arguments are gathered
into a list. This is commonly useful for command line utilities that dispatch
to other command line utilities::
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo')
>>> parser.add_argument('command')
>>> parser.add_argument('args', nargs=argparse.REMAINDER)
>>> print(parser.parse_args('--foo B cmd --arg1 XX ZZ'.split()))
Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')
If the ``nargs`` keyword argument is not provided, the number of arguments consumed
is determined by the action_. Generally this means a single command-line argument
will be consumed and a single item (not a list) will be produced.

View File

@ -22,7 +22,7 @@ defined:
+-----------+--------------------+-------------------+-----------------------+-------+
| ``'B'`` | unsigned char | int | 1 | |
+-----------+--------------------+-------------------+-----------------------+-------+
| ``'u'`` | Py_UNICODE | Unicode character | 2 | \(1) |
| ``'u'`` | wchar_t | Unicode character | 2 | \(1) |
+-----------+--------------------+-------------------+-----------------------+-------+
| ``'h'`` | signed short | int | 2 | |
+-----------+--------------------+-------------------+-----------------------+-------+
@ -48,15 +48,16 @@ defined:
Notes:
(1)
The ``'u'`` type code corresponds to Python's obsolete unicode character
(:c:type:`Py_UNICODE` which is :c:type:`wchar_t`). Depending on the
platform, it can be 16 bits or 32 bits.
It can be 16 bits or 32 bits depending on the platform.
``'u'`` will be removed together with the rest of the :c:type:`Py_UNICODE`
API.
.. versionchanged:: 3.9
``array('u')`` now uses ``wchar_t`` as C type instead of deprecated
``Py_UNICODE``. This change doesn't affect to its behavior because
``Py_UNICODE`` is alias of ``wchar_t`` since Python 3.3.
.. deprecated-removed:: 3.3 4.0
The actual representation of values is determined by the machine architecture
(strictly speaking, by the C implementation). The actual size can be accessed
through the :attr:`itemsize` attribute.

View File

@ -35,7 +35,7 @@ Abstract Grammar
The abstract grammar is currently defined as follows:
.. literalinclude:: ../../Parser/Python.asdl
:language: none
:language: asdl
Node classes

View File

@ -48,6 +48,9 @@ await on multiple things with timeouts.
* - :class:`Task`
- Task object.
* - :func:`to_thread`
- Asychronously run a function in a separate OS thread.
* - :func:`run_coroutine_threadsafe`
- Schedule a coroutine from another OS thread.

View File

@ -170,7 +170,7 @@ Future Object
Returns the number of callbacks removed, which is typically 1,
unless a callback was added more than once.
.. method:: cancel()
.. method:: cancel(msg=None)
Cancel the Future and schedule callbacks.
@ -178,6 +178,9 @@ Future Object
Otherwise, change the Future's state to *cancelled*,
schedule the callbacks, and return ``True``.
.. versionchanged:: 3.9
Added the ``msg`` parameter.
.. method:: exception()
Return the exception that was set on this Future.
@ -255,3 +258,6 @@ the Future has a result::
- asyncio Future is not compatible with the
:func:`concurrent.futures.wait` and
:func:`concurrent.futures.as_completed` functions.
- :meth:`asyncio.Future.cancel` accepts an optional ``msg`` argument,
but :func:`concurrent.futures.cancel` does not.

View File

@ -95,14 +95,14 @@ Creating Subprocesses
See the documentation of :meth:`loop.subprocess_shell` for other
parameters.
.. important::
.. important::
It is the application's responsibility to ensure that all whitespace and
special characters are quoted appropriately to avoid `shell injection
<https://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_
vulnerabilities. The :func:`shlex.quote` function can be used to properly
escape whitespace and special shell characters in strings that are going
to be used to construct shell commands.
It is the application's responsibility to ensure that all whitespace and
special characters are quoted appropriately to avoid `shell injection
<https://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_
vulnerabilities. The :func:`shlex.quote` function can be used to properly
escape whitespace and special shell characters in strings that are going
to be used to construct shell commands.
.. deprecated-removed:: 3.8 3.10

View File

@ -453,7 +453,8 @@ Timeouts
wrap it in :func:`shield`.
The function will wait until the future is actually cancelled,
so the total wait time may exceed the *timeout*.
so the total wait time may exceed the *timeout*. If an exception
happens during cancellation, it is propagated.
If the wait is cancelled, the future *aw* is also cancelled.
@ -498,6 +499,8 @@ Waiting Primitives
set concurrently and block until the condition specified
by *return_when*.
The *aws* set must not be empty.
Returns two sets of Tasks/Futures: ``(done, pending)``.
Usage::
@ -573,7 +576,7 @@ Waiting Primitives
if task in done:
# Everything will work as expected now.
.. deprecated:: 3.8
.. deprecated-removed:: 3.8 3.11
Passing coroutine objects to ``wait()`` directly is
deprecated.
@ -582,9 +585,9 @@ Waiting Primitives
.. function:: as_completed(aws, \*, loop=None, timeout=None)
Run :ref:`awaitable objects <asyncio-awaitables>` in the *aws*
set concurrently. Return an iterator of :class:`Future` objects.
Each Future object returned represents the earliest result
from the set of the remaining awaitables.
set concurrently. Return an iterator of coroutines.
Each coroutine returned can be awaited to get the earliest next
result from the set of the remaining awaitables.
Raises :exc:`asyncio.TimeoutError` if the timeout occurs before
all Futures are done.
@ -594,11 +597,71 @@ Waiting Primitives
Example::
for f in as_completed(aws):
earliest_result = await f
for coro in as_completed(aws):
earliest_result = await coro
# ...
Running in Threads
==================
.. coroutinefunction:: to_thread(func, /, \*args, \*\*kwargs)
Asynchronously run function *func* in a separate thread.
Any \*args and \*\*kwargs supplied for this function are directly passed
to *func*. Also, the current :class:`contextvars.Context` is propogated,
allowing context variables from the event loop thread to be accessed in the
separate thread.
Return an :class:`asyncio.Future` which represents the eventual result of
*func*.
This coroutine function is primarily intended to be used for executing
IO-bound functions/methods that would otherwise block the event loop if
they were ran in the main thread. For example::
def blocking_io():
print(f"start blocking_io at {time.strftime('%X')}")
# Note that time.sleep() can be replaced with any blocking
# IO-bound operation, such as file operations.
time.sleep(1)
print(f"blocking_io complete at {time.strftime('%X')}")
async def main():
print(f"started main at {time.strftime('%X')}")
await asyncio.gather(
asyncio.to_thread(blocking_io),
asyncio.sleep(1))
print(f"finished main at {time.strftime('%X')}")
asyncio.run(main())
# Expected output:
#
# started main at 19:50:53
# start blocking_io at 19:50:53
# blocking_io complete at 19:50:54
# finished main at 19:50:54
Directly calling `blocking_io()` in any coroutine would block the event loop
for its duration, resulting in an additional 1 second of run time. Instead,
by using `asyncio.to_thread()`, we can run it in a separate thread without
blocking the event loop.
.. note::
Due to the :term:`GIL`, `asyncio.to_thread()` can typically only be used
to make IO-bound functions non-blocking. However, for extension modules
that release the GIL or alternative Python implementations that don't
have one, `asyncio.to_thread()` can also be used for CPU-bound functions.
.. versionadded:: 3.9
Scheduling From Other Threads
=============================
@ -721,7 +784,7 @@ Task Object
.. deprecated-removed:: 3.8 3.10
The *loop* parameter.
.. method:: cancel()
.. method:: cancel(msg=None)
Request the Task to be cancelled.
@ -736,6 +799,9 @@ Task Object
suppressing cancellation completely is not common and is actively
discouraged.
.. versionchanged:: 3.9
Added the ``msg`` parameter.
.. _asyncio_example_task_cancel:
The following example illustrates how coroutines can intercept

View File

@ -56,8 +56,8 @@ build applications which provide an interactive interpreter prompt.
*source* is the source string; *filename* is the optional filename from which
source was read, defaulting to ``'<input>'``; and *symbol* is the optional
grammar start symbol, which should be either ``'single'`` (the default) or
``'eval'``.
grammar start symbol, which should be ``'single'`` (the default), ``'eval'``
or ``'exec'``.
Returns a code object (the same as ``compile(source, filename, symbol)``) if the
command is complete and valid; ``None`` if the command is incomplete; raises

View File

@ -43,8 +43,9 @@ To do just the former:
:exc:`OverflowError` or :exc:`ValueError` if there is an invalid literal.
The *symbol* argument determines whether *source* is compiled as a statement
(``'single'``, the default) or as an :term:`expression` (``'eval'``). Any
other value will cause :exc:`ValueError` to be raised.
(``'single'``, the default), as a sequence of statements (``'exec'``) or
as an :term:`expression` (``'eval'``). Any other value will
cause :exc:`ValueError` to be raised.
.. note::

View File

@ -290,6 +290,47 @@ For example::
>>> sorted(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']
.. method:: isdisjoint(other)
True if none of the elements in *self* overlap with those in *other*.
Negative or missing counts are ignored.
Logically equivalent to: ``not (+self) & (+other)``
.. versionadded:: 3.10
.. method:: isequal(other)
Test whether counts agree exactly.
Negative or missing counts are treated as zero.
This method works differently than the inherited :meth:`__eq__` method
which treats negative or missing counts as distinct from zero::
>>> Counter(a=1, b=0).isequal(Counter(a=1))
True
>>> Counter(a=1, b=0) == Counter(a=1)
False
Logically equivalent to: ``+self == +other``
.. versionadded:: 3.10
.. method:: issubset(other)
True if the counts in *self* are less than or equal to those in *other*.
Negative or missing counts are treated as zero.
Logically equivalent to: ``not self - (+other)``
.. versionadded:: 3.10
.. method:: issuperset(other)
True if the counts in *self* are greater than or equal to those in *other*.
Negative or missing counts are treated as zero.
Logically equivalent to: ``not other - (+self)``
.. versionadded:: 3.10
.. method:: most_common([n])
Return a list of the *n* most common elements and their counts from the
@ -1161,6 +1202,8 @@ variants of :func:`functools.lru_cache`::
return value
def __setitem__(self, key, value):
if key in self:
self.move_to_end(key)
super().__setitem__(key, value)
if len(self) > self.maxsize:
oldest = next(iter(self))

View File

@ -113,6 +113,11 @@ compile Python sources.
Ignore symlinks pointing outside the given directory.
.. cmdoption:: --hardlink-dupes
If two ``.pyc`` files with different optimization level have
the same content, use hard links to consolidate duplicate files.
.. versionchanged:: 3.2
Added the ``-i``, ``-b`` and ``-h`` options.
@ -125,7 +130,7 @@ compile Python sources.
Added the ``--invalidation-mode`` option.
.. versionchanged:: 3.9
Added the ``-s``, ``-p``, ``-e`` options.
Added the ``-s``, ``-p``, ``-e`` and ``--hardlink-dupes`` options.
Raised the default recursion limit from 10 to
:py:func:`sys.getrecursionlimit()`.
Added the possibility to specify the ``-o`` option multiple times.
@ -143,14 +148,14 @@ runtime.
Public functions
----------------
.. function:: compile_dir(dir, maxlevels=sys.getrecursionlimit(), ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, workers=1, invalidation_mode=None, \*, stripdir=None, prependdir=None, limit_sl_dest=None)
.. function:: compile_dir(dir, maxlevels=sys.getrecursionlimit(), ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, workers=1, invalidation_mode=None, \*, stripdir=None, prependdir=None, limit_sl_dest=None, hardlink_dupes=False)
Recursively descend the directory tree named by *dir*, compiling all :file:`.py`
files along the way. Return a true value if all the files compiled successfully,
and a false value otherwise.
The *maxlevels* parameter is used to limit the depth of the recursion; it
defaults to ``10``.
defaults to ``sys.getrecursionlimit()``.
If *ddir* is given, it is prepended to the path to each file being compiled
for use in compilation time tracebacks, and is also compiled in to the
@ -176,7 +181,8 @@ Public functions
coexist.
*optimize* specifies the optimization level for the compiler. It is passed to
the built-in :func:`compile` function.
the built-in :func:`compile` function. Accepts also a sequence of optimization
levels which lead to multiple compilations of one :file:`.py` file in one call.
The argument *workers* specifies how many workers are used to
compile files in parallel. The default is to not use multiple workers.
@ -193,6 +199,9 @@ Public functions
the ``-s``, ``-p`` and ``-e`` options described above.
They may be specified as ``str``, ``bytes`` or :py:class:`os.PathLike`.
If *hardlink_dupes* is true and two ``.pyc`` files with different optimization
level have the same content, use hard links to consolidate duplicate files.
.. versionchanged:: 3.2
Added the *legacy* and *optimize* parameter.
@ -219,9 +228,10 @@ Public functions
Setting *workers* to 0 now chooses the optimal number of cores.
.. versionchanged:: 3.9
Added *stripdir*, *prependdir* and *limit_sl_dest* arguments.
Added *stripdir*, *prependdir*, *limit_sl_dest* and *hardlink_dupes* arguments.
Default value of *maxlevels* was changed from ``10`` to ``sys.getrecursionlimit()``
.. function:: compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, invalidation_mode=None, \*, stripdir=None, prependdir=None, limit_sl_dest=None)
.. function:: compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, invalidation_mode=None, \*, stripdir=None, prependdir=None, limit_sl_dest=None, hardlink_dupes=False)
Compile the file with path *fullname*. Return a true value if the file
compiled successfully, and a false value otherwise.
@ -247,7 +257,8 @@ Public functions
coexist.
*optimize* specifies the optimization level for the compiler. It is passed to
the built-in :func:`compile` function.
the built-in :func:`compile` function. Accepts also a sequence of optimization
levels which lead to multiple compilations of one :file:`.py` file in one call.
*invalidation_mode* should be a member of the
:class:`py_compile.PycInvalidationMode` enum and controls how the generated
@ -257,6 +268,9 @@ Public functions
the ``-s``, ``-p`` and ``-e`` options described above.
They may be specified as ``str``, ``bytes`` or :py:class:`os.PathLike`.
If *hardlink_dupes* is true and two ``.pyc`` files with different optimization
level have the same content, use hard links to consolidate duplicate files.
.. versionadded:: 3.2
.. versionchanged:: 3.5
@ -273,7 +287,7 @@ Public functions
The *invalidation_mode* parameter's default value is updated to None.
.. versionchanged:: 3.9
Added *stripdir*, *prependdir* and *limit_sl_dest* arguments.
Added *stripdir*, *prependdir*, *limit_sl_dest* and *hardlink_dupes* arguments.
.. function:: compile_path(skip_curdir=True, maxlevels=0, force=False, quiet=0, legacy=False, optimize=-1, invalidation_mode=None)

View File

@ -19,6 +19,8 @@ in :pep:`557`.
The member variables to use in these generated methods are defined
using :pep:`526` type annotations. For example this code::
from dataclasses import dataclass
@dataclass
class InventoryItem:
'''Class for keeping track of an item in inventory.'''

View File

@ -20,6 +20,7 @@ The following modules are documented in this chapter:
.. toctree::
datetime.rst
zoneinfo.rst
calendar.rst
collections.rst
collections.abc.rst

View File

@ -35,7 +35,8 @@ on efficient attribute extraction for output formatting and manipulation.
Aware and Naive Objects
-----------------------
Date and time objects may be categorized as "aware" or "naive."
Date and time objects may be categorized as "aware" or "naive" depending on
whether or not they include timezone information.
With sufficient knowledge of applicable algorithmic and political time
adjustments, such as time zone and daylight saving time information,
@ -670,7 +671,8 @@ Instance methods:
.. method:: date.isocalendar()
Return a 3-tuple, (ISO year, ISO week number, ISO weekday).
Return a :term:`named tuple` object with three components: ``year``,
``week`` and ``weekday``.
The ISO calendar is a widely used variant of the Gregorian calendar. [#]_
@ -682,11 +684,14 @@ Instance methods:
For example, 2004 begins on a Thursday, so the first week of ISO year 2004
begins on Monday, 29 Dec 2003 and ends on Sunday, 4 Jan 2004::
>>> from datetime import date
>>> date(2003, 12, 29).isocalendar()
(2004, 1, 1)
>>> date(2004, 1, 4).isocalendar()
(2004, 1, 7)
>>> from datetime import date
>>> date(2003, 12, 29).isocalendar()
datetime.IsoCalendarDate(year=2004, week=1, weekday=1)
>>> date(2004, 1, 4).isocalendar()
datetime.IsoCalendarDate(year=2004, week=1, weekday=7)
.. versionchanged:: 3.9
Result changed from a tuple to a :term:`named tuple`.
.. method:: date.isoformat()
@ -1397,8 +1402,8 @@ Instance methods:
.. method:: datetime.isocalendar()
Return a 3-tuple, (ISO year, ISO week number, ISO weekday). The same as
``self.date().isocalendar()``.
Return a :term:`named tuple` with three components: ``year``, ``week``
and ``weekday``. The same as ``self.date().isocalendar()``.
.. method:: datetime.isoformat(sep='T', timespec='auto')

View File

@ -421,7 +421,7 @@ The :class:`SequenceMatcher` class has this constructor:
is not changed.
.. method:: find_longest_match(alo, ahi, blo, bhi)
.. method:: find_longest_match(alo=0, ahi=None, blo=0, bhi=None)
Find longest matching block in ``a[alo:ahi]`` and ``b[blo:bhi]``.
@ -458,6 +458,9 @@ The :class:`SequenceMatcher` class has this constructor:
This method returns a :term:`named tuple` ``Match(a, b, size)``.
.. versionchanged:: 3.9
Added default arguments.
.. method:: get_matching_blocks()

View File

@ -26,6 +26,32 @@ function for the purposes of this module.
The :mod:`functools` module defines the following functions:
.. decorator:: cache(user_function)
Simple lightweight unbounded function cache. Sometimes called
`"memoize" <https://en.wikipedia.org/wiki/Memoization>`_.
Returns the same as ``lru_cache(maxsize=None)``, creating a thin
wrapper around a dictionary lookup for the function arguments. Because it
never needs to evict old values, this is smaller and faster than
:func:`lru_cache()` with a size limit.
For example::
@cache
def factorial(n):
return n * factorial(n-1) if n else 1
>>> factorial(10) # no previously cached result, makes 11 recursive calls
3628800
>>> factorial(5) # just looks up cached value result
120
>>> factorial(12) # makes two new recursive calls, the other 10 are cached
479001600
.. versionadded:: 3.9
.. decorator:: cached_property(func)
Transform a method of a class into a property whose value is computed once
@ -107,8 +133,7 @@ The :mod:`functools` module defines the following functions:
return sum(sentence.count(vowel) for vowel in 'aeiou')
If *maxsize* is set to ``None``, the LRU feature is disabled and the cache can
grow without bound. The LRU feature performs best when *maxsize* is a
power-of-two.
grow without bound.
If *typed* is set to true, function arguments of different types will be
cached separately. For example, ``f(3)`` and ``f(3.0)`` will be treated
@ -133,11 +158,11 @@ The :mod:`functools` module defines the following functions:
bypassing the cache, or for rewrapping the function with a different cache.
An `LRU (least recently used) cache
<https://en.wikipedia.org/wiki/Cache_algorithms#Examples>`_ works
best when the most recent calls are the best predictors of upcoming calls (for
example, the most popular articles on a news server tend to change each day).
The cache's size limit assures that the cache does not grow without bound on
long-running processes such as web servers.
<https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)>`_
works best when the most recent calls are the best predictors of upcoming
calls (for example, the most popular articles on a news server tend to
change each day). The cache's size limit assures that the cache does not
grow without bound on long-running processes such as web servers.
In general, the LRU cache should only be used when you want to reuse
previously computed values. Accordingly, it doesn't make sense to cache

View File

@ -87,6 +87,8 @@ library that Python uses on your platform. On most platforms the
that the hashing algorithm is not used in a security context, e.g. as a
non-cryptographic one-way compression function.
Hashlib now uses SHA3 and SHAKE from OpenSSL 1.1.1 and newer.
For example, to obtain the digest of the byte string ``b'Nobody inspects the
spammish repetition'``::

View File

@ -114,6 +114,12 @@ A hash object has the following attributes:
.. versionadded:: 3.4
.. deprecated:: 3.9
The undocumented attributes ``HMAC.digest_cons``, ``HMAC.inner``, and
``HMAC.outer`` are internal implementation details and will be removed in
Python 3.10.
This module also provides the following helper function:
.. function:: compare_digest(a, b)
@ -132,6 +138,11 @@ This module also provides the following helper function:
.. versionadded:: 3.3
.. versionchanged:: 3.10
The function uses OpenSSL's ``CRYPTO_memcmp()`` internally when
available.
.. seealso::

View File

@ -480,6 +480,8 @@ ABC hierarchy::
.. class:: ResourceReader
*Superseded by TraversableReader*
An :term:`abstract base class` to provide the ability to read
*resources*.
@ -795,6 +797,28 @@ ABC hierarchy::
itself does not end in ``__init__``.
.. class:: Traversable
An object with a subset of pathlib.Path methods suitable for
traversing directories and opening files.
.. versionadded:: 3.9
.. class:: TraversableReader
An abstract base class for resource readers capable of serving
the ``files`` interface. Subclasses ResourceReader and provides
concrete implementations of the ResourceReader's abstract
methods. Therefore, any loader supplying TraversableReader
also supplies ResourceReader.
Loaders that wish to support resource reading are expected to
implement this interface.
.. versionadded:: 3.9
:mod:`importlib.resources` -- Resources
---------------------------------------
@ -853,6 +877,19 @@ The following types are defined.
The following functions are available.
.. function:: files(package)
Returns an :class:`importlib.resources.abc.Traversable` object
representing the resource container for the package (think directory)
and its resources (think files). A Traversable may contain other
containers (think subdirectories).
*package* is either a name or a module object which conforms to the
``Package`` requirements.
.. versionadded:: 3.9
.. function:: open_binary(package, resource)
Open for binary reading the *resource* within *package*.

View File

@ -473,15 +473,12 @@ Retrieving source code
Get the documentation string for an object, cleaned up with :func:`cleandoc`.
If the documentation string for an object is not provided and the object is
a method, a property or a descriptor, retrieve the documentation
a class, a method, a property or a descriptor, retrieve the documentation
string from the inheritance hierarchy.
.. versionchanged:: 3.5
Documentation strings are now inherited if not overridden.
.. versionchanged:: 3.9
Documentation strings for classes are no longer inherited.
.. function:: getcomments(object)

View File

@ -132,12 +132,13 @@ High-level Module Interface
Opens the provided file with mode ``'rb'``. This function should be used
when the intent is to treat the contents as executable code.
``path`` should be an absolute path.
``path`` should be a :class:`str` and an absolute path.
The behavior of this function may be overridden by an earlier call to the
:c:func:`PyFile_SetOpenCodeHook`, however, it should always be considered
interchangeable with ``open(path, 'rb')``. Overriding the behavior is
intended for additional validation or preprocessing of the file.
:c:func:`PyFile_SetOpenCodeHook`. However, assuming that ``path`` is a
:class:`str` and an absolute path, ``open_code(path)`` should always behave
the same as ``open(path, 'rb')``. Overriding the behavior is intended for
additional validation or preprocessing of the file.
.. versionadded:: 3.8

View File

@ -81,7 +81,9 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
private copy-on-write mapping, so changes to the contents of the mmap
object will be private to this process, and :const:`MAP_SHARED` creates a
mapping that's shared with all other processes mapping the same areas of
the file. The default value is :const:`MAP_SHARED`.
the file. The default value is :const:`MAP_SHARED`. Some systems have
additional possible flags with the full list specified in
:ref:`MAP_* constants <map-constants>`.
*prot*, if specified, gives the desired memory protection; the two most
useful values are :const:`PROT_READ` and :const:`PROT_WRITE`, to specify
@ -342,3 +344,21 @@ MADV_* Constants
Availability: Systems with the madvise() system call.
.. versionadded:: 3.8
.. _map-constants:
MAP_* Constants
+++++++++++++++
.. data:: MAP_SHARED
MAP_PRIVATE
MAP_DENYWRITE
MAP_EXECUTABLE
MAP_ANON
MAP_ANONYMOUS
MAP_POPULATE
These are the various flags that can be passed to :meth:`mmap.mmap`. Note that some options might not be present on some systems.
.. versionchanged:: 3.10
Added MAP_POPULATE constant.

View File

@ -2144,7 +2144,7 @@ with the :class:`Pool` class.
or by calling :meth:`close` and :meth:`terminate` manually. Failure to do this
can lead to the process hanging on finalization.
Note that is **not correct** to rely on the garbage colletor to destroy the pool
Note that it is **not correct** to rely on the garbage collector to destroy the pool
as CPython does not assure that the finalizer of the pool will be called
(see :meth:`object.__del__` for more information).

View File

@ -112,6 +112,10 @@ The mathematical and bitwise operations are the most numerous:
Return *a* converted to an integer. Equivalent to ``a.__index__()``.
.. versionchanged:: 3.10
The result always has exact type :class:`int`. Previously, the result
could have been an instance of a subclass of ``int``.
.. function:: inv(obj)
invert(obj)

View File

@ -1151,7 +1151,8 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
Combine the functionality of :func:`os.readv` and :func:`os.pread`.
.. availability:: Linux 2.6.30 and newer, FreeBSD 6.0 and newer,
OpenBSD 2.7 and newer. Using flags requires Linux 4.6 or newer.
OpenBSD 2.7 and newer, AIX 7.1 and newer. Using flags requires
Linux 4.6 or newer.
.. versionadded:: 3.7
@ -1210,6 +1211,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
- :data:`RWF_DSYNC`
- :data:`RWF_SYNC`
- :data:`RWF_APPEND`
Return the total number of bytes actually written.
@ -1219,15 +1221,16 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
Combine the functionality of :func:`os.writev` and :func:`os.pwrite`.
.. availability:: Linux 2.6.30 and newer, FreeBSD 6.0 and newer,
OpenBSD 2.7 and newer. Using flags requires Linux 4.7 or newer.
OpenBSD 2.7 and newer, AIX 7.1 and newer. Using flags requires
Linux 4.7 or newer.
.. versionadded:: 3.7
.. data:: RWF_DSYNC
Provide a per-write equivalent of the :data:`O_DSYNC` ``open(2)`` flag. This
flag effect applies only to the data range written by the system call.
Provide a per-write equivalent of the :data:`O_DSYNC` :func:`os.open` flag.
This flag effect applies only to the data range written by the system call.
.. availability:: Linux 4.7 and newer.
@ -1236,14 +1239,28 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
.. data:: RWF_SYNC
Provide a per-write equivalent of the :data:`O_SYNC` ``open(2)`` flag. This
flag effect applies only to the data range written by the system call.
Provide a per-write equivalent of the :data:`O_SYNC` :func:`os.open` flag.
This flag effect applies only to the data range written by the system call.
.. availability:: Linux 4.7 and newer.
.. versionadded:: 3.7
.. data:: RWF_APPEND
Provide a per-write equivalent of the :data:`O_APPEND` :func:`os.open`
flag. This flag is meaningful only for :func:`os.pwritev`, and its
effect applies only to the data range written by the system call. The
*offset* argument does not affect the write operation; the data is always
appended to the end of the file. However, if the *offset* argument is
``-1``, the current file *offset* is updated.
.. availability:: Linux 4.16 and newer.
.. versionadded:: 3.10
.. function:: read(fd, n)
Read at most *n* bytes from file descriptor *fd*.

View File

@ -549,25 +549,24 @@ Pure paths provide the following methods and properties:
>>> p.relative_to('/usr')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "pathlib.py", line 940, in relative_to
File "pathlib.py", line 941, in relative_to
raise ValueError(error_message.format(str(self), str(formatted)))
ValueError: '/etc/passwd' does not start with '/usr'
ValueError: '/etc/passwd' is not in the subpath of '/usr' OR one path is relative and the other is absolute.
>>> p.relative_to('/usr', strict=False)
PurePosixPath('../etc/passwd')
>>> p.relative_to('foo', strict=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "pathlib.py", line 940, in relative_to
File "pathlib.py", line 941, in relative_to
raise ValueError(error_message.format(str(self), str(formatted)))
ValueError: '/etc/passwd' is not related to 'foo'
ValueError: '/etc/passwd' is not on the same drive as 'foo' OR one path is relative and the other is absolute.
If the path doesn't start with *other* and *strict* is ``True``,
:exc:`ValueError` is raised. If *strict* is ``False`` and the paths are
not both relative or both absolute :exc:`ValueError` is raised (on Windows
both paths must reference the same drive as well).
If the path doesn't start with *other* and *strict* is ``True``, :exc:`ValueError` is raised. If *strict* is ``False`` and one path is relative and the other is absolute or if they reference different drives :exc:`ValueError` is raised.
.. versionadded:: 3.9
The *strict* parameter was added.
NOTE: This function is part of :class:`PurePath` and works with strings. It does not check or access the underlying file structure.
.. versionadded:: 3.10
The *strict* argument (pre-3.10 behavior is strict).
.. method:: PurePath.with_name(name)
@ -1201,6 +1200,7 @@ os and os.path pathlib
:func:`os.path.abspath` :meth:`Path.resolve`
:func:`os.chmod` :meth:`Path.chmod`
:func:`os.mkdir` :meth:`Path.mkdir`
:func:`os.makedirs` :meth:`Path.mkdir`
:func:`os.rename` :meth:`Path.rename`
:func:`os.replace` :meth:`Path.replace`
:func:`os.rmdir` :meth:`Path.rmdir`

View File

@ -252,10 +252,10 @@ process more convenient:
.. versionchanged:: 3.8
The *buffers* argument was added.
.. function:: loads(bytes_object, \*, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)
.. function:: loads(data, /, \*, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)
Return the reconstituted object hierarchy of the pickled representation
*bytes_object* of an object.
*data* of an object. *data* must be a :term:`bytes-like object`.
The protocol version of the pickle is detected automatically, so no
protocol argument is needed. Bytes past the pickled representation

View File

@ -104,21 +104,16 @@ Bookkeeping functions
the time :func:`getstate` was called.
.. function:: getrandbits(k)
Returns a Python integer with *k* random bits. This method is supplied with
the MersenneTwister generator and some other generators may also provide it
as an optional part of the API. When available, :meth:`getrandbits` enables
:meth:`randrange` to handle arbitrarily large ranges.
.. versionchanged:: 3.9
This method now accepts zero for *k*.
Functions for bytes
-------------------
.. function:: randbytes(n)
Generate *n* random bytes.
This method should not be used for generating security tokens.
Use :func:`secrets.token_bytes` instead.
.. versionadded:: 3.9
@ -145,6 +140,16 @@ Functions for integers
Return a random integer *N* such that ``a <= N <= b``. Alias for
``randrange(a, b+1)``.
.. function:: getrandbits(k)
Returns a Python integer with *k* random bits. This method is supplied with
the MersenneTwister generator and some other generators may also provide it
as an optional part of the API. When available, :meth:`getrandbits` enables
:meth:`randrange` to handle arbitrarily large ranges.
.. versionchanged:: 3.9
This method now accepts zero for *k*.
Functions for sequences
-----------------------
@ -208,8 +213,11 @@ Functions for sequences
generated. For example, a sequence of length 2080 is the largest that
can fit within the period of the Mersenne Twister random number generator.
.. deprecated-removed:: 3.9 3.11
The optional parameter *random*.
.. function:: sample(population, k)
.. function:: sample(population, k, *, counts=None)
Return a *k* length list of unique elements chosen from the population sequence
or set. Used for random sampling without replacement.
@ -223,6 +231,11 @@ Functions for sequences
Members of the population need not be :term:`hashable` or unique. If the population
contains repeats, then each occurrence is a possible selection in the sample.
Repeated elements can be specified one at a time or with the optional
keyword-only *counts* parameter. For example, ``sample(['red', 'blue'],
counts=[4, 2], k=5)`` is equivalent to ``sample(['red', 'red', 'red', 'red',
'blue', 'blue'], k=5)``.
To choose a sample from a range of integers, use a :func:`range` object as an
argument. This is especially fast and space efficient for sampling from a large
population: ``sample(range(10000000), k=60)``.
@ -230,6 +243,9 @@ Functions for sequences
If the sample size is larger than the population size, a :exc:`ValueError`
is raised.
.. versionchanged:: 3.9
Added the *counts* parameter.
.. deprecated:: 3.9
In the future, the *population* must be a sequence. Instances of
:class:`set` are no longer supported. The set must first be converted
@ -412,12 +428,11 @@ Simulations::
>>> choices(['red', 'black', 'green'], [18, 18, 2], k=6)
['red', 'green', 'black', 'black', 'red', 'black']
>>> # Deal 20 cards without replacement from a deck of 52 playing cards
>>> # and determine the proportion of cards with a ten-value
>>> # (a ten, jack, queen, or king).
>>> deck = collections.Counter(tens=16, low_cards=36)
>>> seen = sample(list(deck.elements()), k=20)
>>> seen.count('tens') / 20
>>> # Deal 20 cards without replacement from a deck
>>> # of 52 playing cards, and determine the proportion of cards
>>> # with a ten-value: ten, jack, queen, or king.
>>> dealt = sample(['tens', 'low cards'], counts=[16, 36], k=20)
>>> dealt.count('tens') / 20
0.15
>>> # Estimate the probability of getting 5 or more heads from 7 spins
@ -479,7 +494,7 @@ Simulation of arrival times and service deliveries for a multiserver queue::
from heapq import heappush, heappop
from random import expovariate, gauss
from statistics import mean, median, stdev
from statistics import mean, quantiles
average_arrival_interval = 5.6
average_service_time = 15.0
@ -498,8 +513,8 @@ Simulation of arrival times and service deliveries for a multiserver queue::
service_completed = arrival_time + wait + service_duration
heappush(servers, service_completed)
print(f'Mean wait: {mean(waits):.1f}. Stdev wait: {stdev(waits):.1f}.')
print(f'Median wait: {median(waits):.1f}. Max wait: {max(waits):.1f}.')
print(f'Mean wait: {mean(waits):.1f} Max wait: {max(waits):.1f}')
print('Quartiles:', [round(q, 1) for q in quantiles(waits)])
.. seealso::

View File

@ -117,7 +117,7 @@ The module defines the following:
.. function:: select(rlist, wlist, xlist[, timeout])
This is a straightforward interface to the Unix :c:func:`select` system call.
The first three arguments are sequences of 'waitable objects': either
The first three arguments are iterables of 'waitable objects': either
integers representing file descriptors or objects with a parameterless method
named :meth:`~io.IOBase.fileno` returning such an integer:
@ -126,7 +126,7 @@ The module defines the following:
* *xlist*: wait for an "exceptional condition" (see the manual page for what
your system considers such a condition)
Empty sequences are allowed, but acceptance of three empty sequences is
Empty iterables are allowed, but acceptance of three empty iterables is
platform-dependent. (It is known to work on Unix but not on Windows.) The
optional *timeout* argument specifies a time-out as a floating point number
in seconds. When the *timeout* argument is omitted the function blocks until
@ -141,7 +141,7 @@ The module defines the following:
single: socket() (in module socket)
single: popen() (in module os)
Among the acceptable object types in the sequences are Python :term:`file
Among the acceptable object types in the iterables are Python :term:`file
objects <file object>` (e.g. ``sys.stdin``, or objects returned by
:func:`open` or :func:`os.popen`), socket objects returned by
:func:`socket.socket`. You may also define a :dfn:`wrapper` class yourself,

View File

@ -279,9 +279,10 @@ An :class:`SMTP` instance has the following methods:
response for ESMTP option and store them for use by :meth:`has_extn`.
Also sets several informational attributes: the message returned by
the server is stored as the :attr:`ehlo_resp` attribute, :attr:`does_esmtp`
is set to true or false depending on whether the server supports ESMTP, and
:attr:`esmtp_features` will be a dictionary containing the names of the
SMTP service extensions this server supports, and their parameters (if any).
is set to ``True`` or ``False`` depending on whether the server supports
ESMTP, and :attr:`esmtp_features` will be a dictionary containing the names
of the SMTP service extensions this server supports, and their parameters
(if any).
Unless you wish to use :meth:`has_extn` before sending mail, it should not be
necessary to call this method explicitly. It will be implicitly called by

View File

@ -118,6 +118,10 @@ created. Socket addresses are represented as follows:
- :const:`CAN_ISOTP` protocol require a tuple ``(interface, rx_addr, tx_addr)``
where both additional parameters are unsigned long integer that represent a
CAN identifier (standard or extended).
- :const:`CAN_J1939` protocol require a tuple ``(interface, name, pgn, addr)``
where additional parameters are 64-bit unsigned integer representing the
ECU name, a 32-bit unsigned integer representing the Parameter Group Number
(PGN), and an 8-bit integer representing the address.
- A string or a tuple ``(id, unit)`` is used for the :const:`SYSPROTO_CONTROL`
protocol of the :const:`PF_SYSTEM` family. The string is the name of a
@ -428,6 +432,15 @@ Constants
.. versionadded:: 3.7
.. data:: CAN_J1939
CAN_J1939, in the CAN protocol family, is the SAE J1939 protocol.
J1939 constants, documented in the Linux documentation.
.. availability:: Linux >= 5.4.
.. versionadded:: 3.9
.. data:: AF_PACKET
PF_PACKET
@ -544,7 +557,8 @@ The following functions all create :ref:`socket objects <socket-objects>`.
default), :const:`SOCK_DGRAM`, :const:`SOCK_RAW` or perhaps one of the other
``SOCK_`` constants. The protocol number is usually zero and may be omitted
or in the case where the address family is :const:`AF_CAN` the protocol
should be one of :const:`CAN_RAW`, :const:`CAN_BCM` or :const:`CAN_ISOTP`.
should be one of :const:`CAN_RAW`, :const:`CAN_BCM`, :const:`CAN_ISOTP` or
:const:`CAN_J1939`.
If *fileno* is specified, the values for *family*, *type*, and *proto* are
auto-detected from the specified file descriptor. Auto-detection can be
@ -588,6 +602,9 @@ The following functions all create :ref:`socket objects <socket-objects>`.
``SOCK_NONBLOCK``, but ``sock.type`` will be set to
``socket.SOCK_STREAM``.
.. versionchanged:: 3.9
The CAN_J1939 protocol was added.
.. function:: socketpair([family[, type[, proto]]])
Build a pair of connected socket objects using the given address family, socket

View File

@ -928,7 +928,7 @@ a class like this::
self.x, self.y = x, y
Now you want to store the point in a single SQLite column. First you'll have to
choose one of the supported types first to be used for representing the point.
choose one of the supported types to be used for representing the point.
Let's just use str and separate the coordinates using a semicolon. Then you need
to give your class a method ``__conform__(self, protocol)`` which must return
the converted value. The parameter *protocol* will be :class:`PrepareProtocol`.

View File

@ -615,7 +615,7 @@ Constants
Possible value for :attr:`SSLContext.verify_flags`. In this mode, only the
peer cert is checked but none of the intermediate CA certificates. The mode
requires a valid CRL that is signed by the peer cert's issuer (its direct
ancestor CA). If no proper CRL has has been loaded with
ancestor CA). If no proper CRL has been loaded with
:attr:`SSLContext.load_verify_locations`, validation will fail.
.. versionadded:: 3.4

View File

@ -434,12 +434,10 @@ Notes:
Negative shift counts are illegal and cause a :exc:`ValueError` to be raised.
(2)
A left shift by *n* bits is equivalent to multiplication by ``pow(2, n)``
without overflow check.
A left shift by *n* bits is equivalent to multiplication by ``pow(2, n)``.
(3)
A right shift by *n* bits is equivalent to division by ``pow(2, n)`` without
overflow check.
A right shift by *n* bits is equivalent to floor division by ``pow(2, n)``.
(4)
Performing these calculations with at least one extra sign extension bit in

View File

@ -40,7 +40,7 @@ compatibility with older versions, see the :ref:`call-function-trio` section.
.. function:: run(args, *, stdin=None, input=None, stdout=None, stderr=None,\
capture_output=False, shell=False, cwd=None, timeout=None, \
check=False, encoding=None, errors=None, text=None, env=None, \
universal_newlines=None)
universal_newlines=None, **other_popen_kwargs)
Run the command described by *args*. Wait for command to complete, then
return a :class:`CompletedProcess` instance.
@ -791,14 +791,14 @@ Instances of the :class:`Popen` class have the following methods:
.. method:: Popen.terminate()
Stop the child. On Posix OSs the method sends SIGTERM to the
Stop the child. On POSIX OSs the method sends SIGTERM to the
child. On Windows the Win32 API function :c:func:`TerminateProcess` is called
to stop the child.
.. method:: Popen.kill()
Kills the child. On Posix OSs the function sends SIGKILL to the child.
Kills the child. On POSIX OSs the function sends SIGKILL to the child.
On Windows :meth:`kill` is an alias for :meth:`terminate`.
@ -1085,7 +1085,8 @@ Prior to Python 3.5, these three functions comprised the high level API to
subprocess. You can now use :func:`run` in many cases, but lots of existing code
calls these functions.
.. function:: call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None)
.. function:: call(args, *, stdin=None, stdout=None, stderr=None, \
shell=False, cwd=None, timeout=None, **other_popen_kwargs)
Run the command described by *args*. Wait for command to complete, then
return the :attr:`~Popen.returncode` attribute.
@ -1111,7 +1112,9 @@ calls these functions.
.. versionchanged:: 3.3
*timeout* was added.
.. function:: check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None)
.. function:: check_call(args, *, stdin=None, stdout=None, stderr=None, \
shell=False, cwd=None, timeout=None, \
**other_popen_kwargs)
Run command with arguments. Wait for command to complete. If the return
code was zero then return, otherwise raise :exc:`CalledProcessError`. The
@ -1142,7 +1145,8 @@ calls these functions.
.. function:: check_output(args, *, stdin=None, stderr=None, shell=False, \
cwd=None, encoding=None, errors=None, \
universal_newlines=None, timeout=None, text=None)
universal_newlines=None, timeout=None, text=None, \
**other_popen_kwargs)
Run command with arguments and return its output.

View File

@ -74,12 +74,12 @@ places.
Python currently supports seven schemes:
- *posix_prefix*: scheme for Posix platforms like Linux or Mac OS X. This is
- *posix_prefix*: scheme for POSIX platforms like Linux or Mac OS X. This is
the default scheme used when Python or a component is installed.
- *posix_home*: scheme for Posix platforms used when a *home* option is used
- *posix_home*: scheme for POSIX platforms used when a *home* option is used
upon installation. This scheme is used when a component is installed through
Distutils with a specific home prefix.
- *posix_user*: scheme for Posix platforms used when a component is installed
- *posix_user*: scheme for POSIX platforms used when a component is installed
through Distutils and the *user* option is used. This scheme defines paths
located under the user home directory.
- *nt*: scheme for NT platforms like Windows.

View File

@ -263,11 +263,6 @@ The :mod:`test.support` module defines the following constants:
Set to a non-ASCII name for a temporary file.
.. data:: TESTFN_ENCODING
Set to :func:`sys.getfilesystemencoding`.
.. data:: TESTFN_UNENCODABLE
Set to a filename (str type) that should not be able to be encoded by file
@ -838,18 +833,6 @@ The :mod:`test.support` module defines the following functions:
.. versionadded:: 3.9
.. function:: wait_threads_exit(timeout=60.0)
Context manager to wait until all threads created in the ``with`` statement
exit.
.. function:: start_threads(threads, unlock=None)
Context manager to start *threads*. It attempts to join the threads upon
exit.
.. function:: calcobjsize(fmt)
Return :func:`struct.calcsize` for ``nP{fmt}0n`` or, if ``gettotalrefcount``
@ -988,11 +971,6 @@ The :mod:`test.support` module defines the following functions:
the trace function.
.. decorator:: reap_threads(func)
Decorator to ensure the threads are cleaned up even if the test fails.
.. decorator:: bigmemtest(size, memuse, dry_run=True)
Decorator for bigmem tests.
@ -1110,23 +1088,6 @@ The :mod:`test.support` module defines the following functions:
preserve internal cache.
.. function:: threading_setup()
Return current thread count and copy of dangling threads.
.. function:: threading_cleanup(*original_values)
Cleanup up threads not specified in *original_values*. Designed to emit
a warning if a test leaves running threads in the background.
.. function:: join_thread(thread, timeout=30.0)
Join a *thread* within *timeout*. Raise an :exc:`AssertionError` if thread
is still alive after *timeout* seconds.
.. function:: reap_children()
Use this at the end of ``test_main`` whenever sub-processes are started.
@ -1140,39 +1101,6 @@ The :mod:`test.support` module defines the following functions:
is raised.
.. function:: catch_threading_exception()
Context manager catching :class:`threading.Thread` exception using
:func:`threading.excepthook`.
Attributes set when an exception is catched:
* ``exc_type``
* ``exc_value``
* ``exc_traceback``
* ``thread``
See :func:`threading.excepthook` documentation.
These attributes are deleted at the context manager exit.
Usage::
with support.catch_threading_exception() as cm:
# code spawning a thread which raises an exception
...
# check the thread exception, use cm attributes:
# exc_type, exc_value, exc_traceback, thread
...
# exc_type, exc_value, exc_traceback, thread attributes of cm no longer
# exists at this point
# (to avoid reference cycles)
.. versionadded:: 3.8
.. function:: catch_unraisable_exception()
Context manager catching unraisable exception using
@ -1628,3 +1556,81 @@ The module defines the following class:
.. method:: BytecodeTestCase.assertNotInBytecode(x, opname, argval=_UNSPECIFIED)
Throws :exc:`AssertionError` if *opname* is found.
:mod:`test.support.threading_helper` --- Utilities for threading tests
======================================================================
.. module:: test.support.threading_helper
:synopsis: Support for threading tests.
The :mod:`test.support.threading_helper` module provides support for threading tests.
.. versionadded:: 3.10
.. function:: join_thread(thread, timeout=None)
Join a *thread* within *timeout*. Raise an :exc:`AssertionError` if thread
is still alive after *timeout* seconds.
.. decorator:: reap_threads(func)
Decorator to ensure the threads are cleaned up even if the test fails.
.. function:: start_threads(threads, unlock=None)
Context manager to start *threads*. It attempts to join the threads upon
exit.
.. function:: threading_cleanup(*original_values)
Cleanup up threads not specified in *original_values*. Designed to emit
a warning if a test leaves running threads in the background.
.. function:: threading_setup()
Return current thread count and copy of dangling threads.
.. function:: wait_threads_exit(timeout=None)
Context manager to wait until all threads created in the ``with`` statement
exit.
.. function:: catch_threading_exception()
Context manager catching :class:`threading.Thread` exception using
:func:`threading.excepthook`.
Attributes set when an exception is catched:
* ``exc_type``
* ``exc_value``
* ``exc_traceback``
* ``thread``
See :func:`threading.excepthook` documentation.
These attributes are deleted at the context manager exit.
Usage::
with threading_helper.catch_threading_exception() as cm:
# code spawning a thread which raises an exception
...
# check the thread exception, use cm attributes:
# exc_type, exc_value, exc_traceback, thread
...
# exc_type, exc_value, exc_traceback, thread attributes of cm no longer
# exists at this point
# (to avoid reference cycles)
.. versionadded:: 3.8

View File

@ -251,7 +251,8 @@ quotes and using leading spaces. Multiple :option:`-s` options are treated
similarly.
If :option:`-n` is not given, a suitable number of loops is calculated by trying
successive powers of 10 until the total time is at least 0.2 seconds.
increasing numbers from the sequence 1, 2, 5, 10, 20, 50, ... until the total
time is at least 0.2 seconds.
:func:`default_timer` measurements can be affected by other programs running on
the same machine, so the best thing to do when accurate timing is necessary is

View File

@ -249,6 +249,47 @@ Example of output of the Python test suite::
See :meth:`Snapshot.statistics` for more options.
Record the current and peak size of all traced memory blocks
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The following code computes two sums like ``0 + 1 + 2 + ...`` inefficiently, by
creating a list of those numbers. This list consumes a lot of memory
temporarily. We can use :func:`get_traced_memory` and :func:`reset_peak` to
observe the small memory usage after the sum is computed as well as the peak
memory usage during the computations::
import tracemalloc
tracemalloc.start()
# Example code: compute a sum with a large temporary list
large_sum = sum(list(range(100000)))
first_size, first_peak = tracemalloc.get_traced_memory()
tracemalloc.reset_peak()
# Example code: compute a sum with a small temporary list
small_sum = sum(list(range(1000)))
second_size, second_peak = tracemalloc.get_traced_memory()
print(f"{first_size=}, {first_peak=}")
print(f"{second_size=}, {second_peak=}")
Output::
first_size=664, first_peak=3592984
second_size=804, second_peak=29704
Using :func:`reset_peak` ensured we could accurately record the peak during the
computation of ``small_sum``, even though it is much smaller than the overall
peak size of memory blocks since the :func:`start` call. Without the call to
:func:`reset_peak`, ``second_peak`` would still be the peak from the
computation ``large_sum`` (that is, equal to ``first_peak``). In this case,
both peaks are much higher than the final memory usage, and which suggests we
could optimise (by removing the unnecessary call to :class:`list`, and writing
``sum(range(...))``).
API
---
@ -289,6 +330,24 @@ Functions
:mod:`tracemalloc` module as a tuple: ``(current: int, peak: int)``.
.. function:: reset_peak()
Set the peak size of memory blocks traced by the :mod:`tracemalloc` module
to the current size.
Do nothing if the :mod:`tracemalloc` module is not tracing memory
allocations.
This function only modifies the recorded peak size, and does not modify or
clear any traces, unlike :func:`clear_traces`. Snapshots taken with
:func:`take_snapshot` before a call to :func:`reset_peak` can be
meaningfully compared to snapshots taken after the call.
See also :func:`get_traced_memory`.
.. versionadded:: 3.10
.. function:: get_tracemalloc_memory()
Get the memory usage in bytes of the :mod:`tracemalloc` module used to store

View File

@ -329,6 +329,12 @@ Standard names are defined for the following types:
Return a new view of the underlying mapping's values.
.. describe:: reversed(proxy)
Return a reverse iterator over the keys of the underlying mapping.
.. versionadded:: 3.9
Additional Utility Classes and Functions
----------------------------------------
@ -349,8 +355,7 @@ Additional Utility Classes and Functions
self.__dict__.update(kwargs)
def __repr__(self):
keys = sorted(self.__dict__)
items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys)
items = (f"{k}={v!r}" for k, v in self.__dict__.items())
return "{}({})".format(type(self).__name__, ", ".join(items))
def __eq__(self, other):
@ -362,6 +367,9 @@ Additional Utility Classes and Functions
.. versionadded:: 3.3
.. versionchanged:: 3.9
Attribute order in the repr changed from alphabetical to insertion (like
``dict``).
.. function:: DynamicClassAttribute(fget=None, fset=None, fdel=None, doc=None)
@ -373,7 +381,7 @@ Additional Utility Classes and Functions
class's __getattr__ method; this is done by raising AttributeError.
This allows one to have properties active on an instance, and have virtual
attributes on the class with the same name (see Enum for an example).
attributes on the class with the same name (see :class:`enum.Enum` for an example).
.. versionadded:: 3.4

View File

@ -1021,9 +1021,9 @@ The module defines the following classes, functions and decorators:
``List[ForwardRef("SomeClass")]``. This class should not be instantiated by
a user, but may be used by introspection tools.
.. function:: NewType(typ)
.. function:: NewType(name, tp)
A helper function to indicate a distinct types to a typechecker,
A helper function to indicate a distinct type to a typechecker,
see :ref:`distinct`. At runtime it returns a function that returns
its argument. Usage::

View File

@ -1235,7 +1235,7 @@ Here is an example of doing a ``PUT`` request using :class:`Request`::
import urllib.request
DATA = b'some data'
req = urllib.request.Request(url='http://localhost:8080', data=DATA,method='PUT')
req = urllib.request.Request(url='http://localhost:8080', data=DATA, method='PUT')
with urllib.request.urlopen(req) as f:
pass
print(f.status)

View File

@ -249,7 +249,8 @@ creation according to their needs, the :class:`EnvBuilder` class.
There is also a module-level convenience function:
.. function:: create(env_dir, system_site_packages=False, clear=False, \
symlinks=False, with_pip=False, prompt=None)
symlinks=False, with_pip=False, prompt=None, \
upgrade_deps=False)
Create an :class:`EnvBuilder` with the given keyword arguments, and call its
:meth:`~EnvBuilder.create` method with the *env_dir* argument.
@ -262,6 +263,9 @@ There is also a module-level convenience function:
.. versionchanged:: 3.6
Added the ``prompt`` parameter
.. versionchanged:: 3.9
Added the ``upgrade_deps`` parameter
An example of extending ``EnvBuilder``
--------------------------------------

413
Doc/library/zoneinfo.rst Normal file
View File

@ -0,0 +1,413 @@
:mod:`zoneinfo` --- IANA time zone support
==========================================
.. module:: zoneinfo
:synopsis: IANA time zone support
.. versionadded:: 3.9
.. moduleauthor:: Paul Ganssle <paul@ganssle.io>
.. sectionauthor:: Paul Ganssle <paul@ganssle.io>
--------------
The :mod:`zoneinfo` module provides a concrete time zone implementation to
support the IANA time zone database as originally specified in :pep:`615`. By
default, :mod:`zoneinfo` uses the system's time zone data if available; if no
system time zone data is available, the library will fall back to using the
first-party `tzdata`_ package available on PyPI.
.. seealso::
Module: :mod:`datetime`
Provides the :class:`~datetime.time` and :class:`~datetime.datetime`
types with which the :class:`ZoneInfo` class is designed to be used.
Package `tzdata`_
First-party package maintained by the CPython core developers to supply
time zone data via PyPI.
Using ``ZoneInfo``
------------------
:class:`ZoneInfo` is a concrete implementation of the :class:`datetime.tzinfo`
abstract base class, and is intended to be attached to ``tzinfo``, either via
the constructor, the :meth:`datetime.replace <datetime.datetime.replace>`
method or :meth:`datetime.astimezone <datetime.datetime.astimezone>`::
>>> from zoneinfo import ZoneInfo
>>> from datetime import datetime, timedelta
>>> dt = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo("America/Los_Angeles"))
>>> print(dt)
2020-10-31 12:00:00-07:00
>>> dt.tzname()
'PDT'
Datetimes constructed in this way are compatible with datetime arithmetic and
handle daylight saving time transitions with no further intervention::
>>> dt_add = dt + timedelta(days=1)
>>> print(dt_add)
2020-11-01 12:00:00-08:00
>>> dt_add.tzname()
'PST'
These time zones also support the :attr:`~datetime.datetime.fold` attribute
introduced in :pep:`495`. During offset transitions which induce ambiguous
times (such as a daylight saving time to standard time transition), the offset
from *before* the transition is used when ``fold=0``, and the offset *after*
the transition is used when ``fold=1``, for example::
>>> dt = datetime(2020, 11, 1, 1, tzinfo=ZoneInfo("America/Los_Angeles"))
>>> print(dt)
2020-11-01 01:00:00-07:00
>>> print(dt.replace(fold=1))
2020-11-01 01:00:00-08:00
When converting from another time zone, the fold will be set to the correct
value::
>>> from datetime import timezone
>>> LOS_ANGELES = ZoneInfo("America/Los_Angeles")
>>> dt_utc = datetime(2020, 11, 1, 8, tzinfo=timezone.utc)
>>> # Before the PDT -> PST transition
>>> print(dt_utc.astimezone(LOS_ANGELES))
2020-11-01 01:00:00-07:00
>>> # After the PDT -> PST transition
>>> print((dt_utc + timedelta(hours=1)).astimezone(LOS_ANGELES))
2020-11-01 01:00:00-08:00
Data sources
------------
The ``zoneinfo`` module does not directly provide time zone data, and instead
pulls time zone information from the system time zone database or the
first-party PyPI package `tzdata`_, if available. Some systems, including
notably Windows systems, do not have an IANA database available, and so for
projects targeting cross-platform compatibility that require time zone data, it
is recommended to declare a dependency on tzdata. If neither system data nor
tzdata are available, all calls to :class:`ZoneInfo` will raise
:exc:`ZoneInfoNotFoundError`.
.. _zoneinfo_data_configuration:
Configuring the data sources
****************************
When ``ZoneInfo(key)`` is called, the constructor first searches the
directories specified in :data:`TZPATH` for a file matching ``key``, and on
failure looks for a match in the tzdata package. This behavior can be
configured in three ways:
1. The default :data:`TZPATH` when not otherwise specified can be configured at
:ref:`compile time <zoneinfo_data_compile_time_config>`.
2. :data:`TZPATH` can be configured using :ref:`an environment variable
<zoneinfo_data_environment_var>`.
3. At :ref:`runtime <zoneinfo_data_runtime_config>`, the search path can be
manipulated using the :func:`reset_tzpath` function.
.. _zoneinfo_data_compile_time_config:
Compile-time configuration
^^^^^^^^^^^^^^^^^^^^^^^^^^
The default :data:`TZPATH` includes several common deployment locations for the
time zone database (except on Windows, where there are no "well-known"
locations for time zone data). On POSIX systems, downstream distributors and
those building Python from source who know where their system
time zone data is deployed may change the default time zone path by specifying
the compile-time option ``TZPATH`` (or, more likely, the ``configure`` flag
``--with-tzpath``), which should be a string delimited by :data:`os.pathsep`.
On all platforms, the configured value is available as the ``TZPATH`` key in
:func:`sysconfig.get_config_var`.
.. _zoneinfo_data_environment_var:
Environment configuration
^^^^^^^^^^^^^^^^^^^^^^^^^
When initializing :data:`TZPATH` (either at import time or whenever
:func:`reset_tzpath` is called with no arguments), the ``zoneinfo`` module will
use the environment variable ``PYTHONTZPATH``, if it exists, to set the search
path.
.. envvar:: PYTHONTZPATH
This is an :data:`os.pathsep`-separated string containing the time zone
search path to use. It must consist of only absolute rather than relative
paths. Relative components specified in ``PYTHONTZPATH`` will not be used,
but otherwise the behavior when a relative path is specified is
implementation-defined; CPython will raise :exc:`InvalidTZPathWarning`, but
other implementations are free to silently ignore the erroneous component
or raise an exception.
To set the system to ignore the system data and use the tzdata package
instead, set ``PYTHONTZPATH=""``.
.. _zoneinfo_data_runtime_config:
Runtime configuration
^^^^^^^^^^^^^^^^^^^^^
The TZ search path can also be configured at runtime using the
:func:`reset_tzpath` function. This is generally not an advisable operation,
though it is reasonable to use it in test functions that require the use of a
specific time zone path (or require disabling access to the system time zones).
The ``ZoneInfo`` class
----------------------
.. class:: ZoneInfo(key)
A concrete :class:`datetime.tzinfo` subclass that represents an IANA time
zone specified by the string ``key``. Calls to the primary constructor will
always return objects that compare identically; put another way, barring
cache invalidation via :meth:`ZoneInfo.clear_cache`, for all values of
``key``, the following assertion will always be true:
.. code-block:: python
a = ZoneInfo(key)
b = ZoneInfo(key)
assert a is b
``key`` must be in the form of a relative, normalized POSIX path, with no
up-level references. The constructor will raise :exc:`ValueError` if a
non-conforming key is passed.
If no file matching ``key`` is found, the constructor will raise
:exc:`ZoneInfoNotFoundError`.
The ``ZoneInfo`` class has two alternate constructors:
.. classmethod:: ZoneInfo.from_file(fobj, /, key=None)
Constructs a ``ZoneInfo`` object from a file-like object returning bytes
(e.g. a file opened in binary mode or an :class:`io.BytesIO` object).
Unlike the primary constructor, this always constructs a new object.
The ``key`` parameter sets the name of the zone for the purposes of
:py:meth:`~object.__str__` and :py:meth:`~object.__repr__`.
Objects created via this constructor cannot be pickled (see `pickling`_).
.. classmethod:: ZoneInfo.no_cache(key)
An alternate constructor that bypasses the constructor's cache. It is
identical to the primary constructor, but returns a new object on each
call. This is most likely to be useful for testing or demonstration
purposes, but it can also be used to create a system with a different cache
invalidation strategy.
Objects created via this constructor will also bypass the cache of a
deserializing process when unpickled.
.. TODO: Add "See `cache_behavior`_" reference when that section is ready.
.. caution::
Using this constructor may change the semantics of your datetimes in
surprising ways, only use it if you know that you need to.
The following class methods are also available:
.. classmethod:: ZoneInfo.clear_cache(*, only_keys=None)
A method for invalidating the cache on the ``ZoneInfo`` class. If no
arguments are passed, all caches are invalidated and the next call to
the primary constructor for each key will return a new instance.
If an iterable of key names is passed to the ``only_keys`` parameter, only
the specified keys will be removed from the cache. Keys passed to
``only_keys`` but not found in the cache are ignored.
.. TODO: Add "See `cache_behavior`_" reference when that section is ready.
.. warning::
Invoking this function may change the semantics of datetimes using
``ZoneInfo`` in surprising ways; this modifies process-wide global state
and thus may have wide-ranging effects. Only use it if you know that you
need to.
The class has one attribute:
.. attribute:: ZoneInfo.key
This is a read-only :term:`attribute` that returns the value of ``key``
passed to the constructor, which should be a lookup key in the IANA time
zone database (e.g. ``America/New_York``, ``Europe/Paris`` or
``Asia/Tokyo``).
For zones constructed from file without specifying a ``key`` parameter,
this will be set to ``None``.
.. note::
Although it is a somewhat common practice to expose these to end users,
these values are designed to be primary keys for representing the
relevant zones and not necessarily user-facing elements. Projects like
CLDR (the Unicode Common Locale Data Repository) can be used to get
more user-friendly strings from these keys.
String representations
**********************
The string representation returned when calling :py:class:`str` on a
:class:`ZoneInfo` object defaults to using the :attr:`ZoneInfo.key` attribute (see
the note on usage in the attribute documentation)::
>>> zone = ZoneInfo("Pacific/Kwajalein")
>>> str(zone)
'Pacific/Kwajalein'
>>> dt = datetime(2020, 4, 1, 3, 15, tzinfo=zone)
>>> f"{dt.isoformat()} [{dt.tzinfo}]"
'2020-04-01T03:15:00+12:00 [Pacific/Kwajalein]'
For objects constructed from a file without specifying a ``key`` parameter,
``str`` falls back to calling :func:`repr`. ``ZoneInfo``'s ``repr`` is
implementation-defined and not necessarily stable between versions, but it is
guaranteed not to be a valid ``ZoneInfo`` key.
.. _pickling:
Pickle serialization
********************
Rather than serializing all transition data, ``ZoneInfo`` objects are
serialized by key, and ``ZoneInfo`` objects constructed from files (even those
with a value for ``key`` specified) cannot be pickled.
The behavior of a ``ZoneInfo`` file depends on how it was constructed:
1. ``ZoneInfo(key)``: When constructed with the primary constructor, a
``ZoneInfo`` object is serialized by key, and when deserialized, the
deserializing process uses the primary and thus it is expected that these
are expected to be the same object as other references to the same time
zone. For example, if ``europe_berlin_pkl`` is a string containing a pickle
constructed from ``ZoneInfo("Europe/Berlin")``, one would expect the
following behavior:
.. code-block:: pycon
>>> a = ZoneInfo("Europe/Berlin")
>>> b = pickle.loads(europe_berlin_pkl)
>>> a is b
True
2. ``ZoneInfo.no_cache(key)``: When constructed from the cache-bypassing
constructor, the ``ZoneInfo`` object is also serialized by key, but when
deserialized, the deserializing process uses the cache bypassing
constructor. If ``europe_berlin_pkl_nc`` is a string containing a pickle
constructed from ``ZoneInfo.no_cache("Europe/Berlin")``, one would expect
the following behavior:
.. code-block:: pycon
>>> a = ZoneInfo("Europe/Berlin")
>>> b = pickle.loads(europe_berlin_pkl_nc)
>>> a is b
False
3. ``ZoneInfo.from_file(fobj, /, key=None)``: When constructed from a file, the
``ZoneInfo`` object raises an exception on pickling. If an end user wants to
pickle a ``ZoneInfo`` constructed from a file, it is recommended that they
use a wrapper type or a custom serialization function: either serializing by
key or storing the contents of the file object and serializing that.
This method of serialization requires that the time zone data for the required
key be available on both the serializing and deserializing side, similar to the
way that references to classes and functions are expected to exist in both the
serializing and deserializing environments. It also means that no guarantees
are made about the consistency of results when unpickling a ``ZoneInfo``
pickled in an environment with a different version of the time zone data.
Functions
---------
.. function:: available_timezones()
Get a set containing all the valid keys for IANA time zones available
anywhere on the time zone path. This is recalculated on every call to the
function.
This function only includes canonical zone names and does not include
"special" zones such as those under the ``posix/`` and ``right/``
directories, or the ``posixrules`` zone.
.. caution::
This function may open a large number of files, as the best way to
determine if a file on the time zone path is a valid time zone is to
read the "magic string" at the beginning.
.. note::
These values are not designed to be exposed to end-users; for user
facing elements, applications should use something like CLDR (the
Unicode Common Locale Data Repository) to get more user-friendly
strings. See also the cautionary note on :attr:`ZoneInfo.key`.
.. function:: reset_tzpath(to=None)
Sets or resets the time zone search path (:data:`TZPATH`) for the module.
When called with no arguments, :data:`TZPATH` is set to the default value.
Calling ``reset_tzpath`` will not invalidate the :class:`ZoneInfo` cache,
and so calls to the primary ``ZoneInfo`` constructor will only use the new
``TZPATH`` in the case of a cache miss.
The ``to`` parameter must be a :term:`sequence` of strings or
:class:`os.PathLike` and not a string, all of which must be absolute paths.
:exc:`ValueError` will be raised if something other than an absolute path
is passed.
Globals
-------
.. data:: TZPATH
A read-only sequence representing the time zone search path -- when
constructing a ``ZoneInfo`` from a key, the key is joined to each entry in
the ``TZPATH``, and the first file found is used.
``TZPATH`` may contain only absolute paths, never relative paths,
regardless of how it is configured.
The object that ``zoneinfo.TZPATH`` points to may change in response to a
call to :func:`reset_tzpath`, so it is recommended to use
``zoneinfo.TZPATH`` rather than importing ``TZPATH`` from ``zoneinfo`` or
assigning a long-lived variable to ``zoneinfo.TZPATH``.
For more information on configuring the time zone search path, see
:ref:`zoneinfo_data_configuration`.
Exceptions and warnings
-----------------------
.. exception:: ZoneInfoNotFoundError
Raised when construction of a :class:`ZoneInfo` object fails because the
specified key could not be found on the system. This is a subclass of
:exc:`KeyError`.
.. exception:: InvalidTZPathWarning
Raised when :envvar:`PYTHONTZPATH` contains an invalid component that will
be filtered out, such as a relative path.
.. Links and references:
.. _tzdata: https://pypi.org/project/tzdata/

View File

@ -325,7 +325,7 @@ of identifiers is based on NFKC.
A non-normative HTML file listing all valid identifier characters for Unicode
4.1 can be found at
https://www.dcl.hpi.uni-potsdam.de/home/loewis/table-3131.html.
https://www.unicode.org/Public/13.0.0/ucd/DerivedCoreProperties.txt
.. _keywords:

View File

@ -0,0 +1,51 @@
import os
import sys
sys.path.append(os.path.abspath("../Parser/"))
from pygments.lexer import RegexLexer, bygroups, include, words
from pygments.token import (Comment, Generic, Keyword, Name, Operator,
Punctuation, Text)
from asdl import builtin_types
from sphinx.highlighting import lexers
class ASDLLexer(RegexLexer):
name = "ASDL"
aliases = ["asdl"]
filenames = ["*.asdl"]
_name = r"([^\W\d]\w*)"
_text_ws = r"(\s*)"
tokens = {
"ws": [
(r"\n", Text),
(r"\s+", Text),
(r"--.*?$", Comment.Singleline),
],
"root": [
include("ws"),
(
r"(module)" + _text_ws + _name,
bygroups(Keyword, Text, Name.Tag),
),
(
r"(\w+)(\*\s|\?\s|\s)(\w+)",
bygroups(Name.Builtin.Pseudo, Operator, Name),
),
(words(builtin_types), Name.Builtin),
(r"attributes", Name.Builtin),
(
_name + _text_ws + "(=)",
bygroups(Name, Text, Operator),
),
(_name, Name.Class),
(r"\|", Operator),
(r"{|}|\(|\)", Punctuation),
(r".", Text),
],
}
def setup(app):
lexers["asdl"] = ASDLLexer()
return {'version': '1.0', 'parallel_read_safe': True}

View File

@ -10,7 +10,8 @@
'(?:release/\\d.\\d[\\x\\d\\.]*)'];
var all_versions = {
'3.9': 'dev (3.9)',
'3.10': 'dev (3.10)',
'3.9': 'pre (3.9)',
'3.8': '3.8',
'3.7': '3.7',
'3.6': '3.6',

View File

@ -2,7 +2,8 @@
<p><a href="{{ pathto('download') }}">{% trans %}Download these documents{% endtrans %}</a></p>
<h3>{% trans %}Docs by version{% endtrans %}</h3>
<ul>
<li><a href="https://docs.python.org/3.9/">{% trans %}Python 3.9 (in development){% endtrans %}</a></li>
<li><a href="https://docs.python.org/3.10/">{% trans %}Python 3.10 (in development){% endtrans %}</a></li>
<li><a href="https://docs.python.org/3.9/">{% trans %}Python 3.9 (pre-release){% endtrans %}</a></li>
<li><a href="https://docs.python.org/3.8/">{% trans %}Python 3.8 (stable){% endtrans %}</a></li>
<li><a href="https://docs.python.org/3.7/">{% trans %}Python 3.7 (stable){% endtrans %}</a></li>
<li><a href="https://docs.python.org/3.6/">{% trans %}Python 3.6 (security-fixes){% endtrans %}</a></li>

View File

@ -70,6 +70,9 @@ Code that modifies a collection while iterating over that same collection can
be tricky to get right. Instead, it is usually more straight-forward to loop
over a copy of the collection or to create a new collection::
# Create a sample collection
users = {'Hans': 'active', 'Éléonore': 'inactive', '景太郎': 'active'}
# Strategy: Iterate over a copy
for user, status in users.copy().items():
if status == 'inactive':

View File

@ -613,6 +613,21 @@ direction and then call the :func:`reversed` function. ::
To loop over a sequence in sorted order, use the :func:`sorted` function which
returns a new sorted list while leaving the source unaltered. ::
>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for i in sorted(basket):
... print(i)
...
apple
apple
banana
orange
orange
pear
Using :func:`set` on a sequence eliminates duplicate elements. The use of
:func:`sorted` in combination with :func:`set` over a sequence is an idiomatic
way to loop over unique elements of the sequence in sorted order. ::
>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
... print(f)

View File

@ -67,7 +67,7 @@ The rest of the line provides detail based on the type of exception and what
caused it.
The preceding part of the error message shows the context where the exception
happened, in the form of a stack traceback. In general it contains a stack
occurred, in the form of a stack traceback. In general it contains a stack
traceback listing source lines; however, it will not display lines read from
standard input.

View File

@ -172,7 +172,7 @@ Positional and keyword arguments can be arbitrarily combined::
If you have a really long format string that you don't want to split up, it
would be nice if you could reference the variables to be formatted by name
instead of by position. This can be done by simply passing the dict and using
square brackets ``'[]'`` to access the keys ::
square brackets ``'[]'`` to access the keys. ::
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; '
@ -257,10 +257,10 @@ left with zeros. It understands about plus and minus signs::
Old string formatting
---------------------
The ``%`` operator can also be used for string formatting. It interprets the
left argument much like a :c:func:`sprintf`\ -style format string to be applied
to the right argument, and returns the string resulting from this formatting
operation. For example::
The % operator (modulo) can also be used for string formatting. Given ``'string'
% values``, instances of ``%`` in ``string`` are replaced with zero or more
elements of ``values``. This operation is commonly known as string
interpolation. For example::
>>> import math
>>> print('The value of pi is approximately %5.3f.' % math.pi)

View File

@ -10,13 +10,13 @@ Using the Python Interpreter
Invoking the Interpreter
========================
The Python interpreter is usually installed as :file:`/usr/local/bin/python3.9`
The Python interpreter is usually installed as :file:`/usr/local/bin/python3.10`
on those machines where it is available; putting :file:`/usr/local/bin` in your
Unix shell's search path makes it possible to start it by typing the command:
.. code-block:: text
python3.9
python3.10
to the shell. [#]_ Since the choice of the directory where the interpreter lives
is an installation option, other places are possible; check with your local
@ -24,7 +24,7 @@ Python guru or system administrator. (E.g., :file:`/usr/local/python` is a
popular alternative location.)
On Windows machines where you have installed Python from the :ref:`Microsoft Store
<windows-store>`, the :file:`python3.9` command will be available. If you have
<windows-store>`, the :file:`python3.10` command will be available. If you have
the :ref:`py.exe launcher <launcher>` installed, you can use the :file:`py`
command. See :ref:`setting-envvars` for other ways to launch Python.
@ -97,8 +97,8 @@ before printing the first prompt:
.. code-block:: shell-session
$ python3.9
Python 3.9 (default, June 4 2019, 09:25:04)
$ python3.10
Python 3.10 (default, June 4 2019, 09:25:04)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

View File

@ -15,7 +15,7 @@ operating system::
>>> import os
>>> os.getcwd() # Return the current working directory
'C:\\Python39'
'C:\\Python310'
>>> os.chdir('/server/accesslogs') # Change current working directory
>>> os.system('mkdir today') # Run the command mkdir in the system shell
0

View File

@ -278,7 +278,7 @@ applications include caching objects that are expensive to create::
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
d['primary'] # entry was automatically removed
File "C:/python39/lib/weakref.py", line 46, in __getitem__
File "C:/python310/lib/weakref.py", line 46, in __getitem__
o = self.data[key]()
KeyError: 'primary'

View File

@ -27,9 +27,8 @@ What you get after installing is a number of things:
* A :file:`Python 3.9` folder in your :file:`Applications` folder. In here
you find IDLE, the development environment that is a standard part of official
Python distributions; PythonLauncher, which handles double-clicking Python
scripts from the Finder; and the "Build Applet" tool, which allows you to
package Python scripts as standalone applications on your system.
Python distributions; and PythonLauncher, which handles double-clicking Python
scripts from the Finder.
* A framework :file:`/Library/Frameworks/Python.framework`, which includes the
Python executable and libraries. The installer adds this location to your shell
@ -159,11 +158,6 @@ https://riverbankcomputing.com/software/pyqt/intro.
Distributing Python Applications on the Mac
===========================================
The "Build Applet" tool that is placed in the MacPython 3.6 folder is fine for
packaging small Python scripts on your own machine to run as a standard Mac
application. This tool, however, is not robust enough to distribute Python
applications to other users.
The standard tool for deploying standalone Python applications on the Mac is
:program:`py2app`. More information on installing and using py2app can be found
at http://undefined.org/python/#py2app.

View File

@ -91,7 +91,7 @@ The command, if run with ``-h``, will show the available options::
PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
See `About Execution Policies
<ttps:/go.microsoft.com/fwlink/?LinkID=135170>`_
<https://go.microsoft.com/fwlink/?LinkID=135170>`_
for more information.
The created ``pyvenv.cfg`` file also includes the

156
Doc/whatsnew/3.10.rst Normal file
View File

@ -0,0 +1,156 @@
****************************
What's New In Python 3.10
****************************
:Release: |release|
:Date: |today|
.. Rules for maintenance:
* Anyone can add text to this document. Do not spend very much time
on the wording of your changes, because your text will probably
get rewritten to some degree.
* The maintainer will go through Misc/NEWS periodically and add
changes; it's therefore more important to add your changes to
Misc/NEWS than to this file.
* This is not a complete list of every single change; completeness
is the purpose of Misc/NEWS. Some changes I consider too small
or esoteric to include. If such a change is added to the text,
I'll just remove it. (This is another reason you shouldn't spend
too much time on writing your addition.)
* If you want to draw your new text to the attention of the
maintainer, add 'XXX' to the beginning of the paragraph or
section.
* It's OK to just add a fragmentary note about a change. For
example: "XXX Describe the transmogrify() function added to the
socket module." The maintainer will research the change and
write the necessary text.
* You can comment out your additions if you like, but it's not
necessary (especially when a final release is some months away).
* Credit the author of a patch or bugfix. Just the name is
sufficient; the e-mail address isn't necessary.
* It's helpful to add the bug/patch number as a comment:
XXX Describe the transmogrify() function added to the socket
module.
(Contributed by P.Y. Developer in :issue:`12345`.)
This saves the maintainer the effort of going through the Mercurial log
when researching a change.
This article explains the new features in Python 3.10, compared to 3.9.
For full details, see the :ref:`changelog <changelog>`.
.. note::
Prerelease users should be aware that this document is currently in draft
form. It will be updated substantially as Python 3.10 moves towards release,
so it's worth checking back even after reading earlier versions.
Summary -- Release highlights
=============================
.. This section singles out the most important changes in Python 3.10.
Brevity is key.
.. PEP-sized items next.
New Features
============
Other Language Changes
======================
* Builtin and extension functions that take integer arguments no longer accept
:class:`~decimal.Decimal`\ s, :class:`~fractions.Fraction`\ s and other
objects that can be converted to integers only with a loss (e.g. that have
the :meth:`~object.__int__` method but do not have the
:meth:`~object.__index__` method).
(Contributed by Serhiy Storchaka in :issue:`37999`.)
New Modules
===========
* None yet.
Improved Modules
================
tracemalloc
-----------
Added :func:`tracemalloc.reset_peak` to set the peak size of traced memory
blocks to the current size, to measure the peak of specific pieces of code.
(Contributed by Huon Wilson in :issue:`40630`.)
Optimizations
=============
Deprecated
==========
Removed
=======
Porting to Python 3.10
======================
This section lists previously described changes and other bugfixes
that may require changes to your code.
Build Changes
=============
C API Changes
=============
New Features
------------
The result of :c:func:`PyNumber_Index` now always has exact type :class:`int`.
Previously, the result could have been an instance of a subclass of ``int``.
(Contributed by Serhiy Storchaka in :issue:`40792`.)
Porting to Python 3.10
----------------------
* Since :c:func:`Py_TYPE()` is changed to the inline static function,
``Py_TYPE(obj) = new_type`` must be replaced with ``Py_SET_TYPE(obj, new_type)``:
see :c:func:`Py_SET_TYPE()` (available since Python 3.9).
(Contributed by Dong-hee Na in :issue:`39573`.)
* Since :c:func:`Py_REFCNT()` is changed to the inline static function,
``Py_REFCNT(obj) = new_refcnt`` must be replaced with ``Py_SET_REFCNT(obj, new_refcnt)``:
see :c:func:`Py_SET_REFCNT()` (available since Python 3.9).
(Contributed by Victor Stinner in :issue:`39573`.)
* Since :c:func:`Py_SIZE()` is changed to the inline static function,
``Py_SIZE(obj) = new_size`` must be replaced with ``Py_SET_SIZE(obj, new_size)``:
see :c:func:`Py_SET_SIZE()` (available since Python 3.9).
(Contributed by Victor Stinner in :issue:`39573`.)
Removed
-------

View File

@ -428,8 +428,8 @@ Other Language Changes
lastname, *members = family.split()
return lastname.upper(), *members
>>> parse('simpsons homer marge bart lisa sally')
('SIMPSONS', 'homer', 'marge', 'bart', 'lisa', 'sally')
>>> parse('simpsons homer marge bart lisa maggie')
('SIMPSONS', 'homer', 'marge', 'bart', 'lisa', 'maggie')
(Contributed by David Cuthbert and Jordan Chapman in :issue:`32117`.)
@ -1692,7 +1692,7 @@ Deprecated
:meth:`~gettext.NullTranslations.set_output_charset`, and the *codeset*
parameter of functions :func:`~gettext.translation` and
:func:`~gettext.install` are also deprecated, since they are only used for
for the ``l*gettext()`` functions.
the ``l*gettext()`` functions.
(Contributed by Serhiy Storchaka in :issue:`33710`.)
* The :meth:`~threading.Thread.isAlive()` method of :class:`threading.Thread`

View File

@ -113,7 +113,7 @@ PEP 616: New removeprefix() and removesuffix() string methods
to easily remove an unneeded prefix or a suffix from a string. Corresponding
``bytes``, ``bytearray``, and ``collections.UserString`` methods have also been
added. See :pep:`616` for a full description. (Contributed by Dennis Sweeney in
:issue:`18939`.)
:issue:`39939`.)
PEP 585: Builtin Generic Types
------------------------------
@ -205,7 +205,44 @@ Other Language Changes
New Modules
===========
* None yet.
zoneinfo
--------
The :mod:`zoneinfo` module brings support for the IANA time zone database to
the standard library. It adds :class:`zoneinfo.ZoneInfo`, a concrete
:class:`datetime.tzinfo` implementation backed by the system's time zone data.
Example::
>>> from zoneinfo import ZoneInfo
>>> from datetime import datetime, timedelta
>>> # Daylight saving time
>>> dt = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo("America/Los_Angeles"))
>>> print(dt)
2020-10-31 12:00:00-07:00
>>> dt.tzname()
'PDT'
>>> # Standard time
>>> dt += timedelta(days=7)
>>> print(dt)
2020-11-07 12:00:00-08:00
>>> print(dt.tzname())
PST
As a fall-back source of data for platforms that don't ship the IANA database,
the |tzdata|_ module was released as a first-party package -- distributed via
PyPI and maintained by the CPython core team.
.. |tzdata| replace:: ``tzdata``
.. _tzdata: https://pypi.org/project/tzdata/
.. seealso::
:pep:`615` -- Support for the IANA Time Zone Database in the Standard Library
PEP written and implemented by Paul Ganssle
Improved Modules
@ -245,6 +282,22 @@ that schedules a shutdown for the default executor that waits on the
Added :class:`asyncio.PidfdChildWatcher`, a Linux-specific child watcher
implementation that polls process file descriptors. (:issue:`38692`)
Added a new :term:`coroutine` :func:`asyncio.to_thread`. It is mainly used for
running IO-bound functions in a separate thread to avoid blocking the event
loop, and essentially works as a high-level version of
:meth:`~asyncio.loop.run_in_executor` that can directly take keyword arguments.
(Contributed by Kyle Stanley and Yury Selivanov in :issue:`32309`.)
compileall
----------
Added new possibility to use hardlinks for duplicated ``.pyc`` files: *hardlink_dupes* parameter and --hardlink-dupes command line option.
(Contributed by Lumír 'Frenzy' Balhar in :issue:`40495`.)
Added new options for path manipulation in resulting ``.pyc`` files: *stripdir*, *prependdir*, *limit_sl_dest* parameters and -s, -p, -e command line options.
Added the possibility to specify the option for an optimization level multiple times.
(Contributed by Lumír 'Frenzy' Balhar in :issue:`38112`.)
concurrent.futures
------------------
@ -271,6 +324,20 @@ Add :func:`curses.get_escdelay`, :func:`curses.set_escdelay`,
:func:`curses.get_tabsize`, and :func:`curses.set_tabsize` functions.
(Contributed by Anthony Sottile in :issue:`38312`.)
datetime
--------
The :meth:`~datetime.date.isocalendar()` of :class:`datetime.date`
and :meth:`~datetime.datetime.isocalendar()` of :class:`datetime.datetime`
methods now returns a :func:`~collections.namedtuple` instead of a :class:`tuple`.
(Contributed by Dong-hee Na in :issue:`24416`.)
distutils
---------
The :command:`upload` command now creates SHA2-256 and Blake2b-256 hash
digests. It skips MD5 on platforms that block MD5 digest.
(Contributed by Christian Heimes in :issue:`40698`.)
fcntl
-----
@ -304,6 +371,15 @@ Added a new function :func:`gc.is_finalized` to check if an object has been
finalized by the garbage collector. (Contributed by Pablo Galindo in
:issue:`39322`.)
hashlib
-------
Builtin hash modules can now be disabled with
``./configure --without-builtin-hashlib-hashes`` or selectively enabled with
e.g. ``./configure --with-builtin-hashlib-hashes=sha3,blake2`` to force use
of OpenSSL based implementation.
(Contributed by Christian Heimes in :issue:`40479`)
http
----
@ -461,6 +537,17 @@ The :mod:`socket` module now exports the :data:`~socket.CAN_RAW_JOIN_FILTERS`
constant on Linux 4.1 and greater.
(Contributed by Stefan Tatschner and Zackery Spytz in :issue:`25780`.)
The socket module now supports the :data:`~socket.CAN_J1939` protocol on
platforms that support it. (Contributed by Karl Ding in :issue:`40291`.)
time
----
On AIX, :func:`~time.thread_time` is now implemented with ``thread_cputime()``
which has nanosecond resolution, rather than
``clock_gettime(CLOCK_THREAD_CPUTIME_ID)`` which has a resolution of 10 ms.
(Contributed by Batuhan Taskaya in :issue:`40192`)
sys
---
@ -471,6 +558,10 @@ most platforms. On Fedora and SuSE, it is equal to ``"lib64"`` on 64-bit
platforms.
(Contributed by Jan Matějek, Matěj Cepl, Charalampos Stratakis and Victor Stinner in :issue:`1294959`.)
Previously, :attr:`sys.stderr` was block-buffered when non-interactive. Now
``stderr`` defaults to always being line-buffered.
(Contributed by Jendrik Seipp in :issue:`13601`.)
typing
------
@ -514,7 +605,7 @@ Optimizations
sums = [s for s in [0] for x in data for s in [s + x]]
Unlike to the ``:=`` operator this idiom does not leak a variable to the
Unlike the ``:=`` operator this idiom does not leak a variable to the
outer scope.
(Contributed by Serhiy Storchaka in :issue:`32856`.)
@ -533,6 +624,61 @@ Optimizations
(Contributed by Ed Maste, Conrad Meyer, Kyle Evans, Kubilay Kocak and Victor
Stinner in :issue:`38061`.)
Here's a summary of performance improvements from Python 3.4 through Python 3.9:
.. code-block:: none
Python version 3.4 3.5 3.6 3.7 3.8 3.9
-------------- --- --- --- --- --- ---
Variable and attribute read access:
read_local 7.1 7.1 5.4 5.1 3.9 4.0
read_nonlocal 7.1 8.1 5.8 5.4 4.4 4.8
read_global 15.5 19.0 14.3 13.6 7.6 7.7
read_builtin 21.1 21.6 18.5 19.0 7.5 7.7
read_classvar_from_class 25.6 26.5 20.7 19.5 18.4 18.6
read_classvar_from_instance 22.8 23.5 18.8 17.1 16.4 20.1
read_instancevar 32.4 33.1 28.0 26.3 25.4 27.7
read_instancevar_slots 27.8 31.3 20.8 20.8 20.2 24.5
read_namedtuple 73.8 57.5 45.0 46.8 18.4 23.2
read_boundmethod 37.6 37.9 29.6 26.9 27.7 45.9
Variable and attribute write access:
write_local 8.7 9.3 5.5 5.3 4.3 4.2
write_nonlocal 10.5 11.1 5.6 5.5 4.7 4.9
write_global 19.7 21.2 18.0 18.0 15.8 17.2
write_classvar 92.9 96.0 104.6 102.1 39.2 43.2
write_instancevar 44.6 45.8 40.0 38.9 35.5 40.7
write_instancevar_slots 35.6 36.1 27.3 26.6 25.7 27.7
Data structure read access:
read_list 24.2 24.5 20.8 20.8 19.0 21.1
read_deque 24.7 25.5 20.2 20.6 19.8 21.6
read_dict 24.3 25.7 22.3 23.0 21.0 22.5
read_strdict 22.6 24.3 19.5 21.2 18.9 21.6
Data structure write access:
write_list 27.1 28.5 22.5 21.6 20.0 21.6
write_deque 28.7 30.1 22.7 21.8 23.5 23.2
write_dict 31.4 33.3 29.3 29.2 24.7 27.8
write_strdict 28.4 29.9 27.5 25.2 23.1 29.8
Stack (or queue) operations:
list_append_pop 93.4 112.7 75.4 74.2 50.8 53.9
deque_append_pop 43.5 57.0 49.4 49.2 42.5 45.5
deque_append_popleft 43.7 57.3 49.7 49.7 42.8 45.5
Timing loop:
loop_overhead 0.5 0.6 0.4 0.3 0.3 0.3
These results were generated from the variable access benchmark script at:
``Tools/scripts/var_access_benchmark.py``. The benchmark script displays timings
in nanoseconds. The benchmarks were measured on an
`Intel® Core™ i7-4960HQ processor
<https://ark.intel.com/content/www/us/en/ark/products/76088/intel-core-i7-4960hq-processor-6m-cache-up-to-3-80-ghz.html>`_
running the macOS 64-bit builds found at
`python.org <https://www.python.org/downloads/mac-osx/>`_.
Deprecated
==========
@ -608,6 +754,16 @@ Deprecated
* Passing ``None`` as the first argument to the :func:`shlex.split` function
has been deprecated. (Contributed by Zackery Spytz in :issue:`33262`.)
* The :mod:`lib2to3` module now emits a :exc:`PendingDeprecationWarning`.
Python 3.9 switched to a PEG parser (see :pep:`617`), and Python 3.10 may
include new language syntax that is not parsable by lib2to3's LL(1) parser.
The ``lib2to3`` module may be removed from the standard library in a future
Python version. Consider third-party alternatives such as `LibCST`_ or
`parso`_.
(Contributed by Carl Meyer in :issue:`40360`.)
.. _LibCST: https://libcst.readthedocs.io/
.. _parso: https://parso.readthedocs.io/
Removed
=======
@ -673,9 +829,6 @@ Removed
removed, standard :class:`bytes` objects are always used instead.
(Contributed by Jon Janzen in :issue:`36409`.)
* The C function ``PyThreadState_DeleteCurrent()`` has been removed. It was not documented.
(Contributed by Joannah Nanjekye in :issue:`37878`.)
* The C function ``PyGen_NeedsFinalizing`` has been removed. It was not
documented, tested, or used anywhere within CPython after the implementation
of :pep:`442`. Patch by Joannah Nanjekye.
@ -712,7 +865,7 @@ Removed
(Contributed by Victor Stinner in :issue:`39489`.)
* The ``_field_types`` attribute of the :class:`typing.NamedTuple` class
has been removed. It was deprecated deprecated since Python 3.8. Use
has been removed. It was deprecated since Python 3.8. Use
the ``__annotations__`` attribute instead.
(Contributed by Serhiy Storchaka in :issue:`40182`.)
@ -761,11 +914,6 @@ Changes in the Python API
:class:`ftplib.FTP_TLS` as a keyword-only parameter, and the default encoding
is changed from Latin-1 to UTF-8 to follow :rfc:`2640`.
* :func:`inspect.getdoc` no longer returns docstring inherited from the type
of the object or from parent class if it is a class if it is not defined
in the object itself.
(Contributed by Serhiy Storchaka in :issue:`40257`.)
* :meth:`asyncio.loop.shutdown_default_executor` has been added to
:class:`~asyncio.AbstractEventLoop`, meaning alternative event loops that
inherit from it should have this method defined.
@ -776,6 +924,61 @@ Changes in the Python API
``PyCF_ALLOW_TOP_LEVEL_AWAIT`` was clashing with ``CO_FUTURE_DIVISION``.
(Contributed by Batuhan Taskaya in :issue:`39562`)
* ``array('u')`` now uses ``wchar_t`` as C type instead of ``Py_UNICODE``.
This change doesn't affect to its behavior because ``Py_UNICODE`` is alias
of ``wchar_t`` since Python 3.3.
(Contributed by Inada Naoki in :issue:`34538`.)
Changes in the C API
--------------------
* Instances of heap-allocated types (such as those created with
:c:func:`PyType_FromSpec` and similar APIs) hold a reference to their type
object since Python 3.8. As indicated in the "Changes in the C API" of Python
3.8, for the vast majority of cases, there should be no side effect but for
types that have a custom :c:member:`~PyTypeObject.tp_traverse` function,
ensure that all custom ``tp_traverse`` functions of heap-allocated types
visit the object's type.
Example:
.. code-block:: c
int
foo_traverse(foo_struct *self, visitproc visit, void *arg) {
// Rest of the traverse function
#if PY_VERSION_HEX >= 0x03090000
// This was not needed before Python 3.9 (Python issue 35810 and 40217)
Py_VISIT(Py_TYPE(self));
#endif
}
If your traverse function delegates to ``tp_traverse`` of its base class
(or another type), ensure that ``Py_TYPE(self)`` is visited only once.
Note that only heap types are expected to visit the type in ``tp_traverse``.
For example, if your ``tp_traverse`` function includes:
.. code-block:: c
base->tp_traverse(self, visit, arg)
then add:
.. code-block:: c
#if PY_VERSION_HEX >= 0x03090000
// This was not needed before Python 3.9 (Python issue 35810 and 40217)
if (base->tp_flags & Py_TPFLAGS_HEAPTYPE) {
// a heap type's tp_traverse already visited Py_TYPE(self)
} else {
Py_VISIT(Py_TYPE(self));
}
#else
(See :issue:`35810` and :issue:`40217` for more information.)
CPython bytecode changes
------------------------
@ -902,6 +1105,8 @@ Removed
* Exclude the following functions from the limited C API:
* ``PyThreadState_DeleteCurrent()``
(Contributed by Joannah Nanjekye in :issue:`37878`.)
* ``_Py_CheckRecursionLimit``
* ``_Py_NewReference()``
* ``_Py_ForgetReference()``
@ -948,3 +1153,6 @@ Removed
* ``PyTuple_ClearFreeList()``
* ``PyUnicode_ClearFreeList()``: the Unicode free list has been removed in
Python 3.3.
* Remove ``_PyUnicode_ClearStaticStrings()`` function.
(Contributed by Victor Stinner in :issue:`39465`.)

View File

@ -11,6 +11,7 @@ anyone wishing to stay up-to-date after a new release.
.. toctree::
:maxdepth: 2
3.10.rst
3.9.rst
3.8.rst
3.7.rst

View File

@ -17,6 +17,8 @@ _PyPegen_parse(Parser *p)
result = interactive_rule(p);
} else if (p->start_rule == Py_eval_input) {
result = eval_rule(p);
} else if (p->start_rule == Py_func_type_input) {
result = func_type_rule(p);
} else if (p->start_rule == Py_fstring_input) {
result = fstring_rule(p);
}
@ -26,11 +28,24 @@ _PyPegen_parse(Parser *p)
// The end
'''
file[mod_ty]: a=[statements] ENDMARKER { Module(a, NULL, p->arena) }
file[mod_ty]: a=[statements] ENDMARKER { _PyPegen_make_module(p, a) }
interactive[mod_ty]: a=statement_newline { Interactive(a, p->arena) }
eval[mod_ty]: a=expressions NEWLINE* ENDMARKER { Expression(a, p->arena) }
func_type[mod_ty]: '(' a=[type_expressions] ')' '->' b=expression NEWLINE* ENDMARKER { FunctionType(a, b, p->arena) }
fstring[expr_ty]: star_expressions
# type_expressions allow */** but ignore them
type_expressions[asdl_seq*]:
| a=','.expression+ ',' '*' b=expression ',' '**' c=expression {
_PyPegen_seq_append_to_end(p, CHECK(_PyPegen_seq_append_to_end(p, a, b)), c) }
| a=','.expression+ ',' '*' b=expression { _PyPegen_seq_append_to_end(p, a, b) }
| a=','.expression+ ',' '**' b=expression { _PyPegen_seq_append_to_end(p, a, b) }
| '*' a=expression ',' '**' b=expression {
_PyPegen_seq_append_to_end(p, CHECK(_PyPegen_singleton_seq(p, a)), b) }
| '*' a=expression { _PyPegen_singleton_seq(p, a) }
| '**' a=expression { _PyPegen_singleton_seq(p, a) }
| ','.expression+
statements[asdl_seq*]: a=statement+ { _PyPegen_seq_flatten(p, a) }
statement[asdl_seq*]: a=compound_stmt { _PyPegen_singleton_seq(p, a) } | simple_stmt
statement_newline[asdl_seq*]:
@ -67,32 +82,36 @@ compound_stmt[stmt_ty]:
| &'while' while_stmt
# NOTE: annotated_rhs may start with 'yield'; yield_expr must start with 'yield'
assignment:
assignment[stmt_ty]:
| a=NAME ':' b=expression c=['=' d=annotated_rhs { d }] {
_Py_AnnAssign(CHECK(_PyPegen_set_expr_context(p, a, Store)), b, c, 1, EXTRA) }
| a=('(' b=inside_paren_ann_assign_target ')' { b }
| ann_assign_subscript_attribute_target) ':' b=expression c=['=' d=annotated_rhs { d }] {
_Py_AnnAssign(a, b, c, 0, EXTRA)}
| a=(z=star_targets '=' { z })+ b=(yield_expr | star_expressions) {
_Py_Assign(a, b, NULL, EXTRA) }
| a=target b=augassign c=(yield_expr | star_expressions) {
CHECK_VERSION(
6,
"Variable annotation syntax is",
_Py_AnnAssign(CHECK(_PyPegen_set_expr_context(p, a, Store)), b, c, 1, EXTRA)
) }
| a=('(' b=single_target ')' { b }
| single_subscript_attribute_target) ':' b=expression c=['=' d=annotated_rhs { d }] {
CHECK_VERSION(6, "Variable annotations syntax is", _Py_AnnAssign(a, b, c, 0, EXTRA)) }
| a=(z=star_targets '=' { z })+ b=(yield_expr | star_expressions) tc=[TYPE_COMMENT] {
_Py_Assign(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) }
| a=single_target b=augassign c=(yield_expr | star_expressions) {
_Py_AugAssign(a, b->kind, c, EXTRA) }
| invalid_assignment
augassign[AugOperator*]:
| '+=' {_PyPegen_augoperator(p, Add)}
| '-=' {_PyPegen_augoperator(p, Sub)}
| '*=' {_PyPegen_augoperator(p, Mult)}
| '@=' {_PyPegen_augoperator(p, MatMult)}
| '/=' {_PyPegen_augoperator(p, Div)}
| '%=' {_PyPegen_augoperator(p, Mod)}
| '&=' {_PyPegen_augoperator(p, BitAnd)}
| '|=' {_PyPegen_augoperator(p, BitOr)}
| '^=' {_PyPegen_augoperator(p, BitXor)}
| '<<=' {_PyPegen_augoperator(p, LShift)}
| '>>=' {_PyPegen_augoperator(p, RShift)}
| '**=' {_PyPegen_augoperator(p, Pow)}
| '//=' {_PyPegen_augoperator(p, FloorDiv)}
| '+=' { _PyPegen_augoperator(p, Add) }
| '-=' { _PyPegen_augoperator(p, Sub) }
| '*=' { _PyPegen_augoperator(p, Mult) }
| '@=' { CHECK_VERSION(5, "The '@' operator is", _PyPegen_augoperator(p, MatMult)) }
| '/=' { _PyPegen_augoperator(p, Div) }
| '%=' { _PyPegen_augoperator(p, Mod) }
| '&=' { _PyPegen_augoperator(p, BitAnd) }
| '|=' { _PyPegen_augoperator(p, BitOr) }
| '^=' { _PyPegen_augoperator(p, BitXor) }
| '<<=' { _PyPegen_augoperator(p, LShift) }
| '>>=' { _PyPegen_augoperator(p, RShift) }
| '**=' { _PyPegen_augoperator(p, Pow) }
| '//=' { _PyPegen_augoperator(p, FloorDiv) }
global_stmt[stmt_ty]: 'global' a=','.NAME+ {
_Py_Global(CHECK(_PyPegen_map_names_to_ids(p, a)), EXTRA) }
@ -115,8 +134,9 @@ import_from[stmt_ty]:
_Py_ImportFrom(NULL, b, _PyPegen_seq_count_dots(a), EXTRA) }
import_from_targets[asdl_seq*]:
| '(' a=import_from_as_names [','] ')' { a }
| import_from_as_names
| import_from_as_names !','
| '*' { _PyPegen_singleton_seq(p, CHECK(_PyPegen_alias_for_star(p))) }
| invalid_import_from_targets
import_from_as_names[asdl_seq*]:
| a=','.import_from_as_name+ { a }
import_from_as_name[alias_ty]:
@ -145,14 +165,20 @@ while_stmt[stmt_ty]:
| 'while' a=named_expression ':' b=block c=[else_block] { _Py_While(a, b, c, EXTRA) }
for_stmt[stmt_ty]:
| is_async=[ASYNC] 'for' t=star_targets 'in' ex=star_expressions ':' b=block el=[else_block] {
(is_async ? _Py_AsyncFor : _Py_For)(t, ex, b, el, NULL, EXTRA) }
| 'for' t=star_targets 'in' ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
_Py_For(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA) }
| ASYNC 'for' t=star_targets 'in' ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
CHECK_VERSION(5, "Async for loops are", _Py_AsyncFor(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
with_stmt[stmt_ty]:
| is_async=[ASYNC] 'with' '(' a=','.with_item+ ')' ':' b=block {
(is_async ? _Py_AsyncWith : _Py_With)(a, b, NULL, EXTRA) }
| is_async=[ASYNC] 'with' a=','.with_item+ ':' b=block {
(is_async ? _Py_AsyncWith : _Py_With)(a, b, NULL, EXTRA) }
| 'with' '(' a=','.with_item+ ','? ')' ':' b=block {
_Py_With(a, b, NULL, EXTRA) }
| 'with' a=','.with_item+ ':' tc=[TYPE_COMMENT] b=block {
_Py_With(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) }
| ASYNC 'with' '(' a=','.with_item+ ','? ')' ':' b=block {
CHECK_VERSION(5, "Async with statements are", _Py_AsyncWith(a, b, NULL, EXTRA)) }
| ASYNC 'with' a=','.with_item+ ':' tc=[TYPE_COMMENT] b=block {
CHECK_VERSION(5, "Async with statements are", _Py_AsyncWith(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
with_item[withitem_ty]:
| e=expression o=['as' t=target { t }] { _Py_withitem(e, o, p->arena) }
@ -160,7 +186,7 @@ try_stmt[stmt_ty]:
| 'try' ':' b=block f=finally_block { _Py_Try(b, NULL, NULL, f, EXTRA) }
| 'try' ':' b=block ex=except_block+ el=[else_block] f=[finally_block] { _Py_Try(b, ex, el, f, EXTRA) }
except_block[excepthandler_ty]:
| 'except' e=expression t=['as' z=target { z }] ':' b=block {
| 'except' e=expression t=['as' z=NAME { z }] ':' b=block {
_Py_ExceptHandler(e, (t) ? ((expr_ty) t)->v.Name.id : NULL, b, EXTRA) }
| 'except' ':' b=block { _Py_ExceptHandler(NULL, NULL, b, EXTRA) }
finally_block[asdl_seq*]: 'finally' ':' a=block { a }
@ -177,43 +203,82 @@ function_def[stmt_ty]:
| function_def_raw
function_def_raw[stmt_ty]:
| is_async=[ASYNC] 'def' n=NAME '(' params=[params] ')' a=['->' z=annotation { z }] ':' b=block {
(is_async ? _Py_AsyncFunctionDef : _Py_FunctionDef)(n->v.Name.id,
(params) ? params : CHECK(_PyPegen_empty_arguments(p)),
b, NULL, a, NULL, EXTRA) }
| 'def' n=NAME '(' params=[params] ')' a=['->' z=expression { z }] ':' tc=[func_type_comment] b=block {
_Py_FunctionDef(n->v.Name.id,
(params) ? params : CHECK(_PyPegen_empty_arguments(p)),
b, NULL, a, NEW_TYPE_COMMENT(p, tc), EXTRA) }
| ASYNC 'def' n=NAME '(' params=[params] ')' a=['->' z=expression { z }] ':' tc=[func_type_comment] b=block {
CHECK_VERSION(
5,
"Async functions are",
_Py_AsyncFunctionDef(n->v.Name.id,
(params) ? params : CHECK(_PyPegen_empty_arguments(p)),
b, NULL, a, NEW_TYPE_COMMENT(p, tc), EXTRA)
) }
func_type_comment[Token*]:
| NEWLINE t=TYPE_COMMENT &(NEWLINE INDENT) { t } # Must be followed by indented block
| invalid_double_type_comments
| TYPE_COMMENT
params[arguments_ty]:
| invalid_parameters
| parameters
parameters[arguments_ty]:
| a=slash_without_default b=[',' x=plain_names { x }] c=[',' y=names_with_default { y }] d=[',' z=[star_etc] { z }] {
| a=slash_no_default b=param_no_default* c=param_with_default* d=[star_etc] {
_PyPegen_make_arguments(p, a, NULL, b, c, d) }
| a=slash_with_default b=[',' y=names_with_default { y }] c=[',' z=[star_etc] { z }] {
| a=slash_with_default b=param_with_default* c=[star_etc] {
_PyPegen_make_arguments(p, NULL, a, NULL, b, c) }
| a=plain_names b=[',' y=names_with_default { y }] c=[',' z=[star_etc] { z }] {
| a=param_no_default+ b=param_with_default* c=[star_etc] {
_PyPegen_make_arguments(p, NULL, NULL, a, b, c) }
| a=names_with_default b=[',' z=[star_etc] { z }] { _PyPegen_make_arguments(p, NULL, NULL, NULL, a, b)}
| a=param_with_default+ b=[star_etc] { _PyPegen_make_arguments(p, NULL, NULL, NULL, a, b)}
| a=star_etc { _PyPegen_make_arguments(p, NULL, NULL, NULL, NULL, a) }
slash_without_default[asdl_seq*]: a=plain_names ',' '/' { a }
slash_with_default[SlashWithDefault*]: a=[n=plain_names ',' { n }] b=names_with_default ',' '/' {
_PyPegen_slash_with_default(p, a, b) }
# Some duplication here because we can't write (',' | &')'),
# which is because we don't support empty alternatives (yet).
#
slash_no_default[asdl_seq*]:
| a=param_no_default+ '/' ',' { a }
| a=param_no_default+ '/' &')' { a }
slash_with_default[SlashWithDefault*]:
| a=param_no_default* b=param_with_default+ '/' ',' { _PyPegen_slash_with_default(p, a, b) }
| a=param_no_default* b=param_with_default+ '/' &')' { _PyPegen_slash_with_default(p, a, b) }
star_etc[StarEtc*]:
| '*' a=plain_name b=name_with_optional_default* c=[',' d=kwds { d }] [','] {
| '*' a=param_no_default b=param_maybe_default* c=[kwds] {
_PyPegen_star_etc(p, a, b, c) }
| '*' b=name_with_optional_default+ c=[',' d=kwds { d }] [','] {
| '*' ',' b=param_maybe_default+ c=[kwds] {
_PyPegen_star_etc(p, NULL, b, c) }
| a=kwds [','] { _PyPegen_star_etc(p, NULL, NULL, a) }
name_with_optional_default[NameDefaultPair*]:
| ',' a=plain_name b=['=' e=expression { e }] { _PyPegen_name_default_pair(p, a, b) }
names_with_default[asdl_seq*]: a=','.name_with_default+ { a }
name_with_default[NameDefaultPair*]:
| n=plain_name '=' e=expression { _PyPegen_name_default_pair(p, n, e) }
plain_names[asdl_seq*] (memo): a=','.(plain_name !'=')+ { a }
plain_name[arg_ty]:
| a=NAME b=[':' z=annotation { z }] { _Py_arg(a->v.Name.id, b, NULL, EXTRA) }
kwds[arg_ty]:
| '**' a=plain_name { a }
annotation[expr_ty]: expression
| a=kwds { _PyPegen_star_etc(p, NULL, NULL, a) }
| invalid_star_etc
kwds[arg_ty]: '**' a=param_no_default { a }
# One parameter. This *includes* a following comma and type comment.
#
# There are three styles:
# - No default
# - With default
# - Maybe with default
#
# There are two alternative forms of each, to deal with type comments:
# - Ends in a comma followed by an optional type comment
# - No comma, optional type comment, must be followed by close paren
# The latter form is for a final parameter without trailing comma.
#
param_no_default[arg_ty]:
| a=param ',' tc=TYPE_COMMENT? { _PyPegen_add_type_comment_to_arg(p, a, tc) }
| a=param tc=TYPE_COMMENT? &')' { _PyPegen_add_type_comment_to_arg(p, a, tc) }
param_with_default[NameDefaultPair*]:
| a=param c=default ',' tc=TYPE_COMMENT? { _PyPegen_name_default_pair(p, a, c, tc) }
| a=param c=default tc=TYPE_COMMENT? &')' { _PyPegen_name_default_pair(p, a, c, tc) }
param_maybe_default[NameDefaultPair*]:
| a=param c=default? ',' tc=TYPE_COMMENT? { _PyPegen_name_default_pair(p, a, c, tc) }
| a=param c=default? tc=TYPE_COMMENT? &')' { _PyPegen_name_default_pair(p, a, c, tc) }
param[arg_ty]: a=NAME b=annotation? { _Py_arg(a->v.Name.id, b, NULL, EXTRA) }
annotation[expr_ty]: ':' a=expression { a }
default[expr_ty]: '=' a=expression { a }
decorators[asdl_seq*]: a=('@' f=named_expression NEWLINE { f })+ { a }
@ -265,32 +330,48 @@ expression[expr_ty] (memo):
lambdef[expr_ty]:
| 'lambda' a=[lambda_parameters] ':' b=expression { _Py_Lambda((a) ? a : CHECK(_PyPegen_empty_arguments(p)), b, EXTRA) }
# lambda_parameters etc. duplicates parameters but without annotations
# or type comments, and if there's no comma after a parameter, we expect
# a colon, not a close parenthesis. (For more, see parameters above.)
#
lambda_parameters[arguments_ty]:
| a=lambda_slash_without_default b=[',' x=lambda_plain_names { x }] c=[',' y=lambda_names_with_default { y }] d=[',' z=[lambda_star_etc] { z }] {
| a=lambda_slash_no_default b=lambda_param_no_default* c=lambda_param_with_default* d=[lambda_star_etc] {
_PyPegen_make_arguments(p, a, NULL, b, c, d) }
| a=lambda_slash_with_default b=[',' y=lambda_names_with_default { y }] c=[',' z=[lambda_star_etc] { z }] {
| a=lambda_slash_with_default b=lambda_param_with_default* c=[lambda_star_etc] {
_PyPegen_make_arguments(p, NULL, a, NULL, b, c) }
| a=lambda_plain_names b=[',' y=lambda_names_with_default { y }] c=[',' z=[lambda_star_etc] { z }] {
| a=lambda_param_no_default+ b=lambda_param_with_default* c=[lambda_star_etc] {
_PyPegen_make_arguments(p, NULL, NULL, a, b, c) }
| a=lambda_names_with_default b=[',' z=[lambda_star_etc] { z }] { _PyPegen_make_arguments(p, NULL, NULL, NULL, a, b)}
| a=lambda_param_with_default+ b=[lambda_star_etc] { _PyPegen_make_arguments(p, NULL, NULL, NULL, a, b)}
| a=lambda_star_etc { _PyPegen_make_arguments(p, NULL, NULL, NULL, NULL, a) }
lambda_slash_without_default[asdl_seq*]: a=lambda_plain_names ',' '/' { a }
lambda_slash_with_default[SlashWithDefault*]: a=[n=lambda_plain_names ',' { n }] b=lambda_names_with_default ',' '/' {
_PyPegen_slash_with_default(p, a, b) }
lambda_slash_no_default[asdl_seq*]:
| a=lambda_param_no_default+ '/' ',' { a }
| a=lambda_param_no_default+ '/' &':' { a }
lambda_slash_with_default[SlashWithDefault*]:
| a=lambda_param_no_default* b=lambda_param_with_default+ '/' ',' { _PyPegen_slash_with_default(p, a, b) }
| a=lambda_param_no_default* b=lambda_param_with_default+ '/' &':' { _PyPegen_slash_with_default(p, a, b) }
lambda_star_etc[StarEtc*]:
| '*' a=lambda_plain_name b=lambda_name_with_optional_default* c=[',' d=lambda_kwds { d }] [','] {
| '*' a=lambda_param_no_default b=lambda_param_maybe_default* c=[lambda_kwds] {
_PyPegen_star_etc(p, a, b, c) }
| '*' b=lambda_name_with_optional_default+ c=[',' d=lambda_kwds { d }] [','] {
| '*' ',' b=lambda_param_maybe_default+ c=[lambda_kwds] {
_PyPegen_star_etc(p, NULL, b, c) }
| a=lambda_kwds [','] { _PyPegen_star_etc(p, NULL, NULL, a) }
lambda_name_with_optional_default[NameDefaultPair*]:
| ',' a=lambda_plain_name b=['=' e=expression { e }] { _PyPegen_name_default_pair(p, a, b) }
lambda_names_with_default[asdl_seq*]: a=','.lambda_name_with_default+ { a }
lambda_name_with_default[NameDefaultPair*]:
| n=lambda_plain_name '=' e=expression { _PyPegen_name_default_pair(p, n, e) }
lambda_plain_names[asdl_seq*]: a=','.(lambda_plain_name !'=')+ { a }
lambda_plain_name[arg_ty]: a=NAME { _Py_arg(a->v.Name.id, NULL, NULL, EXTRA) }
lambda_kwds[arg_ty]: '**' a=lambda_plain_name { a }
| a=lambda_kwds { _PyPegen_star_etc(p, NULL, NULL, a) }
| invalid_lambda_star_etc
lambda_kwds[arg_ty]: '**' a=lambda_param_no_default { a }
lambda_param_no_default[arg_ty]:
| a=lambda_param ',' { a }
| a=lambda_param &':' { a }
lambda_param_with_default[NameDefaultPair*]:
| a=lambda_param c=default ',' { _PyPegen_name_default_pair(p, a, c, NULL) }
| a=lambda_param c=default &':' { _PyPegen_name_default_pair(p, a, c, NULL) }
lambda_param_maybe_default[NameDefaultPair*]:
| a=lambda_param c=default? ',' { _PyPegen_name_default_pair(p, a, c, NULL) }
| a=lambda_param c=default? &':' { _PyPegen_name_default_pair(p, a, c, NULL) }
lambda_param[arg_ty]: a=NAME { _Py_arg(a->v.Name.id, NULL, NULL, EXTRA) }
disjunction[expr_ty] (memo):
| a=conjunction b=('or' c=conjunction { c })+ { _Py_BoolOp(
@ -357,7 +438,7 @@ term[expr_ty]:
| a=term '/' b=factor { _Py_BinOp(a, Div, b, EXTRA) }
| a=term '//' b=factor { _Py_BinOp(a, FloorDiv, b, EXTRA) }
| a=term '%' b=factor { _Py_BinOp(a, Mod, b, EXTRA) }
| a=term '@' b=factor { _Py_BinOp(a, MatMult, b, EXTRA) }
| a=term '@' b=factor { CHECK_VERSION(5, "The '@' operator is", _Py_BinOp(a, MatMult, b, EXTRA)) }
| factor
factor[expr_ty] (memo):
| '+' a=factor { _Py_UnaryOp(UAdd, a, EXTRA) }
@ -368,7 +449,7 @@ power[expr_ty]:
| a=await_primary '**' b=factor { _Py_BinOp(a, Pow, b, EXTRA) }
| await_primary
await_primary[expr_ty] (memo):
| AWAIT a=primary { _Py_Await(a, EXTRA) }
| AWAIT a=primary { CHECK_VERSION(5, "Await expressions are", _Py_Await(a, EXTRA)) }
| primary
primary[expr_ty]:
| a=primary '.' b=NAME { _Py_Attribute(a, b->v.Name.id, Load, EXTRA) }
@ -418,17 +499,23 @@ setcomp[expr_ty]:
| '{' a=expression b=for_if_clauses '}' { _Py_SetComp(a, b, EXTRA) }
| invalid_comprehension
dict[expr_ty]:
| '{' a=[kvpairs] '}' { _Py_Dict(CHECK(_PyPegen_get_keys(p, a)),
CHECK(_PyPegen_get_values(p, a)), EXTRA) }
| '{' a=[double_starred_kvpairs] '}' {
_Py_Dict(CHECK(_PyPegen_get_keys(p, a)), CHECK(_PyPegen_get_values(p, a)), EXTRA) }
dictcomp[expr_ty]:
| '{' a=kvpair b=for_if_clauses '}' { _Py_DictComp(a->key, a->value, b, EXTRA) }
kvpairs[asdl_seq*]: a=','.kvpair+ [','] { a }
kvpair[KeyValuePair*]:
| invalid_dict_comprehension
double_starred_kvpairs[asdl_seq*]: a=','.double_starred_kvpair+ [','] { a }
double_starred_kvpair[KeyValuePair*]:
| '**' a=bitwise_or { _PyPegen_key_value_pair(p, NULL, a) }
| a=expression ':' b=expression { _PyPegen_key_value_pair(p, a, b) }
| kvpair
kvpair[KeyValuePair*]: a=expression ':' b=expression { _PyPegen_key_value_pair(p, a, b) }
for_if_clauses[asdl_seq*]:
| a=(y=[ASYNC] 'for' a=star_targets 'in' b=disjunction c=('if' z=disjunction { z })*
{ _Py_comprehension(a, b, c, y != NULL, p->arena) })+ { a }
| for_if_clause+
for_if_clause[comprehension_ty]:
| ASYNC 'for' a=star_targets 'in' b=disjunction c=('if' z=disjunction { z })* {
CHECK_VERSION(6, "Async comprehensions are", _Py_comprehension(a, b, c, 1, p->arena)) }
| 'for' a=star_targets 'in' b=disjunction c=('if' z=disjunction { z })* {
_Py_comprehension(a, b, c, 0, p->arena) }
yield_expr[expr_ty]:
| 'yield' 'from' a=expression { _Py_YieldFrom(a, EXTRA) }
@ -464,10 +551,12 @@ kwarg_or_starred[KeywordOrStarred*]:
| a=NAME '=' b=expression {
_PyPegen_keyword_or_starred(p, CHECK(_Py_keyword(a->v.Name.id, b, EXTRA)), 1) }
| a=starred_expression { _PyPegen_keyword_or_starred(p, a, 0) }
| invalid_kwarg
kwarg_or_double_starred[KeywordOrStarred*]:
| a=NAME '=' b=expression {
_PyPegen_keyword_or_starred(p, CHECK(_Py_keyword(a->v.Name.id, b, EXTRA)), 1) }
| '**' a=expression { _PyPegen_keyword_or_starred(p, CHECK(_Py_keyword(NULL, a, EXTRA)), 1) }
| invalid_kwarg
# NOTE: star_targets may contain *bitwise_or, targets may not.
star_targets[expr_ty]:
@ -487,25 +576,28 @@ star_atom[expr_ty]:
| '(' a=[star_targets_seq] ')' { _Py_Tuple(a, Store, EXTRA) }
| '[' a=[star_targets_seq] ']' { _Py_List(a, Store, EXTRA) }
inside_paren_ann_assign_target[expr_ty]:
| ann_assign_subscript_attribute_target
single_target[expr_ty]:
| single_subscript_attribute_target
| a=NAME { _PyPegen_set_expr_context(p, a, Store) }
| '(' a=inside_paren_ann_assign_target ')' { a }
ann_assign_subscript_attribute_target[expr_ty]:
| '(' a=single_target ')' { a }
single_subscript_attribute_target[expr_ty]:
| a=t_primary '.' b=NAME !t_lookahead { _Py_Attribute(a, b->v.Name.id, Store, EXTRA) }
| a=t_primary '[' b=slices ']' !t_lookahead { _Py_Subscript(a, b, Store, EXTRA) }
del_targets[asdl_seq*]: a=','.del_target+ [','] { a }
# The lookaheads to del_target_end ensure that we don't match expressions where a prefix of the
# expression matches our rule, thereby letting these cases fall through to invalid_del_target.
del_target[expr_ty] (memo):
| a=t_primary '.' b=NAME !t_lookahead { _Py_Attribute(a, b->v.Name.id, Del, EXTRA) }
| a=t_primary '[' b=slices ']' !t_lookahead { _Py_Subscript(a, b, Del, EXTRA) }
| a=t_primary '.' b=NAME &del_target_end { _Py_Attribute(a, b->v.Name.id, Del, EXTRA) }
| a=t_primary '[' b=slices ']' &del_target_end { _Py_Subscript(a, b, Del, EXTRA) }
| del_t_atom
del_t_atom[expr_ty]:
| a=NAME { _PyPegen_set_expr_context(p, a, Del) }
| a=NAME &del_target_end { _PyPegen_set_expr_context(p, a, Del) }
| '(' a=del_target ')' { _PyPegen_set_expr_context(p, a, Del) }
| '(' a=[del_targets] ')' { _Py_Tuple(a, Del, EXTRA) }
| '[' a=[del_targets] ']' { _Py_List(a, Del, EXTRA) }
| invalid_del_target
del_target_end: ')' | ']' | ',' | ';' | NEWLINE
targets[asdl_seq*]: a=','.target+ [','] { a }
target[expr_ty] (memo):
@ -533,24 +625,60 @@ t_atom[expr_ty]:
# From here on, there are rules for invalid syntax with specialised error messages
incorrect_arguments:
| args ',' '*' { RAISE_SYNTAX_ERROR("iterable argument unpacking follows keyword argument unpacking") }
| expression for_if_clauses ',' [args | expression for_if_clauses] {
RAISE_SYNTAX_ERROR("Generator expression must be parenthesized") }
| a=expression for_if_clauses ',' [args | expression for_if_clauses] {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "Generator expression must be parenthesized") }
| a=args for_if_clauses { _PyPegen_nonparen_genexp_in_call(p, a) }
| args ',' a=expression for_if_clauses {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "Generator expression must be parenthesized") }
| a=args ',' args { _PyPegen_arguments_parsing_error(p, a) }
invalid_kwarg:
| a=expression '=' {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
a, "expression cannot contain assignment, perhaps you meant \"==\"?") }
invalid_named_expression:
| a=expression ':=' expression {
RAISE_SYNTAX_ERROR("cannot use assignment expressions with %s", _PyPegen_get_expr_name(a)) }
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
a, "cannot use assignment expressions with %s", _PyPegen_get_expr_name(a)) }
invalid_assignment:
| list ':' { RAISE_SYNTAX_ERROR("only single target (not list) can be annotated") }
| tuple ':' { RAISE_SYNTAX_ERROR("only single target (not tuple) can be annotated") }
| expression ':' expression ['=' annotated_rhs] {
RAISE_SYNTAX_ERROR("illegal target for annotation") }
| a=expression ('=' | augassign) (yield_expr | star_expressions) {
RAISE_SYNTAX_ERROR("cannot assign to %s", _PyPegen_get_expr_name(a)) }
| a=list ':' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "only single target (not list) can be annotated") }
| a=tuple ':' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "only single target (not tuple) can be annotated") }
| a=star_named_expression ',' star_named_expressions* ':' {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "only single target (not tuple) can be annotated") }
| a=expression ':' expression ['=' annotated_rhs] {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "illegal target for annotation") }
| a=star_expressions '=' (yield_expr | star_expressions) {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
_PyPegen_get_invalid_target(a),
"cannot assign to %s", _PyPegen_get_expr_name(_PyPegen_get_invalid_target(a))) }
| a=star_expressions augassign (yield_expr | star_expressions) {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
a,
"'%s' is an illegal expression for augmented assignment",
_PyPegen_get_expr_name(a)
)}
invalid_block:
| NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block") }
invalid_comprehension:
| ('[' | '(' | '{') '*' expression for_if_clauses {
RAISE_SYNTAX_ERROR("iterable unpacking cannot be used in comprehension") }
| ('[' | '(' | '{') a=starred_expression for_if_clauses {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "iterable unpacking cannot be used in comprehension") }
invalid_dict_comprehension:
| '{' a='**' bitwise_or for_if_clauses '}' {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "dict unpacking cannot be used in dict comprehension") }
invalid_parameters:
| [plain_names ','] (slash_with_default | names_with_default) ',' plain_names {
| param_no_default* (slash_with_default | param_with_default+) param_no_default {
RAISE_SYNTAX_ERROR("non-default argument follows default argument") }
invalid_star_etc:
| '*' (')' | ',' (')' | '**')) { RAISE_SYNTAX_ERROR("named arguments must follow bare *") }
| '*' ',' TYPE_COMMENT { RAISE_SYNTAX_ERROR("bare * has associated type comment") }
invalid_lambda_star_etc:
| '*' (':' | ',' (':' | '**')) { RAISE_SYNTAX_ERROR("named arguments must follow bare *") }
invalid_double_type_comments:
| TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT {
RAISE_SYNTAX_ERROR("Cannot have two type comments on def") }
invalid_del_target:
| a=star_expression &del_target_end {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot delete %s", _PyPegen_get_expr_name(a)) }
invalid_import_from_targets:
| import_from_as_names ',' {
RAISE_SYNTAX_ERROR("trailing comma not allowed without surrounding parentheses") }

View File

@ -4,9 +4,7 @@
typedef PyObject * identifier;
typedef PyObject * string;
typedef PyObject * bytes;
typedef PyObject * object;
typedef PyObject * singleton;
typedef PyObject * constant;
/* It would be nice if the code generated by asdl_c.py was completely

View File

@ -379,6 +379,9 @@ PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index,
/* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */
PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *);
/* Same as PyNumber_Index but can return an instance of a subclass of int. */
PyAPI_FUNC(PyObject *) _PyNumber_Index(PyObject *o);
#ifdef __cplusplus
}
#endif

View File

@ -409,6 +409,10 @@ typedef struct {
/* If equal to 0, stop Python initialization before the "main" phase */
int _init_main;
/* If non-zero, disallow threads, subprocesses, and fork.
Default: 0. */
int _isolated_interpreter;
} PyConfig;
PyAPI_FUNC(void) PyConfig_InitPythonConfig(PyConfig *config);

View File

@ -0,0 +1,35 @@
#ifndef Py_CPYTHON_METHODOBJECT_H
# error "this header file must not be included directly"
#endif
PyAPI_DATA(PyTypeObject) PyCMethod_Type;
#define PyCMethod_CheckExact(op) Py_IS_TYPE(op, &PyCMethod_Type)
#define PyCMethod_Check(op) PyObject_TypeCheck(op, &PyCMethod_Type)
/* Macros for direct access to these values. Type checks are *not*
done, so use with care. */
#define PyCFunction_GET_FUNCTION(func) \
(((PyCFunctionObject *)func) -> m_ml -> ml_meth)
#define PyCFunction_GET_SELF(func) \
(((PyCFunctionObject *)func) -> m_ml -> ml_flags & METH_STATIC ? \
NULL : ((PyCFunctionObject *)func) -> m_self)
#define PyCFunction_GET_FLAGS(func) \
(((PyCFunctionObject *)func) -> m_ml -> ml_flags)
#define PyCFunction_GET_CLASS(func) \
(((PyCFunctionObject *)func) -> m_ml -> ml_flags & METH_METHOD ? \
((PyCMethodObject *)func) -> mm_class : NULL)
typedef struct {
PyObject_HEAD
PyMethodDef *m_ml; /* Description of the C function to call */
PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */
PyObject *m_module; /* The __module__ attribute, can be anything */
PyObject *m_weakreflist; /* List of weak references */
vectorcallfunc vectorcall;
} PyCFunctionObject;
typedef struct {
PyCFunctionObject func;
PyTypeObject *mm_class; /* Class that defines this method */
} PyCMethodObject;

View File

@ -36,7 +36,7 @@ PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void);
PyId_foo is a static variable, either on block level or file level. On first
usage, the string "foo" is interned, and the structures are linked. On interpreter
shutdown, all strings are released (through _PyUnicode_ClearStaticStrings).
shutdown, all strings are released.
Alternatively, _Py_static_string allows choosing the variable name.
_PyUnicode_FromId returns a borrowed reference to the interned string.
@ -289,6 +289,7 @@ typedef struct _heaptypeobject {
PyBufferProcs as_buffer;
PyObject *ht_name, *ht_slots, *ht_qualname;
struct _dictkeysobject *ht_cached_keys;
PyObject *ht_module;
/* here are optional user slots, followed by the members. */
} PyHeapTypeObject;

View File

@ -75,7 +75,7 @@ typedef PyOSErrorObject PyWindowsErrorObject;
/* Error handling definitions */
PyAPI_FUNC(void) _PyErr_SetKeyError(PyObject *);
_PyErr_StackItem *_PyErr_GetTopmostException(PyThreadState *tstate);
PyAPI_FUNC(_PyErr_StackItem*) _PyErr_GetTopmostException(PyThreadState *tstate);
PyAPI_FUNC(void) _PyErr_GetExcInfo(PyThreadState *, PyObject **, PyObject **, PyObject **);
/* Context manipulation (PEP 3134) */

View File

@ -65,6 +65,8 @@ PyAPI_FUNC(int) _Py_CoerceLegacyLocale(int warn);
PyAPI_FUNC(int) _Py_LegacyLocaleDetected(int warn);
PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category);
PyAPI_FUNC(PyThreadState *) _Py_NewInterpreter(int isolated_subinterpreter);
#ifdef __cplusplus
}
#endif

View File

@ -1215,13 +1215,13 @@ Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) PyUnicode_AsUnicodeCopy(
/* Return an interned Unicode object for an Identifier; may fail if there is no memory.*/
PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*);
/* Clear all static strings. */
PyAPI_FUNC(void) _PyUnicode_ClearStaticStrings(void);
/* Fast equality check when the inputs are known to be exact unicode types
and where the hash values are equal (i.e. a very probable match) */
PyAPI_FUNC(int) _PyUnicode_EQ(PyObject *, PyObject *);
PyAPI_FUNC(Py_ssize_t) _PyUnicode_ScanIdentifier(PyObject *);
#ifdef __cplusplus
}
#endif

View File

@ -29,9 +29,7 @@ extern "C" {
#define E_EOFS 23 /* EOF in triple-quoted string */
#define E_EOLS 24 /* EOL in single-quoted string */
#define E_LINECONT 25 /* Unexpected characters after a line continuation */
#define E_IDENTIFIER 26 /* Invalid characters in identifier */
#define E_BADSINGLE 27 /* Ill-formed single statement input */
#define E_BADPREFIX 28 /* Bad string prefixes */
#ifdef __cplusplus
}

View File

@ -11,25 +11,34 @@ extern "C" {
#include "Python.h"
#include "Python-ast.h"
PyAPI_FUNC(mod_ty) PyPegen_ASTFromFile(const char *filename, int mode, PyCompilerFlags*, PyArena *arena);
PyAPI_FUNC(mod_ty) PyPegen_ASTFromString(const char *str, int mode, PyCompilerFlags *flags,
PyArena *arena);
PyAPI_FUNC(mod_ty) PyPegen_ASTFromStringObject(const char *str, PyObject* filename, int mode,
PyCompilerFlags *flags, PyArena *arena);
PyAPI_FUNC(mod_ty) PyPegen_ASTFromFileObject(FILE *fp, PyObject *filename_ob,
int mode, const char *enc, const char *ps1,
const char *ps2, PyCompilerFlags *flags,
int *errcode, PyArena *arena);
PyAPI_FUNC(PyCodeObject *) PyPegen_CodeObjectFromFile(const char *filename, int mode, PyCompilerFlags *flags);
PyAPI_FUNC(PyCodeObject *) PyPegen_CodeObjectFromString(const char *str, int mode,
PyCompilerFlags *flags);
PyAPI_FUNC(PyCodeObject *) PyPegen_CodeObjectFromFileObject(FILE *, PyObject *filename_ob,
int mode,
const char *ps1,
const char *ps2,
PyCompilerFlags *flags,
const char *enc,
int *errcode);
PyAPI_FUNC(mod_ty) PyPegen_ASTFromString(
const char *str,
const char *filename,
int mode,
PyCompilerFlags *flags,
PyArena *arena);
PyAPI_FUNC(mod_ty) PyPegen_ASTFromStringObject(
const char *str,
PyObject* filename,
int mode,
PyCompilerFlags *flags,
PyArena *arena);
PyAPI_FUNC(mod_ty) PyPegen_ASTFromFileObject(
FILE *fp,
PyObject *filename_ob,
int mode,
const char *enc,
const char *ps1,
const char *ps2,
PyCompilerFlags *flags,
int *errcode,
PyArena *arena);
PyAPI_FUNC(mod_ty) PyPegen_ASTFromFilename(
const char *filename,
int mode,
PyCompilerFlags *flags,
PyArena *arena);
#ifdef __cplusplus
}

View File

@ -50,7 +50,11 @@ extern PyObject *_PyEval_EvalCode(
PyObject *kwdefs, PyObject *closure,
PyObject *name, PyObject *qualname);
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
extern int _PyEval_ThreadsInitialized(PyInterpreterState *interp);
#else
extern int _PyEval_ThreadsInitialized(struct pyruntimestate *runtime);
#endif
extern PyStatus _PyEval_InitGIL(PyThreadState *tstate);
extern void _PyEval_FiniGIL(PyThreadState *tstate);
@ -65,12 +69,12 @@ PyAPI_DATA(int) _Py_CheckRecursionLimit;
/* With USE_STACKCHECK macro defined, trigger stack checks in
_Py_CheckRecursiveCall() on every 64th call to Py_EnterRecursiveCall. */
static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
return (++tstate->recursion_depth > _Py_CheckRecursionLimit
return (++tstate->recursion_depth > tstate->interp->ceval.recursion_limit
|| ++tstate->stackcheck_counter > 64);
}
#else
static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
return (++tstate->recursion_depth > _Py_CheckRecursionLimit);
return (++tstate->recursion_depth > tstate->interp->ceval.recursion_limit);
}
#endif
@ -90,20 +94,22 @@ static inline int _Py_EnterRecursiveCall_inline(const char *where) {
#define Py_EnterRecursiveCall(where) _Py_EnterRecursiveCall_inline(where)
/* Compute the "lower-water mark" for a recursion limit. When
* Py_LeaveRecursiveCall() is called with a recursion depth below this mark,
* the overflowed flag is reset to 0. */
#define _Py_RecursionLimitLowerWaterMark(limit) \
(((limit) > 200) \
? ((limit) - 50) \
: (3 * ((limit) >> 2)))
#define _Py_MakeEndRecCheck(x) \
(--(x) < _Py_RecursionLimitLowerWaterMark(_Py_CheckRecursionLimit))
static inline int _Py_RecursionLimitLowerWaterMark(int limit) {
if (limit > 200) {
return (limit - 50);
}
else {
return (3 * (limit >> 2));
}
}
static inline void _Py_LeaveRecursiveCall(PyThreadState *tstate) {
if (_Py_MakeEndRecCheck(tstate->recursion_depth)) {
tstate->recursion_depth--;
int limit = tstate->interp->ceval.recursion_limit;
if (tstate->recursion_depth < _Py_RecursionLimitLowerWaterMark(limit)) {
tstate->overflowed = 0;
}
}

View File

@ -0,0 +1,148 @@
#ifndef Py_INTERNAL_HASHTABLE_H
#define Py_INTERNAL_HASHTABLE_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
/* Single linked list */
typedef struct _Py_slist_item_s {
struct _Py_slist_item_s *next;
} _Py_slist_item_t;
typedef struct {
_Py_slist_item_t *head;
} _Py_slist_t;
#define _Py_SLIST_ITEM_NEXT(ITEM) (((_Py_slist_item_t *)ITEM)->next)
#define _Py_SLIST_HEAD(SLIST) (((_Py_slist_t *)SLIST)->head)
/* _Py_hashtable: table entry */
typedef struct {
/* used by _Py_hashtable_t.buckets to link entries */
_Py_slist_item_t _Py_slist_item;
Py_uhash_t key_hash;
void *key;
void *value;
} _Py_hashtable_entry_t;
/* _Py_hashtable: prototypes */
/* Forward declaration */
struct _Py_hashtable_t;
typedef struct _Py_hashtable_t _Py_hashtable_t;
typedef Py_uhash_t (*_Py_hashtable_hash_func) (const void *key);
typedef int (*_Py_hashtable_compare_func) (const void *key1, const void *key2);
typedef void (*_Py_hashtable_destroy_func) (void *key);
typedef _Py_hashtable_entry_t* (*_Py_hashtable_get_entry_func)(_Py_hashtable_t *ht,
const void *key);
typedef struct {
// Allocate a memory block
void* (*malloc) (size_t size);
// Release a memory block
void (*free) (void *ptr);
} _Py_hashtable_allocator_t;
/* _Py_hashtable: table */
struct _Py_hashtable_t {
size_t nentries; // Total number of entries in the table
size_t nbuckets;
_Py_slist_t *buckets;
_Py_hashtable_get_entry_func get_entry_func;
_Py_hashtable_hash_func hash_func;
_Py_hashtable_compare_func compare_func;
_Py_hashtable_destroy_func key_destroy_func;
_Py_hashtable_destroy_func value_destroy_func;
_Py_hashtable_allocator_t alloc;
};
/* Hash a pointer (void*) */
PyAPI_FUNC(Py_uhash_t) _Py_hashtable_hash_ptr(const void *key);
/* Comparison using memcmp() */
PyAPI_FUNC(int) _Py_hashtable_compare_direct(
const void *key1,
const void *key2);
PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new(
_Py_hashtable_hash_func hash_func,
_Py_hashtable_compare_func compare_func);
PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new_full(
_Py_hashtable_hash_func hash_func,
_Py_hashtable_compare_func compare_func,
_Py_hashtable_destroy_func key_destroy_func,
_Py_hashtable_destroy_func value_destroy_func,
_Py_hashtable_allocator_t *allocator);
PyAPI_FUNC(void) _Py_hashtable_destroy(_Py_hashtable_t *ht);
PyAPI_FUNC(void) _Py_hashtable_clear(_Py_hashtable_t *ht);
typedef int (*_Py_hashtable_foreach_func) (_Py_hashtable_t *ht,
const void *key, const void *value,
void *user_data);
/* Call func() on each entry of the hashtable.
Iteration stops if func() result is non-zero, in this case it's the result
of the call. Otherwise, the function returns 0. */
PyAPI_FUNC(int) _Py_hashtable_foreach(
_Py_hashtable_t *ht,
_Py_hashtable_foreach_func func,
void *user_data);
PyAPI_FUNC(size_t) _Py_hashtable_size(const _Py_hashtable_t *ht);
/* Add a new entry to the hash. The key must not be present in the hash table.
Return 0 on success, -1 on memory error. */
PyAPI_FUNC(int) _Py_hashtable_set(
_Py_hashtable_t *ht,
const void *key,
void *value);
/* Get an entry.
Return NULL if the key does not exist. */
static inline _Py_hashtable_entry_t *
_Py_hashtable_get_entry(_Py_hashtable_t *ht, const void *key)
{
return ht->get_entry_func(ht, key);
}
/* Get value from an entry.
Return NULL if the entry is not found.
Use _Py_hashtable_get_entry() to distinguish entry value equal to NULL
and entry not found. */
PyAPI_FUNC(void*) _Py_hashtable_get(_Py_hashtable_t *ht, const void *key);
/* Remove a key and its associated value without calling key and value destroy
functions.
Return the removed value if the key was found.
Return NULL if the key was not found. */
PyAPI_FUNC(void*) _Py_hashtable_steal(
_Py_hashtable_t *ht,
const void *key);
#ifdef __cplusplus
}
#endif
#endif /* !Py_INTERNAL_HASHTABLE_H */

View File

@ -33,6 +33,7 @@ struct _pending_calls {
};
struct _ceval_state {
int recursion_limit;
/* Records whether tracing is on for any thread. Counts the number
of threads for which tstate->c_tracefunc is non-NULL, so if the
value is 0, we know we don't have to check this thread's
@ -42,7 +43,25 @@ struct _ceval_state {
/* This single variable consolidates all requests to break out of
the fast path in the eval loop. */
_Py_atomic_int eval_breaker;
/* Request for dropping the GIL */
_Py_atomic_int gil_drop_request;
struct _pending_calls pending;
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
struct _gil_runtime_state gil;
#endif
};
/* fs_codec.encoding is initialized to NULL.
Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */
struct _Py_unicode_fs_codec {
char *encoding; // Filesystem encoding (encoded to UTF-8)
int utf8; // encoding=="utf-8"?
char *errors; // Filesystem errors (encoded to UTF-8)
_Py_error_handler error_handler;
};
struct _Py_unicode_state {
struct _Py_unicode_fs_codec fs_codec;
};
@ -91,14 +110,7 @@ struct _is {
PyObject *codec_error_registry;
int codecs_initialized;
/* fs_codec.encoding is initialized to NULL.
Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */
struct {
char *encoding; /* Filesystem encoding (encoded to UTF-8) */
int utf8; /* encoding=="utf-8"? */
char *errors; /* Filesystem errors (encoded to UTF-8) */
_Py_error_handler error_handler;
} fs_codec;
struct _Py_unicode_state unicode;
PyConfig config;
#ifdef HAVE_DLOPEN

View File

@ -14,6 +14,20 @@ static inline PyObject* _PyErr_Occurred(PyThreadState *tstate)
return tstate->curexc_type;
}
static inline void _PyErr_ClearExcState(_PyErr_StackItem *exc_state)
{
PyObject *t, *v, *tb;
t = exc_state->exc_type;
v = exc_state->exc_value;
tb = exc_state->exc_traceback;
exc_state->exc_type = NULL;
exc_state->exc_value = NULL;
exc_state->exc_traceback = NULL;
Py_XDECREF(t);
Py_XDECREF(v);
Py_XDECREF(tb);
}
PyAPI_FUNC(void) _PyErr_Fetch(
PyThreadState *tstate,
@ -36,6 +50,9 @@ PyAPI_FUNC(void) _PyErr_SetObject(
PyObject *type,
PyObject *value);
PyAPI_FUNC(void) _PyErr_ChainStackItem(
_PyErr_StackItem *exc_info);
PyAPI_FUNC(void) _PyErr_Clear(PyThreadState *tstate);
PyAPI_FUNC(void) _PyErr_SetNone(PyThreadState *tstate, PyObject *exception);

View File

@ -88,17 +88,12 @@ struct _PyTraceMalloc_Config {
/* limit of the number of frames in a traceback, 1 by default.
Variable protected by the GIL. */
int max_nframe;
/* use domain in trace key?
Variable protected by the GIL. */
int use_domain;
};
#define _PyTraceMalloc_Config_INIT \
{.initialized = TRACEMALLOC_NOT_INITIALIZED, \
.tracing = 0, \
.max_nframe = 1, \
.use_domain = 0}
.max_nframe = 1}
PyAPI_DATA(struct _PyTraceMalloc_Config) _Py_tracemalloc_config;

View File

@ -49,8 +49,18 @@ _Py_ThreadCanHandlePendingCalls(void)
/* Variable and macro for in-line access to current thread
and interpreter state */
static inline PyThreadState* _PyRuntimeState_GetThreadState(_PyRuntimeState *runtime) {
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
PyAPI_FUNC(PyThreadState*) _PyThreadState_GetTSS(void);
#endif
static inline PyThreadState*
_PyRuntimeState_GetThreadState(_PyRuntimeState *runtime)
{
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
return _PyThreadState_GetTSS();
#else
return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->gilstate.tstate_current);
#endif
}
/* Get the current Python thread state.
@ -62,8 +72,14 @@ static inline PyThreadState* _PyRuntimeState_GetThreadState(_PyRuntimeState *run
The caller must hold the GIL.
See also PyThreadState_Get() and PyThreadState_GET(). */
static inline PyThreadState *_PyThreadState_GET(void) {
static inline PyThreadState*
_PyThreadState_GET(void)
{
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
return _PyThreadState_GetTSS();
#else
return _PyRuntimeState_GetThreadState(&_PyRuntime);
#endif
}
/* Redefine PyThreadState_GET() as an alias to _PyThreadState_GET() */

View File

@ -14,12 +14,14 @@ extern "C" {
/* ceval state */
struct _ceval_runtime_state {
int recursion_limit;
/* Request for dropping the GIL */
_Py_atomic_int gil_drop_request;
/* Request for checking signals. */
/* Request for checking signals. It is shared by all interpreters (see
bpo-40513). Any thread of any interpreter can receive a signal, but only
the main thread of the main interpreter can handle signals: see
_Py_ThreadCanHandleSignals(). */
_Py_atomic_int signals_pending;
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
struct _gil_runtime_state gil;
#endif
};
/* GIL state */

View File

@ -173,23 +173,6 @@ PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v,
unsigned char* bytes, size_t n,
int little_endian, int is_signed);
/* _PyLong_FromNbInt: Convert the given object to a PyLongObject
using the nb_int slot, if available. Raise TypeError if either the
nb_int slot is not available or the result of the call to nb_int
returns something not of type int.
*/
PyAPI_FUNC(PyObject *) _PyLong_FromNbInt(PyObject *);
/* Convert the given object to a PyLongObject using the nb_index or
nb_int slots, if available (the latter is deprecated).
Raise TypeError if either nb_index and nb_int slots are not
available or the result of the call to nb_index or nb_int
returns something not of type int.
Should be replaced with PyNumber_Index after the end of the
deprecation period.
*/
PyAPI_FUNC(PyObject *) _PyLong_FromNbIndexOrNbInt(PyObject *);
/* _PyLong_Format: Convert the long to a string object with given base,
appending a base prefix of 0[box] if base is 2, 8 or 16. */
PyAPI_FUNC(PyObject *) _PyLong_Format(PyObject *obj, int base);

View File

@ -13,7 +13,8 @@ extern "C" {
PyAPI_DATA(PyTypeObject) PyCFunction_Type;
#define PyCFunction_Check(op) Py_IS_TYPE(op, &PyCFunction_Type)
#define PyCFunction_CheckExact(op) Py_IS_TYPE(op, &PyCFunction_Type)
#define PyCFunction_Check(op) PyObject_TypeCheck(op, &PyCFunction_Type)
typedef PyObject *(*PyCFunction)(PyObject *, PyObject *);
typedef PyObject *(*_PyCFunctionFast) (PyObject *, PyObject *const *, Py_ssize_t);
@ -22,21 +23,13 @@ typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *,
typedef PyObject *(*_PyCFunctionFastWithKeywords) (PyObject *,
PyObject *const *, Py_ssize_t,
PyObject *);
typedef PyObject *(*PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *,
size_t, PyObject *);
PyAPI_FUNC(PyCFunction) PyCFunction_GetFunction(PyObject *);
PyAPI_FUNC(PyObject *) PyCFunction_GetSelf(PyObject *);
PyAPI_FUNC(int) PyCFunction_GetFlags(PyObject *);
/* Macros for direct access to these values. Type checks are *not*
done, so use with care. */
#ifndef Py_LIMITED_API
#define PyCFunction_GET_FUNCTION(func) \
(((PyCFunctionObject *)func) -> m_ml -> ml_meth)
#define PyCFunction_GET_SELF(func) \
(((PyCFunctionObject *)func) -> m_ml -> ml_flags & METH_STATIC ? \
NULL : ((PyCFunctionObject *)func) -> m_self)
#define PyCFunction_GET_FLAGS(func) \
(((PyCFunctionObject *)func) -> m_ml -> ml_flags)
#endif
Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyCFunction_Call(PyObject *, PyObject *, PyObject *);
struct PyMethodDef {
@ -52,6 +45,13 @@ typedef struct PyMethodDef PyMethodDef;
PyAPI_FUNC(PyObject *) PyCFunction_NewEx(PyMethodDef *, PyObject *,
PyObject *);
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000
#define PyCFunction_NewEx(ML, SELF, MOD) PyCMethod_New((ML), (SELF), (MOD), NULL)
PyAPI_FUNC(PyObject *) PyCMethod_New(PyMethodDef *, PyObject *,
PyObject *, PyTypeObject *);
#endif
/* Flag passed to newmethodobject */
/* #define METH_OLDARGS 0x0000 -- unsupported now */
#define METH_VARARGS 0x0001
@ -84,15 +84,24 @@ PyAPI_FUNC(PyObject *) PyCFunction_NewEx(PyMethodDef *, PyObject *,
#define METH_STACKLESS 0x0000
#endif
/* METH_METHOD means the function stores an
* additional reference to the class that defines it;
* both self and class are passed to it.
* It uses PyCMethodObject instead of PyCFunctionObject.
* May not be combined with METH_NOARGS, METH_O, METH_CLASS or METH_STATIC.
*/
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000
#define METH_METHOD 0x0200
#endif
#ifndef Py_LIMITED_API
typedef struct {
PyObject_HEAD
PyMethodDef *m_ml; /* Description of the C function to call */
PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */
PyObject *m_module; /* The __module__ attribute, can be anything */
PyObject *m_weakreflist; /* List of weak references */
vectorcallfunc vectorcall;
} PyCFunctionObject;
#define Py_CPYTHON_METHODOBJECT_H
#include "cpython/methodobject.h"
#undef Py_CPYTHON_METHODOBJECT_H
#endif
#ifdef __cplusplus

View File

@ -119,26 +119,45 @@ typedef struct {
/* Cast argument to PyVarObject* type. */
#define _PyVarObject_CAST(op) ((PyVarObject*)(op))
#define _PyVarObject_CAST_CONST(op) ((const PyVarObject*)(op))
static inline Py_ssize_t _Py_REFCNT(const PyObject *ob) {
return ob->ob_refcnt;
}
#define Py_REFCNT(ob) _Py_REFCNT(_PyObject_CAST_CONST(ob))
static inline Py_ssize_t _Py_SIZE(const PyVarObject *ob) {
return ob->ob_size;
}
#define Py_SIZE(ob) _Py_SIZE(_PyVarObject_CAST_CONST(ob))
static inline PyTypeObject* _Py_TYPE(const PyObject *ob) {
return ob->ob_type;
}
#define Py_TYPE(ob) _Py_TYPE(_PyObject_CAST_CONST(ob))
#define Py_REFCNT(ob) (_PyObject_CAST(ob)->ob_refcnt)
#define Py_TYPE(ob) (_PyObject_CAST(ob)->ob_type)
#define Py_SIZE(ob) (_PyVarObject_CAST(ob)->ob_size)
static inline int _Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) {
return ob->ob_type == type;
}
#define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST_CONST(ob), type)
static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) {
ob->ob_refcnt = refcnt;
}
#define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT(_PyObject_CAST(ob), refcnt)
static inline void _Py_SET_TYPE(PyObject *ob, PyTypeObject *type) {
ob->ob_type = type;
}
#define Py_SET_TYPE(ob, type) _Py_SET_TYPE(_PyObject_CAST(ob), type)
static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) {
ob->ob_size = size;
}
@ -213,6 +232,11 @@ PyAPI_FUNC(PyObject*) PyType_FromSpecWithBases(PyType_Spec*, PyObject*);
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000
PyAPI_FUNC(void*) PyType_GetSlot(PyTypeObject*, int);
#endif
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000
PyAPI_FUNC(PyObject*) PyType_FromModuleAndSpec(PyObject *, PyType_Spec *, PyObject *);
PyAPI_FUNC(PyObject *) PyType_GetModule(struct _typeobject *);
PyAPI_FUNC(void *) PyType_GetModuleState(struct _typeobject *);
#endif
/* Generic type check */
PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *);

Some files were not shown because too many files have changed in this diff Show More