From: DongHun Kwak Date: Wed, 9 Dec 2020 00:49:18 +0000 (+0900) Subject: Imported Upstream version 3.8.6 X-Git-Tag: upstream/3.8.6^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1af55148a1bcf9f73ffeff4b7518d48bb814fa0f;p=platform%2Fupstream%2Fpython3.git Imported Upstream version 3.8.6 --- diff --git a/Doc/Makefile b/Doc/Makefile index b8ca1edf..f653d706 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -143,7 +143,7 @@ clean: venv: $(PYTHON) -m venv $(VENVDIR) $(VENVDIR)/bin/python3 -m pip install -U pip setuptools - $(VENVDIR)/bin/python3 -m pip install -U Sphinx==2.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: diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst index b7baad58..a187a8fb 100644 --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -131,12 +131,12 @@ which disallows mutable objects such as :class:`bytearray`. ``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 @@ -183,7 +183,7 @@ which disallows mutable objects such as :class:`bytearray`. ``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 @@ -196,10 +196,10 @@ which disallows mutable objects such as :class:`bytearray`. 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. @@ -219,10 +219,10 @@ which disallows mutable objects such as :class:`bytearray`. 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 @@ -322,7 +322,7 @@ Other objects ``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. @@ -331,13 +331,13 @@ Other objects ``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. @@ -483,7 +483,7 @@ API Functions *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 @@ -652,8 +652,8 @@ Building values ``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*] diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst index 4e6fa0b3..dd091bb3 100644 --- a/Doc/c-api/buffer.rst +++ b/Doc/c-api/buffer.rst @@ -89,7 +89,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. .. 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 @@ -99,7 +99,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. 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 @@ -145,7 +145,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. 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) @@ -164,7 +164,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. 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 @@ -177,7 +177,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. 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 @@ -189,7 +189,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. 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 @@ -207,7 +207,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. 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 @@ -301,7 +301,7 @@ must be C-contiguous. +-----------------------------------+-------+---------+------------+--------+ | .. 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 | +-----------------------------------+-------+---------+------------+--------+ @@ -438,12 +438,12 @@ Buffer-related functions 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 `). Successful calls to :c:func:`PyObject_GetBuffer` must be paired with calls @@ -455,7 +455,7 @@ Buffer-related functions .. 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 @@ -514,9 +514,9 @@ Buffer-related functions *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 `, *exporter* MUST be set to the exporting object and *flags* must be passed diff --git a/Doc/c-api/capsule.rst b/Doc/c-api/capsule.rst index 78e21140..5eb313c8 100644 --- a/Doc/c-api/capsule.rst +++ b/Doc/c-api/capsule.rst @@ -15,7 +15,7 @@ Refer to :ref:`using-capsules` for more information on using these objects. .. 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 diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index e48c11d3..30905271 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -73,7 +73,7 @@ Dictionary Objects .. 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*. @@ -112,7 +112,7 @@ Dictionary Objects .. 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 @@ -161,7 +161,7 @@ Dictionary Objects 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 diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 85a3d941..a4c263f4 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -635,11 +635,21 @@ The following functions are used to create and modify Unicode exceptions from C. *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) @@ -761,7 +771,7 @@ Standard Exceptions 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:: @@ -981,7 +991,7 @@ Standard Warning Categories 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:: diff --git a/Doc/c-api/file.rst b/Doc/c-api/file.rst index 5370c4e3..ea027ee9 100644 --- a/Doc/c-api/file.rst +++ b/Doc/c-api/file.rst @@ -8,7 +8,7 @@ File Objects .. 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 @@ -17,7 +17,7 @@ error reporting in the interpreter; third-party code is advised to access 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* diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 68d892dc..e12f7c62 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -81,7 +81,7 @@ When a flag is set by an option, the value of the flag is the number of times 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 @@ -89,7 +89,7 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. 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). @@ -97,7 +97,7 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. 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. @@ -105,14 +105,14 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. 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. @@ -120,14 +120,14 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. 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 @@ -136,11 +136,11 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. 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. @@ -149,7 +149,7 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. .. 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. @@ -161,7 +161,7 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. .. 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. @@ -173,7 +173,7 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. .. 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 @@ -182,7 +182,7 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. Set by the :option:`-S` option. -.. c:var:: Py_NoUserSiteDirectory +.. c:var:: int Py_NoUserSiteDirectory Don't add the :data:`user site-packages directory ` to :data:`sys.path`. @@ -190,12 +190,12 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. 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. @@ -203,14 +203,14 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. .. 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 @@ -830,7 +830,7 @@ code, or when embedding the Python interpreter: .. 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. @@ -1516,7 +1516,7 @@ The Python interpreter provides low-level support for thread-local storage (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 @@ -1527,8 +1527,8 @@ you need to include :file:`pythread.h` to use thread-local storage. .. 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: @@ -1624,14 +1624,14 @@ undefined if the given :c:type:`Py_tss_t` has not been initialized by .. 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. diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index 718f40eb..fd1268e3 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -216,13 +216,13 @@ Objects, Types and Reference Counts .. 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. @@ -483,7 +483,7 @@ Types 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 diff --git a/Doc/c-api/marshal.rst b/Doc/c-api/marshal.rst index 7b179e22..7bb0dad2 100644 --- a/Doc/c-api/marshal.rst +++ b/Doc/c-api/marshal.rst @@ -43,7 +43,7 @@ The following functions allow marshalled values to be read back in. .. 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`. @@ -53,7 +53,7 @@ The following functions allow marshalled values to be read back in. .. 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`. @@ -63,7 +63,7 @@ The following functions allow marshalled values to be read back in. .. 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` @@ -72,7 +72,7 @@ The following functions allow marshalled values to be read back in. .. 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 diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index 8a8542f0..87425bcf 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -109,7 +109,7 @@ zero bytes. .. 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 @@ -120,7 +120,7 @@ zero bytes. .. 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 @@ -180,7 +180,7 @@ The :ref:`default memory allocator ` uses the .. 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 @@ -191,7 +191,7 @@ The :ref:`default memory allocator ` uses the .. 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 @@ -233,14 +233,14 @@ The following type-oriented macros are provided for convenience. Note that .. 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. @@ -282,7 +282,7 @@ The :ref:`default object allocator ` uses the .. 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 @@ -293,7 +293,7 @@ The :ref:`default object allocator ` uses the .. 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 @@ -388,7 +388,7 @@ Customize Memory Allocators Enum used to identify an allocator domain. Domains: - .. c:var:: PYMEM_DOMAIN_RAW + .. c:macro:: PYMEM_DOMAIN_RAW Functions: @@ -397,7 +397,7 @@ Customize Memory Allocators * :c:func:`PyMem_RawCalloc` * :c:func:`PyMem_RawFree` - .. c:var:: PYMEM_DOMAIN_MEM + .. c:macro:: PYMEM_DOMAIN_MEM Functions: @@ -406,7 +406,7 @@ Customize Memory Allocators * :c:func:`PyMem_Calloc` * :c:func:`PyMem_Free` - .. c:var:: PYMEM_DOMAIN_OBJ + .. c:macro:: PYMEM_DOMAIN_OBJ Functions: @@ -519,11 +519,11 @@ Customize pymalloc Arena Allocator | ``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. diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index d2b8f4c1..f840dd90 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -301,7 +301,7 @@ The *m_slots* array must be terminated by a slot with id 0. 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: @@ -333,7 +333,7 @@ The available slot types are: ``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, diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 3bdc0f56..d4e8b746 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -290,7 +290,7 @@ Object Protocol 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 @@ -311,17 +311,17 @@ Object Protocol 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 @@ -331,11 +331,11 @@ Object Protocol ``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 @@ -377,7 +377,7 @@ Object Protocol .. 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 @@ -463,7 +463,7 @@ Object Protocol 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. diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 2dc0762e..e9c276ce 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -105,7 +105,7 @@ the definition of all other Python objects. .. 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 @@ -151,10 +151,10 @@ the definition of all other Python objects. +------------------+---------------+-------------------------------+ 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. @@ -168,7 +168,7 @@ also keyword arguments. So there are a total of 6 calling conventions: .. 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 @@ -189,7 +189,7 @@ also keyword arguments. So there are a total of 6 calling conventions: 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 `. @@ -202,7 +202,7 @@ also keyword arguments. So there are a total of 6 calling conventions: 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. @@ -226,7 +226,7 @@ also keyword arguments. So there are a total of 6 calling conventions: 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 @@ -359,7 +359,7 @@ definition with the same method name. | | | 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 *); @@ -367,7 +367,7 @@ definition with the same method name. 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 *); diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst index 25df3974..d7acc4ea 100644 --- a/Doc/c-api/tuple.rst +++ b/Doc/c-api/tuple.rst @@ -166,7 +166,7 @@ type. .. 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. diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 163f599d..3d186231 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -1360,7 +1360,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) 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. @@ -1398,7 +1398,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) 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 diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index b261efe2..9b68c31e 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -34,6 +34,11 @@ can internally be in two states depending on how they were created: :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 """""""""""" @@ -107,6 +112,9 @@ access internal read-only data of Unicode objects: .. 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) @@ -138,6 +146,9 @@ access internal read-only data of Unicode objects: .. versionadded:: 3.3 + .. deprecated-removed:: 3.10 3.12 + ``PyUnicode_WCHAR_KIND`` is deprecated. + .. c:function:: int PyUnicode_KIND(PyObject *o) @@ -188,7 +199,7 @@ access internal read-only data of Unicode objects: .. 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 @@ -208,7 +219,7 @@ access internal read-only data of Unicode objects: 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`. @@ -218,7 +229,7 @@ access internal read-only data of Unicode objects: 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`. @@ -240,7 +251,7 @@ access internal read-only data of Unicode objects: 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. @@ -682,8 +693,10 @@ Extension modules can continue using them, as they will not be removed in Python 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) @@ -696,9 +709,10 @@ Extension modules can continue using them, as they will not be removed in Python 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 @@ -720,6 +734,11 @@ Extension modules can continue using them, as they will not be removed in Python .. 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) @@ -740,7 +759,9 @@ Extension modules can continue using them, as they will not be removed in Python 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) @@ -1477,17 +1498,21 @@ These are the mapping codec APIs: 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, \ @@ -1590,23 +1615,6 @@ They all return ``NULL`` or ``-1`` if an exception occurs. 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 diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index 98cea52a..208a14e6 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -16,11 +16,11 @@ parameter. The available start symbols are :const:`Py_eval_input`, :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. diff --git a/Doc/conf.py b/Doc/conf.py index abaa760c..4cca13b1 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -226,3 +226,13 @@ linkcheck_ignore = [r'https://bugs.python.org/(issue)?\d+', # 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 diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst index 0eb6ffd0..4da77e79 100644 --- a/Doc/extending/newtypes_tutorial.rst +++ b/Doc/extending/newtypes_tutorial.rst @@ -416,7 +416,7 @@ But this would be risky. Our type doesn't restrict the type of the ``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 ` 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 diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index e7921baf..f91b51bf 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -571,8 +571,7 @@ whether an instance or a class implements a particular ABC. The :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 diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 6cc1b52e..70e9190e 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -35,12 +35,6 @@ for Windows Extensions `__ project an as a part of the ActivePython distribution (see https://www.activestate.com/activepython\ ). -`Boa Constructor `_ 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 `_ is an IDE built on PyQt and the Scintilla editing component. @@ -57,22 +51,14 @@ They include: * 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 `_ 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 `_ and +`Pyflakes `_ do basic checking that will +help you catch bugs sooner. Static type checkers such as `Mypy `_, `Pyre `_, and @@ -518,14 +504,14 @@ desired effect in a number of ways. 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. @@ -533,38 +519,41 @@ desired effect in a number of ways. 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. diff --git a/Doc/glossary.rst b/Doc/glossary.rst index e997d366..7be755e4 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -587,7 +587,7 @@ Glossary and :class:`tuple`) and some non-sequence types like :class:`dict`, :term:`file objects `, 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 ` semantics. Iterables can be used in a :keyword:`for` loop and in many other places where a sequence is diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index 9856e6ca..4d25d2cc 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -312,14 +312,12 @@ Running the interpreter shows how the function descriptor works in practice:: >>> d.f > - # 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__ >>> d.f.__self__ <__main__.D object at 0x1012e1f98> - >>> d.f.__class__ - Static Methods and Class Methods diff --git a/Doc/howto/instrumentation.rst b/Doc/howto/instrumentation.rst index 909deb5f..f0081e4e 100644 --- a/Doc/howto/instrumentation.rst +++ b/Doc/howto/instrumentation.rst @@ -272,9 +272,7 @@ should instead read: 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. @@ -290,7 +288,7 @@ Available static markers * ``$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 @@ -298,7 +296,7 @@ Available static markers 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 @@ -306,24 +304,24 @@ Available static markers 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 @@ -332,7 +330,7 @@ Available static markers .. 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` @@ -375,14 +373,14 @@ If this file is installed in SystemTap's tapset directory (e.g. ``/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. diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index 17f4ff6e..de0f8345 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -1368,7 +1368,7 @@ An example dictionary-based configuration ----------------------------------------- Below is an example of a logging configuration dictionary - it's taken from -the `documentation on the Django project `_. +the `documentation on the Django project `_. This dictionary is passed to :func:`~config.dictConfig` to put the configuration into effect:: LOGGING = { @@ -1424,7 +1424,7 @@ This dictionary is passed to :func:`~config.dictConfig` to put the configuration } For more information about this configuration, you can see the `relevant -section `_ +section `_ of the Django documentation. .. _cookbook-rotator-namer: diff --git a/Doc/library/__future__.rst b/Doc/library/__future__.rst index e3d749e6..41399942 100644 --- a/Doc/library/__future__.rst +++ b/Doc/library/__future__.rst @@ -90,7 +90,7 @@ language using this mechanism: | 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* | +------------------+-------------+--------------+---------------------------------------------+ diff --git a/Doc/library/aifc.rst b/Doc/library/aifc.rst index 73289077..2e917cf7 100644 --- a/Doc/library/aifc.rst +++ b/Doc/library/aifc.rst @@ -208,6 +208,7 @@ number of frames must be filled in. .. method:: aifc.tell() + :noindex: Return the current write position in the output file. Useful in combination with :meth:`setmark`. @@ -232,6 +233,7 @@ number of frames must be filled in. .. 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 diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index e1b28e32..2ec7ea3e 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -1123,8 +1123,8 @@ keyword argument to :meth:`~ArgumentParser.add_argument`:: >>> 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 diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index 6ca27609..67c6392a 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -343,5 +343,24 @@ and classes for traversing abstract syntax trees: .. seealso:: - `Green Tree Snakes `_, an external documentation resource, has good - details on working with Python ASTs. + `Green Tree Snakes `_, an external + documentation resource, has good details on working with Python ASTs. + + `ASTTokens `_ + 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 `_ unifies the + token-based and parse-tree-based views of python programs by inserting + two-way links between tokens and ast nodes. + + `LibCST `_ 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 `_ 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 diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst index 0d302ea4..d7ed9628 100644 --- a/Doc/library/asyncio-dev.rst +++ b/Doc/library/asyncio-dev.rst @@ -107,6 +107,16 @@ The :meth:`loop.run_in_executor` method can be used with a 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 ` +section lists APIs that can read from pipes and watch file descriptors +without blocking the event loop. In addition, asyncio's +:ref:`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: diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst index 2a3fb142..db0e25bb 100644 --- a/Doc/library/collections.abc.rst +++ b/Doc/library/collections.abc.rst @@ -98,12 +98,20 @@ ABC Inherits from Abstract Methods Mixin .. 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 @@ -185,7 +193,7 @@ ABC Inherits from Abstract Methods Mixin expressions. Custom implementations must provide the :meth:`__await__` method. - :term:`Coroutine` objects and instances of the + :term:`Coroutine ` objects and instances of the :class:`~collections.abc.Coroutine` ABC are all instances of this ABC. .. note:: diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index 41d47c7e..88c1d23a 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -209,7 +209,8 @@ ProcessPoolExecutor 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 +` but also means that only picklable objects can be executed and returned. The ``__main__`` module must be importable by worker subprocesses. This means diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index 739477f5..2e22a549 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -674,97 +674,98 @@ be overridden by subclasses or by attribute assignment. .. 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
[^]]+?) *\]") + >>> 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
[^]]+?) *\]") - >>> 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 diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index cbd68834..7cd20253 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -214,7 +214,7 @@ The module :mod:`curses` defines the following functions: .. 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 @@ -682,7 +682,7 @@ the following methods and attributes: 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:: diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index ada311bc..a8543b38 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -18,12 +18,13 @@ -------------- 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 @@ -648,6 +649,7 @@ The :class:`Differ` class has this constructor: .. class:: Differ(linejunk=None, charjunk=None) + :noindex: Optional keyword parameters *linejunk* and *charjunk* are for filter functions (or ``None``): diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 5b34e68c..015be202 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -640,7 +640,7 @@ the original TOS1. .. 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) diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index 2649b7d8..bd10016b 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -19,6 +19,12 @@ An enumeration is a set of symbolic names (members) bound to unique, 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 --------------- @@ -50,6 +56,7 @@ helper, :class:`auto`. 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. @@ -743,9 +750,11 @@ Some rules: :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 `, :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__` ------------------------------------------------ @@ -879,6 +888,32 @@ Using an auto-numbering :meth:`__new__` would look like:: >>> 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.pantone + '1246' + >>> Swatch.BLEACHED_CORAL.pantone + 'unknown' .. note:: diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 0f7df0e5..6003898d 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -581,7 +581,7 @@ are always available. They are listed here in alphabetical order. input must conform to the following grammar after leading and trailing whitespace characters are removed: - .. productionlist:: + .. productionlist:: float sign: "+" | "-" infinity: "Infinity" | "inf" nan: "nan" @@ -1035,7 +1035,8 @@ are always available. They are listed here in alphabetical order. .. 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 @@ -1713,6 +1714,9 @@ are always available. They are listed here in alphabetical order. 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) diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst index 13eda917..adaa3029 100644 --- a/Doc/library/gc.rst +++ b/Doc/library/gc.rst @@ -106,9 +106,9 @@ The :mod:`gc` module provides the following functions: 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 `_ for more information. .. function:: get_count() diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst index 92a8c4d1..3c468ebf 100644 --- a/Doc/library/glob.rst +++ b/Doc/library/glob.rst @@ -43,7 +43,9 @@ For example, ``'[?]'`` matches the character ``'?'``. (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 diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 75b6fa38..a59a5d3a 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -491,7 +491,7 @@ in the settings dialog. (To prevent auto popups, set the delay to a 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. @@ -527,30 +527,33 @@ by typing '_' after '.', either before or after the box is opened. 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: diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst index df63d820..b3d53372 100644 --- a/Doc/library/imaplib.rst +++ b/Doc/library/imaplib.rst @@ -132,7 +132,7 @@ The following utility functions are defined: .. 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``]. @@ -186,7 +186,7 @@ you want to avoid having an argument string quoted (eg: the *flags* argument to 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). diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 2de10435..f205f5fe 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1036,7 +1036,7 @@ find and load modules. .. class:: WindowsRegistryFinder - :term:`Finder` for modules declared in the Windows registry. This class + :term:`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 @@ -1051,7 +1051,7 @@ find and load modules. .. class:: PathFinder - A :term:`Finder` for :data:`sys.path` and package ``__path__`` attributes. + A :term:`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 diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index bb3ee87a..a0f814ed 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -14,7 +14,8 @@ Introduction :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 ` 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. diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 77bbf998..c8e316a7 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -1828,6 +1828,8 @@ features: 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), @@ -2233,7 +2235,9 @@ features: 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 @@ -2983,7 +2987,10 @@ features: *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 diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index b900d093..c855a6e1 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -849,6 +849,11 @@ call fails (for example because the path doesn't exist). 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 @@ -1078,7 +1083,7 @@ call fails (for example because the path doesn't exist). Create a hard link pointing to a path named *target*. - .. versionchanged:: 3.8 + .. versionadded:: 3.8 .. method:: Path.write_bytes(data) @@ -1139,9 +1144,12 @@ os and os.path pathlib :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` diff --git a/Doc/library/pkgutil.rst b/Doc/library/pkgutil.rst index 78a51573..9a24e7a7 100644 --- a/Doc/library/pkgutil.rst +++ b/Doc/library/pkgutil.rst @@ -68,7 +68,7 @@ support. .. class:: ImpLoader(fullname, file, filename, etc) - :term:`Loader` that wraps Python's "classic" import algorithm. + :term:`Loader ` that wraps Python's "classic" import algorithm. .. deprecated:: 3.3 This emulation is no longer needed, as the standard import mechanism diff --git a/Doc/library/py_compile.rst b/Doc/library/py_compile.rst index a12a5bb0..cac6dcb6 100644 --- a/Doc/library/py_compile.rst +++ b/Doc/library/py_compile.rst @@ -35,7 +35,7 @@ byte-code cache files in the directory containing the source code. 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 diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index c72f22b5..9ab050e8 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -1627,7 +1627,9 @@ to sockets. .. 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 diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index ea0f13c4..04523e91 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -615,7 +615,7 @@ Constants Possible value for :attr:`SSLContext.verify_flags`. In this mode, only the peer cert is checked but none of the intermediate CA certificates. The mode requires a valid CRL that is signed by the peer cert's issuer (its direct - ancestor CA). If no proper CRL has has been loaded with + ancestor CA). If no proper CRL has been loaded with :attr:`SSLContext.load_verify_locations`, validation will fail. .. versionadded:: 3.4 diff --git a/Doc/library/string.rst b/Doc/library/string.rst index fa906f79..91f43e93 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -205,7 +205,7 @@ literal text, it can be escaped by doubling: ``{{`` and ``}}``. 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`+] @@ -308,7 +308,7 @@ non-empty format specification typically modifies the result. 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: align: "<" | ">" | "=" | "^" diff --git a/Doc/library/struct.rst b/Doc/library/struct.rst index 56b0a361..278cb19f 100644 --- a/Doc/library/struct.rst +++ b/Doc/library/struct.rst @@ -159,8 +159,8 @@ the :ref:`format-characters` section. 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 `_. There is no way to indicate non-native byte order (force byte-swapping); use the appropriate choice of ``'<'`` or ``'>'``. @@ -467,3 +467,5 @@ The :mod:`struct` module also defines the following type: .. _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 diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst index d60f1c8a..87c36aa4 100644 --- a/Doc/library/tarfile.rst +++ b/Doc/library/tarfile.rst @@ -151,6 +151,7 @@ Some facts and figures: .. 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`. diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index a59817c1..f9421da5 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -31,7 +31,7 @@ is recommended to use keyword arguments for clarity. 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 @@ -72,7 +72,7 @@ The module defines the following user-callable items: 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 @@ -93,7 +93,7 @@ The module defines the following user-callable items: 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 @@ -175,9 +175,8 @@ The module defines the following user-callable items: 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 diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index f4b58d3d..4c78e6e1 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -395,7 +395,8 @@ since it is impossible to detect the termination of alien threads. .. impl-detail:: - In CPython, due to the :term:`Global Interpreter Lock`, only one thread + In CPython, due to the :term:`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 diff --git a/Doc/library/timeit.rst b/Doc/library/timeit.rst index 46fa62c1..668fcb86 100644 --- a/Doc/library/timeit.rst +++ b/Doc/library/timeit.rst @@ -233,7 +233,7 @@ Where the following options are understood: .. 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 diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index e1fc051d..79633b77 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -31,7 +31,7 @@ installed, so you can read the Tcl/Tk documentation specific to that version. `TKDocs `_ Extensive tutorial plus friendlier widget pages for some of the widgets. - `Tkinter 8.5 reference: a GUI for Python `_ + `Tkinter 8.5 reference: a GUI for Python `_ On-line reference material. `Tkinter docs from effbot `_ @@ -464,12 +464,11 @@ The Packer .. 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 @@ -542,31 +541,35 @@ the variable, with no further intervention on your part. 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('', - 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 ^^^^^^^^^^^^^^^^^^ diff --git a/Doc/library/token.rst b/Doc/library/token.rst index dab8f0fa..7f598cd3 100644 --- a/Doc/library/token.rst +++ b/Doc/library/token.rst @@ -70,6 +70,7 @@ the :mod:`tokenize` module. .. 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 diff --git a/Doc/library/turtle.rst b/Doc/library/turtle.rst index fed85045..d3487537 100644 --- a/Doc/library/turtle.rst +++ b/Doc/library/turtle.rst @@ -1069,6 +1069,7 @@ More drawing control ~~~~~~~~~~~~~~~~~~~~ .. function:: reset() + :noindex: Delete the turtle's drawings from the screen, re-center the turtle and set variables to the default values. @@ -1090,6 +1091,7 @@ More drawing control .. 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. @@ -1362,6 +1364,7 @@ Using events ------------ .. 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 diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 1467276d..0706bc87 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -324,7 +324,7 @@ every type as being compatible with :data:`Any` and :data:`Any` as being 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 @@ -733,7 +733,7 @@ The module defines the following classes, functions and decorators: .. 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 diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index d9f080a8..67c5fa61 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -73,7 +73,7 @@ test runner for those new to unit testing. For production environments it is recommended that tests be driven by a continuous integration system such as `Buildbot `_, `Jenkins `_ - or `Hudson `_. + or `Travis-CI `_, or `AppVeyor `_. .. _unittest-minimal-example: diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index adc0593e..0edf116f 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -954,7 +954,7 @@ tracking URIs for which authentication credentials should always be sent. 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 diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index 1e30aa4a..e92a689d 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -480,8 +480,8 @@ input, output, and error streams. 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 diff --git a/Doc/library/xml.rst b/Doc/library/xml.rst index fb86b6f5..1981cab7 100644 --- a/Doc/library/xml.rst +++ b/Doc/library/xml.rst @@ -20,7 +20,7 @@ Python's interfaces for processing XML are grouped in the ``xml`` package. 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 @@ -113,9 +113,9 @@ decompression bomb 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 @@ -124,16 +124,8 @@ package is recommended for any server code that parses untrusted XML data. The 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 diff --git a/Doc/license.rst b/Doc/license.rst index 472a5cf3..f70c34d3 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -72,6 +72,19 @@ make these releases possible. Terms and conditions for accessing or otherwise using Python ============================================================ +Python software and documentation are licensed under the +:ref:`PSF License Agreement `. + +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 `. + +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| ------------------------------------------ @@ -258,6 +271,27 @@ CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 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 ======================================================= diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index feaf3109..6900c7ac 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -44,7 +44,8 @@ executed:: Summarizing: -.. productionlist:: + +.. productionlist:: python-grammar compound_stmt: `if_stmt` : | `while_stmt` : | `for_stmt` @@ -89,7 +90,7 @@ The :keyword:`!if` statement 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`] @@ -115,7 +116,7 @@ The :keyword:`!while` statement 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`] @@ -151,7 +152,7 @@ The :keyword:`!for` statement 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`] @@ -234,7 +235,7 @@ The :keyword:`!try` statement 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`)+ @@ -390,7 +391,7 @@ methods defined by a context manager (see section :ref:`context-managers`). 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`] @@ -503,7 +504,7 @@ Function definitions 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`+ @@ -665,7 +666,7 @@ Class definitions 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` @@ -752,7 +753,7 @@ Coroutines Coroutine function definition ----------------------------- -.. productionlist:: +.. productionlist:: python-grammar async_funcdef: [`decorators`] "async" "def" `funcname` "(" [`parameter_list`] ")" : ["->" `expression`] ":" `suite` @@ -785,7 +786,7 @@ An example of a coroutine function:: 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 @@ -830,7 +831,7 @@ body of a coroutine function. 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 diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index d364e61b..3f053858 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2404,6 +2404,13 @@ left undefined. :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) @@ -2596,7 +2603,7 @@ Awaitable Objects ----------------- An :term:`awaitable` object generally implements an :meth:`__await__` method. -:term:`Coroutine` objects returned from :keyword:`async def` functions +:term:`Coroutine objects ` returned from :keyword:`async def` functions are awaitable. .. note:: @@ -2621,7 +2628,7 @@ are awaitable. Coroutine Objects ----------------- -:term:`Coroutine` objects are :term:`awaitable` objects. +:term:`Coroutine objects ` 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 diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 8036a491..b68c2986 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -13,7 +13,7 @@ This chapter explains the meaning of the elements of expressions in Python. 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 @@ -54,7 +54,7 @@ Atoms are the most basic elements of expressions. The simplest atoms are 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` @@ -103,7 +103,7 @@ Literals Python supports string and bytes literals and various numeric literals: -.. productionlist:: +.. productionlist:: python-grammar literal: `stringliteral` | `bytesliteral` : | `integer` | `floatnumber` | `imagnumber` @@ -134,7 +134,7 @@ Parenthesized forms 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 @@ -177,7 +177,7 @@ called "displays", each of them in two flavors: 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` @@ -243,7 +243,7 @@ List displays 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 @@ -267,7 +267,7 @@ Set displays 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 @@ -296,7 +296,7 @@ Dictionary displays 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` @@ -355,7 +355,7 @@ Generator expressions 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 @@ -409,7 +409,7 @@ Yield expressions pair: yield; expression pair: generator; function -.. productionlist:: +.. productionlist:: python-grammar yield_atom: "(" `yield_expression` ")" yield_expression: "yield" [`expression_list` | "from" `expression`] @@ -746,7 +746,7 @@ Primaries Primaries represent the most tightly bound operations of the language. Their syntax is: -.. productionlist:: +.. productionlist:: python-grammar primary: `atom` | `attributeref` | `subscription` | `slicing` | `call` @@ -761,7 +761,7 @@ Attribute references An attribute reference is a primary followed by a period and a name: -.. productionlist:: +.. productionlist:: python-grammar attributeref: `primary` "." `identifier` .. index:: @@ -799,7 +799,7 @@ Subscriptions 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 @@ -855,7 +855,7 @@ A slicing selects a range of items in a sequence object (e.g., a string, tuple 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` @@ -905,7 +905,7 @@ Calls A call calls a callable object (e.g., a :term:`function`) with a possibly empty series of :term:`arguments `: -.. productionlist:: +.. productionlist:: python-grammar call: `primary` "(" [`argument_list` [","] | `comprehension`] ")" argument_list: `positional_arguments` ["," `starred_and_keywords`] : ["," `keywords_arguments`] @@ -1088,7 +1088,7 @@ Await expression 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 @@ -1106,7 +1106,7 @@ The power operator 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 @@ -1139,7 +1139,7 @@ Unary arithmetic and bitwise operations All unary arithmetic and bitwise operations have the same priority: -.. productionlist:: +.. productionlist:: python-grammar u_expr: `power` | "-" `u_expr` | "+" `u_expr` | "~" `u_expr` .. index:: @@ -1183,7 +1183,7 @@ that some of these operations also apply to certain non-numeric types. Apart 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` @@ -1279,7 +1279,7 @@ Shifting operations 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 @@ -1300,7 +1300,7 @@ Binary bitwise operations 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` @@ -1349,7 +1349,7 @@ lower than that of any arithmetic, shifting or bitwise operation. Also unlike 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" @@ -1608,7 +1608,7 @@ Boolean operations 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` @@ -1647,12 +1647,29 @@ returns a boolean value regardless of the type of its argument 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: @@ -1666,7 +1683,7 @@ Conditional expressions 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` @@ -1693,7 +1710,7 @@ Lambdas 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` @@ -1720,7 +1737,7 @@ Expression lists 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`] diff --git a/Doc/reference/introduction.rst b/Doc/reference/introduction.rst index bb7e3906..72e874ee 100644 --- a/Doc/reference/introduction.rst +++ b/Doc/reference/introduction.rst @@ -93,7 +93,7 @@ Notation 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" diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index d0e7fde0..f74ff794 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -296,7 +296,7 @@ Unicode Character Database as included in the :mod:`unicodedata` module. Identifiers are unlimited in length. Case is significant. -.. productionlist:: +.. productionlist:: python-grammar identifier: `xid_start` `xid_continue`* id_start: id_continue: @@ -412,7 +412,7 @@ String and Bytes literals 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" @@ -424,7 +424,7 @@ String literals are described by the following lexical definitions: longstringchar: stringescapeseq: "\" -.. productionlist:: +.. productionlist:: python-grammar bytesliteral: `bytesprefix`(`shortbytes` | `longbytes`) bytesprefix: "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | "Rb" | "RB" shortbytes: "'" `shortbytesitem`* "'" | '"' `shortbytesitem`* '"' @@ -637,9 +637,11 @@ and formatted string literals may be concatenated with plain string literals. 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 @@ -657,9 +659,9 @@ Escape sequences are decoded like in ordinary string literals (except when 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` @@ -671,10 +673,11 @@ The parts of the string outside curly braces are treated literally, 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. @@ -690,6 +693,17 @@ left to right. 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`. @@ -724,9 +738,22 @@ Some examples of formatted string literals:: >>> 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 @@ -793,7 +820,7 @@ Integer literals 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`)+ @@ -837,7 +864,7 @@ Floating point literals 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` @@ -867,7 +894,7 @@ Imaginary literals 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 diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index a8ec0fbe..93be3271 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -11,7 +11,7 @@ A simple statement is comprised within a single logical line. Several simple 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` @@ -46,7 +46,7 @@ result; in Python, procedures return the value ``None``). Other uses of 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 @@ -82,7 +82,7 @@ Assignment statements 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` @@ -280,7 +280,7 @@ Augmented assignment statements 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: "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**=" @@ -328,7 +328,7 @@ Annotated assignment statements :term:`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`)] @@ -385,7 +385,7 @@ The :keyword:`!assert` statement 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 :: @@ -425,7 +425,7 @@ The :keyword:`!pass` statement 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. @@ -447,7 +447,7 @@ The :keyword:`!del` statement 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. @@ -486,7 +486,7 @@ The :keyword:`!return` statement 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, @@ -525,7 +525,7 @@ The :keyword:`!yield` statement single: function; generator exception: StopIteration -.. productionlist:: +.. productionlist:: python-grammar yield_stmt: `yield_expression` A :keyword:`yield` statement is semantically equivalent to a :ref:`yield @@ -560,7 +560,7 @@ The :keyword:`!raise` statement 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 @@ -663,7 +663,7 @@ The :keyword:`!break` statement statement: while pair: loop; statement -.. productionlist:: +.. productionlist:: python-grammar break_stmt: "break" :keyword:`break` may only occur syntactically nested in a :keyword:`for` or @@ -698,7 +698,7 @@ The :keyword:`!continue` statement pair: loop; statement keyword: finally -.. productionlist:: +.. productionlist:: python-grammar continue_stmt: "continue" :keyword:`continue` may only occur syntactically nested in a :keyword:`for` or @@ -725,7 +725,7 @@ The :keyword:`!import` statement 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`])* @@ -859,7 +859,7 @@ that introduce incompatible changes to the language. It allows use of the new 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`] @@ -937,7 +937,7 @@ The :keyword:`!global` statement 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 @@ -982,7 +982,7 @@ The :keyword:`!nonlocal` statement .. index:: statement: nonlocal single: , (comma); identifier list -.. productionlist:: +.. productionlist:: python-grammar nonlocal_stmt: "nonlocal" `identifier` ("," `identifier`)* .. XXX add when implemented diff --git a/Doc/reference/toplevel_components.rst b/Doc/reference/toplevel_components.rst index d5ffb37b..319c9de4 100644 --- a/Doc/reference/toplevel_components.rst +++ b/Doc/reference/toplevel_components.rst @@ -66,7 +66,7 @@ File input 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: @@ -85,7 +85,7 @@ Interactive input 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 @@ -103,5 +103,5 @@ Expression input :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* diff --git a/Doc/requirements.txt b/Doc/requirements.txt new file mode 100644 index 00000000..47b78eea --- /dev/null +++ b/Doc/requirements.txt @@ -0,0 +1,12 @@ +# 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 diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index a128c705..e3369cdc 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -31,7 +31,12 @@ from sphinx.util import status_iterator, logging 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 @@ -238,17 +243,18 @@ class PyDecoratorMixin(object): 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): @@ -265,31 +271,31 @@ class PyAwaitableMixin(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) @@ -299,7 +305,7 @@ class PyAbstractMethod(PyClassmember): def run(self): self.name = 'py:method' - return PyClassmember.run(self) + return PyMethod.run(self) # Support for documenting version of removal in deprecations diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index 685552f9..0d780e3b 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -849,7 +849,7 @@ defines :meth:`__next__`, then :meth:`__iter__` can just return ``self``:: Generators ========== -:term:`Generator`\s are a simple and powerful tool for creating iterators. They +:term:`Generators ` 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 diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index de2c73a3..3af288a1 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -207,15 +207,15 @@ iteration of the loop:: ... 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: @@ -658,7 +658,7 @@ Finally, consider this function definition which has a potential collision betwe 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): diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst index ca3eda05..06bee996 100644 --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -2311,7 +2311,7 @@ Multi-threading =============== * 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 diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index f1a033c6..361e6db0 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -2309,9 +2309,9 @@ Encoders: :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` diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst index b4540ac1..1defee40 100644 --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -412,7 +412,7 @@ uses were to provide type hints to function parameters and return values. It 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 ` to +:pep:`484` introduces a :term:`provisional module ` to provide these standard definitions and tools, along with some conventions for situations where annotations are not available. @@ -726,7 +726,7 @@ New Modules typing ------ -The new :mod:`typing` :term:`provisional ` module +The new :mod:`typing` :term:`provisional ` module provides standard definitions and tools for function type annotations. See :ref:`Type Hints ` for more information. @@ -772,7 +772,7 @@ Steven Bethard, paul j3 and Daniel Eriksson in :issue:`14910`.) asyncio ------- -Since the :mod:`asyncio` module is :term:`provisional `, +Since the :mod:`asyncio` module is :term:`provisional `, 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: @@ -1867,7 +1867,7 @@ A new :func:`~sys.set_coroutine_wrapper` function allows setting a global hook that will be called whenever a :term:`coroutine object ` 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 `, +wrapper. Both functions are :term:`provisional `, and are intended for debugging purposes only. (Contributed by Yury Selivanov in :issue:`24017`.) diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst index 04c1f7e7..85a6657f 100644 --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -1597,7 +1597,7 @@ to filter block traces by their address space (domain). typing ------ -Since the :mod:`typing` module is :term:`provisional `, +Since the :mod:`typing` module is :term:`provisional `, all changes introduced in Python 3.6 have also been backported to Python 3.5.x. diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index b9b50216..4933cba3 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -171,7 +171,7 @@ on a per-module basis in Python 3.7 using a :mod:`__future__` import:: from __future__ import annotations -It will become the default in Python 4.0. +It will become the default in Python 3.10. .. seealso:: @@ -636,7 +636,7 @@ The :mod:`asyncio` module has received many new features, usability and :ref:`performance improvements `. Notable changes include: -* The new :term:`provisional ` :func:`asyncio.run` function can +* The new :term:`provisional ` :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`.) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 475e3ab9..7a86e511 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -1695,7 +1695,7 @@ Deprecated :meth:`~gettext.NullTranslations.set_output_charset`, and the *codeset* parameter of functions :func:`~gettext.translation` and :func:`~gettext.install` are also deprecated, since they are only used for - for the ``l*gettext()`` functions. + the ``l*gettext()`` functions. (Contributed by Serhiy Storchaka in :issue:`33710`.) * The :meth:`~threading.Thread.isAlive()` method of :class:`threading.Thread` diff --git a/Include/cpython/pyerrors.h b/Include/cpython/pyerrors.h index e3098b39..418f48a7 100644 --- a/Include/cpython/pyerrors.h +++ b/Include/cpython/pyerrors.h @@ -148,7 +148,10 @@ PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject( 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, @@ -158,7 +161,10 @@ Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_Create( 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, diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 25fc2d3a..5123b260 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -18,12 +18,12 @@ /*--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. diff --git a/LICENSE b/LICENSE index 66a3ac80..f42f8adb 100644 --- a/LICENSE +++ b/LICENSE @@ -59,6 +59,17 @@ direction to make these releases possible. 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 -------------------------------------------- @@ -252,3 +263,17 @@ 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. + +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. diff --git a/Lib/__future__.py b/Lib/__future__.py index d7cb8ac5..0e7b5552 100644 --- a/Lib/__future__.py +++ b/Lib/__future__.py @@ -66,18 +66,20 @@ __all__ = ["all_feature_names"] + all_feature_names # 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 @@ -88,7 +90,6 @@ class _Feature: This is a 5-tuple, of the same form as sys.version_info. """ - return self.optional def getMandatoryRelease(self): @@ -97,7 +98,6 @@ class _Feature: 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): @@ -105,6 +105,7 @@ class _Feature: self.mandatory, self.compiler_flag)) + nested_scopes = _Feature((2, 1, 0, "beta", 1), (2, 2, 0, "alpha", 0), CO_NESTED) @@ -142,5 +143,5 @@ generator_stop = _Feature((3, 5, 0, "beta", 1), CO_FUTURE_GENERATOR_STOP) annotations = _Feature((3, 7, 0, "beta", 1), - (4, 0, 0, "alpha", 0), + (3, 10, 0, "alpha", 0), CO_FUTURE_ANNOTATIONS) diff --git a/Lib/ast.py b/Lib/ast.py index 99a1148a..d29db80a 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -144,9 +144,14 @@ def copy_location(new_node, old_node): 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 @@ -194,8 +199,11 @@ def increment_lineno(node, n=1): 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 diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index ca08663a..353a9f5a 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -280,7 +280,7 @@ class AbstractEventLoop: 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): diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index 830d8edc..3e0a14f6 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -766,6 +766,14 @@ class BaseProactorEventLoop(base_events.BaseEventLoop): 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 @@ -783,8 +791,17 @@ class BaseProactorEventLoop(base_events.BaseEventLoop): 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 " diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index 2e37e18b..d2fa8b7f 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -5,7 +5,7 @@ from . import events 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 @@ -39,7 +39,8 @@ def run(main, *, debug=False): 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: diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index a05cbb6b..6ba30716 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -133,14 +133,16 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): # 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, diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 66e81f92..9ca9fa0a 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -460,8 +460,13 @@ async def wait_for(fut, timeout, *, loop=None): 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) @@ -475,9 +480,12 @@ async def wait_for(fut, timeout, *, loop=None): 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() diff --git a/Lib/asyncio/transports.py b/Lib/asyncio/transports.py index 513b1c02..45e155c9 100644 --- a/Lib/asyncio/transports.py +++ b/Lib/asyncio/transports.py @@ -29,8 +29,8 @@ class BaseTransport: 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 diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py index ac51109f..a5ad6fc4 100644 --- a/Lib/asyncio/windows_events.py +++ b/Lib/asyncio/windows_events.py @@ -318,8 +318,12 @@ class ProactorEventLoop(proactor_events.BaseProactorEventLoop): 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 @@ -469,7 +473,7 @@ class IocpProactor: else: ov.ReadFileInto(conn.fileno(), buf) except BrokenPipeError: - return self._result(b'') + return self._result(0) def finish_recv(trans, key, ov): try: diff --git a/Lib/codeop.py b/Lib/codeop.py index 3c2bb608..04ca6b93 100644 --- a/Lib/codeop.py +++ b/Lib/codeop.py @@ -84,9 +84,11 @@ def _maybe_compile(compiler, source, filename, symbol): 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: diff --git a/Lib/dis.py b/Lib/dis.py index 10e5f7fb..e289e176 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -542,7 +542,7 @@ def _test(): 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() diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index f3152a55..9415fd73 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -9,9 +9,9 @@ import tempfile __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"), diff --git a/Lib/ensurepip/_bundled/pip-20.1.1-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/pip-20.1.1-py2.py3-none-any.whl deleted file mode 100644 index ea1d0f7c..00000000 Binary files a/Lib/ensurepip/_bundled/pip-20.1.1-py2.py3-none-any.whl and /dev/null differ diff --git a/Lib/ensurepip/_bundled/pip-20.2.1-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/pip-20.2.1-py2.py3-none-any.whl new file mode 100644 index 00000000..3d0d3f8a Binary files /dev/null and b/Lib/ensurepip/_bundled/pip-20.2.1-py2.py3-none-any.whl differ diff --git a/Lib/ensurepip/_bundled/setuptools-47.1.0-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-47.1.0-py3-none-any.whl deleted file mode 100644 index f87867ff..00000000 Binary files a/Lib/ensurepip/_bundled/setuptools-47.1.0-py3-none-any.whl and /dev/null differ diff --git a/Lib/ensurepip/_bundled/setuptools-49.2.1-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-49.2.1-py3-none-any.whl new file mode 100644 index 00000000..308e2f2e Binary files /dev/null and b/Lib/ensurepip/_bundled/setuptools-49.2.1-py3-none-any.whl differ diff --git a/Lib/enum.py b/Lib/enum.py index 14cc00e7..de9ed4c1 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -104,9 +104,9 @@ class _EnumDict(dict): # 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) @@ -123,10 +123,12 @@ class EnumMeta(type): """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 @@ -142,7 +144,7 @@ class EnumMeta(type): 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) @@ -249,7 +251,11 @@ class EnumMeta(type): # 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) @@ -397,7 +403,7 @@ class EnumMeta(type): """ 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? @@ -476,7 +482,14 @@ class EnumMeta(type): 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. @@ -487,14 +500,25 @@ class EnumMeta(type): 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 @@ -610,7 +634,7 @@ class Enum(metaclass=EnumMeta): @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>" % ( @@ -633,8 +657,9 @@ class Enum(metaclass=EnumMeta): # 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 diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index ddc1e22e..5d9602e7 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -1,11 +1,29 @@ +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 ====================================== @@ -82,9 +100,9 @@ bpo-38636: Fix IDLE Format menu tab toggle and file indent width. These 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. diff --git a/Lib/idlelib/calltip.py b/Lib/idlelib/calltip.py index d4092c78..b02f8720 100644 --- a/Lib/idlelib/calltip.py +++ b/Lib/idlelib/calltip.py @@ -118,7 +118,6 @@ _INDENT = ' '*4 # for wrapped signatures _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 ''. @@ -146,9 +145,6 @@ def get_argspec(ob): 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 diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index 81ce5100..0edd3917 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -481,13 +481,13 @@ in the settings dialog. (To prevent auto popups, set the delay to a large number of milliseconds, such as 100000000.) For imported module names or class or function attributes, type ‘.’. For filenames in the root directory, type os.sep or -data:os.altsep immediately after an opening quote. (On Windows, +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.

-

Instead of waiting, or after a box is closed. open a completion box +

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 C-space. 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.

@@ -509,26 +509,29 @@ by typing ‘_’ after ‘.’, either before or after the box is opened.

Calltips¶

-

A calltip is shown when one types ( 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 ) is typed. When the cursor is in the argument part of a definition, -the menu or shortcut 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 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.

+

A calltip is shown automatically when one types ( 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 ) 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.

+

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.

+

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¶

@@ -975,7 +978,7 @@ also used for testing.



- Last updated on Jul 08, 2020. + Last updated on Sep 22, 2020. Found a bug?
diff --git a/Lib/idlelib/idle_test/test_calltip.py b/Lib/idlelib/idle_test/test_calltip.py index d386b5cd..4d53df17 100644 --- a/Lib/idlelib/idle_test/test_calltip.py +++ b/Lib/idlelib/idle_test/test_calltip.py @@ -61,18 +61,16 @@ class Get_argspecTest(unittest.TestCase): 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) diff --git a/Lib/idlelib/idle_test/test_run.py b/Lib/idlelib/idle_test/test_run.py index 9995dbe2..37c0d452 100644 --- a/Lib/idlelib/idle_test/test_run.py +++ b/Lib/idlelib/idle_test/test_run.py @@ -1,9 +1,10 @@ -"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 @@ -282,7 +283,8 @@ class StdOutputFilesTest(unittest.TestCase): 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() @@ -296,12 +298,12 @@ class TestSysRecursionLimitWrappers(unittest.TestCase): 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) @@ -313,6 +315,7 @@ class TestSysRecursionLimitWrappers(unittest.TestCase): 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") @@ -321,5 +324,32 @@ class TestSysRecursionLimitWrappers(unittest.TestCase): 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) diff --git a/Lib/idlelib/iomenu.py b/Lib/idlelib/iomenu.py index 74ebefd4..8bb2fa6a 100644 --- a/Lib/idlelib/iomenu.py +++ b/Lib/idlelib/iomenu.py @@ -155,6 +155,17 @@ class IOBinding: 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 diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 5bd84aad..1e84ecc6 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -387,14 +387,21 @@ class MyRPCServer(rpc.RPCServer): 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() diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index a3a04f7f..1014eba5 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -1416,7 +1416,7 @@ class IPv4Network(_BaseV4, _BaseNetwork): 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' diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index 34ff7a05..29802b61 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -1294,7 +1294,11 @@ class MemoryHandler(BufferingHandler): """ Set the target handler for this handler. """ - self.target = target + self.acquire() + try: + self.target = target + finally: + self.release() def flush(self): """ diff --git a/Lib/multiprocessing/shared_memory.py b/Lib/multiprocessing/shared_memory.py index f92eb012..e5b5e6c0 100644 --- a/Lib/multiprocessing/shared_memory.py +++ b/Lib/multiprocessing/shared_memory.py @@ -75,6 +75,8 @@ class SharedMemory: 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") diff --git a/Lib/multiprocessing/synchronize.py b/Lib/multiprocessing/synchronize.py index 4fcbefc8..d0be48f1 100644 --- a/Lib/multiprocessing/synchronize.py +++ b/Lib/multiprocessing/synchronize.py @@ -270,7 +270,7 @@ class Condition(object): 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 diff --git a/Lib/pathlib.py b/Lib/pathlib.py index ff8bac94..4f72bab3 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -329,7 +329,10 @@ class _PosixFlavour(_Flavour): # 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] diff --git a/Lib/pdb.py b/Lib/pdb.py index 08102352..d7d95715 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -1312,21 +1312,21 @@ class Pdb(bdb.Bdb, cmd.Cmd): # _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: diff --git a/Lib/pstats.py b/Lib/pstats.py index 4b419a8e..67a68ebe 100644 --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -43,9 +43,9 @@ class SortKey(str, Enum): 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 diff --git a/Lib/py_compile.py b/Lib/py_compile.py index 21736896..a81f4937 100644 --- a/Lib/py_compile.py +++ b/Lib/py_compile.py @@ -197,12 +197,10 @@ def main(args=None): 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: @@ -210,8 +208,7 @@ def main(args=None): 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__": diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 68346572..d7600561 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- 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' @@ -6923,6 +6923,14 @@ topics = {'assert': 'The "assert" statement\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' @@ -9603,6 +9611,14 @@ topics = {'assert': 'The "assert" statement\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' diff --git a/Lib/sqlite3/test/backup.py b/Lib/sqlite3/test/backup.py index 903bacf4..ad1da972 100644 --- a/Lib/sqlite3/test/backup.py +++ b/Lib/sqlite3/test/backup.py @@ -36,6 +36,13 @@ class BackupTests(unittest.TestCase): 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)') diff --git a/Lib/tempfile.py b/Lib/tempfile.py index 5b990e06..8f9cb6c3 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -307,8 +307,7 @@ def mkstemp(suffix=None, prefix=None, dir=None, text=False): 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 diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 8626aa37..ee9b47bb 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -3827,6 +3827,18 @@ class _TestSharedMemory(BaseTestCase): 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. diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index b921f4a5..c625e693 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -718,6 +718,15 @@ class ASTHelpers_Test(unittest.TestCase): '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")') @@ -757,6 +766,12 @@ class ASTHelpers_Test(unittest.TestCase): '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') diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py index 007039a7..e4809c30 100644 --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -736,6 +736,7 @@ class BaseProactorEventLoopTests(test_utils.TestCase): 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) diff --git a/Lib/test/test_asyncio/test_runners.py b/Lib/test/test_asyncio/test_runners.py index 3b58ddee..b9ae02dc 100644 --- a/Lib/test/test_asyncio/test_runners.py +++ b/Lib/test/test_asyncio/test_runners.py @@ -87,6 +87,9 @@ class RunTests(BaseTest): 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(): diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index c21b0693..c402f8f0 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -861,6 +861,22 @@ class BaseTaskTests: 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) @@ -872,6 +888,9 @@ class BaseTaskTests: nonlocal task_done try: await asyncio.sleep(0.2) + except asyncio.CancelledError: + await asyncio.sleep(0.1) + raise finally: task_done = True @@ -884,6 +903,34 @@ class BaseTaskTests: 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) diff --git a/Lib/test/test_asyncio/test_windows_events.py b/Lib/test/test_asyncio/test_windows_events.py index 6b005702..f276cd20 100644 --- a/Lib/test/test_asyncio/test_windows_events.py +++ b/Lib/test/test_asyncio/test_windows_events.py @@ -211,6 +211,34 @@ class ProactorTests(test_utils.TestCase): 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): diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py index fb599b0f..418f9b61 100644 --- a/Lib/test/test_c_locale_coercion.py +++ b/Lib/test/test_c_locale_coercion.py @@ -403,7 +403,10 @@ class LocaleCoercionTests(_LocaleHandlingTestCase): # 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 : diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 5fc5bff6..a5ece9bd 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -44,7 +44,11 @@ class CmdLineTest(unittest.TestCase): 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") diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py index f0bd013e..a4a868ad 100644 --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -143,7 +143,7 @@ class CmdLineTest(unittest.TestCase): *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) diff --git a/Lib/test/test_codeop.py b/Lib/test/test_codeop.py index 1e57ab9d..01ee00c3 100644 --- a/Lib/test/test_codeop.py +++ b/Lib/test/test_codeop.py @@ -3,6 +3,7 @@ Nick Mathewson """ import unittest +import warnings from test import support from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT @@ -296,9 +297,18 @@ class CodeopTests(unittest.TestCase): 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() diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index a2a3c567..745962a1 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -445,12 +445,63 @@ class TestEnum(unittest.TestCase): 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): @@ -500,6 +551,56 @@ class TestEnum(unittest.TestCase): 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), '') + + 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 = {} @@ -899,6 +1000,9 @@ class TestEnum(unittest.TestCase): 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): @@ -1711,6 +1815,17 @@ class TestEnum(unittest.TestCase): 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): @@ -1719,6 +1834,18 @@ class TestEnum(unittest.TestCase): 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 @@ -1737,7 +1864,12 @@ class TestEnum(unittest.TestCase): # 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: diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 3a322531..457b46e0 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1,6 +1,7 @@ # Python test set -- part 5, built-in exceptions import copy +import gc import os import sys import unittest @@ -1297,6 +1298,35 @@ class ExceptionTests(unittest.TestCase): 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): diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py index d90ca5a5..01a48af2 100644 --- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -51,6 +51,11 @@ if gdb_major_version < 7: "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.") diff --git a/Lib/test/test_importlib/test_resource.py b/Lib/test/test_importlib/test_resource.py index f88d92d1..e132c572 100644 --- a/Lib/test/test_importlib/test_resource.py +++ b/Lib/test/test_importlib/test_resource.py @@ -1,10 +1,13 @@ 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: @@ -162,5 +165,71 @@ class NamespaceTest(unittest.TestCase): '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() diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index bea4342e..8eef332b 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -922,7 +922,7 @@ class IOTest(unittest.TestCase): 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()) diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 09b273bf..cea51b45 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -1173,6 +1173,27 @@ class MemoryHandlerTest(BaseTest): # 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.""" diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 36226948..e9f928a9 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -2214,6 +2214,15 @@ class PosixPathTest(_BasePathTest, unittest.TestCase): 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) diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 0e7ae1d8..9c9471a8 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -425,6 +425,47 @@ def test_list_commands(): (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-- + > (2)test_function()->None + -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + (Pdb) whatis myvar + + (Pdb) whatis myfunc + Function myfunc + (Pdb) whatis MyClass + Class test.test_pdb.MyClass + (Pdb) whatis MyClass() + + (Pdb) whatis MyClass.mymethod + Function mymethod + (Pdb) whatis MyClass().mymethod + Method mymethod + (Pdb) continue + """ def test_post_mortem(): """Test post mortem traceback debugging. diff --git a/Lib/test/test_pstats.py b/Lib/test/test_pstats.py index f835ce30..052a3b9c 100644 --- a/Lib/test/test_pstats.py +++ b/Lib/test/test_pstats.py @@ -76,5 +76,9 @@ class StatsTestCase(unittest.TestCase): 'calls') + def test_SortKey_enum(self): + self.assertEqual(SortKey.FILENAME, 'filename') + self.assertNotEqual(SortKey.FILENAME, SortKey.CALLS) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_py_compile.py b/Lib/test/test_py_compile.py index d4a68c93..e6791c69 100644 --- a/Lib/test/test_py_compile.py +++ b/Lib/test/test_py_compile.py @@ -4,11 +4,13 @@ import os 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): @@ -216,5 +218,59 @@ class PyCompileTestsWithoutSourceEpoch(PyCompileTestsBase, 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() diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index f8fee368..2d3ab935 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -372,7 +372,9 @@ class ProcessTestCase(BaseTestCase): # 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) @@ -381,7 +383,7 @@ class ProcessTestCase(BaseTestCase): 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. diff --git a/Lib/test/test_turtle.py b/Lib/test/test_turtle.py index 2fd10ccd..571981fc 100644 --- a/Lib/test/test_turtle.py +++ b/Lib/test/test_turtle.py @@ -127,6 +127,14 @@ class VectorComparisonMixin: 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): @@ -208,9 +216,15 @@ 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) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 9f0e2e5e..479eb016 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -146,10 +146,10 @@ def _splitdict(tk, v, cut_minus=True, conv=None): 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' @@ -180,10 +180,10 @@ class EventType(str, enum.Enum): 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 @@ -3963,7 +3963,7 @@ class OptionMenu(Menubutton): 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: diff --git a/Lib/tkinter/test/test_tkinter/test_widgets.py b/Lib/tkinter/test/test_tkinter/test_widgets.py index 16e9d939..721e8136 100644 --- a/Lib/tkinter/test/test_tkinter/test_widgets.py +++ b/Lib/tkinter/test/test_tkinter/test_widgets.py @@ -307,6 +307,10 @@ class OptionMenuTest(MenubuttonTest, unittest.TestCase): 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): diff --git a/Lib/turtle.py b/Lib/turtle.py index ee67a351..ba8288da 100644 --- a/Lib/turtle.py +++ b/Lib/turtle.py @@ -258,6 +258,7 @@ class Vec2D(tuple): 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): diff --git a/Lib/typing.py b/Lib/typing.py index 589eea98..4ec538da 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -263,7 +263,7 @@ def _tp_cache(func): 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): diff --git a/Lib/uuid.py b/Lib/uuid.py index 188e16ba..9540c21e 100644 --- a/Lib/uuid.py +++ b/Lib/uuid.py @@ -45,7 +45,6 @@ Typical usage: """ import os -import platform import sys from enum import Enum @@ -54,10 +53,13 @@ from enum import Enum __author__ = 'Ka-Ping Yee ' # 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', @@ -688,9 +690,9 @@ def _random_getnode(): # @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] diff --git a/Lib/venv/scripts/common/activate b/Lib/venv/scripts/common/activate index b9d498fb..5e7ac174 100644 --- a/Lib/venv/scripts/common/activate +++ b/Lib/venv/scripts/common/activate @@ -59,7 +59,7 @@ if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then 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" diff --git a/Lib/venv/scripts/posix/activate.csh b/Lib/venv/scripts/posix/activate.csh index b0c7028a..0f39ee8c 100644 --- a/Lib/venv/scripts/posix/activate.csh +++ b/Lib/venv/scripts/posix/activate.csh @@ -22,7 +22,7 @@ if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then 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"` diff --git a/Lib/venv/scripts/posix/activate.fish b/Lib/venv/scripts/posix/activate.fish index b4010582..03e893f8 100644 --- a/Lib/venv/scripts/posix/activate.fish +++ b/Lib/venv/scripts/posix/activate.fish @@ -59,7 +59,7 @@ if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" 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) diff --git a/Mac/BuildScript/resources/License.rtf b/Mac/BuildScript/resources/License.rtf index 25d53386..1dfdc1ed 100644 --- a/Mac/BuildScript/resources/License.rtf +++ b/Mac/BuildScript/resources/License.rtf @@ -1,9 +1,9 @@ -{\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\ @@ -47,8 +47,17 @@ Thanks to the many outside volunteers who have worked under Guido's direction to \ \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\ @@ -125,6 +134,18 @@ Permission to use, copy, modify, and distribute this software and its documentat 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\ diff --git a/Misc/ACKS b/Misc/ACKS index a08e917b..8d355da8 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -364,6 +364,7 @@ Raúl Cumplido Antonio Cuni Brian Curtin Hakan Celik +Jason Curtis Paul Dagnelie Lisandro Dalcin Darren Dale @@ -420,6 +421,7 @@ Marcos Donolo Dima Dorfman Yves Dorfsman Michael Dorman +Andrey Doroschenko Steve Dower Allen Downey Cesar Douady @@ -1676,6 +1678,7 @@ Févry Thibault Lowe Thiderman Nicolas M. Thiéry James Thomas +Reuben Thomas Robin Thomas Brian Thorne Christopher Thorne diff --git a/Misc/NEWS b/Misc/NEWS index c7c412e3..6e94ca3e 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -2,6 +2,198 @@ 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? ================================= @@ -1407,7 +1599,7 @@ IDLE - 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 @@ -3400,7 +3592,7 @@ Documentation 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* @@ -7040,8 +7232,8 @@ Tests - 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() diff --git a/Misc/python.man b/Misc/python.man index 3645b020..fa5d7999 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -295,7 +295,7 @@ Set implementation specific option. The following options are available: 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: diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index ebe073f6..b6188a36 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1523,6 +1523,10 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject * sleep_ms = (int)ms; } + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + if (!pysqlite_check_connection((pysqlite_Connection *)target)) { return NULL; } diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 1944393e..e6dda298 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -807,10 +807,11 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) 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; diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 38723d93..8bcf76ff 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2268,8 +2268,12 @@ MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { 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 */ @@ -2289,8 +2293,15 @@ MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 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 { diff --git a/PC/_testconsole.c b/PC/_testconsole.c index 23d1286e..1823ff2c 100644 --- a/PC/_testconsole.c +++ b/PC/_testconsole.c @@ -64,7 +64,7 @@ _testconsole_write_input_impl(PyObject *module, PyObject *file, 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; } diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index ddc0a286..bf7b0c37 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -54,7 +54,7 @@ set libraries= set libraries=%libraries% bzip2-1.0.6 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.3.0-rc0-r1 if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1g -set libraries=%libraries% sqlite-3.31.1.0 +set libraries=%libraries% sqlite-3.32.3.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.9.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.9.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tix-8.4.3.6 diff --git a/PCbuild/python.props b/PCbuild/python.props index 112b9f08..fe594059 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -56,7 +56,7 @@ $(EXTERNALS_DIR) $([System.IO.Path]::GetFullPath(`$(PySourcePath)externals`)) $(ExternalsDir)\ - $(ExternalsDir)sqlite-3.31.1.0\ + $(ExternalsDir)sqlite-3.32.3.0\ $(ExternalsDir)bzip2-1.0.6\ $(ExternalsDir)xz-5.2.2\ $(ExternalsDir)libffi\ diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index 1462e6f4..c5a06707 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -184,7 +184,7 @@ _ssl again when building. _sqlite3 - Wraps SQLite 3.31.1.0, which is itself built by sqlite3.vcxproj + Wraps SQLite 3.32.3.0, which is itself built by sqlite3.vcxproj Homepage: http://www.sqlite.org/ _tkinter diff --git a/Parser/myreadline.c b/Parser/myreadline.c index d7ed357f..e8e57738 100644 --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -292,37 +292,16 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) } #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); @@ -330,7 +309,6 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) PyEval_SaveThread(); return NULL; } - pr = (char *)PyMem_RawRealloc(p, n + incr); if (pr == NULL) { PyMem_RawFree(p); @@ -340,12 +318,18 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) 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) { diff --git a/Python/initconfig.c b/Python/initconfig.c index a930b5d3..b28e0a07 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -80,7 +80,7 @@ static const char usage_3[] = "\ 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\ @@ -2589,7 +2589,7 @@ init_dump_ascii_wstr(const wchar_t *str) 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) { diff --git a/Python/modsupport.c b/Python/modsupport.c index 7271af3a..50628119 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -618,6 +618,9 @@ va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, va_end(lva); if (res < 0) { + if (stack != small_stack) { + PyMem_Free(stack); + } return NULL; } diff --git a/Python/pystrcmp.c b/Python/pystrcmp.c index f9c2277c..9224ce4c 100644 --- a/Python/pystrcmp.c +++ b/Python/pystrcmp.c @@ -6,21 +6,25 @@ 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)); } diff --git a/README.rst b/README.rst index 862a24d5..97a7191c 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -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 diff --git a/Tools/nuget/python.nuspec b/Tools/nuget/python.nuspec index 8f98e808..2da5f203 100644 --- a/Tools/nuget/python.nuspec +++ b/Tools/nuget/python.nuspec @@ -13,6 +13,6 @@ - + diff --git a/Tools/nuget/pythonarm32.nuspec b/Tools/nuget/pythonarm32.nuspec index 273d79a0..2d197931 100644 --- a/Tools/nuget/pythonarm32.nuspec +++ b/Tools/nuget/pythonarm32.nuspec @@ -14,6 +14,7 @@ - + + diff --git a/Tools/nuget/pythondaily.nuspec b/Tools/nuget/pythondaily.nuspec index 5cf55806..7df1983f 100644 --- a/Tools/nuget/pythondaily.nuspec +++ b/Tools/nuget/pythondaily.nuspec @@ -13,6 +13,7 @@ - + + diff --git a/Tools/nuget/pythonx86.nuspec b/Tools/nuget/pythonx86.nuspec index 27ef67e7..ea878ba0 100644 --- a/Tools/nuget/pythonx86.nuspec +++ b/Tools/nuget/pythonx86.nuspec @@ -13,6 +13,7 @@ - + +