From f3626332cf6fcd8c4b395f2e0b39a0d03e33d4d7 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Tue, 8 Dec 2020 13:53:18 +0900 Subject: [PATCH] Imported Upstream version 3.7.6 --- Doc/c-api/arg.rst | 50 +-- Doc/c-api/buffer.rst | 30 +- Doc/c-api/bytearray.rst | 6 +- Doc/c-api/bytes.rst | 12 +- Doc/c-api/capsule.rst | 38 +-- Doc/c-api/cell.rst | 12 +- Doc/c-api/codec.rst | 8 +- Doc/c-api/concrete.rst | 4 +- Doc/c-api/contextvars.rst | 6 +- Doc/c-api/conversion.rst | 18 +- Doc/c-api/coro.rst | 4 +- Doc/c-api/datetime.rst | 28 +- Doc/c-api/dict.rst | 10 +- Doc/c-api/exceptions.rst | 54 ++-- Doc/c-api/file.rst | 4 +- Doc/c-api/float.rst | 4 +- Doc/c-api/function.rst | 20 +- Doc/c-api/gcsupport.rst | 8 +- Doc/c-api/gen.rst | 8 +- Doc/c-api/import.rst | 22 +- Doc/c-api/init.rst | 76 ++--- Doc/c-api/intro.rst | 14 +- Doc/c-api/iter.rst | 4 +- Doc/c-api/list.rst | 20 +- Doc/c-api/long.rst | 18 +- Doc/c-api/mapping.rst | 11 +- Doc/c-api/marshal.rst | 8 +- Doc/c-api/memory.rst | 58 ++-- Doc/c-api/memoryview.rst | 2 +- Doc/c-api/method.rst | 6 +- Doc/c-api/module.rst | 45 ++- Doc/c-api/number.rst | 78 ++--- Doc/c-api/object.rst | 58 ++-- Doc/c-api/refcounting.rst | 20 +- Doc/c-api/reflection.rst | 6 +- Doc/c-api/sequence.rst | 28 +- Doc/c-api/set.rst | 10 +- Doc/c-api/slice.rst | 6 +- Doc/c-api/structures.rst | 20 +- Doc/c-api/sys.rst | 8 +- Doc/c-api/tuple.rst | 74 +++-- Doc/c-api/type.rst | 4 +- Doc/c-api/typeobj.rst | 92 +++--- Doc/c-api/unicode.rst | 318 +++++++++--------- Doc/c-api/veryhigh.rst | 40 +-- Doc/c-api/weakref.rst | 8 +- Doc/distributing/index.rst | 4 +- Doc/distutils/apiref.rst | 10 +- Doc/extending/embedding.rst | 2 +- Doc/extending/extending.rst | 52 +-- Doc/extending/newtypes.rst | 36 +-- Doc/extending/newtypes_tutorial.rst | 26 +- Doc/faq/extending.rst | 2 +- Doc/howto/clinic.rst | 2 +- Doc/howto/logging-cookbook.rst | 396 +++++++++++++++++++++++ Doc/includes/email-dir.py | 2 +- Doc/includes/email-simple.py | 2 +- Doc/includes/email-unpack.py | 2 +- Doc/installing/index.rst | 2 +- Doc/library/2to3.rst | 2 +- Doc/library/argparse.rst | 4 +- Doc/library/array.rst | 4 + Doc/library/asyncio-eventloop.rst | 24 +- Doc/library/asyncio-stream.rst | 4 +- Doc/library/collections.rst | 2 +- Doc/library/ctypes.rst | 8 +- Doc/library/dataclasses.rst | 6 +- Doc/library/difflib.rst | 6 +- Doc/library/doctest.rst | 2 +- Doc/library/email.compat32-message.rst | 2 +- Doc/library/email.errors.rst | 2 +- Doc/library/email.message.rst | 2 +- Doc/library/email.utils.rst | 4 +- Doc/library/fileinput.rst | 8 +- Doc/library/functions.rst | 14 +- Doc/library/gc.rst | 4 +- Doc/library/http.client.rst | 2 +- Doc/library/http.cookiejar.rst | 6 +- Doc/library/http.rst | 2 +- Doc/library/idle.rst | 3 +- Doc/library/importlib.rst | 2 +- Doc/library/inspect.rst | 44 +-- Doc/library/ipaddress.rst | 4 +- Doc/library/keyword.rst | 2 +- Doc/library/linecache.rst | 2 +- Doc/library/logging.handlers.rst | 6 +- Doc/library/logging.rst | 4 +- Doc/library/lzma.rst | 2 +- Doc/library/msvcrt.rst | 2 +- Doc/library/multiprocessing.rst | 3 +- Doc/library/optparse.rst | 10 +- Doc/library/os.rst | 4 +- Doc/library/parser.rst | 4 +- Doc/library/pdb.rst | 8 + Doc/library/sched.rst | 2 +- Doc/library/socket.rst | 10 +- Doc/library/ssl.rst | 7 +- Doc/library/statistics.rst | 2 +- Doc/library/stdtypes.rst | 78 ++--- Doc/library/stringprep.rst | 2 +- Doc/library/sys.rst | 2 +- Doc/library/tempfile.rst | 4 +- Doc/library/threading.rst | 26 +- Doc/library/time.rst | 15 +- Doc/library/tkinter.ttk.rst | 6 +- Doc/library/token.rst | 6 +- Doc/library/unittest.mock.rst | 28 +- Doc/library/unittest.rst | 4 +- Doc/library/urllib.parse.rst | 2 +- Doc/library/urllib.request.rst | 2 +- Doc/library/venv.rst | 4 +- Doc/library/winreg.rst | 4 +- Doc/library/wsgiref.rst | 2 +- Doc/library/xml.dom.rst | 12 +- Doc/library/xml.etree.elementtree.rst | 4 +- Doc/library/zipimport.rst | 2 +- Doc/license.rst | 2 +- Doc/reference/datamodel.rst | 30 +- Doc/reference/import.rst | 6 +- Doc/tools/static/switchers.js | 3 +- Doc/tools/susp-ignored.csv | 7 +- Doc/tutorial/interpreter.rst | 2 +- Doc/tutorial/stdlib.rst | 32 +- Doc/using/cmdline.rst | 6 +- Doc/whatsnew/2.7.rst | 2 +- Doc/whatsnew/3.4.rst | 4 +- Doc/whatsnew/3.6.rst | 10 + Doc/whatsnew/3.7.rst | 12 +- Include/abstract.h | 6 +- Include/patchlevel.h | 4 +- Lib/_pyio.py | 6 +- Lib/argparse.py | 5 +- Lib/asyncio/base_events.py | 25 +- Lib/asyncio/futures.py | 5 +- Lib/asyncio/selector_events.py | 10 + Lib/codeop.py | 11 +- Lib/ctypes/macholib/dyld.py | 2 + Lib/ctypes/test/test_structures.py | 161 +++++++++ Lib/dataclasses.py | 87 +++-- Lib/difflib.py | 4 +- Lib/email/_header_value_parser.py | 2 +- Lib/encodings/uu_codec.py | 4 + Lib/http/cookiejar.py | 18 +- Lib/idlelib/NEWS.txt | 38 ++- Lib/idlelib/autocomplete_w.py | 3 +- Lib/idlelib/config-main.def | 1 + Lib/idlelib/config.py | 2 + Lib/idlelib/configdialog.py | 17 + Lib/idlelib/editor.py | 50 ++- Lib/idlelib/format.py | 13 +- Lib/idlelib/help.html | 25 +- Lib/idlelib/idle_test/mock_idle.py | 5 +- Lib/idlelib/idle_test/test_configdialog.py | 4 + Lib/idlelib/idle_test/test_editor.py | 12 - Lib/idlelib/idle_test/test_format.py | 101 ++++-- Lib/idlelib/idle_test/test_iomenu.py | 24 +- Lib/idlelib/idle_test/test_run.py | 60 ++-- Lib/idlelib/iomenu.py | 61 ++-- Lib/idlelib/pyshell.py | 32 +- Lib/idlelib/run.py | 36 +-- Lib/idlelib/runscript.py | 10 +- Lib/json/tool.py | 4 +- Lib/lib2to3/Grammar.txt | 4 +- Lib/lib2to3/fixes/fix_apply.py | 4 +- Lib/lib2to3/fixes/fix_intern.py | 4 +- Lib/lib2to3/fixes/fix_reload.py | 4 +- Lib/lib2to3/tests/test_parser.py | 7 + Lib/pathlib.py | 50 +-- Lib/pydoc_data/topics.py | 225 ++++++++----- Lib/shlex.py | 1 + Lib/smtplib.py | 2 +- Lib/socket.py | 6 +- Lib/socketserver.py | 2 +- Lib/stat.py | 16 + Lib/tempfile.py | 14 +- Lib/test/ann_module.py | 7 + Lib/test/dataclass_textanno.py | 12 + Lib/test/libregrtest/main.py | 35 +- Lib/test/libregrtest/runtest_mp.py | 91 +++--- Lib/test/libregrtest/utils.py | 11 +- Lib/test/libregrtest/win_utils.py | 121 ++++--- Lib/test/pythoninfo.py | 31 ++ Lib/test/test_ast.py | 12 + Lib/test/test_asyncgen.py | 27 ++ Lib/test/test_asyncio/test_base_events.py | 46 +-- Lib/test/test_asyncio/test_futures.py | 39 +++ Lib/test/test_asyncio/test_sslproto.py | 24 +- Lib/test/test_context.py | 7 +- Lib/test/test_dataclasses.py | 12 + Lib/test/test_email/test__encoded_words.py | 2 + Lib/test/test_email/test__header_value_parser.py | 12 + Lib/test/test_fcntl.py | 39 ++- Lib/test/test_gc.py | 71 ++++ Lib/test/test_http_cookiejar.py | 13 + Lib/test/test_io.py | 11 + Lib/test/test_json/test_tool.py | 21 +- Lib/test/test_mimetypes.py | 15 + Lib/test/test_pathlib.py | 4 + Lib/test/test_pty.py | 19 +- Lib/test/test_py_compile.py | 2 +- Lib/test/test_regrtest.py | 14 +- Lib/test/test_ssl.py | 22 +- Lib/test/test_stat.py | 8 +- Lib/test/test_tcl.py | 5 + Lib/test/test_tempfile.py | 19 +- Lib/test/test_typing.py | 43 ++- Lib/test/test_urlparse.py | 10 +- Lib/test/test_uu.py | 9 + Lib/test/test_weakref.py | 20 ++ Lib/test/test_zipfile.py | 260 +++++++++++++++ Lib/tkinter/__init__.py | 4 +- Lib/tkinter/test/test_tkinter/test_misc.py | 22 ++ Lib/tkinter/test/test_ttk/test_widgets.py | 13 +- Lib/typing.py | 14 +- Lib/unittest/mock.py | 4 + Lib/unittest/test/testmock/testpatch.py | 4 + Lib/urllib/parse.py | 22 +- Lib/urllib/request.py | 6 +- Lib/uu.py | 7 + Lib/wave.py | 2 +- Lib/zipfile.py | 69 ++-- Mac/BuildScript/resources/License.rtf | 2 +- Misc/ACKS | 1 + Misc/NEWS | 247 ++++++++++++++ Misc/valgrind-python.supp | 11 + Modules/_asynciomodule.c | 21 ++ Modules/_contextvarsmodule.c | 3 + Modules/_ctypes/_ctypes.c | 33 +- Modules/_ctypes/_ctypes_test.c | 113 +++++++ Modules/_ctypes/ctypes.h | 2 + Modules/_ctypes/stgdict.c | 9 + Modules/_io/fileio.c | 24 +- Modules/_ssl.c | 49 ++- Modules/_testcapimodule.c | 7 +- Modules/_tkinter.c | 377 +++++++++++---------- Modules/_tracemalloc.c | 4 +- Modules/faulthandler.c | 47 +-- Modules/gcmodule.c | 11 +- Modules/main.c | 1 + Objects/bytes_methods.c | 2 +- Objects/clinic/unicodeobject.c.h | 4 +- Objects/genobject.c | 11 + Objects/unicodeobject.c | 4 +- Objects/weakrefobject.c | 122 +++++-- PCbuild/find_python.bat | 3 + Parser/asdl_c.py | 3 +- Parser/tokenizer.c | 6 + Python/Python-ast.c | 3 +- Python/ast.c | 5 +- Python/context.c | 7 +- Python/formatter_unicode.c | 2 +- Python/getargs.c | 14 +- Python/hamt.c | 2 +- Python/marshal.c | 5 +- README.rst | 2 +- Tools/msi/doc/doc.wxs | 2 +- Tools/scripts/pathfix.py | 4 +- configure | 7 +- configure.ac | 9 +- pyconfig.h.in | 2 +- 260 files changed, 4215 insertions(+), 1878 deletions(-) create mode 100644 Lib/test/dataclass_textanno.py diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst index b41130e..a5d1edc 100644 --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -50,7 +50,7 @@ Unless otherwise stated, buffers are not NUL-terminated. Some formats require a read-only :term:`bytes-like object`, and set a pointer instead of a buffer structure. They work by checking that -the object's :c:member:`PyBufferProcs.bf_releasebuffer` field is *NULL*, +the object's :c:member:`PyBufferProcs.bf_releasebuffer` field is ``NULL``, which disallows mutable objects such as :class:`bytearray`. .. note:: @@ -99,15 +99,15 @@ which disallows mutable objects such as :class:`bytearray`. ``z`` (:class:`str` or ``None``) [const char \*] Like ``s``, but the Python object may also be ``None``, in which case the C - pointer is set to *NULL*. + pointer is set to ``NULL``. ``z*`` (:class:`str`, :term:`bytes-like object` or ``None``) [Py_buffer] Like ``s*``, but the Python object may also be ``None``, in which case the - ``buf`` member of the :c:type:`Py_buffer` structure is set to *NULL*. + ``buf`` member of the :c:type:`Py_buffer` structure is set to ``NULL``. ``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, int] Like ``s#``, but the Python object may also be ``None``, in which case the C - pointer is set to *NULL*. + pointer is set to ``NULL``. ``y`` (read-only :term:`bytes-like object`) [const char \*] This format converts a bytes-like object to a C pointer to a character @@ -166,7 +166,7 @@ which disallows mutable objects such as :class:`bytearray`. ``Z`` (:class:`str` or ``None``) [const Py_UNICODE \*] Like ``u``, but the Python object may also be ``None``, in which case the - :c:type:`Py_UNICODE` pointer is set to *NULL*. + :c:type:`Py_UNICODE` pointer is set to ``NULL``. .. deprecated-removed:: 3.3 4.0 Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using @@ -174,7 +174,7 @@ which disallows mutable objects such as :class:`bytearray`. ``Z#`` (:class:`str` or ``None``) [const Py_UNICODE \*, int] Like ``u#``, but the Python object may also be ``None``, in which case the - :c:type:`Py_UNICODE` pointer is set to *NULL*. + :c:type:`Py_UNICODE` pointer is set to ``NULL``. .. deprecated-removed:: 3.3 4.0 Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using @@ -197,7 +197,7 @@ which disallows mutable objects such as :class:`bytearray`. 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 - NUL-terminated string, or *NULL*, in which case ``'utf-8'`` encoding is used. + 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 references will be set to a buffer with the contents of the argument text. @@ -220,7 +220,7 @@ which disallows mutable objects such as :class:`bytearray`. 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 - NUL-terminated string, or *NULL*, in which case ``'utf-8'`` encoding is used. + 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 references will be set to a buffer with the contents of the argument text. @@ -230,12 +230,12 @@ which disallows mutable objects such as :class:`bytearray`. There are two modes of operation: - If *\*buffer* points a *NULL* pointer, the function will allocate a buffer of + If *\*buffer* points a ``NULL`` pointer, the function will allocate a buffer of the needed size, copy the encoded data into this buffer and set *\*buffer* to reference the newly allocated storage. The caller is responsible for calling :c:func:`PyMem_Free` to free the allocated buffer after usage. - If *\*buffer* points to a non-*NULL* pointer (an already allocated buffer), + If *\*buffer* points to a non-``NULL`` pointer (an already allocated buffer), :c:func:`PyArg_ParseTuple` will use this location as the buffer and interpret the initial value of *\*buffer_length* as the buffer size. It will then copy the encoded data into the buffer and NUL-terminate it. If the buffer is not large @@ -317,7 +317,7 @@ Other objects ``O`` (object) [PyObject \*] Store a Python object (without any conversion) in a C object pointer. The C program thus receives the actual object that was passed. The object's reference - count is not increased. The pointer stored is not *NULL*. + count is not increased. The pointer stored is not ``NULL``. ``O!`` (object) [*typeobject*, PyObject \*] Store a Python object in a C object pointer. This is similar to ``O``, but @@ -345,7 +345,7 @@ Other objects If the *converter* returns ``Py_CLEANUP_SUPPORTED``, it may get called a second time if the argument parsing eventually fails, giving the converter a chance to release any memory that it had already allocated. In this second - call, the *object* parameter will be NULL; *address* will have the same value + call, the *object* parameter will be ``NULL``; *address* will have the same value as in the original call. .. versionchanged:: 3.1 @@ -437,7 +437,7 @@ API Functions Parse the parameters of a function that takes both positional and keyword parameters into local variables. The *keywords* argument is a - *NULL*-terminated array of keyword parameter names. Empty names denote + ``NULL``-terminated array of keyword parameter names. Empty names denote :ref:`positional-only parameters `. Returns true on success; on failure, it returns false and raises the appropriate exception. @@ -520,8 +520,8 @@ Building values Create a new value based on a format string similar to those accepted by the :c:func:`PyArg_Parse\*` family of functions and a sequence of values. Returns - the value or *NULL* in the case of an error; an exception will be raised if - *NULL* is returned. + the value or ``NULL`` in the case of an error; an exception will be raised if + ``NULL`` is returned. :c:func:`Py_BuildValue` does not always build a tuple. It builds a tuple only if its format string contains two or more format units. If the format string is @@ -547,20 +547,20 @@ Building values ``s`` (:class:`str` or ``None``) [const char \*] Convert a null-terminated C string to a Python :class:`str` object using ``'utf-8'`` - encoding. If the C string pointer is *NULL*, ``None`` is used. + encoding. If the C string pointer is ``NULL``, ``None`` is used. ``s#`` (:class:`str` or ``None``) [const char \*, int] Convert a C string and its length to a Python :class:`str` object using ``'utf-8'`` - encoding. If the C string pointer is *NULL*, the length is ignored and + encoding. If the C string pointer is ``NULL``, the length is ignored and ``None`` is returned. ``y`` (:class:`bytes`) [const char \*] This converts a C string to a Python :class:`bytes` object. If the C - string pointer is *NULL*, ``None`` is returned. + string pointer is ``NULL``, ``None`` is returned. ``y#`` (:class:`bytes`) [const char \*, int] This converts a C string and its lengths to a Python object. If the C - string pointer is *NULL*, ``None`` is returned. + string pointer is ``NULL``, ``None`` is returned. ``z`` (:class:`str` or ``None``) [const char \*] Same as ``s``. @@ -570,12 +570,12 @@ Building values ``u`` (:class:`str`) [const wchar_t \*] Convert a null-terminated :c:type:`wchar_t` buffer of Unicode (UTF-16 or UCS-4) - data to a Python Unicode object. If the Unicode buffer pointer is *NULL*, + data to a Python Unicode object. If the Unicode buffer pointer is ``NULL``, ``None`` is returned. ``u#`` (:class:`str`) [const wchar_t \*, int] Convert a Unicode (UTF-16 or UCS-4) data buffer and its length to a Python - Unicode object. If the Unicode buffer pointer is *NULL*, the length is ignored + Unicode object. If the Unicode buffer pointer is ``NULL``, the length is ignored and ``None`` is returned. ``U`` (:class:`str` or ``None``) [const char \*] @@ -636,9 +636,9 @@ Building values ``O`` (object) [PyObject \*] Pass a Python object untouched (except for its reference count, which is - incremented by one). If the object passed in is a *NULL* pointer, it is assumed + incremented by one). If the object passed in is a ``NULL`` pointer, it is assumed that this was caused because the call producing the argument found an error and - set an exception. Therefore, :c:func:`Py_BuildValue` will return *NULL* but won't + set an exception. Therefore, :c:func:`Py_BuildValue` will return ``NULL`` but won't raise an exception. If no exception has been raised yet, :exc:`SystemError` is set. @@ -653,7 +653,7 @@ 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 + \*`) as its argument and should return a "new" Python object, or ``NULL`` if an error occurred. ``(items)`` (:class:`tuple`) [*matching-items*] @@ -668,7 +668,7 @@ Building values respectively. If there is an error in the format string, the :exc:`SystemError` exception is - set and *NULL* returned. + set and ``NULL`` returned. .. c:function:: PyObject* Py_VaBuildValue(const char *format, va_list vargs) diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst index b639ba6..74f518b 100644 --- a/Doc/c-api/buffer.rst +++ b/Doc/c-api/buffer.rst @@ -102,13 +102,13 @@ a buffer, see :c:func:`PyObject_GetBuffer`. .. 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 + the consumer and automatically decremented and set to ``NULL`` by :c:func:`PyBuffer_Release`. The field is the equivalent of the return value of any standard C-API function. As a special case, for *temporary* buffers that are wrapped by :c:func:`PyMemoryView_FromBuffer` or :c:func:`PyBuffer_FillInfo` - this field is *NULL*. In general, exporting objects MUST NOT + this field is ``NULL``. In general, exporting objects MUST NOT use this scheme. .. c:member:: Py_ssize_t len @@ -130,25 +130,25 @@ a buffer, see :c:func:`PyObject_GetBuffer`. .. c:member:: Py_ssize_t itemsize Item size in bytes of a single element. Same as the value of :func:`struct.calcsize` - called on non-NULL :c:member:`~Py_buffer.format` values. + called on non-``NULL`` :c:member:`~Py_buffer.format` values. Important exception: If a consumer requests a buffer without the :c:macro:`PyBUF_FORMAT` flag, :c:member:`~Py_buffer.format` will - be set to *NULL*, but :c:member:`~Py_buffer.itemsize` still has + be set to ``NULL``, but :c:member:`~Py_buffer.itemsize` still has the value for the original format. If :c:member:`~Py_buffer.shape` is present, the equality ``product(shape) * itemsize == len`` still holds and the consumer can use :c:member:`~Py_buffer.itemsize` to navigate the buffer. - If :c:member:`~Py_buffer.shape` is *NULL* as a result of a :c:macro:`PyBUF_SIMPLE` + If :c:member:`~Py_buffer.shape` is ``NULL`` as a result of a :c:macro:`PyBUF_SIMPLE` 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 A *NUL* terminated string in :mod:`struct` module style syntax describing - the contents of a single item. If this is *NULL*, ``"B"`` (unsigned bytes) + the contents of a single item. If this is ``NULL``, ``"B"`` (unsigned bytes) is assumed. This field is controlled by the :c:macro:`PyBUF_FORMAT` flag. @@ -158,7 +158,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. The number of dimensions the memory represents as an n-dimensional array. If it is ``0``, :c:member:`~Py_buffer.buf` points to a single item representing a scalar. In this case, :c:member:`~Py_buffer.shape`, :c:member:`~Py_buffer.strides` - and :c:member:`~Py_buffer.suboffsets` MUST be *NULL*. + and :c:member:`~Py_buffer.suboffsets` MUST be ``NULL``. The macro :c:macro:`PyBUF_MAX_NDIM` limits the maximum number of dimensions to 64. Exporters MUST respect this limit, consumers of multi-dimensional @@ -199,7 +199,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. memory block). If all suboffsets are negative (i.e. no de-referencing is needed), then - this field must be NULL (the default value). + this field must be ``NULL`` (the default value). This type of array representation is used by the Python Imaging Library (PIL). See `complex arrays`_ for further information how to access elements @@ -248,7 +248,7 @@ readonly, format .. c:macro:: PyBUF_FORMAT Controls the :c:member:`~Py_buffer.format` field. If set, this field MUST - be filled in correctly. Otherwise, this field MUST be *NULL*. + be filled in correctly. Otherwise, this field MUST be ``NULL``. :c:macro:`PyBUF_WRITABLE` can be \|'d to any of the flags in the next section. @@ -349,9 +349,9 @@ The logical structure of NumPy-style arrays is defined by :c:member:`~Py_buffer. If ``ndim == 0``, the memory location pointed to by :c:member:`~Py_buffer.buf` is interpreted as a scalar of size :c:member:`~Py_buffer.itemsize`. In that case, -both :c:member:`~Py_buffer.shape` and :c:member:`~Py_buffer.strides` are *NULL*. +both :c:member:`~Py_buffer.shape` and :c:member:`~Py_buffer.strides` are ``NULL``. -If :c:member:`~Py_buffer.strides` is *NULL*, the array is interpreted as +If :c:member:`~Py_buffer.strides` is ``NULL``, the array is interpreted as a standard n-dimensional C-array. Otherwise, the consumer must access an n-dimensional array as follows: @@ -407,7 +407,7 @@ to two ``char x[2][3]`` arrays that can be located anywhere in memory. Here is a function that returns a pointer to the element in an N-D array -pointed to by an N-dimensional index when there are both non-NULL strides +pointed to by an N-dimensional index when there are both non-``NULL`` strides and suboffsets:: void *get_item_pointer(int ndim, void *buf, Py_ssize_t *strides, @@ -438,7 +438,7 @@ 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 :c:member:`view->obj` to ``NULL`` and return ``-1``. On success, fill in *view*, set :c:member:`view->obj` to a new reference @@ -516,8 +516,8 @@ Buffer-related functions On success, set :c:member:`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``; + :c:member:`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 - unmodified. Otherwise, *exporter* MUST be NULL. + unmodified. Otherwise, *exporter* MUST be ``NULL``. diff --git a/Doc/c-api/bytearray.rst b/Doc/c-api/bytearray.rst index 41b6e3c..e6872ce 100644 --- a/Doc/c-api/bytearray.rst +++ b/Doc/c-api/bytearray.rst @@ -48,7 +48,7 @@ Direct API functions .. c:function:: PyObject* PyByteArray_FromStringAndSize(const char *string, Py_ssize_t len) Create a new bytearray object from *string* and its length, *len*. On - failure, *NULL* is returned. + failure, ``NULL`` is returned. .. c:function:: PyObject* PyByteArray_Concat(PyObject *a, PyObject *b) @@ -58,13 +58,13 @@ Direct API functions .. c:function:: Py_ssize_t PyByteArray_Size(PyObject *bytearray) - Return the size of *bytearray* after checking for a *NULL* pointer. + Return the size of *bytearray* after checking for a ``NULL`` pointer. .. c:function:: char* PyByteArray_AsString(PyObject *bytearray) Return the contents of *bytearray* as a char array after checking for a - *NULL* pointer. The returned array always has an extra + ``NULL`` pointer. The returned array always has an extra null byte appended. diff --git a/Doc/c-api/bytes.rst b/Doc/c-api/bytes.rst index 5b9ebf6..6699e35 100644 --- a/Doc/c-api/bytes.rst +++ b/Doc/c-api/bytes.rst @@ -37,14 +37,14 @@ called with a non-bytes parameter. .. c:function:: PyObject* PyBytes_FromString(const char *v) Return a new bytes object with a copy of the string *v* as value on success, - and *NULL* on failure. The parameter *v* must not be *NULL*; it will not be + and ``NULL`` on failure. The parameter *v* must not be ``NULL``; it will not be checked. .. c:function:: PyObject* PyBytes_FromStringAndSize(const char *v, Py_ssize_t len) Return a new bytes object with a copy of the string *v* as value and length - *len* on success, and *NULL* on failure. If *v* is *NULL*, the contents of + *len* on success, and ``NULL`` on failure. If *v* is ``NULL``, the contents of the bytes object are uninitialized. @@ -145,7 +145,7 @@ called with a non-bytes parameter. whether there are any other null bytes. The data must not be modified in any way, unless the object was just created using ``PyBytes_FromStringAndSize(NULL, size)``. It must not be deallocated. If - *o* is not a bytes object at all, :c:func:`PyBytes_AsString` returns *NULL* + *o* is not a bytes object at all, :c:func:`PyBytes_AsString` returns ``NULL`` and raises :exc:`TypeError`. @@ -159,7 +159,7 @@ called with a non-bytes parameter. Return the null-terminated contents of the object *obj* through the output variables *buffer* and *length*. - If *length* is *NULL*, the bytes object + If *length* is ``NULL``, the bytes object may not contain embedded null bytes; if it does, the function returns ``-1`` and a :exc:`ValueError` is raised. @@ -181,7 +181,7 @@ called with a non-bytes parameter. appended to *bytes*; the caller will own the new reference. The reference to the old value of *bytes* will be stolen. If the new object cannot be created, the old reference to *bytes* will still be discarded and the value - of *\*bytes* will be set to *NULL*; the appropriate exception will be set. + of *\*bytes* will be set to ``NULL``; the appropriate exception will be set. .. c:function:: void PyBytes_ConcatAndDel(PyObject **bytes, PyObject *newpart) @@ -201,5 +201,5 @@ called with a non-bytes parameter. desired. On success, *\*bytes* holds the resized bytes object and ``0`` is returned; the address in *\*bytes* may differ from its input value. If the reallocation fails, the original bytes object at *\*bytes* is deallocated, - *\*bytes* is set to *NULL*, :exc:`MemoryError` is set, and ``-1`` is + *\*bytes* is set to ``NULL``, :exc:`MemoryError` is set, and ``-1`` is returned. diff --git a/Doc/c-api/capsule.rst b/Doc/c-api/capsule.rst index 8eb6695..07efb9e 100644 --- a/Doc/c-api/capsule.rst +++ b/Doc/c-api/capsule.rst @@ -40,15 +40,15 @@ Refer to :ref:`using-capsules` for more information on using these objects. .. c:function:: PyObject* PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor) Create a :c:type:`PyCapsule` encapsulating the *pointer*. The *pointer* - argument may not be *NULL*. + argument may not be ``NULL``. - On failure, set an exception and return *NULL*. + On failure, set an exception and return ``NULL``. - The *name* string may either be *NULL* or a pointer to a valid C string. If - non-*NULL*, this string must outlive the capsule. (Though it is permitted to + The *name* string may either be ``NULL`` or a pointer to a valid C string. If + non-``NULL``, this string must outlive the capsule. (Though it is permitted to free it inside the *destructor*.) - If the *destructor* argument is not *NULL*, it will be called with the + If the *destructor* argument is not ``NULL``, it will be called with the capsule as its argument when it is destroyed. If this capsule will be stored as an attribute of a module, the *name* should @@ -59,20 +59,20 @@ Refer to :ref:`using-capsules` for more information on using these objects. .. c:function:: void* PyCapsule_GetPointer(PyObject *capsule, const char *name) Retrieve the *pointer* stored in the capsule. On failure, set an exception - and return *NULL*. + and return ``NULL``. The *name* parameter must compare exactly to the name stored in the capsule. - If the name stored in the capsule is *NULL*, the *name* passed in must also - be *NULL*. Python uses the C function :c:func:`strcmp` to compare capsule + If the name stored in the capsule is ``NULL``, the *name* passed in must also + be ``NULL``. Python uses the C function :c:func:`strcmp` to compare capsule names. .. c:function:: PyCapsule_Destructor PyCapsule_GetDestructor(PyObject *capsule) Return the current destructor stored in the capsule. On failure, set an - exception and return *NULL*. + exception and return ``NULL``. - It is legal for a capsule to have a *NULL* destructor. This makes a *NULL* + It is legal for a capsule to have a ``NULL`` destructor. This makes a ``NULL`` return code somewhat ambiguous; use :c:func:`PyCapsule_IsValid` or :c:func:`PyErr_Occurred` to disambiguate. @@ -80,9 +80,9 @@ Refer to :ref:`using-capsules` for more information on using these objects. .. c:function:: void* PyCapsule_GetContext(PyObject *capsule) Return the current context stored in the capsule. On failure, set an - exception and return *NULL*. + exception and return ``NULL``. - It is legal for a capsule to have a *NULL* context. This makes a *NULL* + It is legal for a capsule to have a ``NULL`` context. This makes a ``NULL`` return code somewhat ambiguous; use :c:func:`PyCapsule_IsValid` or :c:func:`PyErr_Occurred` to disambiguate. @@ -90,9 +90,9 @@ Refer to :ref:`using-capsules` for more information on using these objects. .. c:function:: const char* PyCapsule_GetName(PyObject *capsule) Return the current name stored in the capsule. On failure, set an exception - and return *NULL*. + and return ``NULL``. - It is legal for a capsule to have a *NULL* name. This makes a *NULL* return + It is legal for a capsule to have a ``NULL`` name. This makes a ``NULL`` return code somewhat ambiguous; use :c:func:`PyCapsule_IsValid` or :c:func:`PyErr_Occurred` to disambiguate. @@ -107,13 +107,13 @@ Refer to :ref:`using-capsules` for more information on using these objects. import the module conventionally (using :c:func:`PyImport_ImportModule`). Return the capsule's internal *pointer* on success. On failure, set an - exception and return *NULL*. + exception and return ``NULL``. .. c:function:: int PyCapsule_IsValid(PyObject *capsule, const char *name) Determines whether or not *capsule* is a valid capsule. A valid capsule is - non-*NULL*, passes :c:func:`PyCapsule_CheckExact`, has a non-*NULL* pointer + non-``NULL``, passes :c:func:`PyCapsule_CheckExact`, has a non-``NULL`` pointer stored in it, and its internal name matches the *name* parameter. (See :c:func:`PyCapsule_GetPointer` for information on how capsule names are compared.) @@ -142,9 +142,9 @@ Refer to :ref:`using-capsules` for more information on using these objects. .. c:function:: int PyCapsule_SetName(PyObject *capsule, const char *name) - Set the name inside *capsule* to *name*. If non-*NULL*, the name must + Set the name inside *capsule* to *name*. If non-``NULL``, the name must outlive the capsule. If the previous *name* stored in the capsule was not - *NULL*, no attempt is made to free it. + ``NULL``, no attempt is made to free it. Return ``0`` on success. Return nonzero and set an exception on failure. @@ -152,6 +152,6 @@ Refer to :ref:`using-capsules` for more information on using these objects. .. c:function:: int PyCapsule_SetPointer(PyObject *capsule, void *pointer) Set the void pointer inside *capsule* to *pointer*. The pointer may not be - *NULL*. + ``NULL``. Return ``0`` on success. Return nonzero and set an exception on failure. diff --git a/Doc/c-api/cell.rst b/Doc/c-api/cell.rst index 427259c..624dfe8 100644 --- a/Doc/c-api/cell.rst +++ b/Doc/c-api/cell.rst @@ -27,13 +27,13 @@ Cell objects are not likely to be useful elsewhere. .. c:function:: int PyCell_Check(ob) - Return true if *ob* is a cell object; *ob* must not be *NULL*. + Return true if *ob* is a cell object; *ob* must not be ``NULL``. .. c:function:: PyObject* PyCell_New(PyObject *ob) Create and return a new cell object containing the value *ob*. The parameter may - be *NULL*. + be ``NULL``. .. c:function:: PyObject* PyCell_Get(PyObject *cell) @@ -44,19 +44,19 @@ Cell objects are not likely to be useful elsewhere. .. c:function:: PyObject* PyCell_GET(PyObject *cell) Return the contents of the cell *cell*, but without checking that *cell* is - non-*NULL* and a cell object. + non-``NULL`` and a cell object. .. c:function:: int PyCell_Set(PyObject *cell, PyObject *value) Set the contents of the cell object *cell* to *value*. This releases the - reference to any current content of the cell. *value* may be *NULL*. *cell* - must be non-*NULL*; if it is not a cell object, ``-1`` will be returned. On + reference to any current content of the cell. *value* may be ``NULL``. *cell* + must be non-``NULL``; if it is not a cell object, ``-1`` will be returned. On success, ``0`` will be returned. .. c:function:: void PyCell_SET(PyObject *cell, PyObject *value) Sets the value of the cell object *cell* to *value*. No reference counts are - adjusted, and no checks are made for safety; *cell* must be non-*NULL* and must + adjusted, and no checks are made for safety; *cell* must be non-``NULL`` and must be a cell object. diff --git a/Doc/c-api/codec.rst b/Doc/c-api/codec.rst index c55f199..172dcb3 100644 --- a/Doc/c-api/codec.rst +++ b/Doc/c-api/codec.rst @@ -21,7 +21,7 @@ Codec registry and support functions *object* is passed through the encoder function found for the given *encoding* using the error handling method defined by *errors*. *errors* may - be *NULL* to use the default method defined for the codec. Raises a + be ``NULL`` to use the default method defined for the codec. Raises a :exc:`LookupError` if no encoder can be found. .. c:function:: PyObject* PyCodec_Decode(PyObject *object, const char *encoding, const char *errors) @@ -30,7 +30,7 @@ Codec registry and support functions *object* is passed through the decoder function found for the given *encoding* using the error handling method defined by *errors*. *errors* may - be *NULL* to use the default method defined for the codec. Raises a + be ``NULL`` to use the default method defined for the codec. Raises a :exc:`LookupError` if no encoder can be found. @@ -40,7 +40,7 @@ Codec lookup API In the following functions, the *encoding* string is looked up converted to all lower-case characters, which makes encodings looked up through this mechanism effectively case-insensitive. If no codec is found, a :exc:`KeyError` is set -and *NULL* returned. +and ``NULL`` returned. .. c:function:: PyObject* PyCodec_Encoder(const char *encoding) @@ -92,7 +92,7 @@ Registry API for Unicode encoding error handlers .. c:function:: PyObject* PyCodec_LookupError(const char *name) Lookup the error handling callback function registered under *name*. As a - special case *NULL* can be passed, in which case the error handling callback + special case ``NULL`` can be passed, in which case the error handling callback for "strict" will be returned. .. c:function:: PyObject* PyCodec_StrictErrors(PyObject *exc) diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst index 9558a4a..b4c1372 100644 --- a/Doc/c-api/concrete.rst +++ b/Doc/c-api/concrete.rst @@ -17,8 +17,8 @@ dictionary, use :c:func:`PyDict_Check`. The chapter is structured like the .. warning:: While the functions described in this chapter carefully check the type of the - objects which are passed in, many of them do not check for *NULL* being passed - instead of a valid object. Allowing *NULL* to be passed in can cause memory + objects which are passed in, many of them do not check for ``NULL`` being passed + instead of a valid object. Allowing ``NULL`` to be passed in can cause memory access violations and immediate termination of the interpreter. diff --git a/Doc/c-api/contextvars.rst b/Doc/c-api/contextvars.rst index c344c8d..c0532f2 100644 --- a/Doc/c-api/contextvars.rst +++ b/Doc/c-api/contextvars.rst @@ -60,17 +60,17 @@ Type-check macros: .. c:function:: int PyContext_CheckExact(PyObject *o) Return true if *o* is of type :c:data:`PyContext_Type`. *o* must not be - *NULL*. This function always succeeds. + ``NULL``. This function always succeeds. .. c:function:: int PyContextVar_CheckExact(PyObject *o) Return true if *o* is of type :c:data:`PyContextVar_Type`. *o* must not be - *NULL*. This function always succeeds. + ``NULL``. This function always succeeds. .. c:function:: int PyContextToken_CheckExact(PyObject *o) Return true if *o* is of type :c:data:`PyContextToken_Type`. - *o* must not be *NULL*. This function always succeeds. + *o* must not be ``NULL``. This function always succeeds. Context object management functions: diff --git a/Doc/c-api/conversion.rst b/Doc/c-api/conversion.rst index c46722d..8ea8589 100644 --- a/Doc/c-api/conversion.rst +++ b/Doc/c-api/conversion.rst @@ -32,7 +32,7 @@ NULL``. If the platform doesn't have :c:func:`vsnprintf` and the buffer size needed to avoid truncation exceeds *size* by more than 512 bytes, Python aborts with a -*Py_FatalError*. +:c:func:`Py_FatalError`. The return value (*rv*) for these functions should be interpreted as follows: @@ -95,25 +95,25 @@ The following functions provide locale-independent string to number conversions. must be 0 and is ignored. The ``'r'`` format code specifies the standard :func:`repr` format. - *flags* can be zero or more of the values *Py_DTSF_SIGN*, - *Py_DTSF_ADD_DOT_0*, or *Py_DTSF_ALT*, or-ed together: + *flags* can be zero or more of the values ``Py_DTSF_SIGN``, + ``Py_DTSF_ADD_DOT_0``, or ``Py_DTSF_ALT``, or-ed together: - * *Py_DTSF_SIGN* means to always precede the returned string with a sign + * ``Py_DTSF_SIGN`` means to always precede the returned string with a sign character, even if *val* is non-negative. - * *Py_DTSF_ADD_DOT_0* means to ensure that the returned string will not look + * ``Py_DTSF_ADD_DOT_0`` means to ensure that the returned string will not look like an integer. - * *Py_DTSF_ALT* means to apply "alternate" formatting rules. See the + * ``Py_DTSF_ALT`` means to apply "alternate" formatting rules. See the documentation for the :c:func:`PyOS_snprintf` ``'#'`` specifier for details. - If *ptype* is non-NULL, then the value it points to will be set to one of - *Py_DTST_FINITE*, *Py_DTST_INFINITE*, or *Py_DTST_NAN*, signifying that + If *ptype* is non-``NULL``, then the value it points to will be set to one of + ``Py_DTST_FINITE``, ``Py_DTST_INFINITE``, or ``Py_DTST_NAN``, signifying that *val* is a finite number, an infinite number, or not a number, respectively. The return value is a pointer to *buffer* with the converted string or - *NULL* if the conversion failed. The caller is responsible for freeing the + ``NULL`` if the conversion failed. The caller is responsible for freeing the returned string by calling :c:func:`PyMem_Free`. .. versionadded:: 3.1 diff --git a/Doc/c-api/coro.rst b/Doc/c-api/coro.rst index 2fe50b5..af52d4f 100644 --- a/Doc/c-api/coro.rst +++ b/Doc/c-api/coro.rst @@ -23,7 +23,7 @@ return. .. c:function:: int PyCoro_CheckExact(PyObject *ob) - Return true if *ob*'s type is *PyCoro_Type*; *ob* must not be *NULL*. + Return true if *ob*'s type is :c:type:`PyCoro_Type`; *ob* must not be ``NULL``. .. c:function:: PyObject* PyCoro_New(PyFrameObject *frame, PyObject *name, PyObject *qualname) @@ -31,4 +31,4 @@ return. Create and return a new coroutine object based on the *frame* object, with ``__name__`` and ``__qualname__`` set to *name* and *qualname*. A reference to *frame* is stolen by this function. The *frame* argument - must not be *NULL*. + must not be ``NULL``. diff --git a/Doc/c-api/datetime.rst b/Doc/c-api/datetime.rst index 77b1b21..55de816 100644 --- a/Doc/c-api/datetime.rst +++ b/Doc/c-api/datetime.rst @@ -28,61 +28,61 @@ Type-check macros: .. c:function:: int PyDate_Check(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_DateType` or a subtype of - :c:data:`PyDateTime_DateType`. *ob* must not be *NULL*. + :c:data:`PyDateTime_DateType`. *ob* must not be ``NULL``. .. c:function:: int PyDate_CheckExact(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_DateType`. *ob* must not be - *NULL*. + ``NULL``. .. c:function:: int PyDateTime_Check(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_DateTimeType` or a subtype of - :c:data:`PyDateTime_DateTimeType`. *ob* must not be *NULL*. + :c:data:`PyDateTime_DateTimeType`. *ob* must not be ``NULL``. .. c:function:: int PyDateTime_CheckExact(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_DateTimeType`. *ob* must not - be *NULL*. + be ``NULL``. .. c:function:: int PyTime_Check(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_TimeType` or a subtype of - :c:data:`PyDateTime_TimeType`. *ob* must not be *NULL*. + :c:data:`PyDateTime_TimeType`. *ob* must not be ``NULL``. .. c:function:: int PyTime_CheckExact(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_TimeType`. *ob* must not be - *NULL*. + ``NULL``. .. c:function:: int PyDelta_Check(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_DeltaType` or a subtype of - :c:data:`PyDateTime_DeltaType`. *ob* must not be *NULL*. + :c:data:`PyDateTime_DeltaType`. *ob* must not be ``NULL``. .. c:function:: int PyDelta_CheckExact(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_DeltaType`. *ob* must not be - *NULL*. + ``NULL``. .. c:function:: int PyTZInfo_Check(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_TZInfoType` or a subtype of - :c:data:`PyDateTime_TZInfoType`. *ob* must not be *NULL*. + :c:data:`PyDateTime_TZInfoType`. *ob* must not be ``NULL``. .. c:function:: int PyTZInfo_CheckExact(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_TZInfoType`. *ob* must not be - *NULL*. + ``NULL``. Macros to create objects: @@ -144,7 +144,7 @@ Macros to create objects: Macros to extract fields from date objects. The argument must be an instance of :c:data:`PyDateTime_Date`, including subclasses (such as -:c:data:`PyDateTime_DateTime`). The argument must not be *NULL*, and the type is +:c:data:`PyDateTime_DateTime`). The argument must not be ``NULL``, and the type is not checked: .. c:function:: int PyDateTime_GET_YEAR(PyDateTime_Date *o) @@ -164,7 +164,7 @@ not checked: Macros to extract fields from datetime objects. The argument must be an instance of :c:data:`PyDateTime_DateTime`, including subclasses. The argument -must not be *NULL*, and the type is not checked: +must not be ``NULL``, and the type is not checked: .. c:function:: int PyDateTime_DATE_GET_HOUR(PyDateTime_DateTime *o) @@ -187,7 +187,7 @@ must not be *NULL*, and the type is not checked: Macros to extract fields from time objects. The argument must be an instance of -:c:data:`PyDateTime_Time`, including subclasses. The argument must not be *NULL*, +:c:data:`PyDateTime_Time`, including subclasses. The argument must not be ``NULL``, and the type is not checked: .. c:function:: int PyDateTime_TIME_GET_HOUR(PyDateTime_Time *o) @@ -212,7 +212,7 @@ and the type is not checked: Macros to extract fields from time delta objects. The argument must be an instance of :c:data:`PyDateTime_Delta`, including subclasses. The argument must -not be *NULL*, and the type is not checked: +not be ``NULL``, and the type is not checked: .. c:function:: int PyDateTime_DELTA_GET_DAYS(PyDateTime_Delta *o) diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index 0ced5a5..ea7baf8 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -33,7 +33,7 @@ Dictionary Objects .. c:function:: PyObject* PyDict_New() - Return a new empty dictionary, or *NULL* on failure. + Return a new empty dictionary, or ``NULL`` on failure. .. c:function:: PyObject* PyDictProxy_New(PyObject *mapping) @@ -92,7 +92,7 @@ Dictionary Objects .. c:function:: PyObject* PyDict_GetItem(PyObject *p, PyObject *key) - Return the object from dictionary *p* which has a key *key*. Return *NULL* + Return the object from dictionary *p* which has a key *key*. Return ``NULL`` if the key *key* is not present, but *without* setting an exception. Note that exceptions which occur while calling :meth:`__hash__` and @@ -103,8 +103,8 @@ Dictionary Objects .. c:function:: PyObject* PyDict_GetItemWithError(PyObject *p, PyObject *key) Variant of :c:func:`PyDict_GetItem` that does not suppress - exceptions. Return *NULL* **with** an exception set if an exception - occurred. Return *NULL* **without** an exception set if the key + exceptions. Return ``NULL`` **with** an exception set if an exception + occurred. Return ``NULL`` **without** an exception set if the key wasn't present. @@ -161,7 +161,7 @@ Dictionary Objects 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 - and value, respectively, or may be *NULL*. Any references returned through + 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 since the structure is sparse, the offsets are not consecutive. diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 14ca2b4..a53c49a 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -13,15 +13,15 @@ exception handling. It works somewhat like the POSIX :c:data:`errno` variable: there is a global indicator (per thread) of the last error that occurred. Most C API functions don't clear this on success, but will set it to indicate the cause of the error on failure. Most C API functions also return an error -indicator, usually *NULL* if they are supposed to return a pointer, or ``-1`` +indicator, usually ``NULL`` if they are supposed to return a pointer, or ``-1`` if they return an integer (exception: the :c:func:`PyArg_\*` functions return ``1`` for success and ``0`` for failure). Concretely, the error indicator consists of three object pointers: the exception's type, the exception's value, and the traceback object. Any -of those pointers can be NULL if non-set (although some combinations are -forbidden, for example you can't have a non-NULL traceback if the exception -type is NULL). +of those pointers can be ``NULL`` if non-set (although some combinations are +forbidden, for example you can't have a non-``NULL`` traceback if the exception +type is ``NULL``). When a function must fail because some function it called failed, it generally doesn't set the error indicator; the function it called already set it. It is @@ -89,7 +89,7 @@ Raising exceptions These functions help you set the current thread's error indicator. For convenience, some of these functions will always return a -NULL pointer for use in a ``return`` statement. +``NULL`` pointer for use in a ``return`` statement. .. c:function:: void PyErr_SetString(PyObject *type, const char *message) @@ -108,7 +108,7 @@ NULL pointer for use in a ``return`` statement. .. c:function:: PyObject* PyErr_Format(PyObject *exception, const char *format, ...) - This function sets the error indicator and returns *NULL*. *exception* + This function sets the error indicator and returns ``NULL``. *exception* should be a Python exception class. The *format* and subsequent parameters help format the error message; they have the same meaning and values as in :c:func:`PyUnicode_FromFormat`. *format* is an ASCII-encoded @@ -137,7 +137,7 @@ NULL pointer for use in a ``return`` statement. .. c:function:: PyObject* PyErr_NoMemory() - This is a shorthand for ``PyErr_SetNone(PyExc_MemoryError)``; it returns *NULL* + This is a shorthand for ``PyErr_SetNone(PyExc_MemoryError)``; it returns ``NULL`` so an object allocation function can write ``return PyErr_NoMemory();`` when it runs out of memory. @@ -153,7 +153,7 @@ NULL pointer for use in a ``return`` statement. and then calls ``PyErr_SetObject(type, object)``. On Unix, when the :c:data:`errno` value is :const:`EINTR`, indicating an interrupted system call, this calls :c:func:`PyErr_CheckSignals`, and if that set the error indicator, - leaves it set to that. The function always returns *NULL*, so a wrapper + leaves it set to that. The function always returns ``NULL``, so a wrapper function around a system call can write ``return PyErr_SetFromErrno(type);`` when the system call returns an error. @@ -161,7 +161,7 @@ NULL pointer for use in a ``return`` statement. .. c:function:: PyObject* PyErr_SetFromErrnoWithFilenameObject(PyObject *type, PyObject *filenameObject) Similar to :c:func:`PyErr_SetFromErrno`, with the additional behavior that if - *filenameObject* is not *NULL*, it is passed to the constructor of *type* as + *filenameObject* is not ``NULL``, it is passed to the constructor of *type* as a third parameter. In the case of :exc:`OSError` exception, this is used to define the :attr:`filename` attribute of the exception instance. @@ -192,7 +192,7 @@ NULL pointer for use in a ``return`` statement. then it constructs a tuple object whose first item is the *ierr* value and whose second item is the corresponding error message (gotten from :c:func:`FormatMessage`), and then calls ``PyErr_SetObject(PyExc_WindowsError, - object)``. This function always returns *NULL*. + object)``. This function always returns ``NULL``. .. availability:: Windows. @@ -301,7 +301,7 @@ an error value). .. c:function:: int PyErr_WarnEx(PyObject *category, const char *message, Py_ssize_t stack_level) Issue a warning message. The *category* argument is a warning category (see - below) or *NULL*; the *message* argument is a UTF-8 encoded string. *stack_level* is a + below) or ``NULL``; the *message* argument is a UTF-8 encoded string. *stack_level* is a positive number giving a number of stack frames; the warning will be issued from the currently executing line of code in that stack frame. A *stack_level* of 1 is the function calling :c:func:`PyErr_WarnEx`, 2 is the function above that, @@ -330,7 +330,7 @@ an error value). Issue a warning message with explicit control over all warning attributes. This is a straightforward wrapper around the Python function :func:`warnings.warn_explicit`, see there for more information. The *module* - and *registry* arguments may be set to *NULL* to get the default effect + and *registry* arguments may be set to ``NULL`` to get the default effect described there. .. versionadded:: 3.4 @@ -367,7 +367,7 @@ Querying the error indicator Test whether the error indicator is set. If set, return the exception *type* (the first argument to the last call to one of the :c:func:`PyErr_Set\*` - functions or to :c:func:`PyErr_Restore`). If not set, return *NULL*. You do not + functions or to :c:func:`PyErr_Restore`). If not set, return ``NULL``. You do not own a reference to the return value, so you do not need to :c:func:`Py_DECREF` it. @@ -397,9 +397,9 @@ Querying the error indicator .. c:function:: void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback) Retrieve the error indicator into three variables whose addresses are passed. - If the error indicator is not set, set all three variables to *NULL*. If it is + If the error indicator is not set, set all three variables to ``NULL``. If it is set, it will be cleared and you own a reference to each object retrieved. The - value and traceback object may be *NULL* even when the type object is not. + value and traceback object may be ``NULL`` even when the type object is not. .. note:: @@ -419,8 +419,8 @@ Querying the error indicator .. c:function:: void PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) Set the error indicator from the three objects. If the error indicator is - already set, it is cleared first. If the objects are *NULL*, the error - indicator is cleared. Do not pass a *NULL* type and non-*NULL* value or + already set, it is cleared first. If the objects are ``NULL``, the error + indicator is cleared. Do not pass a ``NULL`` type and non-``NULL`` value or traceback. The exception type should be a class. Do not pass an invalid exception type or value. (Violating these rules will cause subtle problems later.) This call takes away a reference to each object: you must own a @@ -459,7 +459,7 @@ Querying the error indicator Retrieve the exception info, as known from ``sys.exc_info()``. This refers to an exception that was *already caught*, not to an exception that was freshly raised. Returns new references for the three objects, any of which - may be *NULL*. Does not modify the exception info state. + may be ``NULL``. Does not modify the exception info state. .. note:: @@ -476,7 +476,7 @@ Querying the error indicator Set the exception info, as known from ``sys.exc_info()``. This refers to an exception that was *already caught*, not to an exception that was freshly raised. This function steals the references of the arguments. - To clear the exception state, pass *NULL* for all three arguments. + To clear the exception state, pass ``NULL`` for all three arguments. For general rules about the three arguments, see :c:func:`PyErr_Restore`. .. note:: @@ -546,7 +546,7 @@ Exception Classes This utility function creates and returns a new exception class. The *name* argument must be the name of the new exception, a C string of the form - ``module.classname``. The *base* and *dict* arguments are normally *NULL*. + ``module.classname``. The *base* and *dict* arguments are normally ``NULL``. This creates a class object derived from :exc:`Exception` (accessible in C as :c:data:`PyExc_Exception`). @@ -560,7 +560,7 @@ Exception Classes .. c:function:: PyObject* PyErr_NewExceptionWithDoc(const char *name, const char *doc, PyObject *base, PyObject *dict) Same as :c:func:`PyErr_NewException`, except that the new exception class can - easily be given a docstring: If *doc* is non-*NULL*, it will be used as the + easily be given a docstring: If *doc* is non-``NULL``, it will be used as the docstring for the exception class. .. versionadded:: 3.2 @@ -573,7 +573,7 @@ Exception Objects Return the traceback associated with the exception as a new reference, as accessible from Python through :attr:`__traceback__`. If there is no - traceback associated, this returns *NULL*. + traceback associated, this returns ``NULL``. .. c:function:: int PyException_SetTraceback(PyObject *ex, PyObject *tb) @@ -587,12 +587,12 @@ Exception Objects Return the context (another exception instance during whose handling *ex* was raised) associated with the exception as a new reference, as accessible from Python through :attr:`__context__`. If there is no context associated, this - returns *NULL*. + returns ``NULL``. .. c:function:: void PyException_SetContext(PyObject *ex, PyObject *ctx) - Set the context associated with the exception to *ctx*. Use *NULL* to clear + Set the context associated with the exception to *ctx*. Use ``NULL`` to clear it. There is no type check to make sure that *ctx* is an exception instance. This steals a reference to *ctx*. @@ -606,7 +606,7 @@ Exception Objects .. c:function:: void PyException_SetCause(PyObject *ex, PyObject *cause) - Set the cause associated with the exception to *cause*. Use *NULL* to clear + Set the cause associated with the exception to *cause*. Use ``NULL`` to clear it. There is no type check to make sure that *cause* is either an exception instance or :const:`None`. This steals a reference to *cause*. @@ -653,7 +653,7 @@ The following functions are used to create and modify Unicode exceptions from C. int PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start) Get the *start* attribute of the given exception object and place it into - *\*start*. *start* must not be *NULL*. Return ``0`` on success, ``-1`` on + *\*start*. *start* must not be ``NULL``. Return ``0`` on success, ``-1`` on failure. .. c:function:: int PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start) @@ -668,7 +668,7 @@ The following functions are used to create and modify Unicode exceptions from C. int PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end) Get the *end* attribute of the given exception object and place it into - *\*end*. *end* must not be *NULL*. Return ``0`` on success, ``-1`` on + *\*end*. *end* must not be ``NULL``. Return ``0`` on success, ``-1`` on failure. .. c:function:: int PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end) diff --git a/Doc/c-api/file.rst b/Doc/c-api/file.rst index 6f2ecee..63f1101 100644 --- a/Doc/c-api/file.rst +++ b/Doc/c-api/file.rst @@ -21,9 +21,9 @@ the :mod:`io` APIs instead. Create a Python file object from the file descriptor of an already opened file *fd*. The arguments *name*, *encoding*, *errors* and *newline* - can be *NULL* to use the defaults; *buffering* can be *-1* to use the + can be ``NULL`` to use the defaults; *buffering* can be *-1* to use the default. *name* is ignored and kept for backward compatibility. Return - *NULL* on failure. For a more comprehensive description of the arguments, + ``NULL`` on failure. For a more comprehensive description of the arguments, please refer to the :func:`io.open` function documentation. .. warning:: diff --git a/Doc/c-api/float.rst b/Doc/c-api/float.rst index 27a75e3..fae321c 100644 --- a/Doc/c-api/float.rst +++ b/Doc/c-api/float.rst @@ -34,12 +34,12 @@ Floating Point Objects .. c:function:: PyObject* PyFloat_FromString(PyObject *str) Create a :c:type:`PyFloatObject` object based on the string value in *str*, or - *NULL* on failure. + ``NULL`` on failure. .. c:function:: PyObject* PyFloat_FromDouble(double v) - Create a :c:type:`PyFloatObject` object from *v*, or *NULL* on failure. + Create a :c:type:`PyFloatObject` object from *v*, or ``NULL`` on failure. .. c:function:: double PyFloat_AsDouble(PyObject *pyfloat) diff --git a/Doc/c-api/function.rst b/Doc/c-api/function.rst index 17279c7..438381a 100644 --- a/Doc/c-api/function.rst +++ b/Doc/c-api/function.rst @@ -26,7 +26,7 @@ There are a few functions specific to Python functions. .. c:function:: int PyFunction_Check(PyObject *o) Return true if *o* is a function object (has type :c:data:`PyFunction_Type`). - The parameter must not be *NULL*. + The parameter must not be ``NULL``. .. c:function:: PyObject* PyFunction_New(PyObject *code, PyObject *globals) @@ -36,14 +36,14 @@ There are a few functions specific to Python functions. The function's docstring and name are retrieved from the code object. *__module__* is retrieved from *globals*. The argument defaults, annotations and closure are - set to *NULL*. *__qualname__* is set to the same value as the function's name. + set to ``NULL``. *__qualname__* is set to the same value as the function's name. .. c:function:: PyObject* PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname) As :c:func:`PyFunction_New`, but also allows setting the function object's - ``__qualname__`` attribute. *qualname* should be a unicode object or NULL; - if NULL, the ``__qualname__`` attribute is set to the same value as its + ``__qualname__`` attribute. *qualname* should be a unicode object or ``NULL``; + if ``NULL``, the ``__qualname__`` attribute is set to the same value as its ``__name__`` attribute. .. versionadded:: 3.3 @@ -69,27 +69,27 @@ There are a few functions specific to Python functions. .. c:function:: PyObject* PyFunction_GetDefaults(PyObject *op) Return the argument default values of the function object *op*. This can be a - tuple of arguments or *NULL*. + tuple of arguments or ``NULL``. .. c:function:: int PyFunction_SetDefaults(PyObject *op, PyObject *defaults) Set the argument default values for the function object *op*. *defaults* must be - *Py_None* or a tuple. + ``Py_None`` or a tuple. Raises :exc:`SystemError` and returns ``-1`` on failure. .. c:function:: PyObject* PyFunction_GetClosure(PyObject *op) - Return the closure associated with the function object *op*. This can be *NULL* + Return the closure associated with the function object *op*. This can be ``NULL`` or a tuple of cell objects. .. c:function:: int PyFunction_SetClosure(PyObject *op, PyObject *closure) Set the closure associated with the function object *op*. *closure* must be - *Py_None* or a tuple of cell objects. + ``Py_None`` or a tuple of cell objects. Raises :exc:`SystemError` and returns ``-1`` on failure. @@ -97,12 +97,12 @@ There are a few functions specific to Python functions. .. c:function:: PyObject *PyFunction_GetAnnotations(PyObject *op) Return the annotations of the function object *op*. This can be a - mutable dictionary or *NULL*. + mutable dictionary or ``NULL``. .. c:function:: int PyFunction_SetAnnotations(PyObject *op, PyObject *annotations) Set the annotations for the function object *op*. *annotations* - must be a dictionary or *Py_None*. + must be a dictionary or ``Py_None``. Raises :exc:`SystemError` and returns ``-1`` on failure. diff --git a/Doc/c-api/gcsupport.rst b/Doc/c-api/gcsupport.rst index 472cd93..95116d5 100644 --- a/Doc/c-api/gcsupport.rst +++ b/Doc/c-api/gcsupport.rst @@ -49,7 +49,7 @@ Constructors for container types must conform to two rules: .. c:function:: TYPE* PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize) Resize an object allocated by :c:func:`PyObject_NewVar`. Returns the - resized object or *NULL* on failure. *op* must not be tracked by the collector yet. + resized object or ``NULL`` on failure. *op* must not be tracked by the collector yet. .. c:function:: void PyObject_GC_Track(PyObject *op) @@ -121,7 +121,7 @@ The :c:member:`~PyTypeObject.tp_traverse` handler must have the following type: Traversal function for a container object. Implementations must call the *visit* function for each object directly contained by *self*, with the parameters to *visit* being the contained object and the *arg* value passed - to the handler. The *visit* function must not be called with a *NULL* + to the handler. The *visit* function must not be called with a ``NULL`` object argument. If *visit* returns a non-zero value that value should be returned immediately. @@ -132,7 +132,7 @@ must name its arguments exactly *visit* and *arg*: .. c:function:: void Py_VISIT(PyObject *o) - If *o* is not *NULL*, call the *visit* callback, with arguments *o* + If *o* is not ``NULL``, call the *visit* callback, with arguments *o* and *arg*. If *visit* returns a non-zero value, then return it. Using this macro, :c:member:`~PyTypeObject.tp_traverse` handlers look like:: @@ -145,7 +145,7 @@ must name its arguments exactly *visit* and *arg*: return 0; } -The :c:member:`~PyTypeObject.tp_clear` handler must be of the :c:type:`inquiry` type, or *NULL* +The :c:member:`~PyTypeObject.tp_clear` handler must be of the :c:type:`inquiry` type, or ``NULL`` if the object is immutable. diff --git a/Doc/c-api/gen.rst b/Doc/c-api/gen.rst index 1efbae4..2226f58 100644 --- a/Doc/c-api/gen.rst +++ b/Doc/c-api/gen.rst @@ -22,23 +22,23 @@ than explicitly calling :c:func:`PyGen_New` or :c:func:`PyGen_NewWithQualName`. .. c:function:: int PyGen_Check(PyObject *ob) - Return true if *ob* is a generator object; *ob* must not be *NULL*. + Return true if *ob* is a generator object; *ob* must not be ``NULL``. .. c:function:: int PyGen_CheckExact(PyObject *ob) - Return true if *ob*'s type is *PyGen_Type*; *ob* must not be *NULL*. + Return true if *ob*'s type is :c:type:`PyGen_Type`; *ob* must not be ``NULL``. .. c:function:: PyObject* PyGen_New(PyFrameObject *frame) Create and return a new generator object based on the *frame* object. A reference to *frame* is stolen by this function. The argument must not be - *NULL*. + ``NULL``. .. c:function:: PyObject* PyGen_NewWithQualName(PyFrameObject *frame, PyObject *name, PyObject *qualname) Create and return a new generator object based on the *frame* object, with ``__name__`` and ``__qualname__`` set to *name* and *qualname*. A reference to *frame* is stolen by this function. The *frame* argument - must not be *NULL*. + must not be ``NULL``. diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst index 8cdc256..764e2be 100644 --- a/Doc/c-api/import.rst +++ b/Doc/c-api/import.rst @@ -14,7 +14,7 @@ Importing Modules single: modules (in module sys) This is a simplified interface to :c:func:`PyImport_ImportModuleEx` below, - leaving the *globals* and *locals* arguments set to *NULL* and *level* set + leaving the *globals* and *locals* arguments set to ``NULL`` and *level* set to 0. When the *name* argument contains a dot (when it specifies a submodule of a package), the *fromlist* argument is set to the list ``['*']`` so that the return value is the @@ -22,7 +22,7 @@ Importing Modules be the case. (Unfortunately, this has an additional side effect when *name* in fact specifies a subpackage instead of a submodule: the submodules specified in the package's ``__all__`` variable are loaded.) Return a new reference to the - imported module, or *NULL* with an exception set on failure. A failing + imported module, or ``NULL`` with an exception set on failure. A failing import of a module doesn't leave the module in :data:`sys.modules`. This function always uses absolute imports. @@ -47,7 +47,7 @@ Importing Modules function :func:`__import__`. The return value is a new reference to the imported module or top-level - package, or *NULL* with an exception set on failure. Like for + package, or ``NULL`` with an exception set on failure. Like for :func:`__import__`, the return value when a submodule of a package was requested is normally the top-level package, unless a non-empty *fromlist* was given. @@ -63,7 +63,7 @@ Importing Modules this function directly. The return value is a new reference to the imported module or top-level package, - or *NULL* with an exception set on failure. Like for :func:`__import__`, + or ``NULL`` with an exception set on failure. Like for :func:`__import__`, the return value when a submodule of a package was requested is normally the top-level package, unless a non-empty *fromlist* was given. @@ -91,7 +91,7 @@ Importing Modules .. c:function:: PyObject* PyImport_ReloadModule(PyObject *m) - Reload a module. Return a new reference to the reloaded module, or *NULL* with + Reload a module. Return a new reference to the reloaded module, or ``NULL`` with an exception set on failure (the module still exists in this case). @@ -100,7 +100,7 @@ Importing Modules Return the module object corresponding to a module name. The *name* argument may be of the form ``package.module``. First check the modules dictionary if there's one there, and if not, create a new one and insert it in the modules - dictionary. Return *NULL* with an exception set on failure. + dictionary. Return ``NULL`` with an exception set on failure. .. note:: @@ -125,7 +125,7 @@ Importing Modules Given a module name (possibly of the form ``package.module``) and a code object read from a Python bytecode file or obtained from the built-in function :func:`compile`, load the module. Return a new reference to the module object, - or *NULL* with an exception set if an error occurred. *name* + or ``NULL`` with an exception set if an error occurred. *name* is removed from :attr:`sys.modules` in error cases, even if *name* was already in :attr:`sys.modules` on entry to :c:func:`PyImport_ExecCodeModule`. Leaving incompletely initialized modules in :attr:`sys.modules` is dangerous, as imports of @@ -207,8 +207,8 @@ Importing Modules .. c:function:: PyObject* PyImport_GetModule(PyObject *name) Return the already imported module with the given name. If the - module has not been imported yet then returns NULL but does not set - an error. Returns NULL and sets an error if the lookup failed. + module has not been imported yet then returns ``NULL`` but does not set + an error. Returns ``NULL`` and sets an error if the lookup failed. .. versionadded:: 3.7 @@ -277,7 +277,7 @@ Importing Modules .. c:var:: const struct _frozen* PyImport_FrozenModules This pointer is initialized to point to an array of :c:type:`struct _frozen` - records, terminated by one whose members are all *NULL* or zero. When a frozen + records, terminated by one whose members are all ``NULL`` or zero. When a frozen module is imported, it is searched in this table. Third-party code could play tricks with this to provide a dynamically created collection of frozen modules. @@ -310,7 +310,7 @@ Importing Modules .. c:function:: int PyImport_ExtendInittab(struct _inittab *newtab) Add a collection of modules to the table of built-in modules. The *newtab* - array must end with a sentinel entry which contains *NULL* for the :attr:`name` + array must end with a sentinel entry which contains ``NULL`` for the :attr:`name` field; failure to provide the sentinel value can result in a memory fault. Returns ``0`` on success or ``-1`` if insufficient memory could be allocated to extend the internal table. In the event of failure, no modules are added to the diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 93fcfe6..2822b88 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -326,7 +326,7 @@ Process-wide parameters It overrides :envvar:`PYTHONIOENCODING` values, and allows embedding code to control IO encoding when the environment variable does not work. - ``encoding`` and/or ``errors`` may be NULL to use + *encoding* and/or *errors* may be ``NULL`` to use :envvar:`PYTHONIOENCODING` and/or default values (depending on other settings). @@ -844,8 +844,8 @@ code, or when embedding the Python interpreter: .. c:function:: PyThreadState* PyEval_SaveThread() Release the global interpreter lock (if it has been created and thread - support is enabled) and reset the thread state to *NULL*, returning the - previous thread state (which is not *NULL*). If the lock has been created, + support is enabled) and reset the thread state to ``NULL``, returning the + previous thread state (which is not ``NULL``). If the lock has been created, the current thread must have acquired it. @@ -853,7 +853,7 @@ code, or when embedding the Python interpreter: Acquire the global interpreter lock (if it has been created and thread support is enabled) and set the thread state to *tstate*, which must not be - *NULL*. If the lock has been created, the current thread must not have + ``NULL``. If the lock has been created, the current thread must not have acquired it, otherwise deadlock ensues. .. note:: @@ -866,14 +866,14 @@ code, or when embedding the Python interpreter: .. c:function:: PyThreadState* PyThreadState_Get() Return the current thread state. The global interpreter lock must be held. - When the current thread state is *NULL*, this issues a fatal error (so that - the caller needn't check for *NULL*). + When the current thread state is ``NULL``, this issues a fatal error (so that + the caller needn't check for ``NULL``). .. c:function:: PyThreadState* PyThreadState_Swap(PyThreadState *tstate) Swap the current thread state with the thread state given by the argument - *tstate*, which may be *NULL*. The global interpreter lock must be held + *tstate*, which may be ``NULL``. The global interpreter lock must be held and is not released. @@ -1044,7 +1044,7 @@ All of the following functions must be called after :c:func:`Py_Initialize`. Return a dictionary in which extensions can store thread-specific state information. Each extension should use a unique key to use to store state in the dictionary. It is okay to call this function when no current thread state - is available. If this function returns *NULL*, no exception has been raised and + is available. If this function returns ``NULL``, no exception has been raised and the caller should assume no current thread state is available. @@ -1065,7 +1065,7 @@ All of the following functions must be called after :c:func:`Py_Initialize`. .. c:function:: void PyEval_AcquireThread(PyThreadState *tstate) Acquire the global interpreter lock and set the current thread state to - *tstate*, which should not be *NULL*. The lock must have been created earlier. + *tstate*, which should not be ``NULL``. The lock must have been created earlier. If this thread already has the lock, deadlock ensues. :c:func:`PyEval_RestoreThread` is a higher-level function which is always @@ -1074,9 +1074,9 @@ All of the following functions must be called after :c:func:`Py_Initialize`. .. c:function:: void PyEval_ReleaseThread(PyThreadState *tstate) - Reset the current thread state to *NULL* and release the global interpreter + Reset the current thread state to ``NULL`` and release the global interpreter lock. The lock must have been created earlier and must be held by the current - thread. The *tstate* argument, which must not be *NULL*, is only used to check + thread. The *tstate* argument, which must not be ``NULL``, is only used to check that it represents the current thread state --- if it isn't, a fatal error is reported. @@ -1141,7 +1141,7 @@ using the following functions: The return value points to the first thread state created in the new sub-interpreter. This thread state is made in the current thread state. Note that no actual thread is created; see the discussion of thread states - below. If creation of the new interpreter is unsuccessful, *NULL* is + below. If creation of the new interpreter is unsuccessful, ``NULL`` is returned; no exception is set since the exception state is stored in the current thread state and there may not be a current thread state. (Like all other Python/C API functions, the global interpreter lock must be held before @@ -1172,7 +1172,7 @@ using the following functions: Destroy the (sub-)interpreter represented by the given thread state. The given thread state must be the current thread state. See the discussion of thread - states below. When the call returns, the current thread state is *NULL*. All + states below. When the call returns, the current thread state is ``NULL``. All thread states associated with this interpreter are destroyed. (The global interpreter lock must be held before calling this function and is still held when it returns.) :c:func:`Py_FinalizeEx` will destroy all sub-interpreters that @@ -1279,27 +1279,27 @@ Python-level trace functions in previous versions. :const:`PyTrace_C_CALL`, :const:`PyTrace_C_EXCEPTION`, :const:`PyTrace_C_RETURN`, or :const:`PyTrace_OPCODE`, and *arg* depends on the value of *what*: - +------------------------------+--------------------------------------+ - | Value of *what* | Meaning of *arg* | - +==============================+======================================+ - | :const:`PyTrace_CALL` | Always :c:data:`Py_None`. | - +------------------------------+--------------------------------------+ - | :const:`PyTrace_EXCEPTION` | Exception information as returned by | - | | :func:`sys.exc_info`. | - +------------------------------+--------------------------------------+ - | :const:`PyTrace_LINE` | Always :c:data:`Py_None`. | - +------------------------------+--------------------------------------+ - | :const:`PyTrace_RETURN` | Value being returned to the caller, | - | | or *NULL* if caused by an exception. | - +------------------------------+--------------------------------------+ - | :const:`PyTrace_C_CALL` | Function object being called. | - +------------------------------+--------------------------------------+ - | :const:`PyTrace_C_EXCEPTION` | Function object being called. | - +------------------------------+--------------------------------------+ - | :const:`PyTrace_C_RETURN` | Function object being called. | - +------------------------------+--------------------------------------+ - | :const:`PyTrace_OPCODE` | Always :c:data:`Py_None`. | - +------------------------------+--------------------------------------+ + +------------------------------+----------------------------------------+ + | Value of *what* | Meaning of *arg* | + +==============================+========================================+ + | :const:`PyTrace_CALL` | Always :c:data:`Py_None`. | + +------------------------------+----------------------------------------+ + | :const:`PyTrace_EXCEPTION` | Exception information as returned by | + | | :func:`sys.exc_info`. | + +------------------------------+----------------------------------------+ + | :const:`PyTrace_LINE` | Always :c:data:`Py_None`. | + +------------------------------+----------------------------------------+ + | :const:`PyTrace_RETURN` | Value being returned to the caller, | + | | or ``NULL`` if caused by an exception. | + +------------------------------+----------------------------------------+ + | :const:`PyTrace_C_CALL` | Function object being called. | + +------------------------------+----------------------------------------+ + | :const:`PyTrace_C_EXCEPTION` | Function object being called. | + +------------------------------+----------------------------------------+ + | :const:`PyTrace_C_RETURN` | Function object being called. | + +------------------------------+----------------------------------------+ + | :const:`PyTrace_OPCODE` | Always :c:data:`Py_None`. | + +------------------------------+----------------------------------------+ .. c:var:: int PyTrace_CALL @@ -1363,7 +1363,7 @@ Python-level trace functions in previous versions. .. c:function:: void PyEval_SetProfile(Py_tracefunc func, PyObject *obj) Set the profiler function to *func*. The *obj* parameter is passed to the - function as its first parameter, and may be any Python object, or *NULL*. If + function as its first parameter, and may be any Python object, or ``NULL``. If the profile function needs to maintain state, using a different value for *obj* for each thread provides a convenient and thread-safe place to store it. The profile function is called for all monitored events except :const:`PyTrace_LINE` @@ -1486,7 +1486,7 @@ is not possible due to its implementation being opaque at build time. .. c:function:: Py_tss_t* PyThread_tss_alloc() Return a value which is the same state as a value initialized with - :c:macro:`Py_tss_NEEDS_INIT`, or *NULL* in the case of dynamic allocation + :c:macro:`Py_tss_NEEDS_INIT`, or ``NULL`` in the case of dynamic allocation failure. @@ -1505,7 +1505,7 @@ is not possible due to its implementation being opaque at build time. Methods ~~~~~~~ -The parameter *key* of these functions must not be *NULL*. Moreover, the +The parameter *key* of these functions must not be ``NULL``. Moreover, the behaviors of :c:func:`PyThread_tss_set` and :c:func:`PyThread_tss_get` are undefined if the given :c:type:`Py_tss_t` has not been initialized by :c:func:`PyThread_tss_create`. @@ -1545,7 +1545,7 @@ undefined if the given :c:type:`Py_tss_t` has not been initialized by .. c:function:: void* PyThread_tss_get(Py_tss_t *key) 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 + 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 964d348..e4aad1f 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -152,7 +152,7 @@ complete listing. .. c:macro:: Py_GETENV(s) - Like ``getenv(s)``, but returns *NULL* if :option:`-E` was passed on the + Like ``getenv(s)``, but returns ``NULL`` if :option:`-E` was passed on the command line (i.e. if ``Py_IgnoreEnvironmentFlag`` is set). .. c:macro:: Py_UNUSED(arg) @@ -463,7 +463,7 @@ functions in the Python/C API can raise exceptions, unless an explicit claim is made otherwise in a function's documentation. In general, when a function encounters an error, it sets an exception, discards any object references that it owns, and returns an error indicator. If not documented otherwise, this -indicator is either *NULL* or ``-1``, depending on the function's return type. +indicator is either ``NULL`` or ``-1``, depending on the function's return type. A few functions return a Boolean true/false result, with false indicating an error. Very few functions return no explicit error indicator or have an ambiguous return value, and require explicit testing for errors with @@ -478,13 +478,13 @@ using global storage in an unthreaded application). A thread can be in one of two states: an exception has occurred, or not. The function :c:func:`PyErr_Occurred` can be used to check for this: it returns a borrowed reference to the exception type object when an exception has occurred, and -*NULL* otherwise. There are a number of functions to set the exception state: +``NULL`` otherwise. There are a number of functions to set the exception state: :c:func:`PyErr_SetString` is the most common (though not the most general) function to set the exception state, and :c:func:`PyErr_Clear` clears the exception state. The full exception state consists of three objects (all of which can be -*NULL*): the exception type, the corresponding exception value, and the +``NULL``): the exception type, the corresponding exception value, and the traceback. These have the same meanings as the Python result of ``sys.exc_info()``; however, they are not the same: the Python objects represent the last exception being handled by a Python :keyword:`try` ... @@ -585,10 +585,10 @@ Here is the corresponding C code, in all its glory:: This example represents an endorsed use of the ``goto`` statement in C! It illustrates the use of :c:func:`PyErr_ExceptionMatches` and :c:func:`PyErr_Clear` to handle specific exceptions, and the use of -:c:func:`Py_XDECREF` to dispose of owned references that may be *NULL* (note the +:c:func:`Py_XDECREF` to dispose of owned references that may be ``NULL`` (note the ``'X'`` in the name; :c:func:`Py_DECREF` would crash when confronted with a -*NULL* reference). It is important that the variables used to hold owned -references are initialized to *NULL* for this to work; likewise, the proposed +``NULL`` reference). It is important that the variables used to hold owned +references are initialized to ``NULL`` for this to work; likewise, the proposed return value is initialized to ``-1`` (failure) and only set to success after the final call made is successful. diff --git a/Doc/c-api/iter.rst b/Doc/c-api/iter.rst index 2ba444d..62ca082 100644 --- a/Doc/c-api/iter.rst +++ b/Doc/c-api/iter.rst @@ -16,8 +16,8 @@ There are two functions specifically for working with iterators. Return the next value from the iteration *o*. The object must be an iterator (it is up to the caller to check this). If there are no remaining values, - returns *NULL* with no exception set. If an error occurs while retrieving - the item, returns *NULL* and passes along the exception. + returns ``NULL`` with no exception set. If an error occurs while retrieving + the item, returns ``NULL`` and passes along the exception. To write a loop which iterates over an iterator, the C code should look something like this:: diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst index a5cd634..0dde884 100644 --- a/Doc/c-api/list.rst +++ b/Doc/c-api/list.rst @@ -33,7 +33,7 @@ List Objects .. c:function:: PyObject* PyList_New(Py_ssize_t len) - Return a new list of length *len* on success, or *NULL* on failure. + Return a new list of length *len* on success, or ``NULL`` on failure. .. note:: @@ -61,7 +61,7 @@ List Objects Return the object at position *index* in the list pointed to by *list*. The position must be non-negative; indexing from the end of the list is not supported. If *index* is out of bounds (<0 or >=len(list)), - return *NULL* and set an :exc:`IndexError` exception. + return ``NULL`` and set an :exc:`IndexError` exception. .. c:function:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i) @@ -71,8 +71,9 @@ List Objects .. c:function:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item) - Set the item at index *index* in list to *item*. Return ``0`` on success - or ``-1`` on failure. + Set the item at index *index* in list to *item*. Return ``0`` on success. + If *index* is out of bounds, return ``-1`` and set an :exc:`IndexError` + exception. .. note:: @@ -110,18 +111,17 @@ List Objects .. c:function:: PyObject* PyList_GetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high) Return a list of the objects in *list* containing the objects *between* *low* - and *high*. Return *NULL* and set an exception if unsuccessful. Analogous - to ``list[low:high]``. Negative indices, as when slicing from Python, are not - supported. + and *high*. Return ``NULL`` and set an exception if unsuccessful. Analogous + to ``list[low:high]``. Indexing from the end of the list is not supported. .. c:function:: int PyList_SetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high, PyObject *itemlist) Set the slice of *list* between *low* and *high* to the contents of *itemlist*. Analogous to ``list[low:high] = itemlist``. The *itemlist* may - be *NULL*, indicating the assignment of an empty list (slice deletion). - Return ``0`` on success, ``-1`` on failure. Negative indices, as when - slicing from Python, are not supported. + be ``NULL``, indicating the assignment of an empty list (slice deletion). + Return ``0`` on success, ``-1`` on failure. Indexing from the end of the + list is not supported. .. c:function:: int PyList_Sort(PyObject *list) diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index 71144f1..15fccb8 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -38,7 +38,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. .. c:function:: PyObject* PyLong_FromLong(long v) - Return a new :c:type:`PyLongObject` object from *v*, or *NULL* on failure. + Return a new :c:type:`PyLongObject` object from *v*, or ``NULL`` on failure. The current implementation keeps an array of integer objects for all integers between ``-5`` and ``256``, when you create an int in that range you actually @@ -50,43 +50,43 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. .. c:function:: PyObject* PyLong_FromUnsignedLong(unsigned long v) Return a new :c:type:`PyLongObject` object from a C :c:type:`unsigned long`, or - *NULL* on failure. + ``NULL`` on failure. .. c:function:: PyObject* PyLong_FromSsize_t(Py_ssize_t v) Return a new :c:type:`PyLongObject` object from a C :c:type:`Py_ssize_t`, or - *NULL* on failure. + ``NULL`` on failure. .. c:function:: PyObject* PyLong_FromSize_t(size_t v) Return a new :c:type:`PyLongObject` object from a C :c:type:`size_t`, or - *NULL* on failure. + ``NULL`` on failure. .. c:function:: PyObject* PyLong_FromLongLong(long long v) - Return a new :c:type:`PyLongObject` object from a C :c:type:`long long`, or *NULL* + Return a new :c:type:`PyLongObject` object from a C :c:type:`long long`, or ``NULL`` on failure. .. c:function:: PyObject* PyLong_FromUnsignedLongLong(unsigned long long v) Return a new :c:type:`PyLongObject` object from a C :c:type:`unsigned long long`, - or *NULL* on failure. + or ``NULL`` on failure. .. c:function:: PyObject* PyLong_FromDouble(double v) Return a new :c:type:`PyLongObject` object from the integer part of *v*, or - *NULL* on failure. + ``NULL`` on failure. .. c:function:: PyObject* PyLong_FromString(const char *str, char **pend, int base) Return a new :c:type:`PyLongObject` based on the string value in *str*, which - is interpreted according to the radix in *base*. If *pend* is non-*NULL*, + is interpreted according to the radix in *base*. If *pend* is non-``NULL``, *\*pend* will point to the first character in *str* which follows the representation of the number. If *base* is ``0``, *str* is interpreted using the :ref:`integers` definition; in this case, leading zeros in a @@ -294,4 +294,4 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. is only assured to produce a usable :c:type:`void` pointer for values created with :c:func:`PyLong_FromVoidPtr`. - Returns *NULL* on error. Use :c:func:`PyErr_Occurred` to disambiguate. + Returns ``NULL`` on error. Use :c:func:`PyErr_Occurred` to disambiguate. diff --git a/Doc/c-api/mapping.rst b/Doc/c-api/mapping.rst index e37dec9..abdc2ae 100644 --- a/Doc/c-api/mapping.rst +++ b/Doc/c-api/mapping.rst @@ -14,8 +14,7 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and Return ``1`` if the object provides mapping protocol or supports slicing, and ``0`` otherwise. Note that it returns ``1`` for Python classes with a :meth:`__getitem__` method since in general case it is impossible to - determine what the type of keys it supports. This function always - succeeds. + determine what type of keys it supports. This function always succeeds. .. c:function:: Py_ssize_t PyMapping_Size(PyObject *o) @@ -29,7 +28,7 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and .. c:function:: PyObject* PyMapping_GetItemString(PyObject *o, const char *key) - Return element of *o* corresponding to the string *key* or *NULL* on failure. + Return element of *o* corresponding to the string *key* or ``NULL`` on failure. This is the equivalent of the Python expression ``o[key]``. See also :c:func:`PyObject_GetItem`. @@ -79,7 +78,7 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and .. c:function:: PyObject* PyMapping_Keys(PyObject *o) On success, return a list of the keys in object *o*. On failure, return - *NULL*. + ``NULL``. .. versionchanged:: 3.7 Previously, the function returned a list or a tuple. @@ -88,7 +87,7 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and .. c:function:: PyObject* PyMapping_Values(PyObject *o) On success, return a list of the values in object *o*. On failure, return - *NULL*. + ``NULL``. .. versionchanged:: 3.7 Previously, the function returned a list or a tuple. @@ -97,7 +96,7 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and .. c:function:: PyObject* PyMapping_Items(PyObject *o) On success, return a list of the items in object *o*, where each item is a - tuple containing a key-value pair. On failure, return *NULL*. + tuple containing a key-value pair. On failure, return ``NULL``. .. versionchanged:: 3.7 Previously, the function returned a list or a tuple. diff --git a/Doc/c-api/marshal.rst b/Doc/c-api/marshal.rst index 17ec621..bf5fb4e 100644 --- a/Doc/c-api/marshal.rst +++ b/Doc/c-api/marshal.rst @@ -16,7 +16,7 @@ Numeric values are stored with the least significant byte first. The module supports two versions of the data format: version 0 is the historical version, version 1 shares interned strings in the file, and upon unmarshalling. Version 2 uses a binary format for floating point numbers. -*Py_MARSHAL_VERSION* indicates the current file format (currently 2). +``Py_MARSHAL_VERSION`` indicates the current file format (currently 2). .. c:function:: void PyMarshal_WriteLongToFile(long value, FILE *file, int version) @@ -67,7 +67,7 @@ The following functions allow marshalled values to be read back in. reading. On error, sets the appropriate exception (:exc:`EOFError`, :exc:`ValueError` - or :exc:`TypeError`) and returns *NULL*. + or :exc:`TypeError`) and returns ``NULL``. .. c:function:: PyObject* PyMarshal_ReadLastObjectFromFile(FILE *file) @@ -81,7 +81,7 @@ The following functions allow marshalled values to be read back in. anything else from the file. On error, sets the appropriate exception (:exc:`EOFError`, :exc:`ValueError` - or :exc:`TypeError`) and returns *NULL*. + or :exc:`TypeError`) and returns ``NULL``. .. c:function:: PyObject* PyMarshal_ReadObjectFromString(const char *data, Py_ssize_t len) @@ -90,5 +90,5 @@ The following functions allow marshalled values to be read back in. containing *len* bytes pointed to by *data*. On error, sets the appropriate exception (:exc:`EOFError`, :exc:`ValueError` - or :exc:`TypeError`) and returns *NULL*. + or :exc:`TypeError`) and returns ``NULL``. diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index 01f7f42..f14e1e1 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -110,9 +110,9 @@ zero bytes. .. c:function:: void* PyMem_RawMalloc(size_t n) Allocates *n* bytes and returns a pointer of type :c:type:`void\*` to the - allocated memory, or *NULL* if the request fails. + allocated memory, or ``NULL`` if the request fails. - Requesting zero bytes returns a distinct non-*NULL* pointer if possible, as + Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as if ``PyMem_RawMalloc(1)`` had been called instead. The memory will not have been initialized in any way. @@ -120,11 +120,11 @@ 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 - non-*NULL* pointer if possible, as if ``PyMem_RawCalloc(1, 1)`` had been + non-``NULL`` pointer if possible, as if ``PyMem_RawCalloc(1, 1)`` had been called instead. .. versionadded:: 3.5 @@ -135,15 +135,15 @@ zero bytes. Resizes the memory block pointed to by *p* to *n* bytes. The contents will be unchanged to the minimum of the old and the new sizes. - If *p* is *NULL*, the call is equivalent to ``PyMem_RawMalloc(n)``; else if + If *p* is ``NULL``, the call is equivalent to ``PyMem_RawMalloc(n)``; else if *n* is equal to zero, the memory block is resized but is not freed, and the - returned pointer is non-*NULL*. + returned pointer is non-``NULL``. - Unless *p* is *NULL*, it must have been returned by a previous call to + Unless *p* is ``NULL``, it must have been returned by a previous call to :c:func:`PyMem_RawMalloc`, :c:func:`PyMem_RawRealloc` or :c:func:`PyMem_RawCalloc`. - If the request fails, :c:func:`PyMem_RawRealloc` returns *NULL* and *p* + If the request fails, :c:func:`PyMem_RawRealloc` returns ``NULL`` and *p* remains a valid pointer to the previous memory area. @@ -154,7 +154,7 @@ zero bytes. :c:func:`PyMem_RawCalloc`. Otherwise, or if ``PyMem_RawFree(p)`` has been called before, undefined behavior occurs. - If *p* is *NULL*, no operation is performed. + If *p* is ``NULL``, no operation is performed. .. _memoryinterface: @@ -181,9 +181,9 @@ 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 - allocated memory, or *NULL* if the request fails. + allocated memory, or ``NULL`` if the request fails. - Requesting zero bytes returns a distinct non-*NULL* pointer if possible, as + Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as if ``PyMem_Malloc(1)`` had been called instead. The memory will not have been initialized in any way. @@ -191,11 +191,11 @@ 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 - non-*NULL* pointer if possible, as if ``PyMem_Calloc(1, 1)`` had been called + non-``NULL`` pointer if possible, as if ``PyMem_Calloc(1, 1)`` had been called instead. .. versionadded:: 3.5 @@ -206,14 +206,14 @@ The :ref:`default memory allocator ` uses the Resizes the memory block pointed to by *p* to *n* bytes. The contents will be unchanged to the minimum of the old and the new sizes. - If *p* is *NULL*, the call is equivalent to ``PyMem_Malloc(n)``; else if *n* + If *p* is ``NULL``, the call is equivalent to ``PyMem_Malloc(n)``; else if *n* is equal to zero, the memory block is resized but is not freed, and the - returned pointer is non-*NULL*. + returned pointer is non-``NULL``. - Unless *p* is *NULL*, it must have been returned by a previous call to + Unless *p* is ``NULL``, it must have been returned by a previous call to :c:func:`PyMem_Malloc`, :c:func:`PyMem_Realloc` or :c:func:`PyMem_Calloc`. - If the request fails, :c:func:`PyMem_Realloc` returns *NULL* and *p* remains + If the request fails, :c:func:`PyMem_Realloc` returns ``NULL`` and *p* remains a valid pointer to the previous memory area. @@ -224,7 +224,7 @@ The :ref:`default memory allocator ` uses the :c:func:`PyMem_Calloc`. Otherwise, or if ``PyMem_Free(p)`` has been called before, undefined behavior occurs. - If *p* is *NULL*, no operation is performed. + If *p* is ``NULL``, no operation is performed. The following type-oriented macros are provided for convenience. Note that *TYPE* refers to any C type. @@ -241,7 +241,7 @@ The following type-oriented macros are provided for convenience. Note that 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, - *p* will be a pointer to the new memory area, or *NULL* in the event of + *p* will be a pointer to the new memory area, or ``NULL`` in the event of failure. This is a C preprocessor macro; *p* is always reassigned. Save the original @@ -283,9 +283,9 @@ 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 - allocated memory, or *NULL* if the request fails. + allocated memory, or ``NULL`` if the request fails. - Requesting zero bytes returns a distinct non-*NULL* pointer if possible, as + Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as if ``PyObject_Malloc(1)`` had been called instead. The memory will not have been initialized in any way. @@ -293,11 +293,11 @@ 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 - non-*NULL* pointer if possible, as if ``PyObject_Calloc(1, 1)`` had been called + non-``NULL`` pointer if possible, as if ``PyObject_Calloc(1, 1)`` had been called instead. .. versionadded:: 3.5 @@ -308,14 +308,14 @@ The :ref:`default object allocator ` uses the Resizes the memory block pointed to by *p* to *n* bytes. The contents will be unchanged to the minimum of the old and the new sizes. - If *p* is *NULL*, the call is equivalent to ``PyObject_Malloc(n)``; else if *n* + If *p* is ``NULL``, the call is equivalent to ``PyObject_Malloc(n)``; else if *n* is equal to zero, the memory block is resized but is not freed, and the - returned pointer is non-*NULL*. + returned pointer is non-``NULL``. - Unless *p* is *NULL*, it must have been returned by a previous call to + Unless *p* is ``NULL``, it must have been returned by a previous call to :c:func:`PyObject_Malloc`, :c:func:`PyObject_Realloc` or :c:func:`PyObject_Calloc`. - If the request fails, :c:func:`PyObject_Realloc` returns *NULL* and *p* remains + If the request fails, :c:func:`PyObject_Realloc` returns ``NULL`` and *p* remains a valid pointer to the previous memory area. @@ -326,7 +326,7 @@ The :ref:`default object allocator ` uses the :c:func:`PyObject_Calloc`. Otherwise, or if ``PyObject_Free(p)`` has been called before, undefined behavior occurs. - If *p* is *NULL*, no operation is performed. + If *p* is ``NULL``, no operation is performed. .. _default-memory-allocators: @@ -424,7 +424,7 @@ Customize Memory Allocators Set the memory block allocator of the specified domain. - The new allocator must return a distinct non-NULL pointer when requesting + The new allocator must return a distinct non-``NULL`` pointer when requesting zero bytes. For the :c:data:`PYMEM_DOMAIN_RAW` domain, the allocator must be diff --git a/Doc/c-api/memoryview.rst b/Doc/c-api/memoryview.rst index 9f6bfd7..0fcd96d 100644 --- a/Doc/c-api/memoryview.rst +++ b/Doc/c-api/memoryview.rst @@ -57,7 +57,7 @@ any other object. .. c:function:: Py_buffer *PyMemoryView_GET_BASE(PyObject *mview) Return either a pointer to the exporting object that the memoryview is based - on or *NULL* if the memoryview has been created by one of the functions + on or ``NULL`` if the memoryview has been created by one of the functions :c:func:`PyMemoryView_FromMemory` or :c:func:`PyMemoryView_FromBuffer`. *mview* **must** be a memoryview instance. diff --git a/Doc/c-api/method.rst b/Doc/c-api/method.rst index 7a2a84f..c08bc32 100644 --- a/Doc/c-api/method.rst +++ b/Doc/c-api/method.rst @@ -21,7 +21,7 @@ to bind a :c:data:`PyCFunction` to a class object. It replaces the former call .. c:function:: int PyInstanceMethod_Check(PyObject *o) Return true if *o* is an instance method object (has type - :c:data:`PyInstanceMethod_Type`). The parameter must not be *NULL*. + :c:data:`PyInstanceMethod_Type`). The parameter must not be ``NULL``. .. c:function:: PyObject* PyInstanceMethod_New(PyObject *func) @@ -64,14 +64,14 @@ no longer available. .. c:function:: int PyMethod_Check(PyObject *o) Return true if *o* is a method object (has type :c:data:`PyMethod_Type`). The - parameter must not be *NULL*. + parameter must not be ``NULL``. .. c:function:: PyObject* PyMethod_New(PyObject *func, PyObject *self) Return a new method object, with *func* being any callable object and *self* the instance the method should be bound. *func* is the function that will - be called when the method is called. *self* must not be *NULL*. + be called when the method is called. *self* must not be ``NULL``. .. c:function:: PyObject* PyMethod_Function(PyObject *meth) diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index 7168dc7..a06e791 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -61,7 +61,7 @@ Module Objects Return the dictionary object that implements *module*'s namespace; this object is the same as the :attr:`~object.__dict__` attribute of the module object. If *module* is not a module object (or a subtype of a module object), - :exc:`SystemError` is raised and *NULL* is returned. + :exc:`SystemError` is raised and ``NULL`` is returned. It is recommended extensions use other :c:func:`PyModule_\*` and :c:func:`PyObject_\*` functions rather than directly manipulate a module's @@ -75,7 +75,7 @@ Module Objects single: SystemError (built-in exception) Return *module*'s :attr:`__name__` value. If the module does not provide one, - or if it is not a string, :exc:`SystemError` is raised and *NULL* is returned. + or if it is not a string, :exc:`SystemError` is raised and ``NULL`` is returned. .. versionadded:: 3.3 @@ -88,14 +88,14 @@ Module Objects .. c:function:: void* PyModule_GetState(PyObject *module) Return the "state" of the module, that is, a pointer to the block of memory - allocated at module creation time, or *NULL*. See + allocated at module creation time, or ``NULL``. See :c:member:`PyModuleDef.m_size`. .. c:function:: PyModuleDef* PyModule_GetDef(PyObject *module) Return a pointer to the :c:type:`PyModuleDef` struct from which the module was - created, or *NULL* if the module wasn't created from a definition. + created, or ``NULL`` if the module wasn't created from a definition. .. c:function:: PyObject* PyModule_GetFilenameObject(PyObject *module) @@ -106,7 +106,7 @@ Module Objects Return the name of the file from which *module* was loaded using *module*'s :attr:`__file__` attribute. If this is not defined, or if it is not a - unicode string, raise :exc:`SystemError` and return *NULL*; otherwise return + unicode string, raise :exc:`SystemError` and return ``NULL``; otherwise return a reference to a Unicode object. .. versionadded:: 3.2 @@ -178,17 +178,17 @@ or request "multi-phase initialization" by returning the definition struct itsel .. c:member:: PyMethodDef* m_methods A pointer to a table of module-level functions, described by - :c:type:`PyMethodDef` values. Can be *NULL* if no functions are present. + :c:type:`PyMethodDef` values. Can be ``NULL`` if no functions are present. .. c:member:: PyModuleDef_Slot* m_slots An array of slot definitions for multi-phase initialization, terminated by a ``{0, NULL}`` entry. - When using single-phase initialization, *m_slots* must be *NULL*. + When using single-phase initialization, *m_slots* must be ``NULL``. .. versionchanged:: 3.5 - Prior to version 3.5, this member was always set to *NULL*, + Prior to version 3.5, this member was always set to ``NULL``, and was defined as: .. c:member:: inquiry m_reload @@ -196,20 +196,20 @@ or request "multi-phase initialization" by returning the definition struct itsel .. c:member:: traverseproc m_traverse A traversal function to call during GC traversal of the module object, or - *NULL* if not needed. This function may be called before module state + ``NULL`` if not needed. This function may be called before module state is allocated (:c:func:`PyModule_GetState()` may return `NULL`), and before the :c:member:`Py_mod_exec` function is executed. .. c:member:: inquiry m_clear A clear function to call during GC clearing of the module object, or - *NULL* if not needed. This function may be called before module state + ``NULL`` if not needed. This function may be called before module state is allocated (:c:func:`PyModule_GetState()` may return `NULL`), and before the :c:member:`Py_mod_exec` function is executed. .. c:member:: freefunc m_free - A function to call during deallocation of the module object, or *NULL* if + A function to call during deallocation of the module object, or ``NULL`` if not needed. This function may be called before module state is allocated (:c:func:`PyModule_GetState()` may return `NULL`), and before the :c:member:`Py_mod_exec` function is executed. @@ -278,7 +278,7 @@ instance must be initialized with the following function: Ensures a module definition is a properly initialized Python object that correctly reports its type and reference count. - Returns *def* cast to ``PyObject*``, or *NULL* if an error occurred. + Returns *def* cast to ``PyObject*``, or ``NULL`` if an error occurred. .. versionadded:: 3.5 @@ -311,7 +311,7 @@ The available slot types are: The function receives a :py:class:`~importlib.machinery.ModuleSpec` instance, as defined in :PEP:`451`, and the module definition. It should return a new module object, or set an error - and return *NULL*. + and return ``NULL``. This function should be kept minimal. In particular, it should not call arbitrary Python code, as trying to import the same module again may @@ -330,7 +330,7 @@ The available slot types are: :c:type:`PyModule_Type`. Any type can be used, as long as it supports setting and getting import-related attributes. However, only ``PyModule_Type`` instances may be returned if the - ``PyModuleDef`` has non-*NULL* ``m_traverse``, ``m_clear``, + ``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 @@ -394,7 +394,7 @@ objects dynamically. Note that both ``PyModule_FromDefAndSpec`` and .. c:function:: int PyModule_AddFunctions(PyObject *module, PyMethodDef *functions) - Add the functions from the *NULL* terminated *functions* array to *module*. + Add the functions from the ``NULL`` terminated *functions* array to *module*. Refer to the :c:type:`PyMethodDef` documentation for details on individual entries (due to the lack of a shared module namespace, module level "functions" implemented in C typically receive the module as their first @@ -445,7 +445,7 @@ state: Add a string constant to *module* as *name*. This convenience function can be used from the module's initialization function. The string *value* must be - *NULL*-terminated. Return ``-1`` on error, ``0`` on success. + ``NULL``-terminated. Return ``-1`` on error, ``0`` on success. .. c:function:: int PyModule_AddIntMacro(PyObject *module, macro) @@ -476,7 +476,7 @@ since multiple such modules can be created from a single definition. Returns the module object that was created from *def* for the current interpreter. This method requires that the module object has been attached to the interpreter state with :c:func:`PyState_AddModule` beforehand. In case the corresponding module object is not - found or has not been attached to the interpreter state yet, it returns *NULL*. + found or has not been attached to the interpreter state yet, it returns ``NULL``. .. c:function:: int PyState_AddModule(PyObject *module, PyModuleDef *def) @@ -485,10 +485,21 @@ since multiple such modules can be created from a single definition. Only effective on modules created using single-phase initialization. + Python calls ``PyState_AddModule`` automatically after importing a module, + so it is unnecessary (but harmless) to call it from module initialization + code. An explicit call is needed only if the module's own init code + subsequently calls ``PyState_FindModule``. + The function is mainly intended for implementing alternative import + mechanisms (either by calling it directly, or by referring to its + implementation for details of the required state updates). + + Return 0 on success or -1 on failure. + .. versionadded:: 3.3 .. c:function:: int PyState_RemoveModule(PyModuleDef *def) Removes the module object created from *def* from the interpreter state. + Return 0 on success or -1 on failure. .. versionadded:: 3.3 diff --git a/Doc/c-api/number.rst b/Doc/c-api/number.rst index 296b21c..82c4367 100644 --- a/Doc/c-api/number.rst +++ b/Doc/c-api/number.rst @@ -14,25 +14,25 @@ Number Protocol .. c:function:: PyObject* PyNumber_Add(PyObject *o1, PyObject *o2) - Returns the result of adding *o1* and *o2*, or *NULL* on failure. This is the + Returns the result of adding *o1* and *o2*, or ``NULL`` on failure. This is the equivalent of the Python expression ``o1 + o2``. .. c:function:: PyObject* PyNumber_Subtract(PyObject *o1, PyObject *o2) - Returns the result of subtracting *o2* from *o1*, or *NULL* on failure. This is + Returns the result of subtracting *o2* from *o1*, or ``NULL`` on failure. This is the equivalent of the Python expression ``o1 - o2``. .. c:function:: PyObject* PyNumber_Multiply(PyObject *o1, PyObject *o2) - Returns the result of multiplying *o1* and *o2*, or *NULL* on failure. This is + Returns the result of multiplying *o1* and *o2*, or ``NULL`` on failure. This is the equivalent of the Python expression ``o1 * o2``. .. c:function:: PyObject* PyNumber_MatrixMultiply(PyObject *o1, PyObject *o2) - Returns the result of matrix multiplication on *o1* and *o2*, or *NULL* on + Returns the result of matrix multiplication on *o1* and *o2*, or ``NULL`` on failure. This is the equivalent of the Python expression ``o1 @ o2``. .. versionadded:: 3.5 @@ -40,14 +40,14 @@ Number Protocol .. c:function:: PyObject* PyNumber_FloorDivide(PyObject *o1, PyObject *o2) - Return the floor of *o1* divided by *o2*, or *NULL* on failure. This is + Return the floor of *o1* divided by *o2*, or ``NULL`` on failure. This is equivalent to the "classic" division of integers. .. c:function:: PyObject* PyNumber_TrueDivide(PyObject *o1, PyObject *o2) Return a reasonable approximation for the mathematical value of *o1* divided by - *o2*, or *NULL* on failure. The return value is "approximate" because binary + *o2*, or ``NULL`` on failure. The return value is "approximate" because binary floating point numbers are approximate; it is not possible to represent all real numbers in base two. This function can return a floating point value when passed two integers. @@ -55,7 +55,7 @@ Number Protocol .. c:function:: PyObject* PyNumber_Remainder(PyObject *o1, PyObject *o2) - Returns the remainder of dividing *o1* by *o2*, or *NULL* on failure. This is + Returns the remainder of dividing *o1* by *o2*, or ``NULL`` on failure. This is the equivalent of the Python expression ``o1 % o2``. @@ -63,7 +63,7 @@ Number Protocol .. index:: builtin: divmod - See the built-in function :func:`divmod`. Returns *NULL* on failure. This is + See the built-in function :func:`divmod`. Returns ``NULL`` on failure. This is the equivalent of the Python expression ``divmod(o1, o2)``. @@ -71,21 +71,21 @@ Number Protocol .. index:: builtin: pow - See the built-in function :func:`pow`. Returns *NULL* on failure. This is the + See the built-in function :func:`pow`. Returns ``NULL`` on failure. This is the equivalent of the Python expression ``pow(o1, o2, o3)``, where *o3* is optional. - If *o3* is to be ignored, pass :c:data:`Py_None` in its place (passing *NULL* for + If *o3* is to be ignored, pass :c:data:`Py_None` in its place (passing ``NULL`` for *o3* would cause an illegal memory access). .. c:function:: PyObject* PyNumber_Negative(PyObject *o) - Returns the negation of *o* on success, or *NULL* on failure. This is the + Returns the negation of *o* on success, or ``NULL`` on failure. This is the equivalent of the Python expression ``-o``. .. c:function:: PyObject* PyNumber_Positive(PyObject *o) - Returns *o* on success, or *NULL* on failure. This is the equivalent of the + Returns *o* on success, or ``NULL`` on failure. This is the equivalent of the Python expression ``+o``. @@ -93,70 +93,70 @@ Number Protocol .. index:: builtin: abs - Returns the absolute value of *o*, or *NULL* on failure. This is the equivalent + Returns the absolute value of *o*, or ``NULL`` on failure. This is the equivalent of the Python expression ``abs(o)``. .. c:function:: PyObject* PyNumber_Invert(PyObject *o) - Returns the bitwise negation of *o* on success, or *NULL* on failure. This is + Returns the bitwise negation of *o* on success, or ``NULL`` on failure. This is the equivalent of the Python expression ``~o``. .. c:function:: PyObject* PyNumber_Lshift(PyObject *o1, PyObject *o2) - Returns the result of left shifting *o1* by *o2* on success, or *NULL* on + Returns the result of left shifting *o1* by *o2* on success, or ``NULL`` on failure. This is the equivalent of the Python expression ``o1 << o2``. .. c:function:: PyObject* PyNumber_Rshift(PyObject *o1, PyObject *o2) - Returns the result of right shifting *o1* by *o2* on success, or *NULL* on + Returns the result of right shifting *o1* by *o2* on success, or ``NULL`` on failure. This is the equivalent of the Python expression ``o1 >> o2``. .. c:function:: PyObject* PyNumber_And(PyObject *o1, PyObject *o2) - Returns the "bitwise and" of *o1* and *o2* on success and *NULL* on failure. + Returns the "bitwise and" of *o1* and *o2* on success and ``NULL`` on failure. This is the equivalent of the Python expression ``o1 & o2``. .. c:function:: PyObject* PyNumber_Xor(PyObject *o1, PyObject *o2) - Returns the "bitwise exclusive or" of *o1* by *o2* on success, or *NULL* on + Returns the "bitwise exclusive or" of *o1* by *o2* on success, or ``NULL`` on failure. This is the equivalent of the Python expression ``o1 ^ o2``. .. c:function:: PyObject* PyNumber_Or(PyObject *o1, PyObject *o2) - Returns the "bitwise or" of *o1* and *o2* on success, or *NULL* on failure. + Returns the "bitwise or" of *o1* and *o2* on success, or ``NULL`` on failure. This is the equivalent of the Python expression ``o1 | o2``. .. c:function:: PyObject* PyNumber_InPlaceAdd(PyObject *o1, PyObject *o2) - Returns the result of adding *o1* and *o2*, or *NULL* on failure. The operation + Returns the result of adding *o1* and *o2*, or ``NULL`` on failure. The operation is done *in-place* when *o1* supports it. This is the equivalent of the Python statement ``o1 += o2``. .. c:function:: PyObject* PyNumber_InPlaceSubtract(PyObject *o1, PyObject *o2) - Returns the result of subtracting *o2* from *o1*, or *NULL* on failure. The + Returns the result of subtracting *o2* from *o1*, or ``NULL`` on failure. The operation is done *in-place* when *o1* supports it. This is the equivalent of the Python statement ``o1 -= o2``. .. c:function:: PyObject* PyNumber_InPlaceMultiply(PyObject *o1, PyObject *o2) - Returns the result of multiplying *o1* and *o2*, or *NULL* on failure. The + Returns the result of multiplying *o1* and *o2*, or ``NULL`` on failure. The operation is done *in-place* when *o1* supports it. This is the equivalent of the Python statement ``o1 *= o2``. .. c:function:: PyObject* PyNumber_InPlaceMatrixMultiply(PyObject *o1, PyObject *o2) - Returns the result of matrix multiplication on *o1* and *o2*, or *NULL* on + Returns the result of matrix multiplication on *o1* and *o2*, or ``NULL`` on failure. The operation is done *in-place* when *o1* supports it. This is the equivalent of the Python statement ``o1 @= o2``. @@ -165,7 +165,7 @@ Number Protocol .. c:function:: PyObject* PyNumber_InPlaceFloorDivide(PyObject *o1, PyObject *o2) - Returns the mathematical floor of dividing *o1* by *o2*, or *NULL* on failure. + Returns the mathematical floor of dividing *o1* by *o2*, or ``NULL`` on failure. The operation is done *in-place* when *o1* supports it. This is the equivalent of the Python statement ``o1 //= o2``. @@ -173,7 +173,7 @@ Number Protocol .. c:function:: PyObject* PyNumber_InPlaceTrueDivide(PyObject *o1, PyObject *o2) Return a reasonable approximation for the mathematical value of *o1* divided by - *o2*, or *NULL* on failure. The return value is "approximate" because binary + *o2*, or ``NULL`` on failure. The return value is "approximate" because binary floating point numbers are approximate; it is not possible to represent all real numbers in base two. This function can return a floating point value when passed two integers. The operation is done *in-place* when *o1* supports it. @@ -181,7 +181,7 @@ Number Protocol .. c:function:: PyObject* PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2) - Returns the remainder of dividing *o1* by *o2*, or *NULL* on failure. The + Returns the remainder of dividing *o1* by *o2*, or ``NULL`` on failure. The operation is done *in-place* when *o1* supports it. This is the equivalent of the Python statement ``o1 %= o2``. @@ -190,44 +190,44 @@ Number Protocol .. index:: builtin: pow - See the built-in function :func:`pow`. Returns *NULL* on failure. The operation + See the built-in function :func:`pow`. Returns ``NULL`` on failure. The operation is done *in-place* when *o1* supports it. This is the equivalent of the Python statement ``o1 **= o2`` when o3 is :c:data:`Py_None`, or an in-place variant of ``pow(o1, o2, o3)`` otherwise. If *o3* is to be ignored, pass :c:data:`Py_None` - in its place (passing *NULL* for *o3* would cause an illegal memory access). + in its place (passing ``NULL`` for *o3* would cause an illegal memory access). .. c:function:: PyObject* PyNumber_InPlaceLshift(PyObject *o1, PyObject *o2) - Returns the result of left shifting *o1* by *o2* on success, or *NULL* on + Returns the result of left shifting *o1* by *o2* on success, or ``NULL`` on failure. The operation is done *in-place* when *o1* supports it. This is the equivalent of the Python statement ``o1 <<= o2``. .. c:function:: PyObject* PyNumber_InPlaceRshift(PyObject *o1, PyObject *o2) - Returns the result of right shifting *o1* by *o2* on success, or *NULL* on + Returns the result of right shifting *o1* by *o2* on success, or ``NULL`` on failure. The operation is done *in-place* when *o1* supports it. This is the equivalent of the Python statement ``o1 >>= o2``. .. c:function:: PyObject* PyNumber_InPlaceAnd(PyObject *o1, PyObject *o2) - Returns the "bitwise and" of *o1* and *o2* on success and *NULL* on failure. The + Returns the "bitwise and" of *o1* and *o2* on success and ``NULL`` on failure. The operation is done *in-place* when *o1* supports it. This is the equivalent of the Python statement ``o1 &= o2``. .. c:function:: PyObject* PyNumber_InPlaceXor(PyObject *o1, PyObject *o2) - Returns the "bitwise exclusive or" of *o1* by *o2* on success, or *NULL* on + Returns the "bitwise exclusive or" of *o1* by *o2* on success, or ``NULL`` on failure. The operation is done *in-place* when *o1* supports it. This is the equivalent of the Python statement ``o1 ^= o2``. .. c:function:: PyObject* PyNumber_InPlaceOr(PyObject *o1, PyObject *o2) - Returns the "bitwise or" of *o1* and *o2* on success, or *NULL* on failure. The + Returns the "bitwise or" of *o1* and *o2* on success, or ``NULL`` on failure. The operation is done *in-place* when *o1* supports it. This is the equivalent of the Python statement ``o1 |= o2``. @@ -236,7 +236,7 @@ Number Protocol .. index:: builtin: int - Returns the *o* converted to an integer object on success, or *NULL* on + Returns the *o* converted to an integer object on success, or ``NULL`` on failure. This is the equivalent of the Python expression ``int(o)``. @@ -244,13 +244,13 @@ Number Protocol .. index:: builtin: float - Returns the *o* converted to a float object on success, or *NULL* on failure. + Returns the *o* converted to a float object on success, or ``NULL`` on failure. This is the equivalent of the Python expression ``float(o)``. .. c:function:: PyObject* PyNumber_Index(PyObject *o) - Returns the *o* converted to a Python int on success or *NULL* with a + Returns the *o* converted to a Python int on success or ``NULL`` with a :exc:`TypeError` exception raised on failure. @@ -271,9 +271,9 @@ Number Protocol If *o* can be converted to a Python int but the attempt to convert to a Py_ssize_t value would raise an :exc:`OverflowError`, then the *exc* argument is the type of exception that will be raised (usually - :exc:`IndexError` or :exc:`OverflowError`). If *exc* is *NULL*, then the - exception is cleared and the value is clipped to *PY_SSIZE_T_MIN* for a negative - integer or *PY_SSIZE_T_MAX* for a positive integer. + :exc:`IndexError` or :exc:`OverflowError`). If *exc* is ``NULL``, then the + exception is cleared and the value is clipped to ``PY_SSIZE_T_MIN`` for a negative + integer or ``PY_SSIZE_T_MAX`` for a positive integer. .. c:function:: int PyIndex_Check(PyObject *o) diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index c09d97a..d81dc93 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -53,14 +53,14 @@ Object Protocol .. c:function:: PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name) Retrieve an attribute named *attr_name* from object *o*. Returns the attribute - value on success, or *NULL* on failure. This is the equivalent of the Python + value on success, or ``NULL`` on failure. This is the equivalent of the Python expression ``o.attr_name``. .. c:function:: PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name) Retrieve an attribute named *attr_name* from object *o*. Returns the attribute - value on success, or *NULL* on failure. This is the equivalent of the Python + value on success, or ``NULL`` on failure. This is the equivalent of the Python expression ``o.attr_name``. @@ -81,7 +81,7 @@ Object Protocol return ``0`` on success. This is the equivalent of the Python statement ``o.attr_name = v``. - If *v* is *NULL*, the attribute is deleted, however this feature is + If *v* is ``NULL``, the attribute is deleted, however this feature is deprecated in favour of using :c:func:`PyObject_DelAttr`. @@ -92,7 +92,7 @@ Object Protocol return ``0`` on success. This is the equivalent of the Python statement ``o.attr_name = v``. - If *v* is *NULL*, the attribute is deleted, however this feature is + If *v* is ``NULL``, the attribute is deleted, however this feature is deprecated in favour of using :c:func:`PyObject_DelAttrString`. @@ -143,7 +143,7 @@ Object Protocol :const:`Py_NE`, :const:`Py_GT`, or :const:`Py_GE`, corresponding to ``<``, ``<=``, ``==``, ``!=``, ``>``, or ``>=`` respectively. This is the equivalent of the Python expression ``o1 op o2``, where ``op`` is the operator corresponding - to *opid*. Returns the value of the comparison on success, or *NULL* on failure. + to *opid*. Returns the value of the comparison on success, or ``NULL`` on failure. .. c:function:: int PyObject_RichCompareBool(PyObject *o1, PyObject *o2, int opid) @@ -165,7 +165,7 @@ Object Protocol .. index:: builtin: repr Compute a string representation of object *o*. Returns the string - representation on success, *NULL* on failure. This is the equivalent of the + representation on success, ``NULL`` on failure. This is the equivalent of the Python expression ``repr(o)``. Called by the :func:`repr` built-in function. .. versionchanged:: 3.4 @@ -188,7 +188,7 @@ Object Protocol .. c:function:: PyObject* PyObject_Str(PyObject *o) Compute a string representation of object *o*. Returns the string - representation on success, *NULL* on failure. This is the equivalent of the + representation on success, ``NULL`` on failure. This is the equivalent of the Python expression ``str(o)``. Called by the :func:`str` built-in function and, therefore, by the :func:`print` function. @@ -200,7 +200,7 @@ Object Protocol .. index:: builtin: bytes - Compute a bytes representation of object *o*. *NULL* is returned on + Compute a bytes representation of object *o*. ``NULL`` is returned on failure and a bytes object on success. This is equivalent to the Python expression ``bytes(o)``, when *o* is not an integer. Unlike ``bytes(o)``, a TypeError is raised when *o* is an integer instead of a zero-initialized @@ -258,11 +258,11 @@ Object Protocol Call a callable Python object *callable*, with arguments given by the tuple *args*, and named arguments given by the dictionary *kwargs*. - *args* must not be *NULL*, use an empty tuple if no arguments are needed. - If no named arguments are needed, *kwargs* can be *NULL*. + *args* must not be ``NULL``, use an empty tuple if no arguments are needed. + If no named arguments are needed, *kwargs* can be ``NULL``. Return the result of the call on success, or raise an exception and return - *NULL* on failure. + ``NULL`` on failure. This is the equivalent of the Python expression: ``callable(*args, **kwargs)``. @@ -271,10 +271,10 @@ Object Protocol .. c:function:: PyObject* PyObject_CallObject(PyObject *callable, PyObject *args) Call a callable Python object *callable*, with arguments given by the - tuple *args*. If no arguments are needed, then *args* can be *NULL*. + tuple *args*. If no arguments are needed, then *args* can be ``NULL``. Return the result of the call on success, or raise an exception and return - *NULL* on failure. + ``NULL`` on failure. This is the equivalent of the Python expression: ``callable(*args)``. @@ -283,10 +283,10 @@ Object Protocol Call a callable Python object *callable*, with a variable number of C arguments. The C arguments are described using a :c:func:`Py_BuildValue` style format - string. The format can be *NULL*, indicating that no arguments are provided. + string. The format can be ``NULL``, indicating that no arguments are provided. Return the result of the call on success, or raise an exception and return - *NULL* on failure. + ``NULL`` on failure. This is the equivalent of the Python expression: ``callable(*args)``. @@ -303,10 +303,10 @@ Object Protocol arguments. The C arguments are described by a :c:func:`Py_BuildValue` format string that should produce a tuple. - The format can be *NULL*, indicating that no arguments are provided. + The format can be ``NULL``, indicating that no arguments are provided. Return the result of the call on success, or raise an exception and return - *NULL* on failure. + ``NULL`` on failure. This is the equivalent of the Python expression: ``obj.name(arg1, arg2, ...)``. @@ -322,10 +322,10 @@ Object Protocol Call a callable Python object *callable*, with a variable number of :c:type:`PyObject\*` arguments. The arguments are provided as a variable number - of parameters followed by *NULL*. + of parameters followed by ``NULL``. Return the result of the call on success, or raise an exception and return - *NULL* on failure. + ``NULL`` on failure. This is the equivalent of the Python expression: ``callable(arg1, arg2, ...)``. @@ -336,10 +336,10 @@ Object Protocol 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 - of parameters followed by *NULL*. + of parameters followed by ``NULL``. Return the result of the call on success, or raise an exception and return - *NULL* on failure. + ``NULL`` on failure. .. c:function:: Py_hash_t PyObject_Hash(PyObject *o) @@ -380,8 +380,8 @@ Object Protocol .. index:: builtin: type - When *o* is non-*NULL*, returns a type object corresponding to the object type - of object *o*. On failure, raises :exc:`SystemError` and returns *NULL*. This + When *o* is non-``NULL``, returns a type object corresponding to the object type + of object *o*. On failure, raises :exc:`SystemError` and returns ``NULL``. This 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 @@ -392,7 +392,7 @@ Object Protocol .. c:function:: int PyObject_TypeCheck(PyObject *o, PyTypeObject *type) Return true if the object *o* is of type *type* or a subtype of *type*. Both - parameters must be non-*NULL*. + parameters must be non-``NULL``. .. c:function:: Py_ssize_t PyObject_Size(PyObject *o) @@ -417,7 +417,7 @@ Object Protocol .. c:function:: PyObject* PyObject_GetItem(PyObject *o, PyObject *key) - Return element of *o* corresponding to the object *key* or *NULL* on failure. + Return element of *o* corresponding to the object *key* or ``NULL`` on failure. This is the equivalent of the Python expression ``o[key]``. @@ -437,15 +437,15 @@ Object Protocol .. c:function:: PyObject* PyObject_Dir(PyObject *o) This is equivalent to the Python expression ``dir(o)``, returning a (possibly - empty) list of strings appropriate for the object argument, or *NULL* if there - was an error. If the argument is *NULL*, this is like the Python ``dir()``, + empty) list of strings appropriate for the object argument, or ``NULL`` if there + was an error. If the argument is ``NULL``, this is like the Python ``dir()``, returning the names of the current locals; in this case, if no execution frame - is active then *NULL* is returned but :c:func:`PyErr_Occurred` will return false. + is active then ``NULL`` is returned but :c:func:`PyErr_Occurred` will return false. .. c:function:: PyObject* PyObject_GetIter(PyObject *o) This is equivalent to the Python expression ``iter(o)``. It returns a new iterator for the object argument, or the object itself if the object is already - an iterator. Raises :exc:`TypeError` and returns *NULL* if the object cannot be + an iterator. Raises :exc:`TypeError` and returns ``NULL`` if the object cannot be iterated. diff --git a/Doc/c-api/refcounting.rst b/Doc/c-api/refcounting.rst index 4f512ec..1479db4 100644 --- a/Doc/c-api/refcounting.rst +++ b/Doc/c-api/refcounting.rst @@ -13,22 +13,22 @@ objects. .. c:function:: void Py_INCREF(PyObject *o) - Increment the reference count for object *o*. The object must not be *NULL*; if - you aren't sure that it isn't *NULL*, use :c:func:`Py_XINCREF`. + Increment the reference count for object *o*. The object must not be ``NULL``; if + you aren't sure that it isn't ``NULL``, use :c:func:`Py_XINCREF`. .. c:function:: void Py_XINCREF(PyObject *o) - Increment the reference count for object *o*. The object may be *NULL*, in + Increment the reference count for object *o*. The object may be ``NULL``, in which case the macro has no effect. .. c:function:: void Py_DECREF(PyObject *o) - Decrement the reference count for object *o*. The object must not be *NULL*; if - you aren't sure that it isn't *NULL*, use :c:func:`Py_XDECREF`. If the reference + Decrement the reference count for object *o*. The object must not be ``NULL``; if + you aren't sure that it isn't ``NULL``, use :c:func:`Py_XDECREF`. If the reference count reaches zero, the object's type's deallocation function (which must not be - *NULL*) is invoked. + ``NULL``) is invoked. .. warning:: @@ -44,18 +44,18 @@ objects. .. c:function:: void Py_XDECREF(PyObject *o) - Decrement the reference count for object *o*. The object may be *NULL*, in + Decrement the reference count for object *o*. The object may be ``NULL``, in which case the macro has no effect; otherwise the effect is the same as for :c:func:`Py_DECREF`, and the same warning applies. .. c:function:: void Py_CLEAR(PyObject *o) - Decrement the reference count for object *o*. The object may be *NULL*, in + Decrement the reference count for object *o*. The object may be ``NULL``, in which case the macro has no effect; otherwise the effect is the same as for - :c:func:`Py_DECREF`, except that the argument is also set to *NULL*. The warning + :c:func:`Py_DECREF`, except that the argument is also set to ``NULL``. The warning for :c:func:`Py_DECREF` does not apply with respect to the object passed because - the macro carefully uses a temporary variable and sets the argument to *NULL* + the macro carefully uses a temporary variable and sets the argument to ``NULL`` before decrementing its reference count. It is a good idea to use this macro whenever decrementing the value of a diff --git a/Doc/c-api/reflection.rst b/Doc/c-api/reflection.rst index 9689365..cb9a8f8 100644 --- a/Doc/c-api/reflection.rst +++ b/Doc/c-api/reflection.rst @@ -14,18 +14,18 @@ Reflection .. c:function:: PyObject* PyEval_GetLocals() Return a dictionary of the local variables in the current execution frame, - or *NULL* if no frame is currently executing. + or ``NULL`` if no frame is currently executing. .. c:function:: PyObject* PyEval_GetGlobals() Return a dictionary of the global variables in the current execution frame, - or *NULL* if no frame is currently executing. + or ``NULL`` if no frame is currently executing. .. c:function:: PyFrameObject* PyEval_GetFrame() - Return the current thread state's frame, which is *NULL* if no frame is + Return the current thread state's frame, which is ``NULL`` if no frame is currently executing. diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst index d653319..7db618a 100644 --- a/Doc/c-api/sequence.rst +++ b/Doc/c-api/sequence.rst @@ -26,39 +26,39 @@ Sequence Protocol .. c:function:: PyObject* PySequence_Concat(PyObject *o1, PyObject *o2) - Return the concatenation of *o1* and *o2* on success, and *NULL* on failure. + Return the concatenation of *o1* and *o2* on success, and ``NULL`` on failure. This is the equivalent of the Python expression ``o1 + o2``. .. c:function:: PyObject* PySequence_Repeat(PyObject *o, Py_ssize_t count) - Return the result of repeating sequence object *o* *count* times, or *NULL* on + Return the result of repeating sequence object *o* *count* times, or ``NULL`` on failure. This is the equivalent of the Python expression ``o * count``. .. c:function:: PyObject* PySequence_InPlaceConcat(PyObject *o1, PyObject *o2) - Return the concatenation of *o1* and *o2* on success, and *NULL* on failure. + Return the concatenation of *o1* and *o2* on success, and ``NULL`` on failure. The operation is done *in-place* when *o1* supports it. This is the equivalent of the Python expression ``o1 += o2``. .. c:function:: PyObject* PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count) - Return the result of repeating sequence object *o* *count* times, or *NULL* on + Return the result of repeating sequence object *o* *count* times, or ``NULL`` on failure. The operation is done *in-place* when *o* supports it. This is the equivalent of the Python expression ``o *= count``. .. c:function:: PyObject* PySequence_GetItem(PyObject *o, Py_ssize_t i) - Return the *i*\ th element of *o*, or *NULL* on failure. This is the equivalent of + Return the *i*\ th element of *o*, or ``NULL`` on failure. This is the equivalent of the Python expression ``o[i]``. .. c:function:: PyObject* PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2) - Return the slice of sequence object *o* between *i1* and *i2*, or *NULL* on + Return the slice of sequence object *o* between *i1* and *i2*, or ``NULL`` on failure. This is the equivalent of the Python expression ``o[i1:i2]``. @@ -69,7 +69,7 @@ Sequence Protocol is the equivalent of the Python statement ``o[i] = v``. This function *does not* steal a reference to *v*. - If *v* is *NULL*, the element is deleted, however this feature is + If *v* is ``NULL``, the element is deleted, however this feature is deprecated in favour of using :c:func:`PySequence_DelItem`. @@ -114,7 +114,7 @@ Sequence Protocol .. c:function:: PyObject* PySequence_List(PyObject *o) Return a list object with the same contents as the sequence or iterable *o*, - or *NULL* on failure. The returned list is guaranteed to be new. This is + or ``NULL`` on failure. The returned list is guaranteed to be new. This is equivalent to the Python expression ``list(o)``. @@ -123,7 +123,7 @@ Sequence Protocol .. index:: builtin: tuple Return a tuple object with the same contents as the sequence or iterable *o*, - or *NULL* on failure. If *o* is a tuple, a new reference will be returned, + or ``NULL`` on failure. If *o* is a tuple, a new reference will be returned, otherwise a tuple will be constructed with the appropriate contents. This is equivalent to the Python expression ``tuple(o)``. @@ -133,7 +133,7 @@ Sequence Protocol Return the sequence or iterable *o* as an object usable by the other ``PySequence_Fast*`` family of functions. If the object is not a sequence or iterable, raises :exc:`TypeError` with *m* as the message text. Returns - *NULL* on failure. + ``NULL`` on failure. The ``PySequence_Fast*`` functions are thus named because they assume *o* is a :c:type:`PyTupleObject` or a :c:type:`PyListObject` and access @@ -146,7 +146,7 @@ Sequence Protocol .. c:function:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o) Returns the length of *o*, assuming that *o* was returned by - :c:func:`PySequence_Fast` and that *o* is not *NULL*. The size can also be + :c:func:`PySequence_Fast` and that *o* is not ``NULL``. The size can also be gotten by calling :c:func:`PySequence_Size` on *o*, but :c:func:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a list or tuple. @@ -155,13 +155,13 @@ Sequence Protocol .. c:function:: PyObject* PySequence_Fast_GET_ITEM(PyObject *o, Py_ssize_t i) Return the *i*\ th element of *o*, assuming that *o* was returned by - :c:func:`PySequence_Fast`, *o* is not *NULL*, and that *i* is within bounds. + :c:func:`PySequence_Fast`, *o* is not ``NULL``, and that *i* is within bounds. .. c:function:: PyObject** PySequence_Fast_ITEMS(PyObject *o) Return the underlying array of PyObject pointers. Assumes that *o* was returned - by :c:func:`PySequence_Fast` and *o* is not *NULL*. + by :c:func:`PySequence_Fast` and *o* is not ``NULL``. Note, if a list gets resized, the reallocation may relocate the items array. So, only use the underlying array pointer in contexts where the sequence @@ -170,7 +170,7 @@ Sequence Protocol .. c:function:: PyObject* PySequence_ITEM(PyObject *o, Py_ssize_t i) - Return the *i*\ th element of *o* or *NULL* on failure. Faster form of + Return the *i*\ th element of *o* or ``NULL`` on failure. Faster form of :c:func:`PySequence_GetItem` but without checking that :c:func:`PySequence_Check` on *o* is true and without adjustment for negative indices. diff --git a/Doc/c-api/set.rst b/Doc/c-api/set.rst index 64b6dde..34ee077 100644 --- a/Doc/c-api/set.rst +++ b/Doc/c-api/set.rst @@ -80,8 +80,8 @@ the constructor functions work with any iterable Python object. .. c:function:: PyObject* PySet_New(PyObject *iterable) Return a new :class:`set` containing objects returned by the *iterable*. The - *iterable* may be *NULL* to create a new empty set. Return the new set on - success or *NULL* on failure. Raise :exc:`TypeError` if *iterable* is not + *iterable* may be ``NULL`` to create a new empty set. Return the new set on + success or ``NULL`` on failure. Raise :exc:`TypeError` if *iterable* is not actually iterable. The constructor is also useful for copying a set (``c=set(s)``). @@ -89,8 +89,8 @@ the constructor functions work with any iterable Python object. .. c:function:: PyObject* PyFrozenSet_New(PyObject *iterable) Return a new :class:`frozenset` containing objects returned by the *iterable*. - The *iterable* may be *NULL* to create a new empty frozenset. Return the new - set on success or *NULL* on failure. Raise :exc:`TypeError` if *iterable* is + The *iterable* may be ``NULL`` to create a new empty frozenset. Return the new + set on success or ``NULL`` on failure. Raise :exc:`TypeError` if *iterable* is not actually iterable. @@ -149,7 +149,7 @@ subtypes but not for instances of :class:`frozenset` or its subtypes. .. c:function:: PyObject* PySet_Pop(PyObject *set) Return a new reference to an arbitrary object in the *set*, and removes the - object from the *set*. Return *NULL* on failure. Raise :exc:`KeyError` if the + object from the *set*. Return ``NULL`` on failure. Raise :exc:`KeyError` if the set is empty. Raise a :exc:`SystemError` if *set* is not an instance of :class:`set` or its subtype. diff --git a/Doc/c-api/slice.rst b/Doc/c-api/slice.rst index 8ad9a29..c72ab04 100644 --- a/Doc/c-api/slice.rst +++ b/Doc/c-api/slice.rst @@ -14,15 +14,15 @@ Slice Objects .. c:function:: int PySlice_Check(PyObject *ob) - Return true if *ob* is a slice object; *ob* must not be *NULL*. + Return true if *ob* is a slice object; *ob* must not be ``NULL``. .. c:function:: PyObject* PySlice_New(PyObject *start, PyObject *stop, PyObject *step) Return a new slice object with the given values. The *start*, *stop*, and *step* parameters are used as the values of the slice object attributes of - the same names. Any of the values may be *NULL*, in which case the - ``None`` will be used for the corresponding attribute. Return *NULL* if + the same names. Any of the values may be ``NULL``, in which case the + ``None`` will be used for the corresponding attribute. Return ``NULL`` if the new object could not be allocated. diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 274beee..0aa1ef0 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -106,8 +106,8 @@ the definition of all other Python objects. Type of the functions used to implement most Python callables in C. 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 + 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 reference. @@ -179,7 +179,7 @@ also keyword arguments. So there are a total of 6 calling conventions: Methods with these flags must be of type :c:type:`PyCFunctionWithKeywords`. The function expects three parameters: *self*, *args*, *kwargs* where - *kwargs* is a dictionary of all the keyword arguments or possibly *NULL* + *kwargs* is a dictionary of all the keyword arguments or possibly ``NULL`` if there are no keyword arguments. The parameters are typically processed using :c:func:`PyArg_ParseTupleAndKeywords`. @@ -204,7 +204,7 @@ also keyword arguments. So there are a total of 6 calling conventions: Keyword arguments are passed the same way as in the vectorcall protocol: 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 + or possibly ``NULL`` if there are no keywords. The values of the keyword arguments are stored in the *args* array, after the positional arguments. This is not part of the :ref:`limited API `. @@ -218,7 +218,7 @@ also keyword arguments. So there are a total of 6 calling conventions: they are listed with the :const:`METH_NOARGS` flag. They need to be of type :c:type:`PyCFunction`. The first parameter is typically named *self* and will hold a reference to the module or object instance. In all cases the second - parameter will be *NULL*. + parameter will be ``NULL``. .. data:: METH_O @@ -249,7 +249,7 @@ method. .. index:: builtin: staticmethod - The method will be passed *NULL* as the first parameter rather than an + The method will be passed ``NULL`` as the first parameter rather than an instance of the type. This is used to create *static methods*, similar to what is created when using the :func:`staticmethod` built-in function. @@ -323,7 +323,7 @@ definition with the same method name. =============== ================== :c:macro:`T_OBJECT` and :c:macro:`T_OBJECT_EX` differ in that - :c:macro:`T_OBJECT` returns ``None`` if the member is *NULL* and + :c:macro:`T_OBJECT` returns ``None`` if the member is ``NULL`` and :c:macro:`T_OBJECT_EX` raises an :exc:`AttributeError`. Try to use :c:macro:`T_OBJECT_EX` over :c:macro:`T_OBJECT` because :c:macro:`T_OBJECT_EX` handles use of the :keyword:`del` statement on that attribute more correctly @@ -333,7 +333,7 @@ definition with the same method name. read-only access. Using :c:macro:`T_STRING` for :attr:`type` implies :c:macro:`READONLY`. :c:macro:`T_STRING` data is interpreted as UTF-8. Only :c:macro:`T_OBJECT` and :c:macro:`T_OBJECT_EX` - members can be deleted. (They are set to *NULL*). + members can be deleted. (They are set to ``NULL``). .. c:type:: PyGetSetDef @@ -364,7 +364,7 @@ definition with the same method name. typedef PyObject *(*getter)(PyObject *, void *); - It should return a new reference on success or *NULL* with a set exception + 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 @@ -372,5 +372,5 @@ definition with the same method name. typedef int (*setter)(PyObject *, PyObject *, void *); - In case the attribute should be deleted the second parameter is *NULL*. + In case the attribute should be deleted the second parameter is ``NULL``. Should return ``0`` on success or ``-1`` with a set exception on failure. diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst index 994509a..e1715bc 100644 --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -22,7 +22,7 @@ Operating System Utilities Return true (nonzero) if the standard I/O file *fp* with name *filename* is deemed interactive. This is the case for files for which ``isatty(fileno(fp))`` is true. If the global flag :c:data:`Py_InteractiveFlag` is true, this function - also returns true if the *filename* pointer is *NULL* or if the name is equal to + also returns true if the *filename* pointer is ``NULL`` or if the name is equal to one of the strings ``''`` or ``'???'``. @@ -194,12 +194,12 @@ accessible to C code. They all work with the current interpreter thread's .. c:function:: PyObject *PySys_GetObject(const char *name) - Return the object *name* from the :mod:`sys` module or *NULL* if it does + Return the object *name* from the :mod:`sys` module or ``NULL`` if it does not exist, without setting an exception. .. c:function:: int PySys_SetObject(const char *name, PyObject *v) - Set *name* in the :mod:`sys` module to *v* unless *v* is *NULL*, in which + Set *name* in the :mod:`sys` module to *v* unless *v* is ``NULL``, in which case *name* is deleted from the sys module. Returns ``0`` on success, ``-1`` on error. @@ -276,7 +276,7 @@ accessible to C code. They all work with the current interpreter thread's .. c:function:: PyObject *PySys_GetXOptions() Return the current dictionary of :option:`-X` options, similarly to - :data:`sys._xoptions`. On error, *NULL* is returned and an exception is + :data:`sys._xoptions`. On error, ``NULL`` is returned and an exception is set. .. versionadded:: 3.2 diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst index 20bf9f0..b7d4b7b 100644 --- a/Doc/c-api/tuple.rst +++ b/Doc/c-api/tuple.rst @@ -33,12 +33,12 @@ Tuple Objects .. c:function:: PyObject* PyTuple_New(Py_ssize_t len) - Return a new tuple object of size *len*, or *NULL* on failure. + Return a new tuple object of size *len*, or ``NULL`` on failure. .. c:function:: PyObject* PyTuple_Pack(Py_ssize_t n, ...) - Return a new tuple object of size *n*, or *NULL* on failure. The tuple values + Return a new tuple object of size *n*, or ``NULL`` on failure. The tuple values are initialized to the subsequent *n* C arguments pointing to Python objects. ``PyTuple_Pack(2, a, b)`` is equivalent to ``Py_BuildValue("(OO)", a, b)``. @@ -50,14 +50,14 @@ Tuple Objects .. c:function:: Py_ssize_t PyTuple_GET_SIZE(PyObject *p) - Return the size of the tuple *p*, which must be non-*NULL* and point to a tuple; + Return the size of the tuple *p*, which must be non-``NULL`` and point to a tuple; no error checking is performed. .. c:function:: PyObject* PyTuple_GetItem(PyObject *p, Py_ssize_t pos) Return the object at position *pos* in the tuple pointed to by *p*. If *pos* is - out of bounds, return *NULL* and sets an :exc:`IndexError` exception. + out of bounds, return ``NULL`` and set an :exc:`IndexError` exception. .. c:function:: PyObject* PyTuple_GET_ITEM(PyObject *p, Py_ssize_t pos) @@ -67,18 +67,21 @@ Tuple Objects .. c:function:: PyObject* PyTuple_GetSlice(PyObject *p, Py_ssize_t low, Py_ssize_t high) - Take a slice of the tuple pointed to by *p* from *low* to *high* and return it - as a new tuple. + Return the slice of the tuple pointed to by *p* between *low* and *high*, + or ``NULL`` on failure. This is the equivalent of the Python expression + ``p[low:high]``. Indexing from the end of the list is not supported. .. c:function:: int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o) Insert a reference to object *o* at position *pos* of the tuple pointed to by - *p*. Return ``0`` on success. + *p*. Return ``0`` on success. If *pos* is out of bounds, return ``-1`` + and set an :exc:`IndexError` exception. .. note:: - This function "steals" a reference to *o*. + This function "steals" a reference to *o* and discards a reference to + an item already in the tuple at the affected position. .. c:function:: void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o) @@ -88,7 +91,10 @@ Tuple Objects .. note:: - This function "steals" a reference to *o*. + This macro "steals" a reference to *o*, and, unlike + :c:func:`PyTuple_SetItem`, does *not* discard a reference to any item that + is being replaced; any reference in the tuple at position *pos* will be + leaked. .. c:function:: int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize) @@ -101,7 +107,7 @@ Tuple Objects only more efficiently. Returns ``0`` on success. Client code should never assume that the resulting value of ``*p`` will be the same as before calling this function. If the object referenced by ``*p`` is replaced, the original - ``*p`` is destroyed. On failure, returns ``-1`` and sets ``*p`` to *NULL*, and + ``*p`` is destroyed. On failure, returns ``-1`` and sets ``*p`` to ``NULL``, and raises :exc:`MemoryError` or :exc:`SystemError`. @@ -141,20 +147,20 @@ type. Contains the meta information of a struct sequence type to create. - +-------------------+------------------------------+------------------------------------+ - | Field | C Type | Meaning | - +===================+==============================+====================================+ - | ``name`` | ``const char *`` | name of the struct sequence type | - +-------------------+------------------------------+------------------------------------+ - | ``doc`` | ``const char *`` | pointer to docstring for the type | - | | | or NULL to omit | - +-------------------+------------------------------+------------------------------------+ - | ``fields`` | ``PyStructSequence_Field *`` | pointer to *NULL*-terminated array | - | | | with field names of the new type | - +-------------------+------------------------------+------------------------------------+ - | ``n_in_sequence`` | ``int`` | number of fields visible to the | - | | | Python side (if used as tuple) | - +-------------------+------------------------------+------------------------------------+ + +-------------------+------------------------------+--------------------------------------+ + | Field | C Type | Meaning | + +===================+==============================+======================================+ + | ``name`` | ``const char *`` | name of the struct sequence type | + +-------------------+------------------------------+--------------------------------------+ + | ``doc`` | ``const char *`` | pointer to docstring for the type | + | | | or ``NULL`` to omit | + +-------------------+------------------------------+--------------------------------------+ + | ``fields`` | ``PyStructSequence_Field *`` | pointer to ``NULL``-terminated array | + | | | with field names of the new type | + +-------------------+------------------------------+--------------------------------------+ + | ``n_in_sequence`` | ``int`` | number of fields visible to the | + | | | Python side (if used as tuple) | + +-------------------+------------------------------+--------------------------------------+ .. c:type:: PyStructSequence_Field @@ -164,16 +170,16 @@ type. :attr:`fields` array of the :c:type:`PyStructSequence_Desc` determines which field of the struct sequence is described. - +-----------+------------------+--------------------------------------+ - | Field | C Type | Meaning | - +===========+==================+======================================+ - | ``name`` | ``const char *`` | name for the field or *NULL* to end | - | | | the list of named fields, set to | - | | | PyStructSequence_UnnamedField to | - | | | leave unnamed | - +-----------+------------------+--------------------------------------+ - | ``doc`` | ``const char *`` | field docstring or *NULL* to omit | - +-----------+------------------+--------------------------------------+ + +-----------+------------------+-----------------------------------------+ + | Field | C Type | Meaning | + +===========+==================+=========================================+ + | ``name`` | ``const char *`` | name for the field or ``NULL`` to end | + | | | the list of named fields, set to | + | | | :c:data:`PyStructSequence_UnnamedField` | + | | | to leave unnamed | + +-----------+------------------+-----------------------------------------+ + | ``doc`` | ``const char *`` | field docstring or ``NULL`` to omit | + +-----------+------------------+-----------------------------------------+ .. c:var:: char* PyStructSequence_UnnamedField diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index 4dfd53f..5a3d749 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -81,7 +81,7 @@ Type Objects Generic handler for the :c:member:`~PyTypeObject.tp_alloc` slot of a type object. Use Python's default memory allocation mechanism to allocate a new instance and - initialize all its contents to *NULL*. + initialize all its contents to ``NULL``. .. c:function:: PyObject* PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -110,7 +110,7 @@ Type Objects .. c:function:: void* PyType_GetSlot(PyTypeObject *type, int slot) Return the function pointer stored in the given slot. If the - result is *NULL*, this indicates that either the slot is *NULL*, + result is ``NULL``, this indicates that either the slot is ``NULL``, or that the function was called with invalid parameters. Callers will typically cast the result pointer into the appropriate function type. diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 532508e..71b45a6 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -43,8 +43,8 @@ type objects) *must* have the :attr:`ob_size` field. PyObject* PyObject._ob_prev These fields are only present when the macro ``Py_TRACE_REFS`` is defined. - Their initialization to *NULL* is taken care of by the ``PyObject_HEAD_INIT`` - macro. For statically allocated objects, these fields always remain *NULL*. + Their initialization to ``NULL`` is taken care of by the ``PyObject_HEAD_INIT`` + macro. For statically allocated objects, these fields always remain ``NULL``. For dynamically allocated objects, these two fields are used to link the object into a doubly-linked list of *all* live objects on the heap. This could be used for various debugging purposes; currently the only use is to print the objects @@ -71,7 +71,7 @@ type objects) *must* have the :attr:`ob_size` field. argument to the ``PyObject_HEAD_INIT`` macro, and its value should normally be ``&PyType_Type``. However, for dynamically loadable extension modules that must be usable on Windows (at least), the compiler complains that this is not a valid - initializer. Therefore, the convention is to pass *NULL* to the + initializer. Therefore, the convention is to pass ``NULL`` to the ``PyObject_HEAD_INIT`` macro and to initialize this field explicitly at the start of the module's initialization function, before doing anything else. This is typically done like this:: @@ -79,7 +79,7 @@ type objects) *must* have the :attr:`ob_size` field. Foo_Type.ob_type = &PyType_Type; This should be done before any instances of the type are created. - :c:func:`PyType_Ready` checks if :attr:`ob_type` is *NULL*, and if so, + :c:func:`PyType_Ready` checks if :attr:`ob_type` is ``NULL``, and if so, initializes it to the :attr:`ob_type` field of the base class. :c:func:`PyType_Ready` will not change this field if it is non-zero. @@ -205,7 +205,7 @@ type objects) *must* have the :attr:`ob_size` field. This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_getattro`: a subtype inherits both :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` from its base type when - the subtype's :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` are both *NULL*. + the subtype's :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` are both ``NULL``. .. c:member:: setattrfunc PyTypeObject.tp_setattr @@ -218,10 +218,10 @@ type objects) *must* have the :attr:`ob_size` field. PyObject * tp_setattr(PyObject *o, char *attr_name, PyObject *v); - The *v* argument is set to *NULL* to delete the attribute. + The *v* argument is set to ``NULL`` to delete the attribute. This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_setattro`: a subtype inherits both :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` from its base type when - the subtype's :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` are both *NULL*. + the subtype's :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` are both ``NULL``. .. c:member:: PyAsyncMethods* tp_as_async @@ -310,13 +310,13 @@ type objects) *must* have the :attr:`ob_size` field. This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_richcompare`: a subtype inherits both of :c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash`, when the subtype's - :c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash` are both *NULL*. + :c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash` are both ``NULL``. .. c:member:: ternaryfunc PyTypeObject.tp_call An optional pointer to a function that implements calling the object. This - should be *NULL* if the object is not callable. The signature is the same as + should be ``NULL`` if the object is not callable. The signature is the same as for :c:func:`PyObject_Call`. This field is inherited by subtypes. @@ -350,7 +350,7 @@ type objects) *must* have the :attr:`ob_size` field. This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_getattr`: a subtype inherits both :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` from its base type when - the subtype's :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` are both *NULL*. + the subtype's :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` are both ``NULL``. .. c:member:: setattrofunc PyTypeObject.tp_setattro @@ -358,13 +358,13 @@ type objects) *must* have the :attr:`ob_size` field. An optional pointer to the function for setting and deleting attributes. The signature is the same as for :c:func:`PyObject_SetAttr`, but setting - *v* to *NULL* to delete an attribute must be supported. It is usually + *v* to ``NULL`` to delete an attribute must be supported. It is usually convenient to set this field to :c:func:`PyObject_GenericSetAttr`, which implements the normal way of setting object attributes. This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_setattr`: a subtype inherits both :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` from its base type when - the subtype's :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` are both *NULL*. + the subtype's :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` are both ``NULL``. .. c:member:: PyBufferProcs* PyTypeObject.tp_as_buffer @@ -385,7 +385,7 @@ type objects) *must* have the :attr:`ob_size` field. :c:member:`~PyTypeObject.tp_as_number`, :c:member:`~PyTypeObject.tp_as_sequence`, :c:member:`~PyTypeObject.tp_as_mapping`, and :c:member:`~PyTypeObject.tp_as_buffer`) that were historically not always present are valid; if such a flag bit is clear, the type fields it guards must not be accessed and - must be considered to have a zero or *NULL* value instead. + must be considered to have a zero or ``NULL`` value instead. Inheritance of this field is complicated. Most flag bits are inherited individually, i.e. if the base type has a flag bit set, the subtype inherits @@ -396,7 +396,7 @@ type objects) *must* have the :attr:`ob_size` field. the :c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` fields, i.e. if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is clear in the subtype and the :c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` fields in the subtype exist and have - *NULL* values. + ``NULL`` values. The following bit masks are currently defined; these can be ORed together using the ``|`` operator to form the value of the :c:member:`~PyTypeObject.tp_flags` field. The macro @@ -510,7 +510,7 @@ type objects) *must* have the :attr:`ob_size` field. Note that :c:func:`Py_VISIT` is called only on those members that can participate in reference cycles. Although there is also a ``self->key`` member, it can only - be *NULL* or a Python string and therefore cannot be part of a reference cycle. + be ``NULL`` or a Python string and therefore cannot be part of a reference cycle. On the other hand, even if you know a member can never be part of a cycle, as a debugging aid you may want to visit it anyway just so the :mod:`gc` module's @@ -543,7 +543,7 @@ type objects) *must* have the :attr:`ob_size` field. Implementations of :c:member:`~PyTypeObject.tp_clear` should drop the instance's references to those of its members that may be Python objects, and set its pointers to those - members to *NULL*, as in the following example:: + members to ``NULL``, as in the following example:: static int local_clear(localobject *self) @@ -557,12 +557,12 @@ type objects) *must* have the :attr:`ob_size` field. The :c:func:`Py_CLEAR` macro should be used, because clearing references is delicate: the reference to the contained object must not be decremented until - after the pointer to the contained object is set to *NULL*. This is because + after the pointer to the contained object is set to ``NULL``. This is because decrementing the reference count may cause the contained object to become trash, triggering a chain of reclamation activity that may include invoking arbitrary Python code (due to finalizers, or weakref callbacks, associated with the contained object). If it's possible for such code to reference *self* again, - it's important that the pointer to the contained object be *NULL* at that time, + it's important that the pointer to the contained object be ``NULL`` at that time, so that *self* knows the contained object can no longer be used. The :c:func:`Py_CLEAR` macro performs the operations in a safe order. @@ -602,7 +602,7 @@ type objects) *must* have the :attr:`ob_size` field. This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_hash`: a subtype inherits :c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash` when the subtype's :c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash` are both - *NULL*. + ``NULL``. The following constants are defined to be used as the third argument for :c:member:`~PyTypeObject.tp_richcompare` and for :c:func:`PyObject_RichCompare`: @@ -647,7 +647,7 @@ type objects) *must* have the :attr:`ob_size` field. 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 - initialized to *NULL*. + initialized to ``NULL``. Do not confuse this field with :c:member:`~PyTypeObject.tp_weaklist`; that is the list head for weak references to the type object itself. @@ -685,9 +685,9 @@ type objects) *must* have the :attr:`ob_size` field. .. c:member:: iternextfunc PyTypeObject.tp_iternext An optional pointer to a function that returns the next item in an iterator. - When the iterator is exhausted, it must return *NULL*; a :exc:`StopIteration` + When the iterator is exhausted, it must return ``NULL``; a :exc:`StopIteration` exception may or may not be set. When another error occurs, it must return - *NULL* too. Its presence signals that the instances of this type are + ``NULL`` too. Its presence signals that the instances of this type are iterators. Iterator types should also define the :c:member:`~PyTypeObject.tp_iter` function, and that @@ -701,7 +701,7 @@ type objects) *must* have the :attr:`ob_size` field. .. c:member:: struct PyMethodDef* PyTypeObject.tp_methods - An optional pointer to a static *NULL*-terminated array of :c:type:`PyMethodDef` + An optional pointer to a static ``NULL``-terminated array of :c:type:`PyMethodDef` structures, declaring regular methods of this type. For each entry in the array, an entry is added to the type's dictionary (see @@ -713,7 +713,7 @@ type objects) *must* have the :attr:`ob_size` field. .. c:member:: struct PyMemberDef* PyTypeObject.tp_members - An optional pointer to a static *NULL*-terminated array of :c:type:`PyMemberDef` + An optional pointer to a static ``NULL``-terminated array of :c:type:`PyMemberDef` structures, declaring regular data members (fields or slots) of instances of this type. @@ -726,7 +726,7 @@ type objects) *must* have the :attr:`ob_size` field. .. c:member:: struct PyGetSetDef* PyTypeObject.tp_getset - An optional pointer to a static *NULL*-terminated array of :c:type:`PyGetSetDef` + An optional pointer to a static ``NULL``-terminated array of :c:type:`PyGetSetDef` structures, declaring computed attributes of instances of this type. For each entry in the array, an entry is added to the type's dictionary (see @@ -751,7 +751,7 @@ type objects) *must* have the :attr:`ob_size` field. The type's dictionary is stored here by :c:func:`PyType_Ready`. - This field should normally be initialized to *NULL* before PyType_Ready is + This field should normally be initialized to ``NULL`` before PyType_Ready is called; it may also be initialized to a dictionary containing initial attributes for the type. Once :c:func:`PyType_Ready` has initialized the type, extra attributes for the type may be added to this dictionary only if they don't @@ -788,7 +788,7 @@ type objects) *must* have the :attr:`ob_size` field. int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value); - The *value* argument is set to *NULL* to delete the value. + The *value* argument is set to ``NULL`` to delete the value. This field is inherited by subtypes. .. XXX explain. @@ -864,7 +864,7 @@ type objects) *must* have the :attr:`ob_size` field. arguments represent positional and keyword arguments of the call to :meth:`__init__`. - The :c:member:`~PyTypeObject.tp_init` function, if not *NULL*, is called when an instance is + The :c:member:`~PyTypeObject.tp_init` function, if not ``NULL``, is called when an instance is created normally by calling its type, after the type's :c:member:`~PyTypeObject.tp_new` function has returned an instance of the type. If the :c:member:`~PyTypeObject.tp_new` function returns an instance of some other type that is not a subtype of the original type, no @@ -905,7 +905,7 @@ type objects) *must* have the :attr:`ob_size` field. An optional pointer to an instance creation function. - If this function is *NULL* for a particular type, that type cannot be called to + If this function is ``NULL`` for a particular type, that type cannot be called to create new instances; presumably there is some other way to create instances, like a factory function. @@ -928,7 +928,7 @@ type objects) *must* have the :attr:`ob_size` field. deferred to :c:member:`~PyTypeObject.tp_init`. This field is inherited by subtypes, except it is not inherited by static types - whose :c:member:`~PyTypeObject.tp_base` is *NULL* or ``&PyBaseObject_Type``. + whose :c:member:`~PyTypeObject.tp_base` is ``NULL`` or ``&PyBaseObject_Type``. .. c:member:: destructor PyTypeObject.tp_free @@ -971,7 +971,7 @@ type objects) *must* have the :attr:`ob_size` field. Tuple of base types. - This is set for types created by a class statement. It should be *NULL* for + This is set for types created by a class statement. It should be ``NULL`` for statically defined types. This field is not inherited. @@ -1169,14 +1169,14 @@ Mapping Object Structures This function is used by :c:func:`PyMapping_Size` and :c:func:`PyObject_Size`, and has the same signature. This slot may be set to - *NULL* if the object has no defined length. + ``NULL`` if the object has no defined length. .. c:member:: binaryfunc PyMappingMethods.mp_subscript This function is used by :c:func:`PyObject_GetItem` and :c:func:`PySequence_GetSlice`, and has the same signature as :c:func:`!PyObject_GetItem`. This slot must be filled for the - :c:func:`PyMapping_Check` function to return ``1``, it can be *NULL* + :c:func:`PyMapping_Check` function to return ``1``, it can be ``NULL`` otherwise. .. c:member:: objobjargproc PyMappingMethods.mp_ass_subscript @@ -1184,8 +1184,8 @@ Mapping Object Structures This function is used by :c:func:`PyObject_SetItem`, :c:func:`PyObject_DelItem`, :c:func:`PyObject_SetSlice` and :c:func:`PyObject_DelSlice`. It has the same signature as - :c:func:`!PyObject_SetItem`, but *v* can also be set to *NULL* to delete - an item. If this slot is *NULL*, the object does not support item + :c:func:`!PyObject_SetItem`, but *v* can also be set to ``NULL`` to delete + an item. If this slot is ``NULL``, the object does not support item assignment and deletion. @@ -1227,11 +1227,11 @@ Sequence Object Structures signature. It is also used by :c:func:`PyObject_GetItem`, after trying the subscription via the :c:member:`~PyMappingMethods.mp_subscript` slot. This slot must be filled for the :c:func:`PySequence_Check` - function to return ``1``, it can be *NULL* otherwise. + function to return ``1``, it can be ``NULL`` otherwise. Negative indexes are handled as follows: if the :attr:`sq_length` slot is filled, it is called and the sequence length is used to compute a positive - index which is passed to :attr:`sq_item`. If :attr:`sq_length` is *NULL*, + index which is passed to :attr:`sq_item`. If :attr:`sq_length` is ``NULL``, the index is passed as is to the function. .. c:member:: ssizeobjargproc PySequenceMethods.sq_ass_item @@ -1240,13 +1240,13 @@ Sequence Object Structures signature. It is also used by :c:func:`PyObject_SetItem` and :c:func:`PyObject_DelItem`, after trying the item assignment and deletion via the :c:member:`~PyMappingMethods.mp_ass_subscript` slot. - This slot may be left to *NULL* if the object does not support + This slot may be left to ``NULL`` if the object does not support item assignment and deletion. .. c:member:: objobjproc PySequenceMethods.sq_contains This function may be used by :c:func:`PySequence_Contains` and has the same - signature. This slot may be left to *NULL*, in this case + signature. This slot may be left to ``NULL``, in this case :c:func:`!PySequence_Contains` simply traverses the sequence until it finds a match. @@ -1254,7 +1254,7 @@ Sequence Object Structures This function is used by :c:func:`PySequence_InPlaceConcat` and has the same signature. It should modify its first operand, and return it. This slot - may be left to *NULL*, in this case :c:func:`!PySequence_InPlaceConcat` + may be left to ``NULL``, in this case :c:func:`!PySequence_InPlaceConcat` will fall back to :c:func:`PySequence_Concat`. It is also used by the augmented assignment ``+=``, after trying numeric in-place addition via the :c:member:`~PyNumberMethods.nb_inplace_add` slot. @@ -1263,7 +1263,7 @@ Sequence Object Structures This function is used by :c:func:`PySequence_InPlaceRepeat` and has the same signature. It should modify its first operand, and return it. This slot - may be left to *NULL*, in this case :c:func:`!PySequence_InPlaceRepeat` + may be left to ``NULL``, in this case :c:func:`!PySequence_InPlaceRepeat` will fall back to :c:func:`PySequence_Repeat`. It is also used by the augmented assignment ``*=``, after trying numeric in-place multiplication via the :c:member:`~PyNumberMethods.nb_inplace_multiply` slot. @@ -1295,7 +1295,7 @@ Buffer Object Structures steps: (1) Check if the request can be met. If not, raise :c:data:`PyExc_BufferError`, - set :c:data:`view->obj` to *NULL* and return ``-1``. + set :c:data:`view->obj` to ``NULL`` and return ``-1``. (2) Fill in the requested fields. @@ -1341,7 +1341,7 @@ Buffer Object Structures Handle a request to release the resources of the buffer. If no resources need to be released, :c:member:`PyBufferProcs.bf_releasebuffer` may be - *NULL*. Otherwise, a standard implementation of this function will take + ``NULL``. Otherwise, a standard implementation of this function will take these optional steps: (1) Decrement an internal counter for the number of exports. @@ -1395,7 +1395,7 @@ Async Object Structures The returned object must be an iterator, i.e. :c:func:`PyIter_Check` must return ``1`` for it. - This slot may be set to *NULL* if an object is not an :term:`awaitable`. + This slot may be set to ``NULL`` if an object is not an :term:`awaitable`. .. c:member:: unaryfunc PyAsyncMethods.am_aiter @@ -1405,7 +1405,7 @@ Async Object Structures Must return an :term:`awaitable` object. See :meth:`__anext__` for details. - This slot may be set to *NULL* if an object does not implement + This slot may be set to ``NULL`` if an object does not implement asynchronous iteration protocol. .. c:member:: unaryfunc PyAsyncMethods.am_anext @@ -1415,4 +1415,4 @@ Async Object Structures PyObject *am_anext(PyObject *self) Must return an :term:`awaitable` object. See :meth:`__anext__` for details. - This slot may be set to *NULL*. + This slot may be set to ``NULL``. diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index 1d724a3..35f6753 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -236,7 +236,7 @@ access internal read-only data of Unicode objects: .. versionchanged:: 3.3 This macro is now inefficient -- because in many cases the :c:type:`Py_UNICODE` representation does not exist and needs to be created - -- and can fail (return *NULL* with an exception set). Try to port the + -- and can fail (return ``NULL`` with an exception set). Try to port the code to use the new :c:func:`PyUnicode_nBYTE_DATA` macros or use :c:func:`PyUnicode_WRITE` or :c:func:`PyUnicode_READ`. @@ -413,11 +413,11 @@ APIs: Create a Unicode object from the char buffer *u*. The bytes will be interpreted as being UTF-8 encoded. The buffer is copied into the new - object. If the buffer is not *NULL*, the return value might be a shared + object. If the buffer is not ``NULL``, the return value might be a shared object, i.e. modification of the data is not allowed. - If *u* is *NULL*, this function behaves like :c:func:`PyUnicode_FromUnicode` - with the buffer set to *NULL*. This usage is deprecated in favor of + If *u* is ``NULL``, this function behaves like :c:func:`PyUnicode_FromUnicode` + with the buffer set to ``NULL``. This usage is deprecated in favor of :c:func:`PyUnicode_New`. @@ -443,82 +443,82 @@ APIs: .. tabularcolumns:: |l|l|L| - +-------------------+---------------------+--------------------------------+ - | Format Characters | Type | Comment | - +===================+=====================+================================+ - | :attr:`%%` | *n/a* | The literal % character. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%c` | int | A single character, | - | | | represented as a C int. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%d` | int | Equivalent to | - | | | ``printf("%d")``. [1]_ | - +-------------------+---------------------+--------------------------------+ - | :attr:`%u` | unsigned int | Equivalent to | - | | | ``printf("%u")``. [1]_ | - +-------------------+---------------------+--------------------------------+ - | :attr:`%ld` | long | Equivalent to | - | | | ``printf("%ld")``. [1]_ | - +-------------------+---------------------+--------------------------------+ - | :attr:`%li` | long | Equivalent to | - | | | ``printf("%li")``. [1]_ | - +-------------------+---------------------+--------------------------------+ - | :attr:`%lu` | unsigned long | Equivalent to | - | | | ``printf("%lu")``. [1]_ | - +-------------------+---------------------+--------------------------------+ - | :attr:`%lld` | long long | Equivalent to | - | | | ``printf("%lld")``. [1]_ | - +-------------------+---------------------+--------------------------------+ - | :attr:`%lli` | long long | Equivalent to | - | | | ``printf("%lli")``. [1]_ | - +-------------------+---------------------+--------------------------------+ - | :attr:`%llu` | unsigned long long | Equivalent to | - | | | ``printf("%llu")``. [1]_ | - +-------------------+---------------------+--------------------------------+ - | :attr:`%zd` | Py_ssize_t | Equivalent to | - | | | ``printf("%zd")``. [1]_ | - +-------------------+---------------------+--------------------------------+ - | :attr:`%zi` | Py_ssize_t | Equivalent to | - | | | ``printf("%zi")``. [1]_ | - +-------------------+---------------------+--------------------------------+ - | :attr:`%zu` | size_t | Equivalent to | - | | | ``printf("%zu")``. [1]_ | - +-------------------+---------------------+--------------------------------+ - | :attr:`%i` | int | Equivalent to | - | | | ``printf("%i")``. [1]_ | - +-------------------+---------------------+--------------------------------+ - | :attr:`%x` | int | Equivalent to | - | | | ``printf("%x")``. [1]_ | - +-------------------+---------------------+--------------------------------+ - | :attr:`%s` | const char\* | A null-terminated C character | - | | | array. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%p` | const void\* | The hex representation of a C | - | | | pointer. Mostly equivalent to | - | | | ``printf("%p")`` except that | - | | | it is guaranteed to start with | - | | | the literal ``0x`` regardless | - | | | of what the platform's | - | | | ``printf`` yields. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%A` | PyObject\* | The result of calling | - | | | :func:`ascii`. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%U` | PyObject\* | A Unicode object. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%V` | PyObject\*, | A Unicode object (which may be | - | | const char\* | *NULL*) and a null-terminated | - | | | C character array as a second | - | | | parameter (which will be used, | - | | | if the first parameter is | - | | | *NULL*). | - +-------------------+---------------------+--------------------------------+ - | :attr:`%S` | PyObject\* | The result of calling | - | | | :c:func:`PyObject_Str`. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%R` | PyObject\* | The result of calling | - | | | :c:func:`PyObject_Repr`. | - +-------------------+---------------------+--------------------------------+ + +-------------------+---------------------+----------------------------------+ + | Format Characters | Type | Comment | + +===================+=====================+==================================+ + | :attr:`%%` | *n/a* | The literal % character. | + +-------------------+---------------------+----------------------------------+ + | :attr:`%c` | int | A single character, | + | | | represented as a C int. | + +-------------------+---------------------+----------------------------------+ + | :attr:`%d` | int | Equivalent to | + | | | ``printf("%d")``. [1]_ | + +-------------------+---------------------+----------------------------------+ + | :attr:`%u` | unsigned int | Equivalent to | + | | | ``printf("%u")``. [1]_ | + +-------------------+---------------------+----------------------------------+ + | :attr:`%ld` | long | Equivalent to | + | | | ``printf("%ld")``. [1]_ | + +-------------------+---------------------+----------------------------------+ + | :attr:`%li` | long | Equivalent to | + | | | ``printf("%li")``. [1]_ | + +-------------------+---------------------+----------------------------------+ + | :attr:`%lu` | unsigned long | Equivalent to | + | | | ``printf("%lu")``. [1]_ | + +-------------------+---------------------+----------------------------------+ + | :attr:`%lld` | long long | Equivalent to | + | | | ``printf("%lld")``. [1]_ | + +-------------------+---------------------+----------------------------------+ + | :attr:`%lli` | long long | Equivalent to | + | | | ``printf("%lli")``. [1]_ | + +-------------------+---------------------+----------------------------------+ + | :attr:`%llu` | unsigned long long | Equivalent to | + | | | ``printf("%llu")``. [1]_ | + +-------------------+---------------------+----------------------------------+ + | :attr:`%zd` | Py_ssize_t | Equivalent to | + | | | ``printf("%zd")``. [1]_ | + +-------------------+---------------------+----------------------------------+ + | :attr:`%zi` | Py_ssize_t | Equivalent to | + | | | ``printf("%zi")``. [1]_ | + +-------------------+---------------------+----------------------------------+ + | :attr:`%zu` | size_t | Equivalent to | + | | | ``printf("%zu")``. [1]_ | + +-------------------+---------------------+----------------------------------+ + | :attr:`%i` | int | Equivalent to | + | | | ``printf("%i")``. [1]_ | + +-------------------+---------------------+----------------------------------+ + | :attr:`%x` | int | Equivalent to | + | | | ``printf("%x")``. [1]_ | + +-------------------+---------------------+----------------------------------+ + | :attr:`%s` | const char\* | A null-terminated C character | + | | | array. | + +-------------------+---------------------+----------------------------------+ + | :attr:`%p` | const void\* | The hex representation of a C | + | | | pointer. Mostly equivalent to | + | | | ``printf("%p")`` except that | + | | | it is guaranteed to start with | + | | | the literal ``0x`` regardless | + | | | of what the platform's | + | | | ``printf`` yields. | + +-------------------+---------------------+----------------------------------+ + | :attr:`%A` | PyObject\* | The result of calling | + | | | :func:`ascii`. | + +-------------------+---------------------+----------------------------------+ + | :attr:`%U` | PyObject\* | A Unicode object. | + +-------------------+---------------------+----------------------------------+ + | :attr:`%V` | PyObject\*, | A Unicode object (which may be | + | | const char\* | ``NULL``) and a null-terminated | + | | | C character array as a second | + | | | parameter (which will be used, | + | | | if the first parameter is | + | | | ``NULL``). | + +-------------------+---------------------+----------------------------------+ + | :attr:`%S` | PyObject\* | The result of calling | + | | | :c:func:`PyObject_Str`. | + +-------------------+---------------------+----------------------------------+ + | :attr:`%R` | PyObject\* | The result of calling | + | | | :c:func:`PyObject_Repr`. | + +-------------------+---------------------+----------------------------------+ An unrecognized format character causes all the rest of the format string to be copied as-is to the result string, and any extra arguments discarded. @@ -526,9 +526,9 @@ APIs: .. note:: The width formatter unit is number of characters rather than bytes. The precision formatter unit is number of bytes for ``"%s"`` and - ``"%V"`` (if the ``PyObject*`` argument is NULL), and a number of + ``"%V"`` (if the ``PyObject*`` argument is ``NULL``), and a number of characters for ``"%A"``, ``"%U"``, ``"%S"``, ``"%R"`` and ``"%V"`` - (if the ``PyObject*`` argument is not NULL). + (if the ``PyObject*`` argument is not ``NULL``). .. [1] For integer specifiers (d, u, ld, li, lu, lld, lli, llu, zd, zi, zu, i, x): the 0-conversion flag has effect even when a precision is given. @@ -558,13 +558,13 @@ APIs: :class:`bytes`, :class:`bytearray` and other :term:`bytes-like objects ` are decoded according to the given *encoding* and using the error handling - defined by *errors*. Both can be *NULL* to have the interface use the default + defined by *errors*. Both can be ``NULL`` to have the interface use the default values (see :ref:`builtincodecs` for details). All other objects, including Unicode objects, cause a :exc:`TypeError` to be set. - The API returns *NULL* if there was an error. The caller is responsible for + The API returns ``NULL`` if there was an error. The caller is responsible for decref'ing the returned objects. @@ -640,7 +640,7 @@ APIs: Py_ssize_t buflen, int copy_null) Copy the string *u* into a UCS4 buffer, including a null character, if - *copy_null* is set. Returns *NULL* and sets an exception on error (in + *copy_null* is set. Returns ``NULL`` and sets an exception on error (in particular, a :exc:`SystemError` if *buflen* is smaller than the length of *u*). *buffer* is returned on success. @@ -650,7 +650,7 @@ APIs: .. c:function:: Py_UCS4* PyUnicode_AsUCS4Copy(PyObject *u) Copy the string *u* into a new UCS4 buffer that is allocated using - :c:func:`PyMem_Malloc`. If this fails, *NULL* is returned with a + :c:func:`PyMem_Malloc`. If this fails, ``NULL`` is returned with a :exc:`MemoryError` set. The returned buffer always has an extra null code point appended. @@ -670,15 +670,15 @@ Extension modules can continue using them, as they will not be removed in Python .. c:function:: PyObject* PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size) Create a Unicode object from the Py_UNICODE buffer *u* of the given size. *u* - may be *NULL* which causes the contents to be undefined. It is the user's + may be ``NULL`` which causes the contents to be undefined. It is the user's responsibility to fill in the needed data. The buffer is copied into the new object. - If the buffer is not *NULL*, the return value might be a shared object. + If the buffer is not ``NULL``, the return value might be a shared object. Therefore, modification of the resulting Unicode object is only allowed when - *u* is *NULL*. + *u* is ``NULL``. - If the buffer is *NULL*, :c:func:`PyUnicode_READY` must be called once the + If the buffer is ``NULL``, :c:func:`PyUnicode_READY` must be called once the string content has been filled before using any of the access macros such as :c:func:`PyUnicode_KIND`. @@ -689,7 +689,7 @@ Extension modules can continue using them, as they will not be removed in Python .. c:function:: Py_UNICODE* PyUnicode_AsUnicode(PyObject *unicode) Return a read-only pointer to the Unicode object's internal - :c:type:`Py_UNICODE` buffer, or *NULL* on error. This will create the + :c:type:`Py_UNICODE` buffer, or ``NULL`` on error. This will create the :c:type:`Py_UNICODE*` representation of the object if it is not yet available. The buffer is always terminated with an extra null code point. Note that the resulting :c:type:`Py_UNICODE` string may also contain @@ -705,7 +705,7 @@ Extension modules can continue using them, as they will not be removed in Python Create a Unicode object by replacing all decimal digits in :c:type:`Py_UNICODE` buffer of the given *size* by ASCII digits 0--9 - according to their decimal value. Return *NULL* if an exception occurs. + according to their decimal value. Return ``NULL`` if an exception occurs. .. c:function:: Py_UNICODE* PyUnicode_AsUnicodeAndSize(PyObject *unicode, Py_ssize_t *size) @@ -721,7 +721,7 @@ Extension modules can continue using them, as they will not be removed in Python .. c:function:: Py_UNICODE* PyUnicode_AsUnicodeCopy(PyObject *unicode) - Create a copy of a Unicode string ending with a null code point. Return *NULL* + Create a copy of a Unicode string ending with a null code point. Return ``NULL`` and raise a :exc:`MemoryError` exception on memory allocation failure, otherwise return a new allocated buffer (use :c:func:`PyMem_Free` to free the buffer). Note that the resulting :c:type:`Py_UNICODE*` string may @@ -932,7 +932,7 @@ wchar_t Support Create a Unicode object from the :c:type:`wchar_t` buffer *w* of the given *size*. Passing ``-1`` as the *size* indicates that the function must itself compute the length, using wcslen. - Return *NULL* on failure. + Return ``NULL`` on failure. .. c:function:: Py_ssize_t PyUnicode_AsWideChar(PyObject *unicode, wchar_t *w, Py_ssize_t size) @@ -951,22 +951,22 @@ wchar_t Support .. c:function:: wchar_t* PyUnicode_AsWideCharString(PyObject *unicode, Py_ssize_t *size) Convert the Unicode object to a wide character string. The output string - always ends with a null character. If *size* is not *NULL*, write the number + always ends with a null character. If *size* is not ``NULL``, write the number of wide characters (excluding the trailing null termination character) into *\*size*. Note that the resulting :c:type:`wchar_t` string might contain null characters, which would cause the string to be truncated when used with - most C functions. If *size* is *NULL* and the :c:type:`wchar_t*` string + most C functions. If *size* is ``NULL`` and the :c:type:`wchar_t*` string contains null characters a :exc:`ValueError` is raised. Returns a buffer allocated by :c:func:`PyMem_Alloc` (use - :c:func:`PyMem_Free` to free it) on success. On error, returns *NULL* + :c:func:`PyMem_Free` to free it) on success. On error, returns ``NULL`` and *\*size* is undefined. Raises a :exc:`MemoryError` if memory allocation is failed. .. versionadded:: 3.2 .. versionchanged:: 3.7 - Raises a :exc:`ValueError` if *size* is *NULL* and the :c:type:`wchar_t*` + Raises a :exc:`ValueError` if *size* is ``NULL`` and the :c:type:`wchar_t*` string contains null characters. @@ -982,7 +982,7 @@ Many of the following APIs take two arguments encoding and errors, and they have the same semantics as the ones of the built-in :func:`str` string object constructor. -Setting encoding to *NULL* causes the default encoding to be used +Setting encoding to ``NULL`` causes the default encoding to be used which is ASCII. The file system calls should use :c:func:`PyUnicode_FSConverter` for encoding file names. This uses the variable :c:data:`Py_FileSystemDefaultEncoding` internally. This @@ -990,7 +990,7 @@ variable should be treated as read-only: on some systems, it will be a pointer to a static string, on others, it will change at run-time (such as when the application invokes setlocale). -Error handling is set by errors which may also be set to *NULL* meaning to use +Error handling is set by errors which may also be set to ``NULL`` meaning to use the default handling defined for the codec. Default error handling for all built-in codecs is "strict" (:exc:`ValueError` is raised). @@ -1010,7 +1010,7 @@ These are the generic codec APIs: Create a Unicode object by decoding *size* bytes of the encoded string *s*. *encoding* and *errors* have the same meaning as the parameters of the same name in the :func:`str` built-in function. The codec to be used is looked up - using the Python codec registry. Return *NULL* if an exception was raised by + using the Python codec registry. Return ``NULL`` if an exception was raised by the codec. @@ -1020,7 +1020,7 @@ These are the generic codec APIs: Encode a Unicode object and return the result as Python bytes object. *encoding* and *errors* have the same meaning as the parameters of the same name in the Unicode :meth:`~str.encode` method. The codec to be used is looked up - using the Python codec registry. Return *NULL* if an exception was raised by + using the Python codec registry. Return ``NULL`` if an exception was raised by the codec. @@ -1030,7 +1030,7 @@ These are the generic codec APIs: Encode the :c:type:`Py_UNICODE` buffer *s* of the given *size* and return a Python bytes object. *encoding* and *errors* have the same meaning as the parameters of the same name in the Unicode :meth:`~str.encode` method. The codec - to be used is looked up using the Python codec registry. Return *NULL* if an + to be used is looked up using the Python codec registry. Return ``NULL`` if an exception was raised by the codec. .. deprecated-removed:: 3.3 4.0 @@ -1047,14 +1047,14 @@ These are the UTF-8 codec APIs: .. c:function:: PyObject* PyUnicode_DecodeUTF8(const char *s, Py_ssize_t size, const char *errors) Create a Unicode object by decoding *size* bytes of the UTF-8 encoded string - *s*. Return *NULL* if an exception was raised by the codec. + *s*. Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_DecodeUTF8Stateful(const char *s, Py_ssize_t size, \ const char *errors, Py_ssize_t *consumed) - If *consumed* is *NULL*, behave like :c:func:`PyUnicode_DecodeUTF8`. If - *consumed* is not *NULL*, trailing incomplete UTF-8 byte sequences will not be + If *consumed* is ``NULL``, behave like :c:func:`PyUnicode_DecodeUTF8`. If + *consumed* is not ``NULL``, trailing incomplete UTF-8 byte sequences will not be treated as an error. Those bytes will not be decoded and the number of bytes that have been decoded will be stored in *consumed*. @@ -1062,7 +1062,7 @@ These are the UTF-8 codec APIs: .. c:function:: PyObject* PyUnicode_AsUTF8String(PyObject *unicode) Encode a Unicode object using UTF-8 and return the result as Python bytes - object. Error handling is "strict". Return *NULL* if an exception was + object. Error handling is "strict". Return ``NULL`` if an exception was raised by the codec. @@ -1070,11 +1070,11 @@ These are the UTF-8 codec APIs: Return a pointer to the UTF-8 encoding of the Unicode object, and store the size of the encoded representation (in bytes) in *size*. The - *size* argument can be *NULL*; in this case no size will be stored. The + *size* argument can be ``NULL``; in this case no size will be stored. The returned buffer always has an extra null byte appended (not included in *size*), regardless of whether there are any other null code points. - In the case of an error, *NULL* is returned with an exception set and no + In the case of an error, ``NULL`` is returned with an exception set and no *size* is stored. This caches the UTF-8 representation of the string in the Unicode object, and @@ -1100,7 +1100,7 @@ These are the UTF-8 codec APIs: .. c:function:: PyObject* PyUnicode_EncodeUTF8(const Py_UNICODE *s, Py_ssize_t size, const char *errors) Encode the :c:type:`Py_UNICODE` buffer *s* of the given *size* using UTF-8 and - return a Python bytes object. Return *NULL* if an exception was raised by + return a Python bytes object. Return ``NULL`` if an exception was raised by the codec. .. deprecated-removed:: 3.3 4.0 @@ -1119,10 +1119,10 @@ These are the UTF-32 codec APIs: const char *errors, int *byteorder) Decode *size* bytes from a UTF-32 encoded buffer string and return the - corresponding Unicode object. *errors* (if non-*NULL*) defines the error + corresponding Unicode object. *errors* (if non-``NULL``) defines the error handling. It defaults to "strict". - If *byteorder* is non-*NULL*, the decoder starts decoding using the given byte + If *byteorder* is non-``NULL``, the decoder starts decoding using the given byte order:: *byteorder == -1: little endian @@ -1137,16 +1137,16 @@ These are the UTF-32 codec APIs: After completion, *\*byteorder* is set to the current byte order at the end of input data. - If *byteorder* is *NULL*, the codec starts in native order mode. + If *byteorder* is ``NULL``, the codec starts in native order mode. - Return *NULL* if an exception was raised by the codec. + Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_DecodeUTF32Stateful(const char *s, Py_ssize_t size, \ const char *errors, int *byteorder, Py_ssize_t *consumed) - If *consumed* is *NULL*, behave like :c:func:`PyUnicode_DecodeUTF32`. If - *consumed* is not *NULL*, :c:func:`PyUnicode_DecodeUTF32Stateful` will not treat + If *consumed* is ``NULL``, behave like :c:func:`PyUnicode_DecodeUTF32`. If + *consumed* is not ``NULL``, :c:func:`PyUnicode_DecodeUTF32Stateful` will not treat trailing incomplete UTF-32 byte sequences (such as a number of bytes not divisible by four) as an error. Those bytes will not be decoded and the number of bytes that have been decoded will be stored in *consumed*. @@ -1156,7 +1156,7 @@ These are the UTF-32 codec APIs: Return a Python byte string using the UTF-32 encoding in native byte order. The string always starts with a BOM mark. Error handling is "strict". - Return *NULL* if an exception was raised by the codec. + Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_EncodeUTF32(const Py_UNICODE *s, Py_ssize_t size, \ @@ -1172,10 +1172,10 @@ These are the UTF-32 codec APIs: If byteorder is ``0``, the output string will always start with the Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is prepended. - If *Py_UNICODE_WIDE* is not defined, surrogate pairs will be output + If ``Py_UNICODE_WIDE`` is not defined, surrogate pairs will be output as a single code point. - Return *NULL* if an exception was raised by the codec. + Return ``NULL`` if an exception was raised by the codec. .. deprecated-removed:: 3.3 4.0 Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using @@ -1192,10 +1192,10 @@ These are the UTF-16 codec APIs: const char *errors, int *byteorder) Decode *size* bytes from a UTF-16 encoded buffer string and return the - corresponding Unicode object. *errors* (if non-*NULL*) defines the error + corresponding Unicode object. *errors* (if non-``NULL``) defines the error handling. It defaults to "strict". - If *byteorder* is non-*NULL*, the decoder starts decoding using the given byte + If *byteorder* is non-``NULL``, the decoder starts decoding using the given byte order:: *byteorder == -1: little endian @@ -1211,16 +1211,16 @@ These are the UTF-16 codec APIs: After completion, *\*byteorder* is set to the current byte order at the end of input data. - If *byteorder* is *NULL*, the codec starts in native order mode. + If *byteorder* is ``NULL``, the codec starts in native order mode. - Return *NULL* if an exception was raised by the codec. + Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_DecodeUTF16Stateful(const char *s, Py_ssize_t size, \ const char *errors, int *byteorder, Py_ssize_t *consumed) - If *consumed* is *NULL*, behave like :c:func:`PyUnicode_DecodeUTF16`. If - *consumed* is not *NULL*, :c:func:`PyUnicode_DecodeUTF16Stateful` will not treat + If *consumed* is ``NULL``, behave like :c:func:`PyUnicode_DecodeUTF16`. If + *consumed* is not ``NULL``, :c:func:`PyUnicode_DecodeUTF16Stateful` will not treat trailing incomplete UTF-16 byte sequences (such as an odd number of bytes or a split surrogate pair) as an error. Those bytes will not be decoded and the number of bytes that have been decoded will be stored in *consumed*. @@ -1230,7 +1230,7 @@ These are the UTF-16 codec APIs: Return a Python byte string using the UTF-16 encoding in native byte order. The string always starts with a BOM mark. Error handling is "strict". - Return *NULL* if an exception was raised by the codec. + Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_EncodeUTF16(const Py_UNICODE *s, Py_ssize_t size, \ @@ -1246,11 +1246,11 @@ These are the UTF-16 codec APIs: If byteorder is ``0``, the output string will always start with the Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is prepended. - If *Py_UNICODE_WIDE* is defined, a single :c:type:`Py_UNICODE` value may get + If ``Py_UNICODE_WIDE`` is defined, a single :c:type:`Py_UNICODE` value may get represented as a surrogate pair. If it is not defined, each :c:type:`Py_UNICODE` values is interpreted as a UCS-2 character. - Return *NULL* if an exception was raised by the codec. + Return ``NULL`` if an exception was raised by the codec. .. deprecated-removed:: 3.3 4.0 Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using @@ -1266,14 +1266,14 @@ These are the UTF-7 codec APIs: .. c:function:: PyObject* PyUnicode_DecodeUTF7(const char *s, Py_ssize_t size, const char *errors) Create a Unicode object by decoding *size* bytes of the UTF-7 encoded string - *s*. Return *NULL* if an exception was raised by the codec. + *s*. Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_DecodeUTF7Stateful(const char *s, Py_ssize_t size, \ const char *errors, Py_ssize_t *consumed) - If *consumed* is *NULL*, behave like :c:func:`PyUnicode_DecodeUTF7`. If - *consumed* is not *NULL*, trailing incomplete UTF-7 base-64 sections will not + If *consumed* is ``NULL``, behave like :c:func:`PyUnicode_DecodeUTF7`. If + *consumed* is not ``NULL``, trailing incomplete UTF-7 base-64 sections will not be treated as an error. Those bytes will not be decoded and the number of bytes that have been decoded will be stored in *consumed*. @@ -1282,7 +1282,7 @@ These are the UTF-7 codec APIs: int base64SetO, int base64WhiteSpace, const char *errors) Encode the :c:type:`Py_UNICODE` buffer of the given size using UTF-7 and - return a Python bytes object. Return *NULL* if an exception was raised by + return a Python bytes object. Return ``NULL`` if an exception was raised by the codec. If *base64SetO* is nonzero, "Set O" (punctuation that has no otherwise @@ -1305,20 +1305,20 @@ These are the "Unicode Escape" codec APIs: Py_ssize_t size, const char *errors) Create a Unicode object by decoding *size* bytes of the Unicode-Escape encoded - string *s*. Return *NULL* if an exception was raised by the codec. + string *s*. Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_AsUnicodeEscapeString(PyObject *unicode) Encode a Unicode object using Unicode-Escape and return the result as a - bytes object. Error handling is "strict". Return *NULL* if an exception was + bytes object. Error handling is "strict". Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size) Encode the :c:type:`Py_UNICODE` buffer of the given *size* using Unicode-Escape and - return a bytes object. Return *NULL* if an exception was raised by the codec. + return a bytes object. Return ``NULL`` if an exception was raised by the codec. .. deprecated-removed:: 3.3 4.0 Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using @@ -1335,13 +1335,13 @@ These are the "Raw Unicode Escape" codec APIs: Py_ssize_t size, const char *errors) Create a Unicode object by decoding *size* bytes of the Raw-Unicode-Escape - encoded string *s*. Return *NULL* if an exception was raised by the codec. + encoded string *s*. Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) Encode a Unicode object using Raw-Unicode-Escape and return the result as - a bytes object. Error handling is "strict". Return *NULL* if an exception + a bytes object. Error handling is "strict". Return ``NULL`` if an exception was raised by the codec. @@ -1349,7 +1349,7 @@ These are the "Raw Unicode Escape" codec APIs: Py_ssize_t size) Encode the :c:type:`Py_UNICODE` buffer of the given *size* using Raw-Unicode-Escape - and return a bytes object. Return *NULL* if an exception was raised by the codec. + and return a bytes object. Return ``NULL`` if an exception was raised by the codec. .. deprecated-removed:: 3.3 4.0 Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using @@ -1367,20 +1367,20 @@ ordinals and only these are accepted by the codecs during encoding. .. c:function:: PyObject* PyUnicode_DecodeLatin1(const char *s, Py_ssize_t size, const char *errors) Create a Unicode object by decoding *size* bytes of the Latin-1 encoded string - *s*. Return *NULL* if an exception was raised by the codec. + *s*. Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_AsLatin1String(PyObject *unicode) Encode a Unicode object using Latin-1 and return the result as Python bytes - object. Error handling is "strict". Return *NULL* if an exception was + object. Error handling is "strict". Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_EncodeLatin1(const Py_UNICODE *s, Py_ssize_t size, const char *errors) Encode the :c:type:`Py_UNICODE` buffer of the given *size* using Latin-1 and - return a Python bytes object. Return *NULL* if an exception was raised by + return a Python bytes object. Return ``NULL`` if an exception was raised by the codec. .. deprecated-removed:: 3.3 4.0 @@ -1399,20 +1399,20 @@ codes generate errors. .. c:function:: PyObject* PyUnicode_DecodeASCII(const char *s, Py_ssize_t size, const char *errors) Create a Unicode object by decoding *size* bytes of the ASCII encoded string - *s*. Return *NULL* if an exception was raised by the codec. + *s*. Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_AsASCIIString(PyObject *unicode) Encode a Unicode object using ASCII and return the result as Python bytes - object. Error handling is "strict". Return *NULL* if an exception was + object. Error handling is "strict". Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_EncodeASCII(const Py_UNICODE *s, Py_ssize_t size, const char *errors) Encode the :c:type:`Py_UNICODE` buffer of the given *size* using ASCII and - return a Python bytes object. Return *NULL* if an exception was raised by + return a Python bytes object. Return ``NULL`` if an exception was raised by the codec. .. deprecated-removed:: 3.3 4.0 @@ -1436,10 +1436,10 @@ These are the mapping codec APIs: PyObject *mapping, const char *errors) Create a Unicode object by decoding *size* bytes of the encoded string *s* - using the given *mapping* object. Return *NULL* if an exception was raised + using the given *mapping* object. Return ``NULL`` if an exception was raised by the codec. - If *mapping* is *NULL*, Latin-1 decoding will be applied. Else + If *mapping* is ``NULL``, Latin-1 decoding will be applied. Else *mapping* must map bytes ordinals (integers in the range from 0 to 255) to Unicode strings, integers (which are then interpreted as Unicode ordinals) or ``None``. Unmapped data bytes -- ones which cause a @@ -1451,7 +1451,7 @@ These are the mapping codec APIs: .. c:function:: PyObject* PyUnicode_AsCharmapString(PyObject *unicode, PyObject *mapping) Encode a Unicode object using the given *mapping* object and return the - result as a bytes object. Error handling is "strict". Return *NULL* if an + result as a bytes object. Error handling is "strict". Return ``NULL`` if an exception was raised by the codec. The *mapping* object must map Unicode ordinal integers to bytes objects, @@ -1464,7 +1464,7 @@ These are the mapping codec APIs: PyObject *mapping, const char *errors) Encode the :c:type:`Py_UNICODE` buffer of the given *size* using the given - *mapping* object and return the result as a bytes object. Return *NULL* if + *mapping* object and return the result as a bytes object. Return ``NULL`` if an exception was raised by the codec. .. deprecated-removed:: 3.3 4.0 @@ -1479,7 +1479,7 @@ The following codec API is special in that maps Unicode to Unicode. PyObject *mapping, 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 + resulting Unicode object. Return ``NULL`` if an exception was raised by the codec. The *mapping* object must map Unicode ordinal integers to Unicode strings, @@ -1493,7 +1493,7 @@ The following codec API is special in that maps Unicode to Unicode. Translate a :c:type:`Py_UNICODE` buffer of the given *size* by applying a character *mapping* table to it and return the resulting Unicode object. - Return *NULL* when an exception was raised by the codec. + Return ``NULL`` when an exception was raised by the codec. .. deprecated-removed:: 3.3 4.0 Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using @@ -1512,14 +1512,14 @@ the user settings on the machine running the codec. .. c:function:: PyObject* PyUnicode_DecodeMBCS(const char *s, Py_ssize_t size, const char *errors) Create a Unicode object by decoding *size* bytes of the MBCS encoded string *s*. - Return *NULL* if an exception was raised by the codec. + Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_DecodeMBCSStateful(const char *s, Py_ssize_t size, \ const char *errors, Py_ssize_t *consumed) - If *consumed* is *NULL*, behave like :c:func:`PyUnicode_DecodeMBCS`. If - *consumed* is not *NULL*, :c:func:`PyUnicode_DecodeMBCSStateful` will not decode + If *consumed* is ``NULL``, behave like :c:func:`PyUnicode_DecodeMBCS`. If + *consumed* is not ``NULL``, :c:func:`PyUnicode_DecodeMBCSStateful` will not decode trailing lead byte and the number of bytes that have been decoded will be stored in *consumed*. @@ -1527,14 +1527,14 @@ the user settings on the machine running the codec. .. c:function:: PyObject* PyUnicode_AsMBCSString(PyObject *unicode) Encode a Unicode object using MBCS and return the result as Python bytes - object. Error handling is "strict". Return *NULL* if an exception was + object. Error handling is "strict". Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_EncodeCodePage(int code_page, PyObject *unicode, const char *errors) Encode the Unicode object using the specified code page and return a Python - bytes object. Return *NULL* if an exception was raised by the codec. Use + bytes object. Return ``NULL`` if an exception was raised by the codec. Use :c:data:`CP_ACP` code page to get the MBCS encoder. .. versionadded:: 3.3 @@ -1543,7 +1543,7 @@ the user settings on the machine running the codec. .. c:function:: PyObject* PyUnicode_EncodeMBCS(const Py_UNICODE *s, Py_ssize_t size, const char *errors) Encode the :c:type:`Py_UNICODE` buffer of the given *size* using MBCS and return - a Python bytes object. Return *NULL* if an exception was raised by the + a Python bytes object. Return ``NULL`` if an exception was raised by the codec. .. deprecated-removed:: 3.3 4.0 @@ -1565,7 +1565,7 @@ The following APIs are capable of handling Unicode objects and strings on input (we refer to them as strings in the descriptions) and return Unicode objects or integers as appropriate. -They all return *NULL* or ``-1`` if an exception occurs. +They all return ``NULL`` or ``-1`` if an exception occurs. .. c:function:: PyObject* PyUnicode_Concat(PyObject *left, PyObject *right) @@ -1575,7 +1575,7 @@ They all return *NULL* or ``-1`` if an exception occurs. .. c:function:: PyObject* PyUnicode_Split(PyObject *s, PyObject *sep, Py_ssize_t maxsplit) - Split a string giving a list of Unicode strings. If *sep* is *NULL*, splitting + Split a string giving a list of Unicode strings. If *sep* is ``NULL``, splitting will be done at all whitespace substrings. Otherwise, splits occur at the given separator. At most *maxsplit* splits will be done. If negative, no limit is set. Separators are not included in the resulting list. @@ -1601,7 +1601,7 @@ They all return *NULL* or ``-1`` if an exception occurs. 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 + *errors* has the usual meaning for codecs. It may be ``NULL`` which indicates to use the default error handling. diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index 317093e..49a7a0c 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -45,7 +45,7 @@ the same library that the Python runtime is using. .. c:function:: int PyRun_AnyFile(FILE *fp, const char *filename) This is a simplified interface to :c:func:`PyRun_AnyFileExFlags` below, leaving - *closeit* set to ``0`` and *flags* set to *NULL*. + *closeit* set to ``0`` and *flags* set to ``NULL``. .. c:function:: int PyRun_AnyFileFlags(FILE *fp, const char *filename, PyCompilerFlags *flags) @@ -57,7 +57,7 @@ the same library that the Python runtime is using. .. c:function:: int PyRun_AnyFileEx(FILE *fp, const char *filename, int closeit) This is a simplified interface to :c:func:`PyRun_AnyFileExFlags` below, leaving - the *flags* argument set to *NULL*. + the *flags* argument set to ``NULL``. .. c:function:: int PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit, PyCompilerFlags *flags) @@ -66,14 +66,14 @@ the same library that the Python runtime is using. terminal input or Unix pseudo-terminal), return the value of :c:func:`PyRun_InteractiveLoop`, otherwise return the result of :c:func:`PyRun_SimpleFile`. *filename* is decoded from the filesystem - encoding (:func:`sys.getfilesystemencoding`). If *filename* is *NULL*, this + encoding (:func:`sys.getfilesystemencoding`). If *filename* is ``NULL``, this function uses ``"???"`` as the filename. .. c:function:: int PyRun_SimpleString(const char *command) This is a simplified interface to :c:func:`PyRun_SimpleStringFlags` below, - leaving the *PyCompilerFlags\** argument set to NULL. + leaving the :c:type:`PyCompilerFlags`\* argument set to ``NULL``. .. c:function:: int PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags) @@ -92,13 +92,13 @@ the same library that the Python runtime is using. .. c:function:: int PyRun_SimpleFile(FILE *fp, const char *filename) This is a simplified interface to :c:func:`PyRun_SimpleFileExFlags` below, - leaving *closeit* set to ``0`` and *flags* set to *NULL*. + leaving *closeit* set to ``0`` and *flags* set to ``NULL``. .. c:function:: int PyRun_SimpleFileEx(FILE *fp, const char *filename, int closeit) This is a simplified interface to :c:func:`PyRun_SimpleFileExFlags` below, - leaving *flags* set to *NULL*. + leaving *flags* set to ``NULL``. .. c:function:: int PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, PyCompilerFlags *flags) @@ -117,7 +117,7 @@ the same library that the Python runtime is using. .. c:function:: int PyRun_InteractiveOne(FILE *fp, const char *filename) This is a simplified interface to :c:func:`PyRun_InteractiveOneFlags` below, - leaving *flags* set to *NULL*. + leaving *flags* set to ``NULL``. .. c:function:: int PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags) @@ -137,7 +137,7 @@ the same library that the Python runtime is using. .. c:function:: int PyRun_InteractiveLoop(FILE *fp, const char *filename) This is a simplified interface to :c:func:`PyRun_InteractiveLoopFlags` below, - leaving *flags* set to *NULL*. + leaving *flags* set to ``NULL``. .. c:function:: int PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flags) @@ -166,13 +166,13 @@ the same library that the Python runtime is using. ``char *func(FILE *stdin, FILE *stdout, char *prompt)``, overriding the default function used to read a single line of input at the interpreter's prompt. The function is expected to output - the string *prompt* if it's not *NULL*, and then read a line of + the string *prompt* if it's not ``NULL``, and then read a line of input from the provided standard input file, returning the resulting string. For example, The :mod:`readline` module sets this hook to provide line-editing and tab-completion features. The result must be a string allocated by :c:func:`PyMem_RawMalloc` or - :c:func:`PyMem_RawRealloc`, or *NULL* if an error occurred. + :c:func:`PyMem_RawRealloc`, or ``NULL`` if an error occurred. .. versionchanged:: 3.4 The result must be allocated by :c:func:`PyMem_RawMalloc` or @@ -184,14 +184,14 @@ the same library that the Python runtime is using. This is a simplified interface to :c:func:`PyParser_SimpleParseStringFlagsFilename` below, leaving *filename* set - to *NULL* and *flags* set to ``0``. + to ``NULL`` and *flags* set to ``0``. .. c:function:: struct _node* PyParser_SimpleParseStringFlags( const char *str, int start, int flags) This is a simplified interface to :c:func:`PyParser_SimpleParseStringFlagsFilename` below, leaving *filename* set - to *NULL*. + to ``NULL``. .. c:function:: struct _node* PyParser_SimpleParseStringFlagsFilename( const char *str, const char *filename, int start, int flags) @@ -218,7 +218,7 @@ the same library that the Python runtime is using. .. c:function:: PyObject* PyRun_String(const char *str, int start, PyObject *globals, PyObject *locals) This is a simplified interface to :c:func:`PyRun_StringFlags` below, leaving - *flags* set to *NULL*. + *flags* set to ``NULL``. .. c:function:: PyObject* PyRun_StringFlags(const char *str, int start, PyObject *globals, PyObject *locals, PyCompilerFlags *flags) @@ -229,20 +229,20 @@ the same library that the Python runtime is using. that implements the mapping protocol. The parameter *start* specifies the start token that should be used to parse the source code. - Returns the result of executing the code as a Python object, or *NULL* if an + Returns the result of executing the code as a Python object, or ``NULL`` if an exception was raised. .. c:function:: PyObject* PyRun_File(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals) This is a simplified interface to :c:func:`PyRun_FileExFlags` below, leaving - *closeit* set to ``0`` and *flags* set to *NULL*. + *closeit* set to ``0`` and *flags* set to ``NULL``. .. c:function:: PyObject* PyRun_FileEx(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals, int closeit) This is a simplified interface to :c:func:`PyRun_FileExFlags` below, leaving - *flags* set to *NULL*. + *flags* set to ``NULL``. .. c:function:: PyObject* PyRun_FileFlags(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals, PyCompilerFlags *flags) @@ -263,7 +263,7 @@ the same library that the Python runtime is using. .. c:function:: PyObject* Py_CompileString(const char *str, const char *filename, int start) This is a simplified interface to :c:func:`Py_CompileStringFlags` below, leaving - *flags* set to *NULL*. + *flags* set to ``NULL``. .. c:function:: PyObject* Py_CompileStringFlags(const char *str, const char *filename, int start, PyCompilerFlags *flags) @@ -279,7 +279,7 @@ the same library that the Python runtime is using. code which can be compiled and should be :const:`Py_eval_input`, :const:`Py_file_input`, or :const:`Py_single_input`. The filename specified by *filename* is used to construct the code object and may appear in tracebacks or - :exc:`SyntaxError` exception messages. This returns *NULL* if the code + :exc:`SyntaxError` exception messages. This returns ``NULL`` if the code cannot be parsed or compiled. The integer *optimize* specifies the optimization level of the compiler; a @@ -302,7 +302,7 @@ the same library that the Python runtime is using. This is a simplified interface to :c:func:`PyEval_EvalCodeEx`, with just the code object, and global and local variables. The other arguments are - set to *NULL*. + set to ``NULL``. .. c:function:: PyObject* PyEval_EvalCodeEx(PyObject *co, PyObject *globals, PyObject *locals, PyObject *const *args, int argcount, PyObject *const *kws, int kwcount, PyObject *const *defs, int defcount, PyObject *kwdefs, PyObject *closure) @@ -379,7 +379,7 @@ the same library that the Python runtime is using. executed, it is passed as ``PyCompilerFlags *flags``. In this case, ``from __future__ import`` can modify *flags*. - Whenever ``PyCompilerFlags *flags`` is *NULL*, :attr:`cf_flags` is treated as + Whenever ``PyCompilerFlags *flags`` is ``NULL``, :attr:`cf_flags` is treated as equal to ``0``, and any modification due to ``from __future__ import`` is discarded. :: diff --git a/Doc/c-api/weakref.rst b/Doc/c-api/weakref.rst index 6cb3e33..0938ee1 100644 --- a/Doc/c-api/weakref.rst +++ b/Doc/c-api/weakref.rst @@ -33,9 +33,9 @@ as much as it can. reference object may be returned. The second parameter, *callback*, can be a callable object that receives notification when *ob* is garbage collected; it should accept a single parameter, which will be the weak reference object - itself. *callback* may also be ``None`` or *NULL*. If *ob* is not a + itself. *callback* may also be ``None`` or ``NULL``. If *ob* is not a weakly-referencable object, or if *callback* is not callable, ``None``, or - *NULL*, this will return *NULL* and raise :exc:`TypeError`. + ``NULL``, this will return ``NULL`` and raise :exc:`TypeError`. .. c:function:: PyObject* PyWeakref_NewProxy(PyObject *ob, PyObject *callback) @@ -45,9 +45,9 @@ as much as it can. existing proxy object may be returned. The second parameter, *callback*, can be a callable object that receives notification when *ob* is garbage collected; it should accept a single parameter, which will be the weak - reference object itself. *callback* may also be ``None`` or *NULL*. If *ob* + reference object itself. *callback* may also be ``None`` or ``NULL``. If *ob* is not a weakly-referencable object, or if *callback* is not callable, - ``None``, or *NULL*, this will return *NULL* and raise :exc:`TypeError`. + ``None``, or ``NULL``, this will return ``NULL`` and raise :exc:`TypeError`. .. c:function:: PyObject* PyWeakref_GetObject(PyObject *ref) diff --git a/Doc/distributing/index.rst b/Doc/distributing/index.rst index 2e46c7a..5f7b3bb 100644 --- a/Doc/distributing/index.rst +++ b/Doc/distributing/index.rst @@ -40,7 +40,7 @@ Key terms evolution of the standard packaging tools and the associated metadata and file format standards. They maintain a variety of tools, documentation and issue trackers on both `GitHub `__ and - `BitBucket `__. + `Bitbucket `__. * :mod:`distutils` is the original build and distribution system first added to the Python standard library in 1998. While direct use of :mod:`distutils` is being phased out, it still laid the foundation for the current packaging @@ -148,7 +148,7 @@ These are quick answers or links for some common tasks. This isn't an easy topic, but here are a few tips: * check the Python Packaging Index to see if the name is already in use -* check popular hosting sites like GitHub, BitBucket, etc to see if there +* check popular hosting sites like GitHub, Bitbucket, etc to see if there is already a project with that name * check what comes up in a web search for the name you're considering * avoid particularly common words, especially ones with multiple meanings, diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst index 8efeffb..5ae84e0 100644 --- a/Doc/distutils/apiref.rst +++ b/Doc/distutils/apiref.rst @@ -1530,7 +1530,7 @@ Python's own build procedures. ================================================= .. module:: distutils.text_file - :synopsis: provides the TextFile class, a simple interface to text files + :synopsis: Provides the TextFile class, a simple interface to text files This module provides the :class:`TextFile` class, which gives an interface to @@ -1669,7 +1669,7 @@ lines, and joining lines with backslashes. =================================================== .. module:: distutils.version - :synopsis: implements classes that represent module version numbers. + :synopsis: Implements classes that represent module version numbers. .. % todo @@ -1684,7 +1684,7 @@ lines, and joining lines with backslashes. =================================================================== .. module:: distutils.cmd - :synopsis: This module provides the abstract base class Command. This class + :synopsis: Provides the abstract base class :class:`~distutils.cmd.Command`. This class is subclassed by the modules in the distutils.command subpackage. @@ -1777,7 +1777,7 @@ Subclasses of :class:`Command` must define the following methods. ========================================================== .. module:: distutils.command - :synopsis: This subpackage contains one module for each standard Distutils command. + :synopsis: Contains one module for each standard Distutils command. .. % \subsubsection{Individual Distutils commands} @@ -2021,7 +2021,7 @@ This is described in more detail in :pep:`301`. =================================================================== .. module:: distutils.command.check - :synopsis: Check the metadata of a package + :synopsis: Check the meta-data of a package The ``check`` command performs some tests on the meta-data of a package. diff --git a/Doc/extending/embedding.rst b/Doc/extending/embedding.rst index 13d83b7..881390d 100644 --- a/Doc/extending/embedding.rst +++ b/Doc/extending/embedding.rst @@ -196,7 +196,7 @@ function is then made with:: pValue = PyObject_CallObject(pFunc, pArgs); -Upon return of the function, ``pValue`` is either *NULL* or it contains a +Upon return of the function, ``pValue`` is either ``NULL`` or it contains a reference to the return value of the function. Be sure to release the reference after examining the value. diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst index 73a77c7..fb15ecf 100644 --- a/Doc/extending/extending.rst +++ b/Doc/extending/extending.rst @@ -117,7 +117,7 @@ store the converted values. More about this later. type and its components have been stored in the variables whose addresses are passed. It returns false (zero) if an invalid argument list was passed. In the latter case it also raises an appropriate exception so the calling function can -return *NULL* immediately (as we saw in the example). +return ``NULL`` immediately (as we saw in the example). .. _extending-errors: @@ -127,8 +127,8 @@ Intermezzo: Errors and Exceptions An important convention throughout the Python interpreter is the following: when a function fails, it should set an exception condition and return an error value -(usually a *NULL* pointer). Exceptions are stored in a static global variable -inside the interpreter; if this variable is *NULL* no exception has occurred. A +(usually a ``NULL`` pointer). Exceptions are stored in a static global variable +inside the interpreter; if this variable is ``NULL`` no exception has occurred. A second global variable stores the "associated value" of the exception (the second argument to :keyword:`raise`). A third variable contains the stack traceback in case the error originated in Python code. These three variables @@ -152,13 +152,13 @@ its associated value. You don't need to :c:func:`Py_INCREF` the objects passed to any of these functions. You can test non-destructively whether an exception has been set with -:c:func:`PyErr_Occurred`. This returns the current exception object, or *NULL* +:c:func:`PyErr_Occurred`. This returns the current exception object, or ``NULL`` if no exception has occurred. You normally don't need to call :c:func:`PyErr_Occurred` to see whether an error occurred in a function call, since you should be able to tell from the return value. When a function *f* that calls another function *g* detects that the latter -fails, *f* should itself return an error value (usually *NULL* or ``-1``). It +fails, *f* should itself return an error value (usually ``NULL`` or ``-1``). It should *not* call one of the :c:func:`PyErr_\*` functions --- one has already been called by *g*. *f*'s caller is then supposed to also return an error indication to *its* caller, again *without* calling :c:func:`PyErr_\*`, and so on @@ -234,7 +234,7 @@ with an exception object:: Note that the Python name for the exception object is :exc:`spam.error`. The :c:func:`PyErr_NewException` function may create a class with the base class -being :exc:`Exception` (unless another class is passed in instead of *NULL*), +being :exc:`Exception` (unless another class is passed in instead of ``NULL``), described in :ref:`bltin-exceptions`. Note also that the :c:data:`SpamError` variable retains a reference to the newly @@ -278,7 +278,7 @@ statement:: if (!PyArg_ParseTuple(args, "s", &command)) return NULL; -It returns *NULL* (the error indicator for functions returning object pointers) +It returns ``NULL`` (the error indicator for functions returning object pointers) if an error is detected in the argument list, relying on the exception set by :c:func:`PyArg_ParseTuple`. Otherwise the string value of the argument has been copied to the local variable :c:data:`command`. This is a pointer assignment and @@ -308,7 +308,7 @@ macro):: return Py_None; :c:data:`Py_None` is the C name for the special Python object ``None``. It is a -genuine Python object rather than a *NULL* pointer, which means "error" in most +genuine Python object rather than a ``NULL`` pointer, which means "error" in most contexts, as we have seen. @@ -376,7 +376,7 @@ inserts built-in function objects into the newly created module based upon the table (an array of :c:type:`PyMethodDef` structures) found in the module definition. :c:func:`PyModule_Create` returns a pointer to the module object that it creates. It may abort with a fatal error for -certain errors, or return *NULL* if the module could not be initialized +certain errors, or return ``NULL`` if the module could not be initialized satisfactorily. The init function must return the module object to its caller, so that it then gets inserted into ``sys.modules``. @@ -526,8 +526,8 @@ This function must be registered with the interpreter using the :ref:`parsetuple`. The macros :c:func:`Py_XINCREF` and :c:func:`Py_XDECREF` increment/decrement the -reference count of an object and are safe in the presence of *NULL* pointers -(but note that *temp* will not be *NULL* in this context). More info on them +reference count of an object and are safe in the presence of ``NULL`` pointers +(but note that *temp* will not be ``NULL`` in this context). More info on them in section :ref:`refcounts`. .. index:: single: PyObject_CallObject() @@ -536,7 +536,7 @@ Later, when it is time to call the function, you call the C function :c:func:`PyObject_CallObject`. This function has two arguments, both pointers to arbitrary Python objects: the Python function, and the argument list. The argument list must always be a tuple object, whose length is the number of -arguments. To call the Python function with no arguments, pass in NULL, or +arguments. To call the Python function with no arguments, pass in ``NULL``, or an empty tuple; to call it with one argument, pass a singleton tuple. :c:func:`Py_BuildValue` returns a tuple when its format string consists of zero or more format codes between parentheses. For example:: @@ -566,7 +566,7 @@ somehow :c:func:`Py_DECREF` the result, even (especially!) if you are not interested in its value. Before you do this, however, it is important to check that the return value -isn't *NULL*. If it is, the Python function terminated by raising an exception. +isn't ``NULL``. If it is, the Python function terminated by raising an exception. If the C code that called :c:func:`PyObject_CallObject` is called from Python, it should now return an error indication to its Python caller, so the interpreter can print a stack trace, or the calling Python code can handle the exception. @@ -723,7 +723,7 @@ The :c:func:`PyArg_ParseTupleAndKeywords` function is declared as follows:: The *arg* and *format* parameters are identical to those of the :c:func:`PyArg_ParseTuple` function. The *kwdict* parameter is the dictionary of keywords received as the third parameter from the Python runtime. The *kwlist* -parameter is a *NULL*-terminated list of strings which identify the parameters; +parameter is a ``NULL``-terminated list of strings which identify the parameters; the names are matched with the type information from *format* from left to right. On success, :c:func:`PyArg_ParseTupleAndKeywords` returns true, otherwise it returns false and raises an appropriate exception. @@ -1084,32 +1084,32 @@ NULL Pointers ------------- In general, functions that take object references as arguments do not expect you -to pass them *NULL* pointers, and will dump core (or cause later core dumps) if -you do so. Functions that return object references generally return *NULL* only -to indicate that an exception occurred. The reason for not testing for *NULL* +to pass them ``NULL`` pointers, and will dump core (or cause later core dumps) if +you do so. Functions that return object references generally return ``NULL`` only +to indicate that an exception occurred. The reason for not testing for ``NULL`` arguments is that functions often pass the objects they receive on to other -function --- if each function were to test for *NULL*, there would be a lot of +function --- if each function were to test for ``NULL``, there would be a lot of redundant tests and the code would run more slowly. -It is better to test for *NULL* only at the "source:" when a pointer that may be -*NULL* is received, for example, from :c:func:`malloc` or from a function that +It is better to test for ``NULL`` only at the "source:" when a pointer that may be +``NULL`` is received, for example, from :c:func:`malloc` or from a function that may raise an exception. -The macros :c:func:`Py_INCREF` and :c:func:`Py_DECREF` do not check for *NULL* +The macros :c:func:`Py_INCREF` and :c:func:`Py_DECREF` do not check for ``NULL`` pointers --- however, their variants :c:func:`Py_XINCREF` and :c:func:`Py_XDECREF` do. The macros for checking for a particular object type (``Pytype_Check()``) don't -check for *NULL* pointers --- again, there is much code that calls several of +check for ``NULL`` pointers --- again, there is much code that calls several of these in a row to test an object against various different expected types, and -this would generate redundant tests. There are no variants with *NULL* +this would generate redundant tests. There are no variants with ``NULL`` checking. The C function calling mechanism guarantees that the argument list passed to C -functions (``args`` in the examples) is never *NULL* --- in fact it guarantees +functions (``args`` in the examples) is never ``NULL`` --- in fact it guarantees that it is always a tuple [#]_. -It is a severe error to ever let a *NULL* pointer "escape" to the Python user. +It is a severe error to ever let a ``NULL`` pointer "escape" to the Python user. .. Frank Stajano: A pedagogically buggy example, along the lines of the previous listing, would @@ -1184,7 +1184,7 @@ different ways between the module providing the code and the client modules. Whichever method you choose, it's important to name your Capsules properly. The function :c:func:`PyCapsule_New` takes a name parameter -(:c:type:`const char \*`); you're permitted to pass in a *NULL* name, but +(:c:type:`const char \*`); you're permitted to pass in a ``NULL`` name, but we strongly encourage you to specify a name. Properly named Capsules provide a degree of runtime type-safety; there is no feasible way to tell one unnamed Capsule from another. diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst index d0d2ec1..315300e 100644 --- a/Doc/extending/newtypes.rst +++ b/Doc/extending/newtypes.rst @@ -189,7 +189,7 @@ For every object which can support attributes, the corresponding type must provide the functions that control how the attributes are resolved. There needs to be a function which can retrieve attributes (if any are defined), and another to set attributes (if setting attributes is allowed). Removing an attribute is -a special case, for which the new value passed to the handler is *NULL*. +a special case, for which the new value passed to the handler is ``NULL``. Python supports two pairs of attribute handlers; a type that supports attributes only needs to implement the functions for one pair. The difference is that one @@ -231,9 +231,9 @@ attributes, when the values are computed, or how relevant data is stored. When :c:func:`PyType_Ready` is called, it uses three tables referenced by the type object to create :term:`descriptor`\s which are placed in the dictionary of the type object. Each descriptor controls access to one attribute of the instance -object. Each of the tables is optional; if all three are *NULL*, instances of +object. Each of the tables is optional; if all three are ``NULL``, instances of the type will only have attributes that are inherited from their base type, and -should leave the :c:member:`~PyTypeObject.tp_getattro` and :c:member:`~PyTypeObject.tp_setattro` fields *NULL* as +should leave the :c:member:`~PyTypeObject.tp_getattro` and :c:member:`~PyTypeObject.tp_setattro` fields ``NULL`` as well, allowing the base type to handle attributes. The tables are declared as three fields of the type object:: @@ -242,7 +242,7 @@ The tables are declared as three fields of the type object:: struct PyMemberDef *tp_members; struct PyGetSetDef *tp_getset; -If :c:member:`~PyTypeObject.tp_methods` is not *NULL*, it must refer to an array of +If :c:member:`~PyTypeObject.tp_methods` is not ``NULL``, it must refer to an array of :c:type:`PyMethodDef` structures. Each entry in the table is an instance of this structure:: @@ -256,7 +256,7 @@ structure:: One entry should be defined for each method provided by the type; no entries are needed for methods inherited from a base type. One additional entry is needed at the end; it is a sentinel that marks the end of the array. The -:attr:`ml_name` field of the sentinel must be *NULL*. +:attr:`ml_name` field of the sentinel must be ``NULL``. The second table is used to define attributes which map directly to data stored in the instance. A variety of primitive C types are supported, and access may @@ -305,7 +305,7 @@ application can use the introspection API to retrieve the descriptor from the class object, and get the doc string using its :attr:`__doc__` attribute. As with the :c:member:`~PyTypeObject.tp_methods` table, a sentinel entry with a :attr:`name` value -of *NULL* is required. +of ``NULL`` is required. .. XXX Descriptors need to be explained in more detail somewhere, but not here. @@ -350,9 +350,9 @@ Here is an example:: The :c:member:`~PyTypeObject.tp_setattr` handler is called when the :meth:`__setattr__` or :meth:`__delattr__` method of a class instance would be called. When an -attribute should be deleted, the third parameter will be *NULL*. Here is an +attribute should be deleted, the third parameter will be ``NULL``. Here is an example that simply raises an exception; if this were really all you wanted, the -:c:member:`~PyTypeObject.tp_setattr` handler should be set to *NULL*. :: +:c:member:`~PyTypeObject.tp_setattr` handler should be set to ``NULL``. :: static int newdatatype_setattr(newdatatypeobject *obj, char *name, PyObject *v) @@ -378,7 +378,7 @@ where the operator is one of ``Py_EQ``, ``Py_NE``, ``Py_LE``, ``Py_GT``, ``Py_LT`` or ``Py_GT``. It should compare the two objects with respect to the specified operator and return ``Py_True`` or ``Py_False`` if the comparison is successful, ``Py_NotImplemented`` to indicate that comparison is not -implemented and the other object's comparison method should be tried, or *NULL* +implemented and the other object's comparison method should be tried, or ``NULL`` if an exception was set. Here is a sample implementation, for a datatype that is considered equal if the @@ -425,7 +425,7 @@ from the type implementation, the older protocols have been defined as optional blocks of handlers referenced by the type object. For newer protocols there are additional slots in the main type object, with a flag bit being set to indicate that the slots are present and should be checked by the interpreter. (The flag -bit does not indicate that the slot values are non-*NULL*. The flag may be set +bit does not indicate that the slot values are non-``NULL``. The flag may be set to indicate the presence of a slot, but a slot may still be unfilled.) :: PyNumberMethods *tp_as_number; @@ -476,9 +476,9 @@ This function takes three arguments: :c:func:`PyArg_ParseTuple` to extract the arguments. #. *kwds* is a dictionary of keyword arguments that were passed. If this is - non-*NULL* and you support keyword arguments, use + non-``NULL`` and you support keyword arguments, use :c:func:`PyArg_ParseTupleAndKeywords` to extract the arguments. If you - do not want to support keyword arguments and this is non-*NULL*, raise a + do not want to support keyword arguments and this is non-``NULL``, raise a :exc:`TypeError` with a message saying that keyword arguments are not supported. Here is a toy ``tp_call`` implementation:: @@ -510,7 +510,7 @@ Here is a toy ``tp_call`` implementation:: These functions provide support for the iterator protocol. Both handlers take exactly one parameter, the instance for which they are being called, and return a new reference. In the case of an error, they should set an -exception and return *NULL*. :c:member:`~PyTypeObject.tp_iter` corresponds +exception and return ``NULL``. :c:member:`~PyTypeObject.tp_iter` corresponds to the Python :meth:`__iter__` method, while :c:member:`~PyTypeObject.tp_iternext` corresponds to the Python :meth:`~iterator.__next__` method. @@ -532,11 +532,11 @@ and :c:member:`~PyTypeObject.tp_iternext`. An iterator's to the iterator. Its :c:member:`~PyTypeObject.tp_iternext` handler should return a new reference to the next object in the iteration, if there is one. If the iteration has reached the end, :c:member:`~PyTypeObject.tp_iternext` -may return *NULL* without setting an exception, or it may set -:exc:`StopIteration` *in addition* to returning *NULL*; avoiding +may return ``NULL`` without setting an exception, or it may set +:exc:`StopIteration` *in addition* to returning ``NULL``; avoiding the exception can yield slightly better performance. If an actual error occurs, :c:member:`~PyTypeObject.tp_iternext` should always set an exception -and return *NULL*. +and return ``NULL``. .. _weakref-support: @@ -555,7 +555,7 @@ For an object to be weakly referencable, the extension type must do two things: #. Include a :c:type:`PyObject\*` field in the C object structure dedicated to the weak reference mechanism. The object's constructor should leave it - *NULL* (which is automatic when using the default + ``NULL`` (which is automatic when using the default :c:member:`~PyTypeObject.tp_alloc`). #. Set the :c:member:`~PyTypeObject.tp_weaklistoffset` type member @@ -580,7 +580,7 @@ And the corresponding member in the statically-declared type object:: The only further addition is that ``tp_dealloc`` needs to clear any weak references (by calling :c:func:`PyObject_ClearWeakRefs`) if the field is -non-*NULL*:: +non-``NULL``:: static void Trivial_dealloc(TrivialObject *self) diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst index 50be28f..b314e9e 100644 --- a/Doc/extending/newtypes_tutorial.rst +++ b/Doc/extending/newtypes_tutorial.rst @@ -177,7 +177,7 @@ Everything else in the file should be familiar, except for some code in This initializes the :class:`Custom` type, filling in a number of members to the appropriate default values, including :attr:`ob_type` that we initially -set to *NULL*. :: +set to ``NULL``. :: Py_INCREF(&CustomType); if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) { @@ -275,7 +275,7 @@ which is assigned to the :c:member:`~PyTypeObject.tp_dealloc` member:: This method first clears the reference counts of the two Python attributes. :c:func:`Py_XDECREF` correctly handles the case where its argument is -*NULL* (which might happen here if ``tp_new`` failed midway). It then +``NULL`` (which might happen here if ``tp_new`` failed midway). It then calls the :c:member:`~PyTypeObject.tp_free` member of the object's type (computed by ``Py_TYPE(self)``) to free the object's memory. Note that the object's type might not be :class:`CustomType`, because the object may @@ -321,7 +321,7 @@ objects of the type. It is exposed in Python as the :meth:`__new__` method. It is not required to define a ``tp_new`` member, and indeed many extension types will simply reuse :c:func:`PyType_GenericNew` as done in the first version of the ``Custom`` type above. In this case, we use the ``tp_new`` -handler to initialize the ``first`` and ``last`` attributes to non-*NULL* +handler to initialize the ``first`` and ``last`` attributes to non-``NULL`` default values. ``tp_new`` is passed the type being instantiated (not necessarily ``CustomType``, @@ -341,7 +341,7 @@ slot to allocate memory:: self = (CustomObject *) type->tp_alloc(type, 0); Since memory allocation may fail, we must check the :c:member:`~PyTypeObject.tp_alloc` -result against *NULL* before proceeding. +result against ``NULL`` before proceeding. .. note:: We didn't fill the :c:member:`~PyTypeObject.tp_alloc` slot ourselves. Rather @@ -455,9 +455,9 @@ below for details. A disadvantage of this approach is that it doesn't provide a way to restrict the types of objects that can be assigned to the Python attributes. We expect the first and last names to be strings, but any Python objects can be assigned. -Further, the attributes can be deleted, setting the C pointers to *NULL*. Even -though we can make sure the members are initialized to non-*NULL* values, the -members can be set to *NULL* if the attributes are deleted. +Further, the attributes can be deleted, setting the C pointers to ``NULL``. Even +though we can make sure the members are initialized to non-``NULL`` values, the +members can be set to ``NULL`` if the attributes are deleted. We define a single method, :meth:`Custom.name()`, that outputs the objects name as the concatenation of the first and last names. :: @@ -489,8 +489,8 @@ equivalent to the Python method: return "%s %s" % (self.first, self.last) Note that we have to check for the possibility that our :attr:`first` and -:attr:`last` members are *NULL*. This is because they can be deleted, in which -case they are set to *NULL*. It would be better to prevent deletion of these +:attr:`last` members are ``NULL``. This is because they can be deleted, in which +case they are set to ``NULL``. It would be better to prevent deletion of these attributes and to restrict the attribute values to be strings. We'll see how to do that in the next section. @@ -584,7 +584,7 @@ could, for example, be used to allow a single set of getter and setter functions that decide the attribute to get or set based on data in the closure.) The setter function is passed the :class:`Custom` object, the new value, and the -closure. The new value may be *NULL*, in which case the attribute is being +closure. The new value may be ``NULL``, in which case the attribute is being deleted. In our setter, we raise an error if the attribute is deleted or if its new value is not a string. @@ -603,7 +603,7 @@ and register it in the :c:member:`~PyTypeObject.tp_getset` slot:: .tp_getset = Custom_getsetters, The last item in a :c:type:`PyGetSetDef` structure is the "closure" mentioned -above. In this case, we aren't using a closure, so we just pass *NULL*. +above. In this case, we aren't using a closure, so we just pass ``NULL``. We also remove the member definitions for these attributes:: @@ -643,7 +643,7 @@ allow strings [#]_ to be passed:: } With these changes, we can assure that the ``first`` and ``last`` members are -never *NULL* so we can remove checks for *NULL* values in almost all cases. +never ``NULL`` so we can remove checks for ``NULL`` values in almost all cases. This means that most of the :c:func:`Py_XDECREF` calls can be converted to :c:func:`Py_DECREF` calls. The only place we can't change these calls is in the ``tp_dealloc`` implementation, where there is the possibility that the @@ -749,7 +749,7 @@ participate in cycles:: Notice the use of the :c:func:`Py_CLEAR` macro. It is the recommended and safe way to clear data attributes of arbitrary types while decrementing their reference counts. If you were to call :c:func:`Py_XDECREF` instead -on the attribute before setting it to *NULL*, there is a possibility +on the attribute before setting it to ``NULL``, there is a possibility that the attribute's destructor would call back into code that reads the attribute again (*especially* if there is a reference cycle). diff --git a/Doc/faq/extending.rst b/Doc/faq/extending.rst index 2ad2765..aecb56e 100644 --- a/Doc/faq/extending.rst +++ b/Doc/faq/extending.rst @@ -89,7 +89,7 @@ For bytes, :c:func:`PyBytes_Size` returns its length and length. Note that Python bytes objects may contain null bytes so C's :c:func:`strlen` should not be used. -To test the type of an object, first make sure it isn't *NULL*, and then use +To test the type of an object, first make sure it isn't ``NULL``, and then use :c:func:`PyBytes_Check`, :c:func:`PyTuple_Check`, :c:func:`PyList_Check`, etc. There is also a high-level API to Python objects which is provided by the diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 695fbb1..ab5f0e4 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1064,7 +1064,7 @@ Currently Argument Clinic supports only a few return converters: DecodeFSDefault None of these take parameters. For the first three, return -1 to indicate -error. For ``DecodeFSDefault``, the return type is ``const char *``; return a NULL +error. For ``DecodeFSDefault``, the return type is ``const char *``; return a ``NULL`` pointer to indicate an error. (There's also an experimental ``NoneType`` converter, which lets you diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index a9222ab..6ab1e39 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -2584,3 +2584,399 @@ In this case, the message #5 printed to ``stdout`` doesn't appear, as expected. Of course, the approach described here can be generalised, for example to attach logging filters temporarily. Note that the above code works in Python 2 as well as Python 3. + + +.. _starter-template: + +A CLI application starter template +---------------------------------- + +Here's an example which shows how you can: + +* Use a logging level based on command-line arguments +* Dispatch to multiple subcommands in separate files, all logging at the same + level in a consistent way +* Make use of simple, minimal configuration + +Suppose we have a command-line application whose job is to stop, start or +restart some services. This could be organised for the purposes of illustration +as a file ``app.py`` that is the main script for the application, with individual +commands implemented in ``start.py``, ``stop.py`` and ``restart.py``. Suppose +further that we want to control the verbosity of the application via a +command-line argument, defaulting to ``logging.INFO``. Here's one way that +``app.py`` could be written:: + + import argparse + import importlib + import logging + import os + import sys + + def main(args=None): + scriptname = os.path.basename(__file__) + parser = argparse.ArgumentParser(scriptname) + levels = ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL') + parser.add_argument('--log-level', default='INFO', choices=levels) + subparsers = parser.add_subparsers(dest='command', + help='Available commands:') + start_cmd = subparsers.add_parser('start', help='Start a service') + start_cmd.add_argument('name', metavar='NAME', + help='Name of service to start') + stop_cmd = subparsers.add_parser('stop', + help='Stop one or more services') + stop_cmd.add_argument('names', metavar='NAME', nargs='+', + help='Name of service to stop') + restart_cmd = subparsers.add_parser('restart', + help='Restart one or more services') + restart_cmd.add_argument('names', metavar='NAME', nargs='+', + help='Name of service to restart') + options = parser.parse_args() + # the code to dispatch commands could all be in this file. For the purposes + # of illustration only, we implement each command in a separate module. + try: + mod = importlib.import_module(options.command) + cmd = getattr(mod, 'command') + except (ImportError, AttributeError): + print('Unable to find the code for command \'%s\'' % options.command) + return 1 + # Could get fancy here and load configuration from file or dictionary + logging.basicConfig(level=options.log_level, + format='%(levelname)s %(name)s %(message)s') + cmd(options) + + if __name__ == '__main__': + sys.exit(main()) + +And the ``start``, ``stop`` and ``restart`` commands can be implemented in +separate modules, like so for starting:: + + # start.py + import logging + + logger = logging.getLogger(__name__) + + def command(options): + logger.debug('About to start %s', options.name) + # actually do the command processing here ... + logger.info('Started the \'%s\' service.', options.name) + +and thus for stopping:: + + # stop.py + import logging + + logger = logging.getLogger(__name__) + + def command(options): + n = len(options.names) + if n == 1: + plural = '' + services = '\'%s\'' % options.names[0] + else: + plural = 's' + services = ', '.join('\'%s\'' % name for name in options.names) + i = services.rfind(', ') + services = services[:i] + ' and ' + services[i + 2:] + logger.debug('About to stop %s', services) + # actually do the command processing here ... + logger.info('Stopped the %s service%s.', services, plural) + +and similarly for restarting:: + + # restart.py + import logging + + logger = logging.getLogger(__name__) + + def command(options): + n = len(options.names) + if n == 1: + plural = '' + services = '\'%s\'' % options.names[0] + else: + plural = 's' + services = ', '.join('\'%s\'' % name for name in options.names) + i = services.rfind(', ') + services = services[:i] + ' and ' + services[i + 2:] + logger.debug('About to restart %s', services) + # actually do the command processing here ... + logger.info('Restarted the %s service%s.', services, plural) + +If we run this application with the default log level, we get output like this: + +.. code-block:: shell-session + + $ python app.py start foo + INFO start Started the 'foo' service. + + $ python app.py stop foo bar + INFO stop Stopped the 'foo' and 'bar' services. + + $ python app.py restart foo bar baz + INFO restart Restarted the 'foo', 'bar' and 'baz' services. + +The first word is the logging level, and the second word is the module or +package name of the place where the event was logged. + +If we change the logging level, then we can change the information sent to the +log. For example, if we want more information: + +.. code-block:: shell-session + + $ python app.py --log-level DEBUG start foo + DEBUG start About to start foo + INFO start Started the 'foo' service. + + $ python app.py --log-level DEBUG stop foo bar + DEBUG stop About to stop 'foo' and 'bar' + INFO stop Stopped the 'foo' and 'bar' services. + + $ python app.py --log-level DEBUG restart foo bar baz + DEBUG restart About to restart 'foo', 'bar' and 'baz' + INFO restart Restarted the 'foo', 'bar' and 'baz' services. + +And if we want less: + +.. code-block:: shell-session + + $ python app.py --log-level WARNING start foo + $ python app.py --log-level WARNING stop foo bar + $ python app.py --log-level WARNING restart foo bar baz + +In this case, the commands don't print anything to the console, since nothing +at ``WARNING`` level or above is logged by them. + +.. _qt-gui: + +A Qt GUI for logging +-------------------- + +A question that comes up from time to time is about how to log to a GUI +application. The `Qt `_ framework is a popular +cross-platform UI framework with Python bindings using `PySide2 +`_ or `PyQt5 +`_ libraries. + +The following example shows how to log to a Qt GUI. This introduces a simple +``QtHandler`` class which takes a callable, which should be a slot in the main +thread that does GUI updates. A worker thread is also created to show how you +can log to the GUI from both the UI itself (via a button for manual logging) +as well as a worker thread doing work in the background (here, just logging +messages at random levels with random short delays in between). + +The worker thread is implemented using Qt's ``QThread`` class rather than the +:mod:`threading` module, as there are circumstances where one has to use +``QThread``, which offers better integration with other ``Qt`` components. + +The code should work with recent releases of either ``PySide2`` or ``PyQt5``. +You should be able to adapt the approach to earlier versions of Qt. Please +refer to the comments in the code snippet for more detailed information. + +.. code-block:: python3 + + import datetime + import logging + import random + import sys + import time + + # Deal with minor differences between PySide2 and PyQt5 + try: + from PySide2 import QtCore, QtGui, QtWidgets + Signal = QtCore.Signal + Slot = QtCore.Slot + except ImportError: + from PyQt5 import QtCore, QtGui, QtWidgets + Signal = QtCore.pyqtSignal + Slot = QtCore.pyqtSlot + + + logger = logging.getLogger(__name__) + + + # + # Signals need to be contained in a QObject or subclass in order to be correctly + # initialized. + # + class Signaller(QtCore.QObject): + signal = Signal(str, logging.LogRecord) + + # + # Output to a Qt GUI is only supposed to happen on the main thread. So, this + # handler is designed to take a slot function which is set up to run in the main + # thread. In this example, the function takes a string argument which is a + # formatted log message, and the log record which generated it. The formatted + # string is just a convenience - you could format a string for output any way + # you like in the slot function itself. + # + # You specify the slot function to do whatever GUI updates you want. The handler + # doesn't know or care about specific UI elements. + # + class QtHandler(logging.Handler): + def __init__(self, slotfunc, *args, **kwargs): + super(QtHandler, self).__init__(*args, **kwargs) + self.signaller = Signaller() + self.signaller.signal.connect(slotfunc) + + def emit(self, record): + s = self.format(record) + self.signaller.signal.emit(s, record) + + # + # This example uses QThreads, which means that the threads at the Python level + # are named something like "Dummy-1". The function below gets the Qt name of the + # current thread. + # + def ctname(): + return QtCore.QThread.currentThread().objectName() + + + # + # Used to generate random levels for logging. + # + LEVELS = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, + logging.CRITICAL) + + # + # This worker class represents work that is done in a thread separate to the + # main thread. The way the thread is kicked off to do work is via a button press + # that connects to a slot in the worker. + # + # Because the default threadName value in the LogRecord isn't much use, we add + # a qThreadName which contains the QThread name as computed above, and pass that + # value in an "extra" dictionary which is used to update the LogRecord with the + # QThread name. + # + # This example worker just outputs messages sequentially, interspersed with + # random delays of the order of a few seconds. + # + class Worker(QtCore.QObject): + @Slot() + def start(self): + extra = {'qThreadName': ctname() } + logger.debug('Started work', extra=extra) + i = 1 + # Let the thread run until interrupted. This allows reasonably clean + # thread termination. + while not QtCore.QThread.currentThread().isInterruptionRequested(): + delay = 0.5 + random.random() * 2 + time.sleep(delay) + level = random.choice(LEVELS) + logger.log(level, 'Message after delay of %3.1f: %d', delay, i, extra=extra) + i += 1 + + # + # Implement a simple UI for this cookbook example. This contains: + # + # * A read-only text edit window which holds formatted log messages + # * A button to start work and log stuff in a separate thread + # * A button to log something from the main thread + # * A button to clear the log window + # + class Window(QtWidgets.QWidget): + + COLORS = { + logging.DEBUG: 'black', + logging.INFO: 'blue', + logging.WARNING: 'orange', + logging.ERROR: 'red', + logging.CRITICAL: 'purple', + } + + def __init__(self, app): + super(Window, self).__init__() + self.app = app + self.textedit = te = QtWidgets.QPlainTextEdit(self) + # Set whatever the default monospace font is for the platform + f = QtGui.QFont('nosuchfont') + f.setStyleHint(f.Monospace) + te.setFont(f) + te.setReadOnly(True) + PB = QtWidgets.QPushButton + self.work_button = PB('Start background work', self) + self.log_button = PB('Log a message at a random level', self) + self.clear_button = PB('Clear log window', self) + self.handler = h = QtHandler(self.update_status) + # Remember to use qThreadName rather than threadName in the format string. + fs = '%(asctime)s %(qThreadName)-12s %(levelname)-8s %(message)s' + formatter = logging.Formatter(fs) + h.setFormatter(formatter) + logger.addHandler(h) + # Set up to terminate the QThread when we exit + app.aboutToQuit.connect(self.force_quit) + + # Lay out all the widgets + layout = QtWidgets.QVBoxLayout(self) + layout.addWidget(te) + layout.addWidget(self.work_button) + layout.addWidget(self.log_button) + layout.addWidget(self.clear_button) + self.setFixedSize(900, 400) + + # Connect the non-worker slots and signals + self.log_button.clicked.connect(self.manual_update) + self.clear_button.clicked.connect(self.clear_display) + + # Start a new worker thread and connect the slots for the worker + self.start_thread() + self.work_button.clicked.connect(self.worker.start) + # Once started, the button should be disabled + self.work_button.clicked.connect(lambda : self.work_button.setEnabled(False)) + + def start_thread(self): + self.worker = Worker() + self.worker_thread = QtCore.QThread() + self.worker.setObjectName('Worker') + self.worker_thread.setObjectName('WorkerThread') # for qThreadName + self.worker.moveToThread(self.worker_thread) + # This will start an event loop in the worker thread + self.worker_thread.start() + + def kill_thread(self): + # Just tell the worker to stop, then tell it to quit and wait for that + # to happen + self.worker_thread.requestInterruption() + if self.worker_thread.isRunning(): + self.worker_thread.quit() + self.worker_thread.wait() + else: + print('worker has already exited.') + + def force_quit(self): + # For use when the window is closed + if self.worker_thread.isRunning(): + self.kill_thread() + + # The functions below update the UI and run in the main thread because + # that's where the slots are set up + + @Slot(str, logging.LogRecord) + def update_status(self, status, record): + color = self.COLORS.get(record.levelno, 'black') + s = '
%s
' % (color, status) + self.textedit.appendHtml(s) + + @Slot() + def manual_update(self): + # This function uses the formatted message passed in, but also uses + # information from the record to format the message in an appropriate + # color according to its severity (level). + level = random.choice(LEVELS) + extra = {'qThreadName': ctname() } + logger.log(level, 'Manually logged!', extra=extra) + + @Slot() + def clear_display(self): + self.textedit.clear() + + + def main(): + QtCore.QThread.currentThread().setObjectName('MainThread') + logging.getLogger().setLevel(logging.DEBUG) + app = QtWidgets.QApplication(sys.argv) + example = Window(app) + example.show() + sys.exit(app.exec_()) + + if __name__=='__main__': + main() diff --git a/Doc/includes/email-dir.py b/Doc/includes/email-dir.py index 0dcfbfb..2fc1570 100644 --- a/Doc/includes/email-dir.py +++ b/Doc/includes/email-dir.py @@ -41,7 +41,7 @@ must be running an SMTP server. directory = '.' # Create the message msg = EmailMessage() - msg['Subject'] = 'Contents of directory %s' % os.path.abspath(directory) + msg['Subject'] = f'Contents of directory {os.path.abspath(directory)}' msg['To'] = ', '.join(args.recipients) msg['From'] = args.sender msg.preamble = 'You will not see this in a MIME-aware mail reader.\n' diff --git a/Doc/includes/email-simple.py b/Doc/includes/email-simple.py index f69ef40..07dc30f 100644 --- a/Doc/includes/email-simple.py +++ b/Doc/includes/email-simple.py @@ -12,7 +12,7 @@ with open(textfile) as fp: # me == the sender's email address # you == the recipient's email address -msg['Subject'] = 'The contents of %s' % textfile +msg['Subject'] = f'The contents of {textfile}' msg['From'] = me msg['To'] = you diff --git a/Doc/includes/email-unpack.py b/Doc/includes/email-unpack.py index e0a7f01..c8cb0be 100644 --- a/Doc/includes/email-unpack.py +++ b/Doc/includes/email-unpack.py @@ -43,7 +43,7 @@ Unpack a MIME message into a directory of files. if not ext: # Use a generic bag-of-bits extension ext = '.bin' - filename = 'part-%03d%s' % (counter, ext) + filename = f'part-{counter:03d}{ext}' counter += 1 with open(os.path.join(args.directory, filename), 'wb') as fp: fp.write(part.get_payload(decode=True)) diff --git a/Doc/installing/index.rst b/Doc/installing/index.rst index 8af828b..c1a9a1f 100644 --- a/Doc/installing/index.rst +++ b/Doc/installing/index.rst @@ -53,7 +53,7 @@ Key terms evolution of the standard packaging tools and the associated metadata and file format standards. They maintain a variety of tools, documentation, and issue trackers on both `GitHub `__ and - `BitBucket `__. + `Bitbucket `__. * ``distutils`` is the original build and distribution system first added to the Python standard library in 1998. While direct use of ``distutils`` is being phased out, it still laid the foundation for the current packaging diff --git a/Doc/library/2to3.rst b/Doc/library/2to3.rst index fa4b0a9..c3ff3e6 100644 --- a/Doc/library/2to3.rst +++ b/Doc/library/2to3.rst @@ -456,7 +456,7 @@ and off individually. They are described here in more detail. ------------------------------- .. module:: lib2to3 - :synopsis: the 2to3 library + :synopsis: The 2to3 library .. moduleauthor:: Guido van Rossum .. moduleauthor:: Collin Winter diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index a2baa07..4a24c26 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -778,10 +778,12 @@ how the command-line arguments should be handled. The supplied actions are: example, this is useful for increasing verbosity levels:: >>> parser = argparse.ArgumentParser() - >>> parser.add_argument('--verbose', '-v', action='count') + >>> parser.add_argument('--verbose', '-v', action='count', default=0) >>> parser.parse_args(['-vvv']) Namespace(verbose=3) + Note, the *default* will be ``None`` unless explicitly set to *0*. + * ``'help'`` - This prints a complete help message for all the options in the current parser and then exits. By default a help action is automatically added to the parser. See :class:`ArgumentParser` for details of how the diff --git a/Doc/library/array.rst b/Doc/library/array.rst index 0da6b48..901a135 100644 --- a/Doc/library/array.rst +++ b/Doc/library/array.rst @@ -172,6 +172,8 @@ The following data items and methods are also supported: Deprecated alias for :meth:`frombytes`. + .. deprecated-removed:: 3.2 3.9 + .. method:: array.fromunicode(s) @@ -234,6 +236,8 @@ The following data items and methods are also supported: Deprecated alias for :meth:`tobytes`. + .. deprecated-removed:: 3.2 3.9 + .. method:: array.tounicode() diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 7e1d571..d8e1a74 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -429,6 +429,21 @@ Opening network connections reuse_address=None, reuse_port=None, \ allow_broadcast=None, sock=None) + .. note:: + The parameter *reuse_address* is no longer supported, as using + :py:data:`~sockets.SO_REUSEADDR` poses a significant security concern for + UDP. Explicitly passing ``reuse_address=True`` will raise an exception. + + When multiple processes with differing UIDs assign sockets to an + indentical UDP socket address with ``SO_REUSEADDR``, incoming packets can + become randomly distributed among the sockets. + + For supported platforms, *reuse_port* can be used as a replacement for + similar functionality. With *reuse_port*, + :py:data:`~sockets.SO_REUSEPORT` is used instead, which specifically + prevents processes with differing UIDs from assigning sockets to the same + socket address. + Create a datagram connection. The socket family can be either :py:data:`~socket.AF_INET`, @@ -457,11 +472,6 @@ Opening network connections resolution. If given, these should all be integers from the corresponding :mod:`socket` module constants. - * *reuse_address* tells the kernel to reuse a local socket in - ``TIME_WAIT`` state, without waiting for its natural timeout to - expire. If not specified will automatically be set to ``True`` on - Unix. - * *reuse_port* tells the kernel to allow this endpoint to be bound to the same port as other existing endpoints are bound to, so long as they all set this flag when being created. This option is not supported on Windows @@ -485,6 +495,10 @@ Opening network connections The *family*, *proto*, *flags*, *reuse_address*, *reuse_port, *allow_broadcast*, and *sock* parameters were added. + .. versionchanged:: 3.7.6 + The *reuse_address* parameter is no longer supported due to security + concerns. + .. coroutinemethod:: loop.create_unix_connection(protocol_factory, \ path=None, \*, ssl=None, sock=None, \ server_hostname=None, ssl_handshake_timeout=None) diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst index 42b4c1f..2546265 100644 --- a/Doc/library/asyncio-stream.rst +++ b/Doc/library/asyncio-stream.rst @@ -229,8 +229,8 @@ StreamWriter .. method:: can_write_eof() - Return *True* if the underlying transport supports - the :meth:`write_eof` method, *False* otherwise. + Return ``True`` if the underlying transport supports + the :meth:`write_eof` method, ``False`` otherwise. .. method:: write_eof() diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index e9dbd09..6488b12 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -162,7 +162,7 @@ environment variables which in turn take precedence over default values:: parser.add_argument('-u', '--user') parser.add_argument('-c', '--color') namespace = parser.parse_args() - command_line_args = {k:v for k, v in vars(namespace).items() if v} + command_line_args = {k: v for k, v in vars(namespace).items() if v is not None} combined = ChainMap(command_line_args, os.environ, defaults) print(combined['color']) diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 2eafa65..b4f989d 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -152,8 +152,8 @@ the ``time()`` function, which returns system time in seconds since the Unix epoch, and the ``GetModuleHandleA()`` function, which returns a win32 module handle. -This example calls both functions with a NULL pointer (``None`` should be used -as the NULL pointer):: +This example calls both functions with a ``NULL`` pointer (``None`` should be used +as the ``NULL`` pointer):: >>> print(libc.time(None)) # doctest: +SKIP 1150640792 @@ -1083,7 +1083,7 @@ An extended example which also demonstrates the use of pointers accesses the Quoting the docs for that value: This pointer is initialized to point to an array of :c:type:`struct _frozen` - records, terminated by one whose members are all *NULL* or zero. When a frozen + records, terminated by one whose members are all ``NULL`` or zero. When a frozen module is imported, it is searched in this table. Third-party code could play tricks with this to provide a dynamically created collection of frozen modules. @@ -1110,7 +1110,7 @@ Since ``table`` is a ``pointer`` to the array of ``struct_frozen`` records, we can iterate over it, but we just have to make sure that our loop terminates, because pointers have no size. Sooner or later it would probably crash with an access violation or whatever, so it's better to break out of the loop when we -hit the NULL entry:: +hit the ``NULL`` entry:: >>> for item in table: ... if item.name is None: diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst index 6af60b6..37258d4 100644 --- a/Doc/library/dataclasses.rst +++ b/Doc/library/dataclasses.rst @@ -154,7 +154,7 @@ Module-level decorators, classes, and functions method of the superclass will be used (if the superclass is :class:`object`, this means it will fall back to id-based hashing). - - ``frozen``: If true (the default is False), assigning to fields will + - ``frozen``: If true (the default is ``False``), assigning to fields will generate an exception. This emulates read-only frozen instances. If :meth:`__setattr__` or :meth:`__delattr__` is defined in the class, then :exc:`TypeError` is raised. See the discussion below. @@ -387,8 +387,8 @@ Module-level decorators, classes, and functions .. function:: is_dataclass(class_or_instance) - Returns True if its parameter is a dataclass or an instance of one, - otherwise returns False. + Return ``True`` if its parameter is a dataclass or an instance of one, + otherwise return ``False``. If you need to know if a class is an instance of a dataclass (and not a dataclass itself), then add a further check for ``not diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index e245ab8..1576eb1 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -334,14 +334,14 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. .. function:: IS_LINE_JUNK(line) - Return true for ignorable lines. The line *line* is ignorable if *line* is + Return ``True`` for ignorable lines. The line *line* is ignorable if *line* is blank or contains a single ``'#'``, otherwise it is not ignorable. Used as a default for parameter *linejunk* in :func:`ndiff` in older versions. .. function:: IS_CHARACTER_JUNK(ch) - Return true for ignorable characters. The character *ch* is ignorable if *ch* + Return ``True`` for ignorable characters. The character *ch* is ignorable if *ch* is a space or tab, otherwise it is not ignorable. Used as a default for parameter *charjunk* in :func:`ndiff`. @@ -366,7 +366,7 @@ The :class:`SequenceMatcher` class has this constructor: Optional argument *isjunk* must be ``None`` (the default) or a one-argument function that takes a sequence element and returns true if and only if the element is "junk" and should be ignored. Passing ``None`` for *isjunk* is - equivalent to passing ``lambda x: 0``; in other words, no elements are ignored. + equivalent to passing ``lambda x: False``; in other words, no elements are ignored. For example, pass:: lambda x: x in " \t" diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index e7c0033..3e5e101 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -1531,7 +1531,7 @@ OutputChecker objects A class used to check the whether the actual output from a doctest example matches the expected output. :class:`OutputChecker` defines two methods: - :meth:`check_output`, which compares a given pair of outputs, and returns true + :meth:`check_output`, which compares a given pair of outputs, and returns ``True`` if they match; and :meth:`output_difference`, which returns a string describing the differences between two outputs. diff --git a/Doc/library/email.compat32-message.rst b/Doc/library/email.compat32-message.rst index 09ea64a..745b3a6 100644 --- a/Doc/library/email.compat32-message.rst +++ b/Doc/library/email.compat32-message.rst @@ -308,7 +308,7 @@ Here are the methods of the :class:`Message` class: .. method:: __contains__(name) - Return true if the message object has a field named *name*. Matching is + Return ``True`` if the message object has a field named *name*. Matching is done case-insensitively and *name* should not include the trailing colon. Used for the ``in`` operator, e.g.:: diff --git a/Doc/library/email.errors.rst b/Doc/library/email.errors.rst index 511ad16..f4b9f52 100644 --- a/Doc/library/email.errors.rst +++ b/Doc/library/email.errors.rst @@ -99,7 +99,7 @@ All defect classes are subclassed from :class:`email.errors.MessageDefect`. * :class:`MultipartInvariantViolationDefect` -- A message claimed to be a :mimetype:`multipart`, but no subparts were found. Note that when a message has this defect, its :meth:`~email.message.Message.is_multipart` method may - return false even though its content type claims to be :mimetype:`multipart`. + return ``False`` even though its content type claims to be :mimetype:`multipart`. * :class:`InvalidBase64PaddingDefect` -- When decoding a block of base64 encoded bytes, the padding was not correct. Enough padding is added to diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst index 77b8099..6c07e57 100644 --- a/Doc/library/email.message.rst +++ b/Doc/library/email.message.rst @@ -178,7 +178,7 @@ message objects. .. method:: __contains__(name) - Return true if the message object has a field named *name*. Matching is + Return ``True`` if the message object has a field named *name*. Matching is done without regard to case and *name* does not include the trailing colon. Used for the ``in`` operator. For example:: diff --git a/Doc/library/email.utils.rst b/Doc/library/email.utils.rst index 63fae2a..4d0e920 100644 --- a/Doc/library/email.utils.rst +++ b/Doc/library/email.utils.rst @@ -117,8 +117,8 @@ of the new API. a 10-tuple; the first 9 elements make up a tuple that can be passed directly to :func:`time.mktime`, and the tenth is the offset of the date's timezone from UTC (which is the official term for Greenwich Mean Time) [#]_. If the input string - has no timezone, the last element of the tuple returned is ``None``. Note that - indexes 6, 7, and 8 of the result tuple are not usable. + has no timezone, the last element of the tuple returned is ``0``, which represents + UTC. Note that indexes 6, 7, and 8 of the result tuple are not usable. .. function:: parsedate_to_datetime(date) diff --git a/Doc/library/fileinput.rst b/Doc/library/fileinput.rst index bf81749..a21c76d 100644 --- a/Doc/library/fileinput.rst +++ b/Doc/library/fileinput.rst @@ -108,14 +108,14 @@ if there is no active state, :exc:`RuntimeError` is raised. .. function:: isfirstline() - Returns true if the line just read is the first line of its file, otherwise - returns false. + Return ``True`` if the line just read is the first line of its file, otherwise + return ``False``. .. function:: isstdin() - Returns true if the last line was read from ``sys.stdin``, otherwise returns - false. + Return ``True`` if the last line was read from ``sys.stdin``, otherwise return + ``False``. .. function:: nextfile() diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 06ba323..72d82ae 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -178,8 +178,8 @@ are always available. They are listed here in alphabetical order. .. function:: callable(object) Return :const:`True` if the *object* argument appears callable, - :const:`False` if not. If this returns true, it is still possible that a - call fails, but if it is false, calling *object* will never succeed. + :const:`False` if not. If this returns ``True``, it is still possible that a + call fails, but if it is ``False``, calling *object* will never succeed. Note that classes are callable (calling a class returns a new instance); instances are callable if their class has a :meth:`__call__` method. @@ -777,19 +777,19 @@ are always available. They are listed here in alphabetical order. .. function:: isinstance(object, classinfo) - Return true if the *object* argument is an instance of the *classinfo* + Return ``True`` if the *object* argument is an instance of the *classinfo* argument, or of a (direct, indirect or :term:`virtual `) subclass thereof. If *object* is not - an object of the given type, the function always returns false. + an object of the given type, the function always returns ``False``. If *classinfo* is a tuple of type objects (or recursively, other such - tuples), return true if *object* is an instance of any of the types. + tuples), return ``True`` if *object* is an instance of any of the types. If *classinfo* is not a type or tuple of types and such tuples, a :exc:`TypeError` exception is raised. .. function:: issubclass(class, classinfo) - Return true if *class* is a subclass (direct, indirect or :term:`virtual + Return ``True`` if *class* is a subclass (direct, indirect or :term:`virtual `) of *classinfo*. A class is considered a subclass of itself. *classinfo* may be a tuple of class objects, in which case every entry in *classinfo* will be checked. In any other @@ -1173,7 +1173,7 @@ are always available. They are listed here in alphabetical order. * The file is now non-inheritable. - .. deprecated-removed:: 3.4 4.0 + .. deprecated-removed:: 3.4 3.9 The ``'U'`` mode. diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst index 153d8fb..af45581 100644 --- a/Doc/library/gc.rst +++ b/Doc/library/gc.rst @@ -35,7 +35,7 @@ The :mod:`gc` module provides the following functions: .. function:: isenabled() - Returns true if automatic collection is enabled. + Return ``True`` if automatic collection is enabled. .. function:: collect(generation=2) @@ -209,7 +209,7 @@ values but should not rebind them): A list of objects which the collector found to be unreachable but could not be freed (uncollectable objects). Starting with Python 3.4, this list should be empty most of the time, except when using instances of - C extension types with a non-NULL ``tp_del`` slot. + C extension types with a non-``NULL`` ``tp_del`` slot. If :const:`DEBUG_SAVEALL` is set, then all unreachable objects will be added to this list rather than freed. diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst index bc73c7a..d7757d0 100644 --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -20,7 +20,7 @@ HTTPS protocols. It is normally not used directly --- the module .. seealso:: - The `Requests package `_ + The `Requests package `_ is recommended for a higher-level HTTP client interface. .. note:: diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst index 8bacd72..54aca15 100644 --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -369,7 +369,7 @@ methods: .. method:: CookiePolicy.domain_return_ok(domain, request) - Return false if cookies should not be returned, given cookie domain. + Return ``False`` if cookies should not be returned, given cookie domain. This method is an optimization. It removes the need for checking every cookie with a particular domain (which might involve reading many files). Returning @@ -393,7 +393,7 @@ methods: .. method:: CookiePolicy.path_return_ok(path, request) - Return false if cookies should not be returned, given cookie path. + Return ``False`` if cookies should not be returned, given cookie path. See the documentation for :meth:`domain_return_ok`. @@ -702,7 +702,7 @@ accessed using the following methods: .. method:: Cookie.has_nonstandard_attr(name) - Return true if cookie has the named cookie-attribute. + Return ``True`` if cookie has the named cookie-attribute. .. method:: Cookie.get_nonstandard_attr(name, default=None) diff --git a/Doc/library/http.rst b/Doc/library/http.rst index 88d62cc..0deeaf6 100644 --- a/Doc/library/http.rst +++ b/Doc/library/http.rst @@ -38,7 +38,7 @@ associated messages through the :class:`http.HTTPStatus` enum: >>> HTTPStatus.OK == 200 True - >>> http.HTTPStatus.OK.value + >>> HTTPStatus.OK.value 200 >>> HTTPStatus.OK.phrase 'OK' diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 0bd248c..273b583 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -199,7 +199,8 @@ Format Paragraph Strip trailing whitespace Remove trailing space and other whitespace characters after the last non-whitespace character of a line by applying str.rstrip to each line, - including lines within multiline strings. + including lines within multiline strings. Except for Shell windows, + remove extra newlines at the end of the file. .. index:: single: Run script diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 974dbb4..0057eab 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1168,7 +1168,7 @@ find and load modules. .. method:: is_package(fullname) - Return true if :attr:`path` appears to be for a package. + Return ``True`` if :attr:`path` appears to be for a package. .. method:: path_stats(path) diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 18cbacf..d52726d 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -273,39 +273,39 @@ attributes: .. function:: ismodule(object) - Return true if the object is a module. + Return ``True`` if the object is a module. .. function:: isclass(object) - Return true if the object is a class, whether built-in or created in Python + Return ``True`` if the object is a class, whether built-in or created in Python code. .. function:: ismethod(object) - Return true if the object is a bound method written in Python. + Return ``True`` if the object is a bound method written in Python. .. function:: isfunction(object) - Return true if the object is a Python function, which includes functions + Return ``True`` if the object is a Python function, which includes functions created by a :term:`lambda` expression. .. function:: isgeneratorfunction(object) - Return true if the object is a Python generator function. + Return ``True`` if the object is a Python generator function. .. function:: isgenerator(object) - Return true if the object is a generator. + Return ``True`` if the object is a generator. .. function:: iscoroutinefunction(object) - Return true if the object is a :term:`coroutine function` + Return ``True`` if the object is a :term:`coroutine function` (a function defined with an :keyword:`async def` syntax). .. versionadded:: 3.5 @@ -313,7 +313,7 @@ attributes: .. function:: iscoroutine(object) - Return true if the object is a :term:`coroutine` created by an + Return ``True`` if the object is a :term:`coroutine` created by an :keyword:`async def` function. .. versionadded:: 3.5 @@ -321,7 +321,7 @@ attributes: .. function:: isawaitable(object) - Return true if the object can be used in :keyword:`await` expression. + Return ``True`` if the object can be used in :keyword:`await` expression. Can also be used to distinguish generator-based coroutines from regular generators:: @@ -340,7 +340,7 @@ attributes: .. function:: isasyncgenfunction(object) - Return true if the object is an :term:`asynchronous generator` function, + Return ``True`` if the object is an :term:`asynchronous generator` function, for example:: >>> async def agen(): @@ -354,44 +354,44 @@ attributes: .. function:: isasyncgen(object) - Return true if the object is an :term:`asynchronous generator iterator` + Return ``True`` if the object is an :term:`asynchronous generator iterator` created by an :term:`asynchronous generator` function. .. versionadded:: 3.6 .. function:: istraceback(object) - Return true if the object is a traceback. + Return ``True`` if the object is a traceback. .. function:: isframe(object) - Return true if the object is a frame. + Return ``True`` if the object is a frame. .. function:: iscode(object) - Return true if the object is a code. + Return ``True`` if the object is a code. .. function:: isbuiltin(object) - Return true if the object is a built-in function or a bound built-in method. + Return ``True`` if the object is a built-in function or a bound built-in method. .. function:: isroutine(object) - Return true if the object is a user-defined or built-in function or method. + Return ``True`` if the object is a user-defined or built-in function or method. .. function:: isabstract(object) - Return true if the object is an abstract base class. + Return ``True`` if the object is an abstract base class. .. function:: ismethoddescriptor(object) - Return true if the object is a method descriptor, but not if + Return ``True`` if the object is a method descriptor, but not if :func:`ismethod`, :func:`isclass`, :func:`isfunction` or :func:`isbuiltin` are true. @@ -402,14 +402,14 @@ attributes: sensible, and :attr:`__doc__` often is. Methods implemented via descriptors that also pass one of the other tests - return false from the :func:`ismethoddescriptor` test, simply because the + return ``False`` from the :func:`ismethoddescriptor` test, simply because the other tests promise more -- you can, e.g., count on having the :attr:`__func__` attribute (etc) when an object passes :func:`ismethod`. .. function:: isdatadescriptor(object) - Return true if the object is a data descriptor. + Return ``True`` if the object is a data descriptor. Data descriptors have both a :attr:`~object.__get__` and a :attr:`~object.__set__` method. Examples are properties (defined in Python), getsets, and members. The @@ -422,7 +422,7 @@ attributes: .. function:: isgetsetdescriptor(object) - Return true if the object is a getset descriptor. + Return ``True`` if the object is a getset descriptor. .. impl-detail:: @@ -433,7 +433,7 @@ attributes: .. function:: ismemberdescriptor(object) - Return true if the object is a member descriptor. + Return ``True`` if the object is a member descriptor. .. impl-detail:: diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst index b7b502a..140401d 100644 --- a/Doc/library/ipaddress.rst +++ b/Doc/library/ipaddress.rst @@ -557,7 +557,7 @@ dictionaries. .. method:: subnet_of(other) - Returns *True* if this network is a subnet of *other*. + Return ``True`` if this network is a subnet of *other*. >>> a = ip_network('192.168.1.0/24') >>> b = ip_network('192.168.1.128/30') @@ -568,7 +568,7 @@ dictionaries. .. method:: supernet_of(other) - Returns *True* if this network is a supernet of *other*. + Return ``True`` if this network is a supernet of *other*. >>> a = ip_network('192.168.1.0/24') >>> b = ip_network('192.168.1.128/30') diff --git a/Doc/library/keyword.rst b/Doc/library/keyword.rst index 173db23..3768df9 100644 --- a/Doc/library/keyword.rst +++ b/Doc/library/keyword.rst @@ -13,7 +13,7 @@ This module allows a Python program to determine if a string is a keyword. .. function:: iskeyword(s) - Return true if *s* is a Python keyword. + Return ``True`` if *s* is a Python keyword. .. data:: kwlist diff --git a/Doc/library/linecache.rst b/Doc/library/linecache.rst index 34fcac5..8387de4 100644 --- a/Doc/library/linecache.rst +++ b/Doc/library/linecache.rst @@ -2,7 +2,7 @@ ================================================ .. module:: linecache - :synopsis: This module provides random access to individual lines from text files. + :synopsis: Provides random access to individual lines from text files. .. sectionauthor:: Moshe Zadka diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index 0e98704..fa0424d 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -846,8 +846,8 @@ should, then :meth:`flush` is expected to do the flushing. .. method:: emit(record) - Appends the record to the buffer. If :meth:`shouldFlush` returns true, - calls :meth:`flush` to process the buffer. + Append the record to the buffer. If :meth:`shouldFlush` returns true, + call :meth:`flush` to process the buffer. .. method:: flush() @@ -858,7 +858,7 @@ should, then :meth:`flush` is expected to do the flushing. .. method:: shouldFlush(record) - Returns true if the buffer is up to capacity. This method can be + Return ``True`` if the buffer is up to capacity. This method can be overridden to implement custom flushing strategies. diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index cec2f14..f1ab49f 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -283,7 +283,7 @@ is the module's name in the Python package namespace. .. method:: Logger.filter(record) - Applies this logger's filters to the record and returns a true value if the + Apply this logger's filters to the record and return ``True`` if the record is to be processed. The filters are consulted in turn, until one of them returns a false value. If none of them return a false value, the record will be processed (passed to handlers). If one returns a false value, no @@ -429,7 +429,7 @@ subclasses. However, the :meth:`__init__` method in subclasses needs to call .. method:: Handler.filter(record) - Applies this handler's filters to the record and returns a true value if the + Apply this handler's filters to the record and return ``True`` if the record is to be processed. The filters are consulted in turn, until one of them returns a false value. If none of them return a false value, the record will be emitted. If one returns a false value, the handler will not emit the diff --git a/Doc/library/lzma.rst b/Doc/library/lzma.rst index cce6c23..4bfff9c 100644 --- a/Doc/library/lzma.rst +++ b/Doc/library/lzma.rst @@ -313,7 +313,7 @@ Miscellaneous .. function:: is_check_supported(check) - Returns true if the given integrity check is supported on this system. + Return ``True`` if the given integrity check is supported on this system. :const:`CHECK_NONE` and :const:`CHECK_CRC32` are always supported. :const:`CHECK_CRC64` and :const:`CHECK_SHA256` may be unavailable if you are diff --git a/Doc/library/msvcrt.rst b/Doc/library/msvcrt.rst index bd34ffb..14ad2cd 100644 --- a/Doc/library/msvcrt.rst +++ b/Doc/library/msvcrt.rst @@ -92,7 +92,7 @@ Console I/O .. function:: kbhit() - Return true if a keypress is waiting to be read. + Return ``True`` if a keypress is waiting to be read. .. function:: getch() diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 96e0dc8..9bed380 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -2142,7 +2142,8 @@ with the :class:`Pool` class. .. method:: map(func, iterable[, chunksize]) A parallel equivalent of the :func:`map` built-in function (it supports only - one *iterable* argument though). It blocks until the result is ready. + one *iterable* argument though, for multiple iterables see :meth:`starmap`). + It blocks until the result is ready. This method chops the iterable into a number of chunks which it submits to the process pool as separate tasks. The (approximate) size of these diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index 3afc77b..36110bb 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -928,10 +928,10 @@ The canonical way to create an :class:`Option` instance is with the store a constant value ``"store_true"`` - store a true value + store ``True`` ``"store_false"`` - store a false value + store ``False`` ``"append"`` append this option's argument to a list @@ -1135,12 +1135,12 @@ must specify for any option using that action. * ``"store_true"`` [relevant: :attr:`~Option.dest`] - A special case of ``"store_const"`` that stores a true value to + A special case of ``"store_const"`` that stores ``True`` to :attr:`~Option.dest`. * ``"store_false"`` [relevant: :attr:`~Option.dest`] - Like ``"store_true"``, but stores a false value. + Like ``"store_true"``, but stores ``False``. Example:: @@ -1396,7 +1396,7 @@ provides several methods to help you out: .. method:: OptionParser.has_option(opt_str) - Return true if the OptionParser has an option with option string *opt_str* + Return ``True`` if the OptionParser has an option with option string *opt_str* (e.g., ``-q`` or ``--verbose``). .. method:: OptionParser.remove_option(opt_str) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 1556422..10d7dea 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -147,7 +147,7 @@ process and user. versa). :data:`environb` is only available if :data:`supports_bytes_environ` is - True. + ``True``. .. versionadded:: 3.2 @@ -235,7 +235,7 @@ process and user. *default* if it doesn't. *key*, *default* and the result are bytes. :func:`getenvb` is only available if :data:`supports_bytes_environ` - is True. + is ``True``. .. availability:: most flavors of Unix. diff --git a/Doc/library/parser.rst b/Doc/library/parser.rst index 1d2da30..7b380c3 100644 --- a/Doc/library/parser.rst +++ b/Doc/library/parser.rst @@ -234,8 +234,8 @@ determine if an ST was created from source code via :func:`expr` or .. index:: builtin: compile - When *st* represents an ``'eval'`` form, this function returns true, otherwise - it returns false. This is useful, since code objects normally cannot be queried + When *st* represents an ``'eval'`` form, this function returns ``True``, otherwise + it returns ``False``. This is useful, since code objects normally cannot be queried for this information using existing built-in functions. Note that the code objects created by :func:`compilest` cannot be queried like this either, and are identical to those created by the built-in :func:`compile` function. diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index c7864e9..a52549f 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -529,6 +529,14 @@ by the local file. Quit from the debugger. The program being executed is aborted. +.. pdbcommand:: debug code + + Enter a recursive debugger that steps through the code + argument (which is an arbitrary expression or statement to be + executed in the current environment). + +.. pdbcommand:: retval + Print the return value for the last return of a function. .. rubric:: Footnotes diff --git a/Doc/library/sched.rst b/Doc/library/sched.rst index 03753af..047899e 100644 --- a/Doc/library/sched.rst +++ b/Doc/library/sched.rst @@ -104,7 +104,7 @@ Scheduler Objects .. method:: scheduler.empty() - Return true if the event queue is empty. + Return ``True`` if the event queue is empty. .. method:: scheduler.run(blocking=True) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 15c65b9..178d7da 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -1298,9 +1298,9 @@ to sockets. fds = array.array("i") # Array of ints msg, ancdata, flags, addr = sock.recvmsg(msglen, socket.CMSG_LEN(maxfds * fds.itemsize)) for cmsg_level, cmsg_type, cmsg_data in ancdata: - if (cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS): + if cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS: # Append data, ignoring any truncated integers at the end. - fds.fromstring(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) + fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) return msg, list(fds) .. availability:: most Unix platforms, possibly others. @@ -1535,9 +1535,9 @@ to sockets. ``None`` or a :term:`bytes-like object` representing a buffer. In the later case it is up to the caller to ensure that the bytestring contains the proper bits (see the optional built-in module :mod:`struct` for a way to - encode C structures as bytestrings). When value is set to ``None``, - optlen argument is required. It's equivalent to call setsockopt C - function with optval=NULL and optlen=optlen. + encode C structures as bytestrings). When *value* is set to ``None``, + *optlen* argument is required. It's equivalent to call :c:func:`setsockopt` C + function with ``optval=NULL`` and ``optlen=optlen``. .. versionchanged:: 3.5 diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 3730d74..5aff697 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -1247,6 +1247,9 @@ SSL sockets also have the following additional methods and attributes: The returned dictionary includes additional X509v3 extension items such as ``crlDistributionPoints``, ``caIssuers`` and ``OCSP`` URIs. + .. versionchanged:: 3.7.6 + IPv6 address strings no longer have a trailing new line. + .. method:: SSLSocket.cipher() Returns a three-value tuple containing the name of the cipher being used, the @@ -1649,7 +1652,7 @@ to speed up repeated connections from the same clients. return the agreed-upon protocol. This method will raise :exc:`NotImplementedError` if :data:`HAS_ALPN` is - False. + ``False``. OpenSSL 1.1.0 to 1.1.0e will abort the handshake and raise :exc:`SSLError` when both sides support ALPN but cannot agree on a protocol. 1.1.0f+ @@ -1668,7 +1671,7 @@ to speed up repeated connections from the same clients. return the agreed-upon protocol. This method will raise :exc:`NotImplementedError` if :data:`HAS_NPN` is - False. + ``False``. .. versionadded:: 3.3 diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index 26bb592..081fafd 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -2,7 +2,7 @@ ======================================================= .. module:: statistics - :synopsis: mathematical statistics functions + :synopsis: Mathematical statistics functions .. moduleauthor:: Steven D'Aprano .. sectionauthor:: Steven D'Aprano diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 57b72c5..5e9b59e 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1648,16 +1648,16 @@ expression support in the :mod:`re` module). .. method:: str.isalnum() - Return true if all characters in the string are alphanumeric and there is at - least one character, false otherwise. A character ``c`` is alphanumeric if one + Return ``True`` if all characters in the string are alphanumeric and there is at + least one character, ``False`` otherwise. A character ``c`` is alphanumeric if one of the following returns ``True``: ``c.isalpha()``, ``c.isdecimal()``, ``c.isdigit()``, or ``c.isnumeric()``. .. method:: str.isalpha() - Return true if all characters in the string are alphabetic and there is at least - one character, false otherwise. Alphabetic characters are those characters defined + Return ``True`` if all characters in the string are alphabetic and there is at least + one character, ``False`` otherwise. Alphabetic characters are those characters defined in the Unicode character database as "Letter", i.e., those with general category property being one of "Lm", "Lt", "Lu", "Ll", or "Lo". Note that this is different from the "Alphabetic" property defined in the Unicode Standard. @@ -1665,8 +1665,8 @@ expression support in the :mod:`re` module). .. method:: str.isascii() - Return true if the string is empty or all characters in the string are ASCII, - false otherwise. + Return ``True`` if the string is empty or all characters in the string are ASCII, + ``False`` otherwise. ASCII characters have code points in the range U+0000-U+007F. .. versionadded:: 3.7 @@ -1674,8 +1674,8 @@ expression support in the :mod:`re` module). .. method:: str.isdecimal() - Return true if all characters in the string are decimal - characters and there is at least one character, false + Return ``True`` if all characters in the string are decimal + characters and there is at least one character, ``False`` otherwise. Decimal characters are those that can be used to form numbers in base 10, e.g. U+0660, ARABIC-INDIC DIGIT ZERO. Formally a decimal character is a character in the Unicode @@ -1684,8 +1684,8 @@ expression support in the :mod:`re` module). .. method:: str.isdigit() - Return true if all characters in the string are digits and there is at least one - character, false otherwise. Digits include decimal characters and digits that need + Return ``True`` if all characters in the string are digits and there is at least one + character, ``False`` otherwise. Digits include decimal characters and digits that need special handling, such as the compatibility superscript digits. This covers digits which cannot be used to form numbers in base 10, like the Kharosthi numbers. Formally, a digit is a character that has the @@ -1694,7 +1694,7 @@ expression support in the :mod:`re` module). .. method:: str.isidentifier() - Return true if the string is a valid identifier according to the language + Return ``True`` if the string is a valid identifier according to the language definition, section :ref:`identifiers`. Use :func:`keyword.iskeyword` to test for reserved identifiers such as @@ -1702,14 +1702,14 @@ expression support in the :mod:`re` module). .. method:: str.islower() - Return true if all cased characters [4]_ in the string are lowercase and - there is at least one cased character, false otherwise. + Return ``True`` if all cased characters [4]_ in the string are lowercase and + there is at least one cased character, ``False`` otherwise. .. method:: str.isnumeric() - Return true if all characters in the string are numeric - characters, and there is at least one character, false + Return ``True`` if all characters in the string are numeric + characters, and there is at least one character, ``False`` otherwise. Numeric characters include digit characters, and all characters that have the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION ONE FIFTH. Formally, numeric characters are those with the property @@ -1718,8 +1718,8 @@ expression support in the :mod:`re` module). .. method:: str.isprintable() - Return true if all characters in the string are printable or the string is - empty, false otherwise. Nonprintable characters are those characters defined + Return ``True`` if all characters in the string are printable or the string is + empty, ``False`` otherwise. Nonprintable characters are those characters defined in the Unicode character database as "Other" or "Separator", excepting the ASCII space (0x20) which is considered printable. (Note that printable characters in this context are those which should not be escaped when @@ -1729,8 +1729,8 @@ expression support in the :mod:`re` module). .. method:: str.isspace() - Return true if there are only whitespace characters in the string and there is - at least one character, false otherwise. + Return ``True`` if there are only whitespace characters in the string and there is + at least one character, ``False`` otherwise. A character is *whitespace* if in the Unicode character database (see :mod:`unicodedata`), either its general category is ``Zs`` @@ -1740,15 +1740,15 @@ expression support in the :mod:`re` module). .. method:: str.istitle() - Return true if the string is a titlecased string and there is at least one + Return ``True`` if the string is a titlecased string and there is at least one character, for example uppercase characters may only follow uncased characters - and lowercase characters only cased ones. Return false otherwise. + and lowercase characters only cased ones. Return ``False`` otherwise. .. method:: str.isupper() - Return true if all cased characters [4]_ in the string are uppercase and - there is at least one cased character, false otherwise. + Return ``True`` if all cased characters [4]_ in the string are uppercase and + there is at least one cased character, ``False`` otherwise. .. method:: str.join(iterable) @@ -2944,8 +2944,8 @@ place, and instead produce new objects. .. method:: bytes.isalnum() bytearray.isalnum() - Return true if all bytes in the sequence are alphabetical ASCII characters - or ASCII decimal digits and the sequence is not empty, false otherwise. + Return ``True`` if all bytes in the sequence are alphabetical ASCII characters + or ASCII decimal digits and the sequence is not empty, ``False`` otherwise. Alphabetic ASCII characters are those byte values in the sequence ``b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'``. ASCII decimal digits are those byte values in the sequence ``b'0123456789'``. @@ -2961,8 +2961,8 @@ place, and instead produce new objects. .. method:: bytes.isalpha() bytearray.isalpha() - Return true if all bytes in the sequence are alphabetic ASCII characters - and the sequence is not empty, false otherwise. Alphabetic ASCII + Return ``True`` if all bytes in the sequence are alphabetic ASCII characters + and the sequence is not empty, ``False`` otherwise. Alphabetic ASCII characters are those byte values in the sequence ``b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'``. @@ -2977,8 +2977,8 @@ place, and instead produce new objects. .. method:: bytes.isascii() bytearray.isascii() - Return true if the sequence is empty or all bytes in the sequence are ASCII, - false otherwise. + Return ``True`` if the sequence is empty or all bytes in the sequence are ASCII, + ``False`` otherwise. ASCII bytes are in the range 0-0x7F. .. versionadded:: 3.7 @@ -2987,8 +2987,8 @@ place, and instead produce new objects. .. method:: bytes.isdigit() bytearray.isdigit() - Return true if all bytes in the sequence are ASCII decimal digits - and the sequence is not empty, false otherwise. ASCII decimal digits are + Return ``True`` if all bytes in the sequence are ASCII decimal digits + and the sequence is not empty, ``False`` otherwise. ASCII decimal digits are those byte values in the sequence ``b'0123456789'``. For example:: @@ -3002,8 +3002,8 @@ place, and instead produce new objects. .. method:: bytes.islower() bytearray.islower() - Return true if there is at least one lowercase ASCII character - in the sequence and no uppercase ASCII characters, false otherwise. + Return ``True`` if there is at least one lowercase ASCII character + in the sequence and no uppercase ASCII characters, ``False`` otherwise. For example:: @@ -3020,8 +3020,8 @@ place, and instead produce new objects. .. method:: bytes.isspace() bytearray.isspace() - Return true if all bytes in the sequence are ASCII whitespace and the - sequence is not empty, false otherwise. ASCII whitespace characters are + Return ``True`` if all bytes in the sequence are ASCII whitespace and the + sequence is not empty, ``False`` otherwise. ASCII whitespace characters are those byte values in the sequence ``b' \t\n\r\x0b\f'`` (space, tab, newline, carriage return, vertical tab, form feed). @@ -3029,8 +3029,8 @@ place, and instead produce new objects. .. method:: bytes.istitle() bytearray.istitle() - Return true if the sequence is ASCII titlecase and the sequence is not - empty, false otherwise. See :meth:`bytes.title` for more details on the + Return ``True`` if the sequence is ASCII titlecase and the sequence is not + empty, ``False`` otherwise. See :meth:`bytes.title` for more details on the definition of "titlecase". For example:: @@ -3044,8 +3044,8 @@ place, and instead produce new objects. .. method:: bytes.isupper() bytearray.isupper() - Return true if there is at least one uppercase alphabetic ASCII character - in the sequence and no lowercase ASCII characters, false otherwise. + Return ``True`` if there is at least one uppercase alphabetic ASCII character + in the sequence and no lowercase ASCII characters, ``False`` otherwise. For example:: diff --git a/Doc/library/stringprep.rst b/Doc/library/stringprep.rst index 330032b..5cfb533 100644 --- a/Doc/library/stringprep.rst +++ b/Doc/library/stringprep.rst @@ -34,7 +34,7 @@ itself was generated using the ``mkstringprep.py`` utility. As a result, these tables are exposed as functions, not as data structures. There are two kinds of tables in the RFC: sets and mappings. For a set, :mod:`stringprep` provides the "characteristic function", i.e. a function that -returns true if the parameter is part of the set. For mappings, it provides the +returns ``True`` if the parameter is part of the set. For mappings, it provides the mapping function: given the key, it returns the associated value. Below is a list of all functions available in the module. diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 822e22e..4570868 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -1377,7 +1377,7 @@ always available. On Windows, UTF-8 is used for the console device. Non-character devices such as disk files and pipes use the system locale encoding (i.e. the ANSI codepage). Non-console character - devices such as NUL (i.e. where isatty() returns True) use the + devices such as NUL (i.e. where ``isatty()`` returns ``True``) use the value of the console input and output codepages at startup, respectively for stdin and stdout/stderr. This defaults to the system locale encoding if the process is not initially attached diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index dd24a1c..00acf4b 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -95,8 +95,8 @@ The module defines the following user-callable items: causes the file to roll over to an on-disk file regardless of its size. The returned object is a file-like object whose :attr:`_file` attribute - is either an :class:`io.BytesIO` or :class:`io.StringIO` object (depending on - whether binary or text *mode* was specified) or a true file + is either an :class:`io.BytesIO` or :class:`io.TextIOWrapper` object + (depending on whether binary or text *mode* was specified) or a true file object, depending on whether :func:`rollover` has been called. This file-like object can be used in a :keyword:`with` statement, just like a normal file. diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index c58a6ad..02af94e 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -418,6 +418,10 @@ All methods are executed atomically. There is no return value. + .. method:: locked() + Return true if the lock is acquired. + + .. _rlock-objects: @@ -465,15 +469,15 @@ Reentrant locks also support the :ref:`context management protocol ` There is no return value in this case. When invoked with the *blocking* argument set to true, do the same thing as when - called without arguments, and return true. + called without arguments, and return ``True``. When invoked with the *blocking* argument set to false, do not block. If a call - without an argument would block, return false immediately; otherwise, do the - same thing as when called without arguments, and return true. + without an argument would block, return ``False`` immediately; otherwise, do the + same thing as when called without arguments, and return ``True``. When invoked with the floating-point *timeout* argument set to a positive value, block for at most the number of seconds specified by *timeout* - and as long as the lock cannot be acquired. Return true if the lock has + and as long as the lock cannot be acquired. Return ``True`` if the lock has been acquired, false if the timeout has elapsed. .. versionchanged:: 3.2 @@ -706,20 +710,20 @@ Semaphores also support the :ref:`context management protocol `. When invoked without arguments: * If the internal counter is larger than zero on entry, decrement it by - one and return true immediately. + one and return ``True`` immediately. * If the internal counter is zero on entry, block until awoken by a call to :meth:`~Semaphore.release`. Once awoken (and the counter is greater - than 0), decrement the counter by 1 and return true. Exactly one + than 0), decrement the counter by 1 and return ``True``. Exactly one thread will be awoken by each call to :meth:`~Semaphore.release`. The order in which threads are awoken should not be relied on. When invoked with *blocking* set to false, do not block. If a call - without an argument would block, return false immediately; otherwise, do - the same thing as when called without arguments, and return true. + without an argument would block, return ``False`` immediately; otherwise, do + the same thing as when called without arguments, and return ``True``. When invoked with a *timeout* other than ``None``, it will block for at most *timeout* seconds. If acquire does not complete successfully in - that interval, return false. Return true otherwise. + that interval, return ``False``. Return ``True`` otherwise. .. versionchanged:: 3.2 The *timeout* parameter is new. @@ -796,7 +800,7 @@ method. The :meth:`~Event.wait` method blocks until the flag is true. .. method:: is_set() - Return true if and only if the internal flag is true. + Return ``True`` if and only if the internal flag is true. .. method:: set() @@ -820,7 +824,7 @@ method. The :meth:`~Event.wait` method blocks until the flag is true. floating point number specifying a timeout for the operation in seconds (or fractions thereof). - This method returns true if and only if the internal flag has been set to + This method returns ``True`` if and only if the internal flag has been set to true, either before the wait call or after the wait starts, so it will always return ``True`` except if a timeout is given and the operation times out. diff --git a/Doc/library/time.rst b/Doc/library/time.rst index 17f8cfc..c0f336f 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -42,17 +42,12 @@ An explanation of some terminology and conventions is in order. library; for 32-bit systems, it is typically in 2038. .. index:: - single: Year 2000 - single: Y2K + single: 2-digit years -.. _time-y2kissues: - -* **Year 2000 (Y2K) issues**: Python depends on the platform's C library, which - generally doesn't have year 2000 issues, since all dates and times are - represented internally as seconds since the epoch. Function :func:`strptime` - can parse 2-digit years when given ``%y`` format code. When 2-digit years are - parsed, they are converted according to the POSIX and ISO C standards: values - 69--99 are mapped to 1969--1999, and values 0--68 are mapped to 2000--2068. +* Function :func:`strptime` can parse 2-digit years when given ``%y`` format + code. When 2-digit years are parsed, they are converted according to the POSIX + and ISO C standards: values 69--99 are mapped to 1969--1999, and values 0--68 + are mapped to 2000--2068. .. index:: single: UTC diff --git a/Doc/library/tkinter.ttk.rst b/Doc/library/tkinter.ttk.rst index 76ecfcc..f9084c5 100644 --- a/Doc/library/tkinter.ttk.rst +++ b/Doc/library/tkinter.ttk.rst @@ -871,8 +871,8 @@ widget commands. | | remaining values are assumed empty. If there are more values | | | than columns, the extra values are ignored. | +--------+---------------------------------------------------------------+ - | open | True/False value indicating whether the item's children should| - | | be displayed or hidden. | + | open | ``True``/``False`` value indicating whether the item's | + | | children should be displayed or hidden. | +--------+---------------------------------------------------------------+ | tags | A list of tags associated with this item. | +--------+---------------------------------------------------------------+ @@ -997,7 +997,7 @@ ttk.Treeview The minimum width of the column in pixels. The treeview widget will not make the column any smaller than specified by this option when the widget is resized or the user drags a column. - * stretch: True/False + * stretch: ``True``/``False`` Specifies whether the column's width should be adjusted when the widget is resized. * width: width diff --git a/Doc/library/token.rst b/Doc/library/token.rst index 3739910..c56cb76 100644 --- a/Doc/library/token.rst +++ b/Doc/library/token.rst @@ -29,17 +29,17 @@ functions. The functions mirror definitions in the Python C header files. .. function:: ISTERMINAL(x) - Return true for terminal token values. + Return ``True`` for terminal token values. .. function:: ISNONTERMINAL(x) - Return true for non-terminal token values. + Return ``True`` for non-terminal token values. .. function:: ISEOF(x) - Return true if *x* is the marker indicating the end of input. + Return ``True`` if *x* is the marker indicating the end of input. The token constants are: diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 36cc0c2..2e192be 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -336,7 +336,7 @@ the *new_callable* argument to :func:`patch`. assert the mock has been called with the specified calls. The :attr:`mock_calls` list is checked for the calls. - If *any_order* is false (the default) then the calls must be + If *any_order* is false then the calls must be sequential. There can be extra calls before or after the specified calls. @@ -1765,19 +1765,19 @@ to change the default. Methods and their defaults: -* ``__lt__``: NotImplemented -* ``__gt__``: NotImplemented -* ``__le__``: NotImplemented -* ``__ge__``: NotImplemented -* ``__int__``: 1 -* ``__contains__``: False -* ``__len__``: 0 -* ``__iter__``: iter([]) -* ``__exit__``: False -* ``__complex__``: 1j -* ``__float__``: 1.0 -* ``__bool__``: True -* ``__index__``: 1 +* ``__lt__``: ``NotImplemented`` +* ``__gt__``: ``NotImplemented`` +* ``__le__``: ``NotImplemented`` +* ``__ge__``: ``NotImplemented`` +* ``__int__``: ``1`` +* ``__contains__``: ``False`` +* ``__len__``: ``0`` +* ``__iter__``: ``iter([])`` +* ``__exit__``: ``False`` +* ``__complex__``: ``1j`` +* ``__float__``: ``1.0`` +* ``__bool__``: ``True`` +* ``__index__``: ``1`` * ``__hash__``: default hash for the mock * ``__str__``: default str for the mock * ``__sizeof__``: default sizeof for the mock diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index bbe1429..0cd6918 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -56,8 +56,8 @@ test runner Kent Beck's original paper on testing frameworks using the pattern shared by :mod:`unittest`. - `Nose `_ and `pytest `_ - Third-party unittest frameworks with a lighter-weight syntax for writing + `pytest `_ + Third-party unittest framework with a lighter-weight syntax for writing tests. For example, ``assert func(10) == 42``. `The Python Testing Tools Taxonomy `_ diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index ddc3ee2..f499412 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -520,7 +520,7 @@ task isn't already covered by the URL parsing functions above. .. versionchanged:: 3.7 Moved from :rfc:`2396` to :rfc:`3986` for quoting URL strings. "~" is now - included in the set of reserved characters. + included in the set of unreserved characters. The optional *encoding* and *errors* parameters specify how to deal with non-ASCII characters, as accepted by the :meth:`str.encode` method. diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 5d8c0ec..22bad2d 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -18,7 +18,7 @@ authentication, redirections, cookies and more. .. seealso:: - The `Requests package `_ + The `Requests package `_ is recommended for a higher-level HTTP client interface. diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index 18804b5..47324f0 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -273,9 +273,9 @@ subclass which installs setuptools and pip into a created virtual environment:: This builder installs setuptools and pip so that you can pip or easy_install other packages into the created virtual environment. - :param nodist: If True, setuptools and pip are not installed into the + :param nodist: If true, setuptools and pip are not installed into the created virtual environment. - :param nopip: If True, pip is not installed into the created + :param nopip: If true, pip is not installed into the created virtual environment. :param progress: If setuptools or pip are installed, the progress of the installation can be monitored by passing a progress diff --git a/Doc/library/winreg.rst b/Doc/library/winreg.rst index cb67f2f..5e81068 100644 --- a/Doc/library/winreg.rst +++ b/Doc/library/winreg.rst @@ -343,7 +343,7 @@ This module offers the following functions: value set by the :func:`SetValue` method for the key identified by *key*. Values in the registry have name, type, and data components. This method - retrieves the data for a key's first value that has a NULL name. But the + retrieves the data for a key's first value that has a ``NULL`` name. But the underlying API call doesn't return the type, so always use :func:`QueryValueEx` if possible. @@ -391,7 +391,7 @@ This module offers the following functions: `__ for more details. - This function passes NULL for *security_attributes* to the API. + This function passes ``NULL`` for *security_attributes* to the API. .. function:: SetValue(key, sub_key, type, value) diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index 2d9b7b3..95fd188 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -144,7 +144,7 @@ also provides these miscellaneous utilities: .. function:: is_hop_by_hop(header_name) - Return true if 'header_name' is an HTTP/1.1 "Hop-by-Hop" header, as defined by + Return ``True`` if 'header_name' is an HTTP/1.1 "Hop-by-Hop" header, as defined by :rfc:`2616`. diff --git a/Doc/library/xml.dom.rst b/Doc/library/xml.dom.rst index 18519a7..98454e1 100644 --- a/Doc/library/xml.dom.rst +++ b/Doc/library/xml.dom.rst @@ -210,7 +210,7 @@ DOM Level 2 added the ability to create new :class:`Document` and .. method:: DOMImplementation.hasFeature(feature, version) - Return true if the feature identified by the pair of strings *feature* and + Return ``True`` if the feature identified by the pair of strings *feature* and *version* is implemented. @@ -335,17 +335,17 @@ All of the components of an XML document are subclasses of :class:`Node`. .. method:: Node.hasAttributes() - Returns true if the node has any attributes. + Return ``True`` if the node has any attributes. .. method:: Node.hasChildNodes() - Returns true if the node has any child nodes. + Return ``True`` if the node has any child nodes. .. method:: Node.isSameNode(other) - Returns true if *other* refers to the same node as this node. This is especially + Return ``True`` if *other* refers to the same node as this node. This is especially useful for DOM implementations which use any sort of proxy architecture (because more than one object can refer to the same node). @@ -604,12 +604,12 @@ of that class. .. method:: Element.hasAttribute(name) - Returns true if the element has an attribute named by *name*. + Return ``True`` if the element has an attribute named by *name*. .. method:: Element.hasAttributeNS(namespaceURI, localName) - Returns true if the element has an attribute named by *namespaceURI* and + Return ``True`` if the element has an attribute named by *namespaceURI* and *localName*. diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index ca6bdf6..ec38f09 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -510,8 +510,8 @@ Functions .. function:: iselement(element) - Checks if an object appears to be a valid element object. *element* is an - element instance. Returns a true value if this is an element object. + Check if an object appears to be a valid element object. *element* is an + element instance. Return ``True`` if this is an element object. .. function:: iterparse(source, events=None, parser=None) diff --git a/Doc/library/zipimport.rst b/Doc/library/zipimport.rst index eaae2bb..fddbb50 100644 --- a/Doc/library/zipimport.rst +++ b/Doc/library/zipimport.rst @@ -2,7 +2,7 @@ ===================================================== .. module:: zipimport - :synopsis: support for importing Python modules from ZIP archives. + :synopsis: Support for importing Python modules from ZIP archives. .. moduleauthor:: Just van Rossum diff --git a/Doc/license.rst b/Doc/license.rst index ac0e2b3..d9a4314 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -22,7 +22,7 @@ Virginia where he released several versions of the software. In May 2000, Guido and the Python core development team moved to BeOpen.com to form the BeOpen PythonLabs team. In October of the same year, the PythonLabs team moved to Digital Creations (now Zope Corporation; see -http://www.zope.com/). In 2001, the Python Software Foundation (PSF, see +https://www.zope.org/). In 2001, the Python Software Foundation (PSF, see https://www.python.org/psf/) was formed, a non-profit organization created specifically to own Python-related Intellectual Property. Zope Corporation is a sponsoring member of the PSF. diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index f5e23d8..b4f9ddc 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1563,7 +1563,7 @@ not found on a module object through the normal lookup, i.e. the module ``__dict__`` before raising an :exc:`AttributeError`. If found, it is called with the attribute name and the result is returned. -The ``__dir__`` function should accept no arguments, and return a list of +The ``__dir__`` function should accept no arguments, and return a sequence of strings that represents the names accessible on module. If present, this function overrides the standard :func:`dir` search on a module. @@ -1641,8 +1641,22 @@ class' :attr:`~object.__dict__`. Called at the time the owning class *owner* is created. The descriptor has been assigned to *name*. - .. versionadded:: 3.6 + .. note:: + + :meth:`__set_name__` is only called implicitly as part of the + :class:`type` constructor, so it will need to be called explicitly with + the appropriate parameters when a descriptor is added to a class after + initial creation:: + + class A: + pass + descr = custom_descriptor() + A.attr = descr + descr.__set_name__(A, 'attr') + See :ref:`class-object-creation` for more details. + + .. versionadded:: 3.6 The attribute :attr:`__objclass__` is interpreted by the :mod:`inspect` module as specifying the class where this object was defined (setting this @@ -1783,6 +1797,10 @@ Notes on using *__slots__* (the other bases must have empty slot layouts) - violations raise :exc:`TypeError`. +* If an iterator is used for *__slots__* then a descriptor is created for each + of the iterator's values. However, the *__slots__* attribute will be an empty + iterator. + .. _class-customization: Customizing class creation @@ -2115,8 +2133,8 @@ operators. It is recommended that both mappings and sequences implement the mappings, ``in`` should search the mapping's keys; for sequences, it should search through the values. It is further recommended that both mappings and sequences implement the :meth:`__iter__` method to allow efficient iteration -through the container; for mappings, :meth:`__iter__` should be the same as -:meth:`keys`; for sequences, it should iterate through the values. +through the container; for mappings, :meth:`__iter__` should iterate +through the object's keys; for sequences, it should iterate through the values. .. method:: object.__len__(self) @@ -2230,9 +2248,9 @@ through the container; for mappings, :meth:`__iter__` should be the same as The membership test operators (:keyword:`in` and :keyword:`not in`) are normally -implemented as an iteration through a sequence. However, container objects can +implemented as an iteration through a container. However, container objects can supply the following special method with a more efficient implementation, which -also does not require the object be a sequence. +also does not require the object be iterable. .. method:: object.__contains__(self, item) diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index 88290c8..50a7562 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -683,7 +683,7 @@ Before Python loads cached bytecode from ``.pyc`` file, it checks whether the cache is up-to-date with the source ``.py`` file. By default, Python does this by storing the source's last-modified timestamp and size in the cache file when writing it. At runtime, the import system then validates the cache file by -checking the stored metadata in the cache file against at source's +checking the stored metadata in the cache file against the source's metadata. Python also supports "hash-based" cache files, which store a hash of the source @@ -850,7 +850,7 @@ In order to support imports of modules and initialized packages and also to contribute portions to namespace packages, path entry finders must implement the :meth:`~importlib.abc.PathEntryFinder.find_spec` method. -:meth:`~importlib.abc.PathEntryFinder.find_spec` takes two argument, the +:meth:`~importlib.abc.PathEntryFinder.find_spec` takes two arguments: the fully qualified name of the module being imported, and the (optional) target module. ``find_spec()`` returns a fully populated spec for the module. This spec will always have "loader" set (with one exception). @@ -914,7 +914,7 @@ the builtin :func:`__import__` function may be sufficient. This technique may also be employed at the module level to only alter the behaviour of import statements within that module. -To selectively prevent import of some modules from a hook early on the +To selectively prevent the import of some modules from a hook early on the meta path (rather than disabling the standard import system entirely), it is sufficient to raise :exc:`ModuleNotFoundError` directly from :meth:`~importlib.abc.MetaPathFinder.find_spec` instead of returning diff --git a/Doc/tools/static/switchers.js b/Doc/tools/static/switchers.js index fa298a7..e1ef91a 100644 --- a/Doc/tools/static/switchers.js +++ b/Doc/tools/static/switchers.js @@ -11,7 +11,7 @@ var all_versions = { '3.9': 'dev (3.9)', - '3.8': 'pre (3.8)', + '3.8': '3.8', '3.7': '3.7', '3.6': '3.6', '3.5': '3.5', @@ -23,6 +23,7 @@ 'fr': 'French', 'ja': 'Japanese', 'ko': 'Korean', + 'pt-br': 'Brazilian Portuguese', 'zh-cn': 'Simplified Chinese', }; diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index 36d93a4..a3c7cf6 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -2,6 +2,7 @@ c-api/arg,,:ref,"PyArg_ParseTuple(args, ""O|O:ref"", &object, &callback)" c-api/list,,:high,list[low:high] c-api/sequence,,:i2,del o[i1:i2] c-api/sequence,,:i2,o[i1:i2] +c-api/tuple,,:high,p[low:high] c-api/unicode,,:end,str[start:end] c-api/unicode,,:start,unicode[start:start+length] distutils/examples,267,`,This is the description of the ``foobar`` package. @@ -200,7 +201,7 @@ library/readline,,:bind,"python:bind ^I rl_complete" library/smtplib,,:port,method must support that as well as a regular host:port library/socket,,::,'5aef:2b::8' library/socket,,:can,"return (can_id, can_dlc, data[:can_dlc])" -library/socket,,:len,fds.fromstring(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) +library/socket,,:len,fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) library/sqlite3,,:age,"cur.execute(""select * from people where name_last=:who and age=:age"", {""who"": who, ""age"": age})" library/sqlite3,,:memory, library/sqlite3,,:who,"cur.execute(""select * from people where name_last=:who and age=:age"", {""who"": who, ""age"": age})" @@ -238,9 +239,9 @@ library/urllib.request,,:port,:port library/urllib.request,,:lang,"xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en"" lang=""en"">\n\n\n" library/urllib.request,,:password,"""joe:password@python.org""" library/uuid,,:uuid,urn:uuid:12345678-1234-5678-1234-567812345678 -library/venv,,:param,":param nodist: If True, setuptools and pip are not installed into the" +library/venv,,:param,":param nodist: If true, setuptools and pip are not installed into the" library/venv,,:param,":param progress: If setuptools or pip are installed, the progress of the" -library/venv,,:param,":param nopip: If True, pip is not installed into the created" +library/venv,,:param,":param nopip: If true, pip is not installed into the created" library/venv,,:param,:param context: The information for the virtual environment library/xmlrpc.client,,:nil,ex:nil library/xmlrpc.client,,:pass,http://user:pass@host:port/path diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst index daa4173..3bacab3 100644 --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -23,7 +23,7 @@ is an installation option, other places are possible; check with your local Python guru or system administrator. (E.g., :file:`/usr/local/python` is a popular alternative location.) -On Windows machines where you have installed from the :ref:`Microsoft Store +On Windows machines where you have installed Python from the :ref:`Microsoft Store `, the :file:`python3.7` command will be available. If you have the :ref:`py.exe launcher ` installed, you can use the :file:`py` command. See :ref:`setting-envvars` for other ways to launch Python. diff --git a/Doc/tutorial/stdlib.rst b/Doc/tutorial/stdlib.rst index 26f1195..a1b8c23 100644 --- a/Doc/tutorial/stdlib.rst +++ b/Doc/tutorial/stdlib.rst @@ -72,21 +72,23 @@ three`` at the command line:: >>> print(sys.argv) ['demo.py', 'one', 'two', 'three'] -The :mod:`argparse` module provides a mechanism to process command line arguments. -It should always be preferred over directly processing ``sys.argv`` manually. - -Take, for example, the below snippet of code:: - - >>> import argparse - >>> from getpass import getuser - >>> parser = argparse.ArgumentParser(description='An argparse example.') - >>> parser.add_argument('name', nargs='?', default=getuser(), help='The name of someone to greet.') - >>> parser.add_argument('--verbose', '-v', action='count') - >>> args = parser.parse_args() - >>> greeting = ["Hi", "Hello", "Greetings! its very nice to meet you"][args.verbose % 3] - >>> print(f'{greeting}, {args.name}') - >>> if not args.verbose: - >>> print('Try running this again with multiple "-v" flags!') +The :mod:`argparse` module provides a more sophisticated mechanism to process +command line arguments. The following script extracts one or more filenames +and an optional number of lines to be displayed:: + + import argparse + + parser = argparse.ArgumentParser(prog = 'top', + description = 'Show top lines from each file') + parser.add_argument('filenames', nargs='+') + parser.add_argument('-l', '--lines', type=int, default=10) + args = parser.parse_args() + print(args) + +When run at the command line with ``python top.py --lines=5 alpha.txt +beta.txt``, the script sets ``args.lines`` to ``5`` and ``args.filenames`` +to ``['alpha.txt', 'beta.txt']``. + .. _tut-stderr: diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 6a60bc4..2c34ac2 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -449,7 +449,7 @@ Miscellaneous options on a crash. * Enable :ref:`asyncio debug mode `. * Set the :attr:`~sys.flags.dev_mode` attribute of :attr:`sys.flags` to - ``True`` + ``True``. * ``-X utf8`` enables UTF-8 mode for operating system interfaces, overriding the default locale-aware mode. ``-X utf8=0`` explicitly disables UTF-8 @@ -745,8 +745,8 @@ conflict. * ``debug``: install debug hooks on top of the :ref:`default memory allocators `. - * ``malloc_debug``: same as ``malloc`` but also install debug hooks - * ``pymalloc_debug``: same as ``pymalloc`` but also install debug hooks + * ``malloc_debug``: same as ``malloc`` but also install debug hooks. + * ``pymalloc_debug``: same as ``pymalloc`` but also install debug hooks. See the :ref:`default memory allocators ` and the :c:func:`PyMem_SetupDebugHooks` function (install debug hooks on Python diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst index 9f8d9f2..d19c8e0 100644 --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -1169,7 +1169,7 @@ changes, or look through the Subversion logs for all the details. correctly copy bound instance methods. (Implemented by Robert Collins; :issue:`1515`.) -* The :mod:`ctypes` module now always converts ``None`` to a C NULL +* The :mod:`ctypes` module now always converts ``None`` to a C ``NULL`` pointer for arguments declared as pointers. (Changed by Thomas Heller; :issue:`4606`.) The underlying `libffi library `__ has been updated to version diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst index 822ba81..99d0408 100644 --- a/Doc/whatsnew/3.4.rst +++ b/Doc/whatsnew/3.4.rst @@ -2503,13 +2503,13 @@ Changes in the C API * The result of the :c:data:`PyOS_ReadlineFunctionPointer` callback must now be a string allocated by :c:func:`PyMem_RawMalloc` or - :c:func:`PyMem_RawRealloc`, or *NULL* if an error occurred, instead of a + :c:func:`PyMem_RawRealloc`, or ``NULL`` if an error occurred, instead of a string allocated by :c:func:`PyMem_Malloc` or :c:func:`PyMem_Realloc` (:issue:`16742`) * :c:func:`PyThread_set_key_value` now always set the value. In Python 3.3, the function did nothing if the key already exists (if the current - value is a non-NULL pointer). + value is a non-``NULL`` pointer). * The ``f_tstate`` (thread state) field of the :c:type:`PyFrameObject` structure has been removed to fix a bug: see :issue:`14432` for the diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst index 3f5f520..04c1f7e 100644 --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -2433,3 +2433,13 @@ In 3.6.7 the :mod:`tokenize` module now implicitly emits a ``NEWLINE`` token when provided with input that does not have a trailing new line. This behavior now matches what the C tokenizer does internally. (Contributed by Ammar Askar in :issue:`33899`.) + +Notable changes in Python 3.6.10 +================================ + +Due to significant security concerns, the *reuse_address* parameter of +:meth:`asyncio.loop.create_datagram_endpoint` is no longer supported. This is +because of the behavior of the socket option ``SO_REUSEADDR`` in UDP. For more +details, see the documentation for ``loop.create_datagram_endpoint()``. +(Contributed by Kyle Stanley, Antoine Pitrou, and Yury Selivanov in +:issue:`37228`.) diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index f6476a3..c7e3230 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -1720,7 +1720,7 @@ The type of results of :c:func:`PyThread_start_new_thread` and (Contributed by Serhiy Storchaka in :issue:`6532`.) :c:func:`PyUnicode_AsWideCharString` now raises a :exc:`ValueError` if the -second argument is *NULL* and the :c:type:`wchar_t*` string contains null +second argument is ``NULL`` and the :c:type:`wchar_t*` string contains null characters. (Contributed by Serhiy Storchaka in :issue:`30708`.) Changes to the startup sequence and the management of dynamic memory @@ -2557,3 +2557,13 @@ This resolves a long standing issue where all virtual environments would have to be upgraded or recreated with each Python update. However, note that this release will still require recreation of virtual environments in order to get the new scripts. + +Notable changes in Python 3.7.6 +=============================== + +Due to significant security concerns, the *reuse_address* parameter of +:meth:`asyncio.loop.create_datagram_endpoint` is no longer supported. This is +because of the behavior of the socket option ``SO_REUSEADDR`` in UDP. For more +details, see the documentation for ``loop.create_datagram_endpoint()``. +(Contributed by Kyle Stanley, Antoine Pitrou, and Yury Selivanov in +:issue:`37228`.) diff --git a/Include/abstract.h b/Include/abstract.h index 3fe5a00..d8f648e 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -147,7 +147,7 @@ extern "C" { /* Call a callable Python object 'callable' with arguments given by the tuple 'args' and keywords arguments given by the dictionary 'kwargs'. - 'args' must not be *NULL*, use an empty tuple if no arguments are + 'args' must not be NULL, use an empty tuple if no arguments are needed. If no named arguments are needed, 'kwargs' can be NULL. This is the equivalent of the Python expression: @@ -274,9 +274,9 @@ PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult(PyObject *callable, /* Call a callable Python object 'callable', with arguments given by the - tuple 'args'. If no arguments are needed, then 'args' can be *NULL*. + tuple 'args'. If no arguments are needed, then 'args' can be NULL. - Returns the result of the call on success, or *NULL* on failure. + Returns the result of the call on success, or NULL on failure. This is the equivalent of the Python expression: callable(*args). */ diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 083aeb8..ee26960 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -18,12 +18,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 7 -#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.7.5" +#define PY_VERSION "3.7.6" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Lib/_pyio.py b/Lib/_pyio.py index e81cc51..d219781 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -1543,7 +1543,11 @@ class FileIO(RawIOBase): # For consistent behaviour, we explicitly seek to the # end of file (otherwise, it might be done only on the # first write()). - os.lseek(fd, 0, SEEK_END) + try: + os.lseek(fd, 0, SEEK_END) + except OSError as e: + if e.errno != errno.ESPIPE: + raise except: if owned_fd is not None: os.close(owned_fd) diff --git a/Lib/argparse.py b/Lib/argparse.py index 24af355..ac424f4 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -2080,10 +2080,11 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): OPTIONAL: _('expected at most one argument'), ONE_OR_MORE: _('expected at least one argument'), } - default = ngettext('expected %s argument', + msg = nargs_errors.get(action.nargs) + if msg is None: + msg = ngettext('expected %s argument', 'expected %s arguments', action.nargs) % action.nargs - msg = nargs_errors.get(action.nargs, default) raise ArgumentError(action, msg) # return the number of arguments matched diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 5213437..fdd80bc 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -61,6 +61,10 @@ _HAS_IPv6 = hasattr(socket, 'AF_INET6') # Maximum timeout passed to select to avoid OS limitations MAXIMUM_SELECT_TIMEOUT = 24 * 3600 +# Used for deprecation and removal of `loop.create_datagram_endpoint()`'s +# *reuse_address* parameter +_unset = object() + def _format_handle(handle): cb = handle._callback @@ -1138,7 +1142,7 @@ class BaseEventLoop(events.AbstractEventLoop): async def create_datagram_endpoint(self, protocol_factory, local_addr=None, remote_addr=None, *, family=0, proto=0, flags=0, - reuse_address=None, reuse_port=None, + reuse_address=_unset, reuse_port=None, allow_broadcast=None, sock=None): """Create datagram connection.""" if sock is not None: @@ -1147,7 +1151,7 @@ class BaseEventLoop(events.AbstractEventLoop): f'A UDP Socket was expected, got {sock!r}') if (local_addr or remote_addr or family or proto or flags or - reuse_address or reuse_port or allow_broadcast): + reuse_port or allow_broadcast): # show the problematic kwargs in exception msg opts = dict(local_addr=local_addr, remote_addr=remote_addr, family=family, proto=proto, flags=flags, @@ -1201,8 +1205,18 @@ class BaseEventLoop(events.AbstractEventLoop): exceptions = [] - if reuse_address is None: - reuse_address = os.name == 'posix' and sys.platform != 'cygwin' + # bpo-37228 + if reuse_address is not _unset: + if reuse_address: + raise ValueError("Passing `reuse_address=True` is no " + "longer supported, as the usage of " + "SO_REUSEPORT in UDP poses a significant " + "security concern.") + else: + warnings.warn("The *reuse_address* parameter has been " + "deprecated as of 3.7.6 and is scheduled " + "for removal in 3.11.", DeprecationWarning, + stacklevel=2) for ((family, proto), (local_address, remote_address)) in addr_pairs_info: @@ -1211,9 +1225,6 @@ class BaseEventLoop(events.AbstractEventLoop): try: sock = socket.socket( family=family, type=socket.SOCK_DGRAM, proto=proto) - if reuse_address: - sock.setsockopt( - socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) if reuse_port: _set_reuseport(sock) if allow_broadcast: diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index 0e0e696..1bd6c81 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -118,7 +118,10 @@ class Future: def get_loop(self): """Return the event loop the Future is bound to.""" - return self._loop + loop = self._loop + if loop is None: + raise RuntimeError("Future object is not initialized.") + return loop def cancel(self): """Cancel the future and schedule callbacks. diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 23bd8ad..fa8f0cd 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -39,6 +39,11 @@ def _test_selector_event(selector, fd, event): return bool(key.events & event) +def _check_ssl_socket(sock): + if ssl is not None and isinstance(sock, ssl.SSLSocket): + raise TypeError("Socket cannot be of type SSLSocket") + + class BaseSelectorEventLoop(base_events.BaseEventLoop): """Selector event loop. @@ -345,6 +350,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): The maximum amount of data to be received at once is specified by nbytes. """ + _check_ssl_socket(sock) if self._debug and sock.gettimeout() != 0: raise ValueError("the socket must be non-blocking") fut = self.create_future() @@ -378,6 +384,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): The received data is written into *buf* (a writable buffer). The return value is the number of bytes written. """ + _check_ssl_socket(sock) if self._debug and sock.gettimeout() != 0: raise ValueError("the socket must be non-blocking") fut = self.create_future() @@ -415,6 +422,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): raised, and there is no way to determine how much data, if any, was successfully processed by the receiving end of the connection. """ + _check_ssl_socket(sock) if self._debug and sock.gettimeout() != 0: raise ValueError("the socket must be non-blocking") fut = self.create_future() @@ -451,6 +459,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): This method is a coroutine. """ + _check_ssl_socket(sock) if self._debug and sock.gettimeout() != 0: raise ValueError("the socket must be non-blocking") @@ -508,6 +517,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection. """ + _check_ssl_socket(sock) if self._debug and sock.gettimeout() != 0: raise ValueError("the socket must be non-blocking") fut = self.create_future() diff --git a/Lib/codeop.py b/Lib/codeop.py index fb759da..0fa677f 100644 --- a/Lib/codeop.py +++ b/Lib/codeop.py @@ -93,10 +93,13 @@ def _maybe_compile(compiler, source, filename, symbol): except SyntaxError as e: err2 = e - if code: - return code - if not code1 and repr(err1) == repr(err2): - raise err1 + try: + if code: + return code + if not code1 and repr(err1) == repr(err2): + raise err1 + finally: + err1 = err2 = None def _compile(source, filename, symbol): return compile(source, filename, symbol, PyCF_DONT_IMPLY_DEDENT) diff --git a/Lib/ctypes/macholib/dyld.py b/Lib/ctypes/macholib/dyld.py index c158e67..9d86b05 100644 --- a/Lib/ctypes/macholib/dyld.py +++ b/Lib/ctypes/macholib/dyld.py @@ -149,6 +149,8 @@ def framework_find(fn, executable_path=None, env=None): return dyld_find(fn, executable_path=executable_path, env=env) except ValueError: raise error + finally: + error = None def test_dyld_find(): env = {} diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py index d8d6c65..c129377 100644 --- a/Lib/ctypes/test/test_structures.py +++ b/Lib/ctypes/test/test_structures.py @@ -532,6 +532,167 @@ class StructureTestCase(unittest.TestCase): self.assertEqual(f2, [0x4567, 0x0123, 0xcdef, 0x89ab, 0x3210, 0x7654, 0xba98, 0xfedc]) + def test_union_by_value(self): + # See bpo-16575 + + # These should mirror the structures in Modules/_ctypes/_ctypes_test.c + + class Nested1(Structure): + _fields_ = [ + ('an_int', c_int), + ('another_int', c_int), + ] + + class Test4(Union): + _fields_ = [ + ('a_long', c_long), + ('a_struct', Nested1), + ] + + class Nested2(Structure): + _fields_ = [ + ('an_int', c_int), + ('a_union', Test4), + ] + + class Test5(Structure): + _fields_ = [ + ('an_int', c_int), + ('nested', Nested2), + ('another_int', c_int), + ] + + test4 = Test4() + dll = CDLL(_ctypes_test.__file__) + with self.assertRaises(TypeError) as ctx: + func = dll._testfunc_union_by_value1 + func.restype = c_long + func.argtypes = (Test4,) + result = func(test4) + self.assertEqual(ctx.exception.args[0], 'item 1 in _argtypes_ passes ' + 'a union by value, which is unsupported.') + test5 = Test5() + with self.assertRaises(TypeError) as ctx: + func = dll._testfunc_union_by_value2 + func.restype = c_long + func.argtypes = (Test5,) + result = func(test5) + self.assertEqual(ctx.exception.args[0], 'item 1 in _argtypes_ passes ' + 'a union by value, which is unsupported.') + + # passing by reference should be OK + test4.a_long = 12345; + func = dll._testfunc_union_by_reference1 + func.restype = c_long + func.argtypes = (POINTER(Test4),) + result = func(byref(test4)) + self.assertEqual(result, 12345) + self.assertEqual(test4.a_long, 0) + self.assertEqual(test4.a_struct.an_int, 0) + self.assertEqual(test4.a_struct.another_int, 0) + test4.a_struct.an_int = 0x12340000 + test4.a_struct.another_int = 0x5678 + func = dll._testfunc_union_by_reference2 + func.restype = c_long + func.argtypes = (POINTER(Test4),) + result = func(byref(test4)) + self.assertEqual(result, 0x12345678) + self.assertEqual(test4.a_long, 0) + self.assertEqual(test4.a_struct.an_int, 0) + self.assertEqual(test4.a_struct.another_int, 0) + test5.an_int = 0x12000000 + test5.nested.an_int = 0x345600 + test5.another_int = 0x78 + func = dll._testfunc_union_by_reference3 + func.restype = c_long + func.argtypes = (POINTER(Test5),) + result = func(byref(test5)) + self.assertEqual(result, 0x12345678) + self.assertEqual(test5.an_int, 0) + self.assertEqual(test5.nested.an_int, 0) + self.assertEqual(test5.another_int, 0) + + #@unittest.skipIf('s390' in MACHINE, 'Test causes segfault on S390') + def test_bitfield_by_value(self): + # See bpo-16576 + + # These should mirror the structures in Modules/_ctypes/_ctypes_test.c + + class Test6(Structure): + _fields_ = [ + ('A', c_int, 1), + ('B', c_int, 2), + ('C', c_int, 3), + ('D', c_int, 2), + ] + + test6 = Test6() + # As these are signed int fields, all are logically -1 due to sign + # extension. + test6.A = 1 + test6.B = 3 + test6.C = 7 + test6.D = 3 + dll = CDLL(_ctypes_test.__file__) + with self.assertRaises(TypeError) as ctx: + func = dll._testfunc_bitfield_by_value1 + func.restype = c_long + func.argtypes = (Test6,) + result = func(test6) + self.assertEqual(ctx.exception.args[0], 'item 1 in _argtypes_ passes ' + 'a struct/union with a bitfield by value, which is ' + 'unsupported.') + # passing by reference should be OK + func = dll._testfunc_bitfield_by_reference1 + func.restype = c_long + func.argtypes = (POINTER(Test6),) + result = func(byref(test6)) + self.assertEqual(result, -4) + self.assertEqual(test6.A, 0) + self.assertEqual(test6.B, 0) + self.assertEqual(test6.C, 0) + self.assertEqual(test6.D, 0) + + class Test7(Structure): + _fields_ = [ + ('A', c_uint, 1), + ('B', c_uint, 2), + ('C', c_uint, 3), + ('D', c_uint, 2), + ] + test7 = Test7() + test7.A = 1 + test7.B = 3 + test7.C = 7 + test7.D = 3 + func = dll._testfunc_bitfield_by_reference2 + func.restype = c_long + func.argtypes = (POINTER(Test7),) + result = func(byref(test7)) + self.assertEqual(result, 14) + self.assertEqual(test7.A, 0) + self.assertEqual(test7.B, 0) + self.assertEqual(test7.C, 0) + self.assertEqual(test7.D, 0) + + # for a union with bitfields, the union check happens first + class Test8(Union): + _fields_ = [ + ('A', c_int, 1), + ('B', c_int, 2), + ('C', c_int, 3), + ('D', c_int, 2), + ] + + test8 = Test8() + with self.assertRaises(TypeError) as ctx: + func = dll._testfunc_bitfield_by_value2 + func.restype = c_long + func.argtypes = (Test8,) + result = func(test8) + self.assertEqual(ctx.exception.args[0], 'item 1 in _argtypes_ passes ' + 'a union by value, which is unsupported.') + class PointerMemberTestCase(unittest.TestCase): def test(self): diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 33e2646..146468b 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -368,23 +368,24 @@ def _create_fn(name, args, body, *, globals=None, locals=None, # worries about external callers. if locals is None: locals = {} - # __builtins__ may be the "builtins" module or - # the value of its "__dict__", - # so make sure "__builtins__" is the module. - if globals is not None and '__builtins__' not in globals: - globals['__builtins__'] = builtins + if 'BUILTINS' not in locals: + locals['BUILTINS'] = builtins return_annotation = '' if return_type is not MISSING: locals['_return_type'] = return_type return_annotation = '->_return_type' args = ','.join(args) - body = '\n'.join(f' {b}' for b in body) + body = '\n'.join(f' {b}' for b in body) # Compute the text of the entire function. - txt = f'def {name}({args}){return_annotation}:\n{body}' + txt = f' def {name}({args}){return_annotation}:\n{body}' - exec(txt, globals, locals) - return locals[name] + local_vars = ', '.join(locals.keys()) + txt = f"def __create_fn__({local_vars}):\n{txt}\n return {name}" + + ns = {} + exec(txt, globals, ns) + return ns['__create_fn__'](**locals) def _field_assign(frozen, name, value, self_name): @@ -395,7 +396,7 @@ def _field_assign(frozen, name, value, self_name): # self_name is what "self" is called in this function: don't # hard-code "self", since that might be a field name. if frozen: - return f'__builtins__.object.__setattr__({self_name},{name!r},{value})' + return f'BUILTINS.object.__setattr__({self_name},{name!r},{value})' return f'{self_name}.{name}={value}' @@ -472,7 +473,7 @@ def _init_param(f): return f'{f.name}:_type_{f.name}{default}' -def _init_fn(fields, frozen, has_post_init, self_name): +def _init_fn(fields, frozen, has_post_init, self_name, globals): # fields contains both real fields and InitVar pseudo-fields. # Make sure we don't have fields without defaults following fields @@ -490,12 +491,15 @@ def _init_fn(fields, frozen, has_post_init, self_name): raise TypeError(f'non-default argument {f.name!r} ' 'follows default argument') - globals = {'MISSING': MISSING, - '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY} + locals = {f'_type_{f.name}': f.type for f in fields} + locals.update({ + 'MISSING': MISSING, + '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY, + }) body_lines = [] for f in fields: - line = _field_init(f, frozen, globals, self_name) + line = _field_init(f, frozen, locals, self_name) # line is None means that this field doesn't require # initialization (it's a pseudo-field). Just skip it. if line: @@ -511,7 +515,6 @@ def _init_fn(fields, frozen, has_post_init, self_name): if not body_lines: body_lines = ['pass'] - locals = {f'_type_{f.name}': f.type for f in fields} return _create_fn('__init__', [self_name] + [_init_param(f) for f in fields if f.init], body_lines, @@ -520,20 +523,19 @@ def _init_fn(fields, frozen, has_post_init, self_name): return_type=None) -def _repr_fn(fields): +def _repr_fn(fields, globals): fn = _create_fn('__repr__', ('self',), ['return self.__class__.__qualname__ + f"(' + ', '.join([f"{f.name}={{self.{f.name}!r}}" for f in fields]) + - ')"']) + ')"'], + globals=globals) return _recursive_repr(fn) -def _frozen_get_del_attr(cls, fields): - # XXX: globals is modified on the first call to _create_fn, then - # the modified version is used in the second call. Is this okay? - globals = {'cls': cls, +def _frozen_get_del_attr(cls, fields, globals): + locals = {'cls': cls, 'FrozenInstanceError': FrozenInstanceError} if fields: fields_str = '(' + ','.join(repr(f.name) for f in fields) + ',)' @@ -545,17 +547,19 @@ def _frozen_get_del_attr(cls, fields): (f'if type(self) is cls or name in {fields_str}:', ' raise FrozenInstanceError(f"cannot assign to field {name!r}")', f'super(cls, self).__setattr__(name, value)'), + locals=locals, globals=globals), _create_fn('__delattr__', ('self', 'name'), (f'if type(self) is cls or name in {fields_str}:', ' raise FrozenInstanceError(f"cannot delete field {name!r}")', f'super(cls, self).__delattr__(name)'), + locals=locals, globals=globals), ) -def _cmp_fn(name, op, self_tuple, other_tuple): +def _cmp_fn(name, op, self_tuple, other_tuple, globals): # Create a comparison function. If the fields in the object are # named 'x' and 'y', then self_tuple is the string # '(self.x,self.y)' and other_tuple is the string @@ -565,14 +569,16 @@ def _cmp_fn(name, op, self_tuple, other_tuple): ('self', 'other'), [ 'if other.__class__ is self.__class__:', f' return {self_tuple}{op}{other_tuple}', - 'return NotImplemented']) + 'return NotImplemented'], + globals=globals) -def _hash_fn(fields): +def _hash_fn(fields, globals): self_tuple = _tuple_str('self', fields) return _create_fn('__hash__', ('self',), - [f'return hash({self_tuple})']) + [f'return hash({self_tuple})'], + globals=globals) def _is_classvar(a_type, typing): @@ -744,14 +750,14 @@ def _set_new_attribute(cls, name, value): # take. The common case is to do nothing, so instead of providing a # function that is a no-op, use None to signify that. -def _hash_set_none(cls, fields): +def _hash_set_none(cls, fields, globals): return None -def _hash_add(cls, fields): +def _hash_add(cls, fields, globals): flds = [f for f in fields if (f.compare if f.hash is None else f.hash)] - return _hash_fn(flds) + return _hash_fn(flds, globals) -def _hash_exception(cls, fields): +def _hash_exception(cls, fields, globals): # Raise an exception. raise TypeError(f'Cannot overwrite attribute __hash__ ' f'in class {cls.__name__}') @@ -793,6 +799,16 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen): # is defined by the base class, which is found first. fields = {} + if cls.__module__ in sys.modules: + globals = sys.modules[cls.__module__].__dict__ + else: + # Theoretically this can happen if someone writes + # a custom string to cls.__module__. In which case + # such dataclass won't be fully introspectable + # (w.r.t. typing.get_type_hints) but will still function + # correctly. + globals = {} + setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order, unsafe_hash, frozen)) @@ -902,6 +918,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen): # if possible. '__dataclass_self__' if 'self' in fields else 'self', + globals, )) # Get the fields as a list, and include only real fields. This is @@ -910,7 +927,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen): if repr: flds = [f for f in field_list if f.repr] - _set_new_attribute(cls, '__repr__', _repr_fn(flds)) + _set_new_attribute(cls, '__repr__', _repr_fn(flds, globals)) if eq: # Create _eq__ method. There's no need for a __ne__ method, @@ -920,7 +937,8 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen): other_tuple = _tuple_str('other', flds) _set_new_attribute(cls, '__eq__', _cmp_fn('__eq__', '==', - self_tuple, other_tuple)) + self_tuple, other_tuple, + globals=globals)) if order: # Create and set the ordering methods. @@ -933,13 +951,14 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen): ('__ge__', '>='), ]: if _set_new_attribute(cls, name, - _cmp_fn(name, op, self_tuple, other_tuple)): + _cmp_fn(name, op, self_tuple, other_tuple, + globals=globals)): raise TypeError(f'Cannot overwrite attribute {name} ' f'in class {cls.__name__}. Consider using ' 'functools.total_ordering') if frozen: - for fn in _frozen_get_del_attr(cls, field_list): + for fn in _frozen_get_del_attr(cls, field_list, globals): if _set_new_attribute(cls, fn.__name__, fn): raise TypeError(f'Cannot overwrite attribute {fn.__name__} ' f'in class {cls.__name__}') @@ -952,7 +971,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen): if hash_action: # No need to call _set_new_attribute here, since by the time # we're here the overwriting is unconditional. - cls.__hash__ = hash_action(cls, field_list) + cls.__hash__ = hash_action(cls, field_list, globals) if not getattr(cls, '__doc__'): # Create a class doc-string. diff --git a/Lib/difflib.py b/Lib/difflib.py index 887c3c2..9528690 100644 --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -1085,7 +1085,7 @@ import re def IS_LINE_JUNK(line, pat=re.compile(r"\s*(?:#\s*)?$").match): r""" - Return 1 for ignorable line: iff `line` is blank or contains a single '#'. + Return True for ignorable line: iff `line` is blank or contains a single '#'. Examples: @@ -1101,7 +1101,7 @@ def IS_LINE_JUNK(line, pat=re.compile(r"\s*(?:#\s*)?$").match): def IS_CHARACTER_JUNK(ch, ws=" \t"): r""" - Return 1 for ignorable character: iff `ch` is a space or tab. + Return True for ignorable character: iff `ch` is a space or tab. Examples: diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py index 7cc9a46..3197d49 100644 --- a/Lib/email/_header_value_parser.py +++ b/Lib/email/_header_value_parser.py @@ -1055,7 +1055,7 @@ def get_encoded_word(value): value = ''.join(remainder) try: text, charset, lang, defects = _ew.decode('=?' + tok + '?=') - except ValueError: + except (ValueError, KeyError): raise _InvalidEwError( "encoded word format invalid: '{}'".format(ew.cte)) ew.charset = charset diff --git a/Lib/encodings/uu_codec.py b/Lib/encodings/uu_codec.py index 2a5728f..4e58c62 100644 --- a/Lib/encodings/uu_codec.py +++ b/Lib/encodings/uu_codec.py @@ -20,6 +20,10 @@ def uu_encode(input, errors='strict', filename='', mode=0o666): read = infile.read write = outfile.write + # Remove newline chars from filename + filename = filename.replace('\n','\\n') + filename = filename.replace('\r','\\r') + # Encode write(('begin %o %s\n' % (mode & 0o777, filename)).encode('ascii')) chunk = read(45) diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py index 1bed893..d43a219 100644 --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -213,10 +213,14 @@ LOOSE_HTTP_DATE_RE = re.compile( (?::(\d\d))? # optional seconds )? # optional clock \s* - ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+)? # timezone + (?: + ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+) # timezone + \s* + )? + (?: + \(\w+\) # ASCII representation of timezone in parens. \s* - (?:\(\w+\))? # ASCII representation of timezone in parens. - \s*$""", re.X | re.ASCII) + )?$""", re.X | re.ASCII) def http2time(text): """Returns time in seconds since epoch of time represented by a string. @@ -286,9 +290,11 @@ ISO_DATE_RE = re.compile( (?::?(\d\d(?:\.\d*)?))? # optional seconds (and fractional) )? # optional clock \s* - ([-+]?\d\d?:?(:?\d\d)? - |Z|z)? # timezone (Z is "zero meridian", i.e. GMT) - \s*$""", re.X | re. ASCII) + (?: + ([-+]?\d\d?:?(:?\d\d)? + |Z|z) # timezone (Z is "zero meridian", i.e. GMT) + \s* + )?$""", re.X | re. ASCII) def iso2time(text): """ As for http2time, but parses the ISO 8601 formats: diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 32fda8c..5caa98e 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -1,7 +1,43 @@ +What's New in IDLE 3.7.6 +Released on 2019-12-16? +====================================== + + +bpo-38943: Fix autocomplete windows not always appearing on some +systems. Patch by Johnny Najera. + +bpo-38944: Excape key now closes IDLE completion windows. Patch by +Johnny Najera. + +bpo-38862: 'Strip Trailing Whitespace' on the Format menu removes extra +newlines at the end of non-shell files. + +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, +editor, and output windows. See Settings, General, Window Preferences, +Cursor Blink. Patch by Zachary Spytz. + +bpo-26353: Stop adding newline when saving an IDLE shell window. + +bpo-38598: Do not try to compile IDLE shell or output windows. + + What's New in IDLE 3.7.5 -Released on 2019-09-30? +Released on 2019-10-15 ====================================== +bpo-36698: IDLE no longer fails when writing non-encodable characters +to stderr. It now escapes them with a backslash, like the regular +Python interpreter. Add an errors field to the standard streams. + +bpo-13153: Improve tkinter's handing of non-BMP (astral) unicode +characters, such as 'rocket \U0001f680'. Whether a proper glyph or +replacement char is displayed depends on the OS and font. For IDLE, +astral chars in code interfere with editing. + bpo-35379: When exiting IDLE, catch any AttributeError. One happens when EditorWindow.close is called twice. Printing a traceback, when IDLE is run from a terminal, is useless and annoying. diff --git a/Lib/idlelib/autocomplete_w.py b/Lib/idlelib/autocomplete_w.py index 5035e06..0643c09 100644 --- a/Lib/idlelib/autocomplete_w.py +++ b/Lib/idlelib/autocomplete_w.py @@ -17,7 +17,7 @@ KEYPRESS_VIRTUAL_EVENT_NAME = "<>" # before the default specific IDLE function KEYPRESS_SEQUENCES = ("", "", "", "", "", "", "", "", - "", "") + "", "", "") KEYRELEASE_VIRTUAL_EVENT_NAME = "<>" KEYRELEASE_SEQUENCE = "" LISTUPDATE_SEQUENCE = "" @@ -257,6 +257,7 @@ class AutoCompleteWindow: # place acw above current line new_y -= acw_height acw.wm_geometry("+%d+%d" % (new_x, new_y)) + acw.update_idletasks() if platform.system().startswith('Windows'): # See issue 15786. When on Windows platform, Tk will misbehave diff --git a/Lib/idlelib/config-main.def b/Lib/idlelib/config-main.def index b2be625..28ae941 100644 --- a/Lib/idlelib/config-main.def +++ b/Lib/idlelib/config-main.def @@ -59,6 +59,7 @@ delete-exitfunc= 1 [EditorWindow] width= 80 height= 40 +cursor-blink= 1 font= TkFixedFont # For TkFixedFont, the actual size and boldness are obtained from tk # and override 10 and 0. See idlelib.config.IdleConf.GetFont diff --git a/Lib/idlelib/config.py b/Lib/idlelib/config.py index 12e6f9f..04444a3 100644 --- a/Lib/idlelib/config.py +++ b/Lib/idlelib/config.py @@ -158,6 +158,8 @@ class IdleConf: self.defaultCfg = {} self.userCfg = {} self.cfg = {} # TODO use to select userCfg vs defaultCfg + # self.blink_off_time = ['insertofftime'] + # See https:/bugs.python.org/issue4630, msg356516. if not _utest: self.CreateConfigHandlers() diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index df21658..aaf319b 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -236,6 +236,7 @@ class ConfigDialog(Toplevel): instance.set_notabs_indentwidth() instance.ApplyKeybindings() instance.reset_help_menu_entries() + instance.update_cursor_blink() for klass in reloadables: klass.reload() @@ -1820,6 +1821,9 @@ class GenPage(Frame): (*)win_width_int: Entry - win_width win_height_title: Label (*)win_height_int: Entry - win_height + frame_cursor_blink: Frame + cursor_blink_title: Label + (*)cursor_blink_bool: Checkbutton - cursor_blink frame_autocomplete: Frame auto_wait_title: Label (*)auto_wait_int: Entry - autocomplete_wait @@ -1864,6 +1868,8 @@ class GenPage(Frame): StringVar(self), ('main', 'EditorWindow', 'width')) self.win_height = tracers.add( StringVar(self), ('main', 'EditorWindow', 'height')) + self.cursor_blink = tracers.add( + BooleanVar(self), ('main', 'EditorWindow', 'cursor-blink')) self.autocomplete_wait = tracers.add( StringVar(self), ('extensions', 'AutoComplete', 'popupwait')) self.paren_style = tracers.add( @@ -1920,6 +1926,11 @@ class GenPage(Frame): validatecommand=self.digits_only, validate='key', ) + frame_cursor_blink = Frame(frame_window, borderwidth=0) + cursor_blink_title = Label(frame_cursor_blink, text='Cursor Blink') + self.cursor_blink_bool = Checkbutton(frame_cursor_blink, + variable=self.cursor_blink, width=1) + frame_autocomplete = Frame(frame_window, borderwidth=0,) auto_wait_title = Label(frame_autocomplete, text='Completions Popup Wait (milliseconds)') @@ -2024,6 +2035,10 @@ class GenPage(Frame): win_height_title.pack(side=RIGHT, anchor=E, pady=5) self.win_width_int.pack(side=RIGHT, anchor=E, padx=10, pady=5) win_width_title.pack(side=RIGHT, anchor=E, pady=5) + # frame_cursor_blink. + frame_cursor_blink.pack(side=TOP, padx=5, pady=0, fill=X) + cursor_blink_title.pack(side=LEFT, anchor=W, padx=5, pady=5) + self.cursor_blink_bool.pack(side=LEFT, padx=5, pady=5) # frame_autocomplete. frame_autocomplete.pack(side=TOP, padx=5, pady=0, fill=X) auto_wait_title.pack(side=LEFT, anchor=W, padx=5, pady=5) @@ -2078,6 +2093,8 @@ class GenPage(Frame): 'main', 'EditorWindow', 'width', type='int')) self.win_height.set(idleConf.GetOption( 'main', 'EditorWindow', 'height', type='int')) + self.cursor_blink.set(idleConf.GetOption( + 'main', 'EditorWindow', 'cursor-blink', type='bool')) self.autocomplete_wait.set(idleConf.GetOption( 'extensions', 'AutoComplete', 'popupwait', type='int')) self.paren_style.set(idleConf.GetOption( diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index b969f8c..92dcf57 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -186,8 +186,9 @@ class EditorWindow(object): text.bind("<>", fregion.uncomment_region_event) text.bind("<>", fregion.tabify_region_event) text.bind("<>", fregion.untabify_region_event) - text.bind("<>", self.Indents.toggle_tabs_event) - text.bind("<>", self.Indents.change_indentwidth_event) + indents = self.Indents(self) + text.bind("<>", indents.toggle_tabs_event) + text.bind("<>", indents.change_indentwidth_event) text.bind("", self.move_at_edge_if_selection(0)) text.bind("", self.move_at_edge_if_selection(1)) text.bind("<>", self.del_word_left) @@ -241,6 +242,12 @@ class EditorWindow(object): self.indentwidth = self.tabwidth self.set_notabs_indentwidth() + # Store the current value of the insertofftime now so we can restore + # it if needed. + if not hasattr(idleConf, 'blink_off_time'): + idleConf.blink_off_time = self.text['insertofftime'] + self.update_cursor_blink() + # When searching backwards for a reliable place to begin parsing, # first start num_context_lines[0] lines back, then # num_context_lines[1] lines back if that didn't work, and so on. @@ -358,21 +365,6 @@ class EditorWindow(object): Font(text, font=text.cget('font')).measure('0') self.width = pixel_width // zero_char_width - def _filename_to_unicode(self, filename): - """Return filename as BMP unicode so displayable in Tk.""" - # Decode bytes to unicode. - if isinstance(filename, bytes): - try: - filename = filename.decode(self.filesystemencoding) - except UnicodeDecodeError: - try: - filename = filename.decode(self.encoding) - except UnicodeDecodeError: - # byte-to-byte conversion - filename = filename.decode('iso8859-1') - # Replace non-BMP char with diamond questionmark. - return re.sub('[\U00010000-\U0010FFFF]', '\ufffd', filename) - def new_callback(self, event): dirname, basename = self.io.defaultfilename() self.flist.new(dirname) @@ -818,6 +810,16 @@ class EditorWindow(object): text.mark_set("insert", pos + "+1c") text.see(pos) + def update_cursor_blink(self): + "Update the cursor blink configuration." + cursorblink = idleConf.GetOption( + 'main', 'EditorWindow', 'cursor-blink', type='bool') + if not cursorblink: + self.text['insertofftime'] = 0 + else: + # Restore the original value + self.text['insertofftime'] = idleConf.blink_off_time + def ResetFont(self): "Update the text widgets' font if it is changed" # Called from configdialog.py @@ -963,10 +965,8 @@ class EditorWindow(object): menu.delete(0, END) # clear, and rebuild: for i, file_name in enumerate(rf_list): file_name = file_name.rstrip() # zap \n - # make unicode string to display non-ASCII chars correctly - ufile_name = self._filename_to_unicode(file_name) callback = instance.__recent_file_callback(file_name) - menu.add_command(label=ulchars[i] + " " + ufile_name, + menu.add_command(label=ulchars[i] + " " + file_name, command=callback, underline=0) @@ -1004,16 +1004,10 @@ class EditorWindow(object): def short_title(self): filename = self.io.filename - if filename: - filename = os.path.basename(filename) - else: - filename = "untitled" - # return unicode string to display non-ASCII chars correctly - return self._filename_to_unicode(filename) + return os.path.basename(filename) if filename else "untitled" def long_title(self): - # return unicode string to display non-ASCII chars correctly - return self._filename_to_unicode(self.io.filename or "") + return self.io.filename or "" def center_insert_event(self, event): self.center() diff --git a/Lib/idlelib/format.py b/Lib/idlelib/format.py index bced4c1..4b57a18 100644 --- a/Lib/idlelib/format.py +++ b/Lib/idlelib/format.py @@ -353,8 +353,7 @@ class FormatRegion: maxvalue=16) -# With mixed indents not allowed, these are semi-useless and not unittested. -class Indents: # pragma: no cover +class Indents: "Change future indents." def __init__(self, editwin): @@ -409,6 +408,16 @@ class Rstrip: # 'Strip Trailing Whitespace" on "Format" menu. if cut < raw: text.delete('%i.%i' % (cur, cut), '%i.end' % cur) + if (text.get('end-2c') == '\n' # File ends with at least 1 newline; + and not hasattr(self.editwin, 'interp')): # & is not Shell. + # Delete extra user endlines. + while (text.index('end-1c') > '1.0' # Stop if file empty. + and text.get('end-3c') == '\n'): + text.delete('end-3c') + # Because tk indexes are slice indexes and never raise, + # a file with only newlines will be emptied. + # patchcheck.py does the same. + undo.undo_block_stop() diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index 0754f24..09dc4c5 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -4,7 +4,7 @@ - IDLE — Python 3.9.0a0 documentation + IDLE — Python 3.9.0a1 documentation @@ -17,14 +17,14 @@ - + @@ -62,7 +62,7 @@ next |
  • - previous |
  • - 3.9.0a0 Documentation » + 3.9.0a1 Documentation »
  • @@ -240,7 +240,8 @@ paragraph will be formatted to less than N columns, where N defaults to 72.

    Strip trailing whitespace

    Remove trailing space and other whitespace characters after the last non-whitespace character of a line by applying str.rstrip to each line, -including lines within multiline strings.

    +including lines within multiline strings. Except for Shell windows, +remove extra newlines at the end of the file.

    @@ -886,8 +887,8 @@ also used for testing.

    Previous topic

    -

    tkinter.scrolledtext — Scrolled Text Widget

    +

    tkinter.tix — Extension widgets for Tk

    Next topic

    Other Graphical User Interface Packages

    @@ -919,7 +920,7 @@ also used for testing.

    next |
  • - previous |
  • - 3.9.0a0 Documentation » + 3.9.0a1 Documentation »
  • @@ -959,11 +960,11 @@ also used for testing.



    - Last updated on Sep 01, 2019. + Last updated on Nov 24, 2019. Found a bug?
    - Created using Sphinx 2.1.2. + Created using Sphinx 2.1.1. diff --git a/Lib/idlelib/idle_test/mock_idle.py b/Lib/idlelib/idle_test/mock_idle.py index f279a52..71fa480 100644 --- a/Lib/idlelib/idle_test/mock_idle.py +++ b/Lib/idlelib/idle_test/mock_idle.py @@ -40,8 +40,9 @@ class Func: class Editor: '''Minimally imitate editor.EditorWindow class. ''' - def __init__(self, flist=None, filename=None, key=None, root=None): - self.text = Text() + def __init__(self, flist=None, filename=None, key=None, root=None, + text=None): # Allow real Text with mock Editor. + self.text = text or Text() self.undo = UndoDelegator() def get_selection_indices(self): diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index 37e8343..1f14ed1 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -1135,6 +1135,10 @@ class GenPageTest(unittest.TestCase): d.win_width_int.insert(0, '11') self.assertEqual(mainpage, {'EditorWindow': {'width': '11'}}) + def test_cursor_blink(self): + self.page.cursor_blink_bool.invoke() + self.assertEqual(mainpage, {'EditorWindow': {'cursor-blink': 'False'}}) + def test_autocomplete_wait(self): self.page.auto_wait_int.delete(0, 'end') self.page.auto_wait_int.insert(0, '11') diff --git a/Lib/idlelib/idle_test/test_editor.py b/Lib/idlelib/idle_test/test_editor.py index 4af4ff0..240db71 100644 --- a/Lib/idlelib/idle_test/test_editor.py +++ b/Lib/idlelib/idle_test/test_editor.py @@ -30,18 +30,6 @@ class EditorWindowTest(unittest.TestCase): e._close() -class EditorFunctionTest(unittest.TestCase): - - def test_filename_to_unicode(self): - func = Editor._filename_to_unicode - class dummy(): - filesystemencoding = 'utf-8' - pairs = (('abc', 'abc'), ('a\U00011111c', 'a\ufffdc'), - (b'abc', 'abc'), (b'a\xf0\x91\x84\x91c', 'a\ufffdc')) - for inp, out in pairs: - self.assertEqual(func(dummy, inp), out) - - class TestGetLineIndent(unittest.TestCase): def test_empty_lines(self): for tabwidth in [1, 2, 4, 6, 8]: diff --git a/Lib/idlelib/idle_test/test_format.py b/Lib/idlelib/idle_test/test_format.py index c7b123e..a79bb51 100644 --- a/Lib/idlelib/idle_test/test_format.py +++ b/Lib/idlelib/idle_test/test_format.py @@ -417,7 +417,7 @@ class FormatRegionTest(unittest.TestCase): self.text.delete('1.0', 'end') code_sample = """\ - +# WS line needed for test. class C1(): # Class comment. def __init__(self, a, b): @@ -574,39 +574,70 @@ class C1(): self.assertEqual(ask(), 10) -class rstripTest(unittest.TestCase): +class IndentsTest(unittest.TestCase): - def test_rstrip_line(self): - editor = MockEditor() - text = editor.text - do_rstrip = ft.Rstrip(editor).do_rstrip - eq = self.assertEqual + @mock.patch.object(ft, "askyesno") + def test_toggle_tabs(self, askyesno): + editor = DummyEditwin(None, None) # usetabs == False. + indents = ft.Indents(editor) + askyesno.return_value = True + + indents.toggle_tabs_event(None) + self.assertEqual(editor.usetabs, True) + self.assertEqual(editor.indentwidth, 8) + + indents.toggle_tabs_event(None) + self.assertEqual(editor.usetabs, False) + self.assertEqual(editor.indentwidth, 8) + + @mock.patch.object(ft, "askinteger") + def test_change_indentwidth(self, askinteger): + editor = DummyEditwin(None, None) # indentwidth == 4. + indents = ft.Indents(editor) + + askinteger.return_value = None + indents.change_indentwidth_event(None) + self.assertEqual(editor.indentwidth, 4) - do_rstrip() - eq(text.get('1.0', 'insert'), '') - text.insert('1.0', ' ') - do_rstrip() - eq(text.get('1.0', 'insert'), '') - text.insert('1.0', ' \n') - do_rstrip() - eq(text.get('1.0', 'insert'), '\n') - - def test_rstrip_multiple(self): - editor = MockEditor() - # Comment above, uncomment 3 below to test with real Editor & Text. - #from idlelib.editor import EditorWindow as Editor - #from tkinter import Tk - #editor = Editor(root=Tk()) - text = editor.text - do_rstrip = ft.Rstrip(editor).do_rstrip + askinteger.return_value = 3 + indents.change_indentwidth_event(None) + self.assertEqual(editor.indentwidth, 3) + askinteger.return_value = 5 + editor.usetabs = True + indents.change_indentwidth_event(None) + self.assertEqual(editor.indentwidth, 3) + + +class RstripTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + cls.text = Text(cls.root) + cls.editor = MockEditor(text=cls.text) + cls.do_rstrip = ft.Rstrip(cls.editor).do_rstrip + + @classmethod + def tearDownClass(cls): + del cls.text, cls.do_rstrip, cls.editor + cls.root.update_idletasks() + cls.root.destroy() + del cls.root + + def tearDown(self): + self.text.delete('1.0', 'end-1c') + + def test_rstrip_lines(self): original = ( "Line with an ending tab \n" "Line ending in 5 spaces \n" "Linewithnospaces\n" " indented line\n" " indented line with trailing space \n" - " ") + " \n") stripped = ( "Line with an ending tab\n" "Line ending in 5 spaces\n" @@ -614,9 +645,23 @@ class rstripTest(unittest.TestCase): " indented line\n" " indented line with trailing space\n") - text.insert('1.0', original) - do_rstrip() - self.assertEqual(text.get('1.0', 'insert'), stripped) + self.text.insert('1.0', original) + self.do_rstrip() + self.assertEqual(self.text.get('1.0', 'insert'), stripped) + + def test_rstrip_end(self): + text = self.text + for code in ('', '\n', '\n\n\n'): + with self.subTest(code=code): + text.insert('1.0', code) + self.do_rstrip() + self.assertEqual(text.get('1.0','end-1c'), '') + for code in ('a\n', 'a\n\n', 'a\n\n\n'): + with self.subTest(code=code): + text.delete('1.0', 'end-1c') + text.insert('1.0', code) + self.do_rstrip() + self.assertEqual(text.get('1.0','end-1c'), 'a\n') if __name__ == '__main__': diff --git a/Lib/idlelib/idle_test/test_iomenu.py b/Lib/idlelib/idle_test/test_iomenu.py index 743a05b..99f4048 100644 --- a/Lib/idlelib/idle_test/test_iomenu.py +++ b/Lib/idlelib/idle_test/test_iomenu.py @@ -1,14 +1,13 @@ -"Test , coverage 16%." +"Test , coverage 17%." from idlelib import iomenu import unittest from test.support import requires from tkinter import Tk - from idlelib.editor import EditorWindow -class IOBindigTest(unittest.TestCase): +class IOBindingTest(unittest.TestCase): @classmethod def setUpClass(cls): @@ -16,9 +15,11 @@ class IOBindigTest(unittest.TestCase): cls.root = Tk() cls.root.withdraw() cls.editwin = EditorWindow(root=cls.root) + cls.io = iomenu.IOBinding(cls.editwin) @classmethod def tearDownClass(cls): + cls.io.close() cls.editwin._close() del cls.editwin cls.root.update_idletasks() @@ -28,9 +29,20 @@ class IOBindigTest(unittest.TestCase): del cls.root def test_init(self): - io = iomenu.IOBinding(self.editwin) - self.assertIs(io.editwin, self.editwin) - io.close + self.assertIs(self.io.editwin, self.editwin) + + def test_fixnewlines_end(self): + eq = self.assertEqual + io = self.io + fix = io.fixnewlines + text = io.editwin.text + self.editwin.interp = None + eq(fix(), '') + del self.editwin.interp + text.insert(1.0, 'a') + eq(fix(), 'a'+io.eol_convention) + eq(text.get('1.0', 'end-1c'), 'a\n') + eq(fix(), 'a'+io.eol_convention) if __name__ == '__main__': diff --git a/Lib/idlelib/idle_test/test_run.py b/Lib/idlelib/idle_test/test_run.py index cad0b4d..9995dbe 100644 --- a/Lib/idlelib/idle_test/test_run.py +++ b/Lib/idlelib/idle_test/test_run.py @@ -36,7 +36,7 @@ class RunTest(unittest.TestCase): self.assertIn('UnhashableException: ex1', tb[10]) -# PseudoFile tests. +# StdioFile tests. class S(str): def __str__(self): @@ -68,14 +68,14 @@ class MockShell: self.lines = list(lines)[::-1] -class PseudeInputFilesTest(unittest.TestCase): +class StdInputFilesTest(unittest.TestCase): def test_misc(self): shell = MockShell() - f = run.PseudoInputFile(shell, 'stdin', 'utf-8') + f = run.StdInputFile(shell, 'stdin') self.assertIsInstance(f, io.TextIOBase) self.assertEqual(f.encoding, 'utf-8') - self.assertIsNone(f.errors) + self.assertEqual(f.errors, 'strict') self.assertIsNone(f.newlines) self.assertEqual(f.name, '') self.assertFalse(f.closed) @@ -86,7 +86,7 @@ class PseudeInputFilesTest(unittest.TestCase): def test_unsupported(self): shell = MockShell() - f = run.PseudoInputFile(shell, 'stdin', 'utf-8') + f = run.StdInputFile(shell, 'stdin') self.assertRaises(OSError, f.fileno) self.assertRaises(OSError, f.tell) self.assertRaises(OSError, f.seek, 0) @@ -95,7 +95,7 @@ class PseudeInputFilesTest(unittest.TestCase): def test_read(self): shell = MockShell() - f = run.PseudoInputFile(shell, 'stdin', 'utf-8') + f = run.StdInputFile(shell, 'stdin') shell.push(['one\n', 'two\n', '']) self.assertEqual(f.read(), 'one\ntwo\n') shell.push(['one\n', 'two\n', '']) @@ -115,7 +115,7 @@ class PseudeInputFilesTest(unittest.TestCase): def test_readline(self): shell = MockShell() - f = run.PseudoInputFile(shell, 'stdin', 'utf-8') + f = run.StdInputFile(shell, 'stdin') shell.push(['one\n', 'two\n', 'three\n', 'four\n']) self.assertEqual(f.readline(), 'one\n') self.assertEqual(f.readline(-1), 'two\n') @@ -140,7 +140,7 @@ class PseudeInputFilesTest(unittest.TestCase): def test_readlines(self): shell = MockShell() - f = run.PseudoInputFile(shell, 'stdin', 'utf-8') + f = run.StdInputFile(shell, 'stdin') shell.push(['one\n', 'two\n', '']) self.assertEqual(f.readlines(), ['one\n', 'two\n']) shell.push(['one\n', 'two\n', '']) @@ -161,7 +161,7 @@ class PseudeInputFilesTest(unittest.TestCase): def test_close(self): shell = MockShell() - f = run.PseudoInputFile(shell, 'stdin', 'utf-8') + f = run.StdInputFile(shell, 'stdin') shell.push(['one\n', 'two\n', '']) self.assertFalse(f.closed) self.assertEqual(f.readline(), 'one\n') @@ -171,14 +171,14 @@ class PseudeInputFilesTest(unittest.TestCase): self.assertRaises(TypeError, f.close, 1) -class PseudeOutputFilesTest(unittest.TestCase): +class StdOutputFilesTest(unittest.TestCase): def test_misc(self): shell = MockShell() - f = run.PseudoOutputFile(shell, 'stdout', 'utf-8') + f = run.StdOutputFile(shell, 'stdout') self.assertIsInstance(f, io.TextIOBase) self.assertEqual(f.encoding, 'utf-8') - self.assertIsNone(f.errors) + self.assertEqual(f.errors, 'strict') self.assertIsNone(f.newlines) self.assertEqual(f.name, '') self.assertFalse(f.closed) @@ -189,7 +189,7 @@ class PseudeOutputFilesTest(unittest.TestCase): def test_unsupported(self): shell = MockShell() - f = run.PseudoOutputFile(shell, 'stdout', 'utf-8') + f = run.StdOutputFile(shell, 'stdout') self.assertRaises(OSError, f.fileno) self.assertRaises(OSError, f.tell) self.assertRaises(OSError, f.seek, 0) @@ -198,16 +198,36 @@ class PseudeOutputFilesTest(unittest.TestCase): def test_write(self): shell = MockShell() - f = run.PseudoOutputFile(shell, 'stdout', 'utf-8') + f = run.StdOutputFile(shell, 'stdout') f.write('test') self.assertEqual(shell.written, [('test', 'stdout')]) shell.reset() - f.write('t\xe8st') - self.assertEqual(shell.written, [('t\xe8st', 'stdout')]) + f.write('t\xe8\u015b\U0001d599') + self.assertEqual(shell.written, [('t\xe8\u015b\U0001d599', 'stdout')]) shell.reset() - f.write(S('t\xe8st')) - self.assertEqual(shell.written, [('t\xe8st', 'stdout')]) + f.write(S('t\xe8\u015b\U0001d599')) + self.assertEqual(shell.written, [('t\xe8\u015b\U0001d599', 'stdout')]) + self.assertEqual(type(shell.written[0][0]), str) + shell.reset() + + self.assertRaises(TypeError, f.write) + self.assertEqual(shell.written, []) + self.assertRaises(TypeError, f.write, b'test') + self.assertRaises(TypeError, f.write, 123) + self.assertEqual(shell.written, []) + self.assertRaises(TypeError, f.write, 'test', 'spam') + self.assertEqual(shell.written, []) + + def test_write_stderr_nonencodable(self): + shell = MockShell() + f = run.StdOutputFile(shell, 'stderr', 'iso-8859-15', 'backslashreplace') + f.write('t\xe8\u015b\U0001d599\xa4') + self.assertEqual(shell.written, [('t\xe8\\u015b\\U0001d599\\xa4', 'stderr')]) + shell.reset() + + f.write(S('t\xe8\u015b\U0001d599\xa4')) + self.assertEqual(shell.written, [('t\xe8\\u015b\\U0001d599\\xa4', 'stderr')]) self.assertEqual(type(shell.written[0][0]), str) shell.reset() @@ -221,7 +241,7 @@ class PseudeOutputFilesTest(unittest.TestCase): def test_writelines(self): shell = MockShell() - f = run.PseudoOutputFile(shell, 'stdout', 'utf-8') + f = run.StdOutputFile(shell, 'stdout') f.writelines([]) self.assertEqual(shell.written, []) shell.reset() @@ -251,7 +271,7 @@ class PseudeOutputFilesTest(unittest.TestCase): def test_close(self): shell = MockShell() - f = run.PseudoOutputFile(shell, 'stdout', 'utf-8') + f = run.StdOutputFile(shell, 'stdout') self.assertFalse(f.closed) f.write('test') f.close() diff --git a/Lib/idlelib/iomenu.py b/Lib/idlelib/iomenu.py index b9e813b..4b2833b 100644 --- a/Lib/idlelib/iomenu.py +++ b/Lib/idlelib/iomenu.py @@ -15,6 +15,7 @@ from idlelib.config import idleConf if idlelib.testing: # Set True by test.test_idle to avoid setlocale. encoding = 'utf-8' + errors = 'surrogateescape' else: # Try setting the locale, so that we can find out # what encoding to use @@ -24,15 +25,9 @@ else: except (ImportError, locale.Error): pass - locale_decode = 'ascii' if sys.platform == 'win32': - # On Windows, we could use "mbcs". However, to give the user - # a portable encoding name, we need to find the code page - try: - locale_encoding = locale.getdefaultlocale()[1] - codecs.lookup(locale_encoding) - except LookupError: - pass + encoding = 'utf-8' + errors = 'surrogateescape' else: try: # Different things can fail here: the locale module may not be @@ -40,30 +35,30 @@ else: # resulting codeset may be unknown to Python. We ignore all # these problems, falling back to ASCII locale_encoding = locale.nl_langinfo(locale.CODESET) - if locale_encoding is None or locale_encoding == '': - # situation occurs on macOS - locale_encoding = 'ascii' - codecs.lookup(locale_encoding) + if locale_encoding: + codecs.lookup(locale_encoding) except (NameError, AttributeError, LookupError): # Try getdefaultlocale: it parses environment variables, # which may give a clue. Unfortunately, getdefaultlocale has # bugs that can cause ValueError. try: locale_encoding = locale.getdefaultlocale()[1] - if locale_encoding is None or locale_encoding == '': - # situation occurs on macOS - locale_encoding = 'ascii' - codecs.lookup(locale_encoding) + if locale_encoding: + codecs.lookup(locale_encoding) except (ValueError, LookupError): pass - locale_encoding = locale_encoding.lower() - - encoding = locale_encoding - # Encoding is used in multiple files; locale_encoding nowhere. - # The only use of 'encoding' below is in _decode as initial value - # of deprecated block asking user for encoding. - # Perhaps use elsewhere should be reviewed. + if locale_encoding: + encoding = locale_encoding.lower() + errors = 'strict' + else: + # POSIX locale or macOS + encoding = 'ascii' + errors = 'surrogateescape' + # Encoding is used in multiple files; locale_encoding nowhere. + # The only use of 'encoding' below is in _decode as initial value + # of deprecated block asking user for encoding. + # Perhaps use elsewhere should be reviewed. coding_re = re.compile(r'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)', re.ASCII) blank_re = re.compile(r'^[ \t\f]*(?:[#\r\n]|$)', re.ASCII) @@ -376,10 +371,7 @@ class IOBinding: return "break" def writefile(self, filename): - self.fixlastline() - text = self.text.get("1.0", "end-1c") - if self.eol_convention != "\n": - text = text.replace("\n", self.eol_convention) + text = self.fixnewlines() chars = self.encode(text) try: with open(filename, "wb") as f: @@ -392,6 +384,16 @@ class IOBinding: parent=self.text) return False + def fixnewlines(self): + "Return text with final \n if needed and os eols." + if (self.text.get("end-2c") != '\n' + and not hasattr(self.editwin, "interp")): # Not shell. + self.text.insert("end-1c", "\n") + text = self.text.get("1.0", "end-1c") + if self.eol_convention != "\n": + text = text.replace("\n", self.eol_convention) + return text + def encode(self, chars): if isinstance(chars, bytes): # This is either plain ASCII, or Tk was returning mixed-encoding @@ -431,11 +433,6 @@ class IOBinding: # declared encoding return BOM_UTF8 + chars.encode("utf-8") - def fixlastline(self): - c = self.text.get("end-2c") - if c != '\n': - self.text.insert("end-1c", "\n") - def print_window(self, event): confirm = tkMessageBox.askokcancel( title="Print", diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index 2e4dfad..065122d 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -54,7 +54,7 @@ from idlelib.editor import EditorWindow, fixwordbreaks from idlelib.filelist import FileList from idlelib.outwin import OutputWindow from idlelib import rpc -from idlelib.run import idle_formatwarning, PseudoInputFile, PseudoOutputFile +from idlelib.run import idle_formatwarning, StdInputFile, StdOutputFile from idlelib.undo import UndoDelegator HOST = '127.0.0.1' # python execution server on localhost loopback @@ -679,14 +679,6 @@ class ModifiedInterpreter(InteractiveInterpreter): self.more = 0 # at the moment, InteractiveInterpreter expects str assert isinstance(source, str) - #if isinstance(source, str): - # from idlelib import iomenu - # try: - # source = source.encode(iomenu.encoding) - # except UnicodeError: - # self.tkconsole.resetoutput() - # self.write("Unsupported characters in input\n") - # return # InteractiveInterpreter.runsource() calls its runcode() method, # which is overridden (see below) return InteractiveInterpreter.runsource(self, source, filename) @@ -910,10 +902,14 @@ class PyShell(OutputWindow): self.save_stderr = sys.stderr self.save_stdin = sys.stdin from idlelib import iomenu - self.stdin = PseudoInputFile(self, "stdin", iomenu.encoding) - self.stdout = PseudoOutputFile(self, "stdout", iomenu.encoding) - self.stderr = PseudoOutputFile(self, "stderr", iomenu.encoding) - self.console = PseudoOutputFile(self, "console", iomenu.encoding) + self.stdin = StdInputFile(self, "stdin", + iomenu.encoding, iomenu.errors) + self.stdout = StdOutputFile(self, "stdout", + iomenu.encoding, iomenu.errors) + self.stderr = StdOutputFile(self, "stderr", + iomenu.encoding, "backslashreplace") + self.console = StdOutputFile(self, "console", + iomenu.encoding, iomenu.errors) if not use_subprocess: sys.stdout = self.stdout sys.stderr = self.stderr @@ -1298,16 +1294,6 @@ class PyShell(OutputWindow): self.set_line_and_column() def write(self, s, tags=()): - if isinstance(s, str) and len(s) and max(s) > '\uffff': - # Tk doesn't support outputting non-BMP characters - # Let's assume what printed string is not very long, - # find first non-BMP character and construct informative - # UnicodeEncodeError exception. - for start, char in enumerate(s): - if char > '\uffff': - break - raise UnicodeEncodeError("UCS-2", char, start, start+1, - 'Non-BMP character not supported in Tk') try: self.text.mark_gravity("iomark", "right") count = OutputWindow.write(self, s, tags, "iomark") diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 41e0ded..5bd84aa 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -401,18 +401,23 @@ class MyRPCServer(rpc.RPCServer): # Pseudofiles for shell-remote communication (also used in pyshell) -class PseudoFile(io.TextIOBase): +class StdioFile(io.TextIOBase): - def __init__(self, shell, tags, encoding=None): + def __init__(self, shell, tags, encoding='utf-8', errors='strict'): self.shell = shell self.tags = tags self._encoding = encoding + self._errors = errors @property def encoding(self): return self._encoding @property + def errors(self): + return self._errors + + @property def name(self): return '<%s>' % self.tags @@ -420,7 +425,7 @@ class PseudoFile(io.TextIOBase): return True -class PseudoOutputFile(PseudoFile): +class StdOutputFile(StdioFile): def writable(self): return True @@ -428,19 +433,12 @@ class PseudoOutputFile(PseudoFile): def write(self, s): if self.closed: raise ValueError("write to closed file") - if type(s) is not str: - if not isinstance(s, str): - raise TypeError('must be str, not ' + type(s).__name__) - # See issue #19481 - s = str.__str__(s) + s = str.encode(s, self.encoding, self.errors).decode(self.encoding, self.errors) return self.shell.write(s, self.tags) -class PseudoInputFile(PseudoFile): - - def __init__(self, shell, tags, encoding=None): - PseudoFile.__init__(self, shell, tags, encoding) - self._line_buffer = '' +class StdInputFile(StdioFile): + _line_buffer = '' def readable(self): return True @@ -495,12 +493,12 @@ class MyHandler(rpc.RPCHandler): executive = Executive(self) self.register("exec", executive) self.console = self.get_remote_proxy("console") - sys.stdin = PseudoInputFile(self.console, "stdin", - iomenu.encoding) - sys.stdout = PseudoOutputFile(self.console, "stdout", - iomenu.encoding) - sys.stderr = PseudoOutputFile(self.console, "stderr", - iomenu.encoding) + sys.stdin = StdInputFile(self.console, "stdin", + iomenu.encoding, iomenu.errors) + sys.stdout = StdOutputFile(self.console, "stdout", + iomenu.encoding, iomenu.errors) + sys.stderr = StdOutputFile(self.console, "stderr", + iomenu.encoding, "backslashreplace") sys.displayhook = rpc.displayhook # page help() text to shell. diff --git a/Lib/idlelib/runscript.py b/Lib/idlelib/runscript.py index de73bf8..a541087 100644 --- a/Lib/idlelib/runscript.py +++ b/Lib/idlelib/runscript.py @@ -19,6 +19,7 @@ from idlelib.config import idleConf from idlelib import macosx from idlelib import pyshell from idlelib.query import CustomRun +from idlelib import outwin indent_message = """Error: Inconsistent indentation detected! @@ -46,6 +47,9 @@ class ScriptBinding: self.editwin.text_frame.bind('<>', self._run_module_event) def check_module_event(self, event): + if isinstance(self.editwin, outwin.OutputWindow): + self.editwin.text.bell() + return 'break' filename = self.getfilename() if not filename: return 'break' @@ -129,6 +133,9 @@ class ScriptBinding: module being executed and also add that directory to its sys.path if not already included. """ + if isinstance(self.editwin, outwin.OutputWindow): + self.editwin.text.bell() + return 'break' filename = self.getfilename() if not filename: return 'break' @@ -147,8 +154,7 @@ class ScriptBinding: interp = self.shell.interp if pyshell.use_subprocess and restart: interp.restart_subprocess( - with_cwd=False, filename= - self.editwin._filename_to_unicode(filename)) + with_cwd=False, filename=filename) dirname = os.path.dirname(filename) argv = [filename] if self.cli_args: diff --git a/Lib/json/tool.py b/Lib/json/tool.py index 5932f4e..8e63dbd 100644 --- a/Lib/json/tool.py +++ b/Lib/json/tool.py @@ -20,9 +20,9 @@ def main(): description = ('A simple command line interface for json module ' 'to validate and pretty-print JSON objects.') parser = argparse.ArgumentParser(prog=prog, description=description) - parser.add_argument('infile', nargs='?', type=argparse.FileType(), + parser.add_argument('infile', nargs='?', type=argparse.FileType(encoding="utf-8"), help='a JSON file to be validated or pretty-printed') - parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'), + parser.add_argument('outfile', nargs='?', type=argparse.FileType('w', encoding="utf-8"), help='write the output of infile to outfile') parser.add_argument('--sort-keys', action='store_true', default=False, help='sort the output of dictionaries alphabetically by key') diff --git a/Lib/lib2to3/Grammar.txt b/Lib/lib2to3/Grammar.txt index a7ddad3..68b7386 100644 --- a/Lib/lib2to3/Grammar.txt +++ b/Lib/lib2to3/Grammar.txt @@ -138,8 +138,8 @@ arglist: argument (',' argument)* [','] # that precede iterable unpackings are blocked; etc. argument: ( test [comp_for] | test '=' test | - '**' expr | - star_expr ) + '**' test | + '*' test ) comp_iter: comp_for | comp_if comp_for: [ASYNC] 'for' exprlist 'in' testlist_safe [comp_iter] diff --git a/Lib/lib2to3/fixes/fix_apply.py b/Lib/lib2to3/fixes/fix_apply.py index 826ec8c..6408582 100644 --- a/Lib/lib2to3/fixes/fix_apply.py +++ b/Lib/lib2to3/fixes/fix_apply.py @@ -37,10 +37,8 @@ class FixApply(fixer_base.BaseFix): # I feel like we should be able to express this logic in the # PATTERN above but I don't know how to do it so... if args: - if args.type == self.syms.star_expr: - return # Make no change. if (args.type == self.syms.argument and - args.children[0].value == '**'): + args.children[0].value in {'**', '*'}): return # Make no change. if kwds and (kwds.type == self.syms.argument and kwds.children[0].value == '**'): diff --git a/Lib/lib2to3/fixes/fix_intern.py b/Lib/lib2to3/fixes/fix_intern.py index a852330..d752843 100644 --- a/Lib/lib2to3/fixes/fix_intern.py +++ b/Lib/lib2to3/fixes/fix_intern.py @@ -30,10 +30,8 @@ class FixIntern(fixer_base.BaseFix): # PATTERN above but I don't know how to do it so... obj = results['obj'] if obj: - if obj.type == self.syms.star_expr: - return # Make no change. if (obj.type == self.syms.argument and - obj.children[0].value == '**'): + obj.children[0].value in {'**', '*'}): return # Make no change. names = ('sys', 'intern') new = ImportAndCall(node, results, names) diff --git a/Lib/lib2to3/fixes/fix_reload.py b/Lib/lib2to3/fixes/fix_reload.py index 6c7fbbd..b308411 100644 --- a/Lib/lib2to3/fixes/fix_reload.py +++ b/Lib/lib2to3/fixes/fix_reload.py @@ -27,10 +27,8 @@ class FixReload(fixer_base.BaseFix): # PATTERN above but I don't know how to do it so... obj = results['obj'] if obj: - if obj.type == self.syms.star_expr: - return # Make no change. if (obj.type == self.syms.argument and - obj.children[0].value == '**'): + obj.children[0].value in {'**', '*'}): return # Make no change. names = ('importlib', 'reload') new = ImportAndCall(node, results, names) diff --git a/Lib/lib2to3/tests/test_parser.py b/Lib/lib2to3/tests/test_parser.py index 829e5a7..7ec881e 100644 --- a/Lib/lib2to3/tests/test_parser.py +++ b/Lib/lib2to3/tests/test_parser.py @@ -253,6 +253,13 @@ class TestUnpackingGeneralizations(GrammarTest): def test_double_star_dict_literal_after_keywords(self): self.validate("""func(spam='fried', **{'eggs':'scrambled'})""") + def test_double_star_expression(self): + self.validate("""func(**{'a':2} or {})""") + self.validate("""func(**() or {})""") + + def test_star_expression(self): + self.validate("""func(*[] or [2])""") + def test_list_display(self): self.validate("""[*{2}, 3, *[4]]""") diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 24437f8..d868254 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -187,6 +187,9 @@ class _WindowsFlavour(_Flavour): def casefold_parts(self, parts): return [p.lower() for p in parts] + def compile_pattern(self, pattern): + return re.compile(fnmatch.translate(pattern), re.IGNORECASE).fullmatch + def resolve(self, path, strict=False): s = str(path) if not s: @@ -309,6 +312,9 @@ class _PosixFlavour(_Flavour): def casefold_parts(self, parts): return parts + def compile_pattern(self, pattern): + return re.compile(fnmatch.translate(pattern)).fullmatch + def resolve(self, path, strict=False): sep = self.sep accessor = path._accessor @@ -444,7 +450,7 @@ _normal_accessor = _NormalAccessor() # Globbing helpers # -def _make_selector(pattern_parts): +def _make_selector(pattern_parts, flavour): pat = pattern_parts[0] child_parts = pattern_parts[1:] if pat == '**': @@ -455,7 +461,7 @@ def _make_selector(pattern_parts): cls = _WildcardSelector else: cls = _PreciseSelector - return cls(pat, child_parts) + return cls(pat, child_parts, flavour) if hasattr(functools, "lru_cache"): _make_selector = functools.lru_cache()(_make_selector) @@ -465,10 +471,10 @@ class _Selector: """A selector matches a specific glob pattern part against the children of a given path.""" - def __init__(self, child_parts): + def __init__(self, child_parts, flavour): self.child_parts = child_parts if child_parts: - self.successor = _make_selector(child_parts) + self.successor = _make_selector(child_parts, flavour) self.dironly = True else: self.successor = _TerminatingSelector() @@ -494,9 +500,9 @@ class _TerminatingSelector: class _PreciseSelector(_Selector): - def __init__(self, name, child_parts): + def __init__(self, name, child_parts, flavour): self.name = name - _Selector.__init__(self, child_parts) + _Selector.__init__(self, child_parts, flavour) def _select_from(self, parent_path, is_dir, exists, scandir): try: @@ -510,13 +516,12 @@ class _PreciseSelector(_Selector): class _WildcardSelector(_Selector): - def __init__(self, pat, child_parts): - self.pat = re.compile(fnmatch.translate(pat)) - _Selector.__init__(self, child_parts) + def __init__(self, pat, child_parts, flavour): + self.match = flavour.compile_pattern(pat) + _Selector.__init__(self, child_parts, flavour) def _select_from(self, parent_path, is_dir, exists, scandir): try: - cf = parent_path._flavour.casefold entries = list(scandir(parent_path)) for entry in entries: entry_is_dir = False @@ -527,8 +532,7 @@ class _WildcardSelector(_Selector): raise if not self.dironly or entry_is_dir: name = entry.name - casefolded = cf(name) - if self.pat.match(casefolded): + if self.match(name): path = parent_path._make_child_relpath(name) for p in self.successor._select_from(path, is_dir, exists, scandir): yield p @@ -539,8 +543,8 @@ class _WildcardSelector(_Selector): class _RecursiveWildcardSelector(_Selector): - def __init__(self, pat, child_parts): - _Selector.__init__(self, child_parts) + def __init__(self, pat, child_parts, flavour): + _Selector.__init__(self, child_parts, flavour) def _iterate_directories(self, parent_path, is_dir, scandir): yield parent_path @@ -793,7 +797,11 @@ class PurePath(object): @property def suffix(self): - """The final component's last suffix, if any.""" + """ + The final component's last suffix, if any. + + This includes the leading period. For example: '.txt' + """ name = self.name i = name.rfind('.') if 0 < i < len(name) - 1: @@ -803,7 +811,11 @@ class PurePath(object): @property def suffixes(self): - """A list of the final component's suffixes, if any.""" + """ + A list of the final component's suffixes, if any. + + These include the leading periods. For example: ['.tar', '.gz'] + """ name = self.name if name.endswith('.'): return [] @@ -1101,11 +1113,10 @@ class Path(PurePath): """ if not pattern: raise ValueError("Unacceptable pattern: {!r}".format(pattern)) - pattern = self._flavour.casefold(pattern) drv, root, pattern_parts = self._flavour.parse_parts((pattern,)) if drv or root: raise NotImplementedError("Non-relative patterns are unsupported") - selector = _make_selector(tuple(pattern_parts)) + selector = _make_selector(tuple(pattern_parts), self._flavour) for p in selector.select_from(self): yield p @@ -1114,11 +1125,10 @@ class Path(PurePath): directories) matching the given relative pattern, anywhere in this subtree. """ - pattern = self._flavour.casefold(pattern) drv, root, pattern_parts = self._flavour.parse_parts((pattern,)) if drv or root: raise NotImplementedError("Non-relative patterns are unsupported") - selector = _make_selector(("**",) + tuple(pattern_parts)) + selector = _make_selector(("**",) + tuple(pattern_parts), self._flavour) for p in selector.select_from(self): yield p diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index ffde9d4..0438309 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 Oct 14 18:26:58 2019 +# Autogenerated by Sphinx on Wed Dec 18 13:43:31 2019 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -735,10 +735,11 @@ topics = {'assert': 'The "assert" statement\n' 'returned.\n' '\n' 'The "__dir__" function should accept no arguments, and ' - 'return a list\n' - 'of strings that represents the names accessible on ' - 'module. If present,\n' - 'this function overrides the standard "dir()" search on a ' + 'return a\n' + 'sequence of strings that represents the names accessible ' + 'on module. If\n' + 'present, this function overrides the standard "dir()" ' + 'search on a\n' 'module.\n' '\n' 'For a more fine grained customization of the module ' @@ -833,6 +834,22 @@ topics = {'assert': 'The "assert" statement\n' 'created. The\n' ' descriptor has been assigned to *name*.\n' '\n' + ' Note: "__set_name__()" is only called implicitly as ' + 'part of the\n' + ' "type" constructor, so it will need to be called ' + 'explicitly with\n' + ' the appropriate parameters when a descriptor is ' + 'added to a class\n' + ' after initial creation:\n' + '\n' + ' class A:\n' + ' pass\n' + ' descr = custom_descriptor()\n' + ' A.attr = descr\n' + " descr.__set_name__(A, 'attr')\n" + '\n' + ' See Creating the class object for more details.\n' + '\n' ' New in version 3.6.\n' '\n' 'The attribute "__objclass__" is interpreted by the ' @@ -1061,7 +1078,13 @@ topics = {'assert': 'The "assert" statement\n' 'attributes created by\n' ' slots (the other bases must have empty slot layouts) - ' 'violations\n' - ' raise "TypeError".\n', + ' raise "TypeError".\n' + '\n' + '* If an iterator is used for *__slots__* then a ' + 'descriptor is\n' + ' created for each of the iterator’s values. However, ' + 'the *__slots__*\n' + ' attribute will be an empty iterator.\n', 'attribute-references': 'Attribute references\n' '********************\n' '\n' @@ -4199,6 +4222,17 @@ topics = {'assert': 'The "assert" statement\n' ' Quit from the debugger. The program being executed is ' 'aborted.\n' '\n' + 'debug code\n' + '\n' + ' Enter a recursive debugger that steps through the code ' + 'argument\n' + ' (which is an arbitrary expression or statement to be executed ' + 'in\n' + ' the current environment).\n' + '\n' + 'retval\n' + 'Print the return value for the last return of a function.\n' + '\n' '-[ Footnotes ]-\n' '\n' '[1] Whether a frame is considered to originate in a certain ' @@ -7419,9 +7453,9 @@ topics = {'assert': 'The "assert" statement\n' 'to allow\n' 'efficient iteration through the container; for mappings, ' '"__iter__()"\n' - 'should be the same as "keys()"; for sequences, it should ' - 'iterate\n' - 'through the values.\n' + 'should iterate through the object’s keys; for sequences, ' + 'it should\n' + 'iterate through the values.\n' '\n' 'object.__len__(self)\n' '\n' @@ -7573,12 +7607,12 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'The membership test operators ("in" and "not in") are ' 'normally\n' - 'implemented as an iteration through a sequence. However, ' + 'implemented as an iteration through a container. However, ' 'container\n' 'objects can supply the following special method with a ' 'more efficient\n' 'implementation, which also does not require the object be ' - 'a sequence.\n' + 'iterable.\n' '\n' 'object.__contains__(self, item)\n' '\n' @@ -8358,10 +8392,11 @@ topics = {'assert': 'The "assert" statement\n' 'returned.\n' '\n' 'The "__dir__" function should accept no arguments, and ' - 'return a list\n' - 'of strings that represents the names accessible on module. ' - 'If present,\n' - 'this function overrides the standard "dir()" search on a ' + 'return a\n' + 'sequence of strings that represents the names accessible on ' + 'module. If\n' + 'present, this function overrides the standard "dir()" search ' + 'on a\n' 'module.\n' '\n' 'For a more fine grained customization of the module behavior ' @@ -8456,6 +8491,22 @@ topics = {'assert': 'The "assert" statement\n' 'The\n' ' descriptor has been assigned to *name*.\n' '\n' + ' Note: "__set_name__()" is only called implicitly as part ' + 'of the\n' + ' "type" constructor, so it will need to be called ' + 'explicitly with\n' + ' the appropriate parameters when a descriptor is added ' + 'to a class\n' + ' after initial creation:\n' + '\n' + ' class A:\n' + ' pass\n' + ' descr = custom_descriptor()\n' + ' A.attr = descr\n' + " descr.__set_name__(A, 'attr')\n" + '\n' + ' See Creating the class object for more details.\n' + '\n' ' New in version 3.6.\n' '\n' 'The attribute "__objclass__" is interpreted by the "inspect" ' @@ -8682,6 +8733,12 @@ topics = {'assert': 'The "assert" statement\n' 'violations\n' ' raise "TypeError".\n' '\n' + '* If an iterator is used for *__slots__* then a descriptor ' + 'is\n' + ' created for each of the iterator’s values. However, the ' + '*__slots__*\n' + ' attribute will be an empty iterator.\n' + '\n' '\n' 'Customizing class creation\n' '==========================\n' @@ -9127,9 +9184,9 @@ topics = {'assert': 'The "assert" statement\n' 'allow\n' 'efficient iteration through the container; for mappings, ' '"__iter__()"\n' - 'should be the same as "keys()"; for sequences, it should ' - 'iterate\n' - 'through the values.\n' + 'should iterate through the object’s keys; for sequences, it ' + 'should\n' + 'iterate through the values.\n' '\n' 'object.__len__(self)\n' '\n' @@ -9280,12 +9337,12 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'The membership test operators ("in" and "not in") are ' 'normally\n' - 'implemented as an iteration through a sequence. However, ' + 'implemented as an iteration through a container. However, ' 'container\n' 'objects can supply the following special method with a more ' 'efficient\n' - 'implementation, which also does not require the object be a ' - 'sequence.\n' + 'implementation, which also does not require the object be ' + 'iterable.\n' '\n' 'object.__contains__(self, item)\n' '\n' @@ -9881,20 +9938,20 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'str.isalnum()\n' '\n' - ' Return true if all characters in the string are ' + ' Return "True" if all characters in the string are ' 'alphanumeric and\n' - ' there is at least one character, false otherwise. A ' - 'character "c"\n' - ' is alphanumeric if one of the following returns ' + ' there is at least one character, "False" otherwise. A ' + 'character\n' + ' "c" is alphanumeric if one of the following returns ' '"True":\n' ' "c.isalpha()", "c.isdecimal()", "c.isdigit()", or ' '"c.isnumeric()".\n' '\n' 'str.isalpha()\n' '\n' - ' Return true if all characters in the string are ' + ' Return "True" if all characters in the string are ' 'alphabetic and\n' - ' there is at least one character, false otherwise. ' + ' there is at least one character, "False" otherwise. ' 'Alphabetic\n' ' characters are those characters defined in the Unicode ' 'character\n' @@ -9908,45 +9965,46 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'str.isascii()\n' '\n' - ' Return true if the string is empty or all characters in ' - 'the string\n' - ' are ASCII, false otherwise. ASCII characters have code ' - 'points in\n' - ' the range U+0000-U+007F.\n' + ' Return "True" if the string is empty or all characters ' + 'in the\n' + ' string are ASCII, "False" otherwise. ASCII characters ' + 'have code\n' + ' points in the range U+0000-U+007F.\n' '\n' ' New in version 3.7.\n' '\n' 'str.isdecimal()\n' '\n' - ' Return true if all characters in the string are decimal ' - 'characters\n' - ' and there is at least one character, false otherwise. ' - 'Decimal\n' - ' characters are those that can be used to form numbers ' - 'in base 10,\n' - ' e.g. U+0660, ARABIC-INDIC DIGIT ZERO. Formally a ' - 'decimal character\n' - ' is a character in the Unicode General Category “Nd”.\n' + ' Return "True" if all characters in the string are ' + 'decimal\n' + ' characters and there is at least one character, "False" ' + 'otherwise.\n' + ' Decimal characters are those that can be used to form ' + 'numbers in\n' + ' base 10, e.g. U+0660, ARABIC-INDIC DIGIT ZERO. ' + 'Formally a decimal\n' + ' character is a character in the Unicode General ' + 'Category “Nd”.\n' '\n' 'str.isdigit()\n' '\n' - ' Return true if all characters in the string are digits ' - 'and there is\n' - ' at least one character, false otherwise. Digits ' - 'include decimal\n' - ' characters and digits that need special handling, such ' - 'as the\n' - ' compatibility superscript digits. This covers digits ' - 'which cannot\n' - ' be used to form numbers in base 10, like the Kharosthi ' - 'numbers.\n' - ' Formally, a digit is a character that has the property ' - 'value\n' - ' Numeric_Type=Digit or Numeric_Type=Decimal.\n' + ' Return "True" if all characters in the string are ' + 'digits and there\n' + ' is at least one character, "False" otherwise. Digits ' + 'include\n' + ' decimal characters and digits that need special ' + 'handling, such as\n' + ' the compatibility superscript digits. This covers ' + 'digits which\n' + ' cannot be used to form numbers in base 10, like the ' + 'Kharosthi\n' + ' numbers. Formally, a digit is a character that has the ' + 'property\n' + ' value Numeric_Type=Digit or Numeric_Type=Decimal.\n' '\n' 'str.isidentifier()\n' '\n' - ' Return true if the string is a valid identifier ' + ' Return "True" if the string is a valid identifier ' 'according to the\n' ' language definition, section Identifiers and keywords.\n' '\n' @@ -9956,32 +10014,33 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'str.islower()\n' '\n' - ' Return true if all cased characters [4] in the string ' - 'are lowercase\n' - ' and there is at least one cased character, false ' - 'otherwise.\n' + ' Return "True" if all cased characters [4] in the string ' + 'are\n' + ' lowercase and there is at least one cased character, ' + '"False"\n' + ' otherwise.\n' '\n' 'str.isnumeric()\n' '\n' - ' Return true if all characters in the string are numeric ' - 'characters,\n' - ' and there is at least one character, false otherwise. ' - 'Numeric\n' - ' characters include digit characters, and all characters ' - 'that have\n' - ' the Unicode numeric value property, e.g. U+2155, VULGAR ' - 'FRACTION\n' - ' ONE FIFTH. Formally, numeric characters are those with ' - 'the\n' - ' property value Numeric_Type=Digit, Numeric_Type=Decimal ' - 'or\n' + ' Return "True" if all characters in the string are ' + 'numeric\n' + ' characters, and there is at least one character, ' + '"False" otherwise.\n' + ' Numeric characters include digit characters, and all ' + 'characters\n' + ' that have the Unicode numeric value property, e.g. ' + 'U+2155, VULGAR\n' + ' FRACTION ONE FIFTH. Formally, numeric characters are ' + 'those with\n' + ' the property value Numeric_Type=Digit, ' + 'Numeric_Type=Decimal or\n' ' Numeric_Type=Numeric.\n' '\n' 'str.isprintable()\n' '\n' - ' Return true if all characters in the string are ' + ' Return "True" if all characters in the string are ' 'printable or the\n' - ' string is empty, false otherwise. Nonprintable ' + ' string is empty, "False" otherwise. Nonprintable ' 'characters are\n' ' those characters defined in the Unicode character ' 'database as\n' @@ -9997,9 +10056,10 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'str.isspace()\n' '\n' - ' Return true if there are only whitespace characters in ' - 'the string\n' - ' and there is at least one character, false otherwise.\n' + ' Return "True" if there are only whitespace characters ' + 'in the string\n' + ' and there is at least one character, "False" ' + 'otherwise.\n' '\n' ' A character is *whitespace* if in the Unicode character ' 'database\n' @@ -10011,20 +10071,21 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'str.istitle()\n' '\n' - ' Return true if the string is a titlecased string and ' + ' Return "True" if the string is a titlecased string and ' 'there is at\n' ' least one character, for example uppercase characters ' 'may only\n' ' follow uncased characters and lowercase characters only ' 'cased ones.\n' - ' Return false otherwise.\n' + ' Return "False" otherwise.\n' '\n' 'str.isupper()\n' '\n' - ' Return true if all cased characters [4] in the string ' - 'are uppercase\n' - ' and there is at least one cased character, false ' - 'otherwise.\n' + ' Return "True" if all cased characters [4] in the string ' + 'are\n' + ' uppercase and there is at least one cased character, ' + '"False"\n' + ' otherwise.\n' '\n' 'str.join(iterable)\n' '\n' diff --git a/Lib/shlex.py b/Lib/shlex.py index 195dc12..48e31f4 100644 --- a/Lib/shlex.py +++ b/Lib/shlex.py @@ -302,6 +302,7 @@ class shlex: return token def split(s, comments=False, posix=True): + """Split the string *s* using shell-like syntax.""" lex = shlex(s, posix=posix) lex.whitespace_split = True if not comments: diff --git a/Lib/smtplib.py b/Lib/smtplib.py index 6091c7f..22d5097 100755 --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -54,7 +54,7 @@ import datetime import sys from email.base64mime import body_encode as encode_base64 -__all__ = ["SMTPException", "SMTPServerDisconnected", "SMTPResponseException", +__all__ = ["SMTPException", "SMTPNotSupportedError", "SMTPServerDisconnected", "SMTPResponseException", "SMTPSenderRefused", "SMTPRecipientsRefused", "SMTPDataError", "SMTPConnectError", "SMTPHeloError", "SMTPAuthenticationError", "quoteaddr", "quotedata", "SMTP"] diff --git a/Lib/socket.py b/Lib/socket.py index cfa605a..40c7636 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -724,7 +724,11 @@ def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT, sock.close() if err is not None: - raise err + try: + raise err + finally: + # Break explicitly a reference cycle + err = None else: raise error("getaddrinfo returns an empty list") diff --git a/Lib/socketserver.py b/Lib/socketserver.py index 905df93..1ad028f 100644 --- a/Lib/socketserver.py +++ b/Lib/socketserver.py @@ -24,7 +24,7 @@ For request-based servers (including socket-based): The classes in this module favor the server type that is simplest to write: a synchronous TCP/IP server. This is bad class design, but -save some typing. (There's also the issue that a deep class hierarchy +saves some typing. (There's also the issue that a deep class hierarchy slows down method lookups.) There are five classes in an inheritance diagram, four of which represent diff --git a/Lib/stat.py b/Lib/stat.py index 46837c0..165e057 100644 --- a/Lib/stat.py +++ b/Lib/stat.py @@ -40,6 +40,10 @@ S_IFREG = 0o100000 # regular file S_IFIFO = 0o010000 # fifo (named pipe) S_IFLNK = 0o120000 # symbolic link S_IFSOCK = 0o140000 # socket file +# Fallbacks for uncommon platform-specific constants +S_IFDOOR = 0 +S_IFPORT = 0 +S_IFWHT = 0 # Functions to test for each file type @@ -71,6 +75,18 @@ def S_ISSOCK(mode): """Return True if mode is from a socket.""" return S_IFMT(mode) == S_IFSOCK +def S_ISDOOR(mode): + """Return True if mode is from a door.""" + return False + +def S_ISPORT(mode): + """Return True if mode is from an event port.""" + return False + +def S_ISWHT(mode): + """Return True if mode is from a whiteout.""" + return False + # Names for permission bits S_ISUID = 0o4000 # set UID bit diff --git a/Lib/tempfile.py b/Lib/tempfile.py index 2143224..24f673c 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -637,10 +637,8 @@ class SpooledTemporaryFile: if 'b' in mode: self._file = _io.BytesIO() else: - # Setting newline="\n" avoids newline translation; - # this is important because otherwise on Windows we'd - # get double newline translation upon rollover(). - self._file = _io.StringIO(newline="\n") + self._file = _io.TextIOWrapper(_io.BytesIO(), + encoding=encoding, newline=newline) self._max_size = max_size self._rolled = False self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering, @@ -660,8 +658,12 @@ class SpooledTemporaryFile: newfile = self._file = TemporaryFile(**self._TemporaryFileArgs) del self._TemporaryFileArgs - newfile.write(file.getvalue()) - newfile.seek(file.tell(), 0) + pos = file.tell() + if hasattr(newfile, 'buffer'): + newfile.buffer.write(file.detach().getvalue()) + else: + newfile.write(file.getvalue()) + newfile.seek(pos, 0) self._rolled = True diff --git a/Lib/test/ann_module.py b/Lib/test/ann_module.py index 9e6b87d..0567d6d 100644 --- a/Lib/test/ann_module.py +++ b/Lib/test/ann_module.py @@ -6,6 +6,7 @@ Empty lines above are for good reason (testing for correct line numbers) """ from typing import Optional +from functools import wraps __annotations__[1] = 2 @@ -51,3 +52,9 @@ def foo(x: int = 10): def bar(y: List[str]): x: str = 'yes' bar() + +def dec(func): + @wraps(func) + def wrapper(*args, **kwargs): + return func(*args, **kwargs) + return wrapper diff --git a/Lib/test/dataclass_textanno.py b/Lib/test/dataclass_textanno.py new file mode 100644 index 0000000..3eb6c94 --- /dev/null +++ b/Lib/test/dataclass_textanno.py @@ -0,0 +1,12 @@ +from __future__ import annotations + +import dataclasses + + +class Foo: + pass + + +@dataclasses.dataclass +class Bar: + foo: Foo diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index 5ae8878..05878a8 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -138,16 +138,8 @@ class Regrtest: print(xml_data, file=sys.__stderr__) raise - def display_progress(self, test_index, text): - if self.ns.quiet: - return - - # "[ 51/405/1] test_tcl passed" - line = f"{test_index:{self.test_count_width}}{self.test_count}" - fails = len(self.bad) + len(self.environment_changed) - if fails and not self.ns.pgo: - line = f"{line}/{fails}" - line = f"[{line}] {text}" + def log(self, line=''): + empty = not line # add the system load prefix: "load avg: 1.80 " load_avg = self.getloadavg() @@ -158,8 +150,23 @@ class Regrtest: test_time = time.monotonic() - self.start_time test_time = datetime.timedelta(seconds=int(test_time)) line = f"{test_time} {line}" + + if empty: + line = line[:-1] + print(line, flush=True) + def display_progress(self, test_index, text): + if self.ns.quiet: + return + + # "[ 51/405/1] test_tcl passed" + line = f"{test_index:{self.test_count_width}}{self.test_count}" + fails = len(self.bad) + len(self.environment_changed) + if fails and not self.ns.pgo: + line = f"{line}/{fails}" + self.log(f"[{line}] {text}") + def parse_args(self, kwargs): ns = _parse_args(sys.argv[1:], **kwargs) @@ -297,11 +304,11 @@ class Regrtest: self.first_result = self.get_tests_result() - print() - print("Re-running failed tests in verbose mode") + self.log() + self.log("Re-running failed tests in verbose mode") self.rerun = self.bad[:] for test_name in self.rerun: - print(f"Re-running {test_name} in verbose mode", flush=True) + self.log(f"Re-running {test_name} in verbose mode") self.ns.verbose = True result = runtest(self.ns, test_name) @@ -382,7 +389,7 @@ class Regrtest: save_modules = sys.modules.keys() - print("Run tests sequentially") + self.log("Run tests sequentially") previous_test = None for test_index, test_name in enumerate(self.tests, 1): diff --git a/Lib/test/libregrtest/runtest_mp.py b/Lib/test/libregrtest/runtest_mp.py index 38b0578..2770cf9 100644 --- a/Lib/test/libregrtest/runtest_mp.py +++ b/Lib/test/libregrtest/runtest_mp.py @@ -22,6 +22,12 @@ from test.libregrtest.utils import format_duration, print_warning PROGRESS_UPDATE = 30.0 # seconds assert PROGRESS_UPDATE >= PROGRESS_MIN_TIME +# Kill the main process after 5 minutes. It is supposed to write an update +# every PROGRESS_UPDATE seconds. Tolerate 5 minutes for Python slowest +# buildbot workers. +MAIN_PROCESS_TIMEOUT = 5 * 60.0 +assert MAIN_PROCESS_TIMEOUT >= PROGRESS_UPDATE + # Time to wait until a worker completes: should be immediate JOIN_TIMEOUT = 30.0 # seconds @@ -104,13 +110,14 @@ class ExitThread(Exception): class TestWorkerProcess(threading.Thread): - def __init__(self, worker_id, pending, output, ns, timeout): + def __init__(self, worker_id, runner): super().__init__() self.worker_id = worker_id - self.pending = pending - self.output = output - self.ns = ns - self.timeout = timeout + self.pending = runner.pending + self.output = runner.output + self.ns = runner.ns + self.timeout = runner.worker_timeout + self.regrtest = runner.regrtest self.current_test_name = None self.start_time = None self._popen = None @@ -158,20 +165,6 @@ class TestWorkerProcess(threading.Thread): result = TestResult(test_name, error_type, test_time, None) return MultiprocessResult(result, stdout, stderr, err_msg) - def _timedout(self, test_name): - self._kill() - - stdout = stderr = '' - popen = self._popen - try: - stdout, stderr = popen.communicate(timeout=JOIN_TIMEOUT) - except (subprocess.TimeoutExpired, OSError) as exc: - print_warning(f"Failed to read {self} output " - f"(timeout={format_duration(JOIN_TIMEOUT)}): " - f"{exc!r}") - - return self.mp_result_error(test_name, TIMEOUT, stdout, stderr) - def _run_process(self, test_name): self.start_time = time.monotonic() @@ -194,23 +187,32 @@ class TestWorkerProcess(threading.Thread): try: stdout, stderr = popen.communicate(timeout=self.timeout) + retcode = popen.returncode + assert retcode is not None except subprocess.TimeoutExpired: if self._stopped: # kill() has been called: communicate() fails # on reading closed stdout/stderr raise ExitThread - return self._timedout(test_name) + # On timeout, kill the process + self._kill() + + # None means TIMEOUT for the caller + retcode = None + # bpo-38207: Don't attempt to call communicate() again: on it + # can hang until all child processes using stdout and stderr + # pipes completes. + stdout = stderr = '' except OSError: if self._stopped: # kill() has been called: communicate() fails # on reading closed stdout/stderr raise ExitThread raise - - retcode = popen.returncode - stdout = stdout.strip() - stderr = stderr.rstrip() + else: + stdout = stdout.strip() + stderr = stderr.rstrip() return (retcode, stdout, stderr) except: @@ -222,13 +224,10 @@ class TestWorkerProcess(threading.Thread): self.current_test_name = None def _runtest(self, test_name): - result = self._run_process(test_name) - - if isinstance(result, MultiprocessResult): - # _timedout() case - return result + retcode, stdout, stderr = self._run_process(test_name) - retcode, stdout, stderr = result + if retcode is None: + return self.mp_result_error(test_name, TIMEOUT, stdout, stderr) err_msg = None if retcode != 0: @@ -247,7 +246,8 @@ class TestWorkerProcess(threading.Thread): err_msg = "Failed to parse worker JSON: %s" % exc if err_msg is not None: - return self.mp_result_error(test_name, CHILD_ERROR, stdout, stderr, err_msg) + return self.mp_result_error(test_name, CHILD_ERROR, + stdout, stderr, err_msg) return MultiprocessResult(result, stdout, stderr, err_msg) @@ -286,13 +286,24 @@ class TestWorkerProcess(threading.Thread): f"{exc!r}") def wait_stopped(self, start_time): + # bpo-38207: MultiprocessTestRunner.stop_workers() called self.stop() + # which killed the process. Sometimes, killing the process from the + # main thread does not interrupt popen.communicate() in + # TestWorkerProcess thread. This loop with a timeout is a workaround + # for that. + # + # Moreover, if this method fails to join the thread, it is likely + # that Python will hang at exit while calling threading._shutdown() + # which tries again to join the blocked thread. Regrtest.main() + # uses EXIT_TIMEOUT to workaround this second bug. while True: # Write a message every second self.join(1.0) if not self.is_alive(): break dt = time.monotonic() - start_time - print(f"Waiting for {self} thread for {format_duration(dt)}", flush=True) + self.regrtest.log(f"Waiting for {self} thread " + f"for {format_duration(dt)}") if dt > JOIN_TIMEOUT: print_warning(f"Failed to join {self} in {format_duration(dt)}") break @@ -314,6 +325,7 @@ def get_running(workers): class MultiprocessTestRunner: def __init__(self, regrtest): self.regrtest = regrtest + self.log = self.regrtest.log self.ns = regrtest.ns self.output = queue.Queue() self.pending = MultiprocessIterator(self.regrtest.tests) @@ -324,11 +336,10 @@ class MultiprocessTestRunner: self.workers = None def start_workers(self): - self.workers = [TestWorkerProcess(index, self.pending, self.output, - self.ns, self.worker_timeout) + self.workers = [TestWorkerProcess(index, self) for index in range(1, self.ns.use_mp + 1)] - print("Run tests in parallel using %s child processes" - % len(self.workers)) + self.log("Run tests in parallel using %s child processes" + % len(self.workers)) for worker in self.workers: worker.start() @@ -351,7 +362,8 @@ class MultiprocessTestRunner: timeout = PROGRESS_UPDATE while True: if use_faulthandler: - faulthandler.dump_traceback_later(timeout * 2.0, exit=True) + faulthandler.dump_traceback_later(MAIN_PROCESS_TIMEOUT, + exit=True) # wait for a thread try: @@ -362,7 +374,7 @@ class MultiprocessTestRunner: # display progress running = get_running(self.workers) if running and not self.ns.pgo: - print('running: %s' % ', '.join(running), flush=True) + self.log('running: %s' % ', '.join(running)) def display_result(self, mp_result): result = mp_result.result @@ -382,8 +394,7 @@ class MultiprocessTestRunner: if item[0]: # Thread got an exception format_exc = item[1] - print(f"regrtest worker thread failed: {format_exc}", - file=sys.stderr, flush=True) + print_warning(f"regrtest worker thread failed: {format_exc}") return True self.test_index += 1 diff --git a/Lib/test/libregrtest/utils.py b/Lib/test/libregrtest/utils.py index fb9971a..98a60f7 100644 --- a/Lib/test/libregrtest/utils.py +++ b/Lib/test/libregrtest/utils.py @@ -16,11 +16,14 @@ def format_duration(seconds): if minutes: parts.append('%s min' % minutes) if seconds: - parts.append('%s sec' % seconds) - if ms: - parts.append('%s ms' % ms) + if parts: + # 2 min 1 sec + parts.append('%s sec' % seconds) + else: + # 1.0 sec + parts.append('%.1f sec' % (seconds + ms / 1000)) if not parts: - return '0 ms' + return '%s ms' % ms parts = parts[:2] return ' '.join(parts) diff --git a/Lib/test/libregrtest/win_utils.py b/Lib/test/libregrtest/win_utils.py index f0c17b9..028c011 100644 --- a/Lib/test/libregrtest/win_utils.py +++ b/Lib/test/libregrtest/win_utils.py @@ -1,4 +1,5 @@ import _winapi +import math import msvcrt import os import subprocess @@ -10,11 +11,14 @@ from test.libregrtest.utils import print_warning # Max size of asynchronous reads BUFSIZE = 8192 -# Exponential damping factor (see below) -LOAD_FACTOR_1 = 0.9200444146293232478931553241 - # Seconds per measurement -SAMPLING_INTERVAL = 5 +SAMPLING_INTERVAL = 1 +# Exponential damping factor to compute exponentially weighted moving average +# on 1 minute (60 seconds) +LOAD_FACTOR_1 = 1 / math.exp(SAMPLING_INTERVAL / 60) +# Initialize the load using the arithmetic mean of the first NVALUE values +# of the Processor Queue Length +NVALUE = 5 # Windows registry subkey of HKEY_LOCAL_MACHINE where the counter names # of typeperf are registered COUNTER_REGISTRY_KEY = (r"SOFTWARE\Microsoft\Windows NT\CurrentVersion" @@ -30,9 +34,10 @@ class WindowsLoadTracker(): """ def __init__(self): - self.load = 0.0 - self.counter_name = '' - self.popen = None + self._values = [] + self._load = None + self._buffer = '' + self._popen = None self.start() def start(self): @@ -64,7 +69,7 @@ class WindowsLoadTracker(): # Spawn off the load monitor counter_name = self._get_counter_name() command = ['typeperf', counter_name, '-si', str(SAMPLING_INTERVAL)] - self.popen = subprocess.Popen(' '.join(command), stdout=command_stdout, cwd=support.SAVEDCWD) + self._popen = subprocess.Popen(' '.join(command), stdout=command_stdout, cwd=support.SAVEDCWD) # Close our copy of the write end of the pipe os.close(command_stdout) @@ -84,52 +89,88 @@ class WindowsLoadTracker(): process_queue_length = counters_dict['44'] return f'"\\{system}\\{process_queue_length}"' - def close(self): - if self.popen is None: + def close(self, kill=True): + if self._popen is None: return - self.popen.kill() - self.popen.wait() - self.popen = None + + self._load = None + + if kill: + self._popen.kill() + self._popen.wait() + self._popen = None def __del__(self): self.close() - def read_output(self): + def _parse_line(self, line): + # typeperf outputs in a CSV format like this: + # "07/19/2018 01:32:26.605","3.000000" + # (date, process queue length) + tokens = line.split(',') + if len(tokens) != 2: + raise ValueError + + value = tokens[1] + if not value.startswith('"') or not value.endswith('"'): + raise ValueError + value = value[1:-1] + return float(value) + + def _read_lines(self): overlapped, _ = _winapi.ReadFile(self.pipe, BUFSIZE, True) bytes_read, res = overlapped.GetOverlappedResult(False) if res != 0: - return + return () output = overlapped.getbuffer() - return output.decode('oem', 'replace') + output = output.decode('oem', 'replace') + output = self._buffer + output + lines = output.splitlines(True) + + # bpo-36670: typeperf only writes a newline *before* writing a value, + # not after. Sometimes, the written line in incomplete (ex: only + # timestamp, without the process queue length). Only pass the last line + # to the parser if it's a valid value, otherwise store it in + # self._buffer. + try: + self._parse_line(lines[-1]) + except ValueError: + self._buffer = lines.pop(-1) + else: + self._buffer = '' + + return lines def getloadavg(self): - typeperf_output = self.read_output() - # Nothing to update, just return the current load - if not typeperf_output: - return self.load + if self._popen is None: + return None + + returncode = self._popen.poll() + if returncode is not None: + self.close(kill=False) + return None + + try: + lines = self._read_lines() + except BrokenPipeError: + self.close() + return None + + for line in lines: + line = line.rstrip() - # Process the backlog of load values - for line in typeperf_output.splitlines(): # Ignore the initial header: # "(PDH-CSV 4.0)","\\\\WIN\\System\\Processor Queue Length" - if '\\\\' in line: + if 'PDH-CSV' in line: continue # Ignore blank lines - if not line.strip(): + if not line: continue - # typeperf outputs in a CSV format like this: - # "07/19/2018 01:32:26.605","3.000000" - # (date, process queue length) try: - tokens = line.split(',') - if len(tokens) != 2: - raise ValueError - - value = tokens[1].replace('"', '') - load = float(value) + processor_queue_length = self._parse_line(line) except ValueError: print_warning("Failed to parse typeperf output: %a" % line) continue @@ -137,7 +178,13 @@ class WindowsLoadTracker(): # We use an exponentially weighted moving average, imitating the # load calculation on Unix systems. # https://en.wikipedia.org/wiki/Load_(computing)#Unix-style_load_calculation - new_load = self.load * LOAD_FACTOR_1 + load * (1.0 - LOAD_FACTOR_1) - self.load = new_load - - return self.load + # https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average + if self._load is not None: + self._load = (self._load * LOAD_FACTOR_1 + + processor_queue_length * (1.0 - LOAD_FACTOR_1)) + elif len(self._values) < NVALUE: + self._values.append(processor_queue_length) + else: + self._load = sum(self._values) / len(self._values) + + return self._load diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 5809566..9a9d26d 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -439,10 +439,15 @@ def collect_sysconfig(info_add): def collect_ssl(info_add): + import os try: import ssl except ImportError: return + try: + import _ssl + except ImportError: + _ssl = None def format_attr(attr, value): if attr.startswith('OP_'): @@ -459,6 +464,32 @@ def collect_ssl(info_add): ) copy_attributes(info_add, ssl, 'ssl.%s', attributes, formatter=format_attr) + for name, ctx in ( + ('SSLContext', ssl.SSLContext()), + ('default_https_context', ssl._create_default_https_context()), + ('stdlib_context', ssl._create_stdlib_context()), + ): + attributes = ( + 'minimum_version', + 'maximum_version', + 'protocol', + 'options', + 'verify_mode', + ) + copy_attributes(info_add, ctx, f'ssl.{name}.%s', attributes) + + env_names = ["OPENSSL_CONF", "SSLKEYLOGFILE"] + if _ssl is not None and hasattr(_ssl, 'get_default_verify_paths'): + parts = _ssl.get_default_verify_paths() + env_names.extend((parts[0], parts[2])) + + for name in env_names: + try: + value = os.environ[name] + except KeyError: + continue + info_add('ssl.environ[%s]' % name, value) + def collect_socket(info_add): import socket diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 2d0b5b2..2d2fb26 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -125,6 +125,14 @@ exec_tests = [ "{*{1, 2}, 3}", # Asynchronous comprehensions "async def f():\n [i async for b in c]", + # Decorated FunctionDef + "@deco1\n@deco2()\n@deco3(1)\ndef f(): pass", + # Decorated AsyncFunctionDef + "@deco1\n@deco2()\n@deco3(1)\nasync def f(): pass", + # Decorated ClassDef + "@deco1\n@deco2()\n@deco3(1)\nclass C: pass", + # Decorator with generator argument + "@deco(a for a in b)\ndef f(): pass", ] # These are compiled through "single" @@ -1255,6 +1263,10 @@ exec_results = [ ('Module', [('Expr', (1, 0), ('Dict', (1, 0), [None, ('Num', (1, 10), 2)], [('Dict', (1, 3), [('Num', (1, 4), 1)], [('Num', (1, 6), 2)]), ('Num', (1, 12), 3)]))]), ('Module', [('Expr', (1, 0), ('Set', (1, 0), [('Starred', (1, 1), ('Set', (1, 2), [('Num', (1, 3), 1), ('Num', (1, 6), 2)]), ('Load',)), ('Num', (1, 10), 3)]))]), ('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (2, 1), ('ListComp', (2, 2), ('Name', (2, 2), 'i', ('Load',)), [('comprehension', ('Name', (2, 14), 'b', ('Store',)), ('Name', (2, 19), 'c', ('Load',)), [], 1)]))], [], None)]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (4, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 1), ('Name', (2, 1), 'deco2', ('Load',)), [], []), ('Call', (3, 1), ('Name', (3, 1), 'deco3', ('Load',)), [('Num', (3, 7), 1)], [])], None)]), +('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (4, 15))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 1), ('Name', (2, 1), 'deco2', ('Load',)), [], []), ('Call', (3, 1), ('Name', (3, 1), 'deco3', ('Load',)), [('Num', (3, 7), 1)], [])], None)]), +('Module', [('ClassDef', (1, 0), 'C', [], [], [('Pass', (4, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 1), ('Name', (2, 1), 'deco2', ('Load',)), [], []), ('Call', (3, 1), ('Name', (3, 1), 'deco3', ('Load',)), [('Num', (3, 7), 1)], [])])]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (2, 9))], [('Call', (1, 1), ('Name', (1, 1), 'deco', ('Load',)), [('GeneratorExp', (1, 6), ('Name', (1, 6), 'a', ('Load',)), [('comprehension', ('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 17), 'b', ('Load',)), [], 0)])], [])], None)]), ] single_results = [ ('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Num', (1, 0), 1), ('Add',), ('Num', (1, 2), 2)))]), diff --git a/Lib/test/test_asyncgen.py b/Lib/test/test_asyncgen.py index 94c2633..cca6d58 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -696,6 +696,33 @@ class AsyncGenAsyncioTest(unittest.TestCase): self.loop.run_until_complete(run()) self.assertEqual(DONE, 10) + def test_async_gen_asyncio_aclose_12(self): + DONE = 0 + + async def target(): + await asyncio.sleep(0.01) + 1 / 0 + + async def foo(): + nonlocal DONE + task = asyncio.create_task(target()) + try: + yield 1 + finally: + try: + await task + except ZeroDivisionError: + DONE = 1 + + async def run(): + gen = foo() + it = gen.__aiter__() + await it.__anext__() + await gen.aclose() + + self.loop.run_until_complete(run()) + self.assertEqual(DONE, 1) + def test_async_gen_asyncio_asend_01(self): DONE = 0 diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 178ffa6..5025d26 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -1709,10 +1709,6 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): self.assertRaises(ValueError, self.loop.run_until_complete, fut) fut = self.loop.create_datagram_endpoint( - MyDatagramProto, reuse_address=True, sock=FakeSock()) - self.assertRaises(ValueError, self.loop.run_until_complete, fut) - - fut = self.loop.create_datagram_endpoint( MyDatagramProto, reuse_port=True, sock=FakeSock()) self.assertRaises(ValueError, self.loop.run_until_complete, fut) @@ -1722,7 +1718,6 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): def test_create_datagram_endpoint_sockopts(self): # Socket options should not be applied unless asked for. - # SO_REUSEADDR defaults to on for UNIX. # SO_REUSEPORT is not available on all platforms. coro = self.loop.create_datagram_endpoint( @@ -1731,18 +1726,8 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): transport, protocol = self.loop.run_until_complete(coro) sock = transport.get_extra_info('socket') - reuse_address_default_on = ( - os.name == 'posix' and sys.platform != 'cygwin') reuseport_supported = hasattr(socket, 'SO_REUSEPORT') - if reuse_address_default_on: - self.assertTrue( - sock.getsockopt( - socket.SOL_SOCKET, socket.SO_REUSEADDR)) - else: - self.assertFalse( - sock.getsockopt( - socket.SOL_SOCKET, socket.SO_REUSEADDR)) if reuseport_supported: self.assertFalse( sock.getsockopt( @@ -1758,13 +1743,12 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): coro = self.loop.create_datagram_endpoint( lambda: MyDatagramProto(create_future=True, loop=self.loop), local_addr=('127.0.0.1', 0), - reuse_address=True, reuse_port=reuseport_supported, allow_broadcast=True) transport, protocol = self.loop.run_until_complete(coro) sock = transport.get_extra_info('socket') - self.assertTrue( + self.assertFalse( sock.getsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR)) if reuseport_supported: @@ -1779,6 +1763,32 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): self.loop.run_until_complete(protocol.done) self.assertEqual('CLOSED', protocol.state) + def test_create_datagram_endpoint_reuse_address_error(self): + # bpo-37228: Ensure that explicit passing of `reuse_address=True` + # raises an error, as it is not safe to use SO_REUSEADDR when using UDP + + coro = self.loop.create_datagram_endpoint( + lambda: MyDatagramProto(create_future=True, loop=self.loop), + local_addr=('127.0.0.1', 0), + reuse_address=True) + + with self.assertRaises(ValueError): + self.loop.run_until_complete(coro) + + def test_create_datagram_endpoint_reuse_address_warning(self): + # bpo-37228: Deprecate *reuse_address* parameter + + coro = self.loop.create_datagram_endpoint( + lambda: MyDatagramProto(create_future=True, loop=self.loop), + local_addr=('127.0.0.1', 0), + reuse_address=False) + + with self.assertWarns(DeprecationWarning): + transport, protocol = self.loop.run_until_complete(coro) + transport.close() + self.loop.run_until_complete(protocol.done) + self.assertEqual('CLOSED', protocol.state) + @patch_socket def test_create_datagram_endpoint_nosoreuseport(self, m_socket): del m_socket.SO_REUSEPORT @@ -1787,7 +1797,6 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): coro = self.loop.create_datagram_endpoint( lambda: MyDatagramProto(loop=self.loop), local_addr=('127.0.0.1', 0), - reuse_address=False, reuse_port=True) self.assertRaises(ValueError, self.loop.run_until_complete, coro) @@ -1806,7 +1815,6 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): coro = self.loop.create_datagram_endpoint( lambda: MyDatagramProto(loop=self.loop), local_addr=('1.2.3.4', 0), - reuse_address=False, reuse_port=reuseport_supported) t, p = self.loop.run_until_complete(coro) diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py index 9608a3a..8bc861d 100644 --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -818,5 +818,44 @@ class PyFutureDoneCallbackTests(BaseFutureDoneCallbackTests, return futures._PyFuture(loop=self.loop) +class BaseFutureInheritanceTests: + + def _get_future_cls(self): + raise NotImplementedError + + def setUp(self): + super().setUp() + self.loop = self.new_test_loop() + self.addCleanup(self.loop.close) + + def test_inherit_without_calling_super_init(self): + # See https://bugs.python.org/issue38785 for the context + cls = self._get_future_cls() + + class MyFut(cls): + def __init__(self, *args, **kwargs): + # don't call super().__init__() + pass + + fut = MyFut(loop=self.loop) + with self.assertRaisesRegex( + RuntimeError, + "Future object is not initialized." + ): + fut.get_loop() + + +class PyFutureInheritanceTests(BaseFutureInheritanceTests, + test_utils.TestCase): + def _get_future_cls(self): + return futures._PyFuture + + +class CFutureInheritanceTests(BaseFutureInheritanceTests, + test_utils.TestCase): + def _get_future_cls(self): + return futures._CFuture + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py index 866ef81..8720961 100644 --- a/Lib/test/test_asyncio/test_sslproto.py +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -495,14 +495,6 @@ class BaseStartTLS(func_tests.FunctionalTestCaseMixin): server_context = test_utils.simple_server_sslcontext() client_context = test_utils.simple_client_sslcontext() - if (sys.platform.startswith('freebsd') - or sys.platform.startswith('win') - or sys.platform.startswith('darwin')): - # bpo-35031: Some FreeBSD and Windows buildbots fail to run this test - # as the eof was not being received by the server if the payload - # size is not big enough. This behaviour only appears if the - # client is using TLS1.3. Also seen on macOS. - client_context.options |= ssl.OP_NO_TLSv1_3 answer = None def client(sock, addr): @@ -519,9 +511,10 @@ class BaseStartTLS(func_tests.FunctionalTestCaseMixin): sock.close() class ServerProto(asyncio.Protocol): - def __init__(self, on_con, on_con_lost): + def __init__(self, on_con, on_con_lost, on_got_hello): self.on_con = on_con self.on_con_lost = on_con_lost + self.on_got_hello = on_got_hello self.data = b'' self.transport = None @@ -535,7 +528,7 @@ class BaseStartTLS(func_tests.FunctionalTestCaseMixin): def data_received(self, data): self.data += data if len(self.data) >= len(HELLO_MSG): - self.transport.write(ANSWER) + self.on_got_hello.set_result(None) def connection_lost(self, exc): self.transport = None @@ -544,7 +537,7 @@ class BaseStartTLS(func_tests.FunctionalTestCaseMixin): else: self.on_con_lost.set_exception(exc) - async def main(proto, on_con, on_con_lost): + async def main(proto, on_con, on_con_lost, on_got_hello): tr = await on_con tr.write(HELLO_MSG) @@ -554,9 +547,11 @@ class BaseStartTLS(func_tests.FunctionalTestCaseMixin): tr, proto, server_context, server_side=True, ssl_handshake_timeout=self.TIMEOUT) - proto.replace_transport(new_tr) + await on_got_hello + new_tr.write(ANSWER) + await on_con_lost self.assertEqual(proto.data, HELLO_MSG) new_tr.close() @@ -564,7 +559,8 @@ class BaseStartTLS(func_tests.FunctionalTestCaseMixin): async def run_main(): on_con = self.loop.create_future() on_con_lost = self.loop.create_future() - proto = ServerProto(on_con, on_con_lost) + on_got_hello = self.loop.create_future() + proto = ServerProto(on_con, on_con_lost, on_got_hello) server = await self.loop.create_server( lambda: proto, '127.0.0.1', 0) @@ -573,7 +569,7 @@ class BaseStartTLS(func_tests.FunctionalTestCaseMixin): with self.tcp_client(lambda sock: client(sock, addr), timeout=self.TIMEOUT): await asyncio.wait_for( - main(proto, on_con, on_con_lost), + main(proto, on_con, on_con_lost, on_got_hello), loop=self.loop, timeout=self.TIMEOUT) server.close() diff --git a/Lib/test/test_context.py b/Lib/test/test_context.py index efd7319..b9e991a 100644 --- a/Lib/test/test_context.py +++ b/Lib/test/test_context.py @@ -38,9 +38,6 @@ class ContextTest(unittest.TestCase): self.assertNotEqual(hash(c), hash('aaa')) - def test_context_var_new_2(self): - self.assertIsNone(contextvars.ContextVar[int]) - @isolated_context def test_context_var_repr_1(self): c = contextvars.ContextVar('a') @@ -361,6 +358,10 @@ class ContextTest(unittest.TestCase): tp.shutdown() self.assertEqual(results, list(range(10))) + def test_contextvar_getitem(self): + clss = contextvars.ContextVar + self.assertEqual(clss[str], clss) + # HAMT Tests diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index 99086e5..2844845 100755 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -10,6 +10,7 @@ import builtins import unittest from unittest.mock import Mock from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional +from typing import get_type_hints from collections import deque, OrderedDict, namedtuple from functools import total_ordering @@ -2918,6 +2919,17 @@ class TestStringAnnotations(unittest.TestCase): # won't exist on the instance. self.assertNotIn('not_iv4', c.__dict__) + def test_text_annotations(self): + from test import dataclass_textanno + + self.assertEqual( + get_type_hints(dataclass_textanno.Bar), + {'foo': dataclass_textanno.Foo}) + self.assertEqual( + get_type_hints(dataclass_textanno.Bar.__init__), + {'foo': dataclass_textanno.Foo, + 'return': type(None)}) + class TestMakeDataclass(unittest.TestCase): def test_simple(self): diff --git a/Lib/test/test_email/test__encoded_words.py b/Lib/test/test_email/test__encoded_words.py index 5a59aeb..0b8b1de 100644 --- a/Lib/test/test_email/test__encoded_words.py +++ b/Lib/test/test_email/test__encoded_words.py @@ -58,6 +58,8 @@ class TestDecode(TestEmailBase): _ew.decode('=?') with self.assertRaises(ValueError): _ew.decode('') + with self.assertRaises(KeyError): + _ew.decode('=?utf-8?X?somevalue?=') def _test(self, source, result, charset='us-ascii', lang='', defects=[]): res, char, l, d = _ew.decode(source) diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py index 8bb0365..4894d8f 100644 --- a/Lib/test/test_email/test__header_value_parser.py +++ b/Lib/test/test_email/test__header_value_parser.py @@ -89,6 +89,10 @@ class TestParser(TestParserMixin, TestEmailBase): with self.assertRaises(errors.HeaderParseError): parser.get_encoded_word('=?abc?=') + def test_get_encoded_word_invalid_cte(self): + with self.assertRaises(errors.HeaderParseError): + parser.get_encoded_word('=?utf-8?X?somevalue?=') + def test_get_encoded_word_valid_ew(self): self._test_get_x(parser.get_encoded_word, '=?us-ascii?q?this_is_a_test?= bird', @@ -399,6 +403,14 @@ class TestParser(TestParserMixin, TestEmailBase): [], '') + def test_get_unstructured_invalid_ew_cte(self): + self._test_get_x(self._get_unst, + '=?utf-8?X?=somevalue?=', + '=?utf-8?X?=somevalue?=', + '=?utf-8?X?=somevalue?=', + [], + '') + # get_qp_ctext def test_get_qp_ctext_only(self): diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py index acd5c7c..036bd64 100644 --- a/Lib/test/test_fcntl.py +++ b/Lib/test/test_fcntl.py @@ -5,6 +5,7 @@ import os import struct import sys import unittest +from multiprocessing import Process from test.support import (verbose, TESTFN, unlink, run_unittest, import_module, cpython_only) @@ -12,7 +13,6 @@ from test.support import (verbose, TESTFN, unlink, run_unittest, import_module, fcntl = import_module('fcntl') -# TODO - Write tests for flock() and lockf(). def get_lockdata(): try: @@ -51,6 +51,21 @@ class BadFile: def fileno(self): return self.fn +def try_lockf_on_other_process_fail(fname, cmd): + f = open(fname, 'wb+') + try: + fcntl.lockf(f, cmd) + except BlockingIOError: + pass + finally: + f.close() + +def try_lockf_on_other_process(fname, cmd): + f = open(fname, 'wb+') + fcntl.lockf(f, cmd) + fcntl.lockf(f, fcntl.LOCK_UN) + f.close() + class TestFcntl(unittest.TestCase): def setUp(self): @@ -138,6 +153,28 @@ class TestFcntl(unittest.TestCase): self.assertRaises(ValueError, fcntl.flock, -1, fcntl.LOCK_SH) self.assertRaises(TypeError, fcntl.flock, 'spam', fcntl.LOCK_SH) + @unittest.skipIf(platform.system() == "AIX", "AIX returns PermissionError") + def test_lockf_exclusive(self): + self.f = open(TESTFN, 'wb+') + cmd = fcntl.LOCK_EX | fcntl.LOCK_NB + fcntl.lockf(self.f, cmd) + p = Process(target=try_lockf_on_other_process_fail, args=(TESTFN, cmd)) + p.start() + p.join() + fcntl.lockf(self.f, fcntl.LOCK_UN) + self.assertEqual(p.exitcode, 0) + + @unittest.skipIf(platform.system() == "AIX", "AIX returns PermissionError") + def test_lockf_share(self): + self.f = open(TESTFN, 'wb+') + cmd = fcntl.LOCK_SH | fcntl.LOCK_NB + fcntl.lockf(self.f, cmd) + p = Process(target=try_lockf_on_other_process, args=(TESTFN, cmd)) + p.start() + p.join() + fcntl.lockf(self.f, fcntl.LOCK_UN) + self.assertEqual(p.exitcode, 0) + @cpython_only def test_flock_overflow(self): import _testcapi diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py index 8d806db..a2fa8bb 100644 --- a/Lib/test/test_gc.py +++ b/Lib/test/test_gc.py @@ -755,6 +755,77 @@ class GCTests(unittest.TestCase): gc.unfreeze() self.assertEqual(gc.get_freeze_count(), 0) + def test_38379(self): + # When a finalizer resurrects objects, stats were reporting them as + # having been collected. This affected both collect()'s return + # value and the dicts returned by get_stats(). + N = 100 + + class A: # simple self-loop + def __init__(self): + self.me = self + + class Z(A): # resurrecting __del__ + def __del__(self): + zs.append(self) + + zs = [] + + def getstats(): + d = gc.get_stats()[-1] + return d['collected'], d['uncollectable'] + + gc.collect() + gc.disable() + + # No problems if just collecting A() instances. + oldc, oldnc = getstats() + for i in range(N): + A() + t = gc.collect() + c, nc = getstats() + self.assertEqual(t, 2*N) # instance object & its dict + self.assertEqual(c - oldc, 2*N) + self.assertEqual(nc - oldnc, 0) + + # But Z() is not actually collected. + oldc, oldnc = c, nc + Z() + # Nothing is collected - Z() is merely resurrected. + t = gc.collect() + c, nc = getstats() + #self.assertEqual(t, 2) # before + self.assertEqual(t, 0) # after + #self.assertEqual(c - oldc, 2) # before + self.assertEqual(c - oldc, 0) # after + self.assertEqual(nc - oldnc, 0) + + # Unfortunately, a Z() prevents _anything_ from being collected. + # It should be possible to collect the A instances anyway, but + # that will require non-trivial code changes. + oldc, oldnc = c, nc + for i in range(N): + A() + Z() + # Z() prevents anything from being collected. + t = gc.collect() + c, nc = getstats() + #self.assertEqual(t, 2*N + 2) # before + self.assertEqual(t, 0) # after + #self.assertEqual(c - oldc, 2*N + 2) # before + self.assertEqual(c - oldc, 0) # after + self.assertEqual(nc - oldnc, 0) + + # But the A() trash is reclaimed on the next run. + oldc, oldnc = c, nc + t = gc.collect() + c, nc = getstats() + self.assertEqual(t, 2*N) + self.assertEqual(c - oldc, 2*N) + self.assertEqual(nc - oldnc, 0) + + gc.enable() + class GCCallbackTests(unittest.TestCase): def setUp(self): diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py index 6eabeea..ff86ffa 100644 --- a/Lib/test/test_http_cookiejar.py +++ b/Lib/test/test_http_cookiejar.py @@ -123,6 +123,13 @@ class DateTimeTests(unittest.TestCase): "http2time(%s) is not None\n" "http2time(test) %s" % (test, http2time(test))) + def test_http2time_redos_regression_actually_completes(self): + # LOOSE_HTTP_DATE_RE was vulnerable to malicious input which caused catastrophic backtracking (REDoS). + # If we regress to cubic complexity, this test will take a very long time to succeed. + # If fixed, it should complete within a fraction of a second. + http2time("01 Jan 1970{}00:00:00 GMT!".format(" " * 10 ** 5)) + http2time("01 Jan 1970 00:00:00{}GMT!".format(" " * 10 ** 5)) + def test_iso2time(self): def parse_date(text): return time.gmtime(iso2time(text))[:6] @@ -180,6 +187,12 @@ class DateTimeTests(unittest.TestCase): self.assertIsNone(iso2time(test), "iso2time(%r)" % test) + def test_iso2time_performance_regression(self): + # If ISO_DATE_RE regresses to quadratic complexity, this test will take a very long time to succeed. + # If fixed, it should complete within a fraction of a second. + iso2time('1994-02-03{}14:15:29 -0100!'.format(' '*10**6)) + iso2time('1994-02-03 14:15:29{}-0100!'.format(' '*10**6)) + class HeaderTests(unittest.TestCase): diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index d6bf43d..42002b9 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -3830,6 +3830,17 @@ class MiscIOTest(unittest.TestCase): f.close() g.close() + def test_open_pipe_with_append(self): + # bpo-27805: Ignore ESPIPE from lseek() in open(). + r, w = os.pipe() + self.addCleanup(os.close, r) + f = self.open(w, 'a') + self.addCleanup(f.close) + # Check that the file is marked non-seekable. On Windows, however, lseek + # somehow succeeds on pipes. + if sys.platform != 'win32': + self.assertFalse(f.seekable()) + def test_io_after_close(self): for kwargs in [ {"mode": "w"}, diff --git a/Lib/test/test_json/test_tool.py b/Lib/test/test_json/test_tool.py index 9d93f93..2999dc1 100644 --- a/Lib/test/test_json/test_tool.py +++ b/Lib/test/test_json/test_tool.py @@ -67,11 +67,11 @@ class TestTool(unittest.TestCase): self.assertEqual(out.splitlines(), self.expect.encode().splitlines()) self.assertEqual(err, b'') - def _create_infile(self): + def _create_infile(self, data=None): infile = support.TESTFN - with open(infile, "w") as fp: + with open(infile, "w", encoding="utf-8") as fp: self.addCleanup(os.remove, infile) - fp.write(self.data) + fp.write(data or self.data) return infile def test_infile_stdout(self): @@ -81,6 +81,21 @@ class TestTool(unittest.TestCase): self.assertEqual(out.splitlines(), self.expect.encode().splitlines()) self.assertEqual(err, b'') + def test_non_ascii_infile(self): + data = '{"msg": "\u3053\u3093\u306b\u3061\u306f"}' + expect = textwrap.dedent('''\ + { + "msg": "\\u3053\\u3093\\u306b\\u3061\\u306f" + } + ''').encode() + + infile = self._create_infile(data) + rc, out, err = assert_python_ok('-m', 'json.tool', infile) + + self.assertEqual(rc, 0) + self.assertEqual(out.splitlines(), expect.splitlines()) + self.assertEqual(err, b'') + def test_infile_outfile(self): infile = self._create_infile() outfile = support.TESTFN + '.out' diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index adbec8d..f29de8c 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -50,6 +50,21 @@ class MimeTypesTestCase(unittest.TestCase): eq(self.db.guess_type('foo.xul', strict=False), ('text/xul', None)) eq(self.db.guess_extension('image/jpg', strict=False), '.jpg') + def test_filename_with_url_delimiters(self): + # bpo-38449: URL delimiters cases should be handled also. + # They would have different mime types if interpreted as URL as + # compared to when interpreted as filename because of the semicolon. + eq = self.assertEqual + gzip_expected = ('application/x-tar', 'gzip') + eq(self.db.guess_type(";1.tar.gz"), gzip_expected) + eq(self.db.guess_type("?1.tar.gz"), gzip_expected) + eq(self.db.guess_type("#1.tar.gz"), gzip_expected) + eq(self.db.guess_type("#1#.tar.gz"), gzip_expected) + eq(self.db.guess_type(";1#.tar.gz"), gzip_expected) + eq(self.db.guess_type(";&1=123;?.tar.gz"), gzip_expected) + eq(self.db.guess_type("?k1=v1&k2=v2.tar.gz"), gzip_expected) + eq(self.db.guess_type(r" \"\`;b&b&c |.tar.gz"), gzip_expected) + def test_guess_all_types(self): eq = self.assertEqual unless = self.assertTrue diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 9c82c64..e1d699a 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -2216,11 +2216,15 @@ class WindowsPathTest(_BasePathTest, unittest.TestCase): P = self.cls p = P(BASE) self.assertEqual(set(p.glob("FILEa")), { P(BASE, "fileA") }) + self.assertEqual(set(p.glob("F*a")), { P(BASE, "fileA") }) + self.assertEqual(set(map(str, p.glob("FILEa"))), {f"{p}\\FILEa"}) + self.assertEqual(set(map(str, p.glob("F*a"))), {f"{p}\\fileA"}) def test_rglob(self): P = self.cls p = P(BASE, "dirC") self.assertEqual(set(p.rglob("FILEd")), { P(BASE, "dirC/dirD/fileD") }) + self.assertEqual(set(map(str, p.rglob("FILEd"))), {f"{p}\\dirD\\FILEd"}) def test_expanduser(self): P = self.cls diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py index 3b44856..ce85f57 100644 --- a/Lib/test/test_pty.py +++ b/Lib/test/test_pty.py @@ -66,16 +66,27 @@ def _readline(fd): # XXX(nnorwitz): these tests leak fds when there is an error. class PtyTest(unittest.TestCase): def setUp(self): - # isatty() and close() can hang on some platforms. Set an alarm - # before running the test to make sure we don't hang forever. old_alarm = signal.signal(signal.SIGALRM, self.handle_sig) self.addCleanup(signal.signal, signal.SIGALRM, old_alarm) + + old_sighup = signal.signal(signal.SIGHUP, self.handle_sighup) + self.addCleanup(signal.signal, signal.SIGHUP, old_alarm) + + # isatty() and close() can hang on some platforms. Set an alarm + # before running the test to make sure we don't hang forever. self.addCleanup(signal.alarm, 0) signal.alarm(10) def handle_sig(self, sig, frame): self.fail("isatty hung") + @staticmethod + def handle_sighup(sig, frame): + # if the process is the session leader, os.close(master_fd) + # of "master_fd, slave_name = pty.master_open()" raises SIGHUP + # signal: just ignore the signal. + pass + def test_basic(self): try: debug("Calling master_open()") @@ -122,9 +133,11 @@ class PtyTest(unittest.TestCase): self.assertEqual(b'For my pet fish, Eric.\n', normalize_output(s2)) os.close(slave_fd) + # closing master_fd can raise a SIGHUP if the process is + # the session leader: we installed a SIGHUP signal handler + # to ignore this signal. os.close(master_fd) - def test_fork(self): debug("calling pty.fork()") pid, master_fd = pty.fork() diff --git a/Lib/test/test_py_compile.py b/Lib/test/test_py_compile.py index f86abe2..df45764 100644 --- a/Lib/test/test_py_compile.py +++ b/Lib/test/test_py_compile.py @@ -51,7 +51,7 @@ class SourceDateEpochTestMeta(type(unittest.TestCase)): class PyCompileTestsBase: def setUp(self): - self.directory = tempfile.mkdtemp() + self.directory = tempfile.mkdtemp(dir=os.getcwd()) self.source_path = os.path.join(self.directory, '_test.py') self.pyc_path = self.source_path + 'c' self.cache_path = importlib.util.cache_from_source(self.source_path) diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index 7336adc..26c9b16 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -24,6 +24,7 @@ from test.libregrtest import utils Py_DEBUG = hasattr(sys, 'gettotalrefcount') ROOT_DIR = os.path.join(os.path.dirname(__file__), '..', '..') ROOT_DIR = os.path.abspath(os.path.normpath(ROOT_DIR)) +LOG_PREFIX = r'[0-9]+:[0-9]+:[0-9]+ (?:load avg: [0-9]+\.[0-9]{2} )?' TEST_INTERRUPTED = textwrap.dedent(""" from signal import SIGINT @@ -390,8 +391,8 @@ class BaseTestCase(unittest.TestCase): self.assertRegex(output, regex) def parse_executed_tests(self, output): - regex = (r'^[0-9]+:[0-9]+:[0-9]+ (?:load avg: [0-9]+\.[0-9]{2} )?\[ *[0-9]+(?:/ *[0-9]+)*\] (%s)' - % self.TESTNAME_REGEX) + regex = (r'^%s\[ *[0-9]+(?:/ *[0-9]+)*\] (%s)' + % (LOG_PREFIX, self.TESTNAME_REGEX)) parser = re.finditer(regex, output, re.MULTILINE) return list(match.group(1) for match in parser) @@ -451,9 +452,10 @@ class BaseTestCase(unittest.TestCase): if rerun: regex = list_regex('%s re-run test%s', rerun) self.check_line(output, regex) - self.check_line(output, "Re-running failed tests in verbose mode") + regex = LOG_PREFIX + r"Re-running failed tests in verbose mode" + self.check_line(output, regex) for test_name in rerun: - regex = f"Re-running {test_name} in verbose mode" + regex = LOG_PREFIX + f"Re-running {test_name} in verbose mode" self.check_line(output, regex) if no_test_ran: @@ -1173,9 +1175,9 @@ class TestUtils(unittest.TestCase): self.assertEqual(utils.format_duration(10e-3), '10 ms') self.assertEqual(utils.format_duration(1.5), - '1 sec 500 ms') + '1.5 sec') self.assertEqual(utils.format_duration(1), - '1 sec') + '1.0 sec') self.assertEqual(utils.format_duration(2 * 60), '2 min') self.assertEqual(utils.format_duration(2 * 60 + 1), diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index e21e7e0..1018259 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -500,7 +500,7 @@ class BasicSocketTests(unittest.TestCase): ('email', 'null@python.org\x00user@example.org'), ('URI', 'http://null.python.org\x00http://example.org'), ('IP Address', '192.0.2.1'), - ('IP Address', '2001:DB8:0:0:0:0:0:1\n')) + ('IP Address', '2001:DB8:0:0:0:0:0:1')) else: # OpenSSL 0.9.7 doesn't support IPv6 addresses in subjectAltName san = (('DNS', 'altnull.python.org\x00example.com'), @@ -527,7 +527,7 @@ class BasicSocketTests(unittest.TestCase): (('commonName', 'dirname example'),))), ('URI', 'https://www.python.org/'), ('IP Address', '127.0.0.1'), - ('IP Address', '0:0:0:0:0:0:0:1\n'), + ('IP Address', '0:0:0:0:0:0:0:1'), ('Registered ID', '1.2.3.4.5') ) ) @@ -554,11 +554,11 @@ class BasicSocketTests(unittest.TestCase): # Some sanity checks follow # >= 0.9 self.assertGreaterEqual(n, 0x900000) - # < 3.0 - self.assertLess(n, 0x30000000) + # < 4.0 + self.assertLess(n, 0x40000000) major, minor, fix, patch, status = t - self.assertGreaterEqual(major, 0) - self.assertLess(major, 3) + self.assertGreaterEqual(major, 1) + self.assertLess(major, 4) self.assertGreaterEqual(minor, 0) self.assertLess(minor, 256) self.assertGreaterEqual(fix, 0) @@ -1220,12 +1220,18 @@ class ContextTests(unittest.TestCase): # RHEL 8 uses TLS 1.2 by default ssl.TLSVersion.TLSv1_2 } + maximum_range = { + # stock OpenSSL + ssl.TLSVersion.MAXIMUM_SUPPORTED, + # Fedora 32 uses TLS 1.3 by default + ssl.TLSVersion.TLSv1_3 + } self.assertIn( ctx.minimum_version, minimum_range ) - self.assertEqual( - ctx.maximum_version, ssl.TLSVersion.MAXIMUM_SUPPORTED + self.assertIn( + ctx.maximum_version, maximum_range ) ctx.minimum_version = ssl.TLSVersion.TLSv1_1 diff --git a/Lib/test/test_stat.py b/Lib/test/test_stat.py index 73cd901..4ee0dc2 100644 --- a/Lib/test/test_stat.py +++ b/Lib/test/test_stat.py @@ -14,10 +14,10 @@ class TestFilemode: 'UF_IMMUTABLE', 'UF_NODUMP', 'UF_NOUNLINK', 'UF_OPAQUE'} formats = {'S_IFBLK', 'S_IFCHR', 'S_IFDIR', 'S_IFIFO', 'S_IFLNK', - 'S_IFREG', 'S_IFSOCK'} + 'S_IFREG', 'S_IFSOCK', 'S_IFDOOR', 'S_IFPORT', 'S_IFWHT'} format_funcs = {'S_ISBLK', 'S_ISCHR', 'S_ISDIR', 'S_ISFIFO', 'S_ISLNK', - 'S_ISREG', 'S_ISSOCK'} + 'S_ISREG', 'S_ISSOCK', 'S_ISDOOR', 'S_ISPORT', 'S_ISWHT'} stat_struct = { 'ST_MODE': 0, @@ -221,10 +221,6 @@ class TestFilemode: class TestFilemodeCStat(TestFilemode, unittest.TestCase): statmod = c_stat - formats = TestFilemode.formats | {'S_IFDOOR', 'S_IFPORT', 'S_IFWHT'} - format_funcs = TestFilemode.format_funcs | {'S_ISDOOR', 'S_ISPORT', - 'S_ISWHT'} - class TestFilemodePyStat(TestFilemode, unittest.TestCase): statmod = py_stat diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py index 80f1668..3183ea8 100644 --- a/Lib/test/test_tcl.py +++ b/Lib/test/test_tcl.py @@ -429,9 +429,12 @@ class TclTest(unittest.TestCase): self.assertEqual(passValue(False), False if self.wantobjects else '0') self.assertEqual(passValue('string'), 'string') self.assertEqual(passValue('string\u20ac'), 'string\u20ac') + self.assertEqual(passValue('string\U0001f4bb'), 'string\U0001f4bb') self.assertEqual(passValue('str\x00ing'), 'str\x00ing') self.assertEqual(passValue('str\x00ing\xbd'), 'str\x00ing\xbd') self.assertEqual(passValue('str\x00ing\u20ac'), 'str\x00ing\u20ac') + self.assertEqual(passValue('str\x00ing\U0001f4bb'), + 'str\x00ing\U0001f4bb') self.assertEqual(passValue(b'str\x00ing'), b'str\x00ing' if self.wantobjects else 'str\x00ing') self.assertEqual(passValue(b'str\xc0\x80ing'), @@ -490,6 +493,7 @@ class TclTest(unittest.TestCase): check('string') check('string\xbd') check('string\u20ac') + check('string\U0001f4bb') check('') check(b'string', 'string') check(b'string\xe2\x82\xac', 'string\xe2\x82\xac') @@ -531,6 +535,7 @@ class TclTest(unittest.TestCase): ('a\n b\t\r c\n ', ('a', 'b', 'c')), (b'a\n b\t\r c\n ', ('a', 'b', 'c')), ('a \u20ac', ('a', '\u20ac')), + ('a \U0001f4bb', ('a', '\U0001f4bb')), (b'a \xe2\x82\xac', ('a', '\u20ac')), (b'a\xc0\x80b c\xc0\x80d', ('a\x00b', 'c\x00d')), ('a {b c}', ('a', 'b c')), diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index 9313128..c046420 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -1119,7 +1119,8 @@ class TestSpooledTemporaryFile(BaseTestCase): def test_text_mode(self): # Creating a SpooledTemporaryFile with a text mode should produce # a file object reading and writing (Unicode) text strings. - f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10) + f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10, + encoding="utf-8") f.write("abc\n") f.seek(0) self.assertEqual(f.read(), "abc\n") @@ -1129,8 +1130,8 @@ class TestSpooledTemporaryFile(BaseTestCase): self.assertFalse(f._rolled) self.assertEqual(f.mode, 'w+') self.assertIsNone(f.name) - self.assertIsNone(f.newlines) - self.assertIsNone(f.encoding) + self.assertEqual(f.newlines, os.linesep) + self.assertEqual(f.encoding, "utf-8") f.write("xyzzy\n") f.seek(0) @@ -1143,7 +1144,7 @@ class TestSpooledTemporaryFile(BaseTestCase): self.assertEqual(f.mode, 'w+') self.assertIsNotNone(f.name) self.assertEqual(f.newlines, os.linesep) - self.assertIsNotNone(f.encoding) + self.assertEqual(f.encoding, "utf-8") def test_text_newline_and_encoding(self): f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10, @@ -1154,12 +1155,14 @@ class TestSpooledTemporaryFile(BaseTestCase): self.assertFalse(f._rolled) self.assertEqual(f.mode, 'w+') self.assertIsNone(f.name) - self.assertIsNone(f.newlines) - self.assertIsNone(f.encoding) + self.assertIsNotNone(f.newlines) + self.assertEqual(f.encoding, "utf-8") - f.write("\u039B" * 20 + "\r\n") + f.write("\u039C" * 10 + "\r\n") + f.write("\u039D" * 20) f.seek(0) - self.assertEqual(f.read(), "\u039B\r\n" + ("\u039B" * 20) + "\r\n") + self.assertEqual(f.read(), + "\u039B\r\n" + ("\u039C" * 10) + "\r\n" + ("\u039D" * 20)) self.assertTrue(f._rolled) self.assertEqual(f.mode, 'w+') self.assertIsNotNone(f.name) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 4871fb7..087dc2a 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1787,6 +1787,16 @@ except StopIteration as e: gth = get_type_hints +class ForRefExample: + @ann_module.dec + def func(self: 'ForRefExample'): + pass + + @ann_module.dec + @ann_module.dec + def nested(self: 'ForRefExample'): + pass + class GetTypeHintTests(BaseTestCase): def test_get_type_hints_from_various_objects(self): @@ -1885,6 +1895,11 @@ class GetTypeHintTests(BaseTestCase): 'x': ClassVar[Optional[B]]}) self.assertEqual(gth(G), {'lst': ClassVar[List[T]]}) + def test_get_type_hints_wrapped_decoratored_func(self): + expects = {'self': ForRefExample} + self.assertEqual(gth(ForRefExample.func), expects) + self.assertEqual(gth(ForRefExample.nested), expects) + class CollectionsAbcTests(BaseTestCase): @@ -2441,6 +2456,9 @@ class NewTypeTests(BaseTestCase): class NamedTupleTests(BaseTestCase): + class NestedEmployee(NamedTuple): + name: str + cool: int def test_basics(self): Emp = NamedTuple('Emp', [('name', str), ('id', int)]) @@ -2564,14 +2582,25 @@ class XMethBad2(NamedTuple): self.assertEqual(Emp.__name__, 'Emp') self.assertEqual(Emp._fields, ('name', 'id')) - def test_pickle(self): + def test_copy_and_pickle(self): global Emp # pickle wants to reference the class by name - Emp = NamedTuple('Emp', [('name', str), ('id', int)]) - jane = Emp('jane', 37) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - z = pickle.dumps(jane, proto) - jane2 = pickle.loads(z) - self.assertEqual(jane2, jane) + Emp = NamedTuple('Emp', [('name', str), ('cool', int)]) + for cls in Emp, CoolEmployee, self.NestedEmployee: + with self.subTest(cls=cls): + jane = cls('jane', 37) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + z = pickle.dumps(jane, proto) + jane2 = pickle.loads(z) + self.assertEqual(jane2, jane) + self.assertIsInstance(jane2, cls) + + jane2 = copy(jane) + self.assertEqual(jane2, jane) + self.assertIsInstance(jane2, cls) + + jane2 = deepcopy(jane) + self.assertEqual(jane2, jane) + self.assertIsInstance(jane2, cls) class IOTests(BaseTestCase): diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index 68f633c..999272d 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -709,15 +709,17 @@ class UrlParseTestCase(unittest.TestCase): def test_portseparator(self): # Issue 754016 makes changes for port separator ':' from scheme separator - self.assertEqual(urllib.parse.urlparse("path:80"), - ('','','path:80','','','')) + self.assertEqual(urllib.parse.urlparse("http:80"), ('http','','80','','','')) + self.assertEqual(urllib.parse.urlparse("https:80"), ('https','','80','','','')) + self.assertEqual(urllib.parse.urlparse("path:80"), ('path','','80','','','')) self.assertEqual(urllib.parse.urlparse("http:"),('http','','','','','')) self.assertEqual(urllib.parse.urlparse("https:"),('https','','','','','')) self.assertEqual(urllib.parse.urlparse("http://www.python.org:80"), ('http','www.python.org:80','','','','')) # As usual, need to check bytes input as well - self.assertEqual(urllib.parse.urlparse(b"path:80"), - (b'',b'',b'path:80',b'',b'',b'')) + self.assertEqual(urllib.parse.urlparse(b"http:80"), (b'http',b'',b'80',b'',b'',b'')) + self.assertEqual(urllib.parse.urlparse(b"https:80"), (b'https',b'',b'80',b'',b'',b'')) + self.assertEqual(urllib.parse.urlparse(b"path:80"), (b'path',b'',b'80',b'',b'',b'')) self.assertEqual(urllib.parse.urlparse(b"http:"),(b'http',b'',b'',b'',b'',b'')) self.assertEqual(urllib.parse.urlparse(b"https:"),(b'https',b'',b'',b'',b'',b'')) self.assertEqual(urllib.parse.urlparse(b"http://www.python.org:80"), diff --git a/Lib/test/test_uu.py b/Lib/test/test_uu.py index c9f05e5..c8709f7 100644 --- a/Lib/test/test_uu.py +++ b/Lib/test/test_uu.py @@ -136,6 +136,15 @@ class UUTest(unittest.TestCase): decoded = codecs.decode(encodedtext, "uu_codec") self.assertEqual(decoded, plaintext) + def test_newlines_escaped(self): + # Test newlines are escaped with uu.encode + inp = io.BytesIO(plaintext) + out = io.BytesIO() + filename = "test.txt\n\roverflow.txt" + safefilename = b"test.txt\\n\\roverflow.txt" + uu.encode(inp, out, filename) + self.assertIn(safefilename, out.getvalue()) + class UUStdIOTest(unittest.TestCase): def setUp(self): diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index d3396fc..14ec8ef 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -376,6 +376,26 @@ class ReferencesTestCase(TestBase): lyst = List() self.assertEqual(bool(weakref.proxy(lyst)), bool(lyst)) + def test_proxy_iter(self): + # Test fails with a debug build of the interpreter + # (see bpo-38395). + + obj = None + + class MyObj: + def __iter__(self): + nonlocal obj + del obj + return NotImplemented + + obj = MyObj() + p = weakref.proxy(obj) + with self.assertRaises(TypeError): + # "blech" in p calls MyObj.__iter__ through the proxy, + # without keeping a reference to the real object, so it + # can be killed in the middle of the call + "blech" in p + def test_getweakrefcount(self): o = C() ref1 = weakref.ref(o) diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index ac8f64c..7e8e8d2 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -1,5 +1,6 @@ import contextlib import io +import itertools import os import importlib.util import pathlib @@ -801,6 +802,227 @@ class StoredTestZip64InSmallFiles(AbstractTestZip64InSmallFiles, zinfo = zipfp.getinfo("strfile") self.assertEqual(zinfo.extra, extra) + def make_zip64_file( + self, file_size_64_set=False, file_size_extra=False, + compress_size_64_set=False, compress_size_extra=False, + header_offset_64_set=False, header_offset_extra=False, + ): + """Generate bytes sequence for a zip with (incomplete) zip64 data. + + The actual values (not the zip 64 0xffffffff values) stored in the file + are: + file_size: 8 + compress_size: 8 + header_offset: 0 + """ + actual_size = 8 + actual_header_offset = 0 + local_zip64_fields = [] + central_zip64_fields = [] + + file_size = actual_size + if file_size_64_set: + file_size = 0xffffffff + if file_size_extra: + local_zip64_fields.append(actual_size) + central_zip64_fields.append(actual_size) + file_size = struct.pack(" 0: - if url[:i] == 'http': # optimize the common case - url = url[i+1:] - if url[:2] == '//': - netloc, url = _splitnetloc(url, 2) - if (('[' in netloc and ']' not in netloc) or - (']' in netloc and '[' not in netloc)): - raise ValueError("Invalid IPv6 URL") - if allow_fragments and '#' in url: - url, fragment = url.split('#', 1) - if '?' in url: - url, query = url.split('?', 1) - _checknetloc(netloc) - v = SplitResult('http', netloc, url, query, fragment) - _parse_cache[key] = v - return _coerce_result(v) for c in url[:i]: if c not in scheme_chars: break else: - # make sure "url" is not actually a port number (in which case - # "scheme" is really part of the path) - rest = url[i+1:] - if not rest or any(c not in '0123456789' for c in rest): - # not a port number - scheme, url = url[:i].lower(), rest + scheme, url = url[:i].lower(), url[i+1:] if url[:2] == '//': netloc, url = _splitnetloc(url, 2) diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 37b2548..1ec484e 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1143,7 +1143,9 @@ class AbstractDigestAuthHandler: A2 = "%s:%s" % (req.get_method(), # XXX selector: what about proxies and full urls req.selector) - if qop == 'auth': + # NOTE: As per RFC 2617, when server sends "auth,auth-int", the client could use either `auth` + # or `auth-int` to the response back. we use `auth` to send the response back. + if 'auth' in qop.split(','): if nonce == self.last_nonce: self.nonce_count += 1 else: @@ -1151,7 +1153,7 @@ class AbstractDigestAuthHandler: self.last_nonce = nonce ncvalue = '%08x' % self.nonce_count cnonce = self.get_cnonce(nonce) - noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, H(A2)) + noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, 'auth', H(A2)) respdig = KD(H(A1), noncebit) elif qop is None: respdig = KD(H(A1), "%s:%s" % (nonce, H(A2))) diff --git a/Lib/uu.py b/Lib/uu.py index 9b1e5e6..9f1f37f 100755 --- a/Lib/uu.py +++ b/Lib/uu.py @@ -73,6 +73,13 @@ def encode(in_file, out_file, name=None, mode=None, *, backtick=False): name = '-' if mode is None: mode = 0o666 + + # + # Remove newline chars from name + # + name = name.replace('\n','\\n') + name = name.replace('\r','\\r') + # # Write the data # diff --git a/Lib/wave.py b/Lib/wave.py index f155879..823f091 100644 --- a/Lib/wave.py +++ b/Lib/wave.py @@ -53,7 +53,7 @@ This returns an instance of a class with the following public methods: -- set all parameters at once tell() -- return current position in output file writeframesraw(data) - -- write audio frames without pathing up the + -- write audio frames without patching up the file header writeframes(data) -- write audio frames and patch up the file header diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 955d91f..63748d3 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -477,14 +477,26 @@ class ZipInfo (object): # ZIP64 extension (large files and/or large archives) if self.file_size in (0xffffffffffffffff, 0xffffffff): + if len(counts) <= idx: + raise BadZipFile( + "Corrupt zip64 extra field. File size not found." + ) self.file_size = counts[idx] idx += 1 if self.compress_size == 0xFFFFFFFF: + if len(counts) <= idx: + raise BadZipFile( + "Corrupt zip64 extra field. Compress size not found." + ) self.compress_size = counts[idx] idx += 1 if self.header_offset == 0xffffffff: + if len(counts) <= idx: + raise BadZipFile( + "Corrupt zip64 extra field. Header offset not found." + ) old = self.header_offset self.header_offset = counts[idx] idx+=1 @@ -784,10 +796,10 @@ class ZipExtFile(io.BufferedIOBase): # Chunk size to read during seek MAX_SEEK_READ = 1 << 24 - def __init__(self, fileobj, mode, zipinfo, decrypter=None, + def __init__(self, fileobj, mode, zipinfo, pwd=None, close_fileobj=False): self._fileobj = fileobj - self._decrypter = decrypter + self._pwd = pwd self._close_fileobj = close_fileobj self._compress_type = zipinfo.compress_type @@ -802,11 +814,6 @@ class ZipExtFile(io.BufferedIOBase): self.newlines = None - # Adjust read size for encrypted files since the first 12 bytes - # are for the encryption/password information. - if self._decrypter is not None: - self._compress_left -= 12 - self.mode = mode self.name = zipinfo.filename @@ -827,6 +834,30 @@ class ZipExtFile(io.BufferedIOBase): except AttributeError: pass + self._decrypter = None + if pwd: + if zipinfo.flag_bits & 0x8: + # compare against the file type from extended local headers + check_byte = (zipinfo._raw_time >> 8) & 0xff + else: + # compare against the CRC otherwise + check_byte = (zipinfo.CRC >> 24) & 0xff + h = self._init_decrypter() + if h != check_byte: + raise RuntimeError("Bad password for file %r" % zipinfo.orig_filename) + + + def _init_decrypter(self): + self._decrypter = _ZipDecrypter(self._pwd) + # The first 12 bytes in the cypher stream is an encryption header + # used to strengthen the algorithm. The first 11 bytes are + # completely random, while the 12th contains the MSB of the CRC, + # or the MSB of the file time depending on the header type + # and is used to check the correctness of the password. + header = self._fileobj.read(12) + self._compress_left -= 12 + return self._decrypter(header)[11] + def __repr__(self): result = ['<%s.%s' % (self.__class__.__module__, self.__class__.__qualname__)] @@ -1053,6 +1084,8 @@ class ZipExtFile(io.BufferedIOBase): self._decompressor = _get_decompressor(self._compress_type) self._eof = False read_offset = new_pos + if self._decrypter is not None: + self._init_decrypter() while read_offset > 0: read_len = min(self.MAX_SEEK_READ, read_offset) @@ -1515,32 +1548,16 @@ class ZipFile: # check for encrypted flag & handle password is_encrypted = zinfo.flag_bits & 0x1 - zd = None if is_encrypted: if not pwd: pwd = self.pwd if not pwd: raise RuntimeError("File %r is encrypted, password " "required for extraction" % name) + else: + pwd = None - zd = _ZipDecrypter(pwd) - # The first 12 bytes in the cypher stream is an encryption header - # used to strengthen the algorithm. The first 11 bytes are - # completely random, while the 12th contains the MSB of the CRC, - # or the MSB of the file time depending on the header type - # and is used to check the correctness of the password. - header = zef_file.read(12) - h = zd(header[0:12]) - if zinfo.flag_bits & 0x8: - # compare against the file type from extended local headers - check_byte = (zinfo._raw_time >> 8) & 0xff - else: - # compare against the CRC otherwise - check_byte = (zinfo.CRC >> 24) & 0xff - if h[11] != check_byte: - raise RuntimeError("Bad password for file %r" % name) - - return ZipExtFile(zef_file, mode, zinfo, zd, True) + return ZipExtFile(zef_file, mode, zinfo, pwd, True) except: zef_file.close() raise diff --git a/Mac/BuildScript/resources/License.rtf b/Mac/BuildScript/resources/License.rtf index 86e54f6..7566cf3 100644 --- a/Mac/BuildScript/resources/License.rtf +++ b/Mac/BuildScript/resources/License.rtf @@ -16,7 +16,7 @@ Python was created in the early 1990s by Guido van Rossum at Stichting Mathemati \ In 1995, Guido continued his work on Python at the Corporation for National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) in Reston, Virginia where he released several versions of the software.\ \ -In May 2000, Guido and the Python core development team moved to BeOpen.com to form the BeOpen PythonLabs team. In October of the same year, the PythonLabs team moved to Digital Creations (now Zope Corporation, see http://www.zope.com). In 2001, the Python Software Foundation (PSF, see http://www.python.org/psf/) was formed, a non-profit organization created specifically to own Python-related Intellectual Property. Zope Corporation is a sponsoring member of the PSF.\ +In May 2000, Guido and the Python core development team moved to BeOpen.com to form the BeOpen PythonLabs team. In October of the same year, the PythonLabs team moved to Digital Creations (now Zope Corporation, see http://www.zope.org). In 2001, the Python Software Foundation (PSF, see http://www.python.org/psf/) was formed, a non-profit organization created specifically to own Python-related Intellectual Property. Zope Corporation is a sponsoring member of the PSF.\ \ All Python releases are Open Source (see http://www.opensource.org for the Open Source Definition). Historically, most, but not all, Python releases have also been GPL-compatible; the table below summarizes the various releases.\ \ diff --git a/Misc/ACKS b/Misc/ACKS index 7afc92e..ad012ea 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -245,6 +245,7 @@ Zach Byrne Vedran Čačić Nicolas Cadou Jp Calderone +Ben Caller Arnaud Calmettes Daniel Calvelo Tony Campbell diff --git a/Misc/NEWS b/Misc/NEWS index af08260..a81e814 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -2,6 +2,253 @@ Python News +++++++++++ +What's New in Python 3.7.6 final? +================================= + +*Release date: 2019-12-18* + +macOS +----- + +- bpo-38295: Prevent failure of test_relative_path in test_py_compile on + macOS Catalina. + + +What's New in Python 3.7.6 release candidate 1? +=============================================== + +*Release date: 2019-12-11* + +Security +-------- + +- bpo-38945: Newline characters have been escaped when performing uu + encoding to prevent them from overflowing into to content section of the + encoded file. This prevents malicious or accidental modification of data + during the decoding process. + +- bpo-37228: Due to significant security concerns, the *reuse_address* + parameter of :meth:`asyncio.loop.create_datagram_endpoint` is no longer + supported. This is because of the behavior of ``SO_REUSEADDR`` in UDP. For + more details, see the documentation for + ``loop.create_datagram_endpoint()``. (Contributed by Kyle Stanley, Antoine + Pitrou, and Yury Selivanov in :issue:`37228`.) + +- bpo-38804: Fixes a ReDoS vulnerability in :mod:`http.cookiejar`. Patch by + Ben Caller. + +Core and Builtins +----------------- + +- bpo-38673: In REPL mode, don't switch to PS2 if the line starts with + comment or whitespace. Based on work by Batuhan Taşkaya. + +- bpo-38535: Fixed line numbers and column offsets for AST nodes for calls + without arguments in decorators. + +- bpo-38379: When cyclic garbage collection (gc) runs finalizers that + resurrect unreachable objects, the current gc run ends, without collecting + any cyclic trash. However, the statistics reported by ``collect()`` and + ``get_stats()`` claimed that all cyclic trash found was collected, and + that the resurrected objects were collected. Changed the stats to report + that none were collected. + +- bpo-35409: Ignore GeneratorExit exceptions when throwing an exception into + the aclose coroutine of an asynchronous generator. + +Library +------- + +- bpo-39006: Fix asyncio when the ssl module is missing: only check for + ssl.SSLSocket instance if the ssl module is available. + +- bpo-38979: Return class from ``ContextVar.__class_getitem__`` to simplify + subclassing. + +- bpo-38986: Make repr of C accelerated TaskWakeupMethWrapper the same as of + pure Python version. + +- bpo-33684: Fix ``json.tool`` failed to read a JSON file with non-ASCII + characters when locale encoding is not UTF-8. + +- bpo-26730: Fix ``SpooledTemporaryFile.rollover()`` might corrupt the file + when it is in text mode. Patch by Serhiy Storchaka. + +- bpo-37838: :meth:`typing.get_type_hints` properly handles functions + decorated with :meth:`functools.wraps`. + +- bpo-38821: Fix unhandled exceptions in :mod:`argparse` when + internationalizing error messages for arguments with ``nargs`` set to + special (non-integer) values. Patch by Federico Bond. + +- bpo-38820: Make Python compatible with OpenSSL 3.0.0. + :func:`ssl.SSLSocket.getpeercert` no longer returns IPv6 addresses with a + trailing new line. + +- bpo-38785: Prevent asyncio from crashing if parent ``__init__`` is not + called from a constructor of object derived from ``asyncio.Future``. + +- bpo-27805: Allow opening pipes and other non-seekable files in append mode + with :func:`open`. + +- bpo-38686: Added support for multiple ``qop`` values in + :class:`urllib.request.AbstractDigestAuthHandler`. + +- bpo-38334: Fixed seeking backward on an encrypted + :class:`zipfile.ZipExtFile`. + +- bpo-31202: The case the result of :func:`pathlib.WindowsPath.glob` matches + now the case of the pattern for literal parts. + +- bpo-38109: Add missing :data:`stat.S_IFDOOR`, :data:`stat.S_IFPORT`, + :data:`stat.S_IFWHT`, :func:`stat.S_ISDOOR`, :func:`stat.S_ISPORT`, and + :func:`stat.S_ISWHT` values to the Python implementation of :mod:`stat`. + +- bpo-38422: Clarify docstrings of pathlib suffix(es) + +- bpo-38405: Nested subclasses of :class:`typing.NamedTuple` are now + pickleable. + +- bpo-38332: Prevent :exc:`KeyError` thrown by :func:`_encoded_words.decode` + when given an encoded-word with invalid content-type encoding from + propagating all the way to :func:`email.message.get`. + +- bpo-38341: Add :exc:`smtplib.SMTPNotSupportedError` to the :mod:`smtplib` + exported names. + +- bpo-13153: OS native encoding is now used for converting between Python + strings and Tcl objects. This allows to display, copy and paste to + clipboard emoji and other non-BMP characters. Converting strings from Tcl + to Python and back now never fails (except MemoryError). + +- bpo-36993: Improve error reporting for corrupt zip files with bad zip64 + extra data. Patch by Daniel Hillier. + +- bpo-36952: Starting with Python 3.3, importing ABCs from + :mod:`collections` is deprecated, and import should be done from + :mod:`collections.abc`. Still being able to import from :mod:`collections` + was marked for removal in 3.8, but has been delayed to 3.9; documentation + and ``DeprecationWarning`` clarified. + +- bpo-36820: Break cycle generated when saving an exception in socket.py, + codeop.py and dyld.py as they keep alive not only the exception but user + objects through the ``__traceback__`` attribute. Patch by Mario Corchero. + +- bpo-34776: Fix dataclasses to support forward references in type + annotations + +- bpo-33348: lib2to3 now recognizes expressions after ``*`` and `**` like in + ``f(*[] or [])``. + +- bpo-27657: Fix urllib.parse.urlparse() with numeric paths. A string like + "path:80" is no longer parsed as a path but as a scheme ("path") and a + path ("80"). + +Documentation +------------- + +- bpo-38351: Modernize :mod:`email` examples from %-formatting to f-strings. + +- bpo-38592: Add Brazilian Portuguese to the language switcher at Python + Documentation website. + +- bpo-38294: Add list of no-longer-escaped chars to re.escape documentation + +Tests +----- + +- bpo-38547: Fix test_pty: if the process is the session leader, closing the + master file descriptor raises a SIGHUP signal: simply ignore SIGHUP when + running the tests. + +- bpo-38965: Fix test_faulthandler on GCC 10. Use the "volatile" keyword in + ``faulthandler._stack_overflow()`` to prevent tail call optimization on + any compiler, rather than relying on compiler specific pragma. + +- bpo-38669: Raise :exc:`TypeError` when passing target as a string with + :meth:`unittest.mock.patch.object`. + +- bpo-35998: Fix a race condition in test_asyncio.test_start_tls_server_1(). + Previously, there was a race condition between the test main() function + which replaces the protocol and the test ServerProto protocol which sends + ANSWER once it gets HELLO. Now, only the test main() function is + responsible to send data, ServerProto no longer sends data. + +- bpo-37531: On timeout, regrtest no longer attempts to call + ``popen.communicate()`` again: it can hang until all child processes using + stdout and stderr pipes completes. Kill the worker process and ignores its + output. Change also the faulthandler timeout of the main process from 1 + minute to 5 minutes, for Python slowest buildbots. + +Build +----- + +- bpo-37404: :mod:`asyncio` now raises :exc:`TyperError` when calling + incompatible methods with an :class:`ssl.SSLSocket` socket. Patch by Ido + Michael. + +- bpo-38809: On Windows, build scripts will now recognize and use python.exe + from an active virtual env. + +- bpo-37415: Fix stdatomic.h header check for ICC compiler: the ICC + implementation lacks atomic_uintptr_t type which is needed by Python. + +Windows +------- + +- bpo-38589: Fixes HTML Help shortcut when Windows is not installed to C + drive + +IDLE +---- + +- bpo-38944: Excape key now closes IDLE completion windows. Patch by Johnny + Najera. + +- bpo-38943: Fix IDLE autocomplete windows not always appearing on some + systems. Patch by Johnny Najera. + +- bpo-38862: 'Strip Trailing Whitespace' on the Format menu removes extra + newlines at the end of non-shell files. + +- bpo-26353: Stop adding newline when saving an IDLE shell window. + +- 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-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. + +- bpo-38598: Do not try to compile IDLE shell or output windows + +- bpo-36698: IDLE no longer fails when write non-encodable characters to + stderr. It now escapes them with a backslash, as the regular Python + interpreter. Added the ``errors`` field to the standard streams. + +Tools/Demos +----------- + +- bpo-38118: Update Valgrind suppression file to ignore a false alarm in + :c:func:`PyUnicode_Decode` when using GCC builtin strcmp(). + +- bpo-38347: pathfix.py: Assume all files that end on '.py' are Python + scripts when working recursively. + +C API +----- + +- bpo-38540: Fixed possible leak in :c:func:`PyArg_Parse` and similar + functions for format units ``"es#"`` and ``"et#"`` when the macro + :c:macro:`PY_SSIZE_T_CLEAN` is not defined. + +- bpo-38395: Fix a crash in :class:`weakref.proxy` objects due to incorrect + lifetime management when calling some associated methods that may delete + the last reference to object being referenced by the proxy. Patch by Pablo + Galindo. + + What's New in Python 3.7.5 final? ================================= diff --git a/Misc/valgrind-python.supp b/Misc/valgrind-python.supp index bc8f77f..38a5ea3 100644 --- a/Misc/valgrind-python.supp +++ b/Misc/valgrind-python.supp @@ -283,6 +283,17 @@ fun:rl_initialize } +# Valgrind emits "Conditional jump or move depends on uninitialised value(s)" +# false alarms on GCC builtin strcmp() function. The GCC code is correct. +# +# Valgrind bug: https://bugs.kde.org/show_bug.cgi?id=264936 +{ + bpo-38118: Valgrind emits false alarm on GCC builtin strcmp() + Memcheck:Cond + fun:PyUnicode_Decode +} + + ### ### These occur from somewhere within the SSL, when running ### test_socket_sll. They are too general to leave on by default. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 35264f5..441506b 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1089,6 +1089,7 @@ static PyObject * _asyncio_Future_get_loop_impl(FutureObj *self) /*[clinic end generated code: output=119b6ea0c9816c3f input=cba48c2136c79d1f]*/ { + ENSURE_FUTURE_ALIVE(self) Py_INCREF(self->fut_loop); return self->fut_loop; } @@ -1820,6 +1821,21 @@ TaskWakeupMethWrapper_dealloc(TaskWakeupMethWrapper *o) Py_TYPE(o)->tp_free(o); } +static PyObject * +TaskWakeupMethWrapper_get___self__(TaskWakeupMethWrapper *o, void *Py_UNUSED(ignored)) +{ + if (o->ww_task) { + Py_INCREF(o->ww_task); + return (PyObject*)o->ww_task; + } + Py_RETURN_NONE; +} + +static PyGetSetDef TaskWakeupMethWrapper_getsetlist[] = { + {"__self__", (getter)TaskWakeupMethWrapper_get___self__, NULL, NULL}, + {NULL} /* Sentinel */ +}; + static PyTypeObject TaskWakeupMethWrapper_Type = { PyVarObject_HEAD_INIT(NULL, 0) "TaskWakeupMethWrapper", @@ -1831,6 +1847,7 @@ static PyTypeObject TaskWakeupMethWrapper_Type = { .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_traverse = (traverseproc)TaskWakeupMethWrapper_traverse, .tp_clear = (inquiry)TaskWakeupMethWrapper_clear, + .tp_getset = TaskWakeupMethWrapper_getsetlist, }; static PyObject * @@ -3360,24 +3377,28 @@ PyInit__asyncio(void) Py_INCREF(&FutureType); if (PyModule_AddObject(m, "Future", (PyObject *)&FutureType) < 0) { Py_DECREF(&FutureType); + Py_DECREF(m); return NULL; } Py_INCREF(&TaskType); if (PyModule_AddObject(m, "Task", (PyObject *)&TaskType) < 0) { Py_DECREF(&TaskType); + Py_DECREF(m); return NULL; } Py_INCREF(all_tasks); if (PyModule_AddObject(m, "_all_tasks", all_tasks) < 0) { Py_DECREF(all_tasks); + Py_DECREF(m); return NULL; } Py_INCREF(current_tasks); if (PyModule_AddObject(m, "_current_tasks", current_tasks) < 0) { Py_DECREF(current_tasks); + Py_DECREF(m); return NULL; } diff --git a/Modules/_contextvarsmodule.c b/Modules/_contextvarsmodule.c index 71dd7fd..1abcdbf 100644 --- a/Modules/_contextvarsmodule.c +++ b/Modules/_contextvarsmodule.c @@ -52,6 +52,7 @@ PyInit__contextvars(void) (PyObject *)&PyContext_Type) < 0) { Py_DECREF(&PyContext_Type); + Py_DECREF(m); return NULL; } @@ -60,6 +61,7 @@ PyInit__contextvars(void) (PyObject *)&PyContextVar_Type) < 0) { Py_DECREF(&PyContextVar_Type); + Py_DECREF(m); return NULL; } @@ -68,6 +70,7 @@ PyInit__contextvars(void) (PyObject *)&PyContextToken_Type) < 0) { Py_DECREF(&PyContextToken_Type); + Py_DECREF(m); return NULL; } diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index f186e50..c8fed44 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -446,6 +446,9 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt Py_DECREF(result); return NULL; } + if (!isStruct) { + dict->flags |= TYPEFLAG_HASUNION; + } /* replace the class dict by our updated stgdict, which holds info about storage requirements of the instances */ if (-1 == PyDict_Update((PyObject *)dict, result->tp_dict)) { @@ -2273,7 +2276,35 @@ converters_from_argtypes(PyObject *ob) for (i = 0; i < nArgs; ++i) { PyObject *tp = PyTuple_GET_ITEM(ob, i); - PyObject *cnv = PyObject_GetAttrString(tp, "from_param"); + PyObject *cnv; + StgDictObject *stgdict = PyType_stgdict(tp); + + if (stgdict != NULL) { + if (stgdict->flags & TYPEFLAG_HASUNION) { + Py_DECREF(converters); + Py_DECREF(ob); + if (!PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "item %zd in _argtypes_ passes a union by " + "value, which is unsupported.", + i + 1); + } + return NULL; + } + if (stgdict->flags & TYPEFLAG_HASBITFIELD) { + Py_DECREF(converters); + Py_DECREF(ob); + if (!PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "item %zd in _argtypes_ passes a struct/" + "union with a bitfield by value, which is " + "unsupported.", + i + 1); + } + return NULL; + } + } + cnv = PyObject_GetAttrString(tp, "from_param"); if (!cnv) goto argtypes_error_1; PyTuple_SET_ITEM(converters, i, cnv); diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index f59abcc..d08a011 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -135,6 +135,119 @@ _testfunc_array_in_struct2a(Test3B in) return result; } +typedef union { + long a_long; + struct { + int an_int; + int another_int; + } a_struct; +} Test4; + +typedef struct { + int an_int; + struct { + int an_int; + Test4 a_union; + } nested; + int another_int; +} Test5; + +EXPORT(long) +_testfunc_union_by_value1(Test4 in) { + long result = in.a_long + in.a_struct.an_int + in.a_struct.another_int; + + /* As the union/struct are passed by value, changes to them shouldn't be + * reflected in the caller. + */ + memset(&in, 0, sizeof(in)); + return result; +} + +EXPORT(long) +_testfunc_union_by_value2(Test5 in) { + long result = in.an_int + in.nested.an_int; + + /* As the union/struct are passed by value, changes to them shouldn't be + * reflected in the caller. + */ + memset(&in, 0, sizeof(in)); + return result; +} + +EXPORT(long) +_testfunc_union_by_reference1(Test4 *in) { + long result = in->a_long; + + memset(in, 0, sizeof(Test4)); + return result; +} + +EXPORT(long) +_testfunc_union_by_reference2(Test4 *in) { + long result = in->a_struct.an_int + in->a_struct.another_int; + + memset(in, 0, sizeof(Test4)); + return result; +} + +EXPORT(long) +_testfunc_union_by_reference3(Test5 *in) { + long result = in->an_int + in->nested.an_int + in->another_int; + + memset(in, 0, sizeof(Test5)); + return result; +} + +typedef struct { + signed int A: 1, B:2, C:3, D:2; +} Test6; + +EXPORT(long) +_testfunc_bitfield_by_value1(Test6 in) { + long result = in.A + in.B + in.C + in.D; + + /* As the struct is passed by value, changes to it shouldn't be + * reflected in the caller. + */ + memset(&in, 0, sizeof(in)); + return result; +} + +EXPORT(long) +_testfunc_bitfield_by_reference1(Test6 *in) { + long result = in->A + in->B + in->C + in->D; + + memset(in, 0, sizeof(Test6)); + return result; +} + +typedef struct { + unsigned int A: 1, B:2, C:3, D:2; +} Test7; + +EXPORT(long) +_testfunc_bitfield_by_reference2(Test7 *in) { + long result = in->A + in->B + in->C + in->D; + + memset(in, 0, sizeof(Test7)); + return result; +} + +typedef union { + signed int A: 1, B:2, C:3, D:2; +} Test8; + +EXPORT(long) +_testfunc_bitfield_by_value2(Test8 in) { + long result = in.A + in.B + in.C + in.D; + + /* As the struct is passed by value, changes to it shouldn't be + * reflected in the caller. + */ + memset(&in, 0, sizeof(in)); + return result; +} + EXPORT(void)testfunc_array(int values[4]) { printf("testfunc_array %d %d %d %d\n", diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index 5d3b966..e58f852 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -288,6 +288,8 @@ PyObject *_ctypes_callproc(PPROC pProc, #define TYPEFLAG_ISPOINTER 0x100 #define TYPEFLAG_HASPOINTER 0x200 +#define TYPEFLAG_HASUNION 0x400 +#define TYPEFLAG_HASBITFIELD 0x800 #define DICTFLAG_FINAL 0x1000 diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index af12d31..231c3fe 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -407,6 +407,13 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct PyMem_Free(stgdict->ffi_type_pointer.elements); basedict = PyType_stgdict((PyObject *)((PyTypeObject *)type)->tp_base); + if (basedict) { + stgdict->flags |= (basedict->flags & + (TYPEFLAG_HASUNION | TYPEFLAG_HASBITFIELD)); + } + if (!isStruct) { + stgdict->flags |= TYPEFLAG_HASUNION; + } if (basedict && !use_broken_old_ctypes_semantics) { size = offset = basedict->size; align = basedict->align; @@ -482,8 +489,10 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct stgdict->ffi_type_pointer.elements[ffi_ofs + i] = &dict->ffi_type_pointer; if (dict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER)) stgdict->flags |= TYPEFLAG_HASPOINTER; + stgdict->flags |= dict->flags & (TYPEFLAG_HASUNION | TYPEFLAG_HASBITFIELD); dict->flags |= DICTFLAG_FINAL; /* mark field type final */ if (PyTuple_Size(pair) == 3) { /* bits specified */ + stgdict->flags |= TYPEFLAG_HASBITFIELD; switch(dict->ffi_type_pointer.type) { case FFI_TYPE_UINT8: case FFI_TYPE_UINT16: diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 8bbe1ce..ac67051 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -3,6 +3,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" #include "structmember.h" +#include #ifdef HAVE_SYS_TYPES_H #include #endif @@ -74,7 +75,7 @@ _Py_IDENTIFIER(name); #define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type)) /* Forward declarations */ -static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence); +static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error); int _PyFileIO_closed(PyObject *self) @@ -475,7 +476,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, /* For consistent behaviour, we explicitly seek to the end of file (otherwise, it might be done only on the first write()). */ - PyObject *pos = portable_lseek(self, NULL, 2); + PyObject *pos = portable_lseek(self, NULL, 2, true); if (pos == NULL) goto error; Py_DECREF(pos); @@ -598,7 +599,7 @@ _io_FileIO_seekable_impl(fileio *self) return err_closed(); if (self->seekable < 0) { /* portable_lseek() sets the seekable attribute */ - PyObject *pos = portable_lseek(self, NULL, SEEK_CUR); + PyObject *pos = portable_lseek(self, NULL, SEEK_CUR, false); assert(self->seekable >= 0); if (pos == NULL) { PyErr_Clear(); @@ -865,7 +866,7 @@ _io_FileIO_write_impl(fileio *self, Py_buffer *b) /* Cribbed from posix_lseek() */ static PyObject * -portable_lseek(fileio *self, PyObject *posobj, int whence) +portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error) { Py_off_t pos, res; int fd = self->fd; @@ -916,8 +917,13 @@ portable_lseek(fileio *self, PyObject *posobj, int whence) self->seekable = (res >= 0); } - if (res < 0) - return PyErr_SetFromErrno(PyExc_OSError); + if (res < 0) { + if (suppress_pipe_error && errno == ESPIPE) { + res = 0; + } else { + return PyErr_SetFromErrno(PyExc_OSError); + } + } #if defined(HAVE_LARGEFILE_SUPPORT) return PyLong_FromLongLong(res); @@ -950,7 +956,7 @@ _io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence) if (self->fd < 0) return err_closed(); - return portable_lseek(self, pos, whence); + return portable_lseek(self, pos, whence, false); } /*[clinic input] @@ -968,7 +974,7 @@ _io_FileIO_tell_impl(fileio *self) if (self->fd < 0) return err_closed(); - return portable_lseek(self, NULL, 1); + return portable_lseek(self, NULL, 1, false); } #ifdef HAVE_FTRUNCATE @@ -999,7 +1005,7 @@ _io_FileIO_truncate_impl(fileio *self, PyObject *posobj) if (posobj == Py_None || posobj == NULL) { /* Get the current position. */ - posobj = portable_lseek(self, NULL, 1); + posobj = portable_lseek(self, NULL, 1, false); if (posobj == NULL) return NULL; } diff --git a/Modules/_ssl.c b/Modules/_ssl.c index a94dbba..4611710 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1377,6 +1377,54 @@ _get_peer_alt_names (X509 *certificate) { PyTuple_SET_ITEM(t, 1, v); break; + case GEN_IPADD: + /* OpenSSL < 3.0.0 adds a trailing \n to IPv6. 3.0.0 removed + * the trailing newline. Remove it in all versions + */ + t = PyTuple_New(2); + if (t == NULL) + goto fail; + + v = PyUnicode_FromString("IP Address"); + if (v == NULL) { + Py_DECREF(t); + goto fail; + } + PyTuple_SET_ITEM(t, 0, v); + + if (name->d.ip->length == 4) { + unsigned char *p = name->d.ip->data; + v = PyUnicode_FromFormat( + "%d.%d.%d.%d", + p[0], p[1], p[2], p[3] + ); + } else if (name->d.ip->length == 16) { + /* PyUnicode_FromFormat() does not support %X */ + unsigned char *p = name->d.ip->data; + len = sprintf( + buf, + "%X:%X:%X:%X:%X:%X:%X:%X", + p[0] << 8 | p[1], + p[2] << 8 | p[3], + p[4] << 8 | p[5], + p[6] << 8 | p[7], + p[8] << 8 | p[9], + p[10] << 8 | p[11], + p[12] << 8 | p[13], + p[14] << 8 | p[15] + ); + v = PyUnicode_FromStringAndSize(buf, len); + } else { + v = PyUnicode_FromString(""); + } + + if (v == NULL) { + Py_DECREF(t); + goto fail; + } + PyTuple_SET_ITEM(t, 1, v); + break; + default: /* for everything else, we use the OpenSSL print form */ switch (gntype) { @@ -1384,7 +1432,6 @@ _get_peer_alt_names (X509 *certificate) { case GEN_OTHERNAME: case GEN_X400: case GEN_EDIPARTY: - case GEN_IPADD: case GEN_RID: break; default: diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 64b7b69..16ea9c2 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5444,11 +5444,14 @@ PyInit__testcapi(void) PyModule_AddObject(m, "instancemethod", (PyObject *)&PyInstanceMethod_Type); PyModule_AddIntConstant(m, "the_number_three", 3); + PyObject *v; #ifdef WITH_PYMALLOC - PyModule_AddObject(m, "WITH_PYMALLOC", Py_True); + v = Py_True; #else - PyModule_AddObject(m, "WITH_PYMALLOC", Py_False); + v = Py_False; #endif + Py_INCREF(v); + PyModule_AddObject(m, "WITH_PYMALLOC", v); TestError = PyErr_NewException("_testcapi.error", NULL, NULL); Py_INCREF(TestError); diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index a96924c..bc648dc 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -96,6 +96,24 @@ Copyright (C) 1994 Steen Lumholt. #endif /* HAVE_CREATEFILEHANDLER */ +/* Use OS native encoding for converting between Python strings and + Tcl objects. + On Windows use UTF-16 (or UTF-32 for 32-bit Tcl_UniChar) with the + "surrogatepass" error handler for converting to/from Tcl Unicode objects. + On Linux use UTF-8 with the "surrogateescape" error handler for converting + to/from Tcl String objects. */ +#ifdef MS_WINDOWS +#define USE_TCL_UNICODE 1 +#else +#define USE_TCL_UNICODE 0 +#endif + +#if PY_LITTLE_ENDIAN +#define NATIVE_BYTEORDER -1 +#else +#define NATIVE_BYTEORDER 1 +#endif + #ifdef MS_WINDOWS #include #define WAIT_FOR_STDIN @@ -290,7 +308,6 @@ typedef struct { } TkappObject; #define Tkapp_Interp(v) (((TkappObject *) (v))->interp) -#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v)) #define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \ (void *) v, Py_REFCNT(v))) @@ -311,10 +328,16 @@ static int tk_load_failed = 0; #endif +static PyObject *Tkapp_UnicodeResult(TkappObject *); + static PyObject * -Tkinter_Error(PyObject *v) +Tkinter_Error(TkappObject *self) { - PyErr_SetString(Tkinter_TclError, Tkapp_Result(v)); + PyObject *res = Tkapp_UnicodeResult(self); + if (res != NULL) { + PyErr_SetObject(Tkinter_TclError, res); + Py_DECREF(res); + } return NULL; } @@ -368,30 +391,35 @@ static PyObject * unicodeFromTclStringAndSize(const char *s, Py_ssize_t size) { PyObject *r = PyUnicode_DecodeUTF8(s, size, NULL); - if (!r && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { - /* Tcl encodes null character as \xc0\x80 */ - if (memchr(s, '\xc0', size)) { - char *buf, *q; - const char *e = s + size; - PyErr_Clear(); - q = buf = (char *)PyMem_Malloc(size); - if (buf == NULL) { - PyErr_NoMemory(); - return NULL; - } - while (s != e) { - if (s + 1 != e && s[0] == '\xc0' && s[1] == '\x80') { - *q++ = '\0'; - s += 2; - } - else - *q++ = *s++; + if (r != NULL || !PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { + return r; + } + + char *buf = NULL; + PyErr_Clear(); + /* Tcl encodes null character as \xc0\x80 */ + if (memchr(s, '\xc0', size)) { + char *q; + const char *e = s + size; + q = buf = (char *)PyMem_Malloc(size); + if (buf == NULL) { + PyErr_NoMemory(); + return NULL; + } + while (s != e) { + if (s + 1 != e && s[0] == '\xc0' && s[1] == '\x80') { + *q++ = '\0'; + s += 2; } - s = buf; - size = q - s; - r = PyUnicode_DecodeUTF8(s, size, NULL); - PyMem_Free(buf); + else + *q++ = *s++; } + s = buf; + size = q - s; + } + r = PyUnicode_DecodeUTF8(s, size, "surrogateescape"); + if (buf != NULL) { + PyMem_Free(buf); } return r; } @@ -406,8 +434,21 @@ static PyObject * unicodeFromTclObj(Tcl_Obj *value) { int len; - char *s = Tcl_GetStringFromObj(value, &len); +#if USE_TCL_UNICODE + int byteorder = NATIVE_BYTEORDER; + const Tcl_UniChar *u = Tcl_GetUnicodeFromObj(value, &len); + if (sizeof(Tcl_UniChar) == 2) + return PyUnicode_DecodeUTF16((const char *)u, len * 2, + "surrogatepass", &byteorder); + else if (sizeof(Tcl_UniChar) == 4) + return PyUnicode_DecodeUTF32((const char *)u, len * 4, + "surrogatepass", &byteorder); + else + Py_UNREACHABLE(); +#else + const char *s = Tcl_GetStringFromObj(value, &len); return unicodeFromTclStringAndSize(s, len); +#endif } @@ -747,7 +788,7 @@ Tkapp_New(const char *screenName, const char *className, #endif if (Tcl_AppInit(v->interp) != TCL_OK) { - PyObject *result = Tkinter_Error((PyObject *)v); + PyObject *result = Tkinter_Error(v); #ifdef TKINTER_PROTECT_LOADTK if (wantTk) { const char *_tkinter_tk_failed; @@ -819,12 +860,6 @@ PyTclObject_dealloc(PyTclObject *self) Py_DECREF(tp); } -static const char * -PyTclObject_TclString(PyObject *self) -{ - return Tcl_GetString(((PyTclObject*)self)->value); -} - /* Like _str, but create Unicode if necessary. */ PyDoc_STRVAR(PyTclObject_string__doc__, "the string representation of this object, either as str or bytes"); @@ -1050,53 +1085,51 @@ AsObj(PyObject *value) } if (PyUnicode_Check(value)) { - void *inbuf; - Py_ssize_t size; - int kind; - Tcl_UniChar *outbuf = NULL; - Py_ssize_t i; - size_t allocsize; - if (PyUnicode_READY(value) == -1) return NULL; - inbuf = PyUnicode_DATA(value); - size = PyUnicode_GET_LENGTH(value); - if (size == 0) - return Tcl_NewUnicodeObj((const void *)"", 0); + Py_ssize_t size = PyUnicode_GET_LENGTH(value); + if (size == 0) { + return Tcl_NewStringObj("", 0); + } if (!CHECK_SIZE(size, sizeof(Tcl_UniChar))) { PyErr_SetString(PyExc_OverflowError, "string is too long"); return NULL; } - kind = PyUnicode_KIND(value); - if (kind == sizeof(Tcl_UniChar)) - return Tcl_NewUnicodeObj(inbuf, (int)size); - allocsize = ((size_t)size) * sizeof(Tcl_UniChar); - outbuf = (Tcl_UniChar*)PyMem_Malloc(allocsize); - /* Else overflow occurred, and we take the next exit */ - if (!outbuf) { - PyErr_NoMemory(); - return NULL; + if (PyUnicode_IS_ASCII(value)) { + return Tcl_NewStringObj((const char *)PyUnicode_DATA(value), + (int)size); } - for (i = 0; i < size; i++) { - Py_UCS4 ch = PyUnicode_READ(kind, inbuf, i); - /* We cannot test for sizeof(Tcl_UniChar) directly, - so we test for UTF-8 size instead. */ -#if TCL_UTF_MAX == 3 - if (ch >= 0x10000) { - /* Tcl doesn't do UTF-16, yet. */ - PyErr_Format(Tkinter_TclError, - "character U+%x is above the range " - "(U+0000-U+FFFF) allowed by Tcl", - ch); - PyMem_Free(outbuf); - return NULL; - } + + PyObject *encoded; +#if USE_TCL_UNICODE + if (sizeof(Tcl_UniChar) == 2) + encoded = _PyUnicode_EncodeUTF16(value, + "surrogatepass", NATIVE_BYTEORDER); + else if (sizeof(Tcl_UniChar) == 4) + encoded = _PyUnicode_EncodeUTF32(value, + "surrogatepass", NATIVE_BYTEORDER); + else + Py_UNREACHABLE(); +#else + encoded = _PyUnicode_AsUTF8String(value, "surrogateescape"); #endif - outbuf[i] = ch; + if (!encoded) { + return NULL; } - result = Tcl_NewUnicodeObj(outbuf, (int)size); - PyMem_Free(outbuf); + size = PyBytes_GET_SIZE(encoded); + if (size > INT_MAX) { + Py_DECREF(encoded); + PyErr_SetString(PyExc_OverflowError, "string is too long"); + return NULL; + } +#if USE_TCL_UNICODE + result = Tcl_NewUnicodeObj((const Tcl_UniChar *)PyBytes_AS_STRING(encoded), + (int)(size / sizeof(Tcl_UniChar))); +#else + result = Tcl_NewStringObj(PyBytes_AS_STRING(encoded), (int)size); +#endif + Py_DECREF(encoded); return result; } @@ -1115,7 +1148,7 @@ AsObj(PyObject *value) } static PyObject * -fromBoolean(PyObject* tkapp, Tcl_Obj *value) +fromBoolean(TkappObject *tkapp, Tcl_Obj *value) { int boolValue; if (Tcl_GetBooleanFromObj(Tkapp_Interp(tkapp), value, &boolValue) == TCL_ERROR) @@ -1124,7 +1157,7 @@ fromBoolean(PyObject* tkapp, Tcl_Obj *value) } static PyObject* -fromWideIntObj(PyObject* tkapp, Tcl_Obj *value) +fromWideIntObj(TkappObject *tkapp, Tcl_Obj *value) { Tcl_WideInt wideValue; if (Tcl_GetWideIntFromObj(Tkapp_Interp(tkapp), value, &wideValue) == TCL_OK) { @@ -1140,7 +1173,7 @@ fromWideIntObj(PyObject* tkapp, Tcl_Obj *value) #ifdef HAVE_LIBTOMMAMTH static PyObject* -fromBignumObj(PyObject* tkapp, Tcl_Obj *value) +fromBignumObj(TkappObject *tkapp, Tcl_Obj *value) { mp_int bigValue; unsigned long numBytes; @@ -1176,32 +1209,31 @@ fromBignumObj(PyObject* tkapp, Tcl_Obj *value) #endif static PyObject* -FromObj(PyObject* tkapp, Tcl_Obj *value) +FromObj(TkappObject *tkapp, Tcl_Obj *value) { PyObject *result = NULL; - TkappObject *app = (TkappObject*)tkapp; Tcl_Interp *interp = Tkapp_Interp(tkapp); if (value->typePtr == NULL) { - return unicodeFromTclStringAndSize(value->bytes, value->length); + return unicodeFromTclObj(value); } - if (value->typePtr == app->BooleanType || - value->typePtr == app->OldBooleanType) { + if (value->typePtr == tkapp->BooleanType || + value->typePtr == tkapp->OldBooleanType) { return fromBoolean(tkapp, value); } - if (value->typePtr == app->ByteArrayType) { + if (value->typePtr == tkapp->ByteArrayType) { int size; char *data = (char*)Tcl_GetByteArrayFromObj(value, &size); return PyBytes_FromStringAndSize(data, size); } - if (value->typePtr == app->DoubleType) { + if (value->typePtr == tkapp->DoubleType) { return PyFloat_FromDouble(value->internalRep.doubleValue); } - if (value->typePtr == app->IntType) { + if (value->typePtr == tkapp->IntType) { long longValue; if (Tcl_GetLongFromObj(interp, value, &longValue) == TCL_OK) return PyLong_FromLong(longValue); @@ -1209,8 +1241,8 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) fall through to wideInt handling. */ } - if (value->typePtr == app->IntType || - value->typePtr == app->WideIntType) { + if (value->typePtr == tkapp->IntType || + value->typePtr == tkapp->WideIntType) { result = fromWideIntObj(tkapp, value); if (result != NULL || PyErr_Occurred()) return result; @@ -1220,14 +1252,14 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) } #ifdef HAVE_LIBTOMMAMTH - if (value->typePtr == app->IntType || - value->typePtr == app->WideIntType || - value->typePtr == app->BignumType) { + if (value->typePtr == tkapp->IntType || + value->typePtr == tkapp->WideIntType || + value->typePtr == tkapp->BignumType) { return fromBignumObj(tkapp, value); } #endif - if (value->typePtr == app->ListType) { + if (value->typePtr == tkapp->ListType) { int size; int i, status; PyObject *elem; @@ -1255,30 +1287,28 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) return result; } - if (value->typePtr == app->ProcBodyType) { + if (value->typePtr == tkapp->ProcBodyType) { /* fall through: return tcl object. */ } - if (value->typePtr == app->StringType) { - return PyUnicode_FromKindAndData( - sizeof(Tcl_UniChar), Tcl_GetUnicode(value), - Tcl_GetCharLength(value)); + if (value->typePtr == tkapp->StringType) { + return unicodeFromTclObj(value); } #if TK_HEX_VERSION >= 0x08050000 - if (app->BooleanType == NULL && + if (tkapp->BooleanType == NULL && strcmp(value->typePtr->name, "booleanString") == 0) { /* booleanString type is not registered in Tcl */ - app->BooleanType = value->typePtr; + tkapp->BooleanType = value->typePtr; return fromBoolean(tkapp, value); } #endif #ifdef HAVE_LIBTOMMAMTH - if (app->BignumType == NULL && + if (tkapp->BignumType == NULL && strcmp(value->typePtr->name, "bignum") == 0) { /* bignum type is not registered in Tcl */ - app->BignumType = value->typePtr; + tkapp->BignumType = value->typePtr; return fromBignumObj(tkapp, value); } #endif @@ -1368,19 +1398,28 @@ finally: return NULL; } +/* Convert the results of a command call into a Python string. */ + +static PyObject * +Tkapp_UnicodeResult(TkappObject *self) +{ + return unicodeFromTclObj(Tcl_GetObjResult(self->interp)); +} + + /* Convert the results of a command call into a Python objects. */ -static PyObject* -Tkapp_CallResult(TkappObject *self) +static PyObject * +Tkapp_ObjectResult(TkappObject *self) { PyObject *res = NULL; Tcl_Obj *value = Tcl_GetObjResult(self->interp); - if(self->wantobjects) { + if (self->wantobjects) { /* Not sure whether the IncrRef is necessary, but something may overwrite the interpreter result while we are converting it. */ Tcl_IncrRefCount(value); - res = FromObj((PyObject*)self, value); + res = FromObj(self, value); Tcl_DecrRefCount(value); } else { res = unicodeFromTclObj(value); @@ -1412,15 +1451,13 @@ Tkapp_CallProc(Tkapp_CallEvent *e, int flags) i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags); ENTER_PYTHON if (i == TCL_ERROR) { - *(e->res) = NULL; - *(e->exc_type) = NULL; - *(e->exc_tb) = NULL; - *(e->exc_value) = PyObject_CallFunction( - Tkinter_TclError, "s", - Tcl_GetStringResult(e->self->interp)); + *(e->res) = Tkinter_Error(e->self); } else { - *(e->res) = Tkapp_CallResult(e->self); + *(e->res) = Tkapp_ObjectResult(e->self); + } + if (*(e->res) == NULL) { + PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb); } LEAVE_PYTHON @@ -1508,9 +1545,9 @@ Tkapp_Call(PyObject *selfptr, PyObject *args) ENTER_OVERLAP if (i == TCL_ERROR) - Tkinter_Error(selfptr); + Tkinter_Error(self); else - res = Tkapp_CallResult(self); + res = Tkapp_ObjectResult(self); LEAVE_OVERLAP_TCL @@ -1542,9 +1579,9 @@ _tkinter_tkapp_eval_impl(TkappObject *self, const char *script) err = Tcl_Eval(Tkapp_Interp(self), script); ENTER_OVERLAP if (err == TCL_ERROR) - res = Tkinter_Error((PyObject *)self); + res = Tkinter_Error(self); else - res = unicodeFromTclString(Tkapp_Result(self)); + res = Tkapp_UnicodeResult(self); LEAVE_OVERLAP_TCL return res; } @@ -1571,9 +1608,9 @@ _tkinter_tkapp_evalfile_impl(TkappObject *self, const char *fileName) err = Tcl_EvalFile(Tkapp_Interp(self), fileName); ENTER_OVERLAP if (err == TCL_ERROR) - res = Tkinter_Error((PyObject *)self); + res = Tkinter_Error(self); else - res = unicodeFromTclString(Tkapp_Result(self)); + res = Tkapp_UnicodeResult(self); LEAVE_OVERLAP_TCL return res; } @@ -1600,9 +1637,9 @@ _tkinter_tkapp_record_impl(TkappObject *self, const char *script) err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL); ENTER_OVERLAP if (err == TCL_ERROR) - res = Tkinter_Error((PyObject *)self); + res = Tkinter_Error(self); else - res = unicodeFromTclString(Tkapp_Result(self)); + res = Tkapp_UnicodeResult(self); LEAVE_OVERLAP_TCL return res; } @@ -1633,13 +1670,13 @@ _tkinter_tkapp_adderrorinfo_impl(TkappObject *self, const char *msg) /** Tcl Variable **/ -typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags); +typedef PyObject* (*EventFunc)(TkappObject *, PyObject *, int); TCL_DECLARE_MUTEX(var_mutex) typedef struct VarEvent { Tcl_Event ev; /* must be first */ - PyObject *self; + TkappObject *self; PyObject *args; int flags; EventFunc func; @@ -1694,7 +1731,7 @@ varname_converter(PyObject *in, void *_out) return 1; } if (PyTclObject_Check(in)) { - *out = PyTclObject_TclString(in); + *out = Tcl_GetString(((PyTclObject *)in)->value); return 1; } PyErr_Format(PyExc_TypeError, @@ -1752,7 +1789,7 @@ var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags) PyErr_NoMemory(); return NULL; } - ev->self = selfptr; + ev->self = self; ev->args = args; ev->flags = flags; ev->func = func; @@ -1772,11 +1809,11 @@ var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags) return res; } /* Tcl is not threaded, or this is the interpreter thread. */ - return func(selfptr, args, flags); + return func(self, args, flags); } static PyObject * -SetVar(PyObject *self, PyObject *args, int flags) +SetVar(TkappObject *self, PyObject *args, int flags) { const char *name1, *name2; PyObject *newValue; @@ -1845,7 +1882,7 @@ Tkapp_GlobalSetVar(PyObject *self, PyObject *args) static PyObject * -GetVar(PyObject *self, PyObject *args, int flags) +GetVar(TkappObject *self, PyObject *args, int flags) { const char *name1, *name2=NULL; PyObject *res = NULL; @@ -1860,10 +1897,9 @@ GetVar(PyObject *self, PyObject *args, int flags) tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags); ENTER_OVERLAP if (tres == NULL) { - PyErr_SetString(Tkinter_TclError, - Tcl_GetStringResult(Tkapp_Interp(self))); + Tkinter_Error(self); } else { - if (((TkappObject*)self)->wantobjects) { + if (self->wantobjects) { res = FromObj(self, tres); } else { @@ -1889,7 +1925,7 @@ Tkapp_GlobalGetVar(PyObject *self, PyObject *args) static PyObject * -UnsetVar(PyObject *self, PyObject *args, int flags) +UnsetVar(TkappObject *self, PyObject *args, int flags) { char *name1, *name2=NULL; int code; @@ -1961,7 +1997,7 @@ _tkinter_tkapp_getint(TkappObject *self, PyObject *arg) CHECK_STRING_LENGTH(s); value = Tcl_NewStringObj(s, -1); if (value == NULL) - return Tkinter_Error((PyObject *)self); + return Tkinter_Error(self); } /* Don't use Tcl_GetInt() because it returns ambiguous result for value in ranges -2**32..-2**31-1 and 2**31..2**32-1 (on 32-bit platform). @@ -1970,14 +2006,14 @@ _tkinter_tkapp_getint(TkappObject *self, PyObject *arg) value in ranges -2**64..-2**63-1 and 2**63..2**64-1 (on 32-bit platform). */ #ifdef HAVE_LIBTOMMAMTH - result = fromBignumObj((PyObject *)self, value); + result = fromBignumObj(self, value); #else - result = fromWideIntObj((PyObject *)self, value); + result = fromWideIntObj(self, value); #endif Tcl_DecrRefCount(value); if (result != NULL || PyErr_Occurred()) return result; - return Tkinter_Error((PyObject *)self); + return Tkinter_Error(self); } /*[clinic input] @@ -2008,7 +2044,7 @@ _tkinter_tkapp_getdouble(TkappObject *self, PyObject *arg) if (Tcl_GetDoubleFromObj(Tkapp_Interp(self), ((PyTclObject*)arg)->value, &v) == TCL_ERROR) - return Tkinter_Error((PyObject *)self); + return Tkinter_Error(self); return PyFloat_FromDouble(v); } @@ -2016,7 +2052,7 @@ _tkinter_tkapp_getdouble(TkappObject *self, PyObject *arg) return NULL; CHECK_STRING_LENGTH(s); if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR) - return Tkinter_Error((PyObject *)self); + return Tkinter_Error(self); return PyFloat_FromDouble(v); } @@ -2043,7 +2079,7 @@ _tkinter_tkapp_getboolean(TkappObject *self, PyObject *arg) if (Tcl_GetBooleanFromObj(Tkapp_Interp(self), ((PyTclObject*)arg)->value, &v) == TCL_ERROR) - return Tkinter_Error((PyObject *)self); + return Tkinter_Error(self); return PyBool_FromLong(v); } @@ -2051,7 +2087,7 @@ _tkinter_tkapp_getboolean(TkappObject *self, PyObject *arg) return NULL; CHECK_STRING_LENGTH(s); if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR) - return Tkinter_Error((PyObject *)self); + return Tkinter_Error(self); return PyBool_FromLong(v); } @@ -2077,9 +2113,9 @@ _tkinter_tkapp_exprstring_impl(TkappObject *self, const char *s) retval = Tcl_ExprString(Tkapp_Interp(self), s); ENTER_OVERLAP if (retval == TCL_ERROR) - res = Tkinter_Error((PyObject *)self); + res = Tkinter_Error(self); else - res = unicodeFromTclString(Tkapp_Result(self)); + res = Tkapp_UnicodeResult(self); LEAVE_OVERLAP_TCL return res; } @@ -2107,7 +2143,7 @@ _tkinter_tkapp_exprlong_impl(TkappObject *self, const char *s) retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v); ENTER_OVERLAP if (retval == TCL_ERROR) - res = Tkinter_Error((PyObject *)self); + res = Tkinter_Error(self); else res = PyLong_FromLong(v); LEAVE_OVERLAP_TCL @@ -2138,7 +2174,7 @@ _tkinter_tkapp_exprdouble_impl(TkappObject *self, const char *s) ENTER_OVERLAP PyFPE_END_PROTECT(retval) if (retval == TCL_ERROR) - res = Tkinter_Error((PyObject *)self); + res = Tkinter_Error(self); else res = PyFloat_FromDouble(v); LEAVE_OVERLAP_TCL @@ -2167,7 +2203,7 @@ _tkinter_tkapp_exprboolean_impl(TkappObject *self, const char *s) retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v); ENTER_OVERLAP if (retval == TCL_ERROR) - res = Tkinter_Error((PyObject *)self); + res = Tkinter_Error(self); else res = PyLong_FromLong(v); LEAVE_OVERLAP_TCL @@ -2200,12 +2236,12 @@ _tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg) if (Tcl_ListObjGetElements(Tkapp_Interp(self), ((PyTclObject*)arg)->value, &objc, &objv) == TCL_ERROR) { - return Tkinter_Error((PyObject *)self); + return Tkinter_Error(self); } if (!(v = PyTuple_New(objc))) return NULL; for (i = 0; i < objc; i++) { - PyObject *s = FromObj((PyObject*)self, objv[i]); + PyObject *s = FromObj(self, objv[i]); if (!s) { Py_DECREF(v); return NULL; @@ -2233,7 +2269,7 @@ _tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg) if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR) { PyMem_Free(list); - return Tkinter_Error((PyObject *)self); + return Tkinter_Error(self); } if (!(v = PyTuple_New(argc))) @@ -2277,16 +2313,16 @@ _tkinter_tkapp_split(TkappObject *self, PyObject *arg) int i; if (Tcl_ListObjGetElements(Tkapp_Interp(self), value, &objc, &objv) == TCL_ERROR) { - return FromObj((PyObject*)self, value); + return FromObj(self, value); } if (objc == 0) return PyUnicode_FromString(""); if (objc == 1) - return FromObj((PyObject*)self, objv[0]); + return FromObj(self, objv[0]); if (!(v = PyTuple_New(objc))) return NULL; for (i = 0; i < objc; i++) { - PyObject *s = FromObj((PyObject*)self, objv[i]); + PyObject *s = FromObj(self, objv[i]); if (!s) { Py_DECREF(v); return NULL; @@ -2333,34 +2369,31 @@ PythonCmd_Error(Tcl_Interp *interp) * function or method. */ static int -PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) +PythonCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) { PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData; - PyObject *func, *arg, *res; - int i, rv; + PyObject *args, *res; + int i; Tcl_Obj *obj_res; ENTER_PYTHON - /* TBD: no error checking here since we know, via the - * Tkapp_CreateCommand() that the client data is a two-tuple - */ - func = data->func; - - /* Create argument list (argv1, ..., argvN) */ - if (!(arg = PyTuple_New(argc - 1))) + /* Create argument tuple (objv1, ..., objvN) */ + if (!(args = PyTuple_New(objc - 1))) return PythonCmd_Error(interp); - for (i = 0; i < (argc - 1); i++) { - PyObject *s = unicodeFromTclString(argv[i + 1]); + for (i = 0; i < (objc - 1); i++) { + PyObject *s = unicodeFromTclObj(objv[i + 1]); if (!s) { - Py_DECREF(arg); + Py_DECREF(args); return PythonCmd_Error(interp); } - PyTuple_SET_ITEM(arg, i, s); + PyTuple_SET_ITEM(args, i, s); } - res = PyObject_Call(func, arg, NULL); - Py_DECREF(arg); + + res = PyObject_Call(data->func, args, NULL); + Py_DECREF(args); if (res == NULL) return PythonCmd_Error(interp); @@ -2370,18 +2403,15 @@ PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[ Py_DECREF(res); return PythonCmd_Error(interp); } - else { - Tcl_SetObjResult(interp, obj_res); - rv = TCL_OK; - } - + Tcl_SetObjResult(interp, obj_res); Py_DECREF(res); LEAVE_PYTHON - return rv; + return TCL_OK; } + static void PythonCmdDelete(ClientData clientData) { @@ -2413,7 +2443,7 @@ static int Tkapp_CommandProc(CommandEvent *ev, int flags) { if (ev->create) - *ev->status = Tcl_CreateCommand( + *ev->status = Tcl_CreateObjCommand( ev->interp, ev->name, PythonCmd, ev->data, PythonCmdDelete) == NULL; else @@ -2479,7 +2509,7 @@ _tkinter_tkapp_createcommand_impl(TkappObject *self, const char *name, else { ENTER_TCL - err = Tcl_CreateCommand( + err = Tcl_CreateObjCommand( Tkapp_Interp(self), name, PythonCmd, (ClientData)data, PythonCmdDelete) == NULL; LEAVE_TCL @@ -2956,9 +2986,9 @@ _tkinter_tkapp_loadtk_impl(TkappObject *self) if (err == TCL_ERROR) { /* This sets an exception, but we cannot return right away because we need to exit the overlap first. */ - Tkinter_Error((PyObject *)self); + Tkinter_Error(self); } else { - _tk_exists = Tkapp_Result(self); + _tk_exists = Tcl_GetStringResult(Tkapp_Interp(self)); } LEAVE_OVERLAP_TCL if (err == TCL_ERROR) { @@ -2966,8 +2996,7 @@ _tkinter_tkapp_loadtk_impl(TkappObject *self) } if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) { if (Tk_Init(interp) == TCL_ERROR) { - PyErr_SetString(Tkinter_TclError, - Tcl_GetStringResult(Tkapp_Interp(self))); + Tkinter_Error(self); #ifdef TKINTER_PROTECT_LOADTK tk_load_failed = 1; #endif @@ -3523,11 +3552,13 @@ PyInit__tkinter(void) if (!ret && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { str_path = _get_tcl_lib_path(); if (str_path == NULL && PyErr_Occurred()) { + Py_DECREF(m); return NULL; } if (str_path != NULL) { wcs_path = PyUnicode_AsWideCharString(str_path, NULL); if (wcs_path == NULL) { + Py_DECREF(m); return NULL; } SetEnvironmentVariableW(L"TCL_LIBRARY", wcs_path); diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index 7f19c55..1fe72a8 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -1655,8 +1655,10 @@ PyInit__tracemalloc(void) if (m == NULL) return NULL; - if (tracemalloc_init() < 0) + if (tracemalloc_init() < 0) { + Py_DECREF(m); return NULL; + } return m; } diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 97c64f6..f3e3a29 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -1094,18 +1094,14 @@ faulthandler_fatal_error_py(PyObject *self, PyObject *args) #if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) #define FAULTHANDLER_STACK_OVERFLOW -#ifdef __INTEL_COMPILER - /* Issue #23654: Turn off ICC's tail call optimization for the - * stack_overflow generator. ICC turns the recursive tail call into - * a loop. */ -# pragma intel optimization_level 0 -#endif -static -uintptr_t +static uintptr_t stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth) { - /* allocate 4096 bytes on the stack at each call */ - unsigned char buffer[4096]; + /* Allocate (at least) 4096 bytes on the stack at each call. + + bpo-23654, bpo-38965: use volatile keyword to prevent tail call + optimization. */ + volatile unsigned char buffer[4096]; uintptr_t sp = (uintptr_t)&buffer; *depth += 1; if (sp < min_sp || max_sp < sp) @@ -1273,25 +1269,36 @@ PyInit_faulthandler(void) #ifdef MS_WINDOWS /* RaiseException() codes (prefixed by an underscore) */ if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION", - EXCEPTION_ACCESS_VIOLATION)) - return NULL; + EXCEPTION_ACCESS_VIOLATION)) { + goto error; + } if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO", - EXCEPTION_INT_DIVIDE_BY_ZERO)) - return NULL; + EXCEPTION_INT_DIVIDE_BY_ZERO)) { + goto error; + } if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW", - EXCEPTION_STACK_OVERFLOW)) - return NULL; + EXCEPTION_STACK_OVERFLOW)) { + goto error; + } /* RaiseException() flags (prefixed by an underscore) */ if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE", - EXCEPTION_NONCONTINUABLE)) - return NULL; + EXCEPTION_NONCONTINUABLE)) { + goto error; + } if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION", - EXCEPTION_NONCONTINUABLE_EXCEPTION)) - return NULL; + EXCEPTION_NONCONTINUABLE_EXCEPTION)) { + goto error; + } #endif return m; + +#ifdef MS_WINDOWS +error: + Py_DECREF(m); + return NULL; +#endif } static int diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 4d701cb..3258603 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -887,13 +887,9 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, */ move_legacy_finalizer_reachable(&finalizers); - /* Collect statistics on collectable objects found and print - * debugging information. - */ - for (gc = unreachable.gc.gc_next; gc != &unreachable; - gc = gc->gc.gc_next) { - m++; - if (_PyRuntime.gc.debug & DEBUG_COLLECTABLE) { + /* Print debugging information. */ + if (_PyRuntime.gc.debug & DEBUG_COLLECTABLE) { + for (gc = unreachable.gc.gc_next; gc != &unreachable; gc = gc->gc.gc_next) { debug_cycle("collectable", FROM_GC(gc)); } } @@ -913,6 +909,7 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, * the reference cycles to be broken. It may also cause some objects * in finalizers to be freed. */ + m += gc_list_size(&unreachable); delete_garbage(&unreachable, old); } diff --git a/Modules/main.c b/Modules/main.c index acc59c6..4d13184 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -131,6 +131,7 @@ static const char usage_5[] = "PYTHONHOME : alternate directory (or %lc).\n" " The default module search path uses %s.\n" "PYTHONCASEOK : ignore case in 'import' statements (Windows).\n" +"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n" "PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n" "PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n"; static const char usage_6[] = diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c index 07842f7..7c8ea81 100644 --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -757,7 +757,7 @@ tailmatch(const char *str, Py_ssize_t len, PyObject *substr, if (direction < 0) { /* startswith */ - if (start + slen > len) + if (start > len - slen) goto notfound; } else { /* endswith */ diff --git a/Objects/clinic/unicodeobject.c.h b/Objects/clinic/unicodeobject.c.h index 8072516..2b744b6 100644 --- a/Objects/clinic/unicodeobject.c.h +++ b/Objects/clinic/unicodeobject.c.h @@ -484,7 +484,7 @@ PyDoc_STRVAR(unicode_strip__doc__, "strip($self, chars=None, /)\n" "--\n" "\n" -"Return a copy of the string with leading and trailing whitespace remove.\n" +"Return a copy of the string with leading and trailing whitespace removed.\n" "\n" "If chars is given and not None, remove characters in chars instead."); @@ -951,4 +951,4 @@ unicode_sizeof(PyObject *self, PyObject *Py_UNUSED(ignored)) { return unicode_sizeof_impl(self); } -/*[clinic end generated code: output=561c88c912b8fe3b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=49bf50c732b9b53b input=a9049054013a1b77]*/ diff --git a/Objects/genobject.c b/Objects/genobject.c index 8a978b1..7fc7a1f 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -1920,6 +1920,17 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args) PyErr_SetString(PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG); return NULL; } + if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) || + PyErr_ExceptionMatches(PyExc_GeneratorExit)) + { + /* when aclose() is called we don't want to propagate + StopAsyncIteration or GeneratorExit; just raise + StopIteration, signalling that this 'aclose()' await + is done. + */ + PyErr_Clear(); + PyErr_SetNone(PyExc_StopIteration); + } return retval; } } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 9e0731b..d7e5a9d 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -12474,14 +12474,14 @@ str.strip as unicode_strip chars: object = None / -Return a copy of the string with leading and trailing whitespace remove. +Return a copy of the string with leading and trailing whitespace removed. If chars is given and not None, remove characters in chars instead. [clinic start generated code]*/ static PyObject * unicode_strip_impl(PyObject *self, PyObject *chars) -/*[clinic end generated code: output=ca19018454345d57 input=eefe24a1059c352b]*/ +/*[clinic end generated code: output=ca19018454345d57 input=385289c6f423b954]*/ { return do_argstrip(self, BOTHSTRIP, chars); } diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index f600179..4bf662c 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -145,11 +145,14 @@ weakref_hash(PyWeakReference *self) { if (self->hash != -1) return self->hash; - if (PyWeakref_GET_OBJECT(self) == Py_None) { + PyObject* obj = PyWeakref_GET_OBJECT(self); + if (obj == Py_None) { PyErr_SetString(PyExc_TypeError, "weak object has gone away"); return -1; } - self->hash = PyObject_Hash(PyWeakref_GET_OBJECT(self)); + Py_INCREF(obj); + self->hash = PyObject_Hash(obj); + Py_DECREF(obj); return self->hash; } @@ -159,11 +162,18 @@ weakref_repr(PyWeakReference *self) { PyObject *name, *repr; _Py_IDENTIFIER(__name__); + PyObject* obj = PyWeakref_GET_OBJECT(self); - if (PyWeakref_GET_OBJECT(self) == Py_None) + if (obj == Py_None) { return PyUnicode_FromFormat("", self); + } + + Py_INCREF(obj); + if (_PyObject_LookupAttrId(obj, &PyId___name__, &name) < 0) { + Py_DECREF(obj); + return NULL; + } - name = _PyObject_GetAttrId(PyWeakref_GET_OBJECT(self), &PyId___name__); if (name == NULL || !PyUnicode_Check(name)) { if (name == NULL) PyErr_Clear(); @@ -171,16 +181,17 @@ weakref_repr(PyWeakReference *self) "", self, Py_TYPE(PyWeakref_GET_OBJECT(self))->tp_name, - PyWeakref_GET_OBJECT(self)); + obj); } else { repr = PyUnicode_FromFormat( "", self, Py_TYPE(PyWeakref_GET_OBJECT(self))->tp_name, - PyWeakref_GET_OBJECT(self), + obj, name); } + Py_DECREF(obj); Py_XDECREF(name); return repr; } @@ -207,8 +218,14 @@ weakref_richcompare(PyWeakReference* self, PyWeakReference* other, int op) else Py_RETURN_FALSE; } - return PyObject_RichCompare(PyWeakref_GET_OBJECT(self), - PyWeakref_GET_OBJECT(other), op); + PyObject* obj = PyWeakref_GET_OBJECT(self); + PyObject* other_obj = PyWeakref_GET_OBJECT(other); + Py_INCREF(obj); + Py_INCREF(other_obj); + PyObject* res = PyObject_RichCompare(obj, other_obj, op); + Py_DECREF(obj); + Py_DECREF(other_obj); + return res; } /* Given the head of an object's list of weak references, extract the @@ -415,18 +432,14 @@ proxy_checkref(PyWeakReference *proxy) o = PyWeakref_GET_OBJECT(o); \ } -#define UNWRAP_I(o) \ - if (PyWeakref_CheckProxy(o)) { \ - if (!proxy_checkref((PyWeakReference *)o)) \ - return -1; \ - o = PyWeakref_GET_OBJECT(o); \ - } - #define WRAP_UNARY(method, generic) \ static PyObject * \ method(PyObject *proxy) { \ UNWRAP(proxy); \ - return generic(proxy); \ + Py_INCREF(proxy); \ + PyObject* res = generic(proxy); \ + Py_DECREF(proxy); \ + return res; \ } #define WRAP_BINARY(method, generic) \ @@ -434,7 +447,12 @@ proxy_checkref(PyWeakReference *proxy) method(PyObject *x, PyObject *y) { \ UNWRAP(x); \ UNWRAP(y); \ - return generic(x, y); \ + Py_INCREF(x); \ + Py_INCREF(y); \ + PyObject* res = generic(x, y); \ + Py_DECREF(x); \ + Py_DECREF(y); \ + return res; \ } /* Note that the third arg needs to be checked for NULL since the tp_call @@ -447,7 +465,14 @@ proxy_checkref(PyWeakReference *proxy) UNWRAP(v); \ if (w != NULL) \ UNWRAP(w); \ - return generic(proxy, v, w); \ + Py_INCREF(proxy); \ + Py_INCREF(v); \ + Py_XINCREF(w); \ + PyObject* res = generic(proxy, v, w); \ + Py_DECREF(proxy); \ + Py_DECREF(v); \ + Py_XDECREF(w); \ + return res; \ } #define WRAP_METHOD(method, special) \ @@ -455,7 +480,10 @@ proxy_checkref(PyWeakReference *proxy) method(PyObject *proxy) { \ _Py_IDENTIFIER(special); \ UNWRAP(proxy); \ - return _PyObject_CallMethodId(proxy, &PyId_##special, NULL); \ + Py_INCREF(proxy); \ + PyObject* res = _PyObject_CallMethodId(proxy, &PyId_##special, NULL); \ + Py_DECREF(proxy); \ + return res; \ } @@ -481,7 +509,11 @@ proxy_setattr(PyWeakReference *proxy, PyObject *name, PyObject *value) { if (!proxy_checkref(proxy)) return -1; - return PyObject_SetAttr(PyWeakref_GET_OBJECT(proxy), name, value); + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + int res = PyObject_SetAttr(obj, name, value); + Py_DECREF(obj); + return res; } static PyObject * @@ -530,9 +562,13 @@ static int proxy_bool(PyWeakReference *proxy) { PyObject *o = PyWeakref_GET_OBJECT(proxy); - if (!proxy_checkref(proxy)) + if (!proxy_checkref(proxy)) { return -1; - return PyObject_IsTrue(o); + } + Py_INCREF(o); + int res = PyObject_IsTrue(o); + Py_DECREF(o); + return res; } static void @@ -551,9 +587,13 @@ proxy_contains(PyWeakReference *proxy, PyObject *value) { if (!proxy_checkref(proxy)) return -1; - return PySequence_Contains(PyWeakref_GET_OBJECT(proxy), value); -} + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + int res = PySequence_Contains(obj, value); + Py_DECREF(obj); + return res; +} /* mapping slots */ @@ -562,7 +602,12 @@ proxy_length(PyWeakReference *proxy) { if (!proxy_checkref(proxy)) return -1; - return PyObject_Length(PyWeakref_GET_OBJECT(proxy)); + + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + Py_ssize_t res = PyObject_Length(obj); + Py_DECREF(obj); + return res; } WRAP_BINARY(proxy_getitem, PyObject_GetItem) @@ -573,10 +618,16 @@ proxy_setitem(PyWeakReference *proxy, PyObject *key, PyObject *value) if (!proxy_checkref(proxy)) return -1; - if (value == NULL) - return PyObject_DelItem(PyWeakref_GET_OBJECT(proxy), key); - else - return PyObject_SetItem(PyWeakref_GET_OBJECT(proxy), key, value); + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + int res; + if (value == NULL) { + res = PyObject_DelItem(obj, key); + } else { + res = PyObject_SetItem(obj, key, value); + } + Py_DECREF(obj); + return res; } /* iterator slots */ @@ -586,7 +637,11 @@ proxy_iter(PyWeakReference *proxy) { if (!proxy_checkref(proxy)) return NULL; - return PyObject_GetIter(PyWeakref_GET_OBJECT(proxy)); + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + PyObject* res = PyObject_GetIter(obj); + Py_DECREF(obj); + return res; } static PyObject * @@ -594,7 +649,12 @@ proxy_iternext(PyWeakReference *proxy) { if (!proxy_checkref(proxy)) return NULL; - return PyIter_Next(PyWeakref_GET_OBJECT(proxy)); + + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + PyObject* res = PyIter_Next(obj); + Py_DECREF(obj); + return res; } diff --git a/PCbuild/find_python.bat b/PCbuild/find_python.bat index 7f90fca..8b421a3 100644 --- a/PCbuild/find_python.bat +++ b/PCbuild/find_python.bat @@ -24,6 +24,9 @@ :begin_search @set PYTHON= +@rem If there is an active virtual env, use that one +@if NOT "%VIRTUAL_ENV%"=="" (set PYTHON="%VIRTUAL_ENV%\Scripts\python.exe") & (set _Py_Python_Source=found in virtual env) & goto :found + @set _Py_EXTERNALS_DIR=%EXTERNALS_DIR% @if "%_Py_EXTERNALS_DIR%"=="" (set _Py_EXTERNALS_DIR=%~dp0\..\externals) diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index 44e3d40..20a7186 100644 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -1209,7 +1209,6 @@ PyObject* PyAST_mod2obj(mod_ty t) /* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */ mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) { - mod_ty res; PyObject *req_type[3]; char *req_name[] = {"Module", "Expression", "Interactive"}; int isinstance; @@ -1231,6 +1230,8 @@ mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) req_name[mode], Py_TYPE(ast)->tp_name); return NULL; } + + mod_ty res = NULL; if (obj2ast_mod(ast, &res, arena) != 0) return NULL; else diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index d720f19..1739bb7 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -1395,6 +1395,12 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) if (col == 0 && c == '\n' && tok->prompt != NULL) { blankline = 0; /* Let it through */ } + else if (tok->prompt != NULL && tok->lineno == 1) { + /* In interactive mode, if the first line contains + only spaces and/or a comment, let it through. */ + blankline = 0; + col = altcol = 0; + } else { blankline = 1; /* Ignore completely */ } diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 6a2f28e..74fae33 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -8365,7 +8365,6 @@ PyObject* PyAST_mod2obj(mod_ty t) /* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */ mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) { - mod_ty res; PyObject *req_type[3]; char *req_name[] = {"Module", "Expression", "Interactive"}; int isinstance; @@ -8387,6 +8386,8 @@ mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) req_name[mode], Py_TYPE(ast)->tp_name); return NULL; } + + mod_ty res = NULL; if (obj2ast_mod(ast, &res, arena) != 0) return NULL; else diff --git a/Python/ast.c b/Python/ast.c index ce61375..5a60d69 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -1531,8 +1531,9 @@ ast_for_decorator(struct compiling *c, const node *n) name_expr = NULL; } else if (NCH(n) == 5) { /* Call with no arguments */ - d = Call(name_expr, NULL, NULL, LINENO(n), - n->n_col_offset, c->c_arena); + d = Call(name_expr, NULL, NULL, + name_expr->lineno, name_expr->col_offset, + c->c_arena); if (!d) return NULL; name_expr = NULL; diff --git a/Python/context.c b/Python/context.c index 90c71e3..c1575c9 100644 --- a/Python/context.c +++ b/Python/context.c @@ -974,9 +974,10 @@ _contextvars_ContextVar_reset(PyContextVar *self, PyObject *token) static PyObject * -contextvar_cls_getitem(PyObject *self, PyObject *args) +contextvar_cls_getitem(PyObject *self, PyObject *arg) { - Py_RETURN_NONE; + Py_INCREF(self); + return self; } static PyMemberDef PyContextVar_members[] = { @@ -989,7 +990,7 @@ static PyMethodDef PyContextVar_methods[] = { _CONTEXTVARS_CONTEXTVAR_SET_METHODDEF _CONTEXTVARS_CONTEXTVAR_RESET_METHODDEF {"__class_getitem__", contextvar_cls_getitem, - METH_VARARGS | METH_STATIC, NULL}, + METH_O | METH_CLASS, NULL}, {NULL, NULL} }; diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index ef81d15..e0de8cb 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -589,7 +589,7 @@ calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix, spec->n_remainder + spec->n_rpadding; } -/* Fill in the digit parts of a numbers's string representation, +/* Fill in the digit parts of a number's string representation, as determined in calc_number_widths(). Return -1 on error, or 0 on success. */ static int diff --git a/Python/getargs.c b/Python/getargs.c index 73e47f8..1c53361 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -1209,7 +1209,19 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, } } memcpy(*buffer, ptr, size+1); - STORE_SIZE(size); + + if (flags & FLAG_SIZE_T) { + *q2 = size; + } + else { + if (INT_MAX < size) { + Py_DECREF(s); + PyErr_SetString(PyExc_OverflowError, + "size does not fit in an int"); + return converterr("", arg, msgbuf, bufsize); + } + *q = (int)size; + } } else { /* Using a 0-terminated buffer: diff --git a/Python/hamt.c b/Python/hamt.c index 71a5ec8..6bcdfac 100644 --- a/Python/hamt.c +++ b/Python/hamt.c @@ -5,7 +5,7 @@ #include "internal/hamt.h" /* -This file provides an implemention of an immutable mapping using the +This file provides an implementation of an immutable mapping using the Hash Array Mapped Trie (or HAMT) datastructure. This design allows to have: diff --git a/Python/marshal.c b/Python/marshal.c index 7d60614..2e911b7 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -1860,6 +1860,9 @@ PyMarshal_Init(void) PyObject *mod = PyModule_Create(&marshalmodule); if (mod == NULL) return NULL; - PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION); + if (PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION) < 0) { + Py_DECREF(mod); + return NULL; + } return mod; } diff --git a/README.rst b/README.rst index 795b821..27425dd 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.7.5 +This is Python version 3.7.6 ============================ .. image:: https://travis-ci.org/python/cpython.svg?branch=3.7 diff --git a/Tools/msi/doc/doc.wxs b/Tools/msi/doc/doc.wxs index 306fb11..cd1a68c 100644 --- a/Tools/msi/doc/doc.wxs +++ b/Tools/msi/doc/doc.wxs @@ -8,7 +8,7 @@ - + 1 diff --git a/Tools/scripts/pathfix.py b/Tools/scripts/pathfix.py index c5bf984..28ee428 100755 --- a/Tools/scripts/pathfix.py +++ b/Tools/scripts/pathfix.py @@ -70,9 +70,9 @@ def main(): if fix(arg): bad = 1 sys.exit(bad) -ispythonprog = re.compile(r'^[a-zA-Z0-9_]+\.py$') + def ispython(name): - return bool(ispythonprog.match(name)) + return name.endswith('.py') def recursedown(dirname): dbg('recursedown(%r)\n' % (dirname,)) diff --git a/configure b/configure index 0f466db..b769d59 100755 --- a/configure +++ b/configure @@ -16849,9 +16849,12 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #include - atomic_int value = ATOMIC_VAR_INIT(1); + atomic_int int_var; + atomic_uintptr_t uintptr_var; int main() { - int loaded_value = atomic_load(&value); + atomic_store_explicit(&int_var, 5, memory_order_relaxed); + atomic_store_explicit(&uintptr_var, 0, memory_order_relaxed); + int loaded_value = atomic_load_explicit(&int_var, memory_order_seq_cst); return 0; } diff --git a/configure.ac b/configure.ac index 1ef0df7..49acff3 100644 --- a/configure.ac +++ b/configure.ac @@ -5492,9 +5492,12 @@ AC_LINK_IFELSE( [ AC_LANG_SOURCE([[ #include - atomic_int value = ATOMIC_VAR_INIT(1); + atomic_int int_var; + atomic_uintptr_t uintptr_var; int main() { - int loaded_value = atomic_load(&value); + atomic_store_explicit(&int_var, 5, memory_order_relaxed); + atomic_store_explicit(&uintptr_var, 0, memory_order_relaxed); + int loaded_value = atomic_load_explicit(&int_var, memory_order_seq_cst); return 0; } ]]) @@ -5504,7 +5507,7 @@ AC_MSG_RESULT($have_stdatomic_h) if test "$have_stdatomic_h" = yes; then AC_DEFINE(HAVE_STD_ATOMIC, 1, - [Has stdatomic.h with atomic_int]) + [Has stdatomic.h with atomic_int and atomic_uintptr_t]) fi # Check for GCC >= 4.7 __atomic builtins diff --git a/pyconfig.h.in b/pyconfig.h.in index d36fc93..f4816fd 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -963,7 +963,7 @@ /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H -/* Has stdatomic.h with atomic_int */ +/* Has stdatomic.h with atomic_int and atomic_uintptr_t */ #undef HAVE_STD_ATOMIC /* Define to 1 if you have the `strdup' function. */ -- 2.7.4