Merge branch 'master' into bpo-34689
This commit is contained in:
commit
f2b70538a7
|
@ -61,7 +61,7 @@ jobs:
|
|||
variables:
|
||||
testRunTitle: '$(build.sourceBranchName)-linux'
|
||||
testRunPlatform: linux
|
||||
openssl_version: 1.1.1f
|
||||
openssl_version: 1.1.1g
|
||||
|
||||
steps:
|
||||
- template: ./posix-steps.yml
|
||||
|
@ -118,7 +118,7 @@ jobs:
|
|||
variables:
|
||||
testRunTitle: '$(Build.SourceBranchName)-linux-coverage'
|
||||
testRunPlatform: linux-coverage
|
||||
openssl_version: 1.1.1f
|
||||
openssl_version: 1.1.1g
|
||||
|
||||
steps:
|
||||
- template: ./posix-steps.yml
|
||||
|
|
|
@ -61,7 +61,7 @@ jobs:
|
|||
variables:
|
||||
testRunTitle: '$(system.pullRequest.TargetBranch)-linux'
|
||||
testRunPlatform: linux
|
||||
openssl_version: 1.1.1f
|
||||
openssl_version: 1.1.1g
|
||||
|
||||
steps:
|
||||
- template: ./posix-steps.yml
|
||||
|
@ -118,7 +118,7 @@ jobs:
|
|||
variables:
|
||||
testRunTitle: '$(Build.SourceBranchName)-linux-coverage'
|
||||
testRunPlatform: linux-coverage
|
||||
openssl_version: 1.1.1f
|
||||
openssl_version: 1.1.1g
|
||||
|
||||
steps:
|
||||
- template: ./posix-steps.yml
|
||||
|
|
|
@ -41,8 +41,6 @@ PC/readme.txt text eol=crlf
|
|||
|
||||
# Generated files
|
||||
# https://github.com/github/linguist#generated-code
|
||||
Include/graminit.h linguist-generated=true
|
||||
Python/graminit.h linguist-generated=true
|
||||
Modules/clinic/*.h linguist-generated=true
|
||||
Objects/clinic/*.h linguist-generated=true
|
||||
PC/clinic/*.h linguist-generated=true
|
||||
|
|
|
@ -72,10 +72,10 @@ Include/pytime.h @pganssle @abalkin
|
|||
/Modules/gcmodule.c @pablogsal
|
||||
/Doc/library/gc.rst @pablogsal
|
||||
|
||||
# Parser/Pgen
|
||||
/Parser/pgen/ @pablogsal
|
||||
/Parser/pegen/ @pablogsal
|
||||
/Tools/peg_generator/ @pablogsal
|
||||
# Parser
|
||||
/Parser/ @pablogsal @lysnikolaou
|
||||
/Tools/peg_generator/ @pablogsal @lysnikolaou
|
||||
/Lib/test/test_peg_generator/ @pablogsal @lysnikolaou
|
||||
|
||||
# SQLite 3
|
||||
**/*sqlite* @berkerpeksag
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"__comment": "Taken from vscode-cpptools's Extension/package.json gcc rule",
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "gcc-problem-matcher",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^(.*):(\\d+):(\\d+):\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"severity": 4,
|
||||
"message": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -87,6 +87,8 @@ jobs:
|
|||
OPENSSL_VER: 1.1.1f
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Register gcc problem matcher
|
||||
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
|
||||
- name: Install Dependencies
|
||||
run: sudo ./.github/workflows/posix-deps-apt.sh
|
||||
- name: 'Restore OpenSSL build'
|
||||
|
|
|
@ -52,6 +52,7 @@ jobs:
|
|||
python -m pip install -U coverage
|
||||
python -m pip install -r Misc/requirements-test.txt
|
||||
python -m test.pythoninfo
|
||||
export PYTHONPATH=`find .venv -name fullcoverage`
|
||||
- name: 'Tests with coverage'
|
||||
run: >
|
||||
source ./.venv/bin/activate &&
|
||||
|
@ -67,6 +68,7 @@ jobs:
|
|||
|| true
|
||||
- name: 'Publish code coverage results'
|
||||
run: |
|
||||
export PYTHONPATH=
|
||||
source ./.venv/bin/activate
|
||||
bash <(curl -s https://codecov.io/bash) -y .github/codecov.yml
|
||||
env:
|
||||
|
|
14
.travis.yml
14
.travis.yml
|
@ -82,6 +82,12 @@ matrix:
|
|||
packages:
|
||||
- xvfb
|
||||
before_script:
|
||||
- |
|
||||
if [[ "$TRAVIS_PULL_REQUEST" != "false" ]]
|
||||
then
|
||||
echo "Don't run Python coverage on pull requests."
|
||||
exit
|
||||
fi
|
||||
- ./configure
|
||||
- make -j4
|
||||
# Need a venv that can parse covered code.
|
||||
|
@ -89,11 +95,13 @@ matrix:
|
|||
- ./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
|
||||
- export PYTHONPATH=`find venv -name fullcoverage`
|
||||
script:
|
||||
# Skip tests that re-run the entire test suite.
|
||||
- xvfb-run ./venv/bin/python -m coverage run --branch --pylib -m test --fail-env-changed -uall,-cpu -x test_multiprocessing_fork -x test_multiprocessing_forkserver -x test_multiprocessing_spawn -x test_concurrent_futures || true
|
||||
after_script: # Probably should be after_success once test suite updated to run under coverage.py.
|
||||
# Make the `coverage` command available to Codecov w/ a version of Python that can parse all source files.
|
||||
- export PYTHONPATH=
|
||||
- source ./venv/bin/activate
|
||||
- bash <(curl -s https://codecov.io/bash) -y .github/codecov.yml
|
||||
- name: "Test code coverage (C)"
|
||||
|
@ -107,6 +115,12 @@ matrix:
|
|||
- lcov
|
||||
- xvfb
|
||||
before_script:
|
||||
- |
|
||||
if [[ "$TRAVIS_PULL_REQUEST" != "false" ]]
|
||||
then
|
||||
echo "Don't run C coverage on pull requests."
|
||||
exit
|
||||
fi
|
||||
- ./configure
|
||||
script:
|
||||
- xvfb-run make -j4 coverage-report
|
||||
|
|
|
@ -143,7 +143,7 @@ clean:
|
|||
venv:
|
||||
$(PYTHON) -m venv $(VENVDIR)
|
||||
$(VENVDIR)/bin/python3 -m pip install -U pip setuptools
|
||||
$(VENVDIR)/bin/python3 -m pip install -U Sphinx==2.2.0 blurb python-docs-theme
|
||||
$(VENVDIR)/bin/python3 -m pip install -U Sphinx==2.3.1 blurb python-docs-theme
|
||||
@echo "The venv has been created in the $(VENVDIR) directory"
|
||||
|
||||
dist:
|
||||
|
|
|
@ -24,4 +24,3 @@ but whose items have not been set to some non-\ ``NULL`` value yet.
|
|||
mapping.rst
|
||||
iter.rst
|
||||
buffer.rst
|
||||
objbuffer.rst
|
||||
|
|
|
@ -55,13 +55,11 @@ which disallows mutable objects such as :class:`bytearray`.
|
|||
|
||||
.. note::
|
||||
|
||||
For all ``#`` variants of formats (``s#``, ``y#``, etc.), the type of
|
||||
the length argument (int or :c:type:`Py_ssize_t`) is controlled by
|
||||
defining the macro :c:macro:`PY_SSIZE_T_CLEAN` before including
|
||||
:file:`Python.h`. If the macro was defined, length is a
|
||||
:c:type:`Py_ssize_t` rather than an :c:type:`int`. This behavior will change
|
||||
in a future Python version to only support :c:type:`Py_ssize_t` and
|
||||
drop :c:type:`int` support. It is best to always define :c:macro:`PY_SSIZE_T_CLEAN`.
|
||||
For all ``#`` variants of formats (``s#``, ``y#``, etc.), the macro
|
||||
:c:macro:`PY_SSIZE_T_CLEAN` must be defined before including
|
||||
:file:`Python.h`. On Python 3.9 and older, the type of the length argument
|
||||
is :c:type:`Py_ssize_t` if the :c:macro:`PY_SSIZE_T_CLEAN` macro is defined,
|
||||
or int otherwise.
|
||||
|
||||
|
||||
``s`` (:class:`str`) [const char \*]
|
||||
|
@ -90,7 +88,7 @@ which disallows mutable objects such as :class:`bytearray`.
|
|||
In this case the resulting C string may contain embedded NUL bytes.
|
||||
Unicode objects are converted to C strings using ``'utf-8'`` encoding.
|
||||
|
||||
``s#`` (:class:`str`, read-only :term:`bytes-like object`) [const char \*, int or :c:type:`Py_ssize_t`]
|
||||
``s#`` (:class:`str`, read-only :term:`bytes-like object`) [const char \*, :c:type:`Py_ssize_t`]
|
||||
Like ``s*``, except that it doesn't accept mutable objects.
|
||||
The result is stored into two C variables,
|
||||
the first one a pointer to a C string, the second one its length.
|
||||
|
@ -105,7 +103,7 @@ which disallows mutable objects such as :class:`bytearray`.
|
|||
Like ``s*``, but the Python object may also be ``None``, in which case the
|
||||
``buf`` member of the :c:type:`Py_buffer` structure is set to ``NULL``.
|
||||
|
||||
``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`]
|
||||
``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, :c:type:`Py_ssize_t`]
|
||||
Like ``s#``, but the Python object may also be ``None``, in which case the C
|
||||
pointer is set to ``NULL``.
|
||||
|
||||
|
@ -124,7 +122,7 @@ which disallows mutable objects such as :class:`bytearray`.
|
|||
bytes-like objects. **This is the recommended way to accept
|
||||
binary data.**
|
||||
|
||||
``y#`` (read-only :term:`bytes-like object`) [const char \*, int or :c:type:`Py_ssize_t`]
|
||||
``y#`` (read-only :term:`bytes-like object`) [const char \*, :c:type:`Py_ssize_t`]
|
||||
This variant on ``s#`` doesn't accept Unicode objects, only bytes-like
|
||||
objects.
|
||||
|
||||
|
@ -155,7 +153,7 @@ which disallows mutable objects such as :class:`bytearray`.
|
|||
Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
|
||||
:c:func:`PyUnicode_AsWideCharString`.
|
||||
|
||||
``u#`` (:class:`str`) [const Py_UNICODE \*, int or :c:type:`Py_ssize_t`]
|
||||
``u#`` (:class:`str`) [const Py_UNICODE \*, :c:type:`Py_ssize_t`]
|
||||
This variant on ``u`` stores into two C variables, the first one a pointer to a
|
||||
Unicode data buffer, the second one its length. This variant allows
|
||||
null code points.
|
||||
|
@ -172,7 +170,7 @@ which disallows mutable objects such as :class:`bytearray`.
|
|||
Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
|
||||
:c:func:`PyUnicode_AsWideCharString`.
|
||||
|
||||
``Z#`` (:class:`str` or ``None``) [const Py_UNICODE \*, int or :c:type:`Py_ssize_t`]
|
||||
``Z#`` (:class:`str` or ``None``) [const Py_UNICODE \*, :c:type:`Py_ssize_t`]
|
||||
Like ``u#``, but the Python object may also be ``None``, in which case the
|
||||
:c:type:`Py_UNICODE` pointer is set to ``NULL``.
|
||||
|
||||
|
@ -213,7 +211,7 @@ which disallows mutable objects such as :class:`bytearray`.
|
|||
recoding them. Instead, the implementation assumes that the byte string object uses
|
||||
the encoding passed in as parameter.
|
||||
|
||||
``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int or :c:type:`Py_ssize_t` \*buffer_length]
|
||||
``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, :c:type:`Py_ssize_t` \*buffer_length]
|
||||
This variant on ``s#`` is used for encoding Unicode into a character buffer.
|
||||
Unlike the ``es`` format, this variant allows input data which contains NUL
|
||||
characters.
|
||||
|
@ -244,7 +242,7 @@ which disallows mutable objects such as :class:`bytearray`.
|
|||
In both cases, *\*buffer_length* is set to the length of the encoded data
|
||||
without the trailing NUL byte.
|
||||
|
||||
``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int or :c:type:`Py_ssize_t` \*buffer_length]
|
||||
``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, :c:type:`Py_ssize_t` \*buffer_length]
|
||||
Same as ``es#`` except that byte string objects are passed through without recoding
|
||||
them. Instead, the implementation assumes that the byte string object uses the
|
||||
encoding passed in as parameter.
|
||||
|
@ -549,7 +547,7 @@ Building values
|
|||
Convert a null-terminated C string to a Python :class:`str` object using ``'utf-8'``
|
||||
encoding. If the C string pointer is ``NULL``, ``None`` is used.
|
||||
|
||||
``s#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`]
|
||||
``s#`` (:class:`str` or ``None``) [const char \*, :c:type:`Py_ssize_t`]
|
||||
Convert a C string and its length to a Python :class:`str` object using ``'utf-8'``
|
||||
encoding. If the C string pointer is ``NULL``, the length is ignored and
|
||||
``None`` is returned.
|
||||
|
@ -558,14 +556,14 @@ Building values
|
|||
This converts a C string to a Python :class:`bytes` object. If the C
|
||||
string pointer is ``NULL``, ``None`` is returned.
|
||||
|
||||
``y#`` (:class:`bytes`) [const char \*, int or :c:type:`Py_ssize_t`]
|
||||
``y#`` (:class:`bytes`) [const char \*, :c:type:`Py_ssize_t`]
|
||||
This converts a C string and its lengths to a Python object. If the C
|
||||
string pointer is ``NULL``, ``None`` is returned.
|
||||
|
||||
``z`` (:class:`str` or ``None``) [const char \*]
|
||||
Same as ``s``.
|
||||
|
||||
``z#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`]
|
||||
``z#`` (:class:`str` or ``None``) [const char \*, :c:type:`Py_ssize_t`]
|
||||
Same as ``s#``.
|
||||
|
||||
``u`` (:class:`str`) [const wchar_t \*]
|
||||
|
@ -573,7 +571,7 @@ Building values
|
|||
data to a Python Unicode object. If the Unicode buffer pointer is ``NULL``,
|
||||
``None`` is returned.
|
||||
|
||||
``u#`` (:class:`str`) [const wchar_t \*, int or :c:type:`Py_ssize_t`]
|
||||
``u#`` (:class:`str`) [const wchar_t \*, :c:type:`Py_ssize_t`]
|
||||
Convert a Unicode (UTF-16 or UCS-4) data buffer and its length to a Python
|
||||
Unicode object. If the Unicode buffer pointer is ``NULL``, the length is ignored
|
||||
and ``None`` is returned.
|
||||
|
@ -581,7 +579,7 @@ Building values
|
|||
``U`` (:class:`str` or ``None``) [const char \*]
|
||||
Same as ``s``.
|
||||
|
||||
``U#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`]
|
||||
``U#`` (:class:`str` or ``None``) [const char \*, :c:type:`Py_ssize_t`]
|
||||
Same as ``s#``.
|
||||
|
||||
``i`` (:class:`int`) [int]
|
||||
|
|
|
@ -27,12 +27,8 @@ not.
|
|||
|
||||
The wrappers ensure that *str*[*size*-1] is always ``'\0'`` upon return. They
|
||||
never write more than *size* bytes (including the trailing ``'\0'``) into str.
|
||||
Both functions require that ``str != NULL``, ``size > 0`` and ``format !=
|
||||
NULL``.
|
||||
|
||||
If the platform doesn't have :c:func:`vsnprintf` and the buffer size needed to
|
||||
avoid truncation exceeds *size* by more than 512 bytes, Python aborts with a
|
||||
:c:func:`Py_FatalError`.
|
||||
Both functions require that ``str != NULL``, ``size > 0``, ``format != NULL``
|
||||
and ``size < INT_MAX``.
|
||||
|
||||
The return value (*rv*) for these functions should be interpreted as follows:
|
||||
|
||||
|
@ -48,8 +44,8 @@ The return value (*rv*) for these functions should be interpreted as follows:
|
|||
this case too, but the rest of *str* is undefined. The exact cause of the error
|
||||
depends on the underlying platform.
|
||||
|
||||
The following functions provide locale-independent string to number conversions.
|
||||
|
||||
The following functions provide locale-independent string to number conversions.
|
||||
|
||||
.. c:function:: double PyOS_string_to_double(const char *s, char **endptr, PyObject *overflow_exception)
|
||||
|
||||
|
|
|
@ -100,6 +100,10 @@ Dictionary Objects
|
|||
:meth:`__eq__` methods will get suppressed.
|
||||
To get error reporting use :c:func:`PyDict_GetItemWithError()` instead.
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
Calling this API without :term:`GIL` held had been allowed for historical
|
||||
reason. It is no longer allowed.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyDict_GetItemWithError(PyObject *p, PyObject *key)
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ Functions:
|
|||
* :c:func:`Py_PreInitializeFromArgs`
|
||||
* :c:func:`Py_PreInitializeFromBytesArgs`
|
||||
* :c:func:`Py_RunMain`
|
||||
* :c:func:`Py_GetArgcArgv`
|
||||
|
||||
The preconfiguration (``PyPreConfig`` type) is stored in
|
||||
``_PyRuntime.preconfig`` and the configuration (``PyConfig`` type) is stored in
|
||||
|
@ -196,12 +197,12 @@ PyPreConfig
|
|||
|
||||
Function to initialize a preconfiguration:
|
||||
|
||||
.. c:function:: void PyPreConfig_InitIsolatedConfig(PyPreConfig *preconfig)
|
||||
.. c:function:: void PyPreConfig_InitPythonConfig(PyPreConfig *preconfig)
|
||||
|
||||
Initialize the preconfiguration with :ref:`Python Configuration
|
||||
<init-python-config>`.
|
||||
|
||||
.. c:function:: void PyPreConfig_InitPythonConfig(PyPreConfig *preconfig)
|
||||
.. c:function:: void PyPreConfig_InitIsolatedConfig(PyPreConfig *preconfig)
|
||||
|
||||
Initialize the preconfiguration with :ref:`Isolated Configuration
|
||||
<init-isolated-conf>`.
|
||||
|
@ -423,6 +424,8 @@ PyConfig
|
|||
:c:member:`~PyConfig.argv` is empty, an empty string is added to ensure
|
||||
that :data:`sys.argv` always exists and is never empty.
|
||||
|
||||
See also the :c:member:`~PyConfig.orig_argv` member.
|
||||
|
||||
.. c:member:: wchar_t* base_exec_prefix
|
||||
|
||||
:data:`sys.base_exec_prefix`.
|
||||
|
@ -436,6 +439,14 @@ PyConfig
|
|||
|
||||
:data:`sys.base_prefix`.
|
||||
|
||||
.. c:member:: wchar_t* platlibdir
|
||||
|
||||
:data:`sys.platlibdir`: platform library directory name, set at configure time
|
||||
by ``--with-platlibdir``, overrideable by the ``PYTHONPLATLIBDIR``
|
||||
environment variable.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
.. c:member:: int buffered_stdio
|
||||
|
||||
If equals to 0, enable unbuffered mode, making the stdout and stderr
|
||||
|
@ -577,6 +588,23 @@ PyConfig
|
|||
* 1: Remove assertions, set ``__debug__`` to ``False``
|
||||
* 2: Strip docstrings
|
||||
|
||||
.. c:member:: PyWideStringList orig_argv
|
||||
|
||||
The list of the original command line arguments passed to the Python
|
||||
executable.
|
||||
|
||||
If :c:member:`~PyConfig.orig_argv` list is empty and
|
||||
:c:member:`~PyConfig.argv` is not a list only containing an empty
|
||||
string, :c:func:`PyConfig_Read()` copies :c:member:`~PyConfig.argv` into
|
||||
:c:member:`~PyConfig.orig_argv` before modifying
|
||||
:c:member:`~PyConfig.argv` (if :c:member:`~PyConfig.parse_argv` is
|
||||
non-zero).
|
||||
|
||||
See also the :c:member:`~PyConfig.argv` member and the
|
||||
:c:func:`Py_GetArgcArgv` function.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
.. c:member:: int parse_argv
|
||||
|
||||
If non-zero, parse :c:member:`~PyConfig.argv` the same way the regular
|
||||
|
@ -686,16 +714,6 @@ PyConfig
|
|||
|
||||
:data:`sys._xoptions`.
|
||||
|
||||
.. c:member:: int _use_peg_parser
|
||||
|
||||
Enable PEG parser? Default: 1.
|
||||
|
||||
Set to 0 by :option:`-X oldparser <-X>` and :envvar:`PYTHONOLDPARSER`.
|
||||
|
||||
See also :pep:`617`.
|
||||
|
||||
.. deprecated-removed:: 3.9 3.10
|
||||
|
||||
If ``parse_argv`` is non-zero, ``argv`` arguments are parsed the same
|
||||
way the regular Python parses command line arguments, and Python
|
||||
arguments are stripped from ``argv``: see :ref:`Command Line Arguments
|
||||
|
@ -884,6 +902,7 @@ Path Configuration
|
|||
* Path configuration inputs:
|
||||
|
||||
* :c:member:`PyConfig.home`
|
||||
* :c:member:`PyConfig.platlibdir`
|
||||
* :c:member:`PyConfig.pathconfig_warnings`
|
||||
* :c:member:`PyConfig.program_name`
|
||||
* :c:member:`PyConfig.pythonpath_env`
|
||||
|
@ -975,6 +994,16 @@ customized Python always running in isolated mode using
|
|||
:c:func:`Py_RunMain`.
|
||||
|
||||
|
||||
Py_GetArgcArgv()
|
||||
----------------
|
||||
|
||||
.. c:function:: void Py_GetArgcArgv(int *argc, wchar_t ***argv)
|
||||
|
||||
Get the original command line arguments, before Python modified them.
|
||||
|
||||
See also :c:member:`PyConfig.orig_argv` member.
|
||||
|
||||
|
||||
Multi-Phase Initialization Private Provisional API
|
||||
--------------------------------------------------
|
||||
|
||||
|
|
|
@ -94,23 +94,10 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
|||
are no digits, :exc:`ValueError` will be raised.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base)
|
||||
|
||||
Convert a sequence of Unicode digits to a Python integer value. The Unicode
|
||||
string is first encoded to a byte string using :c:func:`PyUnicode_EncodeDecimal`
|
||||
and then converted using :c:func:`PyLong_FromString`.
|
||||
|
||||
.. deprecated-removed:: 3.3 4.0
|
||||
Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
|
||||
:c:func:`PyLong_FromUnicodeObject`.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyLong_FromUnicodeObject(PyObject *u, int base)
|
||||
|
||||
Convert a sequence of Unicode digits in the string *u* to a Python integer
|
||||
value. The Unicode string is first encoded to a byte string using
|
||||
:c:func:`PyUnicode_EncodeDecimal` and then converted using
|
||||
:c:func:`PyLong_FromString`.
|
||||
value.
|
||||
|
||||
.. versionadded:: 3.3
|
||||
|
||||
|
@ -129,9 +116,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 +127,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 +147,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 +157,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 +168,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 +190,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 +261,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 +274,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 +294,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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
.. highlight:: c
|
||||
|
||||
Old Buffer Protocol
|
||||
-------------------
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
These functions were part of the "old buffer protocol" API in Python 2.
|
||||
In Python 3, this protocol doesn't exist anymore but the functions are still
|
||||
exposed to ease porting 2.x code. They act as a compatibility wrapper
|
||||
around the :ref:`new buffer protocol <bufferobjects>`, but they don't give
|
||||
you control over the lifetime of the resources acquired when a buffer is
|
||||
exported.
|
||||
|
||||
Therefore, it is recommended that you call :c:func:`PyObject_GetBuffer`
|
||||
(or the ``y*`` or ``w*`` :ref:`format codes <arg-parsing>` with the
|
||||
:c:func:`PyArg_ParseTuple` family of functions) to get a buffer view over
|
||||
an object, and :c:func:`PyBuffer_Release` when the buffer view can be released.
|
||||
|
||||
|
||||
.. c:function:: int PyObject_AsCharBuffer(PyObject *obj, const char **buffer, Py_ssize_t *buffer_len)
|
||||
|
||||
Returns a pointer to a read-only memory location usable as character-based
|
||||
input. The *obj* argument must support the single-segment character buffer
|
||||
interface. On success, returns ``0``, sets *buffer* to the memory location
|
||||
and *buffer_len* to the buffer length. Returns ``-1`` and sets a
|
||||
:exc:`TypeError` on error.
|
||||
|
||||
|
||||
.. c:function:: int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len)
|
||||
|
||||
Returns a pointer to a read-only memory location containing arbitrary data.
|
||||
The *obj* argument must support the single-segment readable buffer
|
||||
interface. On success, returns ``0``, sets *buffer* to the memory location
|
||||
and *buffer_len* to the buffer length. Returns ``-1`` and sets a
|
||||
:exc:`TypeError` on error.
|
||||
|
||||
|
||||
.. c:function:: int PyObject_CheckReadBuffer(PyObject *o)
|
||||
|
||||
Returns ``1`` if *o* supports the single-segment readable buffer interface.
|
||||
Otherwise returns ``0``. This function always succeeds.
|
||||
|
||||
Note that this function tries to get and release a buffer, and exceptions
|
||||
which occur while calling corresponding functions will get suppressed.
|
||||
To get error reporting use :c:func:`PyObject_GetBuffer()` instead.
|
||||
|
||||
|
||||
.. c:function:: int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, Py_ssize_t *buffer_len)
|
||||
|
||||
Returns a pointer to a writable memory location. The *obj* argument must
|
||||
support the single-segment, character buffer interface. On success,
|
||||
returns ``0``, sets *buffer* to the memory location and *buffer_len* to the
|
||||
buffer length. Returns ``-1`` and sets a :exc:`TypeError` on error.
|
||||
|
|
@ -88,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)
|
||||
|
@ -104,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)
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -724,20 +724,6 @@ Extension modules can continue using them, as they will not be removed in Python
|
|||
.. versionadded:: 3.3
|
||||
|
||||
|
||||
.. c:function:: Py_UNICODE* PyUnicode_AsUnicodeCopy(PyObject *unicode)
|
||||
|
||||
Create a copy of a Unicode string ending with a null code point. Return ``NULL``
|
||||
and raise a :exc:`MemoryError` exception on memory allocation failure,
|
||||
otherwise return a new allocated buffer (use :c:func:`PyMem_Free` to free
|
||||
the buffer). Note that the resulting :c:type:`Py_UNICODE*` string may
|
||||
contain embedded null code points, which would cause the string to be
|
||||
truncated when used in most C functions.
|
||||
|
||||
.. versionadded:: 3.2
|
||||
|
||||
Please migrate to using :c:func:`PyUnicode_AsUCS4Copy` or similar new APIs.
|
||||
|
||||
|
||||
.. c:function:: Py_ssize_t PyUnicode_GetSize(PyObject *unicode)
|
||||
|
||||
Return the size of the deprecated :c:type:`Py_UNICODE` representation, in
|
||||
|
|
|
@ -1205,11 +1205,6 @@ PyLong_FromString:const char*:str::
|
|||
PyLong_FromString:char**:pend::
|
||||
PyLong_FromString:int:base::
|
||||
|
||||
PyLong_FromUnicode:PyObject*::+1:
|
||||
PyLong_FromUnicode:Py_UNICODE*:u::
|
||||
PyLong_FromUnicode:Py_ssize_t:length::
|
||||
PyLong_FromUnicode:int:base::
|
||||
|
||||
PyLong_FromUnicodeObject:PyObject*::+1:
|
||||
PyLong_FromUnicodeObject:PyObject*:u:0:
|
||||
PyLong_FromUnicodeObject:int:base::
|
||||
|
@ -1568,21 +1563,6 @@ PyOS_FSPath:PyObject*:path:0:
|
|||
PyObject_ASCII:PyObject*::+1:
|
||||
PyObject_ASCII:PyObject*:o:0:
|
||||
|
||||
PyObject_AsCharBuffer:int:::
|
||||
PyObject_AsCharBuffer:PyObject*:obj:0:
|
||||
PyObject_AsCharBuffer:const char**:buffer::
|
||||
PyObject_AsCharBuffer:Py_ssize_t*:buffer_len::
|
||||
|
||||
PyObject_AsReadBuffer:int:::
|
||||
PyObject_AsReadBuffer:PyObject*:obj:0:
|
||||
PyObject_AsReadBuffer:const void**:buffer::
|
||||
PyObject_AsReadBuffer:Py_ssize_t*:buffer_len::
|
||||
|
||||
PyObject_AsWriteBuffer:int:::
|
||||
PyObject_AsWriteBuffer:PyObject*:obj:0:
|
||||
PyObject_AsWriteBuffer:void**:buffer::
|
||||
PyObject_AsWriteBuffer:Py_ssize_t*:buffer_len::
|
||||
|
||||
PyObject_Bytes:PyObject*::+1:
|
||||
PyObject_Bytes:PyObject*:o:0:
|
||||
|
||||
|
@ -1618,9 +1598,6 @@ PyObject_CallObject:PyObject*:args:0:
|
|||
PyObject_CheckBuffer:int:::
|
||||
PyObject_CheckBuffer:PyObject*:obj:0:
|
||||
|
||||
PyObject_CheckReadBuffer:int:::
|
||||
PyObject_CheckReadBuffer:PyObject*:o:0:
|
||||
|
||||
PyObject_DelAttr:int:::
|
||||
PyObject_DelAttr:PyObject*:o:0:
|
||||
PyObject_DelAttr:PyObject*:attr_name:0:
|
||||
|
@ -2442,9 +2419,6 @@ PyUnicode_AsUnicodeAndSize:Py_UNICODE*:::
|
|||
PyUnicode_AsUnicodeAndSize:PyObject*:unicode:0:
|
||||
PyUnicode_AsUnicodeAndSize:Py_ssize_t*:size::
|
||||
|
||||
PyUnicode_AsUnicodeCopy:Py_UNICODE*:::
|
||||
PyUnicode_AsUnicodeCopy:PyObject*:unicode:0:
|
||||
|
||||
PyUnicode_GetSize:Py_ssize_t:::
|
||||
PyUnicode_GetSize:PyObject*:unicode:0:
|
||||
|
||||
|
|
|
@ -128,6 +128,7 @@ involved in creating and publishing a project:
|
|||
* `Project structure`_
|
||||
* `Building and packaging the project`_
|
||||
* `Uploading the project to the Python Packaging Index`_
|
||||
* `The .pypirc file`_
|
||||
|
||||
.. _Project structure: \
|
||||
https://packaging.python.org/tutorials/distributing-packages/
|
||||
|
@ -135,6 +136,8 @@ involved in creating and publishing a project:
|
|||
https://packaging.python.org/tutorials/distributing-packages/#packaging-your-project
|
||||
.. _Uploading the project to the Python Packaging Index: \
|
||||
https://packaging.python.org/tutorials/distributing-packages/#uploading-your-project-to-pypi
|
||||
.. _The .pypirc file: \
|
||||
https://packaging.python.org/specifications/pypirc/
|
||||
|
||||
|
||||
How do I...?
|
||||
|
|
|
@ -17,12 +17,13 @@ What is Python?
|
|||
|
||||
Python is an interpreted, interactive, object-oriented programming language. It
|
||||
incorporates modules, exceptions, dynamic typing, very high level dynamic data
|
||||
types, and classes. Python combines remarkable power with very clear syntax.
|
||||
It has interfaces to many system calls and libraries, as well as to various
|
||||
window systems, and is extensible in C or C++. It is also usable as an
|
||||
extension language for applications that need a programmable interface.
|
||||
Finally, Python is portable: it runs on many Unix variants, on the Mac, and on
|
||||
Windows 2000 and later.
|
||||
types, and classes. It supports multiple programming paradigms beyond
|
||||
object-oriented programming, such as procedural and functional programming.
|
||||
Python combines remarkable power with very clear syntax. It has interfaces to
|
||||
many system calls and libraries, as well as to various window systems, and is
|
||||
extensible in C or C++. It is also usable as an extension language for
|
||||
applications that need a programmable interface. Finally, Python is portable:
|
||||
it runs on many Unix variants including Linux and macOS, and on Windows.
|
||||
|
||||
To find out more, start with :ref:`tutorial-index`. The `Beginner's Guide to
|
||||
Python <https://wiki.python.org/moin/BeginnersGuide>`_ links to other
|
||||
|
@ -295,8 +296,8 @@ How stable is Python?
|
|||
---------------------
|
||||
|
||||
Very stable. New, stable releases have been coming out roughly every 6 to 18
|
||||
months since 1991, and this seems likely to continue. Currently there are
|
||||
usually around 18 months between major releases.
|
||||
months since 1991, and this seems likely to continue. As of version 3.9,
|
||||
Python will have a major new release every 12 months (:pep:`602`).
|
||||
|
||||
The developers issue "bugfix" releases of older versions, so the stability of
|
||||
existing releases gradually improves. Bugfix releases, indicated by a third
|
||||
|
@ -314,8 +315,8 @@ be maintained after January 1, 2020 <https://www.python.org/dev/peps/pep-0373/>`
|
|||
How many people are using Python?
|
||||
---------------------------------
|
||||
|
||||
There are probably tens of thousands of users, though it's difficult to obtain
|
||||
an exact count.
|
||||
There are probably millions of users, though it's difficult to obtain an exact
|
||||
count.
|
||||
|
||||
Python is available for free download, so there are no sales figures, and it's
|
||||
available from many different sites and packaged with many Linux distributions,
|
||||
|
|
|
@ -189,6 +189,10 @@ Glossary
|
|||
A list of bytecode instructions can be found in the documentation for
|
||||
:ref:`the dis module <bytecodes>`.
|
||||
|
||||
callback
|
||||
A subroutine function which is passed as an argument to be executed at
|
||||
some point in the future.
|
||||
|
||||
class
|
||||
A template for creating user-defined objects. Class definitions
|
||||
normally contain method definitions which operate on instances of the
|
||||
|
|
|
@ -1368,7 +1368,7 @@ An example dictionary-based configuration
|
|||
-----------------------------------------
|
||||
|
||||
Below is an example of a logging configuration dictionary - it's taken from
|
||||
the `documentation on the Django project <https://docs.djangoproject.com/en/1.9/topics/logging/#configuring-logging>`_.
|
||||
the `documentation on the Django project <https://docs.djangoproject.com/en/stable/topics/logging/#configuring-logging>`_.
|
||||
This dictionary is passed to :func:`~config.dictConfig` to put the configuration into effect::
|
||||
|
||||
LOGGING = {
|
||||
|
@ -1424,7 +1424,7 @@ This dictionary is passed to :func:`~config.dictConfig` to put the configuration
|
|||
}
|
||||
|
||||
For more information about this configuration, you can see the `relevant
|
||||
section <https://docs.djangoproject.com/en/1.9/topics/logging/#configuring-logging>`_
|
||||
section <https://docs.djangoproject.com/en/stable/topics/logging/#configuring-logging>`_
|
||||
of the Django documentation.
|
||||
|
||||
.. _cookbook-rotator-namer:
|
||||
|
|
|
@ -1133,6 +1133,20 @@ container should match the type_ specified::
|
|||
|
||||
Any container can be passed as the *choices* value, so :class:`list` objects,
|
||||
:class:`set` objects, and custom containers are all supported.
|
||||
This includes :class:`enum.Enum`, which could be used to restrain
|
||||
argument's choices; if we reuse previous rock/paper/scissors game example,
|
||||
this could be as follows::
|
||||
|
||||
>>> from enum import Enum
|
||||
>>> class GameMove(Enum):
|
||||
... ROCK = 'rock'
|
||||
... PAPER = 'paper'
|
||||
... SCISSORS = 'scissors'
|
||||
...
|
||||
>>> parser = argparse.ArgumentParser(prog='game.py')
|
||||
>>> parser.add_argument('move', type=GameMove, choices=GameMove)
|
||||
>>> parser.parse_args(['rock'])
|
||||
Namespace(move=<GameMove.ROCK: 'rock'>)
|
||||
|
||||
|
||||
required
|
||||
|
|
|
@ -1553,7 +1553,12 @@ and classes for traversing abstract syntax trees:
|
|||
|
||||
.. warning::
|
||||
The produced code string will not necessarily be equal to the original
|
||||
code that generated the :class:`ast.AST` object.
|
||||
code that generated the :class:`ast.AST` object (without any compiler
|
||||
optimizations, such as constant tuples/frozensets).
|
||||
|
||||
.. warning::
|
||||
Trying to unparse a highly complex expression would result with
|
||||
:exc:`RecursionError`.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ event loop, no other Tasks can run in the same thread. When a Task
|
|||
executes an ``await`` expression, the running Task gets suspended, and
|
||||
the event loop executes the next Task.
|
||||
|
||||
To schedule a callback from a different OS thread, the
|
||||
To schedule a :term:`callback` from another OS thread, the
|
||||
:meth:`loop.call_soon_threadsafe` method should be used. Example::
|
||||
|
||||
loop.call_soon_threadsafe(callback, *args)
|
||||
|
|
|
@ -191,8 +191,8 @@ Scheduling callbacks
|
|||
|
||||
.. method:: loop.call_soon(callback, *args, context=None)
|
||||
|
||||
Schedule a *callback* to be called with *args* arguments at
|
||||
the next iteration of the event loop.
|
||||
Schedule the *callback* :term:`callback` to be called with
|
||||
*args* arguments at the next iteration of the event loop.
|
||||
|
||||
Callbacks are called in the order in which they are registered.
|
||||
Each callback will be called exactly once.
|
||||
|
|
|
@ -614,8 +614,7 @@ Running in Threads
|
|||
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*.
|
||||
Return a coroutine that can be awaited to get 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
|
||||
|
@ -963,31 +962,6 @@ Task Object
|
|||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
.. classmethod:: all_tasks(loop=None)
|
||||
|
||||
Return a set of all tasks for an event loop.
|
||||
|
||||
By default all tasks for the current event loop are returned.
|
||||
If *loop* is ``None``, the :func:`get_event_loop` function
|
||||
is used to get the current loop.
|
||||
|
||||
.. deprecated-removed:: 3.7 3.9
|
||||
|
||||
Do not call this as a task method. Use the :func:`asyncio.all_tasks`
|
||||
function instead.
|
||||
|
||||
.. classmethod:: current_task(loop=None)
|
||||
|
||||
Return the currently running task or ``None``.
|
||||
|
||||
If *loop* is ``None``, the :func:`get_event_loop` function
|
||||
is used to get the current loop.
|
||||
|
||||
.. deprecated-removed:: 3.7 3.9
|
||||
|
||||
Do not call this as a task method. Use the
|
||||
:func:`asyncio.current_task` function instead.
|
||||
|
||||
|
||||
.. _asyncio_generator_based_coro:
|
||||
|
||||
|
|
|
@ -328,6 +328,19 @@ For example::
|
|||
instead of replacing them. Also, the *iterable* is expected to be a
|
||||
sequence of elements, not a sequence of ``(key, value)`` pairs.
|
||||
|
||||
Counters support rich comparison operators for equality, subset, and
|
||||
superset relationships: ``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=``.
|
||||
All of those tests treat missing elements as having zero counts so that
|
||||
``Counter(a=1) == Counter(a=1, b=0)`` returns true.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
Rich comparison operations we were added
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
In equality tests, missing elements are treated as having zero counts.
|
||||
Formerly, ``Counter(a=3)`` and ``Counter(a=3, b=0)`` were considered
|
||||
distinct.
|
||||
|
||||
Common patterns for working with :class:`Counter` objects::
|
||||
|
||||
sum(c.values()) # total of all counts
|
||||
|
|
|
@ -167,6 +167,9 @@ The :mod:`csv` module defines the following classes:
|
|||
All other optional or keyword arguments are passed to the underlying
|
||||
:class:`reader` instance.
|
||||
|
||||
.. versionchanged:: 3.6
|
||||
Returned rows are now of type :class:`OrderedDict`.
|
||||
|
||||
.. versionchanged:: 3.8
|
||||
Returned rows are now of type :class:`dict`.
|
||||
|
||||
|
|
|
@ -33,3 +33,4 @@ The following modules are documented in this chapter:
|
|||
pprint.rst
|
||||
reprlib.rst
|
||||
enum.rst
|
||||
graphlib.rst
|
||||
|
|
|
@ -2193,4 +2193,3 @@ are expected to be exact.
|
|||
.. [#]
|
||||
.. versionchanged:: 3.9
|
||||
This approach now works for all exact results except for non-integer powers.
|
||||
Also backported to 3.7 and 3.8.
|
||||
|
|
|
@ -43,9 +43,8 @@ are always available. They are listed here in alphabetical order.
|
|||
.. function:: abs(x)
|
||||
|
||||
Return the absolute value of a number. The argument may be an
|
||||
integer or a floating point number. If the argument is a complex number, its
|
||||
magnitude is returned. If *x* defines :meth:`__abs__`,
|
||||
``abs(x)`` returns ``x.__abs__()``.
|
||||
integer, a floating point number, or an object implementing :meth:`__abs__`.
|
||||
If the argument is a complex number, its magnitude is returned.
|
||||
|
||||
|
||||
.. function:: all(iterable)
|
||||
|
@ -1721,50 +1720,90 @@ are always available. They are listed here in alphabetical order.
|
|||
dictionary are ignored.
|
||||
|
||||
|
||||
.. function:: zip(*iterables)
|
||||
.. function:: zip(*iterables, strict=False)
|
||||
|
||||
Make an iterator that aggregates elements from each of the iterables.
|
||||
Iterate over several iterables in parallel, producing tuples with an item
|
||||
from each one.
|
||||
|
||||
Returns an iterator of tuples, where the *i*-th tuple contains
|
||||
the *i*-th element from each of the argument sequences or iterables. The
|
||||
iterator stops when the shortest input iterable is exhausted. With a single
|
||||
iterable argument, it returns an iterator of 1-tuples. With no arguments,
|
||||
it returns an empty iterator. Equivalent to::
|
||||
Example::
|
||||
|
||||
def zip(*iterables):
|
||||
# zip('ABCD', 'xy') --> Ax By
|
||||
sentinel = object()
|
||||
iterators = [iter(it) for it in iterables]
|
||||
while iterators:
|
||||
result = []
|
||||
for it in iterators:
|
||||
elem = next(it, sentinel)
|
||||
if elem is sentinel:
|
||||
return
|
||||
result.append(elem)
|
||||
yield tuple(result)
|
||||
>>> for item in zip([1, 2, 3], ['sugar', 'spice', 'everything nice']):
|
||||
... print(item)
|
||||
...
|
||||
(1, 'sugar')
|
||||
(2, 'spice')
|
||||
(3, 'everything nice')
|
||||
|
||||
The left-to-right evaluation order of the iterables is guaranteed. This
|
||||
makes possible an idiom for clustering a data series into n-length groups
|
||||
using ``zip(*[iter(s)]*n)``. This repeats the *same* iterator ``n`` times
|
||||
so that each output tuple has the result of ``n`` calls to the iterator.
|
||||
This has the effect of dividing the input into n-length chunks.
|
||||
More formally: :func:`zip` returns an iterator of tuples, where the *i*-th
|
||||
tuple contains the *i*-th element from each of the argument iterables.
|
||||
|
||||
:func:`zip` should only be used with unequal length inputs when you don't
|
||||
care about trailing, unmatched values from the longer iterables. If those
|
||||
values are important, use :func:`itertools.zip_longest` instead.
|
||||
Another way to think of :func:`zip` is that it turns rows into columns, and
|
||||
columns into rows. This is similar to `transposing a matrix
|
||||
<https://en.wikipedia.org/wiki/Transpose>`_.
|
||||
|
||||
:func:`zip` in conjunction with the ``*`` operator can be used to unzip a
|
||||
list::
|
||||
:func:`zip` is lazy: The elements won't be processed until the iterable is
|
||||
iterated on, e.g. by a :keyword:`!for` loop or by wrapping in a
|
||||
:class:`list`.
|
||||
|
||||
>>> x = [1, 2, 3]
|
||||
>>> y = [4, 5, 6]
|
||||
>>> zipped = zip(x, y)
|
||||
>>> list(zipped)
|
||||
[(1, 4), (2, 5), (3, 6)]
|
||||
>>> x2, y2 = zip(*zip(x, y))
|
||||
>>> x == list(x2) and y == list(y2)
|
||||
True
|
||||
One thing to consider is that the iterables passed to :func:`zip` could have
|
||||
different lengths; sometimes by design, and sometimes because of a bug in
|
||||
the code that prepared these iterables. Python offers three different
|
||||
approaches to dealing with this issue:
|
||||
|
||||
* By default, :func:`zip` stops when the shortest iterable is exhausted.
|
||||
It will ignore the remaining items in the longer iterables, cutting off
|
||||
the result to the length of the shortest iterable::
|
||||
|
||||
>>> list(zip(range(3), ['fee', 'fi', 'fo', 'fum']))
|
||||
[(0, 'fee'), (1, 'fi'), (2, 'fo')]
|
||||
|
||||
* :func:`zip` is often used in cases where the iterables are assumed to be
|
||||
of equal length. In such cases, it's recommended to use the ``strict=True``
|
||||
option. Its output is the same as regular :func:`zip`::
|
||||
|
||||
>>> list(zip(('a', 'b', 'c'), (1, 2, 3), strict=True))
|
||||
[('a', 1), ('b', 2), ('c', 3)]
|
||||
|
||||
Unlike the default behavior, it checks that the lengths of iterables are
|
||||
identical, raising a :exc:`ValueError` if they aren't:
|
||||
|
||||
>>> list(zip(range(3), ['fee', 'fi', 'fo', 'fum'], strict=True))
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: zip() argument 2 is longer than argument 1
|
||||
|
||||
Without the ``strict=True`` argument, any bug that results in iterables of
|
||||
different lengths will be silenced, possibly manifesting as a hard-to-find
|
||||
bug in another part of the program.
|
||||
|
||||
* Shorter iterables can be padded with a constant value to make all the
|
||||
iterables have the same length. This is done by
|
||||
:func:`itertools.zip_longest`.
|
||||
|
||||
Edge cases: With a single iterable argument, :func:`zip` returns an
|
||||
iterator of 1-tuples. With no arguments, it returns an empty iterator.
|
||||
|
||||
Tips and tricks:
|
||||
|
||||
* The left-to-right evaluation order of the iterables is guaranteed. This
|
||||
makes possible an idiom for clustering a data series into n-length groups
|
||||
using ``zip(*[iter(s)]*n, strict=True)``. This repeats the *same* iterator
|
||||
``n`` times so that each output tuple has the result of ``n`` calls to the
|
||||
iterator. This has the effect of dividing the input into n-length chunks.
|
||||
|
||||
* :func:`zip` in conjunction with the ``*`` operator can be used to unzip a
|
||||
list::
|
||||
|
||||
>>> x = [1, 2, 3]
|
||||
>>> y = [4, 5, 6]
|
||||
>>> list(zip(x, y))
|
||||
[(1, 4), (2, 5), (3, 6)]
|
||||
>>> x2, y2 = zip(*zip(x, y))
|
||||
>>> x == list(x2) and y == list(y2)
|
||||
True
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
Added the ``strict`` argument.
|
||||
|
||||
|
||||
.. function:: __import__(name, globals=None, locals=None, fromlist=(), level=0)
|
||||
|
|
|
@ -543,184 +543,6 @@ The :mod:`functools` module defines the following functions:
|
|||
.. versionadded:: 3.8
|
||||
|
||||
|
||||
.. class:: TopologicalSorter(graph=None)
|
||||
|
||||
Provides functionality to topologically sort a graph of hashable nodes.
|
||||
|
||||
A topological order is a linear ordering of the vertices in a graph such that
|
||||
for every directed edge u -> v from vertex u to vertex v, vertex u comes
|
||||
before vertex v in the ordering. For instance, the vertices of the graph may
|
||||
represent tasks to be performed, and the edges may represent constraints that
|
||||
one task must be performed before another; in this example, a topological
|
||||
ordering is just a valid sequence for the tasks. A complete topological
|
||||
ordering is possible if and only if the graph has no directed cycles, that
|
||||
is, if it is a directed acyclic graph.
|
||||
|
||||
If the optional *graph* argument is provided it must be a dictionary
|
||||
representing a directed acyclic graph where the keys are nodes and the values
|
||||
are iterables of all predecessors of that node in the graph (the nodes that
|
||||
have edges that point to the value in the key). Additional nodes can be added
|
||||
to the graph using the :meth:`~TopologicalSorter.add` method.
|
||||
|
||||
In the general case, the steps required to perform the sorting of a given
|
||||
graph are as follows:
|
||||
|
||||
* Create an instance of the :class:`TopologicalSorter` with an optional
|
||||
initial graph.
|
||||
* Add additional nodes to the graph.
|
||||
* Call :meth:`~TopologicalSorter.prepare` on the graph.
|
||||
* While :meth:`~TopologicalSorter.is_active` is ``True``, iterate over
|
||||
the nodes returned by :meth:`~TopologicalSorter.get_ready` and
|
||||
process them. Call :meth:`~TopologicalSorter.done` on each node as it
|
||||
finishes processing.
|
||||
|
||||
In case just an immediate sorting of the nodes in the graph is required and
|
||||
no parallelism is involved, the convenience method
|
||||
:meth:`TopologicalSorter.static_order` can be used directly:
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> graph = {"D": {"B", "C"}, "C": {"A"}, "B": {"A"}}
|
||||
>>> ts = TopologicalSorter(graph)
|
||||
>>> tuple(ts.static_order())
|
||||
('A', 'C', 'B', 'D')
|
||||
|
||||
The class is designed to easily support parallel processing of the nodes as
|
||||
they become ready. For instance::
|
||||
|
||||
topological_sorter = TopologicalSorter()
|
||||
|
||||
# Add nodes to 'topological_sorter'...
|
||||
|
||||
topological_sorter.prepare()
|
||||
while topological_sorter.is_active():
|
||||
for node in topological_sorter.get_ready():
|
||||
# Worker threads or processes take nodes to work on off the
|
||||
# 'task_queue' queue.
|
||||
task_queue.put(node)
|
||||
|
||||
# When the work for a node is done, workers put the node in
|
||||
# 'finalized_tasks_queue' so we can get more nodes to work on.
|
||||
# The definition of 'is_active()' guarantees that, at this point, at
|
||||
# least one node has been placed on 'task_queue' that hasn't yet
|
||||
# been passed to 'done()', so this blocking 'get()' must (eventually)
|
||||
# succeed. After calling 'done()', we loop back to call 'get_ready()'
|
||||
# again, so put newly freed nodes on 'task_queue' as soon as
|
||||
# logically possible.
|
||||
node = finalized_tasks_queue.get()
|
||||
topological_sorter.done(node)
|
||||
|
||||
.. method:: add(node, *predecessors)
|
||||
|
||||
Add a new node and its predecessors to the graph. Both the *node* and all
|
||||
elements in *predecessors* must be hashable.
|
||||
|
||||
If called multiple times with the same node argument, the set of
|
||||
dependencies will be the union of all dependencies passed in.
|
||||
|
||||
It is possible to add a node with no dependencies (*predecessors* is not
|
||||
provided) or to provide a dependency twice. If a node that has not been
|
||||
provided before is included among *predecessors* it will be automatically
|
||||
added to the graph with no predecessors of its own.
|
||||
|
||||
Raises :exc:`ValueError` if called after :meth:`~TopologicalSorter.prepare`.
|
||||
|
||||
.. method:: prepare()
|
||||
|
||||
Mark the graph as finished and check for cycles in the graph. If any cycle
|
||||
is detected, :exc:`CycleError` will be raised, but
|
||||
:meth:`~TopologicalSorter.get_ready` can still be used to obtain as many
|
||||
nodes as possible until cycles block more progress. After a call to this
|
||||
function, the graph cannot be modified, and therefore no more nodes can be
|
||||
added using :meth:`~TopologicalSorter.add`.
|
||||
|
||||
.. method:: is_active()
|
||||
|
||||
Returns ``True`` if more progress can be made and ``False`` otherwise.
|
||||
Progress can be made if cycles do not block the resolution and either
|
||||
there are still nodes ready that haven't yet been returned by
|
||||
:meth:`TopologicalSorter.get_ready` or the number of nodes marked
|
||||
:meth:`TopologicalSorter.done` is less than the number that have been
|
||||
returned by :meth:`TopologicalSorter.get_ready`.
|
||||
|
||||
The :meth:`~TopologicalSorter.__bool__` method of this class defers to
|
||||
this function, so instead of::
|
||||
|
||||
if ts.is_active():
|
||||
...
|
||||
|
||||
if possible to simply do::
|
||||
|
||||
if ts:
|
||||
...
|
||||
|
||||
Raises :exc:`ValueError` if called without calling
|
||||
:meth:`~TopologicalSorter.prepare` previously.
|
||||
|
||||
.. method:: done(*nodes)
|
||||
|
||||
Marks a set of nodes returned by :meth:`TopologicalSorter.get_ready` as
|
||||
processed, unblocking any successor of each node in *nodes* for being
|
||||
returned in the future by a call to :meth:`TopologicalSorter.get_ready`.
|
||||
|
||||
Raises :exc:`ValueError` if any node in *nodes* has already been marked as
|
||||
processed by a previous call to this method or if a node was not added to
|
||||
the graph by using :meth:`TopologicalSorter.add`, if called without
|
||||
calling :meth:`~TopologicalSorter.prepare` or if node has not yet been
|
||||
returned by :meth:`~TopologicalSorter.get_ready`.
|
||||
|
||||
.. method:: get_ready()
|
||||
|
||||
Returns a ``tuple`` with all the nodes that are ready. Initially it
|
||||
returns all nodes with no predecessors, and once those are marked as
|
||||
processed by calling :meth:`TopologicalSorter.done`, further calls will
|
||||
return all new nodes that have all their predecessors already processed.
|
||||
Once no more progress can be made, empty tuples are returned.
|
||||
|
||||
Raises :exc:`ValueError` if called without calling
|
||||
:meth:`~TopologicalSorter.prepare` previously.
|
||||
|
||||
.. method:: static_order()
|
||||
|
||||
Returns an iterable of nodes in a topological order. Using this method
|
||||
does not require to call :meth:`TopologicalSorter.prepare` or
|
||||
:meth:`TopologicalSorter.done`. This method is equivalent to::
|
||||
|
||||
def static_order(self):
|
||||
self.prepare()
|
||||
while self.is_active():
|
||||
node_group = self.get_ready()
|
||||
yield from node_group
|
||||
self.done(*node_group)
|
||||
|
||||
The particular order that is returned may depend on the specific order in
|
||||
which the items were inserted in the graph. For example:
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> ts = TopologicalSorter()
|
||||
>>> ts.add(3, 2, 1)
|
||||
>>> ts.add(1, 0)
|
||||
>>> print([*ts.static_order()])
|
||||
[2, 0, 1, 3]
|
||||
|
||||
>>> ts2 = TopologicalSorter()
|
||||
>>> ts2.add(1, 0)
|
||||
>>> ts2.add(3, 2, 1)
|
||||
>>> print([*ts2.static_order()])
|
||||
[0, 2, 1, 3]
|
||||
|
||||
This is due to the fact that "0" and "2" are in the same level in the
|
||||
graph (they would have been returned in the same call to
|
||||
:meth:`~TopologicalSorter.get_ready`) and the order between them is
|
||||
determined by the order of insertion.
|
||||
|
||||
|
||||
If any cycle is detected, :exc:`CycleError` will be raised.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. function:: update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
|
||||
|
||||
Update a *wrapper* function to look like the *wrapped* function. The optional
|
||||
|
@ -829,20 +651,4 @@ callable, weak referencable, and can have attributes. There are some important
|
|||
differences. For instance, the :attr:`~definition.__name__` and :attr:`__doc__` attributes
|
||||
are not created automatically. Also, :class:`partial` objects defined in
|
||||
classes behave like static methods and do not transform into bound methods
|
||||
during instance attribute look-up.
|
||||
|
||||
|
||||
Exceptions
|
||||
----------
|
||||
The :mod:`functools` module defines the following exception classes:
|
||||
|
||||
.. exception:: CycleError
|
||||
|
||||
Subclass of :exc:`ValueError` raised by :meth:`TopologicalSorter.prepare` if cycles exist
|
||||
in the working graph. If multiple cycles exist, only one undefined choice among them will
|
||||
be reported and included in the exception.
|
||||
|
||||
The detected cycle can be accessed via the second element in the :attr:`~CycleError.args`
|
||||
attribute of the exception instance and consists in a list of nodes, such that each node is,
|
||||
in the graph, an immediate predecessor of the next node in the list. In the reported list,
|
||||
the first and the last node will be the same, to make it clear that it is cyclic.
|
||||
during instance attribute look-up.
|
|
@ -36,7 +36,7 @@ For example, ``'[?]'`` matches the character ``'?'``.
|
|||
The :mod:`pathlib` module offers high-level path objects.
|
||||
|
||||
|
||||
.. function:: glob(pathname, *, recursive=False)
|
||||
.. function:: glob(pathname, *, root_dir=None, dir_fd=None, recursive=False)
|
||||
|
||||
Return a possibly-empty list of path names that match *pathname*, which must be
|
||||
a string containing a path specification. *pathname* can be either absolute
|
||||
|
@ -45,6 +45,15 @@ For example, ``'[?]'`` matches the character ``'?'``.
|
|||
symlinks are included in the results (as in the shell). Whether or not the
|
||||
results are sorted depends on the file system.
|
||||
|
||||
If *root_dir* is not ``None``, it should be a :term:`path-like object`
|
||||
specifying the root directory for searching. It has the same effect on
|
||||
:func:`glob` as changing the current directory before calling it. If
|
||||
*pathname* is relative, the result will contain paths relative to
|
||||
*root_dir*.
|
||||
|
||||
This function can support :ref:`paths relative to directory descriptors
|
||||
<dir_fd>` with the *dir_fd* parameter.
|
||||
|
||||
.. index::
|
||||
single: **; in glob-style wildcards
|
||||
|
||||
|
@ -62,8 +71,11 @@ For example, ``'[?]'`` matches the character ``'?'``.
|
|||
.. versionchanged:: 3.5
|
||||
Support for recursive globs using "``**``".
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
Added the *root_dir* and *dir_fd* parameters.
|
||||
|
||||
.. function:: iglob(pathname, *, recursive=False)
|
||||
|
||||
.. function:: iglob(pathname, *, root_dir=None, dir_fd=None, recursive=False)
|
||||
|
||||
Return an :term:`iterator` which yields the same values as :func:`glob`
|
||||
without actually storing them all simultaneously.
|
||||
|
|
|
@ -0,0 +1,209 @@
|
|||
:mod:`graphlib` --- Functionality to operate with graph-like structures
|
||||
=========================================================================
|
||||
|
||||
.. module:: graphlib
|
||||
:synopsis: Functionality to operate with graph-like structures
|
||||
|
||||
|
||||
**Source code:** :source:`Lib/graphlib.py`
|
||||
|
||||
.. testsetup:: default
|
||||
|
||||
import graphlib
|
||||
from graphlib import *
|
||||
|
||||
--------------
|
||||
|
||||
|
||||
.. class:: TopologicalSorter(graph=None)
|
||||
|
||||
Provides functionality to topologically sort a graph of hashable nodes.
|
||||
|
||||
A topological order is a linear ordering of the vertices in a graph such that
|
||||
for every directed edge u -> v from vertex u to vertex v, vertex u comes
|
||||
before vertex v in the ordering. For instance, the vertices of the graph may
|
||||
represent tasks to be performed, and the edges may represent constraints that
|
||||
one task must be performed before another; in this example, a topological
|
||||
ordering is just a valid sequence for the tasks. A complete topological
|
||||
ordering is possible if and only if the graph has no directed cycles, that
|
||||
is, if it is a directed acyclic graph.
|
||||
|
||||
If the optional *graph* argument is provided it must be a dictionary
|
||||
representing a directed acyclic graph where the keys are nodes and the values
|
||||
are iterables of all predecessors of that node in the graph (the nodes that
|
||||
have edges that point to the value in the key). Additional nodes can be added
|
||||
to the graph using the :meth:`~TopologicalSorter.add` method.
|
||||
|
||||
In the general case, the steps required to perform the sorting of a given
|
||||
graph are as follows:
|
||||
|
||||
* Create an instance of the :class:`TopologicalSorter` with an optional
|
||||
initial graph.
|
||||
* Add additional nodes to the graph.
|
||||
* Call :meth:`~TopologicalSorter.prepare` on the graph.
|
||||
* While :meth:`~TopologicalSorter.is_active` is ``True``, iterate over
|
||||
the nodes returned by :meth:`~TopologicalSorter.get_ready` and
|
||||
process them. Call :meth:`~TopologicalSorter.done` on each node as it
|
||||
finishes processing.
|
||||
|
||||
In case just an immediate sorting of the nodes in the graph is required and
|
||||
no parallelism is involved, the convenience method
|
||||
:meth:`TopologicalSorter.static_order` can be used directly:
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> graph = {"D": {"B", "C"}, "C": {"A"}, "B": {"A"}}
|
||||
>>> ts = TopologicalSorter(graph)
|
||||
>>> tuple(ts.static_order())
|
||||
('A', 'C', 'B', 'D')
|
||||
|
||||
The class is designed to easily support parallel processing of the nodes as
|
||||
they become ready. For instance::
|
||||
|
||||
topological_sorter = TopologicalSorter()
|
||||
|
||||
# Add nodes to 'topological_sorter'...
|
||||
|
||||
topological_sorter.prepare()
|
||||
while topological_sorter.is_active():
|
||||
for node in topological_sorter.get_ready():
|
||||
# Worker threads or processes take nodes to work on off the
|
||||
# 'task_queue' queue.
|
||||
task_queue.put(node)
|
||||
|
||||
# When the work for a node is done, workers put the node in
|
||||
# 'finalized_tasks_queue' so we can get more nodes to work on.
|
||||
# The definition of 'is_active()' guarantees that, at this point, at
|
||||
# least one node has been placed on 'task_queue' that hasn't yet
|
||||
# been passed to 'done()', so this blocking 'get()' must (eventually)
|
||||
# succeed. After calling 'done()', we loop back to call 'get_ready()'
|
||||
# again, so put newly freed nodes on 'task_queue' as soon as
|
||||
# logically possible.
|
||||
node = finalized_tasks_queue.get()
|
||||
topological_sorter.done(node)
|
||||
|
||||
.. method:: add(node, *predecessors)
|
||||
|
||||
Add a new node and its predecessors to the graph. Both the *node* and all
|
||||
elements in *predecessors* must be hashable.
|
||||
|
||||
If called multiple times with the same node argument, the set of
|
||||
dependencies will be the union of all dependencies passed in.
|
||||
|
||||
It is possible to add a node with no dependencies (*predecessors* is not
|
||||
provided) or to provide a dependency twice. If a node that has not been
|
||||
provided before is included among *predecessors* it will be automatically
|
||||
added to the graph with no predecessors of its own.
|
||||
|
||||
Raises :exc:`ValueError` if called after :meth:`~TopologicalSorter.prepare`.
|
||||
|
||||
.. method:: prepare()
|
||||
|
||||
Mark the graph as finished and check for cycles in the graph. If any cycle
|
||||
is detected, :exc:`CycleError` will be raised, but
|
||||
:meth:`~TopologicalSorter.get_ready` can still be used to obtain as many
|
||||
nodes as possible until cycles block more progress. After a call to this
|
||||
function, the graph cannot be modified, and therefore no more nodes can be
|
||||
added using :meth:`~TopologicalSorter.add`.
|
||||
|
||||
.. method:: is_active()
|
||||
|
||||
Returns ``True`` if more progress can be made and ``False`` otherwise.
|
||||
Progress can be made if cycles do not block the resolution and either
|
||||
there are still nodes ready that haven't yet been returned by
|
||||
:meth:`TopologicalSorter.get_ready` or the number of nodes marked
|
||||
:meth:`TopologicalSorter.done` is less than the number that have been
|
||||
returned by :meth:`TopologicalSorter.get_ready`.
|
||||
|
||||
The :meth:`~TopologicalSorter.__bool__` method of this class defers to
|
||||
this function, so instead of::
|
||||
|
||||
if ts.is_active():
|
||||
...
|
||||
|
||||
if possible to simply do::
|
||||
|
||||
if ts:
|
||||
...
|
||||
|
||||
Raises :exc:`ValueError` if called without calling
|
||||
:meth:`~TopologicalSorter.prepare` previously.
|
||||
|
||||
.. method:: done(*nodes)
|
||||
|
||||
Marks a set of nodes returned by :meth:`TopologicalSorter.get_ready` as
|
||||
processed, unblocking any successor of each node in *nodes* for being
|
||||
returned in the future by a call to :meth:`TopologicalSorter.get_ready`.
|
||||
|
||||
Raises :exc:`ValueError` if any node in *nodes* has already been marked as
|
||||
processed by a previous call to this method or if a node was not added to
|
||||
the graph by using :meth:`TopologicalSorter.add`, if called without
|
||||
calling :meth:`~TopologicalSorter.prepare` or if node has not yet been
|
||||
returned by :meth:`~TopologicalSorter.get_ready`.
|
||||
|
||||
.. method:: get_ready()
|
||||
|
||||
Returns a ``tuple`` with all the nodes that are ready. Initially it
|
||||
returns all nodes with no predecessors, and once those are marked as
|
||||
processed by calling :meth:`TopologicalSorter.done`, further calls will
|
||||
return all new nodes that have all their predecessors already processed.
|
||||
Once no more progress can be made, empty tuples are returned.
|
||||
|
||||
Raises :exc:`ValueError` if called without calling
|
||||
:meth:`~TopologicalSorter.prepare` previously.
|
||||
|
||||
.. method:: static_order()
|
||||
|
||||
Returns an iterable of nodes in a topological order. Using this method
|
||||
does not require to call :meth:`TopologicalSorter.prepare` or
|
||||
:meth:`TopologicalSorter.done`. This method is equivalent to::
|
||||
|
||||
def static_order(self):
|
||||
self.prepare()
|
||||
while self.is_active():
|
||||
node_group = self.get_ready()
|
||||
yield from node_group
|
||||
self.done(*node_group)
|
||||
|
||||
The particular order that is returned may depend on the specific order in
|
||||
which the items were inserted in the graph. For example:
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> ts = TopologicalSorter()
|
||||
>>> ts.add(3, 2, 1)
|
||||
>>> ts.add(1, 0)
|
||||
>>> print([*ts.static_order()])
|
||||
[2, 0, 1, 3]
|
||||
|
||||
>>> ts2 = TopologicalSorter()
|
||||
>>> ts2.add(1, 0)
|
||||
>>> ts2.add(3, 2, 1)
|
||||
>>> print([*ts2.static_order()])
|
||||
[0, 2, 1, 3]
|
||||
|
||||
This is due to the fact that "0" and "2" are in the same level in the
|
||||
graph (they would have been returned in the same call to
|
||||
:meth:`~TopologicalSorter.get_ready`) and the order between them is
|
||||
determined by the order of insertion.
|
||||
|
||||
|
||||
If any cycle is detected, :exc:`CycleError` will be raised.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
Exceptions
|
||||
----------
|
||||
The :mod:`graphlib` module defines the following exception classes:
|
||||
|
||||
.. exception:: CycleError
|
||||
|
||||
Subclass of :exc:`ValueError` raised by :meth:`TopologicalSorter.prepare` if cycles exist
|
||||
in the working graph. If multiple cycles exist, only one undefined choice among them will
|
||||
be reported and included in the exception.
|
||||
|
||||
The detected cycle can be accessed via the second element in the :attr:`~CycleError.args`
|
||||
attribute of the exception instance and consists in a list of nodes, such that each node is,
|
||||
in the graph, an immediate predecessor of the next node in the list. In the reported list,
|
||||
the first and the last node will be the same, to make it clear that it is cyclic.
|
|
@ -138,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::
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
**Source code:** :source:`Lib/imp.py`
|
||||
|
||||
.. deprecated:: 3.4
|
||||
The :mod:`imp` package is pending deprecation in favor of :mod:`importlib`.
|
||||
The :mod:`imp` module is deprecated in favor of :mod:`importlib`.
|
||||
|
||||
.. index:: statement: import
|
||||
|
||||
|
|
|
@ -77,7 +77,9 @@ Entry points
|
|||
The ``entry_points()`` function returns a dictionary of all entry points,
|
||||
keyed by group. Entry points are represented by ``EntryPoint`` instances;
|
||||
each ``EntryPoint`` has a ``.name``, ``.group``, and ``.value`` attributes and
|
||||
a ``.load()`` method to resolve the value.
|
||||
a ``.load()`` method to resolve the value. There are also ``.module``,
|
||||
``.attr``, and ``.extras`` attributes for getting the components of the
|
||||
``.value`` attribute::
|
||||
|
||||
>>> eps = entry_points() # doctest: +SKIP
|
||||
>>> list(eps) # doctest: +SKIP
|
||||
|
@ -86,6 +88,12 @@ a ``.load()`` method to resolve the value.
|
|||
>>> wheel = [ep for ep in scripts if ep.name == 'wheel'][0] # doctest: +SKIP
|
||||
>>> wheel # doctest: +SKIP
|
||||
EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts')
|
||||
>>> wheel.module # doctest: +SKIP
|
||||
'wheel.cli'
|
||||
>>> wheel.attr # doctest: +SKIP
|
||||
'main'
|
||||
>>> wheel.extras # doctest: +SKIP
|
||||
[]
|
||||
>>> main = wheel.load() # doctest: +SKIP
|
||||
>>> main # doctest: +SKIP
|
||||
<function main at 0x103528488>
|
||||
|
@ -94,7 +102,7 @@ The ``group`` and ``name`` are arbitrary values defined by the package author
|
|||
and usually a client will wish to resolve all entry points for a particular
|
||||
group. Read `the setuptools docs
|
||||
<https://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins>`_
|
||||
for more information on entrypoints, their definition, and usage.
|
||||
for more information on entry points, their definition, and usage.
|
||||
|
||||
|
||||
.. _metadata:
|
||||
|
@ -235,7 +243,7 @@ method::
|
|||
"""
|
||||
|
||||
The ``DistributionFinder.Context`` object provides ``.path`` and ``.name``
|
||||
properties indicating the path to search and names to match and may
|
||||
properties indicating the path to search and name to match and may
|
||||
supply other relevant context.
|
||||
|
||||
What this means in practice is that to support finding distribution package
|
||||
|
|
|
@ -199,9 +199,9 @@ loops that truncate the stream.
|
|||
|
||||
Return *r* length subsequences of elements from the input *iterable*.
|
||||
|
||||
Combinations are emitted in lexicographic sort order. So, if the
|
||||
input *iterable* is sorted, the combination tuples will be produced
|
||||
in sorted order.
|
||||
The combination tuples are emitted in lexicographic ordering according to
|
||||
the order of the input *iterable*. So, if the input *iterable* is sorted,
|
||||
the combination tuples will be produced in sorted order.
|
||||
|
||||
Elements are treated as unique based on their position, not on their
|
||||
value. So if the input elements are unique, there will be no repeat
|
||||
|
@ -248,9 +248,9 @@ loops that truncate the stream.
|
|||
Return *r* length subsequences of elements from the input *iterable*
|
||||
allowing individual elements to be repeated more than once.
|
||||
|
||||
Combinations are emitted in lexicographic sort order. So, if the
|
||||
input *iterable* is sorted, the combination tuples will be produced
|
||||
in sorted order.
|
||||
The combination tuples are emitted in lexicographic ordering according to
|
||||
the order of the input *iterable*. So, if the input *iterable* is sorted,
|
||||
the combination tuples will be produced in sorted order.
|
||||
|
||||
Elements are treated as unique based on their position, not on their
|
||||
value. So if the input elements are unique, the generated combinations
|
||||
|
@ -484,9 +484,9 @@ loops that truncate the stream.
|
|||
of the *iterable* and all possible full-length permutations
|
||||
are generated.
|
||||
|
||||
Permutations are emitted in lexicographic sort order. So, if the
|
||||
input *iterable* is sorted, the permutation tuples will be produced
|
||||
in sorted order.
|
||||
The permutation tuples are emitted in lexicographic ordering according to
|
||||
the order of the input *iterable*. So, if the input *iterable* is sorted,
|
||||
the combination tuples will be produced in sorted order.
|
||||
|
||||
Elements are treated as unique based on their position, not on their
|
||||
value. So if the input elements are unique, there will be no repeat
|
||||
|
@ -563,6 +563,9 @@ loops that truncate the stream.
|
|||
for prod in result:
|
||||
yield tuple(prod)
|
||||
|
||||
Before :func:`product` runs, it completely consumes the input iterables,
|
||||
keeping pools of values in memory to generate the products. Accordingly,
|
||||
it only useful with finite inputs.
|
||||
|
||||
.. function:: repeat(object[, times])
|
||||
|
||||
|
|
|
@ -22,3 +22,19 @@ This module allows a Python program to determine if a string is a
|
|||
Sequence containing all the :ref:`keywords <keywords>` defined for the
|
||||
interpreter. If any keywords are defined to only be active when particular
|
||||
:mod:`__future__` statements are in effect, these will be included as well.
|
||||
|
||||
|
||||
.. function:: issoftkeyword(s)
|
||||
|
||||
Return ``True`` if *s* is a Python soft :ref:`keyword <keywords>`.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. data:: softkwlist
|
||||
|
||||
Sequence containing all the soft :ref:`keywords <keywords>` defined for the
|
||||
interpreter. If any soft keywords are defined to only be active when particular
|
||||
:mod:`__future__` statements are in effect, these will be included as well.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
|
|
@ -529,7 +529,8 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on
|
|||
:ref:`logrecord-attributes`.
|
||||
|
||||
|
||||
.. class:: Formatter(fmt=None, datefmt=None, style='%', validate=True)
|
||||
.. class:: Formatter(fmt=None, datefmt=None, style='%', validate=True, *,
|
||||
defaults=None)
|
||||
|
||||
Returns a new instance of the :class:`Formatter` class. The instance is
|
||||
initialized with a format string for the message as a whole, as well as a
|
||||
|
@ -545,6 +546,10 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on
|
|||
:ref:`formatting-styles` for more information on using {- and $-formatting
|
||||
for log messages.
|
||||
|
||||
The *defaults* parameter can be a dictionary with default values to use in
|
||||
custom fields. For example:
|
||||
``logging.Formatter('%(ip)s %(message)s', defaults={"ip": None})``
|
||||
|
||||
.. versionchanged:: 3.2
|
||||
The *style* parameter was added.
|
||||
|
||||
|
@ -553,6 +558,9 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on
|
|||
will raise a ``ValueError``.
|
||||
For example: ``logging.Formatter('%(asctime)s - %(message)s', style='{')``.
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
The *defaults* parameter was added.
|
||||
|
||||
.. method:: format(record)
|
||||
|
||||
The record's attribute dictionary is used as the operand to a string
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1211,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.
|
||||
|
||||
|
@ -1228,8 +1229,8 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
|
|||
|
||||
.. 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.
|
||||
|
||||
|
@ -1238,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*.
|
||||
|
|
|
@ -30,10 +30,11 @@ available for Python:
|
|||
for generating bindings for C++ libraries as Python classes, and
|
||||
is specifically designed for Python.
|
||||
|
||||
`PySide <https://wiki.qt.io/PySide>`_
|
||||
PySide is a newer binding to the Qt toolkit, provided by Nokia.
|
||||
Compared to PyQt, its licensing scheme is friendlier to non-open source
|
||||
applications.
|
||||
`PySide2 <https://doc.qt.io/qtforpython/>`_
|
||||
Also known as the Qt for Python project, PySide2 is a newer binding to the
|
||||
Qt toolkit. It is provided by The Qt Company and aims to provide a
|
||||
complete port of PySide to Qt 5. Compared to PyQt, its licensing scheme is
|
||||
friendlier to non-open source applications.
|
||||
|
||||
`wxPython <https://www.wxpython.org>`_
|
||||
wxPython is a cross-platform GUI toolkit for Python that is built around
|
||||
|
@ -47,7 +48,7 @@ available for Python:
|
|||
an XML-based resource format and more, including an ever growing library
|
||||
of user-contributed modules.
|
||||
|
||||
PyGTK, PyQt, and wxPython, all have a modern look and feel and more
|
||||
PyGTK, PyQt, PySide2, and wxPython, all have a modern look and feel and more
|
||||
widgets than Tkinter. In addition, there are many other GUI toolkits for
|
||||
Python, both cross-platform, and platform-specific. See the `GUI Programming
|
||||
<https://wiki.python.org/moin/GuiProgramming>`_ page in the Python Wiki for a
|
||||
|
|
|
@ -538,6 +538,7 @@ by the local file.
|
|||
executed in the current environment).
|
||||
|
||||
.. pdbcommand:: retval
|
||||
|
||||
Print the return value for the last return of a function.
|
||||
|
||||
.. rubric:: Footnotes
|
||||
|
|
|
@ -570,12 +570,14 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules.
|
|||
available), or "xztar" (if the :mod:`lzma` module is available).
|
||||
|
||||
*root_dir* is a directory that will be the root directory of the
|
||||
archive; for example, we typically chdir into *root_dir* before creating the
|
||||
archive.
|
||||
archive, all paths in the archive will be relative to it; for example,
|
||||
we typically chdir into *root_dir* before creating the archive.
|
||||
|
||||
*base_dir* is the directory where we start archiving from;
|
||||
i.e. *base_dir* will be the common prefix of all files and
|
||||
directories in the archive.
|
||||
directories in the archive. *base_dir* must be given relative
|
||||
to *root_dir*. See :ref:`shutil-archiving-example-with-basedir` for how to
|
||||
use *base_dir* and *root_dir* together.
|
||||
|
||||
*root_dir* and *base_dir* both default to the current directory.
|
||||
|
||||
|
@ -727,6 +729,48 @@ The resulting archive contains:
|
|||
-rw-r--r-- tarek/staff 37192 2010-02-06 18:23:10 ./known_hosts
|
||||
|
||||
|
||||
.. _shutil-archiving-example-with-basedir:
|
||||
|
||||
Archiving example with *base_dir*
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In this example, similar to the `one above <shutil-archiving-example_>`_,
|
||||
we show how to use :func:`make_archive`, but this time with the usage of
|
||||
*base_dir*. We now have the following directory structure:
|
||||
|
||||
.. code-block:: shell-session
|
||||
|
||||
$ tree tmp
|
||||
tmp
|
||||
└── root
|
||||
└── structure
|
||||
├── content
|
||||
└── please_add.txt
|
||||
└── do_not_add.txt
|
||||
|
||||
In the final archive, :file:`please_add.txt` should be included, but
|
||||
:file:`do_not_add.txt` should not. Therefore we use the following::
|
||||
|
||||
>>> from shutil import make_archive
|
||||
>>> import os
|
||||
>>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))
|
||||
>>> make_archive(
|
||||
... archive_name,
|
||||
... 'tar',
|
||||
... root_dir='tmp/root',
|
||||
... base_dir='structure/content',
|
||||
... )
|
||||
'/Users/tarek/my_archive.tar'
|
||||
|
||||
Listing the files in the resulting archive gives us:
|
||||
|
||||
.. code-block:: shell-session
|
||||
|
||||
$ python -m tarfile -l /Users/tarek/myarchive.tar
|
||||
structure/content/
|
||||
structure/content/please_add.txt
|
||||
|
||||
|
||||
Querying the size of the output terminal
|
||||
----------------------------------------
|
||||
|
||||
|
|
|
@ -478,6 +478,27 @@ class`. In addition, it provides a few more methods:
|
|||
|
||||
.. versionadded:: 3.1
|
||||
|
||||
.. method:: int.bit_count()
|
||||
|
||||
Return the number of ones in the binary representation of the absolute
|
||||
value of the integer. This is also known as the population count.
|
||||
Example::
|
||||
|
||||
>>> n = 19
|
||||
>>> bin(n)
|
||||
'0b10011'
|
||||
>>> n.bit_count()
|
||||
3
|
||||
>>> (-n).bit_count()
|
||||
3
|
||||
|
||||
Equivalent to::
|
||||
|
||||
def bit_count(self):
|
||||
return bin(self).count("1")
|
||||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
.. method:: int.to_bytes(length, byteorder, \*, signed=False)
|
||||
|
||||
Return an array of bytes representing an integer.
|
||||
|
@ -4601,6 +4622,12 @@ support membership tests:
|
|||
.. versionchanged:: 3.8
|
||||
Dictionary views are now reversible.
|
||||
|
||||
.. describe:: dictview.mapping
|
||||
|
||||
Return a :class:`types.MappingProxyType` that wraps the original
|
||||
dictionary to which the view refers.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
Keys views are set-like since their entries are unique and hashable. If all
|
||||
values are hashable, so that ``(key, value)`` pairs are unique and hashable,
|
||||
|
@ -4640,6 +4667,12 @@ An example of dictionary view usage::
|
|||
>>> keys ^ {'sausage', 'juice'}
|
||||
{'juice', 'sausage', 'bacon', 'spam'}
|
||||
|
||||
>>> # get back a read-only proxy for the original dictionary
|
||||
>>> values.mapping
|
||||
mappingproxy({'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500})
|
||||
>>> values.mapping['spam']
|
||||
500
|
||||
|
||||
|
||||
.. _typecontextmanager:
|
||||
|
||||
|
|
|
@ -738,10 +738,11 @@ Instances of the :class:`Popen` class have the following methods:
|
|||
.. method:: Popen.communicate(input=None, timeout=None)
|
||||
|
||||
Interact with process: Send data to stdin. Read data from stdout and stderr,
|
||||
until end-of-file is reached. Wait for process to terminate. The optional
|
||||
*input* argument should be data to be sent to the child process, or
|
||||
``None``, if no data should be sent to the child. If streams were opened in
|
||||
text mode, *input* must be a string. Otherwise, it must be bytes.
|
||||
until end-of-file is reached. Wait for process to terminate and set the
|
||||
:attr:`~Popen.returncode` attribute. The optional *input* argument should be
|
||||
data to be sent to the child process, or ``None``, if no data should be sent
|
||||
to the child. If streams were opened in text mode, *input* must be a string.
|
||||
Otherwise, it must be bytes.
|
||||
|
||||
:meth:`communicate` returns a tuple ``(stdout_data, stderr_data)``.
|
||||
The data will be strings if streams were opened in text mode; otherwise,
|
||||
|
|
|
@ -17,6 +17,11 @@ the definitions of the names in the context of the language grammar. The
|
|||
specific numeric values which the names map to may change between Python
|
||||
versions.
|
||||
|
||||
.. warning::
|
||||
|
||||
The symbol module is deprecated and will be removed in future versions of
|
||||
Python.
|
||||
|
||||
This module also provides one additional data object:
|
||||
|
||||
|
||||
|
|
|
@ -66,6 +66,8 @@ always available.
|
|||
To loop over the standard input, or the list of files given on the
|
||||
command line, see the :mod:`fileinput` module.
|
||||
|
||||
See also :data:`sys.orig_argv`.
|
||||
|
||||
.. note::
|
||||
On Unix, command line arguments are passed by bytes from OS. Python decodes
|
||||
them with filesystem encoding and "surrogateescape" error handler.
|
||||
|
@ -1037,6 +1039,16 @@ always available.
|
|||
deleting essential items from the dictionary may cause Python to fail.
|
||||
|
||||
|
||||
.. data:: orig_argv
|
||||
|
||||
The list of the original command line arguments passed to the Python
|
||||
executable.
|
||||
|
||||
See also :data:`sys.argv`.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
|
||||
.. data:: path
|
||||
|
||||
.. index:: triple: module; search; path
|
||||
|
@ -1141,8 +1153,7 @@ always available.
|
|||
.. data:: platlibdir
|
||||
|
||||
Name of the platform-specific library directory. It is used to build the
|
||||
path of platform-specific dynamic libraries and the path of the standard
|
||||
library.
|
||||
path of standard library and the paths of installed extension modules.
|
||||
|
||||
It is equal to ``"lib"`` on most platforms. On Fedora and SuSE, it is equal
|
||||
to ``"lib64"`` on 64-bit platforms which gives the following ``sys.path``
|
||||
|
@ -1153,8 +1164,10 @@ always available.
|
|||
* ``/usr/lib64/pythonX.Y/lib-dynload/``:
|
||||
C extension modules of the standard library (like the :mod:`errno` module,
|
||||
the exact filename is platform specific)
|
||||
* ``/usr/lib/pythonX.Y/site-packages`` (always use ``lib``, not
|
||||
* ``/usr/lib/pythonX.Y/site-packages/`` (always use ``lib``, not
|
||||
:data:`sys.platlibdir`): Third-party modules
|
||||
* ``/usr/lib64/pythonX.Y/site-packages/``:
|
||||
C extension modules of third-party packages
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
|
|
@ -787,7 +787,7 @@ How to read a gzip compressed tar archive and display some member information::
|
|||
import tarfile
|
||||
tar = tarfile.open("sample.tar.gz", "r:gz")
|
||||
for tarinfo in tar:
|
||||
print(tarinfo.name, "is", tarinfo.size, "bytes in size and is", end="")
|
||||
print(tarinfo.name, "is", tarinfo.size, "bytes in size and is ", end="")
|
||||
if tarinfo.isreg():
|
||||
print("a regular file.")
|
||||
elif tarinfo.isdir():
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -349,13 +349,12 @@ since it is impossible to detect the termination of alien threads.
|
|||
|
||||
.. attribute:: native_id
|
||||
|
||||
The native integral thread ID of this thread.
|
||||
The Thread ID (``TID``) of this thread, as assigned by the OS (kernel).
|
||||
This is a non-negative integer, or ``None`` if the thread has not
|
||||
been started. See the :func:`get_native_id` function.
|
||||
This represents the Thread ID (``TID``) as assigned to the
|
||||
thread by the OS (kernel). Its value may be used to uniquely identify
|
||||
this particular thread system-wide (until the thread terminates,
|
||||
after which the value may be recycled by the OS).
|
||||
This value may be used to uniquely identify this particular thread
|
||||
system-wide (until the thread terminates, after which the value
|
||||
may be recycled by the OS).
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
|
@ -345,7 +345,7 @@ Functions
|
|||
|
||||
See also :func:`get_traced_memory`.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. function:: get_tracemalloc_memory()
|
||||
|
|
|
@ -672,7 +672,7 @@ The module defines the following classes, functions and decorators:
|
|||
A generic version of :class:`collections.abc.ByteString`.
|
||||
|
||||
This type represents the types :class:`bytes`, :class:`bytearray`,
|
||||
and :class:`memoryview`.
|
||||
and :class:`memoryview` of byte sequences.
|
||||
|
||||
As a shorthand for this type, :class:`bytes` can be used to
|
||||
annotate arguments of any of the types mentioned above.
|
||||
|
|
|
@ -950,6 +950,9 @@ Test cases
|
|||
| :meth:`assertLogs(logger, level) | The ``with`` block logs on *logger* | 3.4 |
|
||||
| <TestCase.assertLogs>` | with minimum *level* | |
|
||||
+---------------------------------------------------------+--------------------------------------+------------+
|
||||
| :meth:`assertNoLogs(logger, level) | The ``with`` block does not log on | 3.10 |
|
||||
| <TestCase.assertNoLogs>` | *logger* with minimum *level* | |
|
||||
+---------------------------------------------------------+--------------------------------------+------------+
|
||||
|
||||
.. method:: assertRaises(exception, callable, *args, **kwds)
|
||||
assertRaises(exception, *, msg=None)
|
||||
|
@ -1121,6 +1124,24 @@ Test cases
|
|||
|
||||
.. versionadded:: 3.4
|
||||
|
||||
.. method:: assertNoLogs(logger=None, level=None)
|
||||
|
||||
A context manager to test that no messages are logged on
|
||||
the *logger* or one of its children, with at least the given
|
||||
*level*.
|
||||
|
||||
If given, *logger* should be a :class:`logging.Logger` object or a
|
||||
:class:`str` giving the name of a logger. The default is the root
|
||||
logger, which will catch all messages.
|
||||
|
||||
If given, *level* should be either a numeric logging level or
|
||||
its string equivalent (for example either ``"ERROR"`` or
|
||||
:attr:`logging.ERROR`). The default is :attr:`logging.INFO`.
|
||||
|
||||
Unlike :meth:`assertLogs`, nothing will be returned by the context
|
||||
manager.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
There are also other methods used to perform more specific checks, such as:
|
||||
|
||||
|
|
|
@ -163,14 +163,6 @@ Extension types can easily be made to support weak references; see
|
|||
application without adding attributes to those objects. This can be especially
|
||||
useful with objects that override attribute accesses.
|
||||
|
||||
.. note::
|
||||
|
||||
Caution: Because a :class:`WeakKeyDictionary` is built on top of a Python
|
||||
dictionary, it must not change size when iterating over it. This can be
|
||||
difficult to ensure for a :class:`WeakKeyDictionary` because actions
|
||||
performed by the program during iteration may cause items in the
|
||||
dictionary to vanish "by magic" (as a side effect of garbage collection).
|
||||
|
||||
.. versionchanged:: 3.9
|
||||
Added support for ``|`` and ``|=`` operators, specified in :pep:`584`.
|
||||
|
||||
|
@ -192,14 +184,6 @@ than needed.
|
|||
Mapping class that references values weakly. Entries in the dictionary will be
|
||||
discarded when no strong reference to the value exists any more.
|
||||
|
||||
.. note::
|
||||
|
||||
Caution: Because a :class:`WeakValueDictionary` is built on top of a Python
|
||||
dictionary, it must not change size when iterating over it. This can be
|
||||
difficult to ensure for a :class:`WeakValueDictionary` because actions performed
|
||||
by the program during iteration may cause items in the dictionary to vanish "by
|
||||
magic" (as a side effect of garbage collection).
|
||||
|
||||
.. versionchanged:: 3.9
|
||||
Added support for ``|`` and ``|=`` operators, as specified in :pep:`584`.
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ for parsing and creating XML data.
|
|||
|
||||
.. versionchanged:: 3.3
|
||||
This module will use a fast implementation whenever available.
|
||||
|
||||
.. deprecated:: 3.3
|
||||
The :mod:`xml.etree.cElementTree` module is deprecated.
|
||||
|
||||
|
||||
|
@ -816,16 +818,25 @@ Functions
|
|||
loader fails, it can return None or raise an exception.
|
||||
|
||||
|
||||
.. function:: xml.etree.ElementInclude.include( elem, loader=None)
|
||||
.. function:: xml.etree.ElementInclude.include( elem, loader=None, base_url=None, \
|
||||
max_depth=6)
|
||||
|
||||
This function expands XInclude directives. *elem* is the root element. *loader* is
|
||||
an optional resource loader. If omitted, it defaults to :func:`default_loader`.
|
||||
If given, it should be a callable that implements the same interface as
|
||||
:func:`default_loader`. Returns the expanded resource. If the parse mode is
|
||||
:func:`default_loader`. *base_url* is base URL of the original file, to resolve
|
||||
relative include file references. *max_depth* is the maximum number of recursive
|
||||
inclusions. Limited to reduce the risk of malicious content explosion. Pass a
|
||||
negative value to disable the limitation.
|
||||
|
||||
Returns the expanded resource. If the parse mode is
|
||||
``"xml"``, this is an ElementTree instance. If the parse mode is "text",
|
||||
this is a Unicode string. If the loader fails, it can return None or
|
||||
raise an exception.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
The *base_url* and *max_depth* parameters.
|
||||
|
||||
|
||||
.. _elementtree-element-objects:
|
||||
|
||||
|
|
|
@ -889,7 +889,7 @@ libmpdec
|
|||
The :mod:`_decimal` module is built using an included copy of the libmpdec
|
||||
library unless the build is configured ``--with-system-libmpdec``::
|
||||
|
||||
Copyright (c) 2008-2016 Stefan Krah. All rights reserved.
|
||||
Copyright (c) 2008-2020 Stefan Krah. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
|
|
|
@ -13,7 +13,7 @@ if not defined SPHINXBUILD (
|
|||
%PYTHON% -c "import sphinx" > nul 2> nul
|
||||
if errorlevel 1 (
|
||||
echo Installing sphinx with %PYTHON%
|
||||
%PYTHON% -m pip install sphinx
|
||||
%PYTHON% -m pip install sphinx==2.2.0
|
||||
if errorlevel 1 exit /B
|
||||
)
|
||||
set SPHINXBUILD=%PYTHON% -c "import sphinx.cmd.build, sys; sys.exit(sphinx.cmd.build.main())"
|
||||
|
|
BIN
Doc/myfile.bz2
BIN
Doc/myfile.bz2
Binary file not shown.
|
@ -704,7 +704,7 @@ Top-level format specifiers may include nested replacement fields. These nested
|
|||
fields may include their own conversion fields and :ref:`format specifiers
|
||||
<formatspec>`, but may not include more deeply-nested replacement fields. The
|
||||
:ref:`format specifier mini-language <formatspec>` is the same as that used by
|
||||
the string .format() method.
|
||||
the :meth:`str.format` method.
|
||||
|
||||
Formatted string literals may be concatenated, but replacement fields
|
||||
cannot be split across literals.
|
||||
|
|
|
@ -311,7 +311,8 @@ class DeprecatedRemoved(Directive):
|
|||
final_argument_whitespace = True
|
||||
option_spec = {}
|
||||
|
||||
_label = 'Deprecated since version {deprecated}, will be removed in version {removed}'
|
||||
_deprecated_label = 'Deprecated since version {deprecated}, will be removed in version {removed}'
|
||||
_removed_label = 'Deprecated since version {deprecated}, removed in version {removed}'
|
||||
|
||||
def run(self):
|
||||
node = addnodes.versionmodified()
|
||||
|
@ -319,7 +320,15 @@ class DeprecatedRemoved(Directive):
|
|||
node['type'] = 'deprecated-removed'
|
||||
version = (self.arguments[0], self.arguments[1])
|
||||
node['version'] = version
|
||||
label = translators['sphinx'].gettext(self._label)
|
||||
env = self.state.document.settings.env
|
||||
current_version = tuple(int(e) for e in env.config.version.split('.'))
|
||||
removed_version = tuple(int(e) for e in self.arguments[1].split('.'))
|
||||
if current_version < removed_version:
|
||||
label = self._deprecated_label
|
||||
else:
|
||||
label = self._removed_label
|
||||
|
||||
label = translators['sphinx'].gettext(label)
|
||||
text = label.format(deprecated=self.arguments[0], removed=self.arguments[1])
|
||||
if len(self.arguments) == 3:
|
||||
inodes, messages = self.state.inline_text(self.arguments[2],
|
||||
|
|
|
@ -5,3 +5,4 @@ In extensions/pyspecific.py:
|
|||
|
||||
{% trans %}CPython implementation detail:{% endtrans %}
|
||||
{% trans %}Deprecated since version {deprecated}, will be removed in version {removed}{% endtrans %}
|
||||
{% trans %}Deprecated since version {deprecated}, removed in version {removed}{% endtrans %}
|
||||
|
|
|
@ -114,8 +114,8 @@ accessible. "Directly accessible" here means that an unqualified reference to a
|
|||
name attempts to find the name in the namespace.
|
||||
|
||||
Although scopes are determined statically, they are used dynamically. At any
|
||||
time during execution, there are at least three nested scopes whose namespaces
|
||||
are directly accessible:
|
||||
time during execution, At any time during execution, there are 3 or 4 nested
|
||||
scopes whose namespaces are directly accessible:
|
||||
|
||||
* the innermost scope, which is searched first, contains the local names
|
||||
* the scopes of any enclosing functions, which are searched starting with the
|
||||
|
|
|
@ -300,11 +300,10 @@ passed using *call by value* (where the *value* is always an object *reference*,
|
|||
not the value of the object). [#]_ When a function calls another function, a new
|
||||
local symbol table is created for that call.
|
||||
|
||||
A function definition introduces the function name in the current symbol table.
|
||||
The value of the function name has a type that is recognized by the interpreter
|
||||
as a user-defined function. This value can be assigned to another name which
|
||||
can then also be used as a function. This serves as a general renaming
|
||||
mechanism::
|
||||
A function definition associates the function name with the function object in
|
||||
the current symbol table. The interpreter recognizes the object pointed to by
|
||||
that name as a user-defined function. Other names can also point to that same
|
||||
function object and can also be used to access the function::
|
||||
|
||||
>>> fib
|
||||
<function fib at 10042ed0>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -369,6 +369,11 @@ Miscellaneous options
|
|||
(filename or built-in module) from which it is loaded. When given twice
|
||||
(:option:`!-vv`), print a message for each file that is checked for when
|
||||
searching for a module. Also provides information on module cleanup at exit.
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
The :mod:`site` module reports the site-specific paths
|
||||
and :file:`.pth` files being processed.
|
||||
|
||||
See also :envvar:`PYTHONVERBOSE`.
|
||||
|
||||
|
||||
|
@ -426,8 +431,6 @@ Miscellaneous options
|
|||
defines the following possible values:
|
||||
|
||||
* ``-X faulthandler`` to enable :mod:`faulthandler`;
|
||||
* ``-X oldparser``: enable the traditional LL(1) parser. See also
|
||||
:envvar:`PYTHONOLDPARSER` and :pep:`617`.
|
||||
* ``-X showrefcount`` to output the total reference count and number of used
|
||||
memory blocks when the program finishes or after each statement in the
|
||||
interactive interpreter. This only works on debug builds.
|
||||
|
@ -538,6 +541,14 @@ conflict.
|
|||
within a Python program as the variable :data:`sys.path`.
|
||||
|
||||
|
||||
.. envvar:: PYTHONPLATLIBDIR
|
||||
|
||||
If this is set to a non-empty string, it overrides the :data:`sys.platlibdir`
|
||||
value.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. envvar:: PYTHONSTARTUP
|
||||
|
||||
If this is the name of a readable file, the Python commands in that file are
|
||||
|
@ -579,15 +590,6 @@ conflict.
|
|||
:option:`-d` multiple times.
|
||||
|
||||
|
||||
.. envvar:: PYTHONOLDPARSER
|
||||
|
||||
If this is set to a non-empty string, enable the traditional LL(1) parser.
|
||||
|
||||
See also the :option:`-X` ``oldparser`` option and :pep:`617`.
|
||||
|
||||
.. deprecated-removed:: 3.9 3.10
|
||||
|
||||
|
||||
.. envvar:: PYTHONINSPECT
|
||||
|
||||
If this is set to a non-empty string it is equivalent to specifying the
|
||||
|
|
|
@ -108,9 +108,7 @@ approximately 32,000 characters. Your administrator will need to activate the
|
|||
to ``1``.
|
||||
|
||||
This allows the :func:`open` function, the :mod:`os` module and most other
|
||||
path functionality to accept and return paths longer than 260 characters when
|
||||
using strings. (Use of bytes as paths is deprecated on Windows, and this feature
|
||||
is not available when using bytes.)
|
||||
path functionality to accept and return paths longer than 260 characters.
|
||||
|
||||
After changing the above option, no further configuration is required.
|
||||
|
||||
|
|
|
@ -70,6 +70,17 @@ Summary -- Release highlights
|
|||
New Features
|
||||
============
|
||||
|
||||
* The :class:`int` type has a new method :meth:`int.bit_count`, returning the
|
||||
number of ones in the binary expansion of a given integer, also known
|
||||
as the population count. (Contributed by Niklas Fiekas in :issue:`29882`.)
|
||||
|
||||
* The views returned by :meth:`dict.keys`, :meth:`dict.values` and
|
||||
:meth:`dict.items` now all have a ``mapping`` attribute that gives a
|
||||
:class:`types.MappingProxyType` object wrapping the original
|
||||
dictionary. (Contributed by Dennis Sweeney in :issue:`40890`.)
|
||||
|
||||
* :pep:`618`: The :func:`zip` function now has an optional ``strict`` flag, used
|
||||
to require that all the iterables have an equal length.
|
||||
|
||||
|
||||
Other Language Changes
|
||||
|
@ -92,16 +103,29 @@ New Modules
|
|||
Improved Modules
|
||||
================
|
||||
|
||||
tracemalloc
|
||||
-----------
|
||||
glob
|
||||
----
|
||||
|
||||
Added the *root_dir* and *dir_fd* parameters in :func:`~glob.glob` and
|
||||
:func:`~glob.iglob` which allow to specify the root directory for searching.
|
||||
(Contributed by Serhiy Storchaka in :issue:`38144`.)
|
||||
|
||||
sys
|
||||
---
|
||||
|
||||
Add :data:`sys.orig_argv` attribute: the list of the original command line
|
||||
arguments passed to the Python executable.
|
||||
(Contributed by Victor Stinner in :issue:`23427`.)
|
||||
|
||||
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
|
||||
=============
|
||||
|
||||
* The :mod:`runpy` module now imports fewer modules.
|
||||
The ``python3 -m module-name`` command startup time is 1.3x faster in
|
||||
average.
|
||||
(Contributed by Victor Stinner in :issue:`41006`.)
|
||||
|
||||
|
||||
Deprecated
|
||||
==========
|
||||
|
@ -122,6 +146,10 @@ that may require changes to your code.
|
|||
Build Changes
|
||||
=============
|
||||
|
||||
* The C99 functions :c:func:`snprintf` and :c:func:`vsnprintf` are now required
|
||||
to build Python.
|
||||
(Contributed by Victor Stinner in :issue:`36020`.)
|
||||
|
||||
|
||||
C API Changes
|
||||
=============
|
||||
|
@ -129,15 +157,95 @@ 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`.)
|
||||
|
||||
* Add a new :c:member:`~PyConfig.orig_argv` member to the :c:type:`PyConfig`
|
||||
structure: the list of the original command line arguments passed to the
|
||||
Python executable.
|
||||
(Contributed by Victor Stinner in :issue:`23427`.)
|
||||
|
||||
Porting to Python 3.10
|
||||
----------------------
|
||||
|
||||
* The ``PY_SSIZE_T_CLEAN`` macro must now be defined to use
|
||||
:c:func:`PyArg_ParseTuple` and :c:func:`Py_BuildValue` formats which use
|
||||
``#``: ``es#``, ``et#``, ``s#``, ``u#``, ``y#``, ``z#``, ``U#`` and ``Z#``.
|
||||
See :ref:`Parsing arguments and building values
|
||||
<arg-parsing>` and the :pep:`353`.
|
||||
(Contributed by Victor Stinner in :issue:`40943`.)
|
||||
|
||||
* 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).
|
||||
see :c:func:`Py_SET_TYPE()` (available since Python 3.9). For backward
|
||||
compatibility, this macro can be used::
|
||||
|
||||
#if PY_VERSION_HEX < 0x030900A4
|
||||
# define Py_SET_TYPE(obj, type) ((Py_TYPE(obj) = (type)), (void)0)
|
||||
#endif
|
||||
|
||||
(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). For backward
|
||||
compatibility, this macro can be used::
|
||||
|
||||
#if PY_VERSION_HEX < 0x030900A4
|
||||
# define Py_SET_REFCNT(obj, refcnt) ((Py_REFCNT(obj) = (refcnt)), (void)0)
|
||||
#endif
|
||||
|
||||
(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). For backward
|
||||
compatibility, this macro can be used::
|
||||
|
||||
#if PY_VERSION_HEX < 0x030900A4
|
||||
# define Py_SET_SIZE(obj, size) ((Py_SIZE(obj) = (size)), (void)0)
|
||||
#endif
|
||||
|
||||
(Contributed by Victor Stinner in :issue:`39573`.)
|
||||
|
||||
* Calling :c:func:`PyDict_GetItem` without :term:`GIL` held had been allowed
|
||||
for historical reason. It is no longer allowed.
|
||||
(Contributed by Victor Stinner in :issue:`40839`.)
|
||||
|
||||
* ``PyUnicode_FromUnicode(NULL, size)`` and ``PyUnicode_FromStringAndSize(NULL, size)``
|
||||
raise ``DeprecationWarning`` now. Use :c:func:`PyUnicode_New` to allocate
|
||||
Unicode object without initial data.
|
||||
(Contributed by Inada Naoki in :issue:`36346`.)
|
||||
|
||||
Removed
|
||||
-------
|
||||
|
||||
* ``PyObject_AsCharBuffer()``, ``PyObject_AsReadBuffer()``, ``PyObject_CheckReadBuffer()``,
|
||||
and ``PyObject_AsWriteBuffer()`` are removed. Please migrate to new buffer protocol;
|
||||
:c:func:`PyObject_GetBuffer` and :c:func:`PyBuffer_Release`.
|
||||
(Contributed by Inada Naoki in :issue:`41103`.)
|
||||
|
||||
* Removed ``Py_UNICODE_str*`` functions manipulating ``Py_UNICODE*`` strings.
|
||||
(Contributed by Inada Naoki in :issue:`41123`.)
|
||||
|
||||
* ``Py_UNICODE_strlen``: use :c:func:`PyUnicode_GetLength` or
|
||||
:c:macro:`PyUnicode_GET_LENGTH`
|
||||
* ``Py_UNICODE_strcat``: use :c:func:`PyUnicode_CopyCharacters` or
|
||||
:c:func:`PyUnicode_FromFormat`
|
||||
* ``Py_UNICODE_strcpy``, ``Py_UNICODE_strncpy``: use
|
||||
:c:func:`PyUnicode_CopyCharacters` or :c:func:`PyUnicode_Substring`
|
||||
* ``Py_UNICODE_strcmp``: use :c:func:`PyUnicode_Compare`
|
||||
* ``Py_UNICODE_strncmp``: use :c:func:`PyUnicode_Tailmatch`
|
||||
* ``Py_UNICODE_strchr``, ``Py_UNICODE_strrchr``: use
|
||||
:c:func:`PyUnicode_FindChar`
|
||||
|
||||
* Removed ``PyUnicode_GetMax()``. Please migrate to new (:pep:`393`) APIs.
|
||||
(Contributed by Inada Naoki in :issue:`41103`.)
|
||||
|
||||
* Removed ``PyLong_FromUnicode()``. Please migrate to :c:func:`PyLong_FromUnicodeObject`.
|
||||
(Contributed by Inada Naoki in :issue:`41103`.)
|
||||
|
||||
* Removed ``PyUnicode_AsUnicodeCopy()``. Please use :c:func:`PyUnicode_AsUCS4Copy` or
|
||||
:c:func:`PyUnicode_AsWideCharString`
|
||||
(Contributed by Inada Naoki in :issue:`41103`.)
|
||||
|
|
|
@ -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
|
||||
------------------------------
|
||||
|
@ -156,7 +156,7 @@ back to the LL(1) parser using a command line switch (``-X
|
|||
oldparser``) or an environment variable (``PYTHONOLDPARSER=1``).
|
||||
|
||||
See :pep:`617` for more details. (Contributed by Guido van Rossum,
|
||||
Pablo Galindo and Lysandros Nikolau in :issue:`40334`.)
|
||||
Pablo Galindo and Lysandros Nikolaou in :issue:`40334`.)
|
||||
|
||||
|
||||
Other Language Changes
|
||||
|
@ -245,6 +245,14 @@ PyPI and maintained by the CPython core team.
|
|||
PEP written and implemented by Paul Ganssle
|
||||
|
||||
|
||||
graphlib
|
||||
---------
|
||||
|
||||
Add the :mod:`graphlib` that contains the :class:`graphlib.TopologicalSorter` class
|
||||
to offer functionality to perform topological sorting of graphs. (Contributed by Pablo
|
||||
Galindo, Tim Peters and Larry Hastings in :issue:`17005`.)
|
||||
|
||||
|
||||
Improved Modules
|
||||
================
|
||||
|
||||
|
@ -352,13 +360,6 @@ ftplib
|
|||
if the given timeout for their constructor is zero to prevent the creation of
|
||||
a non-blocking socket. (Contributed by Dong-hee Na in :issue:`39259`.)
|
||||
|
||||
functools
|
||||
---------
|
||||
|
||||
Add the :class:`functools.TopologicalSorter` class to offer functionality to perform
|
||||
topological sorting of graphs. (Contributed by Pablo Galindo, Tim Peters and Larry
|
||||
Hastings in :issue:`17005`.)
|
||||
|
||||
gc
|
||||
--
|
||||
|
||||
|
@ -552,16 +553,21 @@ sys
|
|||
---
|
||||
|
||||
Add a new :attr:`sys.platlibdir` attribute: name of the platform-specific
|
||||
library directory. It is used to build the path of platform-specific dynamic
|
||||
libraries and the path of the standard library. It is equal to ``"lib"`` on
|
||||
most platforms. On Fedora and SuSE, it is equal to ``"lib64"`` on 64-bit
|
||||
platforms.
|
||||
library directory. It is used to build the path of standard library and the
|
||||
paths of installed extension modules. It is equal to ``"lib"`` on 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`.)
|
||||
|
||||
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`.)
|
||||
|
||||
typing
|
||||
------
|
||||
|
@ -679,6 +685,10 @@ in nanoseconds. The benchmarks were measured on an
|
|||
running the macOS 64-bit builds found at
|
||||
`python.org <https://www.python.org/downloads/mac-osx/>`_.
|
||||
|
||||
* A number of Python builtins (:class:`range`, :class:`tuple`, :class:`set`, :class:`frozenset`, :class:`list`, :class:`dict`)
|
||||
are now sped up by using :pep:`590` vectorcall protocol.
|
||||
(Contributed by Dong-hee Na, Mark Shannon, Jeroen Demeyer and Petr Viktorin in :issue:`37207`.)
|
||||
|
||||
|
||||
Deprecated
|
||||
==========
|
||||
|
@ -693,9 +703,10 @@ Deprecated
|
|||
Python versions it will raise a :exc:`TypeError` for all floats.
|
||||
(Contributed by Serhiy Storchaka in :issue:`37315`.)
|
||||
|
||||
* The :mod:`parser` module is deprecated and will be removed in future versions
|
||||
of Python. For the majority of use cases, users can leverage the Abstract Syntax
|
||||
Tree (AST) generation and compilation stage, using the :mod:`ast` module.
|
||||
* The :mod:`parser` and :mod:`symbol` modules are deprecated and will be
|
||||
removed in future versions of Python. For the majority of use cases,
|
||||
users can leverage the Abstract Syntax Tree (AST) generation and compilation
|
||||
stage, using the :mod:`ast` module.
|
||||
|
||||
* Using :data:`NotImplemented` in a boolean context has been deprecated,
|
||||
as it is almost exclusively the result of incorrect rich comparator
|
||||
|
@ -762,6 +773,9 @@ Deprecated
|
|||
`parso`_.
|
||||
(Contributed by Carl Meyer in :issue:`40360`.)
|
||||
|
||||
* The *random* parameter of :func:`random.shuffle` has been deprecated.
|
||||
(Contributed by Raymond Hettinger in :issue:`40465`)
|
||||
|
||||
.. _LibCST: https://libcst.readthedocs.io/
|
||||
.. _parso: https://parso.readthedocs.io/
|
||||
|
||||
|
@ -816,11 +830,6 @@ Removed
|
|||
module have been removed. They were deprecated in Python 3.2.
|
||||
Use ``iter(x)`` or ``list(x)`` instead of ``x.getchildren()`` and
|
||||
``x.iter()`` or ``list(x.iter())`` instead of ``x.getiterator()``.
|
||||
The ``xml.etree.cElementTree`` module has been removed,
|
||||
use the :mod:`xml.etree.ElementTree` module instead.
|
||||
Since Python 3.3 the ``xml.etree.cElementTree`` module has been deprecated,
|
||||
the ``xml.etree.ElementTree`` module uses a fast implementation whenever
|
||||
available.
|
||||
(Contributed by Serhiy Storchaka in :issue:`36543`.)
|
||||
|
||||
* The old :mod:`plistlib` API has been removed, it was deprecated since Python
|
||||
|
@ -829,9 +838,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.
|
||||
|
@ -876,6 +882,11 @@ Removed
|
|||
deprecated since 2006, and only returning ``False`` when it's called.
|
||||
(Contributed by Batuhan Taskaya in :issue:`40208`)
|
||||
|
||||
* The :meth:`asyncio.Task.current_task` and :meth:`asyncio.Task.all_tasks` have
|
||||
have been removed. They were deprecated since Python 3.7 and you can use
|
||||
:func:`asyncio.current_task` and :func:`asyncio.all_tasks` instead.
|
||||
(Contributed by Rémi Lapeyre in :issue:`40967`)
|
||||
|
||||
|
||||
Porting to Python 3.9
|
||||
=====================
|
||||
|
@ -933,6 +944,55 @@ Changes in the Python API
|
|||
(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
|
||||
------------------------
|
||||
|
||||
|
@ -1042,6 +1102,16 @@ Porting to Python 3.9
|
|||
and refers to a constant string.
|
||||
(Contributed by Serhiy Storchaka in :issue:`38650`.)
|
||||
|
||||
* The :c:type:`PyGC_Head` structure is now opaque. It is only defined in the
|
||||
internal C API (``pycore_gc.h``).
|
||||
(Contributed by Victor Stinner in :issue:`40241`.)
|
||||
|
||||
* The ``Py_UNICODE_COPY``, ``Py_UNICODE_FILL``, ``PyUnicode_WSTR_LENGTH``,
|
||||
:c:func:`PyUnicode_FromUnicode`, :c:func:`PyUnicode_AsUnicode`,
|
||||
``_PyUnicode_AsUnicode``, and :c:func:`PyUnicode_AsUnicodeAndSize` are
|
||||
marked as deprecated in C. They have been deprecated by :pep:`393` since
|
||||
Python 3.3.
|
||||
(Contributed by Inada Naoki in :issue:`36346`.)
|
||||
|
||||
Removed
|
||||
-------
|
||||
|
@ -1059,6 +1129,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()``
|
||||
|
@ -1108,3 +1180,8 @@ Removed
|
|||
|
||||
* Remove ``_PyUnicode_ClearStaticStrings()`` function.
|
||||
(Contributed by Victor Stinner in :issue:`39465`.)
|
||||
|
||||
* Remove ``Py_UNICODE_MATCH``. It has been deprecated by :pep:`393`, and
|
||||
broken since Python 3.3. The :c:func:`PyUnicode_Tailmatch` function can be
|
||||
used instead.
|
||||
(Contributed by Inada Naoki in :issue:`36346`.)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# Simplified grammar for Python
|
||||
# PEG grammar for Python
|
||||
|
||||
@bytecode True
|
||||
@trailer '''
|
||||
void *
|
||||
_PyPegen_parse(Parser *p)
|
||||
|
@ -92,9 +91,9 @@ assignment[stmt_ty]:
|
|||
| 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] {
|
||||
| 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) {
|
||||
| a=single_target b=augassign ~ c=(yield_expr | star_expressions) {
|
||||
_Py_AugAssign(a, b->kind, c, EXTRA) }
|
||||
| invalid_assignment
|
||||
|
||||
|
@ -122,7 +121,9 @@ yield_stmt[stmt_ty]: y=yield_expr { _Py_Expr(y, EXTRA) }
|
|||
|
||||
assert_stmt[stmt_ty]: 'assert' a=expression b=[',' z=expression { z }] { _Py_Assert(a, b, EXTRA) }
|
||||
|
||||
del_stmt[stmt_ty]: 'del' a=del_targets { _Py_Delete(a, EXTRA) }
|
||||
del_stmt[stmt_ty]:
|
||||
| 'del' a=del_targets &(';' | NEWLINE) { _Py_Delete(a, EXTRA) }
|
||||
| invalid_del_stmt
|
||||
|
||||
import_stmt[stmt_ty]: import_name | import_from
|
||||
import_name[stmt_ty]: 'import' a=dotted_as_names { _Py_Import(a, EXTRA) }
|
||||
|
@ -165,10 +166,11 @@ while_stmt[stmt_ty]:
|
|||
| 'while' a=named_expression ':' b=block c=[else_block] { _Py_While(a, b, c, EXTRA) }
|
||||
|
||||
for_stmt[stmt_ty]:
|
||||
| 'for' t=star_targets 'in' ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
|
||||
| '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] {
|
||||
| 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)) }
|
||||
| invalid_for_target
|
||||
|
||||
with_stmt[stmt_ty]:
|
||||
| 'with' '(' a=','.with_item+ ','? ')' ':' b=block {
|
||||
|
@ -180,7 +182,9 @@ with_stmt[stmt_ty]:
|
|||
| 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) }
|
||||
| e=expression 'as' t=target &(',' | ')' | ':') { _Py_withitem(e, t, p->arena) }
|
||||
| invalid_with_item
|
||||
| e=expression { _Py_withitem(e, NULL, p->arena) }
|
||||
|
||||
try_stmt[stmt_ty]:
|
||||
| 'try' ':' b=block f=finally_block { _Py_Try(b, NULL, NULL, f, EXTRA) }
|
||||
|
@ -312,7 +316,7 @@ star_named_expression[expr_ty]:
|
|||
| '*' a=bitwise_or { _Py_Starred(a, Load, EXTRA) }
|
||||
| named_expression
|
||||
named_expression[expr_ty]:
|
||||
| a=NAME ':=' b=expression { _Py_NamedExpr(CHECK(_PyPegen_set_expr_context(p, a, Store)), b, EXTRA) }
|
||||
| a=NAME ':=' ~ b=expression { _Py_NamedExpr(CHECK(_PyPegen_set_expr_context(p, a, Store)), b, EXTRA) }
|
||||
| expression !':='
|
||||
| invalid_named_expression
|
||||
|
||||
|
@ -329,7 +333,11 @@ expression[expr_ty] (memo):
|
|||
| lambdef
|
||||
|
||||
lambdef[expr_ty]:
|
||||
| 'lambda' a=[lambda_parameters] ':' b=expression { _Py_Lambda((a) ? a : CHECK(_PyPegen_empty_arguments(p)), b, EXTRA) }
|
||||
| 'lambda' a=[lambda_params] ':' b=expression { _Py_Lambda((a) ? a : CHECK(_PyPegen_empty_arguments(p)), b, EXTRA) }
|
||||
|
||||
lambda_params[arguments_ty]:
|
||||
| invalid_lambda_parameters
|
||||
| lambda_parameters
|
||||
|
||||
# lambda_parameters etc. duplicates parameters but without annotations
|
||||
# or type comments, and if there's no comma after a parameter, we expect
|
||||
|
@ -473,7 +481,6 @@ atom[expr_ty]:
|
|||
| 'True' { _Py_Constant(Py_True, NULL, EXTRA) }
|
||||
| 'False' { _Py_Constant(Py_False, NULL, EXTRA) }
|
||||
| 'None' { _Py_Constant(Py_None, NULL, EXTRA) }
|
||||
| '__new_parser__' { RAISE_SYNTAX_ERROR("You found it!") }
|
||||
| &STRING strings
|
||||
| NUMBER
|
||||
| &'(' (tuple | group | genexp)
|
||||
|
@ -485,18 +492,20 @@ strings[expr_ty] (memo): a=STRING+ { _PyPegen_concatenate_strings(p, a) }
|
|||
list[expr_ty]:
|
||||
| '[' a=[star_named_expressions] ']' { _Py_List(a, Load, EXTRA) }
|
||||
listcomp[expr_ty]:
|
||||
| '[' a=named_expression b=for_if_clauses ']' { _Py_ListComp(a, b, EXTRA) }
|
||||
| '[' a=named_expression ~ b=for_if_clauses ']' { _Py_ListComp(a, b, EXTRA) }
|
||||
| invalid_comprehension
|
||||
tuple[expr_ty]:
|
||||
| '(' a=[y=star_named_expression ',' z=[star_named_expressions] { _PyPegen_seq_insert_in_front(p, y, z) } ] ')' {
|
||||
_Py_Tuple(a, Load, EXTRA) }
|
||||
group[expr_ty]: '(' a=(yield_expr | named_expression) ')' { a }
|
||||
group[expr_ty]:
|
||||
| '(' a=(yield_expr | named_expression) ')' { a }
|
||||
| invalid_group
|
||||
genexp[expr_ty]:
|
||||
| '(' a=expression b=for_if_clauses ')' { _Py_GeneratorExp(a, b, EXTRA) }
|
||||
| '(' a=expression ~ b=for_if_clauses ')' { _Py_GeneratorExp(a, b, EXTRA) }
|
||||
| invalid_comprehension
|
||||
set[expr_ty]: '{' a=expressions_list '}' { _Py_Set(a, EXTRA) }
|
||||
setcomp[expr_ty]:
|
||||
| '{' a=expression b=for_if_clauses '}' { _Py_SetComp(a, b, EXTRA) }
|
||||
| '{' a=expression ~ b=for_if_clauses '}' { _Py_SetComp(a, b, EXTRA) }
|
||||
| invalid_comprehension
|
||||
dict[expr_ty]:
|
||||
| '{' a=[double_starred_kvpairs] '}' {
|
||||
|
@ -512,10 +521,11 @@ kvpair[KeyValuePair*]: a=expression ':' b=expression { _PyPegen_key_value_pair(p
|
|||
for_if_clauses[asdl_seq*]:
|
||||
| for_if_clause+
|
||||
for_if_clause[comprehension_ty]:
|
||||
| ASYNC 'for' a=star_targets 'in' b=disjunction c=('if' z=disjunction { z })* {
|
||||
| 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 })* {
|
||||
| 'for' a=star_targets 'in' ~ b=disjunction c=('if' z=disjunction { z })* {
|
||||
_Py_comprehension(a, b, c, 0, p->arena) }
|
||||
| invalid_for_target
|
||||
|
||||
yield_expr[expr_ty]:
|
||||
| 'yield' 'from' a=expression { _Py_YieldFrom(a, EXTRA) }
|
||||
|
@ -585,19 +595,15 @@ single_subscript_attribute_target[expr_ty]:
|
|||
| 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 &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) }
|
||||
| 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) }
|
||||
| del_t_atom
|
||||
del_t_atom[expr_ty]:
|
||||
| a=NAME &del_target_end { _PyPegen_set_expr_context(p, a, Del) }
|
||||
| a=NAME { _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):
|
||||
|
@ -640,23 +646,32 @@ invalid_named_expression:
|
|||
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
|
||||
a, "cannot use assignment expressions with %s", _PyPegen_get_expr_name(a)) }
|
||||
invalid_assignment:
|
||||
| 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) {
|
||||
| a=invalid_ann_assign_target ':' expression {
|
||||
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
|
||||
_PyPegen_get_invalid_target(a),
|
||||
"cannot assign to %s", _PyPegen_get_expr_name(_PyPegen_get_invalid_target(a))) }
|
||||
a,
|
||||
"only single target (not %s) can be annotated",
|
||||
_PyPegen_get_expr_name(a)
|
||||
)}
|
||||
| a=star_named_expression ',' star_named_expressions* ':' expression {
|
||||
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "only single target (not tuple) can be annotated") }
|
||||
| a=expression ':' expression {
|
||||
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "illegal target for annotation") }
|
||||
| (star_targets '=')* a=star_expressions '=' {
|
||||
RAISE_SYNTAX_ERROR_INVALID_TARGET(STAR_TARGETS, a) }
|
||||
| (star_targets '=')* a=yield_expr '=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "assignment to yield expression not possible") }
|
||||
| a=star_expressions augassign (yield_expr | star_expressions) {
|
||||
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
|
||||
a,
|
||||
a,
|
||||
"'%s' is an illegal expression for augmented assignment",
|
||||
_PyPegen_get_expr_name(a)
|
||||
)}
|
||||
|
||||
invalid_ann_assign_target[expr_ty]:
|
||||
| list
|
||||
| tuple
|
||||
| '(' a=invalid_ann_assign_target ')' { a }
|
||||
invalid_del_stmt:
|
||||
| 'del' a=star_expressions {
|
||||
RAISE_SYNTAX_ERROR_INVALID_TARGET(DEL_TARGETS, a) }
|
||||
invalid_block:
|
||||
| NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block") }
|
||||
invalid_comprehension:
|
||||
|
@ -668,6 +683,9 @@ invalid_dict_comprehension:
|
|||
invalid_parameters:
|
||||
| param_no_default* (slash_with_default | param_with_default+) param_no_default {
|
||||
RAISE_SYNTAX_ERROR("non-default argument follows default argument") }
|
||||
invalid_lambda_parameters:
|
||||
| lambda_param_no_default* (lambda_slash_with_default | lambda_param_with_default+) lambda_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") }
|
||||
|
@ -676,9 +694,17 @@ invalid_lambda_star_etc:
|
|||
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_with_item:
|
||||
| expression 'as' a=expression {
|
||||
RAISE_SYNTAX_ERROR_INVALID_TARGET(STAR_TARGETS, a) }
|
||||
|
||||
invalid_for_target:
|
||||
| ASYNC? 'for' a=star_expressions {
|
||||
RAISE_SYNTAX_ERROR_INVALID_TARGET(FOR_TARGETS, a) }
|
||||
|
||||
invalid_group:
|
||||
| '(' a=starred_expression ')' {
|
||||
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "can't use starred expression here") }
|
||||
invalid_import_from_targets:
|
||||
| import_from_as_names ',' {
|
||||
RAISE_SYNTAX_ERROR("trailing comma not allowed without surrounding parentheses") }
|
||||
|
|
|
@ -141,6 +141,7 @@
|
|||
#include "modsupport.h"
|
||||
#include "compile.h"
|
||||
#include "pythonrun.h"
|
||||
#include "parser_interface.h"
|
||||
#include "pylifecycle.h"
|
||||
#include "ceval.h"
|
||||
#include "sysmodule.h"
|
||||
|
|
|
@ -309,53 +309,6 @@ PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, const char *key);
|
|||
PyAPI_FUNC(int) PyObject_DelItem(PyObject *o, PyObject *key);
|
||||
|
||||
|
||||
/* === Old Buffer API ============================================ */
|
||||
|
||||
/* FIXME: usage of these should all be replaced in Python itself
|
||||
but for backwards compatibility we will implement them.
|
||||
Their usage without a corresponding "unlock" mechanism
|
||||
may create issues (but they would already be there). */
|
||||
|
||||
/* Takes an arbitrary object which must support the (character, single segment)
|
||||
buffer interface and returns a pointer to a read-only memory location
|
||||
useable as character based input for subsequent processing.
|
||||
|
||||
Return 0 on success. buffer and buffer_len are only set in case no error
|
||||
occurs. Otherwise, -1 is returned and an exception set. */
|
||||
Py_DEPRECATED(3.0)
|
||||
PyAPI_FUNC(int) PyObject_AsCharBuffer(PyObject *obj,
|
||||
const char **buffer,
|
||||
Py_ssize_t *buffer_len);
|
||||
|
||||
/* Checks whether an arbitrary object supports the (character, single segment)
|
||||
buffer interface.
|
||||
|
||||
Returns 1 on success, 0 on failure. */
|
||||
Py_DEPRECATED(3.0) PyAPI_FUNC(int) PyObject_CheckReadBuffer(PyObject *obj);
|
||||
|
||||
/* Same as PyObject_AsCharBuffer() except that this API expects (readable,
|
||||
single segment) buffer interface and returns a pointer to a read-only memory
|
||||
location which can contain arbitrary data.
|
||||
|
||||
0 is returned on success. buffer and buffer_len are only set in case no
|
||||
error occurs. Otherwise, -1 is returned and an exception set. */
|
||||
Py_DEPRECATED(3.0)
|
||||
PyAPI_FUNC(int) PyObject_AsReadBuffer(PyObject *obj,
|
||||
const void **buffer,
|
||||
Py_ssize_t *buffer_len);
|
||||
|
||||
/* Takes an arbitrary object which must support the (writable, single segment)
|
||||
buffer interface and returns a pointer to a writable memory location in
|
||||
buffer of size 'buffer_len'.
|
||||
|
||||
Return 0 on success. buffer and buffer_len are only set in case no error
|
||||
occurs. Otherwise, -1 is returned and an exception set. */
|
||||
Py_DEPRECATED(3.0)
|
||||
PyAPI_FUNC(int) PyObject_AsWriteBuffer(PyObject *obj,
|
||||
void **buffer,
|
||||
Py_ssize_t *buffer_len);
|
||||
|
||||
|
||||
/* === New Buffer API ============================================ */
|
||||
|
||||
/* Takes an arbitrary object and returns the result of calling
|
||||
|
|
|
@ -6,19 +6,8 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "Python-ast.h" /* mod_ty */
|
||||
#include "node.h" /* node */
|
||||
|
||||
PyAPI_FUNC(int) PyAST_Validate(mod_ty);
|
||||
PyAPI_FUNC(mod_ty) PyAST_FromNode(
|
||||
const node *n,
|
||||
PyCompilerFlags *flags,
|
||||
const char *filename, /* decoded from the filesystem encoding */
|
||||
PyArena *arena);
|
||||
PyAPI_FUNC(mod_ty) PyAST_FromNodeObject(
|
||||
const node *n,
|
||||
PyCompilerFlags *flags,
|
||||
PyObject *filename,
|
||||
PyArena *arena);
|
||||
|
||||
/* _PyAST_ExprAsUnicode is defined in ast_unparse.c */
|
||||
PyAPI_FUNC(PyObject *) _PyAST_ExprAsUnicode(expr_ty);
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
|
||||
#ifndef Py_BITSET_H
|
||||
#define Py_BITSET_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Bitset interface */
|
||||
|
||||
#define BYTE char
|
||||
typedef BYTE *bitset;
|
||||
|
||||
#define testbit(ss, ibit) (((ss)[BIT2BYTE(ibit)] & BIT2MASK(ibit)) != 0)
|
||||
|
||||
#define BITSPERBYTE (8*sizeof(BYTE))
|
||||
#define BIT2BYTE(ibit) ((ibit) / BITSPERBYTE)
|
||||
#define BIT2SHIFT(ibit) ((ibit) % BITSPERBYTE)
|
||||
#define BIT2MASK(ibit) (1 << BIT2SHIFT(ibit))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_BITSET_H */
|
|
@ -128,8 +128,12 @@ PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *);
|
|||
|
||||
Py_DEPRECATED(3.9) PyAPI_FUNC(int) PyEval_ThreadsInitialized(void);
|
||||
Py_DEPRECATED(3.9) PyAPI_FUNC(void) PyEval_InitThreads(void);
|
||||
/* PyEval_AcquireLock() and PyEval_ReleaseLock() are part of stable ABI.
|
||||
* They will be removed from this header file in the future version.
|
||||
* But they will be remained in ABI until Python 4.0.
|
||||
*/
|
||||
Py_DEPRECATED(3.2) PyAPI_FUNC(void) PyEval_AcquireLock(void);
|
||||
/* Py_DEPRECATED(3.2) */ PyAPI_FUNC(void) PyEval_ReleaseLock(void);
|
||||
Py_DEPRECATED(3.2) PyAPI_FUNC(void) PyEval_ReleaseLock(void);
|
||||
PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate);
|
||||
PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate);
|
||||
|
||||
|
|
|
@ -8,10 +8,6 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/* Public interface */
|
||||
struct _node; /* Declare the existence of this type */
|
||||
PyAPI_FUNC(PyCodeObject *) PyNode_Compile(struct _node *, const char *);
|
||||
/* XXX (ncoghlan): Unprefixed type name in a public API! */
|
||||
|
||||
#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \
|
||||
CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \
|
||||
CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* === Object Protocol ================================================== */
|
||||
|
||||
#ifdef PY_SSIZE_T_CLEAN
|
||||
|
@ -379,6 +375,5 @@ 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 *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* Same as PyNumber_Index but can return an instance of a subclass of int. */
|
||||
PyAPI_FUNC(PyObject *) _PyNumber_Index(PyObject *o);
|
|
@ -2,10 +2,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *);
|
||||
PyAPI_DATA(int) _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg);
|
||||
PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *);
|
||||
|
@ -32,7 +28,3 @@ PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc);
|
|||
|
||||
PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *);
|
||||
PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _dictkeysobject PyDictKeysObject;
|
||||
|
||||
/* The ma_values pointer is NULL for a combined table
|
||||
|
@ -86,7 +82,3 @@ typedef struct {
|
|||
|
||||
PyAPI_FUNC(PyObject *) _PyDictView_New(PyObject *, PyTypeObject *);
|
||||
PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
|
||||
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000
|
||||
|
@ -26,7 +22,3 @@ typedef PyObject * (*Py_OpenCodeHookFunction)(PyObject *, void *);
|
|||
PyAPI_FUNC(PyObject *) PyFile_OpenCode(const char *utf8path);
|
||||
PyAPI_FUNC(PyObject *) PyFile_OpenCodeObject(PyObject *path);
|
||||
PyAPI_FUNC(int) PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -4,10 +4,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int b_type; /* what kind of block this is */
|
||||
int b_handler; /* where to jump to find handler */
|
||||
|
@ -78,7 +74,3 @@ PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *);
|
|||
PyAPI_FUNC(void) _PyFrame_DebugMallocStats(FILE *out);
|
||||
|
||||
PyAPI_FUNC(PyFrameObject *) PyFrame_GetBack(PyFrameObject *frame);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PyMODINIT_FUNC PyInit__imp(void);
|
||||
|
||||
PyAPI_FUNC(int) _PyImport_IsInitialized(PyInterpreterState *);
|
||||
|
@ -44,7 +40,3 @@ struct _frozen {
|
|||
collection of frozen modules: */
|
||||
|
||||
PyAPI_DATA(const struct _frozen *) PyImport_FrozenModules;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
#ifndef Py_PYCORECONFIG_H
|
||||
#define Py_PYCORECONFIG_H
|
||||
#ifndef Py_LIMITED_API
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* --- PyStatus ----------------------------------------------- */
|
||||
|
||||
|
@ -147,10 +144,6 @@ typedef struct {
|
|||
Set to 1 by -X faulthandler and PYTHONFAULTHANDLER. -1 means unset. */
|
||||
int faulthandler;
|
||||
|
||||
/* Enable PEG parser?
|
||||
1 by default, set to 0 by -X oldparser and PYTHONOLDPARSER */
|
||||
int _use_peg_parser;
|
||||
|
||||
/* Enable tracemalloc?
|
||||
Set by -X tracemalloc=N and PYTHONTRACEMALLOC. -1 means unset */
|
||||
int tracemalloc;
|
||||
|
@ -388,6 +381,7 @@ typedef struct {
|
|||
wchar_t *base_prefix; /* sys.base_prefix */
|
||||
wchar_t *exec_prefix; /* sys.exec_prefix */
|
||||
wchar_t *base_exec_prefix; /* sys.base_exec_prefix */
|
||||
wchar_t *platlibdir; /* sys.platlibdir */
|
||||
|
||||
/* --- Parameter only used by Py_Main() ---------- */
|
||||
|
||||
|
@ -413,6 +407,16 @@ typedef struct {
|
|||
/* If non-zero, disallow threads, subprocesses, and fork.
|
||||
Default: 0. */
|
||||
int _isolated_interpreter;
|
||||
|
||||
/* The list of the original command line arguments passed to the Python
|
||||
executable.
|
||||
|
||||
If 'orig_argv' list is empty and 'argv' is not a list only containing an
|
||||
empty string, PyConfig_Read() copies 'argv' into 'orig_argv' before
|
||||
modifying 'argv' (if 'parse_argv is non-zero).
|
||||
|
||||
_PyConfig_Write() initializes Py_GetArgcArgv() to this list. */
|
||||
PyWideStringList orig_argv;
|
||||
} PyConfig;
|
||||
|
||||
PyAPI_FUNC(void) PyConfig_InitPythonConfig(PyConfig *config);
|
||||
|
@ -438,8 +442,13 @@ PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config,
|
|||
PyWideStringList *list,
|
||||
Py_ssize_t length, wchar_t **items);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* --- Helper functions --------------------------------------- */
|
||||
|
||||
/* Get the original command line arguments, before Python modified them.
|
||||
|
||||
See also PyConfig.orig_argv. */
|
||||
PyAPI_FUNC(void) Py_GetArgcArgv(int *argc, wchar_t ***argv);
|
||||
|
||||
#endif /* !Py_LIMITED_API */
|
||||
#endif /* !Py_PYCORECONFIG_H */
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Interpreter ID Object */
|
||||
|
||||
PyAPI_DATA(PyTypeObject) _PyInterpreterID_Type;
|
||||
|
@ -13,7 +9,3 @@ PyAPI_DATA(PyTypeObject) _PyInterpreterID_Type;
|
|||
PyAPI_FUNC(PyObject *) _PyInterpreterID_New(int64_t);
|
||||
PyAPI_FUNC(PyObject *) _PyInterpreterState_GetIDObject(PyInterpreterState *);
|
||||
PyAPI_FUNC(PyInterpreterState *) _PyInterpreterID_LookUp(PyObject *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
PyObject_VAR_HEAD
|
||||
/* Vector of pointers to list elements. list[0] is ob_item[0], etc. */
|
||||
|
@ -36,8 +32,3 @@ PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out);
|
|||
#define PyList_GET_ITEM(op, i) (_PyList_CAST(op)->ob_item[i])
|
||||
#define PyList_SET_ITEM(op, i, v) (_PyList_CAST(op)->ob_item[i] = (v))
|
||||
#define PyList_GET_SIZE(op) Py_SIZE(_PyList_CAST(op))
|
||||
#define _PyList_ITEMS(op) (_PyList_CAST(op)->ob_item)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(void) _Py_NewReference(PyObject *op);
|
||||
|
||||
#ifdef Py_TRACE_REFS
|
||||
|
@ -13,10 +9,6 @@ PyAPI_FUNC(void) _Py_NewReference(PyObject *op);
|
|||
PyAPI_FUNC(void) _Py_ForgetReference(PyObject *);
|
||||
#endif
|
||||
|
||||
/* Update the Python traceback of an object. This function must be called
|
||||
when a memory block is reused from a free list. */
|
||||
PyAPI_FUNC(int) _PyTraceMalloc_NewReference(PyObject *op);
|
||||
|
||||
#ifdef Py_REF_DEBUG
|
||||
PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void);
|
||||
#endif
|
||||
|
@ -548,7 +540,3 @@ PyAPI_FUNC(void) _PyTrash_end(struct _ts *tstate);
|
|||
* unconditionally */
|
||||
#define Py_TRASHCAN_SAFE_BEGIN(op) Py_TRASHCAN_BEGIN_CONDITION(op, 1)
|
||||
#define Py_TRASHCAN_SAFE_END(op) Py_TRASHCAN_END
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize )
|
||||
|
||||
/* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a
|
||||
|
@ -41,8 +37,9 @@ extern "C" {
|
|||
PyObject *op;
|
||||
|
||||
op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct));
|
||||
if (op == NULL)
|
||||
return PyErr_NoMemory();
|
||||
if (op == NULL) {
|
||||
return PyErr_NoMemory();
|
||||
}
|
||||
|
||||
PyObject_Init(op, &YourTypeStruct);
|
||||
|
||||
|
@ -55,40 +52,6 @@ extern "C" {
|
|||
the 1st step is performed automatically for you, so in a C++ class
|
||||
constructor you would start directly with PyObject_Init/InitVar. */
|
||||
|
||||
|
||||
/* Inline functions trading binary compatibility for speed:
|
||||
PyObject_INIT() is the fast version of PyObject_Init(), and
|
||||
PyObject_INIT_VAR() is the fast version of PyObject_InitVar().
|
||||
|
||||
These inline functions must not be called with op=NULL. */
|
||||
static inline PyObject*
|
||||
_PyObject_INIT(PyObject *op, PyTypeObject *typeobj)
|
||||
{
|
||||
assert(op != NULL);
|
||||
Py_SET_TYPE(op, typeobj);
|
||||
if (PyType_GetFlags(typeobj) & Py_TPFLAGS_HEAPTYPE) {
|
||||
Py_INCREF(typeobj);
|
||||
}
|
||||
_Py_NewReference(op);
|
||||
return op;
|
||||
}
|
||||
|
||||
#define PyObject_INIT(op, typeobj) \
|
||||
_PyObject_INIT(_PyObject_CAST(op), (typeobj))
|
||||
|
||||
static inline PyVarObject*
|
||||
_PyObject_INIT_VAR(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size)
|
||||
{
|
||||
assert(op != NULL);
|
||||
Py_SET_SIZE(op, size);
|
||||
PyObject_INIT((PyObject *)op, typeobj);
|
||||
return op;
|
||||
}
|
||||
|
||||
#define PyObject_INIT_VAR(op, typeobj, size) \
|
||||
_PyObject_INIT_VAR(_PyVarObject_CAST(op), (typeobj), (size))
|
||||
|
||||
|
||||
/* This function returns the number of allocated memory blocks, regardless of size */
|
||||
PyAPI_FUNC(Py_ssize_t) _Py_GetAllocatedBlocks(void);
|
||||
|
||||
|
@ -139,7 +102,3 @@ PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size);
|
|||
#define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0)
|
||||
|
||||
PyAPI_FUNC(PyObject **) PyObject_GET_WEAKREFS_LISTPTR(PyObject *op);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Error objects */
|
||||
|
||||
/* PyException_HEAD defines the initial segment of every exception class. */
|
||||
|
@ -188,7 +184,3 @@ PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFormat(
|
|||
...);
|
||||
|
||||
#define Py_FatalError(message) _Py_FatalErrorFunc(__func__, message)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Only used by applications that embed the interpreter and need to
|
||||
* override the standard encoding determination mechanism
|
||||
*/
|
||||
|
@ -66,7 +62,3 @@ 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
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(void *) PyMem_RawMalloc(size_t size);
|
||||
PyAPI_FUNC(void *) PyMem_RawCalloc(size_t nelem, size_t elsize);
|
||||
PyAPI_FUNC(void *) PyMem_RawRealloc(void *ptr, size_t new_size);
|
||||
|
@ -102,7 +98,3 @@ PyAPI_FUNC(void) PyMem_SetAllocator(PyMemAllocatorDomain domain,
|
|||
|
||||
The function does nothing if Python is not compiled is debug mode. */
|
||||
PyAPI_FUNC(void) PyMem_SetupDebugHooks(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "cpython/initconfig.h"
|
||||
|
||||
PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *);
|
||||
|
@ -257,7 +253,3 @@ typedef int (*crossinterpdatafunc)(PyObject *, struct _xid *);
|
|||
|
||||
PyAPI_FUNC(int) _PyCrossInterpreterData_RegisterClass(PyTypeObject *, crossinterpdatafunc);
|
||||
PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PySys_GetObjectId(_Py_Identifier *key);
|
||||
PyAPI_FUNC(int) _PySys_SetObjectId(_Py_Identifier *key, PyObject *);
|
||||
|
||||
|
@ -18,7 +14,3 @@ PyAPI_FUNC(int) PySys_Audit(
|
|||
const char *argFormat,
|
||||
...);
|
||||
PyAPI_FUNC(int) PySys_AddAuditHook(Py_AuditHookFunction, void*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _traceback {
|
||||
PyObject_HEAD
|
||||
struct _traceback *tb_next;
|
||||
|
@ -16,7 +12,3 @@ typedef struct _traceback {
|
|||
|
||||
PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int);
|
||||
PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
PyObject_VAR_HEAD
|
||||
/* ob_item contains space for 'ob_size' elements.
|
||||
|
@ -30,7 +26,3 @@ PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *);
|
|||
#define PyTuple_SET_ITEM(op, i, v) (_PyTuple_CAST(op)->ob_item[i] = v)
|
||||
|
||||
PyAPI_FUNC(void) _PyTuple_DebugMallocStats(FILE *out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue