venv:
$(PYTHON) -m venv $(VENVDIR)
$(VENVDIR)/bin/python3 -m pip install -U pip setuptools
- $(VENVDIR)/bin/python3 -m pip install -U Sphinx==2.3.1 blurb python-docs-theme
+ $(VENVDIR)/bin/python3 -m pip install -r requirements.txt
@echo "The venv has been created in the $(VENVDIR) directory"
dist:
``S`` (:class:`bytes`) [PyBytesObject \*]
Requires that the Python object is a :class:`bytes` object, without
attempting any conversion. Raises :exc:`TypeError` if the object is not
- a bytes object. The C variable may also be declared as :c:type:`PyObject\*`.
+ a bytes object. The C variable may also be declared as :c:type:`PyObject*`.
``Y`` (:class:`bytearray`) [PyByteArrayObject \*]
Requires that the Python object is a :class:`bytearray` object, without
attempting any conversion. Raises :exc:`TypeError` if the object is not
- a :class:`bytearray` object. The C variable may also be declared as :c:type:`PyObject\*`.
+ a :class:`bytearray` object. The C variable may also be declared as :c:type:`PyObject*`.
``u`` (:class:`str`) [const Py_UNICODE \*]
Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of
``U`` (:class:`str`) [PyObject \*]
Requires that the Python object is a Unicode object, without attempting
any conversion. Raises :exc:`TypeError` if the object is not a Unicode
- object. The C variable may also be declared as :c:type:`PyObject\*`.
+ object. The C variable may also be declared as :c:type:`PyObject*`.
``w*`` (read-write :term:`bytes-like object`) [Py_buffer]
This format accepts any object which implements the read-write buffer
It only works for encoded data without embedded NUL bytes.
This format requires two arguments. The first is only used as input, and
- must be a :c:type:`const char\*` which points to the name of an encoding as a
+ must be a :c:type:`const char*` which points to the name of an encoding as a
NUL-terminated string, or ``NULL``, in which case ``'utf-8'`` encoding is used.
An exception is raised if the named encoding is not known to Python. The
- second argument must be a :c:type:`char\*\*`; the value of the pointer it
+ second argument must be a :c:type:`char**`; the value of the pointer it
references will be set to a buffer with the contents of the argument text.
The text will be encoded in the encoding specified by the first argument.
characters.
It requires three arguments. The first is only used as input, and must be a
- :c:type:`const char\*` which points to the name of an encoding as a
+ :c:type:`const char*` which points to the name of an encoding as a
NUL-terminated string, or ``NULL``, in which case ``'utf-8'`` encoding is used.
An exception is raised if the named encoding is not known to Python. The
- second argument must be a :c:type:`char\*\*`; the value of the pointer it
+ second argument must be a :c:type:`char**`; the value of the pointer it
references will be set to a buffer with the contents of the argument text.
The text will be encoded in the encoding specified by the first argument.
The third argument must be a pointer to an integer; the referenced integer
``O!`` (object) [*typeobject*, PyObject \*]
Store a Python object in a C object pointer. This is similar to ``O``, but
takes two C arguments: the first is the address of a Python type object, the
- second is the address of the C variable (of type :c:type:`PyObject\*`) into which
+ second is the address of the C variable (of type :c:type:`PyObject*`) into which
the object pointer is stored. If the Python object does not have the required
type, :exc:`TypeError` is raised.
``O&`` (object) [*converter*, *anything*]
Convert a Python object to a C variable through a *converter* function. This
takes two arguments: the first is a function, the second is the address of a C
- variable (of arbitrary type), converted to :c:type:`void \*`. The *converter*
+ variable (of arbitrary type), converted to :c:type:`void *`. The *converter*
function in turn is called as follows::
status = converter(object, address);
where *object* is the Python object to be converted and *address* is the
- :c:type:`void\*` argument that was passed to the :c:func:`PyArg_Parse\*` function.
+ :c:type:`void*` argument that was passed to the :c:func:`PyArg_Parse\*` function.
The returned *status* should be ``1`` for a successful conversion and ``0`` if
the conversion has failed. When the conversion fails, the *converter* function
should raise an exception and leave the content of *address* unmodified.
*args*; it must actually be a tuple. The length of the tuple must be at least
*min* and no more than *max*; *min* and *max* may be equal. Additional
arguments must be passed to the function, each of which should be a pointer to a
- :c:type:`PyObject\*` variable; these will be filled in with the values from
+ :c:type:`PyObject*` variable; these will be filled in with the values from
*args*; they will contain borrowed references. The variables which correspond
to optional parameters not given by *args* will not be filled in; these should
be initialized by the caller. This function returns true on success and false if
``O&`` (object) [*converter*, *anything*]
Convert *anything* to a Python object through a *converter* function. The
- function is called with *anything* (which should be compatible with :c:type:`void
- \*`) as its argument and should return a "new" Python object, or ``NULL`` if an
+ function is called with *anything* (which should be compatible with :c:type:`void*`)
+ as its argument and should return a "new" Python object, or ``NULL`` if an
error occurred.
``(items)`` (:class:`tuple`) [*matching-items*]
.. c:type:: Py_buffer
- .. c:member:: void \*buf
+ .. c:member:: void *buf
A pointer to the start of the logical structure described by the buffer
fields. This can be any location within the underlying physical memory
For :term:`contiguous` arrays, the value points to the beginning of
the memory block.
- .. c:member:: void \*obj
+ .. c:member:: void *obj
A new reference to the exporting object. The reference is owned by
the consumer and automatically decremented and set to ``NULL`` by
or a :c:macro:`PyBUF_WRITABLE` request, the consumer must disregard
:c:member:`~Py_buffer.itemsize` and assume ``itemsize == 1``.
- .. c:member:: const char \*format
+ .. c:member:: const char *format
A *NUL* terminated string in :mod:`struct` module style syntax describing
the contents of a single item. If this is ``NULL``, ``"B"`` (unsigned bytes)
to 64. Exporters MUST respect this limit, consumers of multi-dimensional
buffers SHOULD be able to handle up to :c:macro:`PyBUF_MAX_NDIM` dimensions.
- .. c:member:: Py_ssize_t \*shape
+ .. c:member:: Py_ssize_t *shape
An array of :c:type:`Py_ssize_t` of length :c:member:`~Py_buffer.ndim`
indicating the shape of the memory as an n-dimensional array. Note that
The shape array is read-only for the consumer.
- .. c:member:: Py_ssize_t \*strides
+ .. c:member:: Py_ssize_t *strides
An array of :c:type:`Py_ssize_t` of length :c:member:`~Py_buffer.ndim`
giving the number of bytes to skip to get to a new element in each
The strides array is read-only for the consumer.
- .. c:member:: Py_ssize_t \*suboffsets
+ .. c:member:: Py_ssize_t *suboffsets
An array of :c:type:`Py_ssize_t` of length :c:member:`~Py_buffer.ndim`.
If ``suboffsets[n] >= 0``, the values stored along the nth dimension are
The suboffsets array is read-only for the consumer.
- .. c:member:: void \*internal
+ .. c:member:: void *internal
This is for use internally by the exporting object. For example, this
might be re-cast as an integer by the exporter and used to store flags
+-----------------------------------+-------+---------+------------+--------+
| .. c:macro:: PyBUF_ANY_CONTIGUOUS | yes | yes | NULL | C or F |
+-----------------------------------+-------+---------+------------+--------+
-| .. c:macro:: PyBUF_ND | yes | NULL | NULL | C |
+| :c:macro:`PyBUF_ND` | yes | NULL | NULL | C |
+-----------------------------------+-------+---------+------------+--------+
Send a request to *exporter* to fill in *view* as specified by *flags*.
If the exporter cannot provide a buffer of the exact type, it MUST raise
- :c:data:`PyExc_BufferError`, set :c:member:`view->obj` to ``NULL`` and
+ :c:data:`PyExc_BufferError`, set ``view->obj`` to ``NULL`` and
return ``-1``.
- On success, fill in *view*, set :c:member:`view->obj` to a new reference
+ On success, fill in *view*, set ``view->obj`` to a new reference
to *exporter* and return 0. In the case of chained buffer providers
- that redirect requests to a single object, :c:member:`view->obj` MAY
+ that redirect requests to a single object, ``view->obj`` MAY
refer to this object instead of *exporter* (See :ref:`Buffer Object Structures <buffer-structs>`).
Successful calls to :c:func:`PyObject_GetBuffer` must be paired with calls
.. c:function:: void PyBuffer_Release(Py_buffer *view)
Release the buffer *view* and decrement the reference count for
- :c:member:`view->obj`. This function MUST be called when the buffer
+ ``view->obj``. This function MUST be called when the buffer
is no longer being used, otherwise reference leaks may occur.
It is an error to call this function on a buffer that was not obtained via
*view* as specified by flags, unless *buf* has been designated as read-only
and :c:macro:`PyBUF_WRITABLE` is set in *flags*.
- On success, set :c:member:`view->obj` to a new reference to *exporter* and
+ On success, set ``view->obj`` to a new reference to *exporter* and
return 0. Otherwise, raise :c:data:`PyExc_BufferError`, set
- :c:member:`view->obj` to ``NULL`` and return ``-1``;
+ ``view->obj`` to ``NULL`` and return ``-1``;
If this function is used as part of a :ref:`getbufferproc <buffer-structs>`,
*exporter* MUST be set to the exporting object and *flags* must be passed
.. c:type:: PyCapsule
This subtype of :c:type:`PyObject` represents an opaque value, useful for C
- extension modules who need to pass an opaque value (as a :c:type:`void\*`
+ extension modules who need to pass an opaque value (as a :c:type:`void*`
pointer) through Python code to other C code. It is often used to make a C
function pointer defined in one module available to other modules, so the
regular import mechanism can be used to access C APIs defined in dynamically
.. index:: single: PyUnicode_FromString()
Insert *val* into the dictionary *p* using *key* as a key. *key* should
- be a :c:type:`const char\*`. The key object is created using
+ be a :c:type:`const char*`. The key object is created using
``PyUnicode_FromString(key)``. Return ``0`` on success or ``-1`` on
failure. This function *does not* steal a reference to *val*.
.. c:function:: PyObject* PyDict_GetItemString(PyObject *p, const char *key)
This is the same as :c:func:`PyDict_GetItem`, but *key* is specified as a
- :c:type:`const char\*`, rather than a :c:type:`PyObject\*`.
+ :c:type:`const char*`, rather than a :c:type:`PyObject*`.
Note that exceptions which occur while calling :meth:`__hash__` and
:meth:`__eq__` methods and creating a temporary string object
prior to the first call to this function to start the iteration; the
function returns true for each pair in the dictionary, and false once all
pairs have been reported. The parameters *pkey* and *pvalue* should either
- point to :c:type:`PyObject\*` variables that will be filled in with each key
+ point to :c:type:`PyObject*` variables that will be filled in with each key
and value, respectively, or may be ``NULL``. Any references returned through
them are borrowed. *ppos* should not be altered during iteration. Its
value represents offsets within the internal dictionary structure, and
*object*, *length*, *start*, *end* and *reason*. *encoding* and *reason* are
UTF-8 encoded strings.
+ .. deprecated:: 3.3 3.11
+
+ ``Py_UNICODE`` is deprecated since Python 3.3. Please migrate to
+ ``PyObject_CallFunction(PyExc_UnicodeEncodeError, "sOnns", ...)``.
+
.. c:function:: PyObject* PyUnicodeTranslateError_Create(const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)
Create a :class:`UnicodeTranslateError` object with the attributes *object*,
*length*, *start*, *end* and *reason*. *reason* is a UTF-8 encoded string.
+ .. deprecated:: 3.3 3.11
+
+ ``Py_UNICODE`` is deprecated since Python 3.3. Please migrate to
+ ``PyObject_CallFunction(PyExc_UnicodeTranslateError, "Onns", ...)``.
+
.. c:function:: PyObject* PyUnicodeDecodeError_GetEncoding(PyObject *exc)
PyObject* PyUnicodeEncodeError_GetEncoding(PyObject *exc)
All standard Python exceptions are available as global variables whose names are
``PyExc_`` followed by the Python exception name. These have the type
-:c:type:`PyObject\*`; they are all class objects. For completeness, here are all
+:c:type:`PyObject*`; they are all class objects. For completeness, here are all
the variables:
.. index::
All standard Python warning categories are available as global variables whose
names are ``PyExc_`` followed by the Python exception name. These have the type
-:c:type:`PyObject\*`; they are all class objects. For completeness, here are all
+:c:type:`PyObject*`; they are all class objects. For completeness, here are all
the variables:
.. index::
.. index:: object: file
These APIs are a minimal emulation of the Python 2 C API for built-in file
-objects, which used to rely on the buffered I/O (:c:type:`FILE\*`) support
+objects, which used to rely on the buffered I/O (:c:type:`FILE*`) support
from the C standard library. In Python 3, files and streams use the new
:mod:`io` module, which defines several layers over the low-level unbuffered
I/O of the operating system. The functions described below are
the :mod:`io` APIs instead.
-.. c:function:: PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const char *encoding, const char *errors, const char *newline, int closefd)
+.. c:function:: PyObject* PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const char *encoding, const char *errors, const char *newline, int closefd)
Create a Python file object from the file descriptor of an already
opened file *fd*. The arguments *name*, *encoding*, *errors* and *newline*
that the option was set. For example, ``-b`` sets :c:data:`Py_BytesWarningFlag`
to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2.
-.. c:var:: Py_BytesWarningFlag
+.. c:var:: int Py_BytesWarningFlag
Issue a warning when comparing :class:`bytes` or :class:`bytearray` with
:class:`str` or :class:`bytes` with :class:`int`. Issue an error if greater
Set by the :option:`-b` option.
-.. c:var:: Py_DebugFlag
+.. c:var:: int Py_DebugFlag
Turn on parser debugging output (for expert only, depending on compilation
options).
Set by the :option:`-d` option and the :envvar:`PYTHONDEBUG` environment
variable.
-.. c:var:: Py_DontWriteBytecodeFlag
+.. c:var:: int Py_DontWriteBytecodeFlag
If set to non-zero, Python won't try to write ``.pyc`` files on the
import of source modules.
Set by the :option:`-B` option and the :envvar:`PYTHONDONTWRITEBYTECODE`
environment variable.
-.. c:var:: Py_FrozenFlag
+.. c:var:: int Py_FrozenFlag
Suppress error messages when calculating the module search path in
:c:func:`Py_GetPath`.
Private flag used by ``_freeze_importlib`` and ``frozenmain`` programs.
-.. c:var:: Py_HashRandomizationFlag
+.. c:var:: int Py_HashRandomizationFlag
Set to ``1`` if the :envvar:`PYTHONHASHSEED` environment variable is set to
a non-empty string.
If the flag is non-zero, read the :envvar:`PYTHONHASHSEED` environment
variable to initialize the secret hash seed.
-.. c:var:: Py_IgnoreEnvironmentFlag
+.. c:var:: int Py_IgnoreEnvironmentFlag
Ignore all :envvar:`PYTHON*` environment variables, e.g.
:envvar:`PYTHONPATH` and :envvar:`PYTHONHOME`, that might be set.
Set by the :option:`-E` and :option:`-I` options.
-.. c:var:: Py_InspectFlag
+.. c:var:: int Py_InspectFlag
When a script is passed as first argument or the :option:`-c` option is used,
enter interactive mode after executing the script or the command, even when
Set by the :option:`-i` option and the :envvar:`PYTHONINSPECT` environment
variable.
-.. c:var:: Py_InteractiveFlag
+.. c:var:: int Py_InteractiveFlag
Set by the :option:`-i` option.
-.. c:var:: Py_IsolatedFlag
+.. c:var:: int Py_IsolatedFlag
Run Python in isolated mode. In isolated mode :data:`sys.path` contains
neither the script's directory nor the user's site-packages directory.
.. versionadded:: 3.4
-.. c:var:: Py_LegacyWindowsFSEncodingFlag
+.. c:var:: int Py_LegacyWindowsFSEncodingFlag
If the flag is non-zero, use the ``mbcs`` encoding instead of the UTF-8
encoding for the filesystem encoding.
.. availability:: Windows.
-.. c:var:: Py_LegacyWindowsStdioFlag
+.. c:var:: int Py_LegacyWindowsStdioFlag
If the flag is non-zero, use :class:`io.FileIO` instead of
:class:`WindowsConsoleIO` for :mod:`sys` standard streams.
.. availability:: Windows.
-.. c:var:: Py_NoSiteFlag
+.. c:var:: int Py_NoSiteFlag
Disable the import of the module :mod:`site` and the site-dependent
manipulations of :data:`sys.path` that it entails. Also disable these
Set by the :option:`-S` option.
-.. c:var:: Py_NoUserSiteDirectory
+.. c:var:: int Py_NoUserSiteDirectory
Don't add the :data:`user site-packages directory <site.USER_SITE>` to
:data:`sys.path`.
Set by the :option:`-s` and :option:`-I` options, and the
:envvar:`PYTHONNOUSERSITE` environment variable.
-.. c:var:: Py_OptimizeFlag
+.. c:var:: int Py_OptimizeFlag
Set by the :option:`-O` option and the :envvar:`PYTHONOPTIMIZE` environment
variable.
-.. c:var:: Py_QuietFlag
+.. c:var:: int Py_QuietFlag
Don't display the copyright and version messages even in interactive mode.
.. versionadded:: 3.2
-.. c:var:: Py_UnbufferedStdioFlag
+.. c:var:: int Py_UnbufferedStdioFlag
Force the stdout and stderr streams to be unbuffered.
Set by the :option:`-u` option and the :envvar:`PYTHONUNBUFFERED`
environment variable.
-.. c:var:: Py_VerboseFlag
+.. c:var:: int Py_VerboseFlag
Print a message each time a module is initialized, showing the place
(filename or built-in module) from which it is loaded. If greater or equal
.. c:type:: PyThreadState
This data structure represents the state of a single thread. The only public
- data member is :c:type:`PyInterpreterState \*`:attr:`interp`, which points to
+ data member is :attr:`interp` (:c:type:`PyInterpreterState *`), which points to
this thread's interpreter state.
(TLS) which wraps the underlying native TLS implementation to support the
Python-level thread local storage API (:class:`threading.local`). The
CPython C level APIs are similar to those offered by pthreads and Windows:
-use a thread key and functions to associate a :c:type:`void\*` value per
+use a thread key and functions to associate a :c:type:`void*` value per
thread.
The GIL does *not* need to be held when calling these functions; they supply
.. note::
None of these API functions handle memory management on behalf of the
- :c:type:`void\*` values. You need to allocate and deallocate them yourself.
- If the :c:type:`void\*` values happen to be :c:type:`PyObject\*`, these
+ :c:type:`void*` values. You need to allocate and deallocate them yourself.
+ If the :c:type:`void*` values happen to be :c:type:`PyObject*`, these
functions don't do refcount operations on them either.
.. _thread-specific-storage-api:
.. c:function:: int PyThread_tss_set(Py_tss_t *key, void *value)
- Return a zero value to indicate successfully associating a :c:type:`void\*`
+ Return a zero value to indicate successfully associating a :c:type:`void*`
value with a TSS key in the current thread. Each thread has a distinct
- mapping of the key to a :c:type:`void\*` value.
+ mapping of the key to a :c:type:`void*` value.
.. c:function:: void* PyThread_tss_get(Py_tss_t *key)
- Return the :c:type:`void\*` value associated with a TSS key in the current
+ Return the :c:type:`void*` value associated with a TSS key in the current
thread. This returns ``NULL`` if no value is associated with the key in the
current thread.
.. index:: object: type
Most Python/C API functions have one or more arguments as well as a return value
-of type :c:type:`PyObject\*`. This type is a pointer to an opaque data type
+of type :c:type:`PyObject*`. This type is a pointer to an opaque data type
representing an arbitrary Python object. Since all Python object types are
treated the same way by the Python language in most situations (e.g.,
assignments, scope rules, and argument passing), it is only fitting that they
should be represented by a single C type. Almost all Python objects live on the
heap: you never declare an automatic or static variable of type
-:c:type:`PyObject`, only pointer variables of type :c:type:`PyObject\*` can be
+:c:type:`PyObject`, only pointer variables of type :c:type:`PyObject*` can be
declared. The sole exception are the type objects; since these must never be
deallocated, they are typically static :c:type:`PyTypeObject` objects.
There are few other data types that play a significant role in the Python/C
API; most are simple C types such as :c:type:`int`, :c:type:`long`,
-:c:type:`double` and :c:type:`char\*`. A few structure types are used to
+:c:type:`double` and :c:type:`char*`. A few structure types are used to
describe static tables used to list the functions exported by a module or the
data attributes of a new object type, and another is used to describe the value
of a complex number. These will be discussed together with the functions that
.. c:function:: long PyMarshal_ReadLongFromFile(FILE *file)
- Return a C :c:type:`long` from the data stream in a :c:type:`FILE\*` opened
+ Return a C :c:type:`long` from the data stream in a :c:type:`FILE*` opened
for reading. Only a 32-bit value can be read in using this function,
regardless of the native size of :c:type:`long`.
.. c:function:: int PyMarshal_ReadShortFromFile(FILE *file)
- Return a C :c:type:`short` from the data stream in a :c:type:`FILE\*` opened
+ Return a C :c:type:`short` from the data stream in a :c:type:`FILE*` opened
for reading. Only a 16-bit value can be read in using this function,
regardless of the native size of :c:type:`short`.
.. c:function:: PyObject* PyMarshal_ReadObjectFromFile(FILE *file)
- Return a Python object from the data stream in a :c:type:`FILE\*` opened for
+ Return a Python object from the data stream in a :c:type:`FILE*` opened for
reading.
On error, sets the appropriate exception (:exc:`EOFError`, :exc:`ValueError`
.. c:function:: PyObject* PyMarshal_ReadLastObjectFromFile(FILE *file)
- Return a Python object from the data stream in a :c:type:`FILE\*` opened for
+ Return a Python object from the data stream in a :c:type:`FILE*` opened for
reading. Unlike :c:func:`PyMarshal_ReadObjectFromFile`, this function
assumes that no further objects will be read from the file, allowing it to
aggressively load file data into memory so that the de-serialization can
.. c:function:: void* PyMem_RawMalloc(size_t n)
- Allocates *n* bytes and returns a pointer of type :c:type:`void\*` to the
+ Allocates *n* bytes and returns a pointer of type :c:type:`void*` to the
allocated memory, or ``NULL`` if the request fails.
Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as
.. c:function:: void* PyMem_RawCalloc(size_t nelem, size_t elsize)
Allocates *nelem* elements each whose size in bytes is *elsize* and returns
- a pointer of type :c:type:`void\*` to the allocated memory, or ``NULL`` if the
+ a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the
request fails. The memory is initialized to zeros.
Requesting zero elements or elements of size zero bytes returns a distinct
.. c:function:: void* PyMem_Malloc(size_t n)
- Allocates *n* bytes and returns a pointer of type :c:type:`void\*` to the
+ Allocates *n* bytes and returns a pointer of type :c:type:`void*` to the
allocated memory, or ``NULL`` if the request fails.
Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as
.. c:function:: void* PyMem_Calloc(size_t nelem, size_t elsize)
Allocates *nelem* elements each whose size in bytes is *elsize* and returns
- a pointer of type :c:type:`void\*` to the allocated memory, or ``NULL`` if the
+ a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the
request fails. The memory is initialized to zeros.
Requesting zero elements or elements of size zero bytes returns a distinct
.. c:function:: TYPE* PyMem_New(TYPE, size_t n)
Same as :c:func:`PyMem_Malloc`, but allocates ``(n * sizeof(TYPE))`` bytes of
- memory. Returns a pointer cast to :c:type:`TYPE\*`. The memory will not have
+ memory. Returns a pointer cast to :c:type:`TYPE*`. The memory will not have
been initialized in any way.
.. c:function:: TYPE* PyMem_Resize(void *p, TYPE, size_t n)
Same as :c:func:`PyMem_Realloc`, but the memory block is resized to ``(n *
- sizeof(TYPE))`` bytes. Returns a pointer cast to :c:type:`TYPE\*`. On return,
+ sizeof(TYPE))`` bytes. Returns a pointer cast to :c:type:`TYPE*`. On return,
*p* will be a pointer to the new memory area, or ``NULL`` in the event of
failure.
.. c:function:: void* PyObject_Malloc(size_t n)
- Allocates *n* bytes and returns a pointer of type :c:type:`void\*` to the
+ Allocates *n* bytes and returns a pointer of type :c:type:`void*` to the
allocated memory, or ``NULL`` if the request fails.
Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as
.. c:function:: void* PyObject_Calloc(size_t nelem, size_t elsize)
Allocates *nelem* elements each whose size in bytes is *elsize* and returns
- a pointer of type :c:type:`void\*` to the allocated memory, or ``NULL`` if the
+ a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the
request fails. The memory is initialized to zeros.
Requesting zero elements or elements of size zero bytes returns a distinct
Enum used to identify an allocator domain. Domains:
- .. c:var:: PYMEM_DOMAIN_RAW
+ .. c:macro:: PYMEM_DOMAIN_RAW
Functions:
* :c:func:`PyMem_RawCalloc`
* :c:func:`PyMem_RawFree`
- .. c:var:: PYMEM_DOMAIN_MEM
+ .. c:macro:: PYMEM_DOMAIN_MEM
Functions:
* :c:func:`PyMem_Calloc`
* :c:func:`PyMem_Free`
- .. c:var:: PYMEM_DOMAIN_OBJ
+ .. c:macro:: PYMEM_DOMAIN_OBJ
Functions:
| ``void free(void *ctx, size_t size, void *ptr)`` | free an arena |
+--------------------------------------------------+---------------------------------------+
-.. c:function:: PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator)
+.. c:function:: void PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator)
Get the arena allocator.
-.. c:function:: PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator)
+.. c:function:: void PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator)
Set the arena allocator.
The available slot types are:
-.. c:var:: Py_mod_create
+.. c:macro:: Py_mod_create
Specifies a function that is called to create the module object itself.
The *value* pointer of this slot must point to a function of the signature:
``PyModuleDef`` has non-``NULL`` ``m_traverse``, ``m_clear``,
``m_free``; non-zero ``m_size``; or slots other than ``Py_mod_create``.
-.. c:var:: Py_mod_exec
+.. c:macro:: Py_mod_exec
Specifies a function that is called to *execute* the module.
This is equivalent to executing the code of a Python module: typically,
This is the equivalent of the Python expression: ``callable(*args)``.
- Note that if you only pass :c:type:`PyObject \*` args,
+ Note that if you only pass :c:type:`PyObject *` args,
:c:func:`PyObject_CallFunctionObjArgs` is a faster alternative.
.. versionchanged:: 3.4
This is the equivalent of the Python expression:
``obj.name(arg1, arg2, ...)``.
- Note that if you only pass :c:type:`PyObject \*` args,
+ Note that if you only pass :c:type:`PyObject *` args,
:c:func:`PyObject_CallMethodObjArgs` is a faster alternative.
.. versionchanged:: 3.4
The types of *name* and *format* were changed from ``char *``.
-.. c:function:: PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ..., NULL)
+.. c:function:: PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ...)
Call a callable Python object *callable*, with a variable number of
- :c:type:`PyObject\*` arguments. The arguments are provided as a variable number
+ :c:type:`PyObject*` arguments. The arguments are provided as a variable number
of parameters followed by ``NULL``.
Return the result of the call on success, or raise an exception and return
``callable(arg1, arg2, ...)``.
-.. c:function:: PyObject* PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ..., NULL)
+.. c:function:: PyObject* PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...)
Calls a method of the Python object *obj*, where the name of the method is given as a
Python string object in *name*. It is called with a variable number of
- :c:type:`PyObject\*` arguments. The arguments are provided as a variable number
+ :c:type:`PyObject*` arguments. The arguments are provided as a variable number
of parameters followed by ``NULL``.
Return the result of the call on success, or raise an exception and return
.. versionadded:: 3.8
-.. c:var:: PY_VECTORCALL_ARGUMENTS_OFFSET
+.. c:macro:: PY_VECTORCALL_ARGUMENTS_OFFSET
If set in a vectorcall *nargsf* argument, the callee is allowed to
temporarily change ``args[-1]``. In other words, *args* points to
is equivalent to the Python expression ``type(o)``. This function increments the
reference count of the return value. There's really no reason to use this
function instead of the common expression ``o->ob_type``, which returns a
- pointer of type :c:type:`PyTypeObject\*`, except when the incremented reference
+ pointer of type :c:type:`PyTypeObject*`, except when the incremented reference
count is needed.
.. c:type:: PyCFunction
Type of the functions used to implement most Python callables in C.
- Functions of this type take two :c:type:`PyObject\*` parameters and return
+ Functions of this type take two :c:type:`PyObject*` parameters and return
one such value. If the return value is ``NULL``, an exception shall have
been set. If not ``NULL``, the return value is interpreted as the return
value of the function as exposed in Python. The function must return a new
+------------------+---------------+-------------------------------+
The :attr:`ml_meth` is a C function pointer. The functions may be of different
-types, but they always return :c:type:`PyObject\*`. If the function is not of
+types, but they always return :c:type:`PyObject*`. If the function is not of
the :c:type:`PyCFunction`, the compiler will require a cast in the method table.
Even though :c:type:`PyCFunction` defines the first parameter as
-:c:type:`PyObject\*`, it is common that the method implementation uses the
+:c:type:`PyObject*`, it is common that the method implementation uses the
specific C type of the *self* object.
The :attr:`ml_flags` field is a bitfield which can include the following flags.
.. data:: METH_VARARGS
This is the typical calling convention, where the methods have the type
- :c:type:`PyCFunction`. The function expects two :c:type:`PyObject\*` values.
+ :c:type:`PyCFunction`. The function expects two :c:type:`PyObject*` values.
The first one is the *self* object for methods; for module functions, it is
the module object. The second parameter (often called *args*) is a tuple
object representing all arguments. This parameter is typically processed
Fast calling convention supporting only positional arguments.
The methods have the type :c:type:`_PyCFunctionFast`.
The first parameter is *self*, the second parameter is a C array
- of :c:type:`PyObject\*` values indicating the arguments and the third
+ of :c:type:`PyObject*` values indicating the arguments and the third
parameter is the number of arguments (the length of the array).
This is not part of the :ref:`limited API <stable>`.
Extension of :const:`METH_FASTCALL` supporting also keyword arguments,
with methods of type :c:type:`_PyCFunctionFastWithKeywords`.
Keyword arguments are passed the same way as in the vectorcall protocol:
- there is an additional fourth :c:type:`PyObject\*` parameter
+ there is an additional fourth :c:type:`PyObject*` parameter
which is a tuple representing the names of the keyword arguments
or possibly ``NULL`` if there are no keywords. The values of the keyword
arguments are stored in the *args* array, after the positional arguments.
Methods with a single object argument can be listed with the :const:`METH_O`
flag, instead of invoking :c:func:`PyArg_ParseTuple` with a ``"O"`` argument.
They have the type :c:type:`PyCFunction`, with the *self* parameter, and a
- :c:type:`PyObject\*` parameter representing the single argument.
+ :c:type:`PyObject*` parameter representing the single argument.
These two constants are not used to indicate the calling convention but the
| | | getter and setter |
+-------------+------------------+-----------------------------------+
- The ``get`` function takes one :c:type:`PyObject\*` parameter (the
+ The ``get`` function takes one :c:type:`PyObject*` parameter (the
instance) and a function pointer (the associated ``closure``)::
typedef PyObject *(*getter)(PyObject *, void *);
It should return a new reference on success or ``NULL`` with a set exception
on failure.
- ``set`` functions take two :c:type:`PyObject\*` parameters (the instance and
+ ``set`` functions take two :c:type:`PyObject*` parameters (the instance and
the value to be set) and a function pointer (the associated ``closure``)::
typedef int (*setter)(PyObject *, PyObject *, void *);
.. c:type:: PyStructSequence_Field
Describes a field of a struct sequence. As a struct sequence is modeled as a
- tuple, all fields are typed as :c:type:`PyObject\*`. The index in the
+ tuple, all fields are typed as :c:type:`PyObject*`. The index in the
:attr:`fields` array of the :c:type:`PyStructSequence_Desc` determines which
field of the struct sequence is described.
The following macro is defined to ease writing rich comparison functions:
- .. c:function:: PyObject \*Py_RETURN_RICHCOMPARE(VAL_A, VAL_B, int op)
+ .. c:macro:: Py_RETURN_RICHCOMPARE(VAL_A, VAL_B, op)
Return ``Py_True`` or ``Py_False`` from the function, depending on the
result of a comparison.
than zero and contains the offset in the instance structure of the weak
reference list head (ignoring the GC header, if present); this offset is used by
:c:func:`PyObject_ClearWeakRefs` and the :c:func:`PyWeakref_\*` functions. The
- instance structure needs to include a field of type :c:type:`PyObject\*` which is
+ instance structure needs to include a field of type :c:type:`PyObject*` which is
initialized to ``NULL``.
Do not confuse this field with :c:member:`~PyTypeObject.tp_weaklist`; that is the list head for
:c:type:`Py_UNICODE*` representation; you will have to call
:c:func:`PyUnicode_READY` on them before calling any other API.
+.. note::
+ The "legacy" Unicode object will be removed in Python 3.12 with deprecated
+ APIs. All Unicode objects will be "canonical" since then. See :pep:`623`
+ for more information.
+
Unicode Type
""""""""""""
.. versionadded:: 3.3
+ .. deprecated-removed:: 3.10 3.12
+ This API will be removed with :c:func:`PyUnicode_FromUnicode`.
+
.. c:function:: Py_ssize_t PyUnicode_GET_LENGTH(PyObject *o)
.. versionadded:: 3.3
+ .. deprecated-removed:: 3.10 3.12
+ ``PyUnicode_WCHAR_KIND`` is deprecated.
+
.. c:function:: int PyUnicode_KIND(PyObject *o)
.. versionadded:: 3.3
-.. c:function:: PyUnicode_MAX_CHAR_VALUE(PyObject *o)
+.. c:macro:: PyUnicode_MAX_CHAR_VALUE(o)
Return the maximum code point that is suitable for creating another string
based on *o*, which must be in the "canonical" representation. This is
code units (this includes surrogate pairs as 2 units). *o* has to be a
Unicode object (not checked).
- .. deprecated-removed:: 3.3 4.0
+ .. deprecated-removed:: 3.3 3.12
Part of the old-style Unicode API, please migrate to using
:c:func:`PyUnicode_GET_LENGTH`.
Return the size of the deprecated :c:type:`Py_UNICODE` representation in
bytes. *o* has to be a Unicode object (not checked).
- .. deprecated-removed:: 3.3 4.0
+ .. deprecated-removed:: 3.3 3.12
Part of the old-style Unicode API, please migrate to using
:c:func:`PyUnicode_GET_LENGTH`.
code to use the new :c:func:`PyUnicode_nBYTE_DATA` macros or use
:c:func:`PyUnicode_WRITE` or :c:func:`PyUnicode_READ`.
- .. deprecated-removed:: 3.3 4.0
+ .. deprecated-removed:: 3.3 3.12
Part of the old-style Unicode API, please migrate to using the
:c:func:`PyUnicode_nBYTE_DATA` family of macros.
string content has been filled before using any of the access macros such as
:c:func:`PyUnicode_KIND`.
- Please migrate to using :c:func:`PyUnicode_FromKindAndData`,
- :c:func:`PyUnicode_FromWideChar` or :c:func:`PyUnicode_New`.
+ .. deprecated-removed:: 3.3 3.12
+ Part of the old-style Unicode API, please migrate to using
+ :c:func:`PyUnicode_FromKindAndData`, :c:func:`PyUnicode_FromWideChar`, or
+ :c:func:`PyUnicode_New`.
.. c:function:: Py_UNICODE* PyUnicode_AsUnicode(PyObject *unicode)
embedded null code points, which would cause the string to be truncated when
used in most C functions.
- Please migrate to using :c:func:`PyUnicode_AsUCS4`,
- :c:func:`PyUnicode_AsWideChar`, :c:func:`PyUnicode_ReadChar` or similar new
- APIs.
+ .. deprecated-removed:: 3.3 3.12
+ Part of the old-style Unicode API, please migrate to using
+ :c:func:`PyUnicode_AsUCS4`, :c:func:`PyUnicode_AsWideChar`,
+ :c:func:`PyUnicode_ReadChar` or similar new APIs.
.. deprecated-removed:: 3.3 3.10
.. versionadded:: 3.3
+ .. deprecated-removed:: 3.3 3.12
+ Part of the old-style Unicode API, please migrate to using
+ :c:func:`PyUnicode_AsUCS4`, :c:func:`PyUnicode_AsWideChar`,
+ :c:func:`PyUnicode_ReadChar` or similar new APIs.
+
.. c:function:: Py_UNICODE* PyUnicode_AsUnicodeCopy(PyObject *unicode)
Return the size of the deprecated :c:type:`Py_UNICODE` representation, in
code units (this includes surrogate pairs as 2 units).
- Please migrate to using :c:func:`PyUnicode_GetLength`.
+ .. deprecated-removed:: 3.3 3.12
+ Part of the old-style Unicode API, please migrate to using
+ :c:func:`PyUnicode_GET_LENGTH`.
.. c:function:: PyObject* PyUnicode_FromObject(PyObject *obj)
The following codec API is special in that maps Unicode to Unicode.
-.. c:function:: PyObject* PyUnicode_Translate(PyObject *unicode, \
- PyObject *mapping, const char *errors)
+.. c:function:: PyObject* PyUnicode_Translate(PyObject *str, PyObject *table, const char *errors)
- Translate a Unicode object using the given *mapping* object and return the
- resulting Unicode object. Return ``NULL`` if an exception was raised by the
+ Translate a string by applying a character mapping table to it and return the
+ resulting Unicode object. Return ``NULL`` if an exception was raised by the
codec.
- The *mapping* object must map Unicode ordinal integers to Unicode strings,
- integers (which are then interpreted as Unicode ordinals) or ``None``
- (causing deletion of the character). Unmapped character ordinals (ones
- which cause a :exc:`LookupError`) are left untouched and are copied as-is.
+ The mapping table must map Unicode ordinal integers to Unicode ordinal integers
+ or ``None`` (causing deletion of the character).
+
+ Mapping tables need only provide the :meth:`__getitem__` interface; dictionaries
+ and sequences work well. Unmapped character ordinals (ones which cause a
+ :exc:`LookupError`) are left untouched and are copied as-is.
+
+ *errors* has the usual meaning for codecs. It may be ``NULL`` which indicates to
+ use the default error handling.
.. c:function:: PyObject* PyUnicode_TranslateCharmap(const Py_UNICODE *s, Py_ssize_t size, \
characters are not included in the resulting strings.
-.. c:function:: PyObject* PyUnicode_Translate(PyObject *str, PyObject *table, \
- const char *errors)
-
- Translate a string by applying a character mapping table to it and return the
- resulting Unicode object.
-
- The mapping table must map Unicode ordinal integers to Unicode ordinal integers
- or ``None`` (causing deletion of the character).
-
- Mapping tables need only provide the :meth:`__getitem__` interface; dictionaries
- and sequences work well. Unmapped character ordinals (ones which cause a
- :exc:`LookupError`) are left untouched and are copied as-is.
-
- *errors* has the usual meaning for codecs. It may be ``NULL`` which indicates to
- use the default error handling.
-
-
.. c:function:: PyObject* PyUnicode_Join(PyObject *separator, PyObject *seq)
Join a sequence of strings using the given *separator* and return the resulting
:const:`Py_file_input`, and :const:`Py_single_input`. These are described
following the functions which accept them as parameters.
-Note also that several of these functions take :c:type:`FILE\*` parameters. One
+Note also that several of these functions take :c:type:`FILE*` parameters. One
particular issue which needs to be handled carefully is that the :c:type:`FILE`
structure for different C libraries can be different and incompatible. Under
Windows (at least), it is possible for dynamically linked extensions to actually
-use different libraries, so care should be taken that :c:type:`FILE\*` parameters
+use different libraries, so care should be taken that :c:type:`FILE*` parameters
are only passed to these functions if it is certain that they were created by
the same library that the Python runtime is using.
# Relative filename of the reference count data file.
refcount_file = 'data/refcounts.dat'
+
+# Sphinx 2 and Sphinx 3 compatibility
+# -----------------------------------
+
+# bpo-40204: Allow Sphinx 2 syntax in the C domain
+c_allow_pre_v3 = True
+
+# bpo-40204: Disable warnings on Sphinx 2 syntax of the C domain since the
+# documentation is built with -W (warnings treated as errors).
+c_warn_on_allowed_pre_v3 = False
``first`` member, so it could be any kind of object. It could have a
destructor that causes code to be executed that tries to access the
``first`` member; or that destructor could release the
-:term:`Global interpreter Lock` and let arbitrary code run in other
+:term:`Global interpreter Lock <GIL>` and let arbitrary code run in other
threads that accesses and modifies our object.
To be paranoid and protect ourselves against this possibility, we almost
:class:`~collections.abc.MutableMapping`.
For Python, many of the advantages of interface specifications can be obtained
-by an appropriate test discipline for components. There is also a tool,
-PyChecker, which can be used to find problems due to subclassing.
+by an appropriate test discipline for components.
A good test suite for a module can both provide a regression test and serve as a
module interface specification and a set of examples. Many Python modules can
as a part of the ActivePython distribution (see
https://www.activestate.com/activepython\ ).
-`Boa Constructor <http://boa-constructor.sourceforge.net/>`_ is an IDE and GUI
-builder that uses wxWidgets. It offers visual frame creation and manipulation,
-an object inspector, many views on the source like object browsers, inheritance
-hierarchies, doc string generated html documentation, an advanced debugger,
-integrated help, and Zope support.
-
`Eric <http://eric-ide.python-projects.org/>`_ is an IDE built on PyQt
and the Scintilla editing component.
* PyCharm (https://www.jetbrains.com/pycharm/)
-Is there a tool to help find bugs or perform static analysis?
+Are there tools to help find bugs or perform static analysis?
-------------------------------------------------------------
Yes.
-PyChecker is a static analysis tool that finds bugs in Python source code and
-warns about code complexity and style. You can get PyChecker from
-http://pychecker.sourceforge.net/.
-
-`Pylint <https://www.pylint.org/>`_ is another tool that checks
-if a module satisfies a coding standard, and also makes it possible to write
-plug-ins to add a custom feature. In addition to the bug checking that
-PyChecker performs, Pylint offers some additional features such as checking line
-length, whether variable names are well-formed according to your coding
-standard, whether declared interfaces are fully implemented, and more.
-https://docs.pylint.org/ provides a full list of Pylint's features.
+`Pylint <https://www.pylint.org/>`_ and
+`Pyflakes <https://github.com/PyCQA/pyflakes>`_ do basic checking that will
+help you catch bugs sooner.
Static type checkers such as `Mypy <http://mypy-lang.org/>`_,
`Pyre <https://pyre-check.org/>`_, and
1) By returning a tuple of the results::
- def func2(a, b):
- a = 'new-value' # a and b are local names
- b = b + 1 # assigned to new objects
- return a, b # return new values
-
- x, y = 'old-value', 99
- x, y = func2(x, y)
- print(x, y) # output: new-value 100
+ >>> def func1(a, b):
+ ... a = 'new-value' # a and b are local names
+ ... b = b + 1 # assigned to new objects
+ ... return a, b # return new values
+ ...
+ >>> x, y = 'old-value', 99
+ >>> func1(x, y)
+ ('new-value', 100)
This is almost always the clearest solution.
3) By passing a mutable (changeable in-place) object::
- def func1(a):
- a[0] = 'new-value' # 'a' references a mutable list
- a[1] = a[1] + 1 # changes a shared object
-
- args = ['old-value', 99]
- func1(args)
- print(args[0], args[1]) # output: new-value 100
+ >>> def func2(a):
+ ... a[0] = 'new-value' # 'a' references a mutable list
+ ... a[1] = a[1] + 1 # changes a shared object
+ ...
+ >>> args = ['old-value', 99]
+ >>> func2(args)
+ >>> args
+ ['new-value', 100]
4) By passing in a dictionary that gets mutated::
- def func3(args):
- args['a'] = 'new-value' # args is a mutable dictionary
- args['b'] = args['b'] + 1 # change it in-place
-
- args = {'a': 'old-value', 'b': 99}
- func3(args)
- print(args['a'], args['b'])
+ >>> def func3(args):
+ ... args['a'] = 'new-value' # args is a mutable dictionary
+ ... args['b'] = args['b'] + 1 # change it in-place
+ ...
+ >>> args = {'a': 'old-value', 'b': 99}
+ >>> func3(args)
+ >>> args
+ {'a': 'new-value', 'b': 100}
5) Or bundle up values in a class instance::
- class callByRef:
- def __init__(self, /, **args):
- for key, value in args.items():
- setattr(self, key, value)
-
- def func4(args):
- args.a = 'new-value' # args is a mutable callByRef
- args.b = args.b + 1 # change object in-place
-
- args = callByRef(a='old-value', b=99)
- func4(args)
- print(args.a, args.b)
+ >>> class Namespace:
+ ... def __init__(self, /, **args):
+ ... for key, value in args.items():
+ ... setattr(self, key, value)
+ ...
+ >>> def func4(args):
+ ... args.a = 'new-value' # args is a mutable Namespace
+ ... args.b = args.b + 1 # change object in-place
+ ...
+ >>> args = Namespace(a='old-value', b=99)
+ >>> func4(args)
+ >>> vars(args)
+ {'a': 'new-value', 'b': 100}
There's almost never a good reason to get this complicated.
and :class:`tuple`) and some non-sequence types like :class:`dict`,
:term:`file objects <file object>`, and objects of any classes you define
with an :meth:`__iter__` method or with a :meth:`__getitem__` method
- that implements :term:`Sequence` semantics.
+ that implements :term:`Sequence <sequence>` semantics.
Iterables can be
used in a :keyword:`for` loop and in many other places where a sequence is
>>> d.f
<bound method D.f of <__main__.D object at 0x00B18C90>>
- # Internally, the bound method stores the underlying function,
- # the bound instance, and the class of the bound instance.
+ # Internally, the bound method stores the underlying function and
+ # the bound instance.
>>> d.f.__func__
<function D.f at 0x1012e5ae8>
>>> d.f.__self__
<__main__.D object at 0x1012e1f98>
- >>> d.f.__class__
- <class 'method'>
Static Methods and Class Methods
Available static markers
------------------------
-.. I'm reusing the "c:function" type for markers
-
-.. c:function:: function__entry(str filename, str funcname, int lineno)
+.. object:: function__entry(str filename, str funcname, int lineno)
This marker indicates that execution of a Python function has begun.
It is only triggered for pure-Python (bytecode) functions.
* ``$arg3`` : ``int`` line number
-.. c:function:: function__return(str filename, str funcname, int lineno)
+.. object:: function__return(str filename, str funcname, int lineno)
This marker is the converse of :c:func:`function__entry`, and indicates that
execution of a Python function has ended (either via ``return``, or via an
The arguments are the same as for :c:func:`function__entry`
-.. c:function:: line(str filename, str funcname, int lineno)
+.. object:: line(str filename, str funcname, int lineno)
This marker indicates a Python line is about to be executed. It is
the equivalent of line-by-line tracing with a Python profiler. It is
The arguments are the same as for :c:func:`function__entry`.
-.. c:function:: gc__start(int generation)
+.. object:: gc__start(int generation)
Fires when the Python interpreter starts a garbage collection cycle.
``arg0`` is the generation to scan, like :func:`gc.collect()`.
-.. c:function:: gc__done(long collected)
+.. object:: gc__done(long collected)
Fires when the Python interpreter finishes a garbage collection
cycle. ``arg0`` is the number of collected objects.
-.. c:function:: import__find__load__start(str modulename)
+.. object:: import__find__load__start(str modulename)
Fires before :mod:`importlib` attempts to find and load the module.
``arg0`` is the module name.
.. versionadded:: 3.7
-.. c:function:: import__find__load__done(str modulename, int found)
+.. object:: import__find__load__done(str modulename, int found)
Fires after :mod:`importlib`'s find_and_load function is called.
``arg0`` is the module name, ``arg1`` indicates if module was
.. versionadded:: 3.7
-.. c:function:: audit(str event, void *tuple)
+.. object:: audit(str event, void *tuple)
Fires when :func:`sys.audit` or :c:func:`PySys_Audit` is called.
``arg0`` is the event name as C string, ``arg1`` is a :c:type:`PyObject`
``/usr/share/systemtap/tapset``), then these additional probepoints become
available:
-.. c:function:: python.function.entry(str filename, str funcname, int lineno, frameptr)
+.. object:: python.function.entry(str filename, str funcname, int lineno, frameptr)
This probe point indicates that execution of a Python function has begun.
It is only triggered for pure-Python (bytecode) functions.
-.. c:function:: python.function.return(str filename, str funcname, int lineno, frameptr)
+.. object:: python.function.return(str filename, str funcname, int lineno, frameptr)
- This probe point is the converse of :c:func:`python.function.return`, and
+ This probe point is the converse of ``python.function.return``, and
indicates that execution of a Python function has ended (either via
``return``, or via an exception). It is only triggered for pure-Python
(bytecode) functions.
-----------------------------------------
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 = {
}
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:
| generator_stop | 3.5.0b1 | 3.7 | :pep:`479`: |
| | | | *StopIteration handling inside generators* |
+------------------+-------------+--------------+---------------------------------------------+
-| annotations | 3.7.0b1 | 4.0 | :pep:`563`: |
+| annotations | 3.7.0b1 | 3.10 | :pep:`563`: |
| | | | *Postponed evaluation of annotations* |
+------------------+-------------+--------------+---------------------------------------------+
.. method:: aifc.tell()
+ :noindex:
Return the current write position in the output file. Useful in combination
with :meth:`setmark`.
.. method:: aifc.close()
+ :noindex:
Close the AIFF file. The header of the file is updated to reflect the actual
size of the audio data. After calling this method, the object can no longer be
>>> parser.parse_args(['--foo', 'BAR'])
Namespace(foo='BAR')
>>> parser.parse_args([])
- usage: argparse.py [-h] [--foo FOO]
- argparse.py: error: option --foo is required
+ usage: [-h] --foo FOO
+ : error: the following arguments are required: --foo
As the example shows, if an option is marked as ``required``,
:meth:`~ArgumentParser.parse_args` will report an error if that option is not
.. seealso::
- `Green Tree Snakes <https://greentreesnakes.readthedocs.io/>`_, an external documentation resource, has good
- details on working with Python ASTs.
+ `Green Tree Snakes <https://greentreesnakes.readthedocs.io/>`_, an external
+ documentation resource, has good details on working with Python ASTs.
+
+ `ASTTokens <https://asttokens.readthedocs.io/en/latest/user-guide.html>`_
+ annotates Python ASTs with the positions of tokens and text in the source
+ code that generated them. This is helpful for tools that make source code
+ transformations.
+
+ `leoAst.py <http://leoeditor.com/appendices.html#leoast-py>`_ unifies the
+ token-based and parse-tree-based views of python programs by inserting
+ two-way links between tokens and ast nodes.
+
+ `LibCST <https://libcst.readthedocs.io/>`_ parses code as a Concrete Syntax
+ Tree that looks like an ast tree and keeps all formatting details. It's
+ useful for building automated refactoring (codemod) applications and
+ linters.
+
+ `Parso <https://parso.readthedocs.io>`_ is a Python parser that supports
+ error recovery and round-trip parsing for different Python versions (in
+ multiple Python versions). Parso is also able to list multiple syntax errors
+ in your python file.
\ No newline at end of file
blocking code in a different OS thread without blocking the OS thread
that the event loop runs in.
+There is currently no way to schedule coroutines or callbacks directly
+from a different process (such as one started with
+:mod:`multiprocessing`). The :ref:`Event Loop Methods <asyncio-event-loop>`
+section lists APIs that can read from pipes and watch file descriptors
+without blocking the event loop. In addition, asyncio's
+:ref:`Subprocess <asyncio-subprocess>` APIs provide a way to start a
+process and communicate with it from the event loop. Lastly, the
+aforementioned :meth:`loop.run_in_executor` method can also be used
+with a :class:`concurrent.futures.ProcessPoolExecutor` to execute
+code in a different process.
.. _asyncio-handle-blocking:
.. class:: Container
- Hashable
- Sized
- Callable
- ABCs for classes that provide respectively the methods :meth:`__contains__`,
- :meth:`__hash__`, :meth:`__len__`, and :meth:`__call__`.
+ ABC for classes that provide the :meth:`__contains__` method.
+
+.. class:: Hashable
+
+ ABC for classes that provide the :meth:`__hash__` method.
+
+.. class:: Sized
+
+ ABC for classes that provide the :meth:`__len__` method.
+
+.. class:: Callable
+
+ ABC for classes that provide the :meth:`__call__` method.
.. class:: Iterable
expressions. Custom implementations must provide the :meth:`__await__`
method.
- :term:`Coroutine` objects and instances of the
+ :term:`Coroutine <coroutine>` objects and instances of the
:class:`~collections.abc.Coroutine` ABC are all instances of this ABC.
.. note::
The :class:`ProcessPoolExecutor` class is an :class:`Executor` subclass that
uses a pool of processes to execute calls asynchronously.
:class:`ProcessPoolExecutor` uses the :mod:`multiprocessing` module, which
-allows it to side-step the :term:`Global Interpreter Lock` but also means that
+allows it to side-step the :term:`Global Interpreter Lock
+<global interpreter lock>` but also means that
only picklable objects can be executed and returned.
The ``__main__`` module must be importable by worker subprocesses. This means
.. attribute:: ConfigParser.BOOLEAN_STATES
- By default when using :meth:`~ConfigParser.getboolean`, config parsers
- consider the following values ``True``: ``'1'``, ``'yes'``, ``'true'``,
- ``'on'`` and the following values ``False``: ``'0'``, ``'no'``, ``'false'``,
- ``'off'``. You can override this by specifying a custom dictionary of strings
- and their Boolean outcomes. For example:
-
- .. doctest::
-
- >>> custom = configparser.ConfigParser()
- >>> custom['section1'] = {'funky': 'nope'}
- >>> custom['section1'].getboolean('funky')
- Traceback (most recent call last):
- ...
- ValueError: Not a boolean: nope
- >>> custom.BOOLEAN_STATES = {'sure': True, 'nope': False}
- >>> custom['section1'].getboolean('funky')
- False
-
- Other typical Boolean pairs include ``accept``/``reject`` or
- ``enabled``/``disabled``.
+ By default when using :meth:`~ConfigParser.getboolean`, config parsers
+ consider the following values ``True``: ``'1'``, ``'yes'``, ``'true'``,
+ ``'on'`` and the following values ``False``: ``'0'``, ``'no'``, ``'false'``,
+ ``'off'``. You can override this by specifying a custom dictionary of strings
+ and their Boolean outcomes. For example:
+
+ .. doctest::
+
+ >>> custom = configparser.ConfigParser()
+ >>> custom['section1'] = {'funky': 'nope'}
+ >>> custom['section1'].getboolean('funky')
+ Traceback (most recent call last):
+ ...
+ ValueError: Not a boolean: nope
+ >>> custom.BOOLEAN_STATES = {'sure': True, 'nope': False}
+ >>> custom['section1'].getboolean('funky')
+ False
+
+ Other typical Boolean pairs include ``accept``/``reject`` or
+ ``enabled``/``disabled``.
.. method:: ConfigParser.optionxform(option)
+ :noindex:
- This method transforms option names on every read, get, or set
- operation. The default converts the name to lowercase. This also
- means that when a configuration file gets written, all keys will be
- lowercase. Override this method if that's unsuitable.
- For example:
+ This method transforms option names on every read, get, or set
+ operation. The default converts the name to lowercase. This also
+ means that when a configuration file gets written, all keys will be
+ lowercase. Override this method if that's unsuitable.
+ For example:
- .. doctest::
+ .. doctest::
+
+ >>> config = """
+ ... [Section1]
+ ... Key = Value
+ ...
+ ... [Section2]
+ ... AnotherKey = Value
+ ... """
+ >>> typical = configparser.ConfigParser()
+ >>> typical.read_string(config)
+ >>> list(typical['Section1'].keys())
+ ['key']
+ >>> list(typical['Section2'].keys())
+ ['anotherkey']
+ >>> custom = configparser.RawConfigParser()
+ >>> custom.optionxform = lambda option: option
+ >>> custom.read_string(config)
+ >>> list(custom['Section1'].keys())
+ ['Key']
+ >>> list(custom['Section2'].keys())
+ ['AnotherKey']
- >>> config = """
- ... [Section1]
- ... Key = Value
- ...
- ... [Section2]
- ... AnotherKey = Value
- ... """
- >>> typical = configparser.ConfigParser()
- >>> typical.read_string(config)
- >>> list(typical['Section1'].keys())
- ['key']
- >>> list(typical['Section2'].keys())
- ['anotherkey']
- >>> custom = configparser.RawConfigParser()
- >>> custom.optionxform = lambda option: option
- >>> custom.read_string(config)
- >>> list(custom['Section1'].keys())
- ['Key']
- >>> list(custom['Section2'].keys())
- ['AnotherKey']
-
- .. note::
- The optionxform function transforms option names to a canonical form.
- This should be an idempotent function: if the name is already in
- canonical form, it should be returned unchanged.
+ .. note::
+ The optionxform function transforms option names to a canonical form.
+ This should be an idempotent function: if the name is already in
+ canonical form, it should be returned unchanged.
.. attribute:: ConfigParser.SECTCRE
- A compiled regular expression used to parse section headers. The default
- matches ``[section]`` to the name ``"section"``. Whitespace is considered
- part of the section name, thus ``[ larch ]`` will be read as a section of
- name ``" larch "``. Override this attribute if that's unsuitable. For
- example:
+ A compiled regular expression used to parse section headers. The default
+ matches ``[section]`` to the name ``"section"``. Whitespace is considered
+ part of the section name, thus ``[ larch ]`` will be read as a section of
+ name ``" larch "``. Override this attribute if that's unsuitable. For
+ example:
+
+ .. doctest::
+
+ >>> import re
+ >>> config = """
+ ... [Section 1]
+ ... option = value
+ ...
+ ... [ Section 2 ]
+ ... another = val
+ ... """
+ >>> typical = configparser.ConfigParser()
+ >>> typical.read_string(config)
+ >>> typical.sections()
+ ['Section 1', ' Section 2 ']
+ >>> custom = configparser.ConfigParser()
+ >>> custom.SECTCRE = re.compile(r"\[ *(?P<header>[^]]+?) *\]")
+ >>> custom.read_string(config)
+ >>> custom.sections()
+ ['Section 1', 'Section 2']
- .. doctest::
+ .. note::
- >>> import re
- >>> config = """
- ... [Section 1]
- ... option = value
- ...
- ... [ Section 2 ]
- ... another = val
- ... """
- >>> typical = configparser.ConfigParser()
- >>> typical.read_string(config)
- >>> typical.sections()
- ['Section 1', ' Section 2 ']
- >>> custom = configparser.ConfigParser()
- >>> custom.SECTCRE = re.compile(r"\[ *(?P<header>[^]]+?) *\]")
- >>> custom.read_string(config)
- >>> custom.sections()
- ['Section 1', 'Section 2']
-
- .. note::
-
- While ConfigParser objects also use an ``OPTCRE`` attribute for recognizing
- option lines, it's not recommended to override it because that would
- interfere with constructor options *allow_no_value* and *delimiters*.
+ While ConfigParser objects also use an ``OPTCRE`` attribute for recognizing
+ option lines, it's not recommended to override it because that would
+ interfere with constructor options *allow_no_value* and *delimiters*.
Legacy API Examples
.. function:: getmouse()
After :meth:`~window.getch` returns :const:`KEY_MOUSE` to signal a mouse event, this
- method should be call to retrieve the queued mouse event, represented as a
+ method should be called to retrieve the queued mouse event, represented as a
5-tuple ``(id, x, y, z, bstate)``. *id* is an ID value used to distinguish
multiple devices, and *x*, *y*, *z* are the event's coordinates. (*z* is
currently unused.) *bstate* is an integer value whose bits will be set to
window.addch(y, x, ch[, attr])
Paint character *ch* at ``(y, x)`` with attributes *attr*, overwriting any
- character previously painter at that location. By default, the character
+ character previously painted at that location. By default, the character
position and attributes are the current settings for the window object.
.. note::
--------------
This module provides classes and functions for comparing sequences. It
-can be used for example, for comparing files, and can produce difference
-information in various formats, including HTML and context and unified
+can be used for example, for comparing files, and can produce information
+about file differences in various formats, including HTML and context and unified
diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
.. class:: SequenceMatcher
+ :noindex:
This is a flexible class for comparing pairs of sequences of any type, so long
as the sequence elements are :term:`hashable`. The basic algorithm predates, and is a
.. class:: Differ(linejunk=None, charjunk=None)
+ :noindex:
Optional keyword parameters *linejunk* and *charjunk* are for filter functions
(or ``None``):
.. opcode:: LIST_APPEND (i)
- Calls ``list.append(TOS[-i], TOS)``. Used to implement list comprehensions.
+ Calls ``list.append(TOS1[-i], TOS)``. Used to implement list comprehensions.
.. opcode:: MAP_ADD (i)
constant values. Within an enumeration, the members can be compared
by identity, and the enumeration itself can be iterated over.
+.. note:: Case of Enum Members
+
+ Because Enums are used to represent constants we recommend using
+ UPPER_CASE names for enum members, and will be using that style
+ in our examples.
+
Module Contents
---------------
the bitwise operations without losing their :class:`Flag` membership.
.. function:: unique
+ :noindex:
Enum class decorator that ensures only one name is bound to any one value.
:meth:`__str__` and :meth:`__repr__` respectively; other codes (such as
`%i` or `%h` for IntEnum) treat the enum member as its mixed-in type.
5. :ref:`Formatted string literals <f-strings>`, :meth:`str.format`,
- and :func:`format` will use the mixed-in
- type's :meth:`__format__`. If the :class:`Enum` class's :func:`str` or
- :func:`repr` is desired, use the `!s` or `!r` format codes.
+ and :func:`format` will use the mixed-in type's :meth:`__format__`
+ unless :meth:`__str__` or :meth:`__format__` is overridden in the subclass,
+ in which case the overridden methods or :class:`Enum` methods will be used.
+ Use the !s and !r format codes to force usage of the :class:`Enum` class's
+ :meth:`__str__` and :meth:`__repr__` methods.
When to use :meth:`__new__` vs. :meth:`__init__`
------------------------------------------------
>>> Color.GREEN.value
2
+To make a more general purpose ``AutoNumber``, add ``*args`` to the signature::
+
+ >>> class AutoNumber(NoValue):
+ ... def __new__(cls, *args): # this is the only change from above
+ ... value = len(cls.__members__) + 1
+ ... obj = object.__new__(cls)
+ ... obj._value_ = value
+ ... return obj
+ ...
+
+Then when you inherit from ``AutoNumber`` you can write your own ``__init__``
+to handle any extra arguments::
+
+ >>> class Swatch(AutoNumber):
+ ... def __init__(self, pantone='unknown'):
+ ... self.pantone = pantone
+ ... AUBURN = '3497'
+ ... SEA_GREEN = '1246'
+ ... BLEACHED_CORAL = () # New color, no Pantone code yet!
+ ...
+ >>> Swatch.SEA_GREEN
+ <Swatch.SEA_GREEN: 2>
+ >>> Swatch.SEA_GREEN.pantone
+ '1246'
+ >>> Swatch.BLEACHED_CORAL.pantone
+ 'unknown'
.. note::
input must conform to the following grammar after leading and trailing
whitespace characters are removed:
- .. productionlist::
+ .. productionlist:: float
sign: "+" | "-"
infinity: "Infinity" | "inf"
nan: "nan"
.. function:: open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
Open *file* and return a corresponding :term:`file object`. If the file
- cannot be opened, an :exc:`OSError` is raised.
+ cannot be opened, an :exc:`OSError` is raised. See
+ :ref:`tut-files` for more examples of how to use this function.
*file* is a :term:`path-like object` giving the pathname (absolute or
relative to the current working directory) of the file to be opened or an
locals dictionary is only useful for reads since updates to the locals
dictionary are ignored.
+ A :exc:`TypeError` exception is raised if an object is specified but
+ it doesn't have a :attr:`~object.__dict__` attribute (for example, if
+ its class defines the :attr:`~object.__slots__` attribute).
.. function:: zip(*iterables)
allocations minus the number of deallocations exceeds *threshold0*, collection
starts. Initially only generation ``0`` is examined. If generation ``0`` has
been examined more than *threshold1* times since generation ``1`` has been
- examined, then generation ``1`` is examined as well. Similarly, *threshold2*
- controls the number of collections of generation ``1`` before collecting
- generation ``2``.
+ examined, then generation ``1`` is examined as well.
+ With the third generation, things are a bit more complicated,
+ see `Collecting the oldest generation <https://devguide.python.org/garbage_collector/#collecting-the-oldest-generation>`_ for more information.
.. function:: get_count()
(like :file:`/usr/src/Python-1.5/Makefile`) or relative (like
:file:`../../Tools/\*/\*.gif`), and can contain shell-style wildcards. Broken
symlinks are included in the results (as in the shell). Whether or not the
- results are sorted depends on the file system.
+ results are sorted depends on the file system. If a file that satisfies
+ conditions is removed or added during the call of this function, whether
+ a path name for that file be included is unspecified.
.. index::
single: **; in glob-style wildcards
large number of milliseconds, such as 100000000.) For imported module
names or class or function attributes, type '.'.
For filenames in the root directory, type :data:`os.sep` or
-data:`os.altsep` immediately after an opening quote. (On Windows,
+:data:`os.altsep` immediately after an opening quote. (On Windows,
one can specify a drive first.) Move into subdirectories by typing a
directory name and a separator.
Calltips
^^^^^^^^
-A calltip is shown when one types :kbd:`(` after the name of an *accessible*
-function. A name expression may include dots and subscripts. A calltip
-remains until it is clicked, the cursor is moved out of the argument area,
-or :kbd:`)` is typed. When the cursor is in the argument part of a definition,
-the menu or shortcut display a calltip.
+A calltip is shown automatically when one types :kbd:`(` after the name
+of an *accessible* function. A function name expression may include
+dots and subscripts. A calltip remains until it is clicked, the cursor
+is moved out of the argument area, or :kbd:`)` is typed. Whenever the
+cursor is in the argument part of a definition, select Edit and "Show
+Call Tip" on the menu or enter its shortcut to display a calltip.
-A calltip consists of the function signature and the first line of the
-docstring. For builtins without an accessible signature, the calltip
-consists of all lines up the fifth line or the first blank line. These
-details may change.
+The calltip consists of the function's signature and docstring up to
+the latter's first blank line or the fifth non-blank line. (Some builtin
+functions lack an accessible signature.) A '/' or '*' in the signature
+indicates that the preceding or following arguments are passed by
+position or name (keyword) only. Details are subject to change.
-The set of *accessible* functions depends on what modules have been imported
-into the user process, including those imported by Idle itself,
-and what definitions have been run, all since the last restart.
+In Shell, the accessible functions depends on what modules have been
+imported into the user process, including those imported by Idle itself,
+and which definitions have been run, all since the last restart.
For example, restart the Shell and enter ``itertools.count(``. A calltip
-appears because Idle imports itertools into the user process for its own use.
-(This could change.) Enter ``turtle.write(`` and nothing appears. Idle does
-not import turtle. The menu or shortcut do nothing either. Enter
-``import turtle`` and then ``turtle.write(`` will work.
-
-In an editor, import statements have no effect until one runs the file. One
-might want to run a file after writing the import statements at the top,
-or immediately run an existing file before editing.
+appears because Idle imports itertools into the user process for its own
+use. (This could change.) Enter ``turtle.write(`` and nothing appears.
+Idle does not itself import turtle. The menu entry and shortcut also do
+nothing. Enter ``import turtle``. Thereafter, ``turtle.write(``
+will display a calltip.
+
+In an editor, import statements have no effect until one runs the file.
+One might want to run a file after writing import statements, after
+adding function definitions, or after opening an existing file.
.. _code-context:
.. function:: Int2AP(num)
- Converts an integer into a string representation using characters from the set
+ Converts an integer into a bytes representation using characters from the set
[``A`` .. ``P``].
Each command returns a tuple: ``(type, [data, ...])`` where *type* is usually
``'OK'`` or ``'NO'``, and *data* is either the text from the command response,
-or mandated results from the command. Each *data* is either a string, or a
+or mandated results from the command. Each *data* is either a ``bytes``, or a
tuple. If a tuple, then the first part is the header of the response, and the
second part contains the data (ie: 'literal' value).
.. class:: WindowsRegistryFinder
- :term:`Finder` for modules declared in the Windows registry. This class
+ :term:`Finder <finder>` for modules declared in the Windows registry. This class
implements the :class:`importlib.abc.MetaPathFinder` ABC.
Only class methods are defined by this class to alleviate the need for
.. class:: PathFinder
- A :term:`Finder` for :data:`sys.path` and package ``__path__`` attributes.
+ A :term:`Finder <finder>` for :data:`sys.path` and package ``__path__`` attributes.
This class implements the :class:`importlib.abc.MetaPathFinder` ABC.
Only class methods are defined by this class to alleviate the need for
:mod:`multiprocessing` is a package that supports spawning processes using an
API similar to the :mod:`threading` module. The :mod:`multiprocessing` package
offers both local and remote concurrency, effectively side-stepping the
-:term:`Global Interpreter Lock` by using subprocesses instead of threads. Due
+:term:`Global Interpreter Lock <global interpreter lock>` by using
+subprocesses instead of threads. Due
to this, the :mod:`multiprocessing` module allows the programmer to fully
leverage multiple processors on a given machine. It runs on both Unix and
Windows.
Return a list containing the names of the entries in the directory given by
*path*. The list is in arbitrary order, and does not include the special
entries ``'.'`` and ``'..'`` even if they are present in the directory.
+ If a file is removed from or added to the directory during the call of
+ this function, whether a name for that file be included is unspecified.
*path* may be a :term:`path-like object`. If *path* is of type ``bytes``
(directly or indirectly through the :class:`PathLike` interface),
Return an iterator of :class:`os.DirEntry` objects corresponding to the
entries in the directory given by *path*. The entries are yielded in
arbitrary order, and the special entries ``'.'`` and ``'..'`` are not
- included.
+ included. If a file is removed from or added to the directory after
+ creating the iterator, whether an entry for that file be included is
+ unspecified.
Using :func:`scandir` instead of :func:`listdir` can significantly
increase the performance of code that also needs file type or file
*filenames* is a list of the names of the non-directory files in *dirpath*.
Note that the names in the lists contain no path components. To get a full path
(which begins with *top*) to a file or directory in *dirpath*, do
- ``os.path.join(dirpath, name)``.
+ ``os.path.join(dirpath, name)``. Whether or not the lists are sorted
+ depends on the file system. If a file is removed from or added to the
+ *dirpath* directory during generating the lists, whether a name for that
+ file be included is unspecified.
If optional argument *topdown* is ``True`` or not specified, the triple for a
directory is generated before the triples for any of its subdirectories
PosixPath('docs/_static')
PosixPath('docs/Makefile')
+ The children are yielded in arbitrary order, and the special entries
+ ``'.'`` and ``'..'`` are not included. If a file is removed from or added
+ to the directory after creating the iterator, whether an path object for
+ that file be included is unspecified.
+
.. method:: Path.lchmod(mode)
Like :meth:`Path.chmod` but, if the path points to a symbolic link, the
Create a hard link pointing to a path named *target*.
- .. versionchanged:: 3.8
+ .. versionadded:: 3.8
.. method:: Path.write_bytes(data)
:func:`os.path.exists` :meth:`Path.exists`
:func:`os.path.expanduser` :meth:`Path.expanduser` and
:meth:`Path.home`
+:func:`os.listdir` :meth:`Path.iterdir`
:func:`os.path.isdir` :meth:`Path.is_dir`
:func:`os.path.isfile` :meth:`Path.is_file`
:func:`os.path.islink` :meth:`Path.is_symlink`
+:func:`os.link` :meth:`Path.link_to`
+:func:`os.symlink` :meth:`Path.symlink_to`
:func:`os.stat` :meth:`Path.stat`,
:meth:`Path.owner`,
:meth:`Path.group`
.. class:: ImpLoader(fullname, file, filename, etc)
- :term:`Loader` that wraps Python's "classic" import algorithm.
+ :term:`Loader <loader>` that wraps Python's "classic" import algorithm.
.. deprecated:: 3.3
This emulation is no longer needed, as the standard import mechanism
in ``.pyc``.
For example, if *file* is ``/foo/bar/baz.py`` *cfile* will default to
``/foo/bar/__pycache__/baz.cpython-32.pyc`` for Python 3.2. If *dfile* is
- specified, it is used as the name of the source file in error messages when
+ specified, it is used as the name of the source file in error messages
instead of *file*. If *doraise* is true, a :exc:`PyCompileError` is raised
when an error is encountered while compiling *file*. If *doraise* is false
(the default), an error string is written to ``sys.stderr``, but no exception
.. method:: socket.setsockopt(level, optname, value: int)
.. method:: socket.setsockopt(level, optname, value: buffer)
+ :noindex:
.. method:: socket.setsockopt(level, optname, None, optlen: int)
+ :noindex:
.. index:: module: struct
Possible value for :attr:`SSLContext.verify_flags`. In this mode, only the
peer cert is checked but none of the intermediate CA certificates. The mode
requires a valid CRL that is signed by the peer cert's issuer (its direct
- ancestor CA). If no proper CRL has has been loaded with
+ ancestor CA). If no proper CRL has been loaded with
:attr:`SSLContext.load_verify_locations`, validation will fail.
.. versionadded:: 3.4
The grammar for a replacement field is as follows:
- .. productionlist:: sf
+ .. productionlist:: format-string
replacement_field: "{" [`field_name`] ["!" `conversion`] [":" `format_spec`] "}"
field_name: arg_name ("." `attribute_name` | "[" `element_index` "]")*
arg_name: [`identifier` | `digit`+]
The general form of a *standard format specifier* is:
-.. productionlist:: sf
+.. productionlist:: format-spec
format_spec: [[`fill`]`align`][`sign`][#][0][`width`][`grouping_option`][.`precision`][`type`]
fill: <any character>
align: "<" | ">" | "=" | "^"
Note the difference between ``'@'`` and ``'='``: both use native byte order, but
the size and alignment of the latter is standardized.
-The form ``'!'`` is available for those poor souls who claim they can't remember
-whether network byte order is big-endian or little-endian.
+The form ``'!'`` represents the network byte order which is always big-endian
+as defined in `IETF RFC 1700 <IETF RFC 1700_>`_.
There is no way to indicate non-native byte order (force byte-swapping); use the
appropriate choice of ``'<'`` or ``'>'``.
.. _half precision format: https://en.wikipedia.org/wiki/Half-precision_floating-point_format
.. _ieee 754 standard: https://en.wikipedia.org/wiki/IEEE_floating_point#IEEE_754-2008
+
+.. _IETF RFC 1700: https://tools.ietf.org/html/rfc1700
.. class:: TarFile
+ :noindex:
Class for reading and writing tar archives. Do not use this class directly:
use :func:`tarfile.open` instead. See :ref:`tarfile-objects`.
The module defines the following user-callable items:
-.. function:: TemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None)
+.. function:: TemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None)
Return a :term:`file-like object` that can be used as a temporary storage area.
The file is created securely, using the same rules as :func:`mkstemp`. It will be destroyed as soon
Added *errors* parameter.
-.. function:: NamedTemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True, *, errors=None)
+.. function:: NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True, *, errors=None)
This function operates exactly as :func:`TemporaryFile` does, except that
the file is guaranteed to have a visible name in the file system (on
Added *errors* parameter.
-.. function:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None)
+.. function:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None)
This function operates exactly as :func:`TemporaryFile` does, except that
data is spooled in memory until the file size exceeds *max_size*, or
If you want to force a bytes return value with otherwise default behavior,
pass ``suffix=b''``.
- If *text* is specified, it indicates whether to open the file in binary
- mode (the default) or text mode. On some platforms, this makes no
- difference.
+ If *text* is specified and true, the file is opened in text mode.
+ Otherwise, (the default) the file is opened in binary mode.
:func:`mkstemp` returns a tuple containing an OS-level handle to an open
file (as would be returned by :func:`os.open`) and the absolute pathname
.. impl-detail::
- In CPython, due to the :term:`Global Interpreter Lock`, only one thread
+ In CPython, due to the :term:`Global Interpreter Lock
+ <global interpreter lock>`, only one thread
can execute Python code at once (even though certain performance-oriented
libraries might overcome this limitation).
If you want your application to make better use of the computational
.. cmdoption:: -u, --unit=U
- specify a time unit for timer output; can select nsec, usec, msec, or sec
+ specify a time unit for timer output; can select nsec, usec, msec, or sec
.. versionadded:: 3.5
`TKDocs <http://www.tkdocs.com/>`_
Extensive tutorial plus friendlier widget pages for some of the widgets.
- `Tkinter 8.5 reference: a GUI for Python <https://web.archive.org/web/20190524140835/https://infohost.nmt.edu/tcc/help/pubs/tkinter/web/index.html>`_
+ `Tkinter 8.5 reference: a GUI for Python <https://www.tkdocs.com/shipman/>`_
On-line reference material.
`Tkinter docs from effbot <http://effbot.org/tkinterbook/>`_
.. index:: single: packing (widgets)
The packer is one of Tk's geometry-management mechanisms. Geometry managers
-are used to specify the relative positioning of the positioning of widgets
-within their container - their mutual *master*. In contrast to the more
-cumbersome *placer* (which is used less commonly, and we do not cover here), the
-packer takes qualitative relationship specification - *above*, *to the left of*,
-*filling*, etc - and works everything out to determine the exact placement
-coordinates for you.
+are used to specify the relative positioning of widgets within their container -
+their mutual *master*. In contrast to the more cumbersome *placer* (which is
+used less commonly, and we do not cover here), the packer takes qualitative
+relationship specification - *above*, *to the left of*, *filling*, etc - and
+works everything out to determine the exact placement coordinates for you.
The size of any *master* widget is determined by the size of the "slave widgets"
inside. The packer is used to control where slave widgets appear inside the
For example::
- class App(Frame):
- def __init__(self, master=None):
+ import tkinter as tk
+
+ class App(tk.Frame):
+ def __init__(self, master):
super().__init__(master)
self.pack()
- self.entrythingy = Entry()
+ self.entrythingy = tk.Entry()
self.entrythingy.pack()
- # here is the application variable
- self.contents = StringVar()
- # set it to some value
+ # Create the application variable.
+ self.contents = tk.StringVar()
+ # Set it to some value.
self.contents.set("this is a variable")
- # tell the entry widget to watch this variable
+ # Tell the entry widget to watch this variable.
self.entrythingy["textvariable"] = self.contents
- # and here we get a callback when the user hits return.
- # we will have the program print out the value of the
- # application variable when the user hits return
+ # Define a callback for when the user hits return.
+ # It prints the current value of the variable.
self.entrythingy.bind('<Key-Return>',
- self.print_contents)
+ self.print_contents)
def print_contents(self, event):
- print("hi. contents of entry is now ---->",
+ print("Hi. The current entry content is:",
self.contents.get())
+ root = tk.Tk()
+ myapp = App(root)
+ myapp.mainloop()
The Window Manager
^^^^^^^^^^^^^^^^^^
.. data:: TYPE_COMMENT
+ :noindex:
Token value indicating that a type comment was recognized. Such
tokens are only produced when :func:`ast.parse()` is invoked with
~~~~~~~~~~~~~~~~~~~~
.. function:: reset()
+ :noindex:
Delete the turtle's drawings from the screen, re-center the turtle and set
variables to the default values.
.. function:: clear()
+ :noindex:
Delete the turtle's drawings from the screen. Do not move turtle. State and
position of the turtle as well as drawings of other turtles are not affected.
------------
.. function:: onclick(fun, btn=1, add=None)
+ :noindex:
:param fun: a function with two arguments which will be called with the
coordinates of the clicked point on the canvas
compatible with every type.
This means that it is possible to perform any operation or method call on a
-value of type on :data:`Any` and assign it to any variable::
+value of type :data:`Any` and assign it to any variable::
from typing import Any
.. versionadded:: 3.5.2
-.. class:: Coroutine(Awaitable[V_co], Generic[T_co T_contra, V_co])
+.. class:: Coroutine(Awaitable[V_co], Generic[T_co, T_contra, V_co])
A generic version of :class:`collections.abc.Coroutine`.
The variance and order of type variables
for those new to unit testing. For production environments it is
recommended that tests be driven by a continuous integration system such as
`Buildbot <https://buildbot.net/>`_, `Jenkins <https://jenkins.io/>`_
- or `Hudson <http://hudson-ci.org/>`_.
+ or `Travis-CI <https://travis-ci.com>`_, or `AppVeyor <https://www.appveyor.com/>`_.
.. _unittest-minimal-example:
If *is_authenticated* is specified as ``True``, *realm* is ignored.
-.. method:: HTTPPasswordMgr.find_user_password(realm, authuri)
+.. method:: HTTPPasswordMgrWithPriorAuth.find_user_password(realm, authuri)
Same as for :class:`HTTPPasswordMgrWithDefaultRealm` objects
rarely used and is not guaranteed by WSGI. On IIS<7, though, the
setting can only be made on a vhost level, affecting all other script
mappings, many of which break when exposed to the ``PATH_TRANSLATED`` bug.
- For this reason IIS<7 is almost never deployed with the fix. (Even IIS7
- rarely uses it because there is still no UI for it.)
+ For this reason IIS<7 is almost never deployed with the fix (Even IIS7
+ rarely uses it because there is still no UI for it.).
There is no way for CGI code to tell whether the option was set, so a
separate handler class is provided. It is used in the same way as
The XML modules are not secure against erroneous or maliciously
constructed data. If you need to parse untrusted or
unauthenticated data see the :ref:`xml-vulnerabilities` and
- :ref:`defused-packages` sections.
+ :ref:`defusedxml-package` sections.
It is important to note that modules in the :mod:`xml` package require that
there be at least one SAX-compliant XML parser available. The Expat parser is
The documentation for `defusedxml`_ on PyPI has further information about
all known attack vectors with examples and references.
-.. _defused-packages:
+.. _defusedxml-package:
-The :mod:`defusedxml` and :mod:`defusedexpat` Packages
+The :mod:`defusedxml` Package
------------------------------------------------------
`defusedxml`_ is a pure Python package with modified subclasses of all stdlib
package also ships with example exploits and extended documentation on more
XML exploits such as XPath injection.
-`defusedexpat`_ provides a modified libexpat and a patched
-:mod:`pyexpat` module that have countermeasures against entity expansion
-DoS attacks. The :mod:`defusedexpat` module still allows a sane and configurable amount of entity
-expansions. The modifications may be included in some future release of Python,
-but will not be included in any bugfix releases of
-Python because they break backward compatibility.
-
.. _defusedxml: https://pypi.org/project/defusedxml/
-.. _defusedexpat: https://pypi.org/project/defusedexpat/
.. _Billion Laughs: https://en.wikipedia.org/wiki/Billion_laughs
.. _ZIP bomb: https://en.wikipedia.org/wiki/Zip_bomb
.. _DTD: https://en.wikipedia.org/wiki/Document_type_definition
Terms and conditions for accessing or otherwise using Python
============================================================
+Python software and documentation are licensed under the
+:ref:`PSF License Agreement <PSF-license>`.
+
+Starting with Python 3.8.6, examples, recipes, and other code in
+the documentation are dual licensed under the PSF License Agreement
+and the :ref:`Zero-Clause BSD license <BSD0>`.
+
+Some software incorporated into Python is under different licenses.
+The licenses are listed with code falling under that license.
+See :ref:`OtherLicenses` for an incomplete list of these licenses.
+
+
+.. _PSF-license:
PSF LICENSE AGREEMENT FOR PYTHON |release|
------------------------------------------
SOFTWARE.
+.. _BSD0:
+
+ZERO-CLAUSE BSD LICENSE FOR CODE IN THE PYTHON |release| DOCUMENTATION
+----------------------------------------------------------------------
+
+.. parsed-literal::
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ PERFORMANCE OF THIS SOFTWARE.
+
+
+.. _OtherLicenses:
+
Licenses and Acknowledgements for Incorporated Software
=======================================================
Summarizing:
-.. productionlist::
+
+.. productionlist:: python-grammar
compound_stmt: `if_stmt`
: | `while_stmt`
: | `for_stmt`
The :keyword:`if` statement is used for conditional execution:
-.. productionlist::
+.. productionlist:: python-grammar
if_stmt: "if" `assignment_expression` ":" `suite`
: ("elif" `assignment_expression` ":" `suite`)*
: ["else" ":" `suite`]
The :keyword:`while` statement is used for repeated execution as long as an
expression is true:
-.. productionlist::
+.. productionlist:: python-grammar
while_stmt: "while" `assignment_expression` ":" `suite`
: ["else" ":" `suite`]
The :keyword:`for` statement is used to iterate over the elements of a sequence
(such as a string, tuple or list) or other iterable object:
-.. productionlist::
+.. productionlist:: python-grammar
for_stmt: "for" `target_list` "in" `expression_list` ":" `suite`
: ["else" ":" `suite`]
The :keyword:`try` statement specifies exception handlers and/or cleanup code
for a group of statements:
-.. productionlist::
+.. productionlist:: python-grammar
try_stmt: `try1_stmt` | `try2_stmt`
try1_stmt: "try" ":" `suite`
: ("except" [`expression` ["as" `identifier`]] ":" `suite`)+
This allows common :keyword:`try`...\ :keyword:`except`...\ :keyword:`finally`
usage patterns to be encapsulated for convenient reuse.
-.. productionlist::
+.. productionlist:: python-grammar
with_stmt: "with" `with_item` ("," `with_item`)* ":" `suite`
with_item: `expression` ["as" `target`]
A function definition defines a user-defined function object (see section
:ref:`types`):
-.. productionlist::
+.. productionlist:: python-grammar
funcdef: [`decorators`] "def" `funcname` "(" [`parameter_list`] ")"
: ["->" `expression`] ":" `suite`
decorators: `decorator`+
A class definition defines a class object (see section :ref:`types`):
-.. productionlist::
+.. productionlist:: python-grammar
classdef: [`decorators`] "class" `classname` [`inheritance`] ":" `suite`
inheritance: "(" [`argument_list`] ")"
classname: `identifier`
Coroutine function definition
-----------------------------
-.. productionlist::
+.. productionlist:: python-grammar
async_funcdef: [`decorators`] "async" "def" `funcname` "(" [`parameter_list`] ")"
: ["->" `expression`] ":" `suite`
The :keyword:`!async for` statement
-----------------------------------
-.. productionlist::
+.. productionlist:: python-grammar
async_for_stmt: "async" `for_stmt`
An :term:`asynchronous iterable` is able to call asynchronous code in its
The :keyword:`!async with` statement
------------------------------------
-.. productionlist::
+.. productionlist:: python-grammar
async_with_stmt: "async" `with_stmt`
An :term:`asynchronous context manager` is a :term:`context manager` that is
:ref:`faq-augmented-assignment-tuple-error`), but this behavior is in fact
part of the data model.
+ .. note::
+
+ Due to a bug in the dispatching mechanism for ``**=``, a class that
+ defines :meth:`__ipow__` but returns ``NotImplemented`` would fail to
+ fall back to ``x.__pow__(y)`` and ``y.__rpow__(x)``. This bug is fixed
+ in Python 3.10.
+
.. method:: object.__neg__(self)
object.__pos__(self)
-----------------
An :term:`awaitable` object generally implements an :meth:`__await__` method.
-:term:`Coroutine` objects returned from :keyword:`async def` functions
+:term:`Coroutine objects <coroutine>` returned from :keyword:`async def` functions
are awaitable.
.. note::
Coroutine Objects
-----------------
-:term:`Coroutine` objects are :term:`awaitable` objects.
+:term:`Coroutine objects <coroutine>` are :term:`awaitable` objects.
A coroutine's execution can be controlled by calling :meth:`__await__` and
iterating over the result. When the coroutine has finished executing and
returns, the iterator raises :exc:`StopIteration`, and the exception's
be used to describe syntax, not lexical analysis. When (one alternative of) a
syntax rule has the form
-.. productionlist:: *
+.. productionlist:: python-grammar
name: `othername`
and no semantics are given, the semantics of this form of ``name`` are the same
identifiers or literals. Forms enclosed in parentheses, brackets or braces are
also categorized syntactically as atoms. The syntax for atoms is:
-.. productionlist::
+.. productionlist:: python-grammar
atom: `identifier` | `literal` | `enclosure`
enclosure: `parenth_form` | `list_display` | `dict_display` | `set_display`
: | `generator_expression` | `yield_atom`
Python supports string and bytes literals and various numeric literals:
-.. productionlist::
+.. productionlist:: python-grammar
literal: `stringliteral` | `bytesliteral`
: | `integer` | `floatnumber` | `imagnumber`
A parenthesized form is an optional expression list enclosed in parentheses:
-.. productionlist::
+.. productionlist:: python-grammar
parenth_form: "(" [`starred_expression`] ")"
A parenthesized expression list yields whatever that expression list yields: if
Common syntax elements for comprehensions are:
-.. productionlist::
+.. productionlist:: python-grammar
comprehension: `assignment_expression` `comp_for`
comp_for: ["async"] "for" `target_list` "in" `or_test` [`comp_iter`]
comp_iter: `comp_for` | `comp_if`
A list display is a possibly empty series of expressions enclosed in square
brackets:
-.. productionlist::
+.. productionlist:: python-grammar
list_display: "[" [`starred_list` | `comprehension`] "]"
A list display yields a new list object, the contents being specified by either
A set display is denoted by curly braces and distinguishable from dictionary
displays by the lack of colons separating keys and values:
-.. productionlist::
+.. productionlist:: python-grammar
set_display: "{" (`starred_list` | `comprehension`) "}"
A set display yields a new mutable set object, the contents being specified by
A dictionary display is a possibly empty series of key/datum pairs enclosed in
curly braces:
-.. productionlist::
+.. productionlist:: python-grammar
dict_display: "{" [`key_datum_list` | `dict_comprehension`] "}"
key_datum_list: `key_datum` ("," `key_datum`)* [","]
key_datum: `expression` ":" `expression` | "**" `or_expr`
A generator expression is a compact generator notation in parentheses:
-.. productionlist::
+.. productionlist:: python-grammar
generator_expression: "(" `expression` `comp_for` ")"
A generator expression yields a new generator object. Its syntax is the same as
pair: yield; expression
pair: generator; function
-.. productionlist::
+.. productionlist:: python-grammar
yield_atom: "(" `yield_expression` ")"
yield_expression: "yield" [`expression_list` | "from" `expression`]
Primaries represent the most tightly bound operations of the language. Their
syntax is:
-.. productionlist::
+.. productionlist:: python-grammar
primary: `atom` | `attributeref` | `subscription` | `slicing` | `call`
An attribute reference is a primary followed by a period and a name:
-.. productionlist::
+.. productionlist:: python-grammar
attributeref: `primary` "." `identifier`
.. index::
A subscription selects an item of a sequence (string, tuple or list) or mapping
(dictionary) object:
-.. productionlist::
+.. productionlist:: python-grammar
subscription: `primary` "[" `expression_list` "]"
The primary must evaluate to an object that supports subscription (lists or
or list). Slicings may be used as expressions or as targets in assignment or
:keyword:`del` statements. The syntax for a slicing:
-.. productionlist::
+.. productionlist:: python-grammar
slicing: `primary` "[" `slice_list` "]"
slice_list: `slice_item` ("," `slice_item`)* [","]
slice_item: `expression` | `proper_slice`
A call calls a callable object (e.g., a :term:`function`) with a possibly empty
series of :term:`arguments <argument>`:
-.. productionlist::
+.. productionlist:: python-grammar
call: `primary` "(" [`argument_list` [","] | `comprehension`] ")"
argument_list: `positional_arguments` ["," `starred_and_keywords`]
: ["," `keywords_arguments`]
Suspend the execution of :term:`coroutine` on an :term:`awaitable` object.
Can only be used inside a :term:`coroutine function`.
-.. productionlist::
+.. productionlist:: python-grammar
await_expr: "await" `primary`
.. versionadded:: 3.5
The power operator binds more tightly than unary operators on its left; it binds
less tightly than unary operators on its right. The syntax is:
-.. productionlist::
+.. productionlist:: python-grammar
power: (`await_expr` | `primary`) ["**" `u_expr`]
Thus, in an unparenthesized sequence of power and unary operators, the operators
All unary arithmetic and bitwise operations have the same priority:
-.. productionlist::
+.. productionlist:: python-grammar
u_expr: `power` | "-" `u_expr` | "+" `u_expr` | "~" `u_expr`
.. index::
from the power operator, there are only two levels, one for multiplicative
operators and one for additive operators:
-.. productionlist::
+.. productionlist:: python-grammar
m_expr: `u_expr` | `m_expr` "*" `u_expr` | `m_expr` "@" `m_expr` |
: `m_expr` "//" `u_expr` | `m_expr` "/" `u_expr` |
: `m_expr` "%" `u_expr`
The shifting operations have lower priority than the arithmetic operations:
-.. productionlist::
+.. productionlist:: python-grammar
shift_expr: `a_expr` | `shift_expr` ("<<" | ">>") `a_expr`
These operators accept integers as arguments. They shift the first argument to
Each of the three bitwise operations has a different priority level:
-.. productionlist::
+.. productionlist:: python-grammar
and_expr: `shift_expr` | `and_expr` "&" `shift_expr`
xor_expr: `and_expr` | `xor_expr` "^" `and_expr`
or_expr: `xor_expr` | `or_expr` "|" `xor_expr`
C, expressions like ``a < b < c`` have the interpretation that is conventional
in mathematics:
-.. productionlist::
+.. productionlist:: python-grammar
comparison: `or_expr` (`comp_operator` `or_expr`)*
comp_operator: "<" | ">" | "==" | ">=" | "<=" | "!="
: | "is" ["not"] | ["not"] "in"
pair: Conditional; expression
pair: Boolean; operation
-.. productionlist::
+.. productionlist:: python-grammar
or_test: `and_test` | `or_test` "or" `and_test`
and_test: `not_test` | `and_test` "and" `not_test`
not_test: `comparison` | "not" `not_test`
Assignment expressions
======================
-.. productionlist::
+.. productionlist:: python-grammar
assignment_expression: [`identifier` ":="] `expression`
-.. TODO: BPO-39868
+An assignment expression (sometimes also called a "named expression" or
+"walrus") assigns an :token:`expression` to an :token:`identifier`, while also
+returning the value of the :token:`expression`.
-See :pep:`572` for more details about assignment expressions.
+One common use case is when handling matched regular expressions:
+
+.. code-block:: python
+
+ if matching := pattern.search(data):
+ do_something(matching)
+
+Or, when processing a file stream in chunks:
+
+.. code-block:: python
+
+ while chunk := file.read(9000):
+ process(chunk)
+
+.. versionadded:: 3.8
+ See :pep:`572` for more details about assignment expressions.
.. _if_expr:
single: if; conditional expression
single: else; conditional expression
-.. productionlist::
+.. productionlist:: python-grammar
conditional_expression: `or_test` ["if" `or_test` "else" `expression`]
expression: `conditional_expression` | `lambda_expr`
expression_nocond: `or_test` | `lambda_expr_nocond`
pair: anonymous; function
single: : (colon); lambda expression
-.. productionlist::
+.. productionlist:: python-grammar
lambda_expr: "lambda" [`parameter_list`] ":" `expression`
lambda_expr_nocond: "lambda" [`parameter_list`] ":" `expression_nocond`
pair: expression; list
single: , (comma); expression list
-.. productionlist::
+.. productionlist:: python-grammar
expression_list: `expression` ("," `expression`)* [","]
starred_list: `starred_item` ("," `starred_item`)* [","]
starred_expression: `expression` | (`starred_item` ",")* [`starred_item`]
The descriptions of lexical analysis and syntax use a modified BNF grammar
notation. This uses the following style of definition:
-.. productionlist:: *
+.. productionlist:: notation
name: `lc_letter` (`lc_letter` | "_")*
lc_letter: "a"..."z"
Identifiers are unlimited in length. Case is significant.
-.. productionlist::
+.. productionlist:: python-grammar
identifier: `xid_start` `xid_continue`*
id_start: <all characters in general categories Lu, Ll, Lt, Lm, Lo, Nl, the underscore, and characters with the Other_ID_Start property>
id_continue: <all characters in `id_start`, plus characters in the categories Mn, Mc, Nd, Pc and others with the Other_ID_Continue property>
String literals are described by the following lexical definitions:
-.. productionlist::
+.. productionlist:: python-grammar
stringliteral: [`stringprefix`](`shortstring` | `longstring`)
stringprefix: "r" | "u" | "R" | "U" | "f" | "F"
: | "fr" | "Fr" | "fR" | "FR" | "rf" | "rF" | "Rf" | "RF"
longstringchar: <any source character except "\">
stringescapeseq: "\" <any source character>
-.. productionlist::
+.. productionlist:: python-grammar
bytesliteral: `bytesprefix`(`shortbytes` | `longbytes`)
bytesprefix: "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | "Rb" | "RB"
shortbytes: "'" `shortbytesitem`* "'" | '"' `shortbytesitem`* '"'
single: string; formatted literal
single: string; interpolated literal
single: f-string
+ single: fstring
single: {} (curly brackets); in formatted string literal
single: ! (exclamation); in formatted string literal
single: : (colon); in formatted string literal
+ single: = (equals); for help in debugging using string literals
.. _f-strings:
Formatted string literals
a literal is also marked as a raw string). After decoding, the grammar
for the contents of the string is:
-.. productionlist::
+.. productionlist:: python-grammar
f_string: (`literal_char` | "{{" | "}}" | `replacement_field`)*
- replacement_field: "{" `f_expression` ["!" `conversion`] [":" `format_spec`] "}"
+ replacement_field: "{" `f_expression` ["="] ["!" `conversion`] [":" `format_spec`] "}"
f_expression: (`conditional_expression` | "*" `or_expr`)
: ("," `conditional_expression` | "," "*" `or_expr`)* [","]
: | `yield_expression`
except that any doubled curly braces ``'{{'`` or ``'}}'`` are replaced
with the corresponding single curly brace. A single opening curly
bracket ``'{'`` marks a replacement field, which starts with a
-Python expression. After the expression, there may be a conversion field,
-introduced by an exclamation point ``'!'``. A format specifier may also
-be appended, introduced by a colon ``':'``. A replacement field ends
-with a closing curly bracket ``'}'``.
+Python expression. To display both the expression text and its value after
+evaluation, (useful in debugging), an equal sign ``'='`` may be added after the
+expression. A conversion field, introduced by an exclamation point ``'!'`` may
+follow. A format specifier may also be appended, introduced by a colon ``':'``.
+A replacement field ends with a closing curly bracket ``'}'``.
Expressions in formatted string literals are treated like regular
Python expressions surrounded by parentheses, with a few exceptions.
containing an :keyword:`async for` clause were illegal in the expressions
in formatted string literals due to a problem with the implementation.
+When the equal sign ``'='`` is provided, the output will have the expression
+text, the ``'='`` and the evaluated value. Spaces after the opening brace
+``'{'``, within the expression and after the ``'='`` are all retained in the
+output. By default, the ``'='`` causes the :func:`repr` of the expression to be
+provided, unless there is a format specified. When a format is specified it
+defaults to the :func:`str` of the expression unless a conversion ``'!r'`` is
+declared.
+
+.. versionadded:: 3.8
+ The equal sign ``'='``.
+
If a conversion is specified, the result of evaluating the expression
is converted before formatting. Conversion ``'!s'`` calls :func:`str` on
the result, ``'!r'`` calls :func:`repr`, and ``'!a'`` calls :func:`ascii`.
>>> today = datetime(year=2017, month=1, day=27)
>>> f"{today:%B %d, %Y}" # using date format specifier
'January 27, 2017'
+ >>> f"{today=:%B %d, %Y}" # using date format specifier and debugging
+ 'today=January 27, 2017'
>>> number = 1024
>>> f"{number:#0x}" # using integer format specifier
'0x400'
+ >>> foo = "bar"
+ >>> f"{ foo = }" # preserves whitespace
+ " foo = 'bar'"
+ >>> line = "The mill's closed"
+ >>> f"{line = }"
+ 'line = "The mill\'s closed"'
+ >>> f"{line = :20}"
+ "line = The mill's closed "
+ >>> f"{line = !r:20}"
+ 'line = "The mill\'s closed" '
+
A consequence of sharing the same syntax as regular string literals is
that characters in the replacement fields must not conflict with the
Integer literals are described by the following lexical definitions:
-.. productionlist::
+.. productionlist:: python-grammar
integer: `decinteger` | `bininteger` | `octinteger` | `hexinteger`
decinteger: `nonzerodigit` (["_"] `digit`)* | "0"+ (["_"] "0")*
bininteger: "0" ("b" | "B") (["_"] `bindigit`)+
Floating point literals are described by the following lexical definitions:
-.. productionlist::
+.. productionlist:: python-grammar
floatnumber: `pointfloat` | `exponentfloat`
pointfloat: [`digitpart`] `fraction` | `digitpart` "."
exponentfloat: (`digitpart` | `pointfloat`) `exponent`
Imaginary literals are described by the following lexical definitions:
-.. productionlist::
+.. productionlist:: python-grammar
imagnumber: (`floatnumber` | `digitpart`) ("j" | "J")
An imaginary literal yields a complex number with a real part of 0.0. Complex
statements may occur on a single line separated by semicolons. The syntax for
simple statements is:
-.. productionlist::
+.. productionlist:: python-grammar
simple_stmt: `expression_stmt`
: | `assert_stmt`
: | `assignment_stmt`
expression statements are allowed and occasionally useful. The syntax for an
expression statement is:
-.. productionlist::
+.. productionlist:: python-grammar
expression_stmt: `starred_expression`
An expression statement evaluates the expression list (which may be a single
Assignment statements are used to (re)bind names to values and to modify
attributes or items of mutable objects:
-.. productionlist::
+.. productionlist:: python-grammar
assignment_stmt: (`target_list` "=")+ (`starred_expression` | `yield_expression`)
target_list: `target` ("," `target`)* [","]
target: `identifier`
Augmented assignment is the combination, in a single statement, of a binary
operation and an assignment statement:
-.. productionlist::
+.. productionlist:: python-grammar
augmented_assignment_stmt: `augtarget` `augop` (`expression_list` | `yield_expression`)
augtarget: `identifier` | `attributeref` | `subscription` | `slicing`
augop: "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**="
:term:`Annotation <variable annotation>` assignment is the combination, in a single
statement, of a variable or attribute annotation and an optional assignment statement:
-.. productionlist::
+.. productionlist:: python-grammar
annotated_assignment_stmt: `augtarget` ":" `expression`
: ["=" (`starred_expression` | `yield_expression`)]
Assert statements are a convenient way to insert debugging assertions into a
program:
-.. productionlist::
+.. productionlist:: python-grammar
assert_stmt: "assert" `expression` ["," `expression`]
The simple form, ``assert expression``, is equivalent to ::
pair: null; operation
pair: null; operation
-.. productionlist::
+.. productionlist:: python-grammar
pass_stmt: "pass"
:keyword:`pass` is a null operation --- when it is executed, nothing happens.
pair: deletion; target
triple: deletion; target; list
-.. productionlist::
+.. productionlist:: python-grammar
del_stmt: "del" `target_list`
Deletion is recursively defined very similar to the way assignment is defined.
pair: function; definition
pair: class; definition
-.. productionlist::
+.. productionlist:: python-grammar
return_stmt: "return" [`expression_list`]
:keyword:`return` may only occur syntactically nested in a function definition,
single: function; generator
exception: StopIteration
-.. productionlist::
+.. productionlist:: python-grammar
yield_stmt: `yield_expression`
A :keyword:`yield` statement is semantically equivalent to a :ref:`yield
pair: raising; exception
single: __traceback__ (exception attribute)
-.. productionlist::
+.. productionlist:: python-grammar
raise_stmt: "raise" [`expression` ["from" `expression`]]
If no expressions are present, :keyword:`raise` re-raises the last exception
statement: while
pair: loop; statement
-.. productionlist::
+.. productionlist:: python-grammar
break_stmt: "break"
:keyword:`break` may only occur syntactically nested in a :keyword:`for` or
pair: loop; statement
keyword: finally
-.. productionlist::
+.. productionlist:: python-grammar
continue_stmt: "continue"
:keyword:`continue` may only occur syntactically nested in a :keyword:`for` or
exception: ImportError
single: , (comma); import statement
-.. productionlist::
+.. productionlist:: python-grammar
import_stmt: "import" `module` ["as" `identifier`] ("," `module` ["as" `identifier`])*
: | "from" `relative_module` "import" `identifier` ["as" `identifier`]
: ("," `identifier` ["as" `identifier`])*
features on a per-module basis before the release in which the feature becomes
standard.
-.. productionlist:: *
+.. productionlist:: python-grammar
future_stmt: "from" "__future__" "import" `feature` ["as" `identifier`]
: ("," `feature` ["as" `identifier`])*
: | "from" "__future__" "import" "(" `feature` ["as" `identifier`]
triple: global; name; binding
single: , (comma); identifier list
-.. productionlist::
+.. productionlist:: python-grammar
global_stmt: "global" `identifier` ("," `identifier`)*
The :keyword:`global` statement is a declaration which holds for the entire
.. index:: statement: nonlocal
single: , (comma); identifier list
-.. productionlist::
+.. productionlist:: python-grammar
nonlocal_stmt: "nonlocal" `identifier` ("," `identifier`)*
.. XXX add when implemented
All input read from non-interactive files has the same form:
-.. productionlist::
+.. productionlist:: python-grammar
file_input: (NEWLINE | `statement`)*
This syntax is used in the following situations:
Input in interactive mode is parsed using the following grammar:
-.. productionlist::
+.. productionlist:: python-grammar
interactive_input: [`stmt_list`] NEWLINE | `compound_stmt` NEWLINE
Note that a (top-level) compound statement must be followed by a blank line in
:func:`eval` is used for expression input. It ignores leading whitespace. The
string argument to :func:`eval` must have the following form:
-.. productionlist::
+.. productionlist:: python-grammar
eval_input: `expression_list` NEWLINE*
--- /dev/null
+# Requirements to build the Python documentation
+
+# Sphinx version is pinned so that new versions that introduce new warnings
+# won't suddenly cause build failures. Updating the version is fine as long
+# as no warnings are raised by doing so.
+sphinx==2.4.4
+
+blurb
+
+# The theme used by the documentation is stored separately, so we need
+# to install that as well.
+python-docs-theme
from sphinx.util.nodes import split_explicit_title
from sphinx.writers.text import TextWriter, TextTranslator
from sphinx.writers.latex import LaTeXTranslator
-from sphinx.domains.python import PyModulelevel, PyClassmember
+
+try:
+ from sphinx.domains.python import PyFunction, PyMethod
+except ImportError:
+ from sphinx.domains.python import PyClassmember as PyMethod
+ from sphinx.domains.python import PyModulelevel as PyFunction
# Support for checking for suspicious markup
return False
-class PyDecoratorFunction(PyDecoratorMixin, PyModulelevel):
+class PyDecoratorFunction(PyDecoratorMixin, PyFunction):
def run(self):
# a decorator function is a function after all
self.name = 'py:function'
- return PyModulelevel.run(self)
+ return PyFunction.run(self)
-class PyDecoratorMethod(PyDecoratorMixin, PyClassmember):
+# TODO: Use sphinx.domains.python.PyDecoratorMethod when possible
+class PyDecoratorMethod(PyDecoratorMixin, PyMethod):
def run(self):
self.name = 'py:method'
- return PyClassmember.run(self)
+ return PyMethod.run(self)
class PyCoroutineMixin(object):
return ret
-class PyCoroutineFunction(PyCoroutineMixin, PyModulelevel):
+class PyCoroutineFunction(PyCoroutineMixin, PyFunction):
def run(self):
self.name = 'py:function'
- return PyModulelevel.run(self)
+ return PyFunction.run(self)
-class PyCoroutineMethod(PyCoroutineMixin, PyClassmember):
+class PyCoroutineMethod(PyCoroutineMixin, PyMethod):
def run(self):
self.name = 'py:method'
- return PyClassmember.run(self)
+ return PyMethod.run(self)
-class PyAwaitableFunction(PyAwaitableMixin, PyClassmember):
+class PyAwaitableFunction(PyAwaitableMixin, PyFunction):
def run(self):
self.name = 'py:function'
- return PyClassmember.run(self)
+ return PyFunction.run(self)
-class PyAwaitableMethod(PyAwaitableMixin, PyClassmember):
+class PyAwaitableMethod(PyAwaitableMixin, PyMethod):
def run(self):
self.name = 'py:method'
- return PyClassmember.run(self)
+ return PyMethod.run(self)
-class PyAbstractMethod(PyClassmember):
+class PyAbstractMethod(PyMethod):
def handle_signature(self, sig, signode):
ret = super(PyAbstractMethod, self).handle_signature(sig, signode)
def run(self):
self.name = 'py:method'
- return PyClassmember.run(self)
+ return PyMethod.run(self)
# Support for documenting version of removal in deprecations
Generators
==========
-:term:`Generator`\s are a simple and powerful tool for creating iterators. They
+:term:`Generators <generator>` are a simple and powerful tool for creating iterators. They
are written like regular functions but use the :keyword:`yield` statement
whenever they want to return data. Each time :func:`next` is called on it, the
generator resumes where it left off (it remembers all the data values and which
... if num % 2 == 0:
... print("Found an even number", num)
... continue
- ... print("Found a number", num)
+ ... print("Found an odd number", num)
Found an even number 2
- Found a number 3
+ Found an odd number 3
Found an even number 4
- Found a number 5
+ Found an odd number 5
Found an even number 6
- Found a number 7
+ Found an odd number 7
Found an even number 8
- Found a number 9
+ Found an odd number 9
.. _tut-pass:
return 'name' in kwds
There is no possible call that will make it return ``True`` as the keyword ``'name'``
-will always to bind to the first parameter. For example::
+will always bind to the first parameter. For example::
>>> foo(1, **{'name': 2})
Traceback (most recent call last):
===============
* The mechanism for serializing execution of concurrently running Python threads
- (generally known as the :term:`GIL` or :term:`Global Interpreter Lock`) has
+ (generally known as the :term:`GIL` or Global Interpreter Lock) has
been rewritten. Among the objectives were more predictable switching
intervals and reduced overhead due to lock contention and the number of
ensuing system calls. The notion of a "check interval" to allow thread
:c:func:`PyUnicode_AsUTF8String`
* :c:func:`PyUnicode_EncodeUTF32`
* :c:func:`PyUnicode_EncodeUTF16`
-* :c:func:`PyUnicode_EncodeUnicodeEscape:` use
+* :c:func:`PyUnicode_EncodeUnicodeEscape` use
:c:func:`PyUnicode_AsUnicodeEscapeString`
-* :c:func:`PyUnicode_EncodeRawUnicodeEscape:` use
+* :c:func:`PyUnicode_EncodeRawUnicodeEscape` use
:c:func:`PyUnicode_AsRawUnicodeEscapeString`
* :c:func:`PyUnicode_EncodeLatin1`: use :c:func:`PyUnicode_AsLatin1String`
* :c:func:`PyUnicode_EncodeASCII`: use :c:func:`PyUnicode_AsASCIIString`
became evident that it would be beneficial for Python users, if the
standard library included the base definitions and tools for type annotations.
-:pep:`484` introduces a :term:`provisional module <provisional api>` to
+:pep:`484` introduces a :term:`provisional module <provisional API>` to
provide these standard definitions and tools, along with some conventions
for situations where annotations are not available.
typing
------
-The new :mod:`typing` :term:`provisional <provisional api>` module
+The new :mod:`typing` :term:`provisional <provisional API>` module
provides standard definitions and tools for function type annotations.
See :ref:`Type Hints <whatsnew-pep-484>` for more information.
asyncio
-------
-Since the :mod:`asyncio` module is :term:`provisional <provisional api>`,
+Since the :mod:`asyncio` module is :term:`provisional <provisional API>`,
all changes introduced in Python 3.5 have also been backported to Python 3.4.x.
Notable changes in the :mod:`asyncio` module since Python 3.4.0:
hook that will be called whenever a :term:`coroutine object <coroutine>`
is created by an :keyword:`async def` function. A corresponding
:func:`~sys.get_coroutine_wrapper` can be used to obtain a currently set
-wrapper. Both functions are :term:`provisional <provisional api>`,
+wrapper. Both functions are :term:`provisional <provisional API>`,
and are intended for debugging purposes only. (Contributed by Yury Selivanov
in :issue:`24017`.)
typing
------
-Since the :mod:`typing` module is :term:`provisional <provisional api>`,
+Since the :mod:`typing` module is :term:`provisional <provisional API>`,
all changes introduced in Python 3.6 have also been
backported to Python 3.5.x.
from __future__ import annotations
-It will become the default in Python 4.0.
+It will become the default in Python 3.10.
.. seealso::
:ref:`performance improvements <whatsnew37-asyncio-perf>`. Notable changes
include:
-* The new :term:`provisional <provisional api>` :func:`asyncio.run` function can
+* The new :term:`provisional <provisional API>` :func:`asyncio.run` function can
be used to run a coroutine from synchronous code by automatically creating and
destroying the event loop.
(Contributed by Yury Selivanov in :issue:`32314`.)
:meth:`~gettext.NullTranslations.set_output_charset`, and the *codeset*
parameter of functions :func:`~gettext.translation` and
:func:`~gettext.install` are also deprecated, since they are only used for
- for the ``l*gettext()`` functions.
+ the ``l*gettext()`` functions.
(Contributed by Serhiy Storchaka in :issue:`33710`.)
* The :meth:`~threading.Thread.isAlive()` method of :class:`threading.Thread`
PyObject *filename,
int lineno);
-/* Create a UnicodeEncodeError object */
+/* Create a UnicodeEncodeError object.
+ *
+ * TODO: This API will be removed in Python 3.11.
+ */
Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_Create(
const char *encoding, /* UTF-8 encoded string */
const Py_UNICODE *object,
const char *reason /* UTF-8 encoded string */
);
-/* Create a UnicodeTranslateError object */
+/* Create a UnicodeTranslateError object.
+ *
+ * TODO: This API will be removed in Python 3.11.
+ */
Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_Create(
const Py_UNICODE *object,
Py_ssize_t length,
/*--start constants--*/
#define PY_MAJOR_VERSION 3
#define PY_MINOR_VERSION 8
-#define PY_MICRO_VERSION 5
+#define PY_MICRO_VERSION 6
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL
#define PY_RELEASE_SERIAL 0
/* Version as a string */
-#define PY_VERSION "3.8.5"
+#define PY_VERSION "3.8.6"
/*--end constants--*/
/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.
B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
===============================================================
+Python software and documentation are licensed under the
+Python Software Foundation License Version 2.
+
+Starting with Python 3.8.6, examples, recipes, and other code in
+the documentation are dual licensed under the PSF License Version 2
+and the Zero-Clause BSD license.
+
+Some software incorporated into Python is under different licenses.
+The licenses are listed with code falling under that license.
+
+
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
--------------------------------------------
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ZERO-CLAUSE BSD LICENSE FOR CODE IN THE PYTHON DOCUMENTATION
+----------------------------------------------------------------------
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
# code.h and used by compile.h, so that an editor search will find them here.
# However, they're not exported in __all__, because they don't really belong to
# this module.
-CO_NESTED = 0x0010 # nested_scopes
-CO_GENERATOR_ALLOWED = 0 # generators (obsolete, was 0x1000)
-CO_FUTURE_DIVISION = 0x20000 # division
-CO_FUTURE_ABSOLUTE_IMPORT = 0x40000 # perform absolute imports by default
-CO_FUTURE_WITH_STATEMENT = 0x80000 # with statement
-CO_FUTURE_PRINT_FUNCTION = 0x100000 # print function
-CO_FUTURE_UNICODE_LITERALS = 0x200000 # unicode string literals
+CO_NESTED = 0x0010 # nested_scopes
+CO_GENERATOR_ALLOWED = 0 # generators (obsolete, was 0x1000)
+CO_FUTURE_DIVISION = 0x20000 # division
+CO_FUTURE_ABSOLUTE_IMPORT = 0x40000 # perform absolute imports by default
+CO_FUTURE_WITH_STATEMENT = 0x80000 # with statement
+CO_FUTURE_PRINT_FUNCTION = 0x100000 # print function
+CO_FUTURE_UNICODE_LITERALS = 0x200000 # unicode string literals
CO_FUTURE_BARRY_AS_BDFL = 0x400000
-CO_FUTURE_GENERATOR_STOP = 0x800000 # StopIteration becomes RuntimeError in generators
-CO_FUTURE_ANNOTATIONS = 0x1000000 # annotations become strings at runtime
+CO_FUTURE_GENERATOR_STOP = 0x800000 # StopIteration becomes RuntimeError in generators
+CO_FUTURE_ANNOTATIONS = 0x1000000 # annotations become strings at runtime
+
class _Feature:
+
def __init__(self, optionalRelease, mandatoryRelease, compiler_flag):
self.optional = optionalRelease
self.mandatory = mandatoryRelease
This is a 5-tuple, of the same form as sys.version_info.
"""
-
return self.optional
def getMandatoryRelease(self):
This is a 5-tuple, of the same form as sys.version_info, or, if
the feature was dropped, is None.
"""
-
return self.mandatory
def __repr__(self):
self.mandatory,
self.compiler_flag))
+
nested_scopes = _Feature((2, 1, 0, "beta", 1),
(2, 2, 0, "alpha", 0),
CO_NESTED)
CO_FUTURE_GENERATOR_STOP)
annotations = _Feature((3, 7, 0, "beta", 1),
- (4, 0, 0, "alpha", 0),
+ (3, 10, 0, "alpha", 0),
CO_FUTURE_ANNOTATIONS)
attributes) from *old_node* to *new_node* if possible, and return *new_node*.
"""
for attr in 'lineno', 'col_offset', 'end_lineno', 'end_col_offset':
- if attr in old_node._attributes and attr in new_node._attributes \
- and hasattr(old_node, attr):
- setattr(new_node, attr, getattr(old_node, attr))
+ if attr in old_node._attributes and attr in new_node._attributes:
+ value = getattr(old_node, attr, None)
+ # end_lineno and end_col_offset are optional attributes, and they
+ # should be copied whether the value is None or not.
+ if value is not None or (
+ hasattr(old_node, attr) and attr.startswith("end_")
+ ):
+ setattr(new_node, attr, value)
return new_node
for child in walk(node):
if 'lineno' in child._attributes:
child.lineno = getattr(child, 'lineno', 0) + n
- if 'end_lineno' in child._attributes:
- child.end_lineno = getattr(child, 'end_lineno', 0) + n
+ if (
+ "end_lineno" in child._attributes
+ and (end_lineno := getattr(child, "end_lineno", 0)) is not None
+ ):
+ child.end_lineno = end_lineno + n
return node
def call_soon_threadsafe(self, callback, *args):
raise NotImplementedError
- async def run_in_executor(self, executor, func, *args):
+ def run_in_executor(self, executor, func, *args):
raise NotImplementedError
def set_default_executor(self, executor):
try:
if f is not None:
f.result() # may raise
+ if self._self_reading_future is not f:
+ # When we scheduled this Future, we assigned it to
+ # _self_reading_future. If it's not there now, something has
+ # tried to cancel the loop while this callback was still in the
+ # queue (see windows_events.ProactorEventLoop.run_forever). In
+ # that case stop here instead of continuing to schedule a new
+ # iteration.
+ return
f = self._proactor.recv(self._ssock, 4096)
except exceptions.CancelledError:
# _close_self_pipe() has been called, stop waiting for data
f.add_done_callback(self._loop_self_reading)
def _write_to_self(self):
+ # This may be called from a different thread, possibly after
+ # _close_self_pipe() has been called or even while it is
+ # running. Guard for self._csock being None or closed. When
+ # a socket is closed, send() raises OSError (with errno set to
+ # EBADF, but let's not rely on the exact error code).
+ csock = self._csock
+ if csock is None:
+ return
+
try:
- self._csock.send(b'\0')
+ csock.send(b'\0')
except OSError:
if self._debug:
logger.debug("Fail to write a null byte into the "
from . import tasks
-def run(main, *, debug=False):
+def run(main, *, debug=None):
"""Execute the coroutine and return the result.
This function runs the passed coroutine, taking care of
loop = events.new_event_loop()
try:
events.set_event_loop(loop)
- loop.set_debug(debug)
+ if debug is not None:
+ loop.set_debug(debug)
return loop.run_until_complete(main)
finally:
try:
# a socket is closed, send() raises OSError (with errno set to
# EBADF, but let's not rely on the exact error code).
csock = self._csock
- if csock is not None:
- try:
- csock.send(b'\0')
- except OSError:
- if self._debug:
- logger.debug("Fail to write a null byte into the "
- "self-pipe socket",
- exc_info=True)
+ if csock is None:
+ return
+
+ try:
+ csock.send(b'\0')
+ except OSError:
+ if self._debug:
+ logger.debug("Fail to write a null byte into the "
+ "self-pipe socket",
+ exc_info=True)
def _start_serving(self, protocol_factory, sock,
sslcontext=None, server=None, backlog=100,
if fut.done():
return fut.result()
- fut.cancel()
- raise exceptions.TimeoutError()
+ await _cancel_and_wait(fut, loop=loop)
+ try:
+ fut.result()
+ except exceptions.CancelledError as exc:
+ raise exceptions.TimeoutError() from exc
+ else:
+ raise exceptions.TimeoutError()
waiter = loop.create_future()
timeout_handle = loop.call_later(timeout, _release_waiter, waiter)
try:
await waiter
except exceptions.CancelledError:
- fut.remove_done_callback(cb)
- fut.cancel()
- raise
+ if fut.done():
+ return fut.result()
+ else:
+ fut.remove_done_callback(cb)
+ fut.cancel()
+ raise
if fut.done():
return fut.result()
Buffered data will be flushed asynchronously. No more data
will be received. After all buffered data is flushed, the
- protocol's connection_lost() method will (eventually) called
- with None as its argument.
+ protocol's connection_lost() method will (eventually) be
+ called with None as its argument.
"""
raise NotImplementedError
if self._self_reading_future is not None:
ov = self._self_reading_future._ov
self._self_reading_future.cancel()
- # self_reading_future was just cancelled so it will never be signalled
- # Unregister it otherwise IocpProactor.close will wait for it forever
+ # self_reading_future was just cancelled so if it hasn't been
+ # finished yet, it never will be (it's possible that it has
+ # already finished and its callback is waiting in the queue,
+ # where it could still happen if the event loop is restarted).
+ # Unregister it otherwise IocpProactor.close will wait for it
+ # forever
if ov is not None:
self._proactor._unregister(ov)
self._self_reading_future = None
else:
ov.ReadFileInto(conn.fileno(), buf)
except BrokenPipeError:
- return self._result(b'')
+ return self._result(0)
def finish_recv(trans, key, ov):
try:
except SyntaxError as err:
pass
- # Suppress warnings after the first compile to avoid duplication.
+ # Catch syntax warnings after the first compile
+ # to emit warnings (SyntaxWarning, DeprecationWarning) at most once.
with warnings.catch_warnings():
- warnings.simplefilter("ignore")
+ warnings.simplefilter("error")
+
try:
code1 = compiler(source + "\n", filename, symbol)
except SyntaxError as e:
import argparse
parser = argparse.ArgumentParser()
- parser.add_argument('infile', type=argparse.FileType(), nargs='?', default='-')
+ parser.add_argument('infile', type=argparse.FileType('rb'), nargs='?', default='-')
args = parser.parse_args()
with args.infile as infile:
source = infile.read()
__all__ = ["version", "bootstrap"]
-_SETUPTOOLS_VERSION = "47.1.0"
+_SETUPTOOLS_VERSION = "49.2.1"
-_PIP_VERSION = "20.1.1"
+_PIP_VERSION = "20.2.1"
_PROJECTS = [
("setuptools", _SETUPTOOLS_VERSION, "py3"),
# enum overwriting a descriptor?
raise TypeError('%r already defined as: %r' % (key, self[key]))
if isinstance(value, auto):
- self._auto_called = True
if value.value == _auto_null:
value.value = self._generate_next_value(key, 1, len(self._member_names), self._last_values[:])
+ self._auto_called = True
value = value.value
self._member_names.append(key)
self._last_values.append(value)
"""Metaclass for Enum"""
@classmethod
def __prepare__(metacls, cls, bases):
+ # check that previous enum members do not exist
+ metacls._check_for_existing_members(cls, bases)
# create the namespace dict
enum_dict = _EnumDict()
# inherit previous flags and _generate_next_value_ function
- member_type, first_enum = metacls._get_mixins_(bases)
+ member_type, first_enum = metacls._get_mixins_(cls, bases)
if first_enum is not None:
enum_dict['_generate_next_value_'] = getattr(first_enum, '_generate_next_value_', None)
return enum_dict
ignore = classdict['_ignore_']
for key in ignore:
classdict.pop(key, None)
- member_type, first_enum = metacls._get_mixins_(bases)
+ member_type, first_enum = metacls._get_mixins_(cls, bases)
__new__, save_new, use_args = metacls._find_new_(classdict, member_type,
first_enum)
# double check that repr and friends are not the mixin's or various
# things break (such as pickle)
+ # however, if the method is defined in the Enum itself, don't replace
+ # it
for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'):
+ if name in classdict:
+ continue
class_method = getattr(enum_class, name)
obj_method = getattr(member_type, name, None)
enum_method = getattr(first_enum, name, None)
"""
metacls = cls.__class__
bases = (cls, ) if type is None else (type, cls)
- _, first_enum = cls._get_mixins_(bases)
+ _, first_enum = cls._get_mixins_(cls, bases)
classdict = metacls.__prepare__(class_name, bases)
# special processing needed for names?
return cls._convert_(*args, **kwargs)
@staticmethod
- def _get_mixins_(bases):
+ def _check_for_existing_members(class_name, bases):
+ for chain in bases:
+ for base in chain.__mro__:
+ if issubclass(base, Enum) and base._member_names_:
+ raise TypeError("%s: cannot extend enumeration %r" % (class_name, base.__name__))
+
+ @staticmethod
+ def _get_mixins_(class_name, bases):
"""Returns the type for creating enum members, and the first inherited
enum class.
return object, Enum
def _find_data_type(bases):
+ data_types = []
for chain in bases:
+ candidate = None
for base in chain.__mro__:
if base is object:
continue
elif '__new__' in base.__dict__:
if issubclass(base, Enum):
continue
- return base
+ data_types.append(candidate or base)
+ break
+ elif not issubclass(base, Enum):
+ candidate = base
+ if len(data_types) > 1:
+ raise TypeError('%r: too many data types: %r' % (class_name, data_types))
+ elif data_types:
+ return data_types[0]
+ else:
+ return None
# ensure final parent class is an Enum derivative, find any concrete
# data type, and check that Enum has no members
@classmethod
def _missing_(cls, value):
- raise ValueError("%r is not a valid %s" % (value, cls.__name__))
+ return None
def __repr__(self):
return "<%s.%s: %r>" % (
# we can get strange results with the Enum name showing up instead of
# the value
- # pure Enum branch
- if self._member_type_ is object:
+ # pure Enum branch, or branch with __str__ explicitly overridden
+ str_overridden = type(self).__str__ != Enum.__str__
+ if self._member_type_ is object or str_overridden:
cls = str
val = str(self)
# mix-in branch
+What's New in IDLE 3.8.6
+Released on 2020-09-14?
+======================================
+
+
+bpo-35764: Rewrite the Calltips doc section.
+
+bpo-40181: In calltips, stop reminding that '/' marks the end of
+positional-only arguments.
+
+bpo-41468: Improve IDLE run crash error message (which users should
+never see).
+
+bpo-41373: Save files loaded with no line ending, as when blank, or
+different line endings, by setting its line ending to the system
+default. Fix regression in 3.8.4 and 3.9.0b4.
+
+
What's New in IDLE 3.8.5
Released on 2020-07-20
======================================
-
bpo-41300: Save files with non-ascii chars. Fix regression in
3.9.0b4 and 3.8.4.
+
What's New in IDLE 3.8.4
Released on 2020-06-30
======================================
functions (default shortcuts Alt-T and Alt-U) were mistakenly disabled
in 3.7.5 and 3.8.0.
-bpo-4360: Add an option to toggle IDLE's cursor blink for shell,
+bpo-4630: Add an option to toggle IDLE's cursor blink for shell,
editor, and output windows. See Settings, General, Window Preferences,
-Cursor Blink. Patch by Zachary Spytz.
+Cursor Blink. Patch by Zackery Spytz.
bpo-26353: Stop adding newline when saving an IDLE shell window.
_first_param = re.compile(r'(?<=\()\w*\,?\s*')
_default_callable_argspec = "See source or doc"
_invalid_method = "invalid method signature"
-_argument_positional = " # '/' marks preceding args as positional-only."
def get_argspec(ob):
'''Return a string describing the signature of a callable object, or ''.
else:
argspec = ''
- if '/' in argspec and len(argspec) < _MAX_COLS - len(_argument_positional):
- # Add explanation TODO remove after 3.7, before 3.9.
- argspec += _argument_positional
if isinstance(fob, type) and argspec == '()':
# If fob has no argument, use default callable argspec.
argspec = _default_callable_argspec
large number of milliseconds, such as 100000000.) For imported module
names or class or function attributes, type ‘.’.
For filenames in the root directory, type <a class="reference internal" href="os.html#os.sep" title="os.sep"><code class="xref py py-data docutils literal notranslate"><span class="pre">os.sep</span></code></a> or
-data:<cite>os.altsep</cite> immediately after an opening quote. (On Windows,
+<a class="reference internal" href="os.html#os.altsep" title="os.altsep"><code class="xref py py-data docutils literal notranslate"><span class="pre">os.altsep</span></code></a> immediately after an opening quote. (On Windows,
one can specify a drive first.) Move into subdirectories by typing a
directory name and a separator.</p>
-<p>Instead of waiting, or after a box is closed. open a completion box
+<p>Instead of waiting, or after a box is closed, open a completion box
immediately with Show Completions on the Edit menu. The default hot
key is <kbd class="kbd docutils literal notranslate">C-space</kbd>. If one types a prefix for the desired name
-before opening the box, the first match is displayed.
+before opening the box, the first match or near miss is made visible.
The result is the same as if one enters a prefix
after the box is displayed. Show Completions after a quote completes
filenames in the current directory instead of a root directory.</p>
</div>
<div class="section" id="calltips">
<span id="id4"></span><h3>Calltips<a class="headerlink" href="#calltips" title="Permalink to this headline">¶</a></h3>
-<p>A calltip is shown when one types <kbd class="kbd docutils literal notranslate">(</kbd> after the name of an <em>accessible</em>
-function. A name expression may include dots and subscripts. A calltip
-remains until it is clicked, the cursor is moved out of the argument area,
-or <kbd class="kbd docutils literal notranslate">)</kbd> is typed. When the cursor is in the argument part of a definition,
-the menu or shortcut display a calltip.</p>
-<p>A calltip consists of the function signature and the first line of the
-docstring. For builtins without an accessible signature, the calltip
-consists of all lines up the fifth line or the first blank line. These
-details may change.</p>
-<p>The set of <em>accessible</em> functions depends on what modules have been imported
-into the user process, including those imported by Idle itself,
-and what definitions have been run, all since the last restart.</p>
+<p>A calltip is shown automatically when one types <kbd class="kbd docutils literal notranslate">(</kbd> after the name
+of an <em>accessible</em> function. A function name expression may include
+dots and subscripts. A calltip remains until it is clicked, the cursor
+is moved out of the argument area, or <kbd class="kbd docutils literal notranslate">)</kbd> is typed. Whenever the
+cursor is in the argument part of a definition, select Edit and “Show
+Call Tip” on the menu or enter its shortcut to display a calltip.</p>
+<p>The calltip consists of the function’s signature and docstring up to
+the latter’s first blank line or the fifth non-blank line. (Some builtin
+functions lack an accessible signature.) A ‘/’ or ‘*’ in the signature
+indicates that the preceding or following arguments are passed by
+position or name (keyword) only. Details are subject to change.</p>
+<p>In Shell, the accessible functions depends on what modules have been
+imported into the user process, including those imported by Idle itself,
+and which definitions have been run, all since the last restart.</p>
<p>For example, restart the Shell and enter <code class="docutils literal notranslate"><span class="pre">itertools.count(</span></code>. A calltip
-appears because Idle imports itertools into the user process for its own use.
-(This could change.) Enter <code class="docutils literal notranslate"><span class="pre">turtle.write(</span></code> and nothing appears. Idle does
-not import turtle. The menu or shortcut do nothing either. Enter
-<code class="docutils literal notranslate"><span class="pre">import</span> <span class="pre">turtle</span></code> and then <code class="docutils literal notranslate"><span class="pre">turtle.write(</span></code> will work.</p>
-<p>In an editor, import statements have no effect until one runs the file. One
-might want to run a file after writing the import statements at the top,
-or immediately run an existing file before editing.</p>
+appears because Idle imports itertools into the user process for its own
+use. (This could change.) Enter <code class="docutils literal notranslate"><span class="pre">turtle.write(</span></code> and nothing appears.
+Idle does not itself import turtle. The menu entry and shortcut also do
+nothing. Enter <code class="docutils literal notranslate"><span class="pre">import</span> <span class="pre">turtle</span></code>. Thereafter, <code class="docutils literal notranslate"><span class="pre">turtle.write(</span></code>
+will display a calltip.</p>
+<p>In an editor, import statements have no effect until one runs the file.
+One might want to run a file after writing import statements, after
+adding function definitions, or after opening an existing file.</p>
</div>
<div class="section" id="code-context">
<span id="id5"></span><h3>Code Context<a class="headerlink" href="#code-context" title="Permalink to this headline">¶</a></h3>
<br />
<br />
- Last updated on Jul 08, 2020.
+ Last updated on Sep 22, 2020.
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
<br />
if List.__doc__ is not None:
tiptest(List,
- f'(iterable=(), /){calltip._argument_positional}'
+ f'(iterable=(), /)'
f'\n{List.__doc__}')
tiptest(list.__new__,
'(*args, **kwargs)\n'
'Create and return a new object. '
'See help(type) for accurate signature.')
tiptest(list.__init__,
- '(self, /, *args, **kwargs)'
- + calltip._argument_positional + '\n' +
+ '(self, /, *args, **kwargs)\n'
'Initialize self. See help(type(self)) for accurate signature.')
- append_doc = (calltip._argument_positional
- + "\nAppend object to the end of the list.")
+ append_doc = "\nAppend object to the end of the list."
tiptest(list.append, '(self, object, /)' + append_doc)
tiptest(List.append, '(self, object, /)' + append_doc)
tiptest([].append, '(object, /)' + append_doc)
-"Test run, coverage 42%."
+"Test run, coverage 49%."
from idlelib import run
import unittest
from unittest import mock
-from test.support import captured_stderr
+from idlelib.idle_test.mock_idle import Func
+from test.support import captured_output, captured_stderr
import io
import sys
self.assertRaises(TypeError, f.close, 1)
-class TestSysRecursionLimitWrappers(unittest.TestCase):
+class RecursionLimitTest(unittest.TestCase):
+ # Test (un)install_recursionlimit_wrappers and fixdoc.
def test_bad_setrecursionlimit_calls(self):
run.install_recursionlimit_wrappers()
run.install_recursionlimit_wrappers()
self.addCleanup(run.uninstall_recursionlimit_wrappers)
- # check that setting the recursion limit works
+ # Check that setting the recursion limit works.
orig_reclimit = sys.getrecursionlimit()
self.addCleanup(sys.setrecursionlimit, orig_reclimit)
sys.setrecursionlimit(orig_reclimit + 3)
- # check that the new limit is returned by sys.getrecursionlimit()
+ # Check that the new limit is returned by sys.getrecursionlimit().
new_reclimit = sys.getrecursionlimit()
self.assertEqual(new_reclimit, orig_reclimit + 3)
self.assertEqual(new_reclimit, orig_reclimit)
def test_fixdoc(self):
+ # Put here until better place for miscellaneous test.
def func(): "docstring"
run.fixdoc(func, "more")
self.assertEqual(func.__doc__, "docstring\n\nmore")
self.assertEqual(func.__doc__, "more")
+class HandleErrorTest(unittest.TestCase):
+ # Method of MyRPCServer
+ def test_fatal_error(self):
+ eq = self.assertEqual
+ with captured_output('__stderr__') as err,\
+ mock.patch('idlelib.run.thread.interrupt_main',
+ new_callable=Func) as func:
+ try:
+ raise EOFError
+ except EOFError:
+ run.MyRPCServer.handle_error(None, 'abc', '123')
+ eq(run.exit_now, True)
+ run.exit_now = False
+ eq(err.getvalue(), '')
+
+ try:
+ raise IndexError
+ except IndexError:
+ run.MyRPCServer.handle_error(None, 'abc', '123')
+ eq(run.quitting, True)
+ run.quitting = False
+ msg = err.getvalue()
+ self.assertIn('abc', msg)
+ self.assertIn('123', msg)
+ self.assertIn('IndexError', msg)
+ eq(func.called, 2)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
parent=self.text)
return False
+ if not isinstance(eol_convention, str):
+ # If the file does not contain line separators, it is None.
+ # If the file contains mixed line separators, it is a tuple.
+ if eol_convention is not None:
+ tkMessageBox.showwarning("Mixed Newlines",
+ "Mixed newlines detected.\n"
+ "The file will be changed on save.",
+ parent=self.text)
+ converted = True
+ eol_convention = os.linesep # default
+
self.text.delete("1.0", "end")
self.set_filename(None)
self.fileencoding = fileencoding
thread.interrupt_main()
except:
erf = sys.__stderr__
- print('\n' + '-'*40, file=erf)
- print('Unhandled server exception!', file=erf)
- print('Thread: %s' % threading.current_thread().name, file=erf)
- print('Client Address: ', client_address, file=erf)
- print('Request: ', repr(request), file=erf)
- traceback.print_exc(file=erf)
- print('\n*** Unrecoverable, server exiting!', file=erf)
- print('-'*40, file=erf)
+ print(textwrap.dedent(f"""
+ {'-'*40}
+ Unhandled exception in user code execution server!'
+ Thread: {threading.current_thread().name}
+ IDLE Client Address: {client_address}
+ Request: {request!r}
+ """), file=erf)
+ traceback.print_exc(limit=-20, file=erf)
+ print(textwrap.dedent(f"""
+ *** Unrecoverable, server exiting!
+
+ Users should never see this message; it is likely transient.
+ If this recurs, report this with a copy of the message
+ and an explanation of how to make it repeat.
+ {'-'*40}"""), file=erf)
quitting = True
thread.interrupt_main()
address: A string or integer representing the IP [& network].
'192.0.2.0/24'
'192.0.2.0/255.255.255.0'
- '192.0.0.2/0.0.0.255'
+ '192.0.2.0/0.0.0.255'
are all functionally the same in IPv4. Similarly,
'192.0.2.1'
'192.0.2.1/255.255.255.255'
"""
Set the target handler for this handler.
"""
- self.target = target
+ self.acquire()
+ try:
+ self.target = target
+ finally:
+ self.release()
def flush(self):
"""
raise ValueError("'size' must be a positive integer")
if create:
self._flags = _O_CREX | os.O_RDWR
+ if size == 0:
+ raise ValueError("'size' must be a positive number different from zero")
if name is None and not self._flags & os.O_EXCL:
raise ValueError("'name' can only be None if create=True")
def notify(self, n=1):
assert self._lock._semlock._is_mine(), 'lock is not owned'
assert not self._wait_semaphore.acquire(
- False), ('notify: Should not have been able to acquire'
+ False), ('notify: Should not have been able to acquire '
+ '_wait_semaphore')
# to take account of timeouts since last notify*() we subtract
# parent dir
path, _, _ = path.rpartition(sep)
continue
- newpath = path + sep + name
+ if path.endswith(sep):
+ newpath = path + name
+ else:
+ newpath = path + sep + name
if newpath in seen:
# Already seen this path
path = seen[newpath]
# _getval() already printed the error
return
code = None
- # Is it a function?
+ # Is it an instance method?
try:
- code = value.__code__
+ code = value.__func__.__code__
except Exception:
pass
if code:
- self.message('Function %s' % code.co_name)
+ self.message('Method %s' % code.co_name)
return
- # Is it an instance method?
+ # Is it a function?
try:
- code = value.__func__.__code__
+ code = value.__code__
except Exception:
pass
if code:
- self.message('Method %s' % code.co_name)
+ self.message('Function %s' % code.co_name)
return
# Is it a class?
if value.__class__ is type:
TIME = 'time', 'tottime'
def __new__(cls, *values):
- obj = str.__new__(cls)
-
- obj._value_ = values[0]
+ value = values[0]
+ obj = str.__new__(cls, value)
+ obj._value_ = value
for other_value in values[1:]:
cls._value2member_map_[other_value] = obj
obj._all_values = values
compile(filename, doraise=True)
except PyCompileError as error:
rv = 1
- if quiet < 2:
- sys.stderr.write("%s\n" % error.msg)
+ sys.stderr.write("%s\n" % error.msg)
except OSError as error:
rv = 1
- if quiet < 2:
- sys.stderr.write("%s\n" % error)
+ sys.stderr.write("%s\n" % error)
else:
for filename in args:
try:
except PyCompileError as error:
# return value to indicate at least one failure
rv = 1
- if quiet < 2:
- sys.stderr.write("%s\n" % error.msg)
+ sys.stderr.write("%s\n" % error.msg)
return rv
if __name__ == "__main__":
# -*- coding: utf-8 -*-
-# Autogenerated by Sphinx on Mon Jul 20 14:14:54 2020
+# Autogenerated by Sphinx on Wed Sep 23 14:35:51 2020
topics = {'assert': 'The "assert" statement\n'
'**********************\n'
'\n'
'the data\n'
' model.\n'
'\n'
+ ' Note: Due to a bug in the dispatching mechanism for '
+ '"**=", a\n'
+ ' class that defines "__ipow__()" but returns '
+ '"NotImplemented"\n'
+ ' would fail to fall back to "x.__pow__(y)" and '
+ '"y.__rpow__(x)".\n'
+ ' This bug is fixed in Python 3.10.\n'
+ '\n'
'object.__neg__(self)\n'
'object.__pos__(self)\n'
'object.__abs__(self)\n'
'the data\n'
' model.\n'
'\n'
+ ' Note: Due to a bug in the dispatching mechanism for '
+ '"**=", a\n'
+ ' class that defines "__ipow__()" but returns '
+ '"NotImplemented"\n'
+ ' would fail to fall back to "x.__pow__(y)" and '
+ '"y.__rpow__(x)".\n'
+ ' This bug is fixed in Python 3.10.\n'
+ '\n'
'object.__neg__(self)\n'
'object.__pos__(self)\n'
'object.__abs__(self)\n'
with self.assertRaises(sqlite.ProgrammingError):
self.cx.backup(bck)
+ def test_bad_source_closed_connection(self):
+ bck = sqlite.connect(':memory:')
+ source = sqlite.connect(":memory:")
+ source.close()
+ with self.assertRaises(sqlite.ProgrammingError):
+ source.backup(bck)
+
def test_bad_target_in_transaction(self):
bck = sqlite.connect(':memory:')
bck.execute('CREATE TABLE bar (key INTEGER)')
otherwise a default directory is used.
If 'text' is specified and true, the file is opened in text
- mode. Else (the default) the file is opened in binary mode. On
- some operating systems, this makes no difference.
+ mode. Else (the default) the file is opened in binary mode.
If any of 'suffix', 'prefix' and 'dir' are not None, they must be the
same type. If they are bytes, the returned name will be bytes; str
sms.close()
+ # Test creating a shared memory segment with negative size
+ with self.assertRaises(ValueError):
+ sms_invalid = shared_memory.SharedMemory(create=True, size=-1)
+
+ # Test creating a shared memory segment with size 0
+ with self.assertRaises(ValueError):
+ sms_invalid = shared_memory.SharedMemory(create=True, size=0)
+
+ # Test creating a shared memory segment without size argument
+ with self.assertRaises(ValueError):
+ sms_invalid = shared_memory.SharedMemory(create=True)
+
def test_shared_memory_across_processes(self):
# bpo-40135: don't define shared memory block's name in case of
# the failure when we run multiprocessing tests in parallel.
'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
'col_offset=0, end_lineno=1, end_col_offset=5))'
)
+ src = ast.Call(col_offset=1, lineno=1, end_lineno=1, end_col_offset=1)
+ new = ast.copy_location(src, ast.Call(
+ col_offset=None, lineno=None,
+ end_lineno=None, end_col_offset=None
+ ))
+ self.assertIsNone(new.end_lineno)
+ self.assertIsNone(new.end_col_offset)
+ self.assertEqual(new.lineno, 1)
+ self.assertEqual(new.col_offset, 1)
def test_fix_missing_locations(self):
src = ast.parse('write("spam")')
'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
'col_offset=0, end_lineno=4, end_col_offset=5))'
)
+ src = ast.Call(
+ func=ast.Name("test", ast.Load()), args=[], keywords=[],
+ lineno=1, end_lineno=None
+ )
+ self.assertEqual(ast.increment_lineno(src).lineno, 2)
+ self.assertIsNone(ast.increment_lineno(src).end_lineno)
def test_iter_fields(self):
node = ast.parse('foo()', mode='eval')
def test_loop_self_reading_fut(self):
fut = mock.Mock()
+ self.loop._self_reading_future = fut
self.loop._loop_self_reading(fut)
self.assertTrue(fut.result.called)
self.proactor.recv.assert_called_with(self.ssock, 4096)
asyncio.run(main(False))
asyncio.run(main(True), debug=True)
+ with mock.patch('asyncio.coroutines._is_debug_mode', lambda: True):
+ asyncio.run(main(True))
+ asyncio.run(main(False), debug=False)
def test_asyncio_run_from_running_loop(self):
async def main():
res = loop.run_until_complete(task)
self.assertEqual(res, "ok")
+ def test_wait_for_cancellation_race_condition(self):
+ def gen():
+ yield 0.1
+ yield 0.1
+ yield 0.1
+ yield 0.1
+
+ loop = self.new_test_loop(gen)
+
+ fut = self.new_future(loop)
+ loop.call_later(0.1, fut.set_result, "ok")
+ task = loop.create_task(asyncio.wait_for(fut, timeout=1))
+ loop.call_later(0.1, task.cancel)
+ res = loop.run_until_complete(task)
+ self.assertEqual(res, "ok")
+
def test_wait_for_waits_for_task_cancellation(self):
loop = asyncio.new_event_loop()
self.addCleanup(loop.close)
nonlocal task_done
try:
await asyncio.sleep(0.2)
+ except asyncio.CancelledError:
+ await asyncio.sleep(0.1)
+ raise
finally:
task_done = True
loop.run_until_complete(foo())
+ def test_wait_for_waits_for_task_cancellation_w_timeout_0(self):
+ loop = asyncio.new_event_loop()
+ self.addCleanup(loop.close)
+
+ task_done = False
+
+ async def foo():
+ async def inner():
+ nonlocal task_done
+ try:
+ await asyncio.sleep(10)
+ except asyncio.CancelledError:
+ await asyncio.sleep(0.1)
+ raise
+ finally:
+ task_done = True
+
+ inner_task = self.new_task(loop, inner())
+ await asyncio.sleep(0.1)
+ await asyncio.wait_for(inner_task, timeout=0)
+
+ with self.assertRaises(asyncio.TimeoutError) as cm:
+ loop.run_until_complete(foo())
+
+ self.assertTrue(task_done)
+ chained = cm.exception.__context__
+ self.assertEqual(type(chained), asyncio.CancelledError)
+
def test_wait_for_self_cancellation(self):
loop = asyncio.new_event_loop()
self.addCleanup(loop.close)
fut.cancel()
fut.cancel()
+ def test_read_self_pipe_restart(self):
+ # Regression test for https://bugs.python.org/issue39010
+ # Previously, restarting a proactor event loop in certain states
+ # would lead to spurious ConnectionResetErrors being logged.
+ self.loop.call_exception_handler = mock.Mock()
+ # Start an operation in another thread so that the self-pipe is used.
+ # This is theoretically timing-dependent (the task in the executor
+ # must complete before our start/stop cycles), but in practice it
+ # seems to work every time.
+ f = self.loop.run_in_executor(None, lambda: None)
+ self.loop.stop()
+ self.loop.run_forever()
+ self.loop.stop()
+ self.loop.run_forever()
+
+ # Shut everything down cleanly. This is an important part of the
+ # test - in issue 39010, the error occurred during loop.close(),
+ # so we want to close the loop during the test instead of leaving
+ # it for tearDown.
+ #
+ # First wait for f to complete to avoid a "future's result was never
+ # retrieved" error.
+ self.loop.run_until_complete(f)
+ # Now shut down the loop itself (self.close_loop also shuts down the
+ # loop's default executor).
+ self.close_loop(self.loop)
+ self.assertFalse(self.loop.call_exception_handler.called)
+
class WinPolicyTests(test_utils.TestCase):
# skip the test if the LC_CTYPE locale is C or coerced
old_loc = locale.setlocale(locale.LC_CTYPE, None)
self.addCleanup(locale.setlocale, locale.LC_CTYPE, old_loc)
- loc = locale.setlocale(locale.LC_CTYPE, "")
+ try:
+ loc = locale.setlocale(locale.LC_CTYPE, "")
+ except locale.Error as e:
+ self.skipTest(str(e))
if loc == "C":
self.skipTest("test requires LC_CTYPE locale different than C")
if loc in TARGET_LOCALES :
def test_usage(self):
rc, out, err = assert_python_ok('-h')
- self.assertIn(b'usage', out)
+ lines = out.splitlines()
+ self.assertIn(b'usage', lines[0])
+ # The first line contains the program name,
+ # but the rest should be ASCII-only
+ b''.join(lines[1:]).decode('ascii')
def test_version(self):
version = ('Python %d.%d' % sys.version_info[:2]).encode("ascii")
*run_args, __isolated=False, __cwd=cwd, **env_vars
)
if verbose > 1:
- print('Output from test script %r:' % script_exec_args)
+ print(f'Output from test script {script_exec_args!r:}')
print(repr(err))
print('Expected output: %r' % expected_msg)
self.assertIn(expected_msg.encode('utf-8'), err)
Nick Mathewson
"""
import unittest
+import warnings
from test import support
from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT
def test_warning(self):
# Test that the warning is only returned once.
- with support.check_warnings((".*literal", SyntaxWarning)) as w:
- compile_command("0 is 0")
- self.assertEqual(len(w.warnings), 1)
+ with support.check_warnings(
+ (".*literal", SyntaxWarning),
+ (".*invalid", DeprecationWarning),
+ ) as w:
+ compile_command(r"'\e' is 0")
+ self.assertEqual(len(w.warnings), 2)
+
+ # bpo-41520: check SyntaxWarning treated as an SyntaxError
+ with warnings.catch_warnings(), self.assertRaises(SyntaxError):
+ warnings.simplefilter('error', SyntaxWarning)
+ compile_command('1 is 1', symbol='exec')
+
if __name__ == "__main__":
unittest.main()
self.assertEqual('{:<20}'.format(Season.SPRING),
'{:<20}'.format(str(Season.SPRING)))
- def test_format_enum_custom(self):
+ def test_str_override_enum(self):
+ class EnumWithStrOverrides(Enum):
+ one = auto()
+ two = auto()
+
+ def __str__(self):
+ return 'Str!'
+ self.assertEqual(str(EnumWithStrOverrides.one), 'Str!')
+ self.assertEqual('{}'.format(EnumWithStrOverrides.one), 'Str!')
+
+ def test_format_override_enum(self):
+ class EnumWithFormatOverride(Enum):
+ one = 1.0
+ two = 2.0
+ def __format__(self, spec):
+ return 'Format!!'
+ self.assertEqual(str(EnumWithFormatOverride.one), 'EnumWithFormatOverride.one')
+ self.assertEqual('{}'.format(EnumWithFormatOverride.one), 'Format!!')
+
+ def test_str_and_format_override_enum(self):
+ class EnumWithStrFormatOverrides(Enum):
+ one = auto()
+ two = auto()
+ def __str__(self):
+ return 'Str!'
+ def __format__(self, spec):
+ return 'Format!'
+ self.assertEqual(str(EnumWithStrFormatOverrides.one), 'Str!')
+ self.assertEqual('{}'.format(EnumWithStrFormatOverrides.one), 'Format!')
+
+ def test_str_override_mixin(self):
+ class MixinEnumWithStrOverride(float, Enum):
+ one = 1.0
+ two = 2.0
+ def __str__(self):
+ return 'Overridden!'
+ self.assertEqual(str(MixinEnumWithStrOverride.one), 'Overridden!')
+ self.assertEqual('{}'.format(MixinEnumWithStrOverride.one), 'Overridden!')
+
+ def test_str_and_format_override_mixin(self):
+ class MixinWithStrFormatOverrides(float, Enum):
+ one = 1.0
+ two = 2.0
+ def __str__(self):
+ return 'Str!'
+ def __format__(self, spec):
+ return 'Format!'
+ self.assertEqual(str(MixinWithStrFormatOverrides.one), 'Str!')
+ self.assertEqual('{}'.format(MixinWithStrFormatOverrides.one), 'Format!')
+
+ def test_format_override_mixin(self):
class TestFloat(float, Enum):
one = 1.0
two = 2.0
def __format__(self, spec):
return 'TestFloat success!'
+ self.assertEqual(str(TestFloat.one), 'TestFloat.one')
self.assertEqual('{}'.format(TestFloat.one), 'TestFloat success!')
def assertFormatIsValue(self, spec, member):
self.assertFormatIsValue('{:>20}', Directional.WEST)
self.assertFormatIsValue('{:<20}', Directional.WEST)
+ def test_object_str_override(self):
+ class Colors(Enum):
+ RED, GREEN, BLUE = 1, 2, 3
+ def __repr__(self):
+ return "test.%s" % (self._name_, )
+ __str__ = object.__str__
+ self.assertEqual(str(Colors.RED), 'test.RED')
+
+ def test_enum_str_override(self):
+ class MyStrEnum(Enum):
+ def __str__(self):
+ return 'MyStr'
+ class MyMethodEnum(Enum):
+ def hello(self):
+ return 'Hello! My name is %s' % self.name
+ class Test1Enum(MyMethodEnum, int, MyStrEnum):
+ One = 1
+ Two = 2
+ self.assertEqual(str(Test1Enum.One), 'MyStr')
+ #
+ class Test2Enum(MyStrEnum, MyMethodEnum):
+ One = 1
+ Two = 2
+ self.assertEqual(str(Test2Enum.One), 'MyStr')
+
+ def test_inherited_data_type(self):
+ class HexInt(int):
+ def __repr__(self):
+ return hex(self)
+ class MyEnum(HexInt, enum.Enum):
+ A = 1
+ B = 2
+ C = 3
+ self.assertEqual(repr(MyEnum.A), '<MyEnum.A: 0x1>')
+
+ def test_too_many_data_types(self):
+ with self.assertRaisesRegex(TypeError, 'too many data types'):
+ class Huh(str, int, Enum):
+ One = 1
+
+ class MyStr(str):
+ def hello(self):
+ return 'hello, %s' % self
+ class MyInt(int):
+ def repr(self):
+ return hex(self)
+ with self.assertRaisesRegex(TypeError, 'too many data types'):
+ class Huh(MyStr, MyInt, Enum):
+ One = 1
+
def test_hash(self):
Season = self.Season
dates = {}
cyan = 4
magenta = 5
yellow = 6
+ with self.assertRaisesRegex(TypeError, "EvenMoreColor: cannot extend enumeration 'Color'"):
+ class EvenMoreColor(Color, IntEnum):
+ chartruese = 7
def test_exclude_methods(self):
class whatever(Enum):
def _generate_next_value_(name, start, count, last):
return name
+ def test_auto_order_wierd(self):
+ weird_auto = auto()
+ weird_auto.value = 'pathological case'
+ class Color(Enum):
+ red = weird_auto
+ def _generate_next_value_(name, start, count, last):
+ return name
+ blue = auto()
+ self.assertEqual(list(Color), [Color.red, Color.blue])
+ self.assertEqual(Color.red.value, 'pathological case')
+ self.assertEqual(Color.blue.value, 'blue')
def test_duplicate_auto(self):
class Dupes(Enum):
third = auto()
self.assertEqual([Dupes.first, Dupes.second, Dupes.third], list(Dupes))
+ def test_default_missing(self):
+ class Color(Enum):
+ RED = 1
+ GREEN = 2
+ BLUE = 3
+ try:
+ Color(7)
+ except ValueError as exc:
+ self.assertTrue(exc.__context__ is None)
+ else:
+ raise Exception('Exception not raised.')
+
def test_missing(self):
class Color(Enum):
red = 1
# trigger not found
return None
self.assertIs(Color('three'), Color.blue)
- self.assertRaises(ValueError, Color, 7)
+ try:
+ Color(7)
+ except ValueError as exc:
+ self.assertTrue(exc.__context__ is None)
+ else:
+ raise Exception('Exception not raised.')
try:
Color('bad return')
except TypeError as exc:
# Python test set -- part 5, built-in exceptions
import copy
+import gc
import os
import sys
import unittest
next(i)
next(i)
+ def test_memory_error_subclasses(self):
+ # bpo-41654: MemoryError instances use a freelist of objects that are
+ # linked using the 'dict' attribute when they are inactive/dead.
+ # Subclasses of MemoryError should not participate in the freelist
+ # schema. This test creates a MemoryError object and keeps it alive
+ # (therefore advancing the freelist) and then it creates and destroys a
+ # subclass object. Finally, it checks that creating a new MemoryError
+ # succeeds, proving that the freelist is not corrupted.
+
+ class TestException(MemoryError):
+ pass
+
+ try:
+ raise MemoryError
+ except MemoryError as exc:
+ inst = exc
+
+ try:
+ raise TestException
+ except Exception:
+ pass
+
+ for _ in range(10):
+ try:
+ raise MemoryError
+ except MemoryError as exc:
+ pass
+
+ gc_collect()
class ImportErrorTests(unittest.TestCase):
"embedding. Saw %s.%s:\n%s"
% (gdb_major_version, gdb_minor_version,
gdb_version))
+if (gdb_major_version, gdb_minor_version) >= (9, 2):
+ # gdb 9.2 on Fedora Rawhide is not reliable, see:
+ # * https://bugs.python.org/issue41473
+ # * https://bugzilla.redhat.com/show_bug.cgi?id=1866884
+ raise unittest.SkipTest("https://bugzilla.redhat.com/show_bug.cgi?id=1866884")
if not sysconfig.is_python_build():
raise unittest.SkipTest("test_gdb only works on source builds at the moment.")
import sys
import unittest
+import uuid
from . import data01
from . import zipdata01, zipdata02
from . import util
from importlib import resources, import_module
+from pathlib import Path
+from test import support
class ResourceTests:
'test.test_importlib.data03.namespace', 'resource1.txt')
+class DeletingZipsTest(unittest.TestCase):
+ """Having accessed resources in a zip file should not keep an open
+ reference to the zip.
+ """
+ ZIP_MODULE = zipdata01
+
+ def setUp(self):
+ modules = support.modules_setup()
+ self.addCleanup(support.modules_cleanup, *modules)
+
+ data_path = Path(self.ZIP_MODULE.__file__)
+ data_dir = data_path.parent
+ self.source_zip_path = data_dir / 'ziptestdata.zip'
+ self.zip_path = Path.cwd() / '{}.zip'.format(uuid.uuid4())
+ self.zip_path.write_bytes(self.source_zip_path.read_bytes())
+ sys.path.append(str(self.zip_path))
+ self.data = import_module('ziptestdata')
+
+ def tearDown(self):
+ try:
+ sys.path.remove(str(self.zip_path))
+ except ValueError:
+ pass
+
+ try:
+ del sys.path_importer_cache[str(self.zip_path)]
+ del sys.modules[self.data.__name__]
+ except KeyError:
+ pass
+
+ try:
+ support.unlink(self.zip_path)
+ except OSError:
+ # If the test fails, this will probably fail too
+ pass
+
+ def test_contents_does_not_keep_open(self):
+ c = resources.contents('ziptestdata')
+ self.zip_path.unlink()
+
+ def test_is_resource_does_not_keep_open(self):
+ c = resources.is_resource('ziptestdata', 'binary.file')
+ self.zip_path.unlink()
+
+ def test_is_resource_failure_does_not_keep_open(self):
+ c = resources.is_resource('ziptestdata', 'not-present')
+ self.zip_path.unlink()
+
+ def test_path_does_not_keep_open(self):
+ c = resources.path('ziptestdata', 'binary.file')
+ self.zip_path.unlink()
+
+ def test_entered_path_does_not_keep_open(self):
+ # This is what certifi does on import to make its bundle
+ # available for the process duration.
+ c = resources.path('ziptestdata', 'binary.file').__enter__()
+ self.zip_path.unlink()
+
+ def test_read_binary_does_not_keep_open(self):
+ c = resources.read_binary('ziptestdata', 'binary.file')
+ self.zip_path.unlink()
+
+ def test_read_text_does_not_keep_open(self):
+ c = resources.read_text('ziptestdata', 'utf-8.file', encoding='utf-8')
+ self.zip_path.unlink()
+
if __name__ == '__main__':
unittest.main()
self.assertEqual(f.read(), "egg\n")
check_path_succeeds(FakePath(support.TESTFN))
- check_path_succeeds(FakePath(support.TESTFN.encode('utf-8')))
+ check_path_succeeds(FakePath(os.fsencode(support.TESTFN)))
with self.open(support.TESTFN, "w") as f:
bad_path = FakePath(f.fileno())
# assert that no new lines have been added
self.assert_log_lines(lines) # no change
+ def test_race_between_set_target_and_flush(self):
+ class MockRaceConditionHandler:
+ def __init__(self, mem_hdlr):
+ self.mem_hdlr = mem_hdlr
+
+ def removeTarget(self):
+ self.mem_hdlr.setTarget(None)
+
+ def handle(self, msg):
+ t = threading.Thread(target=self.removeTarget)
+ t.daemon = True
+ t.start()
+
+ target = MockRaceConditionHandler(self.mem_hdlr)
+ self.mem_hdlr.setTarget(target)
+
+ for _ in range(10):
+ time.sleep(0.005)
+ self.mem_logger.info("not flushed")
+ self.mem_logger.warning("flushed")
+
class ExceptionFormatter(logging.Formatter):
"""A special exception formatter."""
st = os.stat(join('other_new_file'))
self.assertEqual(stat.S_IMODE(st.st_mode), 0o644)
+ def test_resolve_root(self):
+ current_directory = os.getcwd()
+ try:
+ os.chdir('/')
+ p = self.cls('spam')
+ self.assertEqual(str(p.resolve()), '/spam')
+ finally:
+ os.chdir(current_directory)
+
def test_touch_mode(self):
old_mask = os.umask(0)
self.addCleanup(os.umask, old_mask)
(Pdb) continue
"""
+def test_pdb_whatis_command():
+ """Test the whatis command
+
+ >>> myvar = (1,2)
+ >>> def myfunc():
+ ... pass
+
+ >>> class MyClass:
+ ... def mymethod(self):
+ ... pass
+
+ >>> def test_function():
+ ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
+
+ >>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
+ ... 'whatis myvar',
+ ... 'whatis myfunc',
+ ... 'whatis MyClass',
+ ... 'whatis MyClass()',
+ ... 'whatis MyClass.mymethod',
+ ... 'whatis MyClass().mymethod',
+ ... 'continue',
+ ... ]):
+ ... test_function()
+ --Return--
+ > <doctest test.test_pdb.test_pdb_whatis_command[3]>(2)test_function()->None
+ -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
+ (Pdb) whatis myvar
+ <class 'tuple'>
+ (Pdb) whatis myfunc
+ Function myfunc
+ (Pdb) whatis MyClass
+ Class test.test_pdb.MyClass
+ (Pdb) whatis MyClass()
+ <class 'test.test_pdb.MyClass'>
+ (Pdb) whatis MyClass.mymethod
+ Function mymethod
+ (Pdb) whatis MyClass().mymethod
+ Method mymethod
+ (Pdb) continue
+ """
def test_post_mortem():
"""Test post mortem traceback debugging.
'calls')
+ def test_SortKey_enum(self):
+ self.assertEqual(SortKey.FILENAME, 'filename')
+ self.assertNotEqual(SortKey.FILENAME, SortKey.CALLS)
+
if __name__ == "__main__":
unittest.main()
import py_compile
import shutil
import stat
+import subprocess
import sys
import tempfile
import unittest
from test import support
+from test.support import script_helper
def without_source_date_epoch(fxn):
pass
+class PyCompileCLITestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.directory = tempfile.mkdtemp()
+ self.source_path = os.path.join(self.directory, '_test.py')
+ self.cache_path = importlib.util.cache_from_source(self.source_path)
+ with open(self.source_path, 'w') as file:
+ file.write('x = 123\n')
+
+ def tearDown(self):
+ support.rmtree(self.directory)
+
+ def pycompilecmd(self, *args, **kwargs):
+ # assert_python_* helpers don't return proc object. We'll just use
+ # subprocess.run() instead of spawn_python() and its friends to test
+ # stdin support of the CLI.
+ if args and args[0] == '-' and 'input' in kwargs:
+ return subprocess.run([sys.executable, '-m', 'py_compile', '-'],
+ input=kwargs['input'].encode(),
+ capture_output=True)
+ return script_helper.assert_python_ok('-m', 'py_compile', *args, **kwargs)
+
+ def pycompilecmd_failure(self, *args):
+ return script_helper.assert_python_failure('-m', 'py_compile', *args)
+
+ def test_stdin(self):
+ result = self.pycompilecmd('-', input=self.source_path)
+ self.assertEqual(result.returncode, 0)
+ self.assertEqual(result.stdout, b'')
+ self.assertEqual(result.stderr, b'')
+ self.assertTrue(os.path.exists(self.cache_path))
+
+ def test_with_files(self):
+ rc, stdout, stderr = self.pycompilecmd(self.source_path, self.source_path)
+ self.assertEqual(rc, 0)
+ self.assertEqual(stdout, b'')
+ self.assertEqual(stderr, b'')
+ self.assertTrue(os.path.exists(self.cache_path))
+
+ def test_bad_syntax(self):
+ bad_syntax = os.path.join(os.path.dirname(__file__), 'badsyntax_3131.py')
+ rc, stdout, stderr = self.pycompilecmd_failure(bad_syntax)
+ self.assertEqual(rc, 1)
+ self.assertEqual(stdout, b'')
+ self.assertIn(b'SyntaxError', stderr)
+
+ def test_file_not_exists(self):
+ should_not_exists = os.path.join(os.path.dirname(__file__), 'should_not_exists.py')
+ rc, stdout, stderr = self.pycompilecmd_failure(self.source_path, should_not_exists)
+ self.assertEqual(rc, 1)
+ self.assertEqual(stdout, b'')
+ self.assertIn(b'No such file or directory', stderr)
+
+
if __name__ == "__main__":
unittest.main()
# matches *expected_cwd*.
p = subprocess.Popen([python_arg, "-c",
"import os, sys; "
- "sys.stdout.write(os.getcwd()); "
+ "buf = sys.stdout.buffer; "
+ "buf.write(os.getcwd().encode()); "
+ "buf.flush(); "
"sys.exit(47)"],
stdout=subprocess.PIPE,
**kwargs)
self.assertEqual(47, p.returncode)
normcase = os.path.normcase
self.assertEqual(normcase(expected_cwd),
- normcase(p.stdout.read().decode("utf-8")))
+ normcase(p.stdout.read().decode()))
def test_cwd(self):
# Check that cwd changes the cwd for the child process.
self.assertAlmostEqual(
i, j, msg='values at index {} do not match'.format(idx))
+class Multiplier:
+
+ def __mul__(self, other):
+ return f'M*{other}'
+
+ def __rmul__(self, other):
+ return f'{other}*M'
+
class TestVec2D(VectorComparisonMixin, unittest.TestCase):
self.assertAlmostEqual(answer, expected)
vec = Vec2D(0.5, 3)
- answer = vec * 10
expected = Vec2D(5, 30)
- self.assertVectorsAlmostEqual(answer, expected)
+ self.assertVectorsAlmostEqual(vec * 10, expected)
+ self.assertVectorsAlmostEqual(10 * vec, expected)
+ self.assertVectorsAlmostEqual(vec * 10.0, expected)
+ self.assertVectorsAlmostEqual(10.0 * vec, expected)
+
+ M = Multiplier()
+ self.assertEqual(vec * M, Vec2D(f"{vec[0]}*M", f"{vec[1]}*M"))
+ self.assertEqual(M * vec, f'M*{vec}')
def test_vector_negative(self):
vec = Vec2D(10, -10)
class EventType(str, enum.Enum):
KeyPress = '2'
- Key = KeyPress,
+ Key = KeyPress
KeyRelease = '3'
ButtonPress = '4'
- Button = ButtonPress,
+ Button = ButtonPress
ButtonRelease = '5'
Motion = '6'
Enter = '7'
Colormap = '32'
ClientMessage = '33' # undocumented
Mapping = '34' # undocumented
- VirtualEvent = '35', # undocumented
- Activate = '36',
- Deactivate = '37',
- MouseWheel = '38',
+ VirtualEvent = '35' # undocumented
+ Activate = '36'
+ Deactivate = '37'
+ MouseWheel = '38'
def __str__(self):
return self.name
if 'command' in kwargs:
del kwargs['command']
if kwargs:
- raise TclError('unknown option -'+kwargs.keys()[0])
+ raise TclError('unknown option -'+next(iter(kwargs)))
menu.add_command(label=value,
command=_setit(variable, value, callback))
for v in values:
def create(self, default='b', values=('a', 'b', 'c'), **kwargs):
return tkinter.OptionMenu(self.root, None, default, *values, **kwargs)
+ def test_bad_kwarg(self):
+ with self.assertRaisesRegex(TclError, r"^unknown option -image$"):
+ tkinter.OptionMenu(self.root, None, 'b', image='')
+
@add_standard_options(IntegerSizeTests, StandardOptionsTests)
class EntryTest(AbstractWidgetTest, unittest.TestCase):
def __rmul__(self, other):
if isinstance(other, int) or isinstance(other, float):
return Vec2D(self[0]*other, self[1]*other)
+ return NotImplemented
def __sub__(self, other):
return Vec2D(self[0]-other[0], self[1]-other[1])
def __neg__(self):
def _eval_type(t, globalns, localns):
- """Evaluate all forward reverences in the given type t.
+ """Evaluate all forward references in the given type t.
For use of globalns and localns see the docstring for get_type_hints().
"""
if isinstance(t, ForwardRef):
"""
import os
-import platform
import sys
from enum import Enum
__author__ = 'Ka-Ping Yee <ping@zesty.ca>'
# The recognized platforms - known behaviors
-_AIX = platform.system() == 'AIX'
-_DARWIN = platform.system() == 'Darwin'
-_LINUX = platform.system() == 'Linux'
-_WINDOWS = platform.system() == 'Windows'
+if sys.platform in ('win32', 'darwin'):
+ _AIX = _LINUX = False
+else:
+ import platform
+ _platform_system = platform.system()
+ _AIX = _platform_system == 'AIX'
+ _LINUX = _platform_system == 'Linux'
RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [
'reserved for NCS compatibility', 'specified in RFC 4122',
# @unittest.skipUnless(_uuid._ifconfig_getnode in _uuid._GETTERS, ...)
if _LINUX:
_OS_GETTERS = [_ip_getnode, _ifconfig_getnode]
-elif _DARWIN:
+elif sys.platform == 'darwin':
_OS_GETTERS = [_ifconfig_getnode, _arp_getnode, _netstat_getnode]
-elif _WINDOWS:
+elif sys.platform == 'win32':
_OS_GETTERS = [_netbios_getnode, _ipconfig_getnode]
elif _AIX:
_OS_GETTERS = [_netstat_getnode]
else
if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
# special case for Aspen magic directories
- # see http://www.zetadev.com/software/aspen/
+ # see https://aspen.io/
PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1"
else
PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1"
else
if (`basename "VIRTUAL_ENV"` == "__") then
# special case for Aspen magic directories
- # see http://www.zetadev.com/software/aspen/
+ # see https://aspen.io/
set env_name = `basename \`dirname "$VIRTUAL_ENV"\``
else
set env_name = `basename "$VIRTUAL_ENV"`
set -l _checkbase (basename "$VIRTUAL_ENV")
if test $_checkbase = "__"
# special case for Aspen magic directories
- # see http://www.zetadev.com/software/aspen/
+ # see https://aspen.io/
printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal)
else
printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal)
-{\rtf1\ansi\ansicpg1252\cocoartf2511
+{\rtf1\ansi\ansicpg1252\cocoartf2513
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;\f2\fmodern\fcharset0 CourierNewPS-BoldMT;
\f3\fmodern\fcharset0 CourierNewPSMT;}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;}
-\margl1440\margr1440\vieww14620\viewh13380\viewkind0
+\margl1440\margr1440\vieww18500\viewh13520\viewkind0
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
\f0\b\fs36 \cf0 \ul \ulc0 HISTORY AND LICENSE\
\
\f0\b \ul TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON\
+\
+\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
-\f1\b0 \ulnone \
+\f1\b0 \cf0 \ulnone Python software and documentation are licensed under the Python Software Foundation License Version 2.\
+\
+Starting with Python 3.8.6, examples, recipes, and other code in the documentation are dual licensed under the PSF License Version 2 and the Zero-Clause BSD license.\
+\
+Some software incorporated into Python is under different licenses. The licenses are listed with code falling under that license.\
+\
+\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
+\cf0 \
\f0\b PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2\
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\
\
\
+\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
+
+\f0\b \cf0 ZERO-CLAUSE BSD LICENSE FOR CODE IN THE PYTHON DOCUMENTATION\
+\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
+
+\f1\b0 \cf0 \
+Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.\
+\
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\
+\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
+\cf0 \
+\
\f0\b \ul LICENSES AND ACKNOWLEDGEMENTS FOR INCORPORATED SOFTWARE\
Antonio Cuni
Brian Curtin
Hakan Celik
+Jason Curtis
Paul Dagnelie
Lisandro Dalcin
Darren Dale
Dima Dorfman
Yves Dorfsman
Michael Dorman
+Andrey Doroschenko
Steve Dower
Allen Downey
Cesar Douady
Lowe Thiderman
Nicolas M. Thiéry
James Thomas
+Reuben Thomas
Robin Thomas
Brian Thorne
Christopher Thorne
Python News
+++++++++++
+What's New in Python 3.8.6 final?
+=================================
+
+*Release date: 2020-09-23*
+
+Core and Builtins
+-----------------
+
+- bpo-41525: The output of ``python --help`` contains now only ASCII
+ characters.
+
+Library
+-------
+
+- bpo-41817: fix `tkinter.EventType` Enum so all members are strings, and
+ none are tuples
+
+- bpo-41815: Fix SQLite3 segfault when backing up closed database. Patch
+ contributed by Peter David McCormick.
+
+- bpo-41517: fix bug allowing Enums to be extended via multiple inheritance
+
+- bpo-39587: use the correct mix-in data type when constructing Enums
+
+- bpo-41789: Honor `object` overrides in `Enum` class creation
+ (specifically, `__str__`, `__repr__`, `__format__`, and `__reduce_ex__`).
+
+- bpo-39651: Fix a race condition in the ``call_soon_threadsafe()`` method
+ of ``asyncio.ProactorEventLoop``: do nothing if the self-pipe socket has
+ been closed.
+
+- bpo-41720: Fixed :meth:`turtle.Vec2D.__rmul__` for arguments which are not
+ int or float.
+
+- bpo-39728: fix default `_missing_` so a duplicate `ValueError` is not set
+ as the `__context__` of the original `ValueError`
+
+- bpo-37479: When `Enum.__str__` is overridden in a derived class, the
+ override will be used by `Enum.__format__` regardless of whether mixin
+ classes are present.
+
+Documentation
+-------------
+
+- bpo-35293: Fix RemovedInSphinx40Warning when building the documentation.
+ Patch by Dong-hee Na.
+
+- bpo-37149: Change Shipman tkinter doc link from archive.org to TkDocs.
+ (The doc has been removed from the NMT server.) The new link responds
+ much faster and includes a short explanatory note.
+
+Tests
+-----
+
+- bpo-41731: Make test_cmd_line_script pass with option '-vv'.
+
+Windows
+-------
+
+- bpo-41744: Fixes automatic import of props file when using the Nuget
+ package.
+
+IDLE
+----
+
+- bpo-35764: Rewrite the Calltips doc section.
+
+- bpo-40181: In calltips, stop reminding that '/' marks the end of
+ positional-only arguments.
+
+
+What's New in Python 3.8.6 release candidate 1?
+===============================================
+
+*Release date: 2020-09-07*
+
+Core and Builtins
+-----------------
+
+- bpo-41654: Fix a crash that occurred when destroying subclasses of
+ :class:`MemoryError`. Patch by Pablo Galindo.
+
+- bpo-41533: Free the stack allocated in ``va_build_stack`` if
+ ``do_mkstack`` fails and the stack is not a ``small_stack``.
+
+- bpo-38156: Handle interrupts that come after EOF correctly in
+ ``PyOS_StdioReadline``.
+
+Library
+-------
+
+- bpo-41696: Fix handling of debug mode in :func:`asyncio.run`. This allows
+ setting ``PYTHONASYNCIODEBUG`` or ``-X dev`` to enable asyncio debug mode
+ when using :func:`asyncio.run`.
+
+- bpo-39010: Restarting a ``ProactorEventLoop`` on Windows no longer logs
+ spurious ``ConnectionResetErrors``.
+
+- bpo-41609: The pdb whatis command correctly reports instance methods as
+ 'Method' rather than 'Function'.
+
+- bpo-32751: When cancelling the task due to a timeout,
+ :meth:`asyncio.wait_for` will now wait until the cancellation is complete
+ also in the case when *timeout* is <= 0, like it does with positive
+ timeouts.
+
+- bpo-37658: :meth:`asyncio.wait_for` now properly handles races between
+ cancellation of itself and the completion of the wrapped awaitable.
+
+- bpo-40782: Change the method asyncio.AbstractEventLoop.run_in_executor to
+ not be a coroutine.
+
+- bpo-41520: Fix :mod:`codeop` regression that prevented turning compile
+ warnings into errors.
+
+- bpo-41503: Fixed a race between setTarget and flush in
+ logging.handlers.MemoryHandler.
+
+- bpo-41497: Fix potential UnicodeDecodeError in dis module.
+
+- bpo-41490: Update :mod:`ensurepip` to install pip 20.2.1 and setuptools
+ 49.2.1.
+
+- bpo-41467: On Windows, fix asyncio ``recv_into()`` return value when the
+ socket/pipe is closed (:exc:`BrokenPipeError`): return ``0`` rather than
+ an empty byte string (``b''``).
+
+- bpo-41425: Make tkinter doc example runnable.
+
+- bpo-41384: Raise TclError instead of TypeError when an unknown option is
+ passed to tkinter.OptionMenu.
+
+- bpo-38731: Fix :exc:`NameError` in command-line interface of
+ :mod:`py_compile`.
+
+- bpo-41364: Reduce import overhead of :mod:`uuid`.
+
+- bpo-41344: Prevent creating :class:`shared_memory.SharedMemory` objects
+ with :code:`size=0`.
+
+- bpo-40726: Handle cases where the ``end_lineno`` is ``None`` on
+ :func:`ast.increment_lineno`.
+
+- bpo-31122: ssl.wrap_socket() now raises ssl.SSLEOFError rather than
+ OSError when peer closes connection during TLS negotiation
+
+- bpo-33660: Fix pathlib.PosixPath to resolve a relative path located on the
+ root directory properly.
+
+Documentation
+-------------
+
+- bpo-41624: Fix the signature of :class:`typing.Coroutine`.
+
+- bpo-40204: Enable Sphinx 3.2 ``c_allow_pre_v3`` option and disable
+ ``c_warn_on_allowed_pre_v3`` option to make the documentation compatible
+ with Sphinx 2 and Sphinx 3.
+
+- bpo-41045: Add documentation for debug feature of f-strings.
+
+- bpo-41314: Changed the release when ``from __future__ import annotations``
+ becomes the default from ``4.0`` to ``3.10`` (following a change in PEP
+ 563).
+
+- bpo-39883: Make code, examples, and recipes in the Python documentation be
+ licensed under the more permissive BSD0 license in addition to the
+ existing Python 2.0 license.
+
+Windows
+-------
+
+- bpo-41492: Fixes the description that appears in UAC prompts.
+
+- bpo-40741: Update Windows release to include SQLite 3.32.3.
+
+IDLE
+----
+
+- bpo-41468: Improve IDLE run crash error message (which users should never
+ see).
+
+- bpo-41373: Save files loaded with no line ending, as when blank, or
+ different line endings, by setting its line ending to the system default.
+ Fix regression in 3.8.4 and 3.9.0b4.
+
+C API
+-----
+
+- bpo-41524: Fix bug in PyOS_mystrnicmp and PyOS_mystricmp that incremented
+ pointers beyond the end of a string.
+
+
What's New in Python 3.8.5 final?
=================================
- bpo-4630: Add an option to toggle IDLE's cursor blink for shell, editor,
and output windows. See Settings, General, Window Preferences, Cursor
- Blink. Patch by Zachary Spytz.
+ Blink. Patch by Zackery Spytz.
- bpo-38598: Do not try to compile IDLE shell or output windows
between Python versions.
- bpo-36686: Improve documentation of the stdin, stdout, and stderr
- arguments of of the ``asyncio.subprocess_exec`` function to specify which
+ arguments of the ``asyncio.subprocess_exec`` function to specify which
values are supported. Also mention that decoding as text is not supported.
Add a few tests to verify that the various values passed to the std*
- bpo-34391: Fix ftplib test for TLS 1.3 by reading from data socket.
-- bpo-11192: Fix `test_socket` on AIX AIX 6.1 and later IPv6 zone id
- supports only supported by inet_pton6_zone() Switch to runtime-based
+- bpo-11192: Fix `test_socket` on AIX 6.1 and later IPv6 zone id supports
+ only supported by inet_pton6_zone() Switch to runtime-based
platform.system() to establish current platform rather than build-time
based sys.platform()
nested imports). Note that its output may be broken in multi-threaded
application. Typical usage is python3 -X importtime -c 'import asyncio'
- -X dev: enable CPython’s “development mode”, introducing additional runtime
+ -X dev: enable CPython's "development mode", introducing additional runtime
checks which are too expensive to be enabled by default. It will not be
more verbose than the default if the code is correct: new warnings are
only emitted when an issue is detected. Effect of the developer mode:
sleep_ms = (int)ms;
}
+ if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
+ return NULL;
+ }
+
if (!pysqlite_check_connection((pysqlite_Connection *)target)) {
return NULL;
}
errno = err.c;
return PyErr_SetFromErrno(PyExc_OSError);
}
- Py_INCREF(s);
- s->errorhandler();
- Py_DECREF(s);
- return NULL;
+ else {
+ p = PY_SSL_ERROR_EOF;
+ type = PySSLEOFErrorObject;
+ errstr = "EOF occurred in violation of protocol";
+ }
} else { /* possible? */
p = PY_SSL_ERROR_SYSCALL;
type = PySSLSyscallErrorObject;
{
PyBaseExceptionObject *self;
- if (type != (PyTypeObject *) PyExc_MemoryError)
+ /* If this is a subclass of MemoryError, don't use the freelist
+ * and just return a fresh object */
+ if (type != (PyTypeObject *) PyExc_MemoryError) {
return BaseException_new(type, args, kwds);
+ }
+
if (memerrors_freelist == NULL)
return BaseException_new(type, args, kwds);
/* Fetch object from freelist and revive it */
static void
MemoryError_dealloc(PyBaseExceptionObject *self)
{
- _PyObject_GC_UNTRACK(self);
BaseException_clear(self);
+
+ if (Py_TYPE(self) != (PyTypeObject *)PyExc_MemoryError) {
+ Py_TYPE(self)->tp_free((PyObject *)self);
+ return;
+ }
+
+ _PyObject_GC_UNTRACK(self);
+
if (memerrors_numfree >= MEMERRORS_SAVE)
Py_TYPE(self)->tp_free((PyObject *)self);
else {
for (DWORD i = 0; i < size; ++i, ++p, ++prec) {
prec->EventType = KEY_EVENT;
prec->Event.KeyEvent.bKeyDown = TRUE;
- prec->Event.KeyEvent.wRepeatCount = 10;
+ prec->Event.KeyEvent.wRepeatCount = 1;
prec->Event.KeyEvent.uChar.UnicodeChar = *p;
}
set libraries=%libraries% bzip2-1.0.6\r
if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.3.0-rc0-r1\r
if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1g\r
-set libraries=%libraries% sqlite-3.31.1.0\r
+set libraries=%libraries% sqlite-3.32.3.0\r
if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.9.0\r
if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.9.0\r
if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tix-8.4.3.6\r
<ExternalsDir>$(EXTERNALS_DIR)</ExternalsDir>\r
<ExternalsDir Condition="$(ExternalsDir) == ''">$([System.IO.Path]::GetFullPath(`$(PySourcePath)externals`))</ExternalsDir>\r
<ExternalsDir Condition="!HasTrailingSlash($(ExternalsDir))">$(ExternalsDir)\</ExternalsDir>\r
- <sqlite3Dir>$(ExternalsDir)sqlite-3.31.1.0\</sqlite3Dir>\r
+ <sqlite3Dir>$(ExternalsDir)sqlite-3.32.3.0\</sqlite3Dir>\r
<bz2Dir>$(ExternalsDir)bzip2-1.0.6\</bz2Dir>\r
<lzmaDir>$(ExternalsDir)xz-5.2.2\</lzmaDir>\r
<libffiDir>$(ExternalsDir)libffi\</libffiDir>\r
again when building.\r
\r
_sqlite3\r
- Wraps SQLite 3.31.1.0, which is itself built by sqlite3.vcxproj\r
+ Wraps SQLite 3.32.3.0, which is itself built by sqlite3.vcxproj\r
Homepage:\r
http://www.sqlite.org/\r
_tkinter\r
}
#endif
- n = 100;
- p = (char *)PyMem_RawMalloc(n);
- if (p == NULL) {
- PyEval_RestoreThread(tstate);
- PyErr_NoMemory();
- PyEval_SaveThread();
- return NULL;
- }
-
fflush(sys_stdout);
if (prompt) {
fprintf(stderr, "%s", prompt);
}
fflush(stderr);
- switch (my_fgets(tstate, p, (int)n, sys_stdin)) {
- case 0: /* Normal case */
- break;
- case 1: /* Interrupt */
- PyMem_RawFree(p);
- return NULL;
- case -1: /* EOF */
- case -2: /* Error */
- default: /* Shouldn't happen */
- *p = '\0';
- break;
- }
-
- n = strlen(p);
- while (n > 0 && p[n-1] != '\n') {
- size_t incr = n+2;
+ n = 0;
+ p = NULL;
+ do {
+ size_t incr = (n > 0) ? n + 2 : 100;
if (incr > INT_MAX) {
PyMem_RawFree(p);
PyEval_RestoreThread(tstate);
PyEval_SaveThread();
return NULL;
}
-
pr = (char *)PyMem_RawRealloc(p, n + incr);
if (pr == NULL) {
PyMem_RawFree(p);
return NULL;
}
p = pr;
-
- if (my_fgets(tstate, p+n, (int)incr, sys_stdin) != 0) {
+ int err = my_fgets(tstate, p + n, (int)incr, sys_stdin);
+ if (err == 1) {
+ // Interrupt
+ PyMem_RawFree(p);
+ return NULL;
+ } else if (err != 0) {
+ // EOF or error
+ p[n] = '\0';
break;
}
- n += strlen(p+n);
- }
+ n += strlen(p + n);
+ } while (p[n-1] != '\n');
pr = (char *)PyMem_RawRealloc(p, n+1);
if (pr == NULL) {
cumulative time (including nested imports) and self time (excluding\n\
nested imports). Note that its output may be broken in multi-threaded\n\
application. Typical usage is python3 -X importtime -c 'import asyncio'\n\
- -X dev: enable CPython’s “development mode”, introducing additional runtime\n\
+ -X dev: enable CPython's \"development mode\", introducing additional runtime\n\
checks which are too expensive to be enabled by default. Effect of the\n\
developer mode:\n\
* Add default warning filter, as -W default\n\
PySys_WriteStderr("'");
for (; *str != L'\0'; str++) {
- wchar_t ch = *str;
+ unsigned int ch = (unsigned int)*str;
if (ch == L'\'') {
PySys_WriteStderr("\\'");
} else if (0x20 <= ch && ch < 0x7f) {
va_end(lva);
if (res < 0) {
+ if (stack != small_stack) {
+ PyMem_Free(stack);
+ }
return NULL;
}
int
PyOS_mystrnicmp(const char *s1, const char *s2, Py_ssize_t size)
{
+ const unsigned char *p1, *p2;
if (size == 0)
return 0;
- while ((--size > 0) &&
- (tolower((unsigned)*s1) == tolower((unsigned)*s2))) {
- if (!*s1++ || !*s2++)
- break;
+ p1 = (const unsigned char *)s1;
+ p2 = (const unsigned char *)s2;
+ for (; (--size > 0) && *p1 && *p2 && (tolower(*p1) == tolower(*p2));
+ p1++, p2++) {
+ ;
}
- return tolower((unsigned)*s1) - tolower((unsigned)*s2);
+ return tolower(*p1) - tolower(*p2);
}
int
PyOS_mystricmp(const char *s1, const char *s2)
{
- while (*s1 && (tolower((unsigned)*s1++) == tolower((unsigned)*s2++))) {
+ const unsigned char *p1 = (const unsigned char *)s1;
+ const unsigned char *p2 = (const unsigned char *)s2;
+ for (; *p1 && *p2 && (tolower(*p1) == tolower(*p2)); p1++, p2++) {
;
}
- return (tolower((unsigned)*s1) - tolower((unsigned)*s2));
+ return (tolower(*p1) - tolower(*p2));
}
-This is Python version 3.8.5
+This is Python version 3.8.6
============================
.. image:: https://travis-ci.org/python/cpython.svg?branch=3.8
</metadata>
<files>
<file src="**\*" exclude="python.props" target="tools" />
- <file src="python.props" target="build\native" />
+ <file src="python.props" target="build\native\python.props" />
</files>
</package>
</metadata>
<files>
<file src="**\*" exclude="python.props" target="tools" />
- <file src="python.props" target="build\native" />
+ <file src="python.props" target="build\native\python.props" />
+ <file src="python.props" target="build\native\pythonarm32.props" />
</files>
</package>
</metadata>
<files>
<file src="**\*" exclude="python.props" target="tools" />
- <file src="python.props" target="build\native" />
+ <file src="python.props" target="build\native\python.props" />
+ <file src="python.props" target="build\native\pythondaily.props" />
</files>
</package>
</metadata>
<files>
<file src="**\*" exclude="python.props" target="tools" />
- <file src="python.props" target="build\native" />
+ <file src="python.props" target="build\native\python.props" />
+ <file src="python.props" target="build\native\pythonx86.props" />
</files>
</package>