Merge branch 'master' into feat/dataclass-init-args
This commit is contained in:
commit
4e90401d12
|
@ -31,7 +31,7 @@ jobs:
|
|||
buildVersionToDownload: specific
|
||||
buildId: $(BuildToPublish)
|
||||
|
||||
- powershell: gci pythonarm*.nupkg | %{ Write-Host "Not publishing: $($_.Name)"; gi $_ } | del
|
||||
- powershell: 'gci pythonarm*.nupkg | %{ Write-Host "Not publishing: $($_.Name)"; gi $_ } | del'
|
||||
displayName: 'Prevent publishing ARM/ARM64 packages'
|
||||
workingDirectory: '$(Build.BinariesDirectory)\nuget'
|
||||
condition: and(succeeded(), not(variables['PublishArmPackages']))
|
||||
|
|
|
@ -39,7 +39,7 @@ jobs:
|
|||
artifactName: embed
|
||||
downloadPath: $(Build.BinariesDirectory)
|
||||
|
||||
- powershell: gci *embed-arm*.zip | %{ Write-Host "Not publishing: $($_.Name)"; gi $_ } | del
|
||||
- powershell: 'gci *embed-arm*.zip | %{ Write-Host "Not publishing: $($_.Name)"; gi $_ } | del'
|
||||
displayName: 'Prevent publishing ARM/ARM64 packages'
|
||||
workingDirectory: '$(Build.BinariesDirectory)\embed'
|
||||
condition: and(succeeded(), not(variables['PublishArmPackages']))
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
**/*context* @1st1
|
||||
**/*genobject* @1st1
|
||||
**/*hamt* @1st1
|
||||
Objects/set* @rhettinger
|
||||
Objects/dict* @methane
|
||||
|
||||
# Hashing
|
||||
|
@ -93,6 +94,7 @@ Include/pytime.h @pganssle @abalkin
|
|||
/Tools/msi/ @python/windows-team
|
||||
/Tools/nuget/ @python/windows-team
|
||||
|
||||
# Misc
|
||||
**/*itertools* @rhettinger
|
||||
**/*collections* @rhettinger
|
||||
**/*random* @rhettinger
|
||||
|
@ -108,6 +110,15 @@ Include/pytime.h @pganssle @abalkin
|
|||
|
||||
**/*typing* @gvanrossum @ilevkivskyi
|
||||
|
||||
**/*asyncore @giampaolo
|
||||
**/*asynchat @giampaolo
|
||||
**/*ftplib @giampaolo
|
||||
**/*shutil @giampaolo
|
||||
|
||||
**/*enum* @ethanfurman
|
||||
**/*cgi* @ethanfurman
|
||||
**/*tarfile* @ethanfurman
|
||||
|
||||
# macOS
|
||||
/Mac/ @python/macos-team
|
||||
**/*osx_support* @python/macos-team
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
*.iml
|
||||
*.o
|
||||
*.a
|
||||
*.so*
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
*.dll
|
||||
*.orig
|
||||
|
|
|
@ -195,8 +195,8 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
|||
:meth:`__int__` method (if present) to convert it to a
|
||||
:c:type:`PyLongObject`.
|
||||
|
||||
If the value of *obj* is greater than :const:`PY_LLONG_MAX` or less than
|
||||
:const:`PY_LLONG_MIN`, set *\*overflow* to ``1`` or ``-1``, respectively,
|
||||
If the value of *obj* is greater than :const:`LLONG_MAX` or less than
|
||||
:const:`LLONG_MIN`, set *\*overflow* to ``1`` or ``-1``, respectively,
|
||||
and return ``-1``; otherwise, set *\*overflow* to ``0``. If any other
|
||||
exception occurs set *\*overflow* to ``0`` and return ``-1`` as usual.
|
||||
|
||||
|
@ -304,7 +304,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
|||
it to a :c:type:`PyLongObject`.
|
||||
|
||||
If the value of *obj* is out of range for an :c:type:`unsigned long long`,
|
||||
return the reduction of that value modulo ``PY_ULLONG_MAX + 1``.
|
||||
return the reduction of that value modulo ``ULLONG_MAX + 1``.
|
||||
|
||||
Returns ``(unsigned long long)-1`` on error. Use :c:func:`PyErr_Occurred`
|
||||
to disambiguate.
|
||||
|
|
|
@ -309,7 +309,7 @@ accessible to C code. They all work with the current interpreter thread's
|
|||
|
||||
.. c:function:: int PySys_Audit(const char *event, const char *format, ...)
|
||||
|
||||
Raises an auditing event with any active hooks. Returns zero for success
|
||||
Raise an auditing event with any active hooks. Return zero for success
|
||||
and non-zero with an exception set on failure.
|
||||
|
||||
If any hooks have been added, *format* and other arguments will be used
|
||||
|
@ -320,18 +320,31 @@ accessible to C code. They all work with the current interpreter thread's
|
|||
arguments to this function will be consumed, using it may cause reference
|
||||
leaks.)
|
||||
|
||||
Note that ``#`` format characters should always be treated as
|
||||
``Py_ssize_t``, regardless of whether ``PY_SSIZE_T_CLEAN`` was defined.
|
||||
|
||||
:func:`sys.audit` performs the same function from Python code.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
.. versionchanged:: 3.8.2
|
||||
|
||||
Require ``Py_ssize_t`` for ``#`` format characters. Previously, an
|
||||
unavoidable deprecation warning was raised.
|
||||
|
||||
|
||||
.. c:function:: int PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
|
||||
|
||||
Adds to the collection of active auditing hooks. Returns zero for success
|
||||
and non-zero on failure. If the runtime has been initialized, also sets an
|
||||
Append the callable *hook* to the list of active auditing hooks.
|
||||
Return zero for success
|
||||
and non-zero on failure. If the runtime has been initialized, also set an
|
||||
error on failure. Hooks added through this API are called for all
|
||||
interpreters created by the runtime.
|
||||
|
||||
The *userData* pointer is passed into the hook function. Since hook
|
||||
functions may be called from different runtimes, this pointer should not
|
||||
refer directly to Python state.
|
||||
|
||||
This function is safe to call before :c:func:`Py_Initialize`. When called
|
||||
after runtime initialization, existing audit hooks are notified and may
|
||||
silently abort the operation by raising an error subclassed from
|
||||
|
@ -342,14 +355,10 @@ accessible to C code. They all work with the current interpreter thread's
|
|||
:c:type:`PyTupleObject`. The hook function is always called with the GIL
|
||||
held by the Python interpreter that raised the event.
|
||||
|
||||
The *userData* pointer is passed into the hook function. Since hook
|
||||
functions may be called from different runtimes, this pointer should not
|
||||
refer directly to Python state.
|
||||
|
||||
See :pep:`578` for a detailed description of auditing. Functions in the
|
||||
runtime and standard library that raise events include the details in each
|
||||
function's documentation and listed in the :ref:`audit events table
|
||||
<audit-events>`.
|
||||
runtime and standard library that raise events are listed in the
|
||||
:ref:`audit events table <audit-events>`.
|
||||
Details are in each function's documentation.
|
||||
|
||||
.. audit-event:: sys.addaudithook "" c.PySys_AddAuditHook
|
||||
|
||||
|
|
|
@ -955,7 +955,7 @@ and :c:type:`PyType_Type` effectively act as defaults.)
|
|||
|
||||
The signature is the same as for :c:func:`PyObject_SetAttr`::
|
||||
|
||||
PyObject *tp_setattro(PyObject *self, PyObject *attr, PyObject *value);
|
||||
int tp_setattro(PyObject *self, PyObject *attr, PyObject *value);
|
||||
|
||||
In addition, setting *value* to ``NULL`` to delete an attribute must be
|
||||
supported. It is usually convenient to set this field to
|
||||
|
|
|
@ -197,11 +197,6 @@ access internal read-only data of Unicode objects:
|
|||
.. versionadded:: 3.3
|
||||
|
||||
|
||||
.. c:function:: int PyUnicode_ClearFreeList()
|
||||
|
||||
Clear the free list. Return the total number of freed items.
|
||||
|
||||
|
||||
.. c:function:: Py_ssize_t PyUnicode_GET_SIZE(PyObject *o)
|
||||
|
||||
Return the size of the deprecated :c:type:`Py_UNICODE` representation, in
|
||||
|
|
|
@ -3045,8 +3045,6 @@ Py_XINCREF:PyObject*:o:+1:if o is not NULL
|
|||
|
||||
_PyImport_Fini:void:::
|
||||
|
||||
_PyImport_Init:void:::
|
||||
|
||||
_PyObject_New:PyObject*::+1:
|
||||
_PyObject_New:PyTypeObject*:type:0:
|
||||
|
||||
|
|
|
@ -1545,7 +1545,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
|
||||
|
@ -1684,7 +1684,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
|
||||
|
@ -1699,7 +1699,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.
|
||||
|
||||
|
||||
|
@ -1792,7 +1792,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}
|
||||
|
@ -2039,7 +2039,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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -169,11 +169,6 @@ The following data items and methods are also supported:
|
|||
a.append(x)`` except that if there is a type error, the array is unchanged.
|
||||
|
||||
|
||||
.. method:: array.fromstring()
|
||||
|
||||
Deprecated alias for :meth:`frombytes`.
|
||||
|
||||
|
||||
.. method:: array.fromunicode(s)
|
||||
|
||||
Extends this array with data from the given unicode string. The array must
|
||||
|
@ -231,11 +226,6 @@ The following data items and methods are also supported:
|
|||
Convert the array to an ordinary list with the same items.
|
||||
|
||||
|
||||
.. method:: array.tostring()
|
||||
|
||||
Deprecated alias for :meth:`tobytes`.
|
||||
|
||||
|
||||
.. method:: array.tounicode()
|
||||
|
||||
Convert the array to a unicode string. The array must be a type ``'u'`` array;
|
||||
|
|
|
@ -161,6 +161,19 @@ and classes for traversing abstract syntax trees:
|
|||
Added ``type_comments``, ``mode='func_type'`` and ``feature_version``.
|
||||
|
||||
|
||||
.. function:: unparse(ast_obj)
|
||||
|
||||
Unparse an :class:`ast.AST` object and generate a string with code
|
||||
that would produce an equivalent :class:`ast.AST` object if parsed
|
||||
back with :func:`ast.parse`.
|
||||
|
||||
.. warning::
|
||||
The produced code string will not necesarily be equal to the original
|
||||
code that generated the :class:`ast.AST` object.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. function:: literal_eval(node_or_string)
|
||||
|
||||
Safely evaluate an expression node or a string containing a Python literal or
|
||||
|
|
|
@ -473,6 +473,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`,
|
||||
|
@ -501,11 +516,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
|
||||
|
@ -527,6 +537,10 @@ Opening network connections
|
|||
The *family*, *proto*, *flags*, *reuse_address*, *reuse_port,
|
||||
*allow_broadcast*, and *sock* parameters were added.
|
||||
|
||||
.. versionchanged:: 3.8.1
|
||||
The *reuse_address* parameter is no longer supported due to security
|
||||
concerns.
|
||||
|
||||
.. versionchanged:: 3.8
|
||||
Added support for Windows.
|
||||
|
||||
|
|
|
@ -588,9 +588,6 @@ Buffered Streaming Protocols
|
|||
----------------------------
|
||||
|
||||
.. versionadded:: 3.7
|
||||
**Important:** this has been added to asyncio in Python 3.7
|
||||
*on a provisional basis*! This is as an experimental API that
|
||||
might be changed or removed completely in Python 3.8.
|
||||
|
||||
Buffered Protocols can be used with any event loop method
|
||||
that supports `Streaming Protocols`_.
|
||||
|
|
|
@ -7,7 +7,7 @@ Audit events table
|
|||
|
||||
This table contains all events raised by :func:`sys.audit` or
|
||||
:c:func:`PySys_Audit` calls throughout the CPython runtime and the
|
||||
standard library.
|
||||
standard library. These calls were added in 3.8.0 or later.
|
||||
|
||||
See :func:`sys.addaudithook` and :c:func:`PySys_AddAuditHook` for
|
||||
information on handling these events.
|
||||
|
|
|
@ -881,7 +881,7 @@ Other constructors, all class methods:
|
|||
Because naive ``datetime`` objects are treated by many ``datetime`` methods
|
||||
as local times, it is preferred to use aware datetimes to represent times
|
||||
in UTC. As such, the recommended way to create an object representing the
|
||||
current time in UTC by calling ``datetime.now(timezone.utc)``.
|
||||
current time in UTC is by calling ``datetime.now(timezone.utc)``.
|
||||
|
||||
|
||||
.. classmethod:: datetime.fromtimestamp(timestamp, tz=None)
|
||||
|
@ -942,7 +942,7 @@ Other constructors, all class methods:
|
|||
Because naive ``datetime`` objects are treated by many ``datetime`` methods
|
||||
as local times, it is preferred to use aware datetimes to represent times
|
||||
in UTC. As such, the recommended way to create an object representing a
|
||||
specific timestamp in UTC by calling
|
||||
specific timestamp in UTC is by calling
|
||||
``datetime.fromtimestamp(timestamp, tz=timezone.utc)``.
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
|
@ -2362,7 +2362,7 @@ requires, and these work on all platforms with a standard C implementation.
|
|||
| | string if the object is | +063415, | |
|
||||
| | naive). | -030712.345216 | |
|
||||
+-----------+--------------------------------+------------------------+-------+
|
||||
| ``%Z`` | Time zone name (empty string | (empty), UTC, EST, CST | |
|
||||
| ``%Z`` | Time zone name (empty string | (empty), UTC, GMT | \(6) |
|
||||
| | if the object is naive). | | |
|
||||
+-----------+--------------------------------+------------------------+-------+
|
||||
| ``%j`` | Day of the year as a | 001, 002, ..., 366 | \(9) |
|
||||
|
@ -2533,9 +2533,18 @@ Notes:
|
|||
In addition, providing ``'Z'`` is identical to ``'+00:00'``.
|
||||
|
||||
``%Z``
|
||||
If :meth:`tzname` returns ``None``, ``%Z`` is replaced by an empty
|
||||
string. Otherwise ``%Z`` is replaced by the returned value, which must
|
||||
be a string.
|
||||
In :meth:`strftime`, ``%Z`` is replaced by an empty string if
|
||||
:meth:`tzname` returns ``None``; otherwise ``%Z`` is replaced by the
|
||||
returned value, which must be a string.
|
||||
|
||||
:meth:`strptime` only accepts certain values for ``%Z``:
|
||||
|
||||
1. any value in ``time.tzname`` for your machine's locale
|
||||
2. the hard-coded values ``UTC`` and ``GMT``
|
||||
|
||||
So someone living in Japan may have ``JST``, ``UTC``, and ``GMT`` as
|
||||
valid values, but probably not ``EST``. It will raise ``ValueError`` for
|
||||
invalid values.
|
||||
|
||||
.. versionchanged:: 3.2
|
||||
When the ``%z`` directive is provided to the :meth:`strptime` method, an
|
||||
|
|
|
@ -706,50 +706,21 @@ iterations of the loop.
|
|||
popped values are used to restore the exception state.
|
||||
|
||||
|
||||
.. opcode:: POP_FINALLY (preserve_tos)
|
||||
.. opcode:: RERAISE
|
||||
|
||||
Cleans up the value stack and the block stack. If *preserve_tos* is not
|
||||
``0`` TOS first is popped from the stack and pushed on the stack after
|
||||
performing other stack operations:
|
||||
Re-raises the exception currently on top of the stack.
|
||||
|
||||
* If TOS is ``NULL`` or an integer (pushed by :opcode:`BEGIN_FINALLY`
|
||||
or :opcode:`CALL_FINALLY`) it is popped from the stack.
|
||||
* If TOS is an exception type (pushed when an exception has been raised)
|
||||
6 values are popped from the stack, the last three popped values are
|
||||
used to restore the exception state. An exception handler block is
|
||||
removed from the block stack.
|
||||
|
||||
It is similar to :opcode:`END_FINALLY`, but doesn't change the bytecode
|
||||
counter nor raise an exception. Used for implementing :keyword:`break`,
|
||||
:keyword:`continue` and :keyword:`return` in the :keyword:`finally` block.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. opcode:: BEGIN_FINALLY
|
||||
.. opcode:: WITH_EXCEPT_START
|
||||
|
||||
Pushes ``NULL`` onto the stack for using it in :opcode:`END_FINALLY`,
|
||||
:opcode:`POP_FINALLY`, :opcode:`WITH_CLEANUP_START` and
|
||||
:opcode:`WITH_CLEANUP_FINISH`. Starts the :keyword:`finally` block.
|
||||
Calls the function in position 7 on the stack with the top three
|
||||
items on the stack as arguments.
|
||||
Used to implement the call ``context_manager.__exit__(*exc_info())`` when an exception
|
||||
has occurred in a :keyword:`with` statement.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
|
||||
.. opcode:: END_FINALLY
|
||||
|
||||
Terminates a :keyword:`finally` clause. The interpreter recalls whether the
|
||||
exception has to be re-raised or execution has to be continued depending on
|
||||
the value of TOS.
|
||||
|
||||
* If TOS is ``NULL`` (pushed by :opcode:`BEGIN_FINALLY`) continue from
|
||||
the next instruction. TOS is popped.
|
||||
* If TOS is an integer (pushed by :opcode:`CALL_FINALLY`), sets the
|
||||
bytecode counter to TOS. TOS is popped.
|
||||
* If TOS is an exception type (pushed when an exception has been raised)
|
||||
6 values are popped from the stack, the first three popped values are
|
||||
used to re-raise the exception and the last three popped values are used
|
||||
to restore the exception state. An exception handler block is removed
|
||||
from the block stack.
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. opcode:: LOAD_ASSERTION_ERROR
|
||||
|
@ -780,35 +751,6 @@ iterations of the loop.
|
|||
.. versionadded:: 3.2
|
||||
|
||||
|
||||
.. opcode:: WITH_CLEANUP_START
|
||||
|
||||
Starts cleaning up the stack when a :keyword:`with` statement block exits.
|
||||
|
||||
At the top of the stack are either ``NULL`` (pushed by
|
||||
:opcode:`BEGIN_FINALLY`) or 6 values pushed if an exception has been
|
||||
raised in the with block. Below is the context manager's
|
||||
:meth:`~object.__exit__` or :meth:`~object.__aexit__` bound method.
|
||||
|
||||
If TOS is ``NULL``, calls ``SECOND(None, None, None)``,
|
||||
removes the function from the stack, leaving TOS, and pushes ``None``
|
||||
to the stack. Otherwise calls ``SEVENTH(TOP, SECOND, THIRD)``,
|
||||
shifts the bottom 3 values of the stack down, replaces the empty spot
|
||||
with ``NULL`` and pushes TOS. Finally pushes the result of the call.
|
||||
|
||||
|
||||
.. opcode:: WITH_CLEANUP_FINISH
|
||||
|
||||
Finishes cleaning up the stack when a :keyword:`with` statement block exits.
|
||||
|
||||
TOS is result of ``__exit__()`` or ``__aexit__()`` function call pushed
|
||||
by :opcode:`WITH_CLEANUP_START`. SECOND is ``None`` or an exception type
|
||||
(pushed when an exception has been raised).
|
||||
|
||||
Pops two values from the stack. If SECOND is not None and TOS is true
|
||||
unwinds the EXCEPT_HANDLER block which was created when the exception
|
||||
was caught and pushes ``NULL`` to the stack.
|
||||
|
||||
|
||||
All of the following opcodes use their arguments.
|
||||
|
||||
.. opcode:: STORE_NAME (namei)
|
||||
|
@ -1060,15 +1002,6 @@ All of the following opcodes use their arguments.
|
|||
stack. *delta* points to the finally block or the first except block.
|
||||
|
||||
|
||||
.. opcode:: CALL_FINALLY (delta)
|
||||
|
||||
Pushes the address of the next instruction onto the stack and increments
|
||||
bytecode counter by *delta*. Used for calling the finally block as a
|
||||
"subroutine".
|
||||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
|
||||
.. opcode:: LOAD_FAST (var_num)
|
||||
|
||||
Pushes a reference to the local ``co_varnames[var_num]`` onto the stack.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -732,12 +732,24 @@ Command line options
|
|||
|
||||
.. versionadded:: 3.5
|
||||
|
||||
.. cmdoption:: --no-ensure-ascii
|
||||
|
||||
Disable escaping of non-ascii characters, see :func:`json.dumps` for more information.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
.. cmdoption:: --json-lines
|
||||
|
||||
Parse every input line as separate JSON object.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
.. cmdoption:: --indent, --tab, --no-indent, --compact
|
||||
|
||||
Mutually exclusive options for whitespace control
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
.. cmdoption:: -h, --help
|
||||
|
||||
Show the help message.
|
||||
|
|
|
@ -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 <moshez@zadka.site.co.il>
|
||||
|
||||
|
|
|
@ -2169,7 +2169,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
|
||||
|
|
|
@ -165,8 +165,9 @@ Functions for sequences
|
|||
|
||||
The *weights* or *cum_weights* can use any numeric type that interoperates
|
||||
with the :class:`float` values returned by :func:`random` (that includes
|
||||
integers, floats, and fractions but excludes decimals). Weights are
|
||||
assumed to be non-negative.
|
||||
integers, floats, and fractions but excludes decimals). Behavior is
|
||||
undefined if any weight is negative. A :exc:`ValueError` is raised if all
|
||||
weights are zero.
|
||||
|
||||
For a given seed, the :func:`choices` function with equal weighting
|
||||
typically produces a different sequence than repeated calls to
|
||||
|
@ -177,6 +178,9 @@ Functions for sequences
|
|||
|
||||
.. versionadded:: 3.6
|
||||
|
||||
.. versionchanged:: 3.9
|
||||
Raises a :exc:`ValueError` if all weights are zero.
|
||||
|
||||
|
||||
.. function:: shuffle(x[, random])
|
||||
|
||||
|
|
|
@ -1411,9 +1411,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.
|
||||
|
|
|
@ -1256,6 +1256,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.9
|
||||
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
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
=======================================================
|
||||
|
||||
.. module:: statistics
|
||||
:synopsis: mathematical statistics functions
|
||||
:synopsis: Mathematical statistics functions
|
||||
|
||||
.. moduleauthor:: Steven D'Aprano <steve+python@pearwood.info>
|
||||
.. sectionauthor:: Steven D'Aprano <steve+python@pearwood.info>
|
||||
|
|
|
@ -25,7 +25,7 @@ always available.
|
|||
|
||||
.. function:: addaudithook(hook)
|
||||
|
||||
Adds the callable *hook* to the collection of active auditing hooks for the
|
||||
Append the callable *hook* to the list of active auditing hooks for the
|
||||
current interpreter.
|
||||
|
||||
When an auditing event is raised through the :func:`sys.audit` function, each
|
||||
|
@ -35,14 +35,19 @@ always available.
|
|||
|
||||
.. audit-event:: sys.addaudithook "" sys.addaudithook
|
||||
|
||||
Raises a auditing event ``sys.addaudithook`` with no arguments. If any
|
||||
existing hooks raise an exception derived from :class:`Exception`, the
|
||||
Raise an auditing event ``sys.addaudithook`` with no arguments. If any
|
||||
existing hooks raise an exception derived from :class:`RuntimeError`, the
|
||||
new hook will not be added and the exception suppressed. As a result,
|
||||
callers cannot assume that their hook has been added unless they control
|
||||
all existing hooks.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
.. versionchanged:: 3.8.1
|
||||
|
||||
Exceptions derived from :class:`Exception` but not :class:`RuntimeError`
|
||||
are no longer suppressed.
|
||||
|
||||
.. impl-detail::
|
||||
|
||||
When tracing is enabled (see :func:`settrace`), Python hooks are only
|
||||
|
@ -74,7 +79,7 @@ always available.
|
|||
|
||||
.. index:: single: auditing
|
||||
|
||||
Raises an auditing event with any active hooks. The event name is a string
|
||||
Raise an auditing event with any active hooks. The event name is a string
|
||||
identifying the event and its associated schema, which is the number and
|
||||
types of arguments. The schema for a given event is considered public and
|
||||
stable API and should not be modified between releases.
|
||||
|
@ -308,6 +313,15 @@ always available.
|
|||
before the program exits. The handling of such top-level exceptions can be
|
||||
customized by assigning another three-argument function to ``sys.excepthook``.
|
||||
|
||||
.. audit-event:: sys.excepthook hook,type,value,traceback sys.excepthook
|
||||
|
||||
Raise an auditing event ``sys.excepthook`` with arguments ``hook``,
|
||||
``type``, ``value``, ``traceback`` when an uncaught exception occurs.
|
||||
If no hook has been set, ``hook`` may be ``None``. If any hook raises
|
||||
an exception derived from :class:`RuntimeError` the call to the hook will
|
||||
be suppressed. Otherwise, the audit hook exception will be reported as
|
||||
unraisable and ``sys.excepthook`` will be called.
|
||||
|
||||
.. seealso::
|
||||
|
||||
The :func:`sys.unraisablehook` function handles unraisable exceptions
|
||||
|
@ -1540,6 +1554,13 @@ always available.
|
|||
|
||||
See also :func:`excepthook` which handles uncaught exceptions.
|
||||
|
||||
.. audit-event:: sys.unraisablehook hook,unraisable sys.unraisablehook
|
||||
|
||||
Raise an auditing event ``sys.unraisablehook`` with arguments
|
||||
``hook``, ``unraisable`` when an exception that cannot be handled occurs.
|
||||
The ``unraisable`` object is the same as what will be passed to the hook.
|
||||
If no hook has been set, ``hook`` may be ``None``.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
.. data:: version
|
||||
|
|
|
@ -105,8 +105,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.
|
||||
|
|
|
@ -686,13 +686,6 @@ The :mod:`test.support` module defines the following functions:
|
|||
``sys.stdout`` if it's not set.
|
||||
|
||||
|
||||
.. function:: strip_python_strerr(stderr)
|
||||
|
||||
Strip the *stderr* of a Python process from potential debug output
|
||||
emitted by the interpreter. This will typically be run on the result of
|
||||
:meth:`subprocess.Popen.communicate`.
|
||||
|
||||
|
||||
.. function:: args_from_interpreter_flags()
|
||||
|
||||
Return a list of command line arguments reproducing the current settings
|
||||
|
@ -1499,6 +1492,9 @@ script execution tests.
|
|||
in a subprocess. The values can include ``__isolated``, ``__cleanenv``,
|
||||
``__cwd``, and ``TERM``.
|
||||
|
||||
.. versionchanged:: 3.9
|
||||
The function no longer strips whitespaces from *stderr*.
|
||||
|
||||
|
||||
.. function:: assert_python_ok(*args, **env_vars)
|
||||
|
||||
|
@ -1512,6 +1508,9 @@ script execution tests.
|
|||
Python is started in isolated mode (command line option ``-I``),
|
||||
except if the ``__isolated`` keyword is set to ``False``.
|
||||
|
||||
.. versionchanged:: 3.9
|
||||
The function no longer strips whitespaces from *stderr*.
|
||||
|
||||
|
||||
.. function:: assert_python_failure(*args, **env_vars)
|
||||
|
||||
|
@ -1521,6 +1520,9 @@ script execution tests.
|
|||
|
||||
See :func:`assert_python_ok` for more options.
|
||||
|
||||
.. versionchanged:: 3.9
|
||||
The function no longer strips whitespaces from *stderr*.
|
||||
|
||||
|
||||
.. function:: spawn_python(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw)
|
||||
|
||||
|
|
|
@ -496,6 +496,10 @@ All methods are executed atomically.
|
|||
|
||||
There is no return value.
|
||||
|
||||
.. method:: locked()
|
||||
Return true if the lock is acquired.
|
||||
|
||||
|
||||
|
||||
.. _rlock-objects:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -132,7 +132,7 @@ creation according to their needs, the :class:`EnvBuilder` class.
|
|||
.. versionadded:: 3.6
|
||||
Added the ``prompt`` parameter
|
||||
|
||||
.. versionadded:: 3.8
|
||||
.. versionadded:: 3.9
|
||||
Added the ``upgrade_deps`` parameter
|
||||
|
||||
Creators of third-party virtual environment tools will be free to use the
|
||||
|
@ -197,7 +197,7 @@ creation according to their needs, the :class:`EnvBuilder` class.
|
|||
``setuptools``) in the environment. This is done by shelling out to the
|
||||
``pip`` executable in the environment.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
.. versionadded:: 3.9
|
||||
|
||||
.. method:: post_setup(context)
|
||||
|
||||
|
|
|
@ -53,6 +53,8 @@ This module offers the following functions:
|
|||
The return value is the handle of the opened key. If the function fails, an
|
||||
:exc:`OSError` exception is raised.
|
||||
|
||||
.. audit-event:: winreg.ConnectRegistry computer_name,key winreg.ConnectRegistry
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
See :ref:`above <exception-changed>`.
|
||||
|
||||
|
@ -75,6 +77,10 @@ This module offers the following functions:
|
|||
The return value is the handle of the opened key. If the function fails, an
|
||||
:exc:`OSError` exception is raised.
|
||||
|
||||
.. audit-event:: winreg.CreateKey key,sub_key,access winreg.CreateKey
|
||||
|
||||
.. audit-event:: winreg.OpenKey/result key winreg.CreateKey
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
See :ref:`above <exception-changed>`.
|
||||
|
||||
|
@ -103,6 +109,10 @@ This module offers the following functions:
|
|||
The return value is the handle of the opened key. If the function fails, an
|
||||
:exc:`OSError` exception is raised.
|
||||
|
||||
.. audit-event:: winreg.CreateKey key,sub_key,access winreg.CreateKeyEx
|
||||
|
||||
.. audit-event:: winreg.OpenKey/result key winreg.CreateKeyEx
|
||||
|
||||
.. versionadded:: 3.2
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
|
@ -124,6 +134,8 @@ This module offers the following functions:
|
|||
If the method succeeds, the entire key, including all of its values, is removed.
|
||||
If the method fails, an :exc:`OSError` exception is raised.
|
||||
|
||||
.. audit-event:: winreg.DeleteKey key,sub_key,access winreg.DeleteKey
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
See :ref:`above <exception-changed>`.
|
||||
|
||||
|
@ -158,6 +170,8 @@ This module offers the following functions:
|
|||
|
||||
On unsupported Windows versions, :exc:`NotImplementedError` is raised.
|
||||
|
||||
.. audit-event:: winreg.DeleteKey key,sub_key,access winreg.DeleteKeyEx
|
||||
|
||||
.. versionadded:: 3.2
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
|
@ -173,6 +187,8 @@ This module offers the following functions:
|
|||
|
||||
*value* is a string that identifies the value to remove.
|
||||
|
||||
.. audit-event:: winreg.DeleteValue key,value winreg.DeleteValue
|
||||
|
||||
|
||||
.. function:: EnumKey(key, index)
|
||||
|
||||
|
@ -187,6 +203,8 @@ This module offers the following functions:
|
|||
typically called repeatedly until an :exc:`OSError` exception is
|
||||
raised, indicating, no more values are available.
|
||||
|
||||
.. audit-event:: winreg.EnumKey key,index winreg.EnumKey
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
See :ref:`above <exception-changed>`.
|
||||
|
||||
|
@ -220,6 +238,8 @@ This module offers the following functions:
|
|||
| | :meth:`SetValueEx`) |
|
||||
+-------+--------------------------------------------+
|
||||
|
||||
.. audit-event:: winreg.EnumValue key,index winreg.EnumValue
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
See :ref:`above <exception-changed>`.
|
||||
|
||||
|
@ -235,6 +255,8 @@ This module offers the following functions:
|
|||
>>> ExpandEnvironmentStrings('%windir%')
|
||||
'C:\\Windows'
|
||||
|
||||
.. audit-event:: winreg.ExpandEnvironmentStrings str winreg.ExpandEnvironmentStrings
|
||||
|
||||
|
||||
.. function:: FlushKey(key)
|
||||
|
||||
|
@ -279,6 +301,8 @@ This module offers the following functions:
|
|||
If *key* is a handle returned by :func:`ConnectRegistry`, then the path
|
||||
specified in *file_name* is relative to the remote computer.
|
||||
|
||||
.. audit-event:: winreg.LoadKey key,sub_key,file_name winreg.LoadKey
|
||||
|
||||
|
||||
.. function:: OpenKey(key, sub_key, reserved=0, access=KEY_READ)
|
||||
OpenKeyEx(key, sub_key, reserved=0, access=KEY_READ)
|
||||
|
@ -300,6 +324,10 @@ This module offers the following functions:
|
|||
|
||||
If the function fails, :exc:`OSError` is raised.
|
||||
|
||||
.. audit-event:: winreg.OpenKey key,sub_key,access winreg.OpenKey
|
||||
|
||||
.. audit-event:: winreg.OpenKey/result key winreg.OpenKey
|
||||
|
||||
.. versionchanged:: 3.2
|
||||
Allow the use of named arguments.
|
||||
|
||||
|
@ -330,6 +358,8 @@ This module offers the following functions:
|
|||
| | nanoseconds since Jan 1, 1601. |
|
||||
+-------+---------------------------------------------+
|
||||
|
||||
.. audit-event:: winreg.QueryInfoKey key winreg.QueryInfoKey
|
||||
|
||||
|
||||
.. function:: QueryValue(key, sub_key)
|
||||
|
||||
|
@ -347,6 +377,8 @@ This module offers the following functions:
|
|||
underlying API call doesn't return the type, so always use
|
||||
:func:`QueryValueEx` if possible.
|
||||
|
||||
.. audit-event:: winreg.QueryValue key,sub_key,value_name winreg.QueryValue
|
||||
|
||||
|
||||
.. function:: QueryValueEx(key, value_name)
|
||||
|
||||
|
@ -370,6 +402,8 @@ This module offers the following functions:
|
|||
| | :meth:`SetValueEx`) |
|
||||
+-------+-----------------------------------------+
|
||||
|
||||
.. audit-event:: winreg.QueryValue key,sub_key,value_name winreg.QueryValueEx
|
||||
|
||||
|
||||
.. function:: SaveKey(key, file_name)
|
||||
|
||||
|
@ -393,6 +427,8 @@ This module offers the following functions:
|
|||
|
||||
This function passes ``NULL`` for *security_attributes* to the API.
|
||||
|
||||
.. audit-event:: winreg.SaveKey key,file_name winreg.SaveKey
|
||||
|
||||
|
||||
.. function:: SetValue(key, sub_key, type, value)
|
||||
|
||||
|
@ -419,6 +455,8 @@ This module offers the following functions:
|
|||
The key identified by the *key* parameter must have been opened with
|
||||
:const:`KEY_SET_VALUE` access.
|
||||
|
||||
.. audit-event:: winreg.SetValue key,sub_key,type,value winreg.SetValue
|
||||
|
||||
|
||||
.. function:: SetValueEx(key, value_name, reserved, type, value)
|
||||
|
||||
|
@ -447,6 +485,8 @@ This module offers the following functions:
|
|||
bytes) should be stored as files with the filenames stored in the configuration
|
||||
registry. This helps the registry perform efficiently.
|
||||
|
||||
.. audit-event:: winreg.SetValue key,sub_key,type,value winreg.SetValueEx
|
||||
|
||||
|
||||
.. function:: DisableReflectionKey(key)
|
||||
|
||||
|
@ -463,6 +503,8 @@ This module offers the following functions:
|
|||
effect. Disabling reflection for a key does not affect reflection of any
|
||||
subkeys.
|
||||
|
||||
.. audit-event:: winreg.DisableReflectionKey key winreg.DisableReflectionKey
|
||||
|
||||
|
||||
.. function:: EnableReflectionKey(key)
|
||||
|
||||
|
@ -476,6 +518,8 @@ This module offers the following functions:
|
|||
|
||||
Restoring reflection for a key does not affect reflection of any subkeys.
|
||||
|
||||
.. audit-event:: winreg.EnableReflectionKey key winreg.EnableReflectionKey
|
||||
|
||||
|
||||
.. function:: QueryReflectionKey(key)
|
||||
|
||||
|
@ -489,6 +533,8 @@ This module offers the following functions:
|
|||
Will generally raise :exc:`NotImplementedError` if executed on a 32-bit
|
||||
operating system.
|
||||
|
||||
.. audit-event:: winreg.QueryReflectionKey key winreg.QueryReflectionKey
|
||||
|
||||
|
||||
.. _constants:
|
||||
|
||||
|
@ -741,6 +787,9 @@ integer handle, and also disconnect the Windows handle from the handle object.
|
|||
handle is not closed. You would call this function when you need the
|
||||
underlying Win32 handle to exist beyond the lifetime of the handle object.
|
||||
|
||||
.. audit-event:: winreg.PyHKEY.Detach key winreg.PyHKEY.Detach
|
||||
|
||||
|
||||
.. method:: PyHKEY.__enter__()
|
||||
PyHKEY.__exit__(\*exc_info)
|
||||
|
||||
|
|
|
@ -494,7 +494,7 @@ Path objects are traversable using the ``/`` operator.
|
|||
Invoke :meth:`ZipFile.open` on the current path. Accepts
|
||||
the same arguments as :meth:`ZipFile.open`.
|
||||
|
||||
.. method:: Path.listdir()
|
||||
.. method:: Path.iterdir()
|
||||
|
||||
Enumerate the children of the current directory.
|
||||
|
||||
|
|
|
@ -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 <just@letterror.com>
|
||||
|
||||
|
|
|
@ -1655,8 +1655,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
|
||||
|
|
|
@ -201,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})"
|
||||
|
|
|
|
@ -104,7 +104,7 @@ directory containing the virtual environment):
|
|||
+=============+=================+=========================================+
|
||||
| POSIX | bash/zsh | $ source <venv>/bin/activate |
|
||||
+-------------+-----------------+-----------------------------------------+
|
||||
| | fish | $ . <venv>/bin/activate.fish |
|
||||
| | fish | $ source <venv>/bin/activate.fish |
|
||||
+-------------+-----------------+-----------------------------------------+
|
||||
| | csh/tcsh | $ source <venv>/bin/activate.csh |
|
||||
+-------------+-----------------+-----------------------------------------+
|
||||
|
|
|
@ -121,6 +121,11 @@ Added the *indent* option to :func:`~ast.dump` which allows it to produce a
|
|||
multiline indented output.
|
||||
(Contributed by Serhiy Storchaka in :issue:`37995`.)
|
||||
|
||||
Added :func:`ast.unparse` as a function in the :mod:`ast` module that can
|
||||
be used to unparse an :class:`ast.AST` object and produce a string with code
|
||||
that would produce an equivalent :class:`ast.AST` object when parsed.
|
||||
(Contributed by Pablo Galindo and Batuhan Taskaya in :issue:`38870`.)
|
||||
|
||||
asyncio
|
||||
-------
|
||||
|
||||
|
@ -179,8 +184,8 @@ case), and one used ``__VENV_NAME__`` instead.
|
|||
pathlib
|
||||
-------
|
||||
|
||||
Added :meth:`~pathlib.Path.readlink()` which acts similar to
|
||||
:func:`~os.readlink`.
|
||||
Added :meth:`pathlib.Path.readlink()` which acts similarly to
|
||||
:func:`os.readlink`.
|
||||
(Contributed by Girts Folkmanis in :issue:`30618`)
|
||||
|
||||
pprint
|
||||
|
@ -235,6 +240,10 @@ Build and C API Changes
|
|||
functions: the free lists of bound method objects have been removed.
|
||||
(Contributed by Inada Naoki and Victor Stinner in :issue:`37340`.)
|
||||
|
||||
* Remove ``PyUnicode_ClearFreeList()`` function: the Unicode free list has been
|
||||
removed in Python 3.3.
|
||||
(Contributed by Victor Stinner in :issue:`38896`.)
|
||||
|
||||
|
||||
Deprecated
|
||||
==========
|
||||
|
@ -270,6 +279,11 @@ Deprecated
|
|||
Removed
|
||||
=======
|
||||
|
||||
* :class:`array.array`: ``tostring()`` and ``fromstring()`` methods have been
|
||||
removed. They were aliases to ``tobytes()`` and ``frombytes()``, deprecated
|
||||
since Python 3.2.
|
||||
(Contributed by Victor Stinner in :issue:`38916`.)
|
||||
|
||||
* The abstract base classes in :mod:`collections.abc` no longer are
|
||||
exposed in the regular :mod:`collections` module. This will help
|
||||
create a clearer distinction between the concrete classes and the abstract
|
||||
|
|
|
@ -147,7 +147,6 @@ struct _ts {
|
|||
The caller must hold the GIL.*/
|
||||
PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void);
|
||||
|
||||
PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*);
|
||||
PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *);
|
||||
|
||||
/* Similar to PyThreadState_Get(), but don't issue a fatal error
|
||||
|
|
|
@ -40,11 +40,9 @@ extern PyObject * _PyBuiltin_Init(PyThreadState *tstate);
|
|||
extern PyStatus _PySys_Create(
|
||||
PyThreadState *tstate,
|
||||
PyObject **sysmod_p);
|
||||
extern PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict);
|
||||
extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options);
|
||||
extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config);
|
||||
extern int _PySys_InitMain(PyThreadState *tstate);
|
||||
extern PyStatus _PyImport_Init(PyThreadState *tstate);
|
||||
extern PyStatus _PyExc_Init(void);
|
||||
extern PyStatus _PyErr_Init(void);
|
||||
extern PyStatus _PyBuiltins_AddExceptions(PyObject * bltinmod);
|
||||
|
@ -77,7 +75,7 @@ extern void _PyImport_Fini2(void);
|
|||
extern void _PyGC_Fini(PyThreadState *tstate);
|
||||
extern void _PyType_Fini(void);
|
||||
extern void _Py_HashRandomization_Fini(void);
|
||||
extern void _PyUnicode_Fini(void);
|
||||
extern void _PyUnicode_Fini(PyThreadState *tstate);
|
||||
extern void _PyLong_Fini(void);
|
||||
extern void _PyFaulthandler_Fini(void);
|
||||
extern void _PyHash_Fini(void);
|
||||
|
|
|
@ -324,6 +324,12 @@ extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp);
|
|||
|
||||
PyAPI_FUNC(void) _PyGILState_Reinit(_PyRuntimeState *runtime);
|
||||
|
||||
|
||||
PyAPI_FUNC(int) _PyState_AddModule(
|
||||
PyThreadState *tstate,
|
||||
PyObject* module,
|
||||
struct PyModuleDef* def);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -30,10 +30,11 @@ extern "C" {
|
|||
#define BINARY_TRUE_DIVIDE 27
|
||||
#define INPLACE_FLOOR_DIVIDE 28
|
||||
#define INPLACE_TRUE_DIVIDE 29
|
||||
#define RERAISE 48
|
||||
#define WITH_EXCEPT_START 49
|
||||
#define GET_AITER 50
|
||||
#define GET_ANEXT 51
|
||||
#define BEFORE_ASYNC_WITH 52
|
||||
#define BEGIN_FINALLY 53
|
||||
#define END_ASYNC_FOR 54
|
||||
#define INPLACE_ADD 55
|
||||
#define INPLACE_SUBTRACT 56
|
||||
|
@ -59,14 +60,11 @@ extern "C" {
|
|||
#define INPLACE_AND 77
|
||||
#define INPLACE_XOR 78
|
||||
#define INPLACE_OR 79
|
||||
#define WITH_CLEANUP_START 81
|
||||
#define WITH_CLEANUP_FINISH 82
|
||||
#define RETURN_VALUE 83
|
||||
#define IMPORT_STAR 84
|
||||
#define SETUP_ANNOTATIONS 85
|
||||
#define YIELD_VALUE 86
|
||||
#define POP_BLOCK 87
|
||||
#define END_FINALLY 88
|
||||
#define POP_EXCEPT 89
|
||||
#define HAVE_ARGUMENT 90
|
||||
#define STORE_NAME 90
|
||||
|
@ -127,8 +125,6 @@ extern "C" {
|
|||
#define BUILD_TUPLE_UNPACK_WITH_CALL 158
|
||||
#define LOAD_METHOD 160
|
||||
#define CALL_METHOD 161
|
||||
#define CALL_FINALLY 162
|
||||
#define POP_FINALLY 163
|
||||
|
||||
/* EXCEPT_HANDLER is a special, implicit block type which is created when
|
||||
entering an except handler. It is not an opcode but we define it here
|
||||
|
|
|
@ -51,16 +51,16 @@ PyAPI_FUNC(int) PyThread_acquire_lock(PyThread_type_lock, int);
|
|||
#if defined(_POSIX_THREADS)
|
||||
/* PyThread_acquire_lock_timed() uses _PyTime_FromNanoseconds(us * 1000),
|
||||
convert microseconds to nanoseconds. */
|
||||
# define PY_TIMEOUT_MAX (PY_LLONG_MAX / 1000)
|
||||
# define PY_TIMEOUT_MAX (LLONG_MAX / 1000)
|
||||
#elif defined (NT_THREADS)
|
||||
/* In the NT API, the timeout is a DWORD and is expressed in milliseconds */
|
||||
# if 0xFFFFFFFFLL * 1000 < PY_LLONG_MAX
|
||||
# if 0xFFFFFFFFLL * 1000 < LLONG_MAX
|
||||
# define PY_TIMEOUT_MAX (0xFFFFFFFFLL * 1000)
|
||||
# else
|
||||
# define PY_TIMEOUT_MAX PY_LLONG_MAX
|
||||
# define PY_TIMEOUT_MAX LLONG_MAX
|
||||
# endif
|
||||
#else
|
||||
# define PY_TIMEOUT_MAX PY_LLONG_MAX
|
||||
# define PY_TIMEOUT_MAX LLONG_MAX
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -328,17 +328,6 @@ PyAPI_FUNC(wchar_t*) PyUnicode_AsWideCharString(
|
|||
|
||||
PyAPI_FUNC(PyObject*) PyUnicode_FromOrdinal(int ordinal);
|
||||
|
||||
/* --- Free-list management ----------------------------------------------- */
|
||||
|
||||
/* Clear the free list used by the Unicode implementation.
|
||||
|
||||
This can be used to release memory used for objects on the free
|
||||
list back to the Python memory allocator.
|
||||
|
||||
*/
|
||||
|
||||
PyAPI_FUNC(int) PyUnicode_ClearFreeList(void);
|
||||
|
||||
/* === Builtin Codecs =====================================================
|
||||
|
||||
Many of these APIs take two arguments encoding and errors. These
|
||||
|
|
|
@ -87,7 +87,6 @@ __all__ = [
|
|||
|
||||
import os as _os
|
||||
import re as _re
|
||||
import shutil as _shutil
|
||||
import sys as _sys
|
||||
|
||||
from gettext import gettext as _, ngettext
|
||||
|
@ -167,7 +166,8 @@ class HelpFormatter(object):
|
|||
|
||||
# default setting for width
|
||||
if width is None:
|
||||
width = _shutil.get_terminal_size().columns
|
||||
import shutil
|
||||
width = shutil.get_terminal_size().columns
|
||||
width -= 2
|
||||
|
||||
self._prog = prog
|
||||
|
@ -264,7 +264,7 @@ class HelpFormatter(object):
|
|||
invocations.append(get_invocation(subaction))
|
||||
|
||||
# update the maximum item length
|
||||
invocation_length = max([len(s) for s in invocations])
|
||||
invocation_length = max(map(len, invocations))
|
||||
action_length = invocation_length + self._current_indent
|
||||
self._action_max_length = max(self._action_max_length,
|
||||
action_length)
|
||||
|
|
699
Lib/ast.py
699
Lib/ast.py
|
@ -24,6 +24,7 @@
|
|||
:copyright: Copyright 2008 by Armin Ronacher.
|
||||
:license: Python License.
|
||||
"""
|
||||
import sys
|
||||
from _ast import *
|
||||
|
||||
|
||||
|
@ -551,6 +552,704 @@ _const_node_type_names = {
|
|||
type(...): 'Ellipsis',
|
||||
}
|
||||
|
||||
# Large float and imaginary literals get turned into infinities in the AST.
|
||||
# We unparse those infinities to INFSTR.
|
||||
_INFSTR = "1e" + repr(sys.float_info.max_10_exp + 1)
|
||||
|
||||
class _Unparser(NodeVisitor):
|
||||
"""Methods in this class recursively traverse an AST and
|
||||
output source code for the abstract syntax; original formatting
|
||||
is disregarded."""
|
||||
|
||||
def __init__(self):
|
||||
self._source = []
|
||||
self._buffer = []
|
||||
self._indent = 0
|
||||
|
||||
def interleave(self, inter, f, seq):
|
||||
"""Call f on each item in seq, calling inter() in between."""
|
||||
seq = iter(seq)
|
||||
try:
|
||||
f(next(seq))
|
||||
except StopIteration:
|
||||
pass
|
||||
else:
|
||||
for x in seq:
|
||||
inter()
|
||||
f(x)
|
||||
|
||||
def fill(self, text=""):
|
||||
"""Indent a piece of text and append it, according to the current
|
||||
indentation level"""
|
||||
self.write("\n" + " " * self._indent + text)
|
||||
|
||||
def write(self, text):
|
||||
"""Append a piece of text"""
|
||||
self._source.append(text)
|
||||
|
||||
def buffer_writer(self, text):
|
||||
self._buffer.append(text)
|
||||
|
||||
@property
|
||||
def buffer(self):
|
||||
value = "".join(self._buffer)
|
||||
self._buffer.clear()
|
||||
return value
|
||||
|
||||
class _Block:
|
||||
"""A context manager for preparing the source for blocks. It adds
|
||||
the character':', increases the indentation on enter and decreases
|
||||
the indentation on exit."""
|
||||
def __init__(self, unparser):
|
||||
self.unparser = unparser
|
||||
|
||||
def __enter__(self):
|
||||
self.unparser.write(":")
|
||||
self.unparser._indent += 1
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
self.unparser._indent -= 1
|
||||
|
||||
def block(self):
|
||||
return self._Block(self)
|
||||
|
||||
def traverse(self, node):
|
||||
if isinstance(node, list):
|
||||
for item in node:
|
||||
self.traverse(item)
|
||||
else:
|
||||
super().visit(node)
|
||||
|
||||
def visit(self, node):
|
||||
"""Outputs a source code string that, if converted back to an ast
|
||||
(using ast.parse) will generate an AST equivalent to *node*"""
|
||||
self._source = []
|
||||
self.traverse(node)
|
||||
return "".join(self._source)
|
||||
|
||||
def visit_Module(self, node):
|
||||
for subnode in node.body:
|
||||
self.traverse(subnode)
|
||||
|
||||
def visit_Expr(self, node):
|
||||
self.fill()
|
||||
self.traverse(node.value)
|
||||
|
||||
def visit_NamedExpr(self, node):
|
||||
self.write("(")
|
||||
self.traverse(node.target)
|
||||
self.write(" := ")
|
||||
self.traverse(node.value)
|
||||
self.write(")")
|
||||
|
||||
def visit_Import(self, node):
|
||||
self.fill("import ")
|
||||
self.interleave(lambda: self.write(", "), self.traverse, node.names)
|
||||
|
||||
def visit_ImportFrom(self, node):
|
||||
self.fill("from ")
|
||||
self.write("." * node.level)
|
||||
if node.module:
|
||||
self.write(node.module)
|
||||
self.write(" import ")
|
||||
self.interleave(lambda: self.write(", "), self.traverse, node.names)
|
||||
|
||||
def visit_Assign(self, node):
|
||||
self.fill()
|
||||
for target in node.targets:
|
||||
self.traverse(target)
|
||||
self.write(" = ")
|
||||
self.traverse(node.value)
|
||||
|
||||
def visit_AugAssign(self, node):
|
||||
self.fill()
|
||||
self.traverse(node.target)
|
||||
self.write(" " + self.binop[node.op.__class__.__name__] + "= ")
|
||||
self.traverse(node.value)
|
||||
|
||||
def visit_AnnAssign(self, node):
|
||||
self.fill()
|
||||
if not node.simple and isinstance(node.target, Name):
|
||||
self.write("(")
|
||||
self.traverse(node.target)
|
||||
if not node.simple and isinstance(node.target, Name):
|
||||
self.write(")")
|
||||
self.write(": ")
|
||||
self.traverse(node.annotation)
|
||||
if node.value:
|
||||
self.write(" = ")
|
||||
self.traverse(node.value)
|
||||
|
||||
def visit_Return(self, node):
|
||||
self.fill("return")
|
||||
if node.value:
|
||||
self.write(" ")
|
||||
self.traverse(node.value)
|
||||
|
||||
def visit_Pass(self, node):
|
||||
self.fill("pass")
|
||||
|
||||
def visit_Break(self, node):
|
||||
self.fill("break")
|
||||
|
||||
def visit_Continue(self, node):
|
||||
self.fill("continue")
|
||||
|
||||
def visit_Delete(self, node):
|
||||
self.fill("del ")
|
||||
self.interleave(lambda: self.write(", "), self.traverse, node.targets)
|
||||
|
||||
def visit_Assert(self, node):
|
||||
self.fill("assert ")
|
||||
self.traverse(node.test)
|
||||
if node.msg:
|
||||
self.write(", ")
|
||||
self.traverse(node.msg)
|
||||
|
||||
def visit_Global(self, node):
|
||||
self.fill("global ")
|
||||
self.interleave(lambda: self.write(", "), self.write, node.names)
|
||||
|
||||
def visit_Nonlocal(self, node):
|
||||
self.fill("nonlocal ")
|
||||
self.interleave(lambda: self.write(", "), self.write, node.names)
|
||||
|
||||
def visit_Await(self, node):
|
||||
self.write("(")
|
||||
self.write("await")
|
||||
if node.value:
|
||||
self.write(" ")
|
||||
self.traverse(node.value)
|
||||
self.write(")")
|
||||
|
||||
def visit_Yield(self, node):
|
||||
self.write("(")
|
||||
self.write("yield")
|
||||
if node.value:
|
||||
self.write(" ")
|
||||
self.traverse(node.value)
|
||||
self.write(")")
|
||||
|
||||
def visit_YieldFrom(self, node):
|
||||
self.write("(")
|
||||
self.write("yield from")
|
||||
if node.value:
|
||||
self.write(" ")
|
||||
self.traverse(node.value)
|
||||
self.write(")")
|
||||
|
||||
def visit_Raise(self, node):
|
||||
self.fill("raise")
|
||||
if not node.exc:
|
||||
if node.cause:
|
||||
raise ValueError(f"Node can't use cause without an exception.")
|
||||
return
|
||||
self.write(" ")
|
||||
self.traverse(node.exc)
|
||||
if node.cause:
|
||||
self.write(" from ")
|
||||
self.traverse(node.cause)
|
||||
|
||||
def visit_Try(self, node):
|
||||
self.fill("try")
|
||||
with self.block():
|
||||
self.traverse(node.body)
|
||||
for ex in node.handlers:
|
||||
self.traverse(ex)
|
||||
if node.orelse:
|
||||
self.fill("else")
|
||||
with self.block():
|
||||
self.traverse(node.orelse)
|
||||
if node.finalbody:
|
||||
self.fill("finally")
|
||||
with self.block():
|
||||
self.traverse(node.finalbody)
|
||||
|
||||
def visit_ExceptHandler(self, node):
|
||||
self.fill("except")
|
||||
if node.type:
|
||||
self.write(" ")
|
||||
self.traverse(node.type)
|
||||
if node.name:
|
||||
self.write(" as ")
|
||||
self.write(node.name)
|
||||
with self.block():
|
||||
self.traverse(node.body)
|
||||
|
||||
def visit_ClassDef(self, node):
|
||||
self.write("\n")
|
||||
for deco in node.decorator_list:
|
||||
self.fill("@")
|
||||
self.traverse(deco)
|
||||
self.fill("class " + node.name)
|
||||
self.write("(")
|
||||
comma = False
|
||||
for e in node.bases:
|
||||
if comma:
|
||||
self.write(", ")
|
||||
else:
|
||||
comma = True
|
||||
self.traverse(e)
|
||||
for e in node.keywords:
|
||||
if comma:
|
||||
self.write(", ")
|
||||
else:
|
||||
comma = True
|
||||
self.traverse(e)
|
||||
self.write(")")
|
||||
|
||||
with self.block():
|
||||
self.traverse(node.body)
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
self.__FunctionDef_helper(node, "def")
|
||||
|
||||
def visit_AsyncFunctionDef(self, node):
|
||||
self.__FunctionDef_helper(node, "async def")
|
||||
|
||||
def __FunctionDef_helper(self, node, fill_suffix):
|
||||
self.write("\n")
|
||||
for deco in node.decorator_list:
|
||||
self.fill("@")
|
||||
self.traverse(deco)
|
||||
def_str = fill_suffix + " " + node.name + "("
|
||||
self.fill(def_str)
|
||||
self.traverse(node.args)
|
||||
self.write(")")
|
||||
if node.returns:
|
||||
self.write(" -> ")
|
||||
self.traverse(node.returns)
|
||||
with self.block():
|
||||
self.traverse(node.body)
|
||||
|
||||
def visit_For(self, node):
|
||||
self.__For_helper("for ", node)
|
||||
|
||||
def visit_AsyncFor(self, node):
|
||||
self.__For_helper("async for ", node)
|
||||
|
||||
def __For_helper(self, fill, node):
|
||||
self.fill(fill)
|
||||
self.traverse(node.target)
|
||||
self.write(" in ")
|
||||
self.traverse(node.iter)
|
||||
with self.block():
|
||||
self.traverse(node.body)
|
||||
if node.orelse:
|
||||
self.fill("else")
|
||||
with self.block():
|
||||
self.traverse(node.orelse)
|
||||
|
||||
def visit_If(self, node):
|
||||
self.fill("if ")
|
||||
self.traverse(node.test)
|
||||
with self.block():
|
||||
self.traverse(node.body)
|
||||
# collapse nested ifs into equivalent elifs.
|
||||
while node.orelse and len(node.orelse) == 1 and isinstance(node.orelse[0], If):
|
||||
node = node.orelse[0]
|
||||
self.fill("elif ")
|
||||
self.traverse(node.test)
|
||||
with self.block():
|
||||
self.traverse(node.body)
|
||||
# final else
|
||||
if node.orelse:
|
||||
self.fill("else")
|
||||
with self.block():
|
||||
self.traverse(node.orelse)
|
||||
|
||||
def visit_While(self, node):
|
||||
self.fill("while ")
|
||||
self.traverse(node.test)
|
||||
with self.block():
|
||||
self.traverse(node.body)
|
||||
if node.orelse:
|
||||
self.fill("else")
|
||||
with self.block():
|
||||
self.traverse(node.orelse)
|
||||
|
||||
def visit_With(self, node):
|
||||
self.fill("with ")
|
||||
self.interleave(lambda: self.write(", "), self.traverse, node.items)
|
||||
with self.block():
|
||||
self.traverse(node.body)
|
||||
|
||||
def visit_AsyncWith(self, node):
|
||||
self.fill("async with ")
|
||||
self.interleave(lambda: self.write(", "), self.traverse, node.items)
|
||||
with self.block():
|
||||
self.traverse(node.body)
|
||||
|
||||
def visit_JoinedStr(self, node):
|
||||
self.write("f")
|
||||
self._fstring_JoinedStr(node, self.buffer_writer)
|
||||
self.write(repr(self.buffer))
|
||||
|
||||
def visit_FormattedValue(self, node):
|
||||
self.write("f")
|
||||
self._fstring_FormattedValue(node, self.buffer_writer)
|
||||
self.write(repr(self.buffer))
|
||||
|
||||
def _fstring_JoinedStr(self, node, write):
|
||||
for value in node.values:
|
||||
meth = getattr(self, "_fstring_" + type(value).__name__)
|
||||
meth(value, write)
|
||||
|
||||
def _fstring_Constant(self, node, write):
|
||||
if not isinstance(node.value, str):
|
||||
raise ValueError("Constants inside JoinedStr should be a string.")
|
||||
value = node.value.replace("{", "{{").replace("}", "}}")
|
||||
write(value)
|
||||
|
||||
def _fstring_FormattedValue(self, node, write):
|
||||
write("{")
|
||||
expr = type(self)().visit(node.value).rstrip("\n")
|
||||
if expr.startswith("{"):
|
||||
write(" ") # Separate pair of opening brackets as "{ {"
|
||||
write(expr)
|
||||
if node.conversion != -1:
|
||||
conversion = chr(node.conversion)
|
||||
if conversion not in "sra":
|
||||
raise ValueError("Unknown f-string conversion.")
|
||||
write(f"!{conversion}")
|
||||
if node.format_spec:
|
||||
write(":")
|
||||
meth = getattr(self, "_fstring_" + type(node.format_spec).__name__)
|
||||
meth(node.format_spec, write)
|
||||
write("}")
|
||||
|
||||
def visit_Name(self, node):
|
||||
self.write(node.id)
|
||||
|
||||
def _write_constant(self, value):
|
||||
if isinstance(value, (float, complex)):
|
||||
# Substitute overflowing decimal literal for AST infinities.
|
||||
self.write(repr(value).replace("inf", _INFSTR))
|
||||
else:
|
||||
self.write(repr(value))
|
||||
|
||||
def visit_Constant(self, node):
|
||||
value = node.value
|
||||
if isinstance(value, tuple):
|
||||
self.write("(")
|
||||
if len(value) == 1:
|
||||
self._write_constant(value[0])
|
||||
self.write(",")
|
||||
else:
|
||||
self.interleave(lambda: self.write(", "), self._write_constant, value)
|
||||
self.write(")")
|
||||
elif value is ...:
|
||||
self.write("...")
|
||||
else:
|
||||
if node.kind == "u":
|
||||
self.write("u")
|
||||
self._write_constant(node.value)
|
||||
|
||||
def visit_List(self, node):
|
||||
self.write("[")
|
||||
self.interleave(lambda: self.write(", "), self.traverse, node.elts)
|
||||
self.write("]")
|
||||
|
||||
def visit_ListComp(self, node):
|
||||
self.write("[")
|
||||
self.traverse(node.elt)
|
||||
for gen in node.generators:
|
||||
self.traverse(gen)
|
||||
self.write("]")
|
||||
|
||||
def visit_GeneratorExp(self, node):
|
||||
self.write("(")
|
||||
self.traverse(node.elt)
|
||||
for gen in node.generators:
|
||||
self.traverse(gen)
|
||||
self.write(")")
|
||||
|
||||
def visit_SetComp(self, node):
|
||||
self.write("{")
|
||||
self.traverse(node.elt)
|
||||
for gen in node.generators:
|
||||
self.traverse(gen)
|
||||
self.write("}")
|
||||
|
||||
def visit_DictComp(self, node):
|
||||
self.write("{")
|
||||
self.traverse(node.key)
|
||||
self.write(": ")
|
||||
self.traverse(node.value)
|
||||
for gen in node.generators:
|
||||
self.traverse(gen)
|
||||
self.write("}")
|
||||
|
||||
def visit_comprehension(self, node):
|
||||
if node.is_async:
|
||||
self.write(" async for ")
|
||||
else:
|
||||
self.write(" for ")
|
||||
self.traverse(node.target)
|
||||
self.write(" in ")
|
||||
self.traverse(node.iter)
|
||||
for if_clause in node.ifs:
|
||||
self.write(" if ")
|
||||
self.traverse(if_clause)
|
||||
|
||||
def visit_IfExp(self, node):
|
||||
self.write("(")
|
||||
self.traverse(node.body)
|
||||
self.write(" if ")
|
||||
self.traverse(node.test)
|
||||
self.write(" else ")
|
||||
self.traverse(node.orelse)
|
||||
self.write(")")
|
||||
|
||||
def visit_Set(self, node):
|
||||
if not node.elts:
|
||||
raise ValueError("Set node should has at least one item")
|
||||
self.write("{")
|
||||
self.interleave(lambda: self.write(", "), self.traverse, node.elts)
|
||||
self.write("}")
|
||||
|
||||
def visit_Dict(self, node):
|
||||
self.write("{")
|
||||
|
||||
def write_key_value_pair(k, v):
|
||||
self.traverse(k)
|
||||
self.write(": ")
|
||||
self.traverse(v)
|
||||
|
||||
def write_item(item):
|
||||
k, v = item
|
||||
if k is None:
|
||||
# for dictionary unpacking operator in dicts {**{'y': 2}}
|
||||
# see PEP 448 for details
|
||||
self.write("**")
|
||||
self.traverse(v)
|
||||
else:
|
||||
write_key_value_pair(k, v)
|
||||
|
||||
self.interleave(
|
||||
lambda: self.write(", "), write_item, zip(node.keys, node.values)
|
||||
)
|
||||
self.write("}")
|
||||
|
||||
def visit_Tuple(self, node):
|
||||
self.write("(")
|
||||
if len(node.elts) == 1:
|
||||
elt = node.elts[0]
|
||||
self.traverse(elt)
|
||||
self.write(",")
|
||||
else:
|
||||
self.interleave(lambda: self.write(", "), self.traverse, node.elts)
|
||||
self.write(")")
|
||||
|
||||
unop = {"Invert": "~", "Not": "not", "UAdd": "+", "USub": "-"}
|
||||
|
||||
def visit_UnaryOp(self, node):
|
||||
self.write("(")
|
||||
self.write(self.unop[node.op.__class__.__name__])
|
||||
self.write(" ")
|
||||
self.traverse(node.operand)
|
||||
self.write(")")
|
||||
|
||||
binop = {
|
||||
"Add": "+",
|
||||
"Sub": "-",
|
||||
"Mult": "*",
|
||||
"MatMult": "@",
|
||||
"Div": "/",
|
||||
"Mod": "%",
|
||||
"LShift": "<<",
|
||||
"RShift": ">>",
|
||||
"BitOr": "|",
|
||||
"BitXor": "^",
|
||||
"BitAnd": "&",
|
||||
"FloorDiv": "//",
|
||||
"Pow": "**",
|
||||
}
|
||||
|
||||
def visit_BinOp(self, node):
|
||||
self.write("(")
|
||||
self.traverse(node.left)
|
||||
self.write(" " + self.binop[node.op.__class__.__name__] + " ")
|
||||
self.traverse(node.right)
|
||||
self.write(")")
|
||||
|
||||
cmpops = {
|
||||
"Eq": "==",
|
||||
"NotEq": "!=",
|
||||
"Lt": "<",
|
||||
"LtE": "<=",
|
||||
"Gt": ">",
|
||||
"GtE": ">=",
|
||||
"Is": "is",
|
||||
"IsNot": "is not",
|
||||
"In": "in",
|
||||
"NotIn": "not in",
|
||||
}
|
||||
|
||||
def visit_Compare(self, node):
|
||||
self.write("(")
|
||||
self.traverse(node.left)
|
||||
for o, e in zip(node.ops, node.comparators):
|
||||
self.write(" " + self.cmpops[o.__class__.__name__] + " ")
|
||||
self.traverse(e)
|
||||
self.write(")")
|
||||
|
||||
boolops = {And: "and", Or: "or"}
|
||||
|
||||
def visit_BoolOp(self, node):
|
||||
self.write("(")
|
||||
s = " %s " % self.boolops[node.op.__class__]
|
||||
self.interleave(lambda: self.write(s), self.traverse, node.values)
|
||||
self.write(")")
|
||||
|
||||
def visit_Attribute(self, node):
|
||||
self.traverse(node.value)
|
||||
# Special case: 3.__abs__() is a syntax error, so if node.value
|
||||
# is an integer literal then we need to either parenthesize
|
||||
# it or add an extra space to get 3 .__abs__().
|
||||
if isinstance(node.value, Constant) and isinstance(node.value.value, int):
|
||||
self.write(" ")
|
||||
self.write(".")
|
||||
self.write(node.attr)
|
||||
|
||||
def visit_Call(self, node):
|
||||
self.traverse(node.func)
|
||||
self.write("(")
|
||||
comma = False
|
||||
for e in node.args:
|
||||
if comma:
|
||||
self.write(", ")
|
||||
else:
|
||||
comma = True
|
||||
self.traverse(e)
|
||||
for e in node.keywords:
|
||||
if comma:
|
||||
self.write(", ")
|
||||
else:
|
||||
comma = True
|
||||
self.traverse(e)
|
||||
self.write(")")
|
||||
|
||||
def visit_Subscript(self, node):
|
||||
self.traverse(node.value)
|
||||
self.write("[")
|
||||
self.traverse(node.slice)
|
||||
self.write("]")
|
||||
|
||||
def visit_Starred(self, node):
|
||||
self.write("*")
|
||||
self.traverse(node.value)
|
||||
|
||||
def visit_Ellipsis(self, node):
|
||||
self.write("...")
|
||||
|
||||
def visit_Index(self, node):
|
||||
self.traverse(node.value)
|
||||
|
||||
def visit_Slice(self, node):
|
||||
if node.lower:
|
||||
self.traverse(node.lower)
|
||||
self.write(":")
|
||||
if node.upper:
|
||||
self.traverse(node.upper)
|
||||
if node.step:
|
||||
self.write(":")
|
||||
self.traverse(node.step)
|
||||
|
||||
def visit_ExtSlice(self, node):
|
||||
self.interleave(lambda: self.write(", "), self.traverse, node.dims)
|
||||
|
||||
def visit_arg(self, node):
|
||||
self.write(node.arg)
|
||||
if node.annotation:
|
||||
self.write(": ")
|
||||
self.traverse(node.annotation)
|
||||
|
||||
def visit_arguments(self, node):
|
||||
first = True
|
||||
# normal arguments
|
||||
all_args = node.posonlyargs + node.args
|
||||
defaults = [None] * (len(all_args) - len(node.defaults)) + node.defaults
|
||||
for index, elements in enumerate(zip(all_args, defaults), 1):
|
||||
a, d = elements
|
||||
if first:
|
||||
first = False
|
||||
else:
|
||||
self.write(", ")
|
||||
self.traverse(a)
|
||||
if d:
|
||||
self.write("=")
|
||||
self.traverse(d)
|
||||
if index == len(node.posonlyargs):
|
||||
self.write(", /")
|
||||
|
||||
# varargs, or bare '*' if no varargs but keyword-only arguments present
|
||||
if node.vararg or node.kwonlyargs:
|
||||
if first:
|
||||
first = False
|
||||
else:
|
||||
self.write(", ")
|
||||
self.write("*")
|
||||
if node.vararg:
|
||||
self.write(node.vararg.arg)
|
||||
if node.vararg.annotation:
|
||||
self.write(": ")
|
||||
self.traverse(node.vararg.annotation)
|
||||
|
||||
# keyword-only arguments
|
||||
if node.kwonlyargs:
|
||||
for a, d in zip(node.kwonlyargs, node.kw_defaults):
|
||||
if first:
|
||||
first = False
|
||||
else:
|
||||
self.write(", ")
|
||||
self.traverse(a),
|
||||
if d:
|
||||
self.write("=")
|
||||
self.traverse(d)
|
||||
|
||||
# kwargs
|
||||
if node.kwarg:
|
||||
if first:
|
||||
first = False
|
||||
else:
|
||||
self.write(", ")
|
||||
self.write("**" + node.kwarg.arg)
|
||||
if node.kwarg.annotation:
|
||||
self.write(": ")
|
||||
self.traverse(node.kwarg.annotation)
|
||||
|
||||
def visit_keyword(self, node):
|
||||
if node.arg is None:
|
||||
self.write("**")
|
||||
else:
|
||||
self.write(node.arg)
|
||||
self.write("=")
|
||||
self.traverse(node.value)
|
||||
|
||||
def visit_Lambda(self, node):
|
||||
self.write("(")
|
||||
self.write("lambda ")
|
||||
self.traverse(node.args)
|
||||
self.write(": ")
|
||||
self.traverse(node.body)
|
||||
self.write(")")
|
||||
|
||||
def visit_alias(self, node):
|
||||
self.write(node.name)
|
||||
if node.asname:
|
||||
self.write(" as " + node.asname)
|
||||
|
||||
def visit_withitem(self, node):
|
||||
self.traverse(node.context_expr)
|
||||
if node.optional_vars:
|
||||
self.write(" as ")
|
||||
self.traverse(node.optional_vars)
|
||||
|
||||
def unparse(ast_obj):
|
||||
unparser = _Unparser()
|
||||
return unparser.visit(ast_obj)
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
|
|
@ -66,6 +66,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
|
||||
|
@ -1230,7 +1234,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:
|
||||
|
@ -1239,7 +1243,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,
|
||||
|
@ -1306,8 +1310,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.5.10 and is scheduled "
|
||||
"for removal in 3.11.", DeprecationWarning,
|
||||
stacklevel=2)
|
||||
|
||||
for ((family, proto),
|
||||
(local_address, remote_address)) in addr_pairs_info:
|
||||
|
@ -1316,9 +1330,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:
|
||||
|
|
|
@ -636,7 +636,7 @@ class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy):
|
|||
"""
|
||||
if (self._local._loop is None and
|
||||
not self._local._set_called and
|
||||
isinstance(threading.current_thread(), threading._MainThread)):
|
||||
threading.current_thread() is threading.main_thread()):
|
||||
self.set_event_loop(self.new_event_loop())
|
||||
|
||||
if self._local._loop is None:
|
||||
|
|
|
@ -103,6 +103,9 @@ class Future:
|
|||
context['source_traceback'] = self._source_traceback
|
||||
self._loop.call_exception_handler(context)
|
||||
|
||||
def __class_getitem__(cls, type):
|
||||
return cls
|
||||
|
||||
@property
|
||||
def _log_traceback(self):
|
||||
return self.__log_traceback
|
||||
|
|
|
@ -76,6 +76,9 @@ class Queue:
|
|||
def __str__(self):
|
||||
return f'<{type(self).__name__} {self._format()}>'
|
||||
|
||||
def __class_getitem__(cls, type):
|
||||
return cls
|
||||
|
||||
def _format(self):
|
||||
result = f'maxsize={self._maxsize!r}'
|
||||
if getattr(self, '_queue', None):
|
||||
|
|
|
@ -40,6 +40,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.
|
||||
|
||||
|
@ -348,6 +353,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")
|
||||
try:
|
||||
|
@ -386,6 +392,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")
|
||||
try:
|
||||
|
@ -425,6 +432,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")
|
||||
try:
|
||||
|
@ -472,6 +480,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")
|
||||
|
||||
|
@ -533,6 +542,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()
|
||||
|
|
|
@ -214,8 +214,7 @@ class StreamReaderProtocol(FlowControlMixin, protocols.Protocol):
|
|||
def __init__(self, stream_reader, client_connected_cb=None, loop=None):
|
||||
super().__init__(loop=loop)
|
||||
if stream_reader is not None:
|
||||
self._stream_reader_wr = weakref.ref(stream_reader,
|
||||
self._on_reader_gc)
|
||||
self._stream_reader_wr = weakref.ref(stream_reader)
|
||||
self._source_traceback = stream_reader._source_traceback
|
||||
else:
|
||||
self._stream_reader_wr = None
|
||||
|
@ -231,22 +230,6 @@ class StreamReaderProtocol(FlowControlMixin, protocols.Protocol):
|
|||
self._over_ssl = False
|
||||
self._closed = self._loop.create_future()
|
||||
|
||||
def _on_reader_gc(self, wr):
|
||||
transport = self._transport
|
||||
if transport is not None:
|
||||
# connection_made was called
|
||||
context = {
|
||||
'message': ('An open stream object is being garbage '
|
||||
'collected; call "stream.close()" explicitly.')
|
||||
}
|
||||
if self._source_traceback:
|
||||
context['source_traceback'] = self._source_traceback
|
||||
self._loop.call_exception_handler(context)
|
||||
transport.abort()
|
||||
else:
|
||||
self._reject_connection = True
|
||||
self._stream_reader_wr = None
|
||||
|
||||
@property
|
||||
def _stream_reader(self):
|
||||
if self._stream_reader_wr is None:
|
||||
|
|
|
@ -175,6 +175,9 @@ class Task(futures._PyFuture): # Inherit Python Task implementation
|
|||
self._loop.call_exception_handler(context)
|
||||
super().__del__()
|
||||
|
||||
def __class_getitem__(cls, type):
|
||||
return cls
|
||||
|
||||
def _repr_info(self):
|
||||
return base_tasks._task_repr_info(self)
|
||||
|
||||
|
|
|
@ -930,9 +930,20 @@ class PidfdChildWatcher(AbstractChildWatcher):
|
|||
def _do_wait(self, pid):
|
||||
pidfd, callback, args = self._callbacks.pop(pid)
|
||||
self._loop._remove_reader(pidfd)
|
||||
try:
|
||||
_, status = os.waitpid(pid, 0)
|
||||
os.close(pidfd)
|
||||
except ChildProcessError:
|
||||
# The child process is already reaped
|
||||
# (may happen if waitpid() is called elsewhere).
|
||||
returncode = 255
|
||||
logger.warning(
|
||||
"child process pid %d exit status already read: "
|
||||
" will report returncode 255",
|
||||
pid)
|
||||
else:
|
||||
returncode = _compute_returncode(status)
|
||||
|
||||
os.close(pidfd)
|
||||
callback(pid, returncode, *args)
|
||||
|
||||
def remove_child_handler(self, pid):
|
||||
|
@ -1406,8 +1417,7 @@ class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy):
|
|||
with events._lock:
|
||||
if self._watcher is None: # pragma: no branch
|
||||
self._watcher = ThreadedChildWatcher()
|
||||
if isinstance(threading.current_thread(),
|
||||
threading._MainThread):
|
||||
if threading.current_thread() is threading.main_thread():
|
||||
self._watcher.attach_loop(self._local._loop)
|
||||
|
||||
def set_event_loop(self, loop):
|
||||
|
@ -1421,7 +1431,7 @@ class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy):
|
|||
super().set_event_loop(loop)
|
||||
|
||||
if (self._watcher is not None and
|
||||
isinstance(threading.current_thread(), threading._MainThread)):
|
||||
threading.current_thread() is threading.main_thread()):
|
||||
self._watcher.attach_loop(loop)
|
||||
|
||||
def get_child_watcher(self):
|
||||
|
|
|
@ -93,10 +93,13 @@ def _maybe_compile(compiler, source, filename, symbol):
|
|||
except SyntaxError as e:
|
||||
err2 = e
|
||||
|
||||
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)
|
||||
|
|
|
@ -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 = {}
|
||||
|
|
|
@ -378,11 +378,8 @@ 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
|
||||
|
@ -391,10 +388,14 @@ def _create_fn(name, args, body, *, globals=None, locals=None,
|
|||
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):
|
||||
|
@ -405,7 +406,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}'
|
||||
|
||||
|
||||
|
@ -482,15 +483,18 @@ 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.
|
||||
|
||||
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:
|
||||
|
@ -520,7 +524,6 @@ def _init_fn(fields, frozen, has_post_init, self_name):
|
|||
args.append("*")
|
||||
args.append(_init_param(f))
|
||||
|
||||
locals = {f'_type_{f.name}': f.type for f in fields}
|
||||
return _create_fn('__init__',
|
||||
args,
|
||||
body_lines,
|
||||
|
@ -529,20 +532,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) + ',)'
|
||||
|
@ -554,17 +556,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
|
||||
|
@ -574,14 +578,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):
|
||||
|
@ -754,14 +760,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__}')
|
||||
|
@ -803,6 +809,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))
|
||||
|
||||
|
@ -912,6 +928,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
|
||||
|
@ -920,7 +937,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,
|
||||
|
@ -930,7 +947,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.
|
||||
|
@ -943,13 +961,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__}')
|
||||
|
@ -962,7 +981,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.
|
||||
|
|
|
@ -850,10 +850,15 @@ class MsgID(TokenList):
|
|||
# message-id tokens may not be folded.
|
||||
return str(self) + policy.linesep
|
||||
|
||||
|
||||
class MessageID(MsgID):
|
||||
token_type = 'message-id'
|
||||
|
||||
|
||||
class InvalidMessageID(MessageID):
|
||||
token_type = 'invalid-message-id'
|
||||
|
||||
|
||||
class Header(TokenList):
|
||||
token_type = 'header'
|
||||
|
||||
|
@ -2042,7 +2047,7 @@ def get_msg_id(value):
|
|||
no-fold-literal = "[" *dtext "]"
|
||||
"""
|
||||
msg_id = MsgID()
|
||||
if value[0] in CFWS_LEADER:
|
||||
if value and value[0] in CFWS_LEADER:
|
||||
token, value = get_cfws(value)
|
||||
msg_id.append(token)
|
||||
if not value or value[0] != '<':
|
||||
|
@ -2110,10 +2115,18 @@ def parse_message_id(value):
|
|||
message_id = MessageID()
|
||||
try:
|
||||
token, value = get_msg_id(value)
|
||||
except errors.HeaderParseError:
|
||||
message_id.defects.append(errors.InvalidHeaderDefect(
|
||||
"Expected msg-id but found {!r}".format(value)))
|
||||
message_id.append(token)
|
||||
except errors.HeaderParseError as ex:
|
||||
token = get_unstructured(value)
|
||||
message_id = InvalidMessageID(token)
|
||||
message_id.defects.append(
|
||||
errors.InvalidHeaderDefect("Invalid msg-id: {!r}".format(ex)))
|
||||
else:
|
||||
# Value after parsing a valid msg_id should be None.
|
||||
if value:
|
||||
message_id.defects.append(errors.InvalidHeaderDefect(
|
||||
"Unexpected {!r}".format(value)))
|
||||
|
||||
return message_id
|
||||
|
||||
#
|
||||
|
|
|
@ -20,6 +20,10 @@ def uu_encode(input, errors='strict', filename='<data>', 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)
|
||||
|
|
33
Lib/enum.py
33
Lib/enum.py
|
@ -861,28 +861,20 @@ def _decompose(flag, value):
|
|||
# _decompose is only called if the value is not named
|
||||
not_covered = value
|
||||
negative = value < 0
|
||||
# issue29167: wrap accesses to _value2member_map_ in a list to avoid race
|
||||
# conditions between iterating over it and having more pseudo-
|
||||
# members added to it
|
||||
if negative:
|
||||
# only check for named flags
|
||||
flags_to_check = [
|
||||
(m, v)
|
||||
for v, m in list(flag._value2member_map_.items())
|
||||
if m.name is not None
|
||||
]
|
||||
else:
|
||||
# check for named flags and powers-of-two flags
|
||||
flags_to_check = [
|
||||
(m, v)
|
||||
for v, m in list(flag._value2member_map_.items())
|
||||
if m.name is not None or _power_of_two(v)
|
||||
]
|
||||
members = []
|
||||
for member, member_value in flags_to_check:
|
||||
for member in flag:
|
||||
member_value = member.value
|
||||
if member_value and member_value & value == member_value:
|
||||
members.append(member)
|
||||
not_covered &= ~member_value
|
||||
if not negative:
|
||||
tmp = not_covered
|
||||
while tmp:
|
||||
flag_value = 2 ** _high_bit(tmp)
|
||||
if flag_value in flag._value2member_map_:
|
||||
members.append(flag._value2member_map_[flag_value])
|
||||
not_covered &= ~flag_value
|
||||
tmp &= ~flag_value
|
||||
if not members and value in flag._value2member_map_:
|
||||
members.append(flag._value2member_map_[value])
|
||||
members.sort(key=lambda m: m._value_, reverse=True)
|
||||
|
@ -890,8 +882,3 @@ def _decompose(flag, value):
|
|||
# we have the breakdown, don't need the value member itself
|
||||
members.pop(0)
|
||||
return members, not_covered
|
||||
|
||||
def _power_of_two(value):
|
||||
if value < 1:
|
||||
return False
|
||||
return value == 2 ** _high_bit(value)
|
||||
|
|
|
@ -214,10 +214,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*$""", re.X | re.ASCII)
|
||||
)?
|
||||
(?:
|
||||
\(\w+\) # ASCII representation of timezone in parens.
|
||||
\s*
|
||||
)?$""", re.X | re.ASCII)
|
||||
def http2time(text):
|
||||
"""Returns time in seconds since epoch of time represented by a string.
|
||||
|
||||
|
@ -287,9 +291,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)
|
||||
|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:
|
||||
|
|
|
@ -1014,8 +1014,10 @@ class CGIHTTPRequestHandler(SimpleHTTPRequestHandler):
|
|||
"""
|
||||
collapsed_path = _url_collapse_path(self.path)
|
||||
dir_sep = collapsed_path.find('/', 1)
|
||||
while dir_sep > 0 and not collapsed_path[:dir_sep] in self.cgi_directories:
|
||||
dir_sep = collapsed_path.find('/', dir_sep+1)
|
||||
if dir_sep > 0:
|
||||
head, tail = collapsed_path[:dir_sep], collapsed_path[dir_sep+1:]
|
||||
if head in self.cgi_directories:
|
||||
self.cgi_info = head, tail
|
||||
return True
|
||||
return False
|
||||
|
|
|
@ -3,6 +3,15 @@ Released on 2020-10-05?
|
|||
======================================
|
||||
|
||||
|
||||
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.
|
||||
|
|
|
@ -17,7 +17,7 @@ KEYPRESS_VIRTUAL_EVENT_NAME = "<<autocompletewindow-keypress>>"
|
|||
# before the default specific IDLE function
|
||||
KEYPRESS_SEQUENCES = ("<Key>", "<Key-BackSpace>", "<Key-Return>", "<Key-Tab>",
|
||||
"<Key-Up>", "<Key-Down>", "<Key-Home>", "<Key-End>",
|
||||
"<Key-Prior>", "<Key-Next>")
|
||||
"<Key-Prior>", "<Key-Next>", "<Key-Escape>")
|
||||
KEYRELEASE_VIRTUAL_EVENT_NAME = "<<autocompletewindow-keyrelease>>"
|
||||
KEYRELEASE_SEQUENCE = "<KeyRelease>"
|
||||
LISTUPDATE_SEQUENCE = "<B1-ButtonRelease>"
|
||||
|
@ -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
|
||||
|
|
|
@ -408,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()
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>IDLE — Python 3.9.0a0 documentation</title>
|
||||
<title>IDLE — Python 3.9.0a1 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
|
@ -17,14 +17,14 @@
|
|||
<script type="text/javascript" src="../_static/sidebar.js"></script>
|
||||
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
title="Search within Python 3.9.0a0 documentation"
|
||||
title="Search within Python 3.9.0a1 documentation"
|
||||
href="../_static/opensearch.xml"/>
|
||||
<link rel="author" title="About these documents" href="../about.html" />
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="copyright" title="Copyright" href="../copyright.html" />
|
||||
<link rel="next" title="Other Graphical User Interface Packages" href="othergui.html" />
|
||||
<link rel="prev" title="tkinter.scrolledtext — Scrolled Text Widget" href="tkinter.scrolledtext.html" />
|
||||
<link rel="prev" title="tkinter.tix — Extension widgets for Tk" href="tkinter.tix.html" />
|
||||
<link rel="canonical" href="https://docs.python.org/3/library/idle.html" />
|
||||
|
||||
|
||||
|
@ -62,7 +62,7 @@
|
|||
<a href="othergui.html" title="Other Graphical User Interface Packages"
|
||||
accesskey="N">next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="tkinter.scrolledtext.html" title="tkinter.scrolledtext — Scrolled Text Widget"
|
||||
<a href="tkinter.tix.html" title="tkinter.tix — Extension widgets for Tk"
|
||||
accesskey="P">previous</a> |</li>
|
||||
|
||||
<li><img src="../_static/py.png" alt=""
|
||||
|
@ -71,7 +71,7 @@
|
|||
|
||||
|
||||
<li>
|
||||
<a href="../index.html">3.9.0a0 Documentation</a> »
|
||||
<a href="../index.html">3.9.0a1 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" >The Python Standard Library</a> »</li>
|
||||
|
@ -240,7 +240,8 @@ paragraph will be formatted to less than N columns, where N defaults to 72.</p>
|
|||
</dd>
|
||||
<dt>Strip trailing whitespace</dt><dd><p>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.</p>
|
||||
including lines within multiline strings. Except for Shell windows,
|
||||
remove extra newlines at the end of the file.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
@ -886,8 +887,8 @@ also used for testing.</p>
|
|||
</ul>
|
||||
|
||||
<h4>Previous topic</h4>
|
||||
<p class="topless"><a href="tkinter.scrolledtext.html"
|
||||
title="previous chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">tkinter.scrolledtext</span></code> — Scrolled Text Widget</a></p>
|
||||
<p class="topless"><a href="tkinter.tix.html"
|
||||
title="previous chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">tkinter.tix</span></code> — Extension widgets for Tk</a></p>
|
||||
<h4>Next topic</h4>
|
||||
<p class="topless"><a href="othergui.html"
|
||||
title="next chapter">Other Graphical User Interface Packages</a></p>
|
||||
|
@ -919,7 +920,7 @@ also used for testing.</p>
|
|||
<a href="othergui.html" title="Other Graphical User Interface Packages"
|
||||
>next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="tkinter.scrolledtext.html" title="tkinter.scrolledtext — Scrolled Text Widget"
|
||||
<a href="tkinter.tix.html" title="tkinter.tix — Extension widgets for Tk"
|
||||
>previous</a> |</li>
|
||||
|
||||
<li><img src="../_static/py.png" alt=""
|
||||
|
@ -928,7 +929,7 @@ also used for testing.</p>
|
|||
|
||||
|
||||
<li>
|
||||
<a href="../index.html">3.9.0a0 Documentation</a> »
|
||||
<a href="../index.html">3.9.0a1 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" >The Python Standard Library</a> »</li>
|
||||
|
@ -959,11 +960,11 @@ also used for testing.</p>
|
|||
<br />
|
||||
<br />
|
||||
|
||||
Last updated on Sep 01, 2019.
|
||||
Last updated on Nov 24, 2019.
|
||||
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
|
||||
<br />
|
||||
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.1.2.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.1.1.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -611,37 +611,33 @@ class IndentsTest(unittest.TestCase):
|
|||
|
||||
class RstripTest(unittest.TestCase):
|
||||
|
||||
def test_rstrip_line(self):
|
||||
editor = MockEditor()
|
||||
text = editor.text
|
||||
do_rstrip = ft.Rstrip(editor).do_rstrip
|
||||
eq = self.assertEqual
|
||||
@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
|
||||
|
||||
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')
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
del cls.text, cls.do_rstrip, cls.editor
|
||||
cls.root.update_idletasks()
|
||||
cls.root.destroy()
|
||||
del cls.root
|
||||
|
||||
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
|
||||
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"
|
||||
|
@ -649,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__':
|
||||
|
|
|
@ -272,6 +272,8 @@ _code_type = type(_write_atomic.__code__)
|
|||
# only args in ast.arguments #37593)
|
||||
# Python 3.8b4 3413 (Fix "break" and "continue" in "finally" #37830)
|
||||
# Python 3.9a0 3420 (add LOAD_ASSERTION_ERROR #34880)
|
||||
# Python 3.9a0 3421 (simplified bytecode for with blocks #32949)
|
||||
# Python 3.9a0 3422 (remove BEGIN_FINALLY, END_FINALLY, CALL_FINALLY, POP_FINALLY bytecodes #33387)
|
||||
#
|
||||
# MAGIC must change whenever the bytecode emitted by the compiler may no
|
||||
# longer be understood by older implementations of the eval loop (usually
|
||||
|
@ -280,7 +282,7 @@ _code_type = type(_write_atomic.__code__)
|
|||
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
|
||||
# in PC/launcher.c must also be updated.
|
||||
|
||||
MAGIC_NUMBER = (3420).to_bytes(2, 'little') + b'\r\n'
|
||||
MAGIC_NUMBER = (3422).to_bytes(2, 'little') + b'\r\n'
|
||||
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
|
||||
|
||||
_PYCACHE = '__pycache__'
|
||||
|
|
|
@ -1136,7 +1136,6 @@ def getfullargspec(func):
|
|||
varkw = None
|
||||
posonlyargs = []
|
||||
kwonlyargs = []
|
||||
defaults = ()
|
||||
annotations = {}
|
||||
defaults = ()
|
||||
kwdefaults = {}
|
||||
|
|
|
@ -20,30 +20,52 @@ 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',
|
||||
default=sys.stdin)
|
||||
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',
|
||||
default=sys.stdout)
|
||||
parser.add_argument('--sort-keys', action='store_true', default=False,
|
||||
help='sort the output of dictionaries alphabetically by key')
|
||||
parser.add_argument('--no-ensure-ascii', dest='ensure_ascii', action='store_false',
|
||||
help='disable escaping of non-ASCII characters')
|
||||
parser.add_argument('--json-lines', action='store_true', default=False,
|
||||
help='parse input using the jsonlines format')
|
||||
help='parse input using the JSON Lines format. '
|
||||
'Use with --no-indent or --compact to produce valid JSON Lines output.')
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument('--indent', default=4, type=int,
|
||||
help='separate items with newlines and use this number '
|
||||
'of spaces for indentation')
|
||||
group.add_argument('--tab', action='store_const', dest='indent',
|
||||
const='\t', help='separate items with newlines and use '
|
||||
'tabs for indentation')
|
||||
group.add_argument('--no-indent', action='store_const', dest='indent',
|
||||
const=None,
|
||||
help='separate items with spaces rather than newlines')
|
||||
group.add_argument('--compact', action='store_true',
|
||||
help='suppress all whitespace separation (most compact)')
|
||||
options = parser.parse_args()
|
||||
|
||||
infile = options.infile
|
||||
outfile = options.outfile
|
||||
sort_keys = options.sort_keys
|
||||
json_lines = options.json_lines
|
||||
with infile, outfile:
|
||||
dump_args = {
|
||||
'sort_keys': options.sort_keys,
|
||||
'indent': options.indent,
|
||||
'ensure_ascii': options.ensure_ascii,
|
||||
}
|
||||
if options.compact:
|
||||
dump_args['indent'] = None
|
||||
dump_args['separators'] = ',', ':'
|
||||
|
||||
with options.infile as infile, options.outfile as outfile:
|
||||
try:
|
||||
if json_lines:
|
||||
if options.json_lines:
|
||||
objs = (json.loads(line) for line in infile)
|
||||
else:
|
||||
objs = (json.load(infile), )
|
||||
for obj in objs:
|
||||
json.dump(obj, outfile, sort_keys=sort_keys, indent=4)
|
||||
json.dump(obj, outfile, **dump_args)
|
||||
outfile.write('\n')
|
||||
except ValueError as e:
|
||||
raise SystemExit(e)
|
||||
|
|
|
@ -84,10 +84,12 @@ def_op('BINARY_TRUE_DIVIDE', 27)
|
|||
def_op('INPLACE_FLOOR_DIVIDE', 28)
|
||||
def_op('INPLACE_TRUE_DIVIDE', 29)
|
||||
|
||||
def_op('RERAISE', 48)
|
||||
def_op('WITH_EXCEPT_START', 49)
|
||||
def_op('GET_AITER', 50)
|
||||
def_op('GET_ANEXT', 51)
|
||||
def_op('BEFORE_ASYNC_WITH', 52)
|
||||
def_op('BEGIN_FINALLY', 53)
|
||||
|
||||
def_op('END_ASYNC_FOR', 54)
|
||||
def_op('INPLACE_ADD', 55)
|
||||
def_op('INPLACE_SUBTRACT', 56)
|
||||
|
@ -115,14 +117,13 @@ def_op('INPLACE_RSHIFT', 76)
|
|||
def_op('INPLACE_AND', 77)
|
||||
def_op('INPLACE_XOR', 78)
|
||||
def_op('INPLACE_OR', 79)
|
||||
def_op('WITH_CLEANUP_START', 81)
|
||||
def_op('WITH_CLEANUP_FINISH', 82)
|
||||
|
||||
def_op('RETURN_VALUE', 83)
|
||||
def_op('IMPORT_STAR', 84)
|
||||
def_op('SETUP_ANNOTATIONS', 85)
|
||||
def_op('YIELD_VALUE', 86)
|
||||
def_op('POP_BLOCK', 87)
|
||||
def_op('END_FINALLY', 88)
|
||||
|
||||
def_op('POP_EXCEPT', 89)
|
||||
|
||||
HAVE_ARGUMENT = 90 # Opcodes from here have an argument:
|
||||
|
@ -210,7 +211,5 @@ def_op('BUILD_TUPLE_UNPACK_WITH_CALL', 158)
|
|||
|
||||
name_op('LOAD_METHOD', 160)
|
||||
def_op('CALL_METHOD', 161)
|
||||
jrel_op('CALL_FINALLY', 162)
|
||||
def_op('POP_FINALLY', 163)
|
||||
|
||||
del def_op, name_op, jrel_op, jabs_op
|
||||
|
|
|
@ -1072,6 +1072,9 @@ class PathLike(abc.ABC):
|
|||
def __subclasshook__(cls, subclass):
|
||||
return hasattr(subclass, '__fspath__')
|
||||
|
||||
def __class_getitem__(cls, type):
|
||||
return cls
|
||||
|
||||
|
||||
if name == 'nt':
|
||||
class _AddedDllDirectory:
|
||||
|
|
|
@ -777,6 +777,9 @@ class PurePath(object):
|
|||
return NotImplemented
|
||||
return self._cparts >= other._cparts
|
||||
|
||||
def __class_getitem__(cls, type):
|
||||
return cls
|
||||
|
||||
drive = property(attrgetter('_drv'),
|
||||
doc="""The drive prefix (letter or UNC path), if any.""")
|
||||
|
||||
|
|
|
@ -1604,17 +1604,29 @@ class _Unpickler:
|
|||
|
||||
def load_get(self):
|
||||
i = int(self.readline()[:-1])
|
||||
try:
|
||||
self.append(self.memo[i])
|
||||
except KeyError:
|
||||
msg = f'Memo value not found at index {i}'
|
||||
raise UnpicklingError(msg) from None
|
||||
dispatch[GET[0]] = load_get
|
||||
|
||||
def load_binget(self):
|
||||
i = self.read(1)[0]
|
||||
try:
|
||||
self.append(self.memo[i])
|
||||
except KeyError as exc:
|
||||
msg = f'Memo value not found at index {i}'
|
||||
raise UnpicklingError(msg) from None
|
||||
dispatch[BINGET[0]] = load_binget
|
||||
|
||||
def load_long_binget(self):
|
||||
i, = unpack('<I', self.read(4))
|
||||
try:
|
||||
self.append(self.memo[i])
|
||||
except KeyError as exc:
|
||||
msg = f'Memo value not found at index {i}'
|
||||
raise UnpicklingError(msg) from None
|
||||
dispatch[LONG_BINGET[0]] = load_long_binget
|
||||
|
||||
def load_put(self):
|
||||
|
|
|
@ -413,8 +413,10 @@ class Random(_random.Random):
|
|||
raise TypeError('Cannot specify both weights and cumulative weights')
|
||||
if len(cum_weights) != n:
|
||||
raise ValueError('The number of weights does not match the population')
|
||||
bisect = _bisect
|
||||
total = cum_weights[-1] + 0.0 # convert to float
|
||||
if total <= 0.0:
|
||||
raise ValueError('Total of weights must be greater than zero')
|
||||
bisect = _bisect
|
||||
hi = n - 1
|
||||
return [population[bisect(cum_weights, random() * total, 0, hi)]
|
||||
for i in _repeat(None, k)]
|
||||
|
|
|
@ -442,7 +442,7 @@ def ignore_patterns(*patterns):
|
|||
def _copytree(entries, src, dst, symlinks, ignore, copy_function,
|
||||
ignore_dangling_symlinks, dirs_exist_ok=False):
|
||||
if ignore is not None:
|
||||
ignored_names = ignore(src, set(os.listdir(src)))
|
||||
ignored_names = ignore(src, {x.name for x in entries})
|
||||
else:
|
||||
ignored_names = set()
|
||||
|
||||
|
@ -543,7 +543,8 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2,
|
|||
|
||||
"""
|
||||
sys.audit("shutil.copytree", src, dst)
|
||||
with os.scandir(src) as entries:
|
||||
with os.scandir(src) as itr:
|
||||
entries = list(itr)
|
||||
return _copytree(entries=entries, src=src, dst=dst, symlinks=symlinks,
|
||||
ignore=ignore, copy_function=copy_function,
|
||||
ignore_dangling_symlinks=ignore_dangling_symlinks,
|
||||
|
|
|
@ -839,7 +839,11 @@ def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
|
|||
sock.close()
|
||||
|
||||
if err is not None:
|
||||
try:
|
||||
raise err
|
||||
finally:
|
||||
# Break explicitly a reference cycle
|
||||
err = None
|
||||
else:
|
||||
raise error("getaddrinfo returns an empty list")
|
||||
|
||||
|
|
|
@ -633,10 +633,9 @@ 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, errors=errors,
|
||||
newline=newline)
|
||||
self._max_size = max_size
|
||||
self._rolled = False
|
||||
self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering,
|
||||
|
@ -656,8 +655,12 @@ class SpooledTemporaryFile:
|
|||
newfile = self._file = TemporaryFile(**self._TemporaryFileArgs)
|
||||
del self._TemporaryFileArgs
|
||||
|
||||
pos = file.tell()
|
||||
if hasattr(newfile, 'buffer'):
|
||||
newfile.buffer.write(file.detach().getvalue())
|
||||
else:
|
||||
newfile.write(file.getvalue())
|
||||
newfile.seek(file.tell(), 0)
|
||||
newfile.seek(pos, 0)
|
||||
|
||||
self._rolled = True
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -263,13 +263,73 @@ def test_cantrace():
|
|||
|
||||
def test_mmap():
|
||||
import mmap
|
||||
|
||||
with TestHook() as hook:
|
||||
mmap.mmap(-1, 8)
|
||||
assertEqual(hook.seen[0][1][:2], (-1, 8))
|
||||
|
||||
|
||||
def test_excepthook():
|
||||
def excepthook(exc_type, exc_value, exc_tb):
|
||||
if exc_type is not RuntimeError:
|
||||
sys.__excepthook__(exc_type, exc_value, exc_tb)
|
||||
|
||||
def hook(event, args):
|
||||
if event == "sys.excepthook":
|
||||
if not isinstance(args[2], args[1]):
|
||||
raise TypeError(f"Expected isinstance({args[2]!r}, " f"{args[1]!r})")
|
||||
if args[0] != excepthook:
|
||||
raise ValueError(f"Expected {args[0]} == {excepthook}")
|
||||
print(event, repr(args[2]))
|
||||
|
||||
sys.addaudithook(hook)
|
||||
sys.excepthook = excepthook
|
||||
raise RuntimeError("fatal-error")
|
||||
|
||||
|
||||
def test_unraisablehook():
|
||||
from _testcapi import write_unraisable_exc
|
||||
|
||||
def unraisablehook(hookargs):
|
||||
pass
|
||||
|
||||
def hook(event, args):
|
||||
if event == "sys.unraisablehook":
|
||||
if args[0] != unraisablehook:
|
||||
raise ValueError(f"Expected {args[0]} == {unraisablehook}")
|
||||
print(event, repr(args[1].exc_value), args[1].err_msg)
|
||||
|
||||
sys.addaudithook(hook)
|
||||
sys.unraisablehook = unraisablehook
|
||||
write_unraisable_exc(RuntimeError("nonfatal-error"), "for audit hook test", None)
|
||||
|
||||
|
||||
def test_winreg():
|
||||
from winreg import OpenKey, EnumKey, CloseKey, HKEY_LOCAL_MACHINE
|
||||
|
||||
def hook(event, args):
|
||||
if not event.startswith("winreg."):
|
||||
return
|
||||
print(event, *args)
|
||||
|
||||
sys.addaudithook(hook)
|
||||
|
||||
k = OpenKey(HKEY_LOCAL_MACHINE, "Software")
|
||||
EnumKey(k, 0)
|
||||
try:
|
||||
EnumKey(k, 10000)
|
||||
except OSError:
|
||||
pass
|
||||
else:
|
||||
raise RuntimeError("Expected EnumKey(HKLM, 10000) to fail")
|
||||
|
||||
kv = k.Detach()
|
||||
CloseKey(kv)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from test.libregrtest.setup import suppress_msvcrt_asserts
|
||||
|
||||
suppress_msvcrt_asserts(False)
|
||||
|
||||
test = sys.argv[1]
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import dataclasses
|
||||
|
||||
|
||||
class Foo:
|
||||
pass
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Bar:
|
||||
foo: Foo
|
|
@ -1019,7 +1019,9 @@ class AbstractUnpickleTests(unittest.TestCase):
|
|||
self.assertEqual(self.loads(dumped), '\u20ac\x00')
|
||||
|
||||
def test_misc_get(self):
|
||||
self.check_unpickling_error(KeyError, b'g0\np0')
|
||||
self.check_unpickling_error(pickle.UnpicklingError, b'g0\np0')
|
||||
self.check_unpickling_error(pickle.UnpicklingError, b'jens:')
|
||||
self.check_unpickling_error(pickle.UnpicklingError, b'hens:')
|
||||
self.assert_is_copy([(100,), (100,)],
|
||||
self.loads(b'((Kdtp0\nh\x00l.))'))
|
||||
|
||||
|
|
|
@ -2512,16 +2512,6 @@ def swap_item(obj, item, new_val):
|
|||
if item in obj:
|
||||
del obj[item]
|
||||
|
||||
def strip_python_stderr(stderr):
|
||||
"""Strip the stderr of a Python process from potential debug output
|
||||
emitted by the interpreter.
|
||||
|
||||
This will typically be run on the result of the communicate() method
|
||||
of a subprocess.Popen object.
|
||||
"""
|
||||
stderr = re.sub(br"\[\d+ refs, \d+ blocks\]\r?\n?", b"", stderr).strip()
|
||||
return stderr
|
||||
|
||||
requires_type_collecting = unittest.skipIf(hasattr(sys, 'getcounts'),
|
||||
'types are immortal if COUNT_ALLOCS is defined')
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import py_compile
|
|||
import zipfile
|
||||
|
||||
from importlib.util import source_from_cache
|
||||
from test.support import make_legacy_pyc, strip_python_stderr
|
||||
from test.support import make_legacy_pyc
|
||||
|
||||
|
||||
# Cached result of the expensive test performed in the function below.
|
||||
|
@ -134,7 +134,6 @@ def run_python_until_end(*args, **env_vars):
|
|||
proc.kill()
|
||||
subprocess._cleanup()
|
||||
rc = proc.returncode
|
||||
err = strip_python_stderr(err)
|
||||
return _PythonRunResult(rc, out, err), cmd_line
|
||||
|
||||
def _assert_python(expected_success, /, *args, **env_vars):
|
||||
|
|
|
@ -30,7 +30,7 @@ def setUpModule():
|
|||
global candidate_locales
|
||||
# Issue #13441: Skip some locales (e.g. cs_CZ and hu_HU) on Solaris to
|
||||
# workaround a mbstowcs() bug. For example, on Solaris, the hu_HU locale uses
|
||||
# the locale encoding ISO-8859-2, the thousauds separator is b'\xA0' and it is
|
||||
# the locale encoding ISO-8859-2, the thousands separator is b'\xA0' and it is
|
||||
# decoded as U+30000020 (an invalid character) by mbstowcs().
|
||||
if sys.platform == 'sunos5':
|
||||
old_locale = locale.setlocale(locale.LC_ALL)
|
||||
|
|
|
@ -426,26 +426,6 @@ class BaseTest:
|
|||
b.fromlist(a.tolist())
|
||||
self.assertEqual(a, b)
|
||||
|
||||
def test_tofromstring(self):
|
||||
# Warnings not raised when arguments are incorrect as Argument Clinic
|
||||
# handles that before the warning can be raised.
|
||||
nb_warnings = 2
|
||||
with warnings.catch_warnings(record=True) as r:
|
||||
warnings.filterwarnings("always",
|
||||
message=r"(to|from)string\(\) is deprecated",
|
||||
category=DeprecationWarning)
|
||||
a = array.array(self.typecode, 2*self.example)
|
||||
b = array.array(self.typecode)
|
||||
self.assertRaises(TypeError, a.tostring, 42)
|
||||
self.assertRaises(TypeError, b.fromstring)
|
||||
self.assertRaises(TypeError, b.fromstring, 42)
|
||||
b.fromstring(a.tostring())
|
||||
self.assertEqual(a, b)
|
||||
if a.itemsize>1:
|
||||
self.assertRaises(ValueError, b.fromstring, "x")
|
||||
nb_warnings += 1
|
||||
self.assertEqual(len(r), nb_warnings)
|
||||
|
||||
def test_tofrombytes(self):
|
||||
a = array.array(self.typecode, 2*self.example)
|
||||
b = array.array(self.typecode)
|
||||
|
|
|
@ -1738,10 +1738,6 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
|
|||
MyDatagramProto, flags=1, sock=FakeSock())
|
||||
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)
|
||||
|
@ -1752,7 +1748,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(
|
||||
|
@ -1761,18 +1756,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(
|
||||
|
@ -1788,13 +1773,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:
|
||||
|
@ -1809,6 +1793,29 @@ 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):
|
||||
self.loop.run_until_complete(coro)
|
||||
|
||||
@patch_socket
|
||||
def test_create_datagram_endpoint_nosoreuseport(self, m_socket):
|
||||
del m_socket.SO_REUSEPORT
|
||||
|
|
|
@ -924,59 +924,6 @@ os.close(fd)
|
|||
wr.close()
|
||||
self.loop.run_until_complete(wr.wait_closed())
|
||||
|
||||
def test_del_stream_before_sock_closing(self):
|
||||
messages = []
|
||||
self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx))
|
||||
|
||||
with test_utils.run_test_server() as httpd:
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
rd, wr = self.loop.run_until_complete(
|
||||
asyncio.open_connection(*httpd.address, loop=self.loop))
|
||||
sock = wr.get_extra_info('socket')
|
||||
self.assertNotEqual(sock.fileno(), -1)
|
||||
|
||||
wr.write(b'GET / HTTP/1.0\r\n\r\n')
|
||||
f = rd.readline()
|
||||
data = self.loop.run_until_complete(f)
|
||||
self.assertEqual(data, b'HTTP/1.0 200 OK\r\n')
|
||||
|
||||
# drop refs to reader/writer
|
||||
del rd
|
||||
del wr
|
||||
gc.collect()
|
||||
# make a chance to close the socket
|
||||
test_utils.run_briefly(self.loop)
|
||||
|
||||
self.assertEqual(1, len(messages))
|
||||
self.assertEqual(sock.fileno(), -1)
|
||||
|
||||
self.assertEqual(1, len(messages))
|
||||
self.assertEqual('An open stream object is being garbage '
|
||||
'collected; call "stream.close()" explicitly.',
|
||||
messages[0]['message'])
|
||||
|
||||
def test_del_stream_before_connection_made(self):
|
||||
messages = []
|
||||
self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx))
|
||||
|
||||
with test_utils.run_test_server() as httpd:
|
||||
rd = asyncio.StreamReader(loop=self.loop)
|
||||
pr = asyncio.StreamReaderProtocol(rd, loop=self.loop)
|
||||
del rd
|
||||
gc.collect()
|
||||
tr, _ = self.loop.run_until_complete(
|
||||
self.loop.create_connection(
|
||||
lambda: pr, *httpd.address))
|
||||
|
||||
sock = tr.get_extra_info('socket')
|
||||
self.assertEqual(sock.fileno(), -1)
|
||||
|
||||
self.assertEqual(1, len(messages))
|
||||
self.assertEqual('An open stream was garbage collected prior to '
|
||||
'establishing network connection; '
|
||||
'call "stream.close()" explicitly.',
|
||||
messages[0]['message'])
|
||||
|
||||
def test_async_writer_api(self):
|
||||
async def inner(httpd):
|
||||
rd, wr = await asyncio.open_connection(*httpd.address)
|
||||
|
|
|
@ -24,7 +24,23 @@ class AuditTest(unittest.TestCase):
|
|||
sys.stdout.writelines(p.stdout)
|
||||
sys.stderr.writelines(p.stderr)
|
||||
if p.returncode:
|
||||
self.fail(''.join(p.stderr))
|
||||
self.fail("".join(p.stderr))
|
||||
|
||||
def run_python(self, *args):
|
||||
events = []
|
||||
with subprocess.Popen(
|
||||
[sys.executable, "-X utf8", AUDIT_TESTS_PY, *args],
|
||||
encoding="utf-8",
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
) as p:
|
||||
p.wait()
|
||||
sys.stderr.writelines(p.stderr)
|
||||
return (
|
||||
p.returncode,
|
||||
[line.strip().partition(" ") for line in p.stdout],
|
||||
"".join(p.stderr),
|
||||
)
|
||||
|
||||
def test_basic(self):
|
||||
self.do_test("test_basic")
|
||||
|
@ -36,19 +52,11 @@ class AuditTest(unittest.TestCase):
|
|||
self.do_test("test_block_add_hook_baseexception")
|
||||
|
||||
def test_finalize_hooks(self):
|
||||
events = []
|
||||
with subprocess.Popen(
|
||||
[sys.executable, "-X utf8", AUDIT_TESTS_PY, "test_finalize_hooks"],
|
||||
encoding="utf-8",
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
) as p:
|
||||
p.wait()
|
||||
for line in p.stdout:
|
||||
events.append(line.strip().partition(" "))
|
||||
sys.stderr.writelines(p.stderr)
|
||||
if p.returncode:
|
||||
self.fail(''.join(p.stderr))
|
||||
returncode, events, stderr = self.run_python("test_finalize_hooks")
|
||||
if stderr:
|
||||
print(stderr, file=sys.stderr)
|
||||
if returncode:
|
||||
self.fail(stderr)
|
||||
|
||||
firstId = events[0][2]
|
||||
self.assertSequenceEqual(
|
||||
|
@ -76,6 +84,40 @@ class AuditTest(unittest.TestCase):
|
|||
def test_mmap(self):
|
||||
self.do_test("test_mmap")
|
||||
|
||||
def test_excepthook(self):
|
||||
returncode, events, stderr = self.run_python("test_excepthook")
|
||||
if not returncode:
|
||||
self.fail(f"Expected fatal exception\n{stderr}")
|
||||
|
||||
self.assertSequenceEqual(
|
||||
[("sys.excepthook", " ", "RuntimeError('fatal-error')")], events
|
||||
)
|
||||
|
||||
def test_unraisablehook(self):
|
||||
returncode, events, stderr = self.run_python("test_unraisablehook")
|
||||
if returncode:
|
||||
self.fail(stderr)
|
||||
|
||||
self.assertEqual(events[0][0], "sys.unraisablehook")
|
||||
self.assertEqual(
|
||||
events[0][2],
|
||||
"RuntimeError('nonfatal-error') Exception ignored for audit hook test",
|
||||
)
|
||||
|
||||
def test_winreg(self):
|
||||
support.import_module("winreg")
|
||||
returncode, events, stderr = self.run_python("test_winreg")
|
||||
if returncode:
|
||||
self.fail(stderr)
|
||||
|
||||
self.assertEqual(events[0][0], "winreg.OpenKey")
|
||||
self.assertEqual(events[1][0], "winreg.OpenKey/result")
|
||||
expected = events[1][2]
|
||||
self.assertTrue(expected)
|
||||
self.assertSequenceEqual(["winreg.EnumKey", " ", f"{expected} 0"], events[2])
|
||||
self.assertSequenceEqual(["winreg.EnumKey", " ", f"{expected} 10000"], events[3])
|
||||
self.assertSequenceEqual(["winreg.PyHKEY.Detach", " ", expected], events[4])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -351,9 +351,11 @@ class CAPITest(unittest.TestCase):
|
|||
for i in range(1000):
|
||||
L = MyList((L,))
|
||||
|
||||
@support.requires_resource('cpu')
|
||||
def test_trashcan_python_class1(self):
|
||||
self.do_test_trashcan_python_class(list)
|
||||
|
||||
@support.requires_resource('cpu')
|
||||
def test_trashcan_python_class2(self):
|
||||
from _testcapi import MyList
|
||||
self.do_test_trashcan_python_class(MyList)
|
||||
|
|
|
@ -332,10 +332,10 @@ class CmdLineTest(unittest.TestCase):
|
|||
|
||||
if sys.platform == 'win32':
|
||||
self.assertEqual(b'1\r\n2\r\n', out)
|
||||
self.assertEqual(b'3\r\n4', err)
|
||||
self.assertEqual(b'3\r\n4\r\n', err)
|
||||
else:
|
||||
self.assertEqual(b'1\n2\n', out)
|
||||
self.assertEqual(b'3\n4', err)
|
||||
self.assertEqual(b'3\n4\n', err)
|
||||
|
||||
def test_unmached_quote(self):
|
||||
# Issue #10206: python program starting with unmatched quote
|
||||
|
@ -391,7 +391,7 @@ class CmdLineTest(unittest.TestCase):
|
|||
stderr=subprocess.PIPE,
|
||||
preexec_fn=preexec)
|
||||
out, err = p.communicate()
|
||||
self.assertEqual(support.strip_python_stderr(err), b'')
|
||||
self.assertEqual(err, b'')
|
||||
self.assertEqual(p.returncode, 42)
|
||||
|
||||
def test_no_stdin(self):
|
||||
|
|
|
@ -223,12 +223,13 @@ class CmdLineTest(unittest.TestCase):
|
|||
|
||||
def test_script_abspath(self):
|
||||
# pass the script using the relative path, expect the absolute path
|
||||
# in __file__ and sys.argv[0]
|
||||
# in __file__
|
||||
with support.temp_cwd() as script_dir:
|
||||
self.assertTrue(os.path.isabs(script_dir), script_dir)
|
||||
|
||||
script_name = _make_test_script(script_dir, 'script')
|
||||
self._check_script(os.path.basename(script_name), script_name, script_name,
|
||||
relative_name = os.path.basename(script_name)
|
||||
self._check_script(relative_name, script_name, relative_name,
|
||||
script_dir, None,
|
||||
importlib.machinery.SourceFileLoader)
|
||||
|
||||
|
@ -535,7 +536,7 @@ class CmdLineTest(unittest.TestCase):
|
|||
script_name = _make_test_script(script_dir, 'script', script)
|
||||
exitcode, stdout, stderr = assert_python_failure(script_name)
|
||||
text = stderr.decode('ascii').split('\n')
|
||||
self.assertEqual(len(text), 4)
|
||||
self.assertEqual(len(text), 5)
|
||||
self.assertTrue(text[0].startswith('Traceback'))
|
||||
self.assertTrue(text[1].startswith(' File '))
|
||||
self.assertTrue(text[3].startswith('NameError'))
|
||||
|
@ -579,7 +580,7 @@ class CmdLineTest(unittest.TestCase):
|
|||
script_name = _make_test_script(script_dir, 'script', script)
|
||||
exitcode, stdout, stderr = assert_python_failure(script_name)
|
||||
text = stderr.decode('ascii')
|
||||
self.assertEqual(text, "some text")
|
||||
self.assertEqual(text.rstrip(), "some text")
|
||||
|
||||
def test_syntaxerror_unindented_caret_position(self):
|
||||
script = "1 + 1 = 2\n"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -2983,6 +2984,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):
|
||||
|
|
|
@ -278,32 +278,34 @@ dis_traceback = """\
|
|||
--> 6 BINARY_TRUE_DIVIDE
|
||||
8 POP_TOP
|
||||
10 POP_BLOCK
|
||||
12 JUMP_FORWARD 40 (to 54)
|
||||
12 JUMP_FORWARD 44 (to 58)
|
||||
|
||||
%3d >> 14 DUP_TOP
|
||||
16 LOAD_GLOBAL 0 (Exception)
|
||||
18 COMPARE_OP 10 (exception match)
|
||||
20 POP_JUMP_IF_FALSE 52
|
||||
20 POP_JUMP_IF_FALSE 56
|
||||
22 POP_TOP
|
||||
24 STORE_FAST 0 (e)
|
||||
26 POP_TOP
|
||||
28 SETUP_FINALLY 10 (to 40)
|
||||
28 SETUP_FINALLY 18 (to 48)
|
||||
|
||||
%3d 30 LOAD_FAST 0 (e)
|
||||
32 LOAD_ATTR 1 (__traceback__)
|
||||
34 STORE_FAST 1 (tb)
|
||||
36 POP_BLOCK
|
||||
38 BEGIN_FINALLY
|
||||
>> 40 LOAD_CONST 0 (None)
|
||||
38 POP_EXCEPT
|
||||
40 LOAD_CONST 0 (None)
|
||||
42 STORE_FAST 0 (e)
|
||||
44 DELETE_FAST 0 (e)
|
||||
46 END_FINALLY
|
||||
48 POP_EXCEPT
|
||||
50 JUMP_FORWARD 2 (to 54)
|
||||
>> 52 END_FINALLY
|
||||
46 JUMP_FORWARD 10 (to 58)
|
||||
>> 48 LOAD_CONST 0 (None)
|
||||
50 STORE_FAST 0 (e)
|
||||
52 DELETE_FAST 0 (e)
|
||||
54 RERAISE
|
||||
>> 56 RERAISE
|
||||
|
||||
%3d >> 54 LOAD_FAST 1 (tb)
|
||||
56 RETURN_VALUE
|
||||
%3d >> 58 LOAD_FAST 1 (tb)
|
||||
60 RETURN_VALUE
|
||||
""" % (TRACEBACK_CODE.co_firstlineno + 1,
|
||||
TRACEBACK_CODE.co_firstlineno + 2,
|
||||
TRACEBACK_CODE.co_firstlineno + 3,
|
||||
|
@ -752,7 +754,7 @@ Argument count: 0
|
|||
Positional-only arguments: 0
|
||||
Kw-only arguments: 0
|
||||
Number of locals: 2
|
||||
Stack size: 10
|
||||
Stack size: 9
|
||||
Flags: OPTIMIZED, NEWLOCALS, NOFREE, COROUTINE
|
||||
Constants:
|
||||
0: None
|
||||
|
@ -977,10 +979,10 @@ expected_opinfo_jumpy = [
|
|||
Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=96, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=98, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=100, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='SETUP_FINALLY', opcode=122, arg=70, argval=174, argrepr='to 174', offset=102, starts_line=20, is_jump_target=True),
|
||||
Instruction(opname='SETUP_FINALLY', opcode=122, arg=98, argval=202, argrepr='to 202', offset=102, starts_line=20, is_jump_target=True),
|
||||
Instruction(opname='SETUP_FINALLY', opcode=122, arg=12, argval=118, argrepr='to 118', offset=104, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=106, starts_line=21, is_jump_target=False),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval=0, argrepr='0', offset=108, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=108, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='BINARY_TRUE_DIVIDE', opcode=27, arg=None, argval=None, argrepr='', offset=110, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=112, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=114, starts_line=None, is_jump_target=False),
|
||||
|
@ -993,33 +995,47 @@ expected_opinfo_jumpy = [
|
|||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=128, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=130, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=132, starts_line=23, is_jump_target=False),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=134, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=134, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=136, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=138, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=140, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='JUMP_FORWARD', opcode=110, arg=26, argval=170, argrepr='to 170', offset=142, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=144, starts_line=None, is_jump_target=True),
|
||||
Instruction(opname='JUMP_FORWARD', opcode=110, arg=46, argval=190, argrepr='to 190', offset=142, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='RERAISE', opcode=48, arg=None, argval=None, argrepr='', offset=144, starts_line=None, is_jump_target=True),
|
||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=146, starts_line=25, is_jump_target=True),
|
||||
Instruction(opname='SETUP_WITH', opcode=143, arg=14, argval=164, argrepr='to 164', offset=148, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='SETUP_WITH', opcode=143, arg=24, argval=174, argrepr='to 174', offset=148, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=150, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=152, starts_line=26, is_jump_target=False),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval='Never reach this', argrepr="'Never reach this'", offset=154, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Never reach this', argrepr="'Never reach this'", offset=154, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=156, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=158, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=160, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='BEGIN_FINALLY', opcode=53, arg=None, argval=None, argrepr='', offset=162, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='WITH_CLEANUP_START', opcode=81, arg=None, argval=None, argrepr='', offset=164, starts_line=None, is_jump_target=True),
|
||||
Instruction(opname='WITH_CLEANUP_FINISH', opcode=82, arg=None, argval=None, argrepr='', offset=166, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=168, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=170, starts_line=None, is_jump_target=True),
|
||||
Instruction(opname='BEGIN_FINALLY', opcode=53, arg=None, argval=None, argrepr='', offset=172, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=174, starts_line=28, is_jump_target=True),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=176, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=178, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=180, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=182, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=184, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=186, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=162, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=164, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=166, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=3, argval=3, argrepr='', offset=168, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=170, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='JUMP_FORWARD', opcode=110, arg=16, argval=190, argrepr='to 190', offset=172, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=174, starts_line=None, is_jump_target=True),
|
||||
Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=180, argval=180, argrepr='', offset=176, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='RERAISE', opcode=48, arg=None, argval=None, argrepr='', offset=178, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=180, starts_line=None, is_jump_target=True),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=182, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=184, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=186, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=188, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=190, starts_line=None, is_jump_target=True),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=192, starts_line=28, is_jump_target=False),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=194, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=196, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=198, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='JUMP_FORWARD', opcode=110, arg=10, argval=212, argrepr='to 212', offset=200, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=202, starts_line=None, is_jump_target=True),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=204, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=206, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=208, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='RERAISE', opcode=48, arg=None, argval=None, argrepr='', offset=210, starts_line=None, is_jump_target=False),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=212, starts_line=None, is_jump_target=True),
|
||||
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=214, starts_line=None, is_jump_target=False)
|
||||
]
|
||||
|
||||
# One last piece of inspect fodder to check the default line number handling
|
||||
|
@ -1032,6 +1048,10 @@ expected_opinfo_simple = [
|
|||
|
||||
class InstructionTests(BytecodeTestCase):
|
||||
|
||||
def __init__(self, *args):
|
||||
super().__init__(*args)
|
||||
self.maxDiff = None
|
||||
|
||||
def test_default_first_line(self):
|
||||
actual = dis.get_instructions(simple)
|
||||
self.assertEqual(list(actual), expected_opinfo_simple)
|
||||
|
@ -1063,6 +1083,7 @@ class InstructionTests(BytecodeTestCase):
|
|||
# get_instructions has its own tests above, so can rely on it to validate
|
||||
# the object oriented API
|
||||
class BytecodeTests(unittest.TestCase):
|
||||
|
||||
def test_instantiation(self):
|
||||
# Test with function, method, code string and code object
|
||||
for obj in [_f, _C(1).__init__, "a=1", _f.__code__]:
|
||||
|
|
|
@ -2583,6 +2583,11 @@ class TestParser(TestParserMixin, TestEmailBase):
|
|||
|
||||
# get_msg_id
|
||||
|
||||
def test_get_msg_id_empty(self):
|
||||
# bpo-38708: Test that HeaderParseError is raised and not IndexError.
|
||||
with self.assertRaises(errors.HeaderParseError):
|
||||
parser.get_msg_id('')
|
||||
|
||||
def test_get_msg_id_valid(self):
|
||||
msg_id = self._test_get_x(
|
||||
parser.get_msg_id,
|
||||
|
@ -2638,6 +2643,46 @@ class TestParser(TestParserMixin, TestEmailBase):
|
|||
)
|
||||
self.assertEqual(msg_id.token_type, 'msg-id')
|
||||
|
||||
def test_get_msg_id_invalid_expected_msg_id_not_found(self):
|
||||
text = "935-XPB-567:0:45327:9:90305:17843586-40@example.com"
|
||||
msg_id = parser.parse_message_id(text)
|
||||
self.assertDefectsEqual(
|
||||
msg_id.all_defects,
|
||||
[errors.InvalidHeaderDefect])
|
||||
|
||||
def test_parse_invalid_message_id(self):
|
||||
message_id = self._test_parse_x(
|
||||
parser.parse_message_id,
|
||||
"935-XPB-567:0:45327:9:90305:17843586-40@example.com",
|
||||
"935-XPB-567:0:45327:9:90305:17843586-40@example.com",
|
||||
"935-XPB-567:0:45327:9:90305:17843586-40@example.com",
|
||||
[errors.InvalidHeaderDefect],
|
||||
)
|
||||
self.assertEqual(message_id.token_type, 'invalid-message-id')
|
||||
|
||||
def test_parse_valid_message_id(self):
|
||||
message_id = self._test_parse_x(
|
||||
parser.parse_message_id,
|
||||
"<aperson@somedomain>",
|
||||
"<aperson@somedomain>",
|
||||
"<aperson@somedomain>",
|
||||
[],
|
||||
)
|
||||
self.assertEqual(message_id.token_type, 'message-id')
|
||||
|
||||
def test_parse_message_id_with_remaining(self):
|
||||
message_id = self._test_parse_x(
|
||||
parser.parse_message_id,
|
||||
"<validmessageid@example>thensomething",
|
||||
"<validmessageid@example>",
|
||||
"<validmessageid@example>",
|
||||
[errors.InvalidHeaderDefect],
|
||||
[],
|
||||
)
|
||||
self.assertEqual(message_id.token_type, 'message-id')
|
||||
self.assertEqual(str(message_id.all_defects[0]),
|
||||
"Unexpected 'thensomething'")
|
||||
|
||||
def test_get_msg_id_no_angle_start(self):
|
||||
with self.assertRaises(errors.HeaderParseError):
|
||||
parser.get_msg_id("msgwithnoankle")
|
||||
|
@ -2654,6 +2699,7 @@ class TestParser(TestParserMixin, TestEmailBase):
|
|||
self.assertEqual(msg_id.token_type, 'msg-id')
|
||||
|
||||
|
||||
|
||||
@parameterize
|
||||
class Test_parse_mime_parameters(TestParserMixin, TestEmailBase):
|
||||
|
||||
|
|
|
@ -858,10 +858,9 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
preconfig = {
|
||||
'allocator': PYMEM_ALLOCATOR_DEBUG,
|
||||
}
|
||||
script_abspath = os.path.abspath('script.py')
|
||||
config = {
|
||||
'argv': [script_abspath],
|
||||
'run_filename': script_abspath,
|
||||
'argv': ['script.py'],
|
||||
'run_filename': os.path.abspath('script.py'),
|
||||
'dev_mode': 1,
|
||||
'faulthandler': 1,
|
||||
'warnoptions': ['default'],
|
||||
|
|
|
@ -71,9 +71,8 @@ class FaultHandlerTests(unittest.TestCase):
|
|||
with support.SuppressCrashReport():
|
||||
process = script_helper.spawn_python('-c', code, pass_fds=pass_fds)
|
||||
with process:
|
||||
stdout, stderr = process.communicate()
|
||||
output, stderr = process.communicate()
|
||||
exitcode = process.wait()
|
||||
output = support.strip_python_stderr(stdout)
|
||||
output = output.decode('ascii', 'backslashreplace')
|
||||
if filename:
|
||||
self.assertEqual(output, '')
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue