.. c:function:: int PyBool_Check(PyObject *o)
- Return true if *o* is of type :c:data:`PyBool_Type`.
+ Return true if *o* is of type :c:data:`PyBool_Type`. This function always
+ succeeds.
.. c:var:: PyObject* Py_False
.. c:function:: int PyByteArray_Check(PyObject *o)
Return true if the object *o* is a bytearray object or an instance of a
- subtype of the bytearray type.
+ subtype of the bytearray type. This function always succeeds.
.. c:function:: int PyByteArray_CheckExact(PyObject *o)
Return true if the object *o* is a bytearray object, but not an instance of a
- subtype of the bytearray type.
+ subtype of the bytearray type. This function always succeeds.
Direct API functions
.. c:function:: int PyBytes_Check(PyObject *o)
Return true if the object *o* is a bytes object or an instance of a subtype
- of the bytes type.
+ of the bytes type. This function always succeeds.
.. c:function:: int PyBytes_CheckExact(PyObject *o)
Return true if the object *o* is a bytes object, but not an instance of a
- subtype of the bytes type.
+ subtype of the bytes type. This function always succeeds.
.. c:function:: PyObject* PyBytes_FromString(const char *v)
.. c:function:: int PyCapsule_CheckExact(PyObject *p)
- Return true if its argument is a :c:type:`PyCapsule`.
+ Return true if its argument is a :c:type:`PyCapsule`. This function always
+ succeeds.
.. c:function:: PyObject* PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
.. c:function:: int PyCell_Check(ob)
- Return true if *ob* is a cell object; *ob* must not be ``NULL``.
+ Return true if *ob* is a cell object; *ob* must not be ``NULL``. This
+ function always succeeds.
.. c:function:: PyObject* PyCell_New(PyObject *ob)
.. c:function:: int PyCode_Check(PyObject *co)
- Return true if *co* is a :class:`code` object.
+ Return true if *co* is a :class:`code` object. This function always succeeds.
.. c:function:: int PyCode_GetNumFree(PyCodeObject *co)
.. c:function:: int PyComplex_Check(PyObject *p)
Return true if its argument is a :c:type:`PyComplexObject` or a subtype of
- :c:type:`PyComplexObject`.
+ :c:type:`PyComplexObject`. This function always succeeds.
.. c:function:: int PyComplex_CheckExact(PyObject *p)
Return true if its argument is a :c:type:`PyComplexObject`, but not a subtype of
- :c:type:`PyComplexObject`.
+ :c:type:`PyComplexObject`. This function always succeeds.
.. c:function:: PyObject* PyComplex_FromCComplex(Py_complex v)
.. c:function:: int PyOS_snprintf(char *str, size_t size, const char *format, ...)
Output not more than *size* bytes to *str* according to the format string
- *format* and the extra arguments. See the Unix man page :manpage:`snprintf(2)`.
+ *format* and the extra arguments. See the Unix man page :manpage:`snprintf(3)`.
.. c:function:: int PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
Output not more than *size* bytes to *str* according to the format string
*format* and the variable argument list *va*. Unix man page
- :manpage:`vsnprintf(2)`.
+ :manpage:`vsnprintf(3)`.
:c:func:`PyOS_snprintf` and :c:func:`PyOS_vsnprintf` wrap the Standard C library
functions :c:func:`snprintf` and :c:func:`vsnprintf`. Their purpose is to
.. c:function:: int PyCoro_CheckExact(PyObject *ob)
Return true if *ob*'s type is :c:type:`PyCoro_Type`; *ob* must not be ``NULL``.
+ This function always succeeds.
.. c:function:: PyObject* PyCoro_New(PyFrameObject *frame, PyObject *name, PyObject *qualname)
.. c:function:: int PyDate_Check(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DateType` or a subtype of
- :c:data:`PyDateTime_DateType`. *ob* must not be ``NULL``.
+ :c:data:`PyDateTime_DateType`. *ob* must not be ``NULL``. This function always
+ succeeds.
.. c:function:: int PyDate_CheckExact(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DateType`. *ob* must not be
- ``NULL``.
+ ``NULL``. This function always succeeds.
.. c:function:: int PyDateTime_Check(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DateTimeType` or a subtype of
- :c:data:`PyDateTime_DateTimeType`. *ob* must not be ``NULL``.
+ :c:data:`PyDateTime_DateTimeType`. *ob* must not be ``NULL``. This function always
+ succeeds.
.. c:function:: int PyDateTime_CheckExact(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DateTimeType`. *ob* must not
- be ``NULL``.
+ be ``NULL``. This function always succeeds.
.. c:function:: int PyTime_Check(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_TimeType` or a subtype of
- :c:data:`PyDateTime_TimeType`. *ob* must not be ``NULL``.
+ :c:data:`PyDateTime_TimeType`. *ob* must not be ``NULL``. This function always
+ succeeds.
.. c:function:: int PyTime_CheckExact(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_TimeType`. *ob* must not be
- ``NULL``.
+ ``NULL``. This function always succeeds.
.. c:function:: int PyDelta_Check(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DeltaType` or a subtype of
- :c:data:`PyDateTime_DeltaType`. *ob* must not be ``NULL``.
+ :c:data:`PyDateTime_DeltaType`. *ob* must not be ``NULL``. This function always
+ succeeds.
.. c:function:: int PyDelta_CheckExact(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DeltaType`. *ob* must not be
- ``NULL``.
+ ``NULL``. This function always succeeds.
.. c:function:: int PyTZInfo_Check(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_TZInfoType` or a subtype of
- :c:data:`PyDateTime_TZInfoType`. *ob* must not be ``NULL``.
+ :c:data:`PyDateTime_TZInfoType`. *ob* must not be ``NULL``. This function always
+ succeeds.
.. c:function:: int PyTZInfo_CheckExact(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_TZInfoType`. *ob* must not be
- ``NULL``.
+ ``NULL``. This function always succeeds.
Macros to create objects:
.. c:function:: int PyDict_Check(PyObject *p)
Return true if *p* is a dict object or an instance of a subtype of the dict
- type.
+ type. This function always succeeds.
.. c:function:: int PyDict_CheckExact(PyObject *p)
Return true if *p* is a dict object, but not an instance of a subtype of
- the dict type.
+ the dict type. This function always succeeds.
.. c:function:: PyObject* PyDict_New()
.. c:function:: int PyFloat_Check(PyObject *p)
Return true if its argument is a :c:type:`PyFloatObject` or a subtype of
- :c:type:`PyFloatObject`.
+ :c:type:`PyFloatObject`. This function always succeeds.
.. c:function:: int PyFloat_CheckExact(PyObject *p)
Return true if its argument is a :c:type:`PyFloatObject`, but not a subtype of
- :c:type:`PyFloatObject`.
+ :c:type:`PyFloatObject`. This function always succeeds.
.. c:function:: PyObject* PyFloat_FromString(PyObject *str)
.. c:function:: int PyFunction_Check(PyObject *o)
Return true if *o* is a function object (has type :c:data:`PyFunction_Type`).
- The parameter must not be ``NULL``.
+ The parameter must not be ``NULL``. This function always succeeds.
.. c:function:: PyObject* PyFunction_New(PyObject *code, PyObject *globals)
.. c:function:: int PyGen_Check(PyObject *ob)
- Return true if *ob* is a generator object; *ob* must not be ``NULL``.
+ Return true if *ob* is a generator object; *ob* must not be ``NULL``. This
+ function always succeeds.
.. c:function:: int PyGen_CheckExact(PyObject *ob)
- Return true if *ob*'s type is :c:type:`PyGen_Type`; *ob* must not be ``NULL``.
+ Return true if *ob*'s type is :c:type:`PyGen_Type`; *ob* must not be
+ ``NULL``. This function always succeeds.
.. c:function:: PyObject* PyGen_New(PyFrameObject *frame)
.. versionadded:: 3.9
-.. c:function:: void _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp, _PyFrameEvalFunction eval_frame);
+.. c:function:: void _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp, _PyFrameEvalFunction eval_frame)
Set the frame evaluation function.
.. c:function:: int PyIter_Check(PyObject *o)
- Return true if the object *o* supports the iterator protocol.
+ Return true if the object *o* supports the iterator protocol. This
+ function always succeeds.
.. c:function:: PyObject* PyIter_Next(PyObject *o)
.. c:function:: int PySeqIter_Check(op)
- Return true if the type of *op* is :c:data:`PySeqIter_Type`.
+ Return true if the type of *op* is :c:data:`PySeqIter_Type`. This function
+ always succeeds.
.. c:function:: PyObject* PySeqIter_New(PyObject *seq)
.. c:function:: int PyCallIter_Check(op)
- Return true if the type of *op* is :c:data:`PyCallIter_Type`.
+ Return true if the type of *op* is :c:data:`PyCallIter_Type`. This
+ function always succeeds.
.. c:function:: PyObject* PyCallIter_New(PyObject *callable, PyObject *sentinel)
.. c:function:: int PyList_Check(PyObject *p)
Return true if *p* is a list object or an instance of a subtype of the list
- type.
+ type. This function always succeeds.
.. c:function:: int PyList_CheckExact(PyObject *p)
Return true if *p* is a list object, but not an instance of a subtype of
- the list type.
+ the list type. This function always succeeds.
.. c:function:: PyObject* PyList_New(Py_ssize_t len)
.. c:function:: int PyLong_Check(PyObject *p)
Return true if its argument is a :c:type:`PyLongObject` or a subtype of
- :c:type:`PyLongObject`.
+ :c:type:`PyLongObject`. This function always succeeds.
.. c:function:: int PyLong_CheckExact(PyObject *p)
Return true if its argument is a :c:type:`PyLongObject`, but not a subtype of
- :c:type:`PyLongObject`.
+ :c:type:`PyLongObject`. This function always succeeds.
.. c:function:: PyObject* PyLong_FromLong(long v)
.. c:function:: int PyMemoryView_Check(PyObject *obj)
Return true if the object *obj* is a memoryview object. It is not
- currently allowed to create subclasses of :class:`memoryview`.
+ currently allowed to create subclasses of :class:`memoryview`. This
+ function always succeeds.
.. c:function:: Py_buffer *PyMemoryView_GET_BUFFER(PyObject *mview)
Return true if *o* is an instance method object (has type
:c:data:`PyInstanceMethod_Type`). The parameter must not be ``NULL``.
+ This function always succeeds.
.. c:function:: PyObject* PyInstanceMethod_New(PyObject *func)
.. c:function:: int PyMethod_Check(PyObject *o)
Return true if *o* is a method object (has type :c:data:`PyMethod_Type`). The
- parameter must not be ``NULL``.
+ parameter must not be ``NULL``. This function always succeeds.
.. c:function:: PyObject* PyMethod_New(PyObject *func, PyObject *self)
.. c:function:: int PyModule_Check(PyObject *p)
Return true if *p* is a module object, or a subtype of a module object.
+ This function always succeeds.
.. c:function:: int PyModule_CheckExact(PyObject *p)
Return true if *p* is a module object, but not a subtype of
- :c:data:`PyModule_Type`.
+ :c:data:`PyModule_Type`. This function always succeeds.
.. c:function:: PyObject* PyModule_NewObject(PyObject *name)
.. c:function:: int PySet_Check(PyObject *p)
Return true if *p* is a :class:`set` object or an instance of a subtype.
+ This function always succeeds.
.. c:function:: int PyFrozenSet_Check(PyObject *p)
Return true if *p* is a :class:`frozenset` object or an instance of a
- subtype.
+ subtype. This function always succeeds.
.. c:function:: int PyAnySet_Check(PyObject *p)
Return true if *p* is a :class:`set` object, a :class:`frozenset` object, or an
- instance of a subtype.
+ instance of a subtype. This function always succeeds.
.. c:function:: int PyAnySet_CheckExact(PyObject *p)
Return true if *p* is a :class:`set` object or a :class:`frozenset` object but
- not an instance of a subtype.
+ not an instance of a subtype. This function always succeeds.
.. c:function:: int PyFrozenSet_CheckExact(PyObject *p)
Return true if *p* is a :class:`frozenset` object but not an instance of a
- subtype.
+ subtype. This function always succeeds.
.. c:function:: PyObject* PySet_New(PyObject *iterable)
.. c:function:: int PySlice_Check(PyObject *ob)
- Return true if *ob* is a slice object; *ob* must not be ``NULL``.
+ Return true if *ob* is a slice object; *ob* must not be ``NULL``. This
+ function always succeeds.
.. c:function:: PyObject* PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
.. c:function:: int PyTuple_Check(PyObject *p)
- Return true if *p* is a tuple object or an instance of a subtype of the tuple
- type.
+ Return true if *p* is a tuple object or an instance of a subtype of the
+ tuple type. This function always succeeds.
.. c:function:: int PyTuple_CheckExact(PyObject *p)
Return true if *p* is a tuple object, but not an instance of a subtype of the
- tuple type.
+ tuple type. This function always succeeds.
.. c:function:: PyObject* PyTuple_New(Py_ssize_t len)
Return non-zero if the object *o* is a type object, including instances of
types derived from the standard type object. Return 0 in all other cases.
+ This function always succeeds.
.. c:function:: int PyType_CheckExact(PyObject *o)
- Return non-zero if the object *o* is a type object, but not a subtype of the
- standard type object. Return 0 in all other cases.
+ Return non-zero if the object *o* is a type object, but not a subtype of
+ the standard type object. Return 0 in all other cases. This function
+ always succeeds.
.. c:function:: unsigned int PyType_ClearCache()
.. c:function:: int PyUnicode_Check(PyObject *o)
Return true if the object *o* is a Unicode object or an instance of a Unicode
- subtype.
+ subtype. This function always succeeds.
.. c:function:: int PyUnicode_CheckExact(PyObject *o)
Return true if the object *o* is a Unicode object, but not an instance of a
- subtype.
+ subtype. This function always succeeds.
.. c:function:: int PyUnicode_READY(PyObject *o)
.. c:function:: int PyWeakref_Check(ob)
- Return true if *ob* is either a reference or proxy object.
+ Return true if *ob* is either a reference or proxy object. This function
+ always succeeds.
.. c:function:: int PyWeakref_CheckRef(ob)
- Return true if *ob* is a reference object.
+ Return true if *ob* is a reference object. This function always succeeds.
.. c:function:: int PyWeakref_CheckProxy(ob)
- Return true if *ob* is a proxy object.
+ Return true if *ob* is a proxy object. This function always succeeds.
.. c:function:: PyObject* PyWeakref_NewRef(PyObject *ob, PyObject *callback)
Python and this documentation is:
-Copyright © 2001-2020 Python Software Foundation. All rights reserved.
+Copyright © 2001-2021 Python Software Foundation. All rights reserved.
Copyright © 2000 BeOpen.com. All rights reserved.
In general, a descriptor is an attribute value that has one of the methods in
the descriptor protocol. Those methods are :meth:`__get__`, :meth:`__set__`,
-and :meth:`__delete__`. If any of those methods are defined for an the
+and :meth:`__delete__`. If any of those methods are defined for an
attribute, it is said to be a :term:`descriptor`.
The default behavior for attribute access is to get, set, or delete the
In the case of HTTP, there are two extra things that Request objects allow you
to do: First, you can pass data to be sent to the server. Second, you can pass
-extra information ("metadata") *about* the data or the about request itself, to
+extra information ("metadata") *about* the data or about the request itself, to
the server - this information is sent as HTTP "headers". Let's look at each of
these in turn.
.. [#] This also means you could replace all existing COFF-libraries with OMF-libraries
of the same name.
-.. [#] Check https://www.sourceware.org/cygwin/ and http://www.mingw.org/ for more
- information
+.. [#] Check https://www.sourceware.org/cygwin/ for more information
.. [#] Then you have no POSIX emulation available, but you also don't need
:file:`cygwin1.dll`.
type
^^^^
-By default, :class:`ArgumentParser` objects read command-line arguments in as simple
+By default, the parser reads command-line arguments in as simple
strings. However, quite often the command-line string should instead be
-interpreted as another type, like a :class:`float` or :class:`int`. The
-``type`` keyword argument of :meth:`~ArgumentParser.add_argument` allows any
-necessary type-checking and type conversions to be performed. Common built-in
-types and functions can be used directly as the value of the ``type`` argument::
+interpreted as another type, such as a :class:`float` or :class:`int`. The
+``type`` keyword for :meth:`~ArgumentParser.add_argument` allows any
+necessary type-checking and type conversions to be performed.
- >>> parser = argparse.ArgumentParser()
- >>> parser.add_argument('foo', type=int)
- >>> parser.add_argument('bar', type=open)
- >>> parser.parse_args('2 temp.txt'.split())
- Namespace(bar=<_io.TextIOWrapper name='temp.txt' encoding='UTF-8'>, foo=2)
+If the type_ keyword is used with the default_ keyword, the type converter
+is only applied if the default is a string.
-See the section on the default_ keyword argument for information on when the
-``type`` argument is applied to default arguments.
+The argument to ``type`` can be any callable that accepts a single string.
+If the function raises :exc:`ArgumentTypeError`, :exc:`TypeError`, or
+:exc:`ValueError`, the exception is caught and a nicely formatted error
+message is displayed. No other exception types are handled.
-To ease the use of various types of files, the argparse module provides the
-factory FileType which takes the ``mode=``, ``bufsize=``, ``encoding=`` and
-``errors=`` arguments of the :func:`open` function. For example,
-``FileType('w')`` can be used to create a writable file::
+Common built-in types and functions can be used as type converters:
- >>> parser = argparse.ArgumentParser()
- >>> parser.add_argument('bar', type=argparse.FileType('w'))
- >>> parser.parse_args(['out.txt'])
- Namespace(bar=<_io.TextIOWrapper name='out.txt' encoding='UTF-8'>)
-
-``type=`` can take any callable that takes a single string argument and returns
-the converted value::
-
- >>> def perfect_square(string):
- ... value = int(string)
- ... sqrt = math.sqrt(value)
- ... if sqrt != int(sqrt):
- ... msg = "%r is not a perfect square" % string
- ... raise argparse.ArgumentTypeError(msg)
- ... return value
+.. testcode::
+
+ import argparse
+ import pathlib
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument('count', type=int)
+ parser.add_argument('distance', type=float)
+ parser.add_argument('street', type=ascii)
+ parser.add_argument('code_point', type=ord)
+ parser.add_argument('source_file', type=open)
+ parser.add_argument('dest_file', type=argparse.FileType('w', encoding='latin-1'))
+ parser.add_argument('datapath', type=pathlib.Path)
+
+User defined functions can be used as well:
+
+.. doctest::
+
+ >>> def hyphenated(string):
+ ... return '-'.join([word[:4] for word in string.casefold().split()])
...
- >>> parser = argparse.ArgumentParser(prog='PROG')
- >>> parser.add_argument('foo', type=perfect_square)
- >>> parser.parse_args(['9'])
- Namespace(foo=9)
- >>> parser.parse_args(['7'])
- usage: PROG [-h] foo
- PROG: error: argument foo: '7' is not a perfect square
+ >>> parser = argparse.ArgumentParser()
+ >>> _ = parser.add_argument('short_title', type=hyphenated)
+ >>> parser.parse_args(['"The Tale of Two Cities"'])
+ Namespace(short_title='"the-tale-of-two-citi')
-The choices_ keyword argument may be more convenient for type checkers that
-simply check against a range of values::
+The :func:`bool` function is not recommended as a type converter. All it does
+is convert empty strings to ``False`` and non-empty strings to ``True``.
+This is usually not what is desired.
- >>> parser = argparse.ArgumentParser(prog='PROG')
- >>> parser.add_argument('foo', type=int, choices=range(5, 10))
- >>> parser.parse_args(['7'])
- Namespace(foo=7)
- >>> parser.parse_args(['11'])
- usage: PROG [-h] {5,6,7,8,9}
- PROG: error: argument foo: invalid choice: 11 (choose from 5, 6, 7, 8, 9)
+In general, the ``type`` keyword is a convenience that should only be used for
+simple conversions that can only raise one of the three supported exceptions.
+Anything with more interesting error-handling or resource management should be
+done downstream after the arguments are parsed.
-See the choices_ section for more details.
+For example, JSON or YAML conversions have complex error cases that require
+better reporting than can be given by the ``type`` keyword. An
+:exc:`~json.JSONDecodeError` would not be well formatted and a
+:exc:`FileNotFound` exception would not be handled at all.
+
+Even :class:`~argparse.FileType` has its limitations for use with the ``type``
+keyword. If one argument uses *FileType* and then a subsequent argument fails,
+an error is reported but the file is not automatically closed. In this case, it
+would be better to wait until after the parser has run and then use the
+:keyword:`with`-statement to manage the files.
+
+For type checkers that simply check against a fixed set of values, consider
+using the choices_ keyword instead.
choices
Use of :class:`enum.Enum` is not recommended because it is difficult to
control its appearance in usage, help, and error messages.
+Formatted choices overrides the default *metavar* which is normally derived
+from *dest*. This is usually what you want because the user never sees the
+*dest* parameter. If this display isn't desirable (perhaps because there are
+many choices), just specify an explicit metavar_.
+
required
^^^^^^^^
.. versionadded:: 3.5.2
-.. method:: loop.create_task(coro, \*, name=None)
+.. method:: loop.create_task(coro, *, name=None)
Schedule the execution of a :ref:`coroutine`.
Return a :class:`Task` object.
^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. coroutinemethod:: loop.create_connection(protocol_factory, \
- host=None, port=None, \*, ssl=None, \
+ host=None, port=None, *, ssl=None, \
family=0, proto=0, flags=0, sock=None, \
local_addr=None, server_hostname=None, \
ssl_handshake_timeout=None, \
that can be used directly in async/await code.
.. coroutinemethod:: loop.create_datagram_endpoint(protocol_factory, \
- local_addr=None, remote_addr=None, \*, \
+ local_addr=None, remote_addr=None, *, \
family=0, proto=0, flags=0, \
reuse_address=None, reuse_port=None, \
allow_broadcast=None, sock=None)
Added support for Windows.
.. coroutinemethod:: loop.create_unix_connection(protocol_factory, \
- path=None, \*, ssl=None, sock=None, \
+ path=None, *, ssl=None, sock=None, \
server_hostname=None, ssl_handshake_timeout=None)
Create a Unix connection.
^^^^^^^^^^^^^^^^^^^^^^^^
.. coroutinemethod:: loop.create_server(protocol_factory, \
- host=None, port=None, \*, \
+ host=None, port=None, *, \
family=socket.AF_UNSPEC, \
flags=socket.AI_PASSIVE, \
sock=None, backlog=100, ssl=None, \
.. coroutinemethod:: loop.create_unix_server(protocol_factory, path=None, \
- \*, sock=None, backlog=100, ssl=None, \
+ *, sock=None, backlog=100, ssl=None, \
ssl_handshake_timeout=None, start_serving=True)
Similar to :meth:`loop.create_server` but works with the
The *path* parameter can now be a :class:`~pathlib.Path` object.
.. coroutinemethod:: loop.connect_accepted_socket(protocol_factory, \
- sock, \*, ssl=None, ssl_handshake_timeout=None)
+ sock, *, ssl=None, ssl_handshake_timeout=None)
Wrap an already accepted connection into a transport/protocol pair.
^^^^^^^^^^^
.. coroutinemethod:: loop.start_tls(transport, protocol, \
- sslcontext, \*, server_side=False, \
+ sslcontext, *, server_side=False, \
server_hostname=None, ssl_handshake_timeout=None)
Upgrade an existing transport-based connection to TLS.
Watching file descriptors
^^^^^^^^^^^^^^^^^^^^^^^^^
-.. method:: loop.add_reader(fd, callback, \*args)
+.. method:: loop.add_reader(fd, callback, *args)
Start monitoring the *fd* file descriptor for read availability and
invoke *callback* with the specified arguments once *fd* is available for
Stop monitoring the *fd* file descriptor for read availability.
-.. method:: loop.add_writer(fd, callback, \*args)
+.. method:: loop.add_writer(fd, callback, *args)
Start monitoring the *fd* file descriptor for write availability and
invoke *callback* with the specified arguments once *fd* is available for
:meth:`loop.create_server` and :func:`start_server`.
.. coroutinemethod:: loop.sock_sendfile(sock, file, offset=0, count=None, \
- \*, fallback=True)
+ *, fallback=True)
Send a file using high-performance :mod:`os.sendfile` if possible.
Return the total number of bytes sent.
DNS
^^^
-.. coroutinemethod:: loop.getaddrinfo(host, port, \*, family=0, \
+.. coroutinemethod:: loop.getaddrinfo(host, port, *, family=0, \
type=0, proto=0, flags=0)
Asynchronous version of :meth:`socket.getaddrinfo`.
Unix signals
^^^^^^^^^^^^
-.. method:: loop.add_signal_handler(signum, callback, \*args)
+.. method:: loop.add_signal_handler(signum, callback, *args)
Set *callback* as the handler for the *signum* signal.
Executing code in thread or process pools
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. awaitablemethod:: loop.run_in_executor(executor, func, \*args)
+.. awaitablemethod:: loop.run_in_executor(executor, func, *args)
Arrange for *func* to be called in the specified executor.
subprocesses. See :ref:`Subprocess Support on Windows
<asyncio-windows-subprocess>` for details.
-.. coroutinemethod:: loop.subprocess_exec(protocol_factory, \*args, \
+.. coroutinemethod:: loop.subprocess_exec(protocol_factory, *args, \
stdin=subprocess.PIPE, stdout=subprocess.PIPE, \
- stderr=subprocess.PIPE, \*\*kwargs)
+ stderr=subprocess.PIPE, **kwargs)
Create a subprocess from one or more string arguments specified by
*args*.
conforms to the :class:`asyncio.SubprocessTransport` base class and
*protocol* is an object instantiated by the *protocol_factory*.
-.. coroutinemethod:: loop.subprocess_shell(protocol_factory, cmd, \*, \
+.. coroutinemethod:: loop.subprocess_shell(protocol_factory, cmd, *, \
stdin=subprocess.PIPE, stdout=subprocess.PIPE, \
- stderr=subprocess.PIPE, \*\*kwargs)
+ stderr=subprocess.PIPE, **kwargs)
Create a subprocess from *cmd*, which can be a :class:`str` or a
:class:`bytes` string encoded to the
.. versionadded:: 3.5
-.. function:: ensure_future(obj, \*, loop=None)
+.. function:: ensure_future(obj, *, loop=None)
Return:
The function accepts any :term:`awaitable` object.
-.. function:: wrap_future(future, \*, loop=None)
+.. function:: wrap_future(future, *, loop=None)
Wrap a :class:`concurrent.futures.Future` object in a
:class:`asyncio.Future` object.
Future Object
=============
-.. class:: Future(\*, loop=None)
+.. class:: Future(*, loop=None)
A Future represents an eventual result of an asynchronous
operation. Not thread-safe.
.. class:: AbstractChildWatcher
- .. method:: add_child_handler(pid, callback, \*args)
+ .. method:: add_child_handler(pid, callback, *args)
Register a new child handler.
and work with streams:
-.. coroutinefunction:: open_connection(host=None, port=None, \*, \
+.. coroutinefunction:: open_connection(host=None, port=None, *, \
loop=None, limit=None, ssl=None, family=0, \
proto=0, flags=0, sock=None, local_addr=None, \
server_hostname=None, ssl_handshake_timeout=None)
The *ssl_handshake_timeout* parameter.
.. coroutinefunction:: start_server(client_connected_cb, host=None, \
- port=None, \*, loop=None, limit=None, \
+ port=None, *, loop=None, limit=None, \
family=socket.AF_UNSPEC, \
flags=socket.AI_PASSIVE, sock=None, \
backlog=100, ssl=None, reuse_address=None, \
.. rubric:: Unix Sockets
-.. coroutinefunction:: open_unix_connection(path=None, \*, loop=None, \
+.. coroutinefunction:: open_unix_connection(path=None, *, loop=None, \
limit=None, ssl=None, sock=None, \
server_hostname=None, ssl_handshake_timeout=None)
.. coroutinefunction:: start_unix_server(client_connected_cb, path=None, \
- \*, loop=None, limit=None, sock=None, \
+ *, loop=None, limit=None, sock=None, \
backlog=100, ssl=None, ssl_handshake_timeout=None, \
start_serving=True)
Creating Subprocesses
=====================
-.. coroutinefunction:: create_subprocess_exec(program, \*args, stdin=None, \
+.. coroutinefunction:: create_subprocess_exec(program, *args, stdin=None, \
stdout=None, stderr=None, loop=None, \
- limit=None, \*\*kwds)
+ limit=None, **kwds)
Create a subprocess.
.. coroutinefunction:: create_subprocess_shell(cmd, stdin=None, \
stdout=None, stderr=None, loop=None, \
- limit=None, \*\*kwds)
+ limit=None, **kwds)
Run the *cmd* shell command.
that some event has happened.
An Event object manages an internal flag that can be set to *true*
- with the :meth:`set` method and reset to *false* with the
- :meth:`clear` method. The :meth:`wait` method blocks until the
+ with the :meth:`~Event.set` method and reset to *false* with the
+ :meth:`clear` method. The :meth:`~Event.wait` method blocks until the
flag is set to *true*. The flag is set to *false* initially.
Wait until the event is set.
If the event is set, return ``True`` immediately.
- Otherwise block until another task calls :meth:`set`.
+ Otherwise block until another task calls :meth:`~Event.set`.
.. method:: set()
Clear (unset) the event.
- Tasks awaiting on :meth:`wait` will now block until the
- :meth:`set` method is called again.
+ Tasks awaiting on :meth:`~Event.wait` will now block until the
+ :meth:`~Event.set` method is called again.
.. method:: is_set()
Running an asyncio Program
==========================
-.. function:: run(coro, \*, debug=False)
+.. function:: run(coro, *, debug=False)
Execute the :term:`coroutine` *coro* and return the result.
Creating Tasks
==============
-.. function:: create_task(coro, \*, name=None)
+.. function:: create_task(coro, *, name=None)
Wrap the *coro* :ref:`coroutine <coroutine>` into a :class:`Task`
and schedule its execution. Return the Task object.
Sleeping
========
-.. coroutinefunction:: sleep(delay, result=None, \*, loop=None)
+.. coroutinefunction:: sleep(delay, result=None, *, loop=None)
Block for *delay* seconds.
Running Tasks Concurrently
==========================
-.. awaitablefunction:: gather(\*aws, loop=None, return_exceptions=False)
+.. awaitablefunction:: gather(*aws, loop=None, return_exceptions=False)
Run :ref:`awaitable objects <asyncio-awaitables>` in the *aws*
sequence *concurrently*.
Shielding From Cancellation
===========================
-.. awaitablefunction:: shield(aw, \*, loop=None)
+.. awaitablefunction:: shield(aw, *, loop=None)
Protect an :ref:`awaitable object <asyncio-awaitables>`
from being :meth:`cancelled <Task.cancel>`.
Timeouts
========
-.. coroutinefunction:: wait_for(aw, timeout, \*, loop=None)
+.. coroutinefunction:: wait_for(aw, timeout, *, loop=None)
Wait for the *aw* :ref:`awaitable <asyncio-awaitables>`
to complete with a timeout.
Waiting Primitives
==================
-.. coroutinefunction:: wait(aws, \*, loop=None, timeout=None,\
+.. coroutinefunction:: wait(aws, *, loop=None, timeout=None,\
return_when=ALL_COMPLETED)
Run :ref:`awaitable objects <asyncio-awaitables>` in the *aws*
deprecated.
-.. function:: as_completed(aws, \*, loop=None, timeout=None)
+.. function:: as_completed(aws, *, loop=None, timeout=None)
Run :ref:`awaitable objects <asyncio-awaitables>` in the *aws*
iterable concurrently. Return an iterator of coroutines.
Running in Threads
==================
-.. coroutinefunction:: to_thread(func, /, \*args, \*\*kwargs)
+.. coroutinefunction:: to_thread(func, /, *args, **kwargs)
Asynchronously run function *func* in a separate thread.
Task Object
===========
-.. class:: Task(coro, \*, loop=None, name=None)
+.. class:: Task(coro, *, loop=None, name=None)
A :class:`Future-like <Future>` object that runs a Python
:ref:`coroutine <coroutine>`. Not thread-safe.
See the documentation of :meth:`Future.remove_done_callback`
for more details.
- .. method:: get_stack(\*, limit=None)
+ .. method:: get_stack(*, limit=None)
Return the list of stack frames for this Task.
stack are returned, but the oldest frames of a traceback are
returned. (This matches the behavior of the traceback module.)
- .. method:: print_stack(\*, limit=None, file=None)
+ .. method:: print_stack(*, limit=None, file=None)
Print the stack or traceback for this Task.
algorithms implemented in this module in other circumstances.
-.. function:: parse(fp=None, environ=os.environ, keep_blank_values=False, strict_parsing=False)
+.. function:: parse(fp=None, environ=os.environ, keep_blank_values=False, strict_parsing=False, separator="&")
Parse a query in the environment or from a file (the file defaults to
- ``sys.stdin``). The *keep_blank_values* and *strict_parsing* parameters are
+ ``sys.stdin``). The *keep_blank_values*, *strict_parsing* and *separator* parameters are
passed to :func:`urllib.parse.parse_qs` unchanged.
-.. function:: parse_multipart(fp, pdict, encoding="utf-8", errors="replace")
+.. function:: parse_multipart(fp, pdict, encoding="utf-8", errors="replace", separator="&")
Parse input of type :mimetype:`multipart/form-data` (for file uploads).
Arguments are *fp* for the input file, *pdict* for a dictionary containing
Added the *encoding* and *errors* parameters. For non-file fields, the
value is now a list of strings, not bytes.
+ .. versionchanged:: 3.9.2
+ Added the *separator* parameter.
+
.. function:: parse_header(string)
.. method:: reset()
- Flushes and resets the codec buffers used for keeping state.
+ Resets the codec buffers used for keeping internal state.
Calling this method should ensure that the data on the output is put into
a clean state that allows appending of new fresh data without having to
.. method:: reset()
- Resets the codec buffers used for keeping state.
+ Resets the codec buffers used for keeping internal state.
Note that no stream repositioning should take place. This method is
primarily intended to be able to recover from decoding errors.
Public functions
----------------
-.. function:: compile_dir(dir, maxlevels=sys.getrecursionlimit(), ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, workers=1, invalidation_mode=None, \*, stripdir=None, prependdir=None, limit_sl_dest=None, hardlink_dupes=False)
+.. function:: compile_dir(dir, maxlevels=sys.getrecursionlimit(), ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, workers=1, invalidation_mode=None, *, stripdir=None, prependdir=None, limit_sl_dest=None, hardlink_dupes=False)
Recursively descend the directory tree named by *dir*, compiling all :file:`.py`
files along the way. Return a true value if all the files compiled successfully,
Added *stripdir*, *prependdir*, *limit_sl_dest* and *hardlink_dupes* arguments.
Default value of *maxlevels* was changed from ``10`` to ``sys.getrecursionlimit()``
-.. function:: compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, invalidation_mode=None, \*, stripdir=None, prependdir=None, limit_sl_dest=None, hardlink_dupes=False)
+.. function:: compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, invalidation_mode=None, *, stripdir=None, prependdir=None, limit_sl_dest=None, hardlink_dupes=False)
Compile the file with path *fullname*. Return a true value if the file
compiled successfully, and a false value otherwise.
.. versionchanged:: 3.5
Added the *chunksize* argument.
- .. method:: shutdown(wait=True, \*, cancel_futures=False)
+ .. method:: shutdown(wait=True, *, cancel_futures=False)
Signal the executor that it should free any resources that it is using
when the currently pending futures are done executing. Calls to
Context Variables
-----------------
-.. class:: ContextVar(name, [\*, default])
+.. class:: ContextVar(name, [*, default])
This class is used to declare a new Context Variable, e.g.::
Context implements the :class:`collections.abc.Mapping` interface.
- .. method:: run(callable, \*args, \*\*kwargs)
+ .. method:: run(callable, *args, **kwargs)
Execute ``callable(*args, **kwargs)`` code in the context object
the *run* method is called on. Return the result of the execution
Arrays and pointers
^^^^^^^^^^^^^^^^^^^
-.. class:: Array(\*args)
+.. class:: Array(*args)
Abstract base class for arrays.
.. function:: color_content(color_number)
Return the intensity of the red, green, and blue (RGB) components in the color
- *color_number*, which must be between ``0`` and :const:`COLORS`. Return a 3-tuple,
+ *color_number*, which must be between ``0`` and ``COLORS - 1``. Return a 3-tuple,
containing the R,G,B values for the given color, which will be between
``0`` (no component) and ``1000`` (maximum amount of component).
-.. function:: color_pair(color_number)
+.. function:: color_pair(pair_number)
- Return the attribute value for displaying text in the specified color. This
+ Return the attribute value for displaying text in the specified color pair.
+ Only the first 256 color pairs are supported. This
attribute value can be combined with :const:`A_STANDOUT`, :const:`A_REVERSE`,
and the other :const:`A_\*` attributes. :func:`pair_number` is the counterpart
to this function.
Change the definition of a color, taking the number of the color to be changed
followed by three RGB values (for the amounts of red, green, and blue
components). The value of *color_number* must be between ``0`` and
- :const:`COLORS`. Each of *r*, *g*, *b*, must be a value between ``0`` and
+ `COLORS - 1`. Each of *r*, *g*, *b*, must be a value between ``0`` and
``1000``. When :func:`init_color` is used, all occurrences of that color on the
screen immediately change to the new definition. This function is a no-op on
most terminals; it is active only if :func:`can_change_color` returns ``True``.
color number. The value of *pair_number* must be between ``1`` and
``COLOR_PAIRS - 1`` (the ``0`` color pair is wired to white on black and cannot
be changed). The value of *fg* and *bg* arguments must be between ``0`` and
- :const:`COLORS`. If the color-pair was previously initialized, the screen is
+ ``COLORS - 1``, or, after calling :func:`use_default_colors`, ``-1``.
+ If the color-pair was previously initialized, the screen is
refreshed and all occurrences of that color-pair are changed to the new
definition.
.. function:: pair_content(pair_number)
Return a tuple ``(fg, bg)`` containing the colors for the requested color pair.
- The value of *pair_number* must be between ``1`` and ``COLOR_PAIRS - 1``.
+ The value of *pair_number* must be between ``0`` and ``COLOR_PAIRS - 1``.
.. function:: pair_number(attr)
.. method:: datetime.replace(year=self.year, month=self.month, day=self.day, \
hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, \
- tzinfo=self.tzinfo, * fold=0)
+ tzinfo=self.tzinfo, *, fold=0)
Return a datetime with the same attributes, except for those attributes given
new values by whichever keyword arguments are specified. Note that
Instance methods:
.. method:: time.replace(hour=self.hour, minute=self.minute, second=self.second, \
- microsecond=self.microsecond, tzinfo=self.tzinfo, * fold=0)
+ microsecond=self.microsecond, tzinfo=self.tzinfo, *, fold=0)
Return a :class:`.time` with the same value, except for those attributes given
new values by whichever keyword arguments are specified. Note that
A subclass of FileDialog that creates a dialog window for selecting a
destination file.
- .. method:: ok_command()
+ .. method:: ok_command()
Test whether or not the selection points to a valid file that is not a
directory. Confirmation is required if an already existing file is
decoding the payload to unicode. The default error handler is
``replace``.
- .. method:: set_content(msg, <'str'>, subtype="plain", charset='utf-8' \
+ .. method:: set_content(msg, <'str'>, subtype="plain", charset='utf-8', \
cte=None, \
disposition=None, filename=None, cid=None, \
params=None, headers=None)
A :class:`ParameterizedMIMEHeader` class that handles the
:mailheader:`Content-Disposition` header.
- .. attribute:: content-disposition
+ .. attribute:: content_disposition
``inline`` and ``attachment`` are the only valid values in common use.
:meth:`register_defect` method.
- .. attribute:: mangle_from\_
+ .. attribute:: mangle_from_
If :const:`True`, lines starting with *"From "* in the body are
escaped by putting a ``>`` in front of them. This parameter is used when
the bitwise operations without losing their :class:`Flag` membership.
.. function:: unique
- :noindex:
+ :noindex:
Enum class decorator that ensures only one name is bound to any one value.
In Python 2 code the :attr:`_order_` attribute is necessary as definition
order is lost before it can be recorded.
+
+_Private__names
+"""""""""""""""
+
+Private names will be normal attributes in Python 3.10 instead of either an error
+or a member (depending on if the name ends with an underscore). Using these names
+in 3.9 will issue a :exc:`DeprecationWarning`.
+
+
``Enum`` member type
""""""""""""""""""""
.. function:: filter(names, pattern)
- Return the subset of the list of *names* that match *pattern*. It is the same as
+ Construct a list from those elements of the iterable *names* that match *pattern*. It is the same as
``[n for n in names if fnmatch(n, pattern)]``, but implemented more efficiently.
occurs). [#]_ If it is a code object, it is simply executed. In all cases,
the code that's executed is expected to be valid as file input (see the
section "File input" in the Reference Manual). Be aware that the
- :keyword:`return` and :keyword:`yield` statements may not be used outside of
+ :keyword:`nonlocal`, :keyword:`yield`, and :keyword:`return`
+ statements may not be used outside of
function definitions even within the context of code passed to the
:func:`exec` function. The return value is ``None``.
With three arguments, return a new type object. This is essentially a
- dynamic form of the :keyword:`class` statement. The *name* string is the
- class name and becomes the :attr:`~definition.__name__` attribute; the *bases*
- tuple itemizes the base classes and becomes the :attr:`~class.__bases__`
- attribute; and the *dict* dictionary is the namespace containing definitions
- for class body and is copied to a standard dictionary to become the
- :attr:`~object.__dict__` attribute. For example, the following two
- statements create identical :class:`type` objects:
+ dynamic form of the :keyword:`class` statement. The *name* string is
+ the class name and becomes the :attr:`~definition.__name__` attribute.
+ The *bases* tuple contains the base classes and becomes the
+ :attr:`~class.__bases__` attribute; if empty, :class:`object`, the
+ ultimate base of all classes, is added. The *dict* dictionary contains
+ attribute and method definitions for the class body; it may be copied
+ or wrapped before becoming the :attr:`~object.__dict__` attribute.
+ The following two statements create identical :class:`type` objects:
>>> class X:
... a = 1
...
- >>> X = type('X', (object,), dict(a=1))
+ >>> X = type('X', (), dict(a=1))
See also :ref:`bltin-type-objects`.
Example::
class DataSet:
+
def __init__(self, sequence_of_numbers):
- self._data = sequence_of_numbers
+ self._data = tuple(sequence_of_numbers)
@cached_property
def stdev(self):
return statistics.stdev(self._data)
- @cached_property
- def variance(self):
- return statistics.variance(self._data)
+ The mechanics of :func:`cached_property` are somewhat different from
+ :func:`property`. A regular property blocks attribute writes unless a
+ setter is defined. In contrast, a *cached_property* allows writes.
+
+ The *cached_property* decorator only runs on lookups and only when an
+ attribute of the same name doesn't exist. When it does run, the
+ *cached_property* writes to the attribute with the same name. Subsequent
+ attribute reads and writes take precedence over the *cached_property*
+ method and it works like a normal attribute.
+
+ The cached value can be cleared by deleting the attribute. This
+ allows the *cached_property* method to run again.
Note, this decorator interferes with the operation of :pep:`412`
key-sharing dictionaries. This means that instance dictionaries
Scroll the shell window to the last Shell restart.
Restart Shell
- Restart the shell to clean the environment.
+ Restart the shell to clean the environment and reset display and exception handling.
Previous History
Cycle through earlier commands in history which match the current entry.
There are all kinds of additional metadata available on the ``Distribution``
instance::
- >>> d.metadata['Requires-Python'] # doctest: +SKIP
+ >>> dist.metadata['Requires-Python'] # doctest: +SKIP
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
- >>> d.metadata['License'] # doctest: +SKIP
+ >>> dist.metadata['License'] # doctest: +SKIP
'MIT'
The full set of available metadata is not described here. See :pep:`566`
directory for ``''`` (i.e. the empty string).
-.. class:: FileFinder(path, \*loader_details)
+.. class:: FileFinder(path, *loader_details)
A concrete implementation of :class:`importlib.abc.PathEntryFinder` which
caches results from the file system.
Clear out the internal cache.
- .. classmethod:: path_hook(\*loader_details)
+ .. classmethod:: path_hook(*loader_details)
A class method which returns a closure for use on :attr:`sys.path_hooks`.
An instance of :class:`FileFinder` is returned by the closure using the
If **name** has no leading dots, then **name** is simply returned. This
allows for usage such as
- ``importlib.util.resolve_name('sys', __package__)`` without doing a
+ ``importlib.util.resolve_name('sys', __spec__.parent)`` without doing a
check to see if the **package** argument is needed.
:exc:`ImportError` is raised if **name** is a relative module name but
return annotation. To retrieve a Signature object, use the :func:`signature`
function.
-.. function:: signature(callable, \*, follow_wrapped=True)
+.. function:: signature(callable, *, follow_wrapped=True)
Return a :class:`Signature` object for the given ``callable``::
C provide no metadata about their arguments.
-.. class:: Signature(parameters=None, \*, return_annotation=Signature.empty)
+.. class:: Signature(parameters=None, *, return_annotation=Signature.empty)
A Signature object represents the call signature of a function and its return
annotation. For each parameter accepted by the function it stores a
>>> str(new_sig)
"(a, b) -> 'new return anno'"
- .. classmethod:: Signature.from_callable(obj, \*, follow_wrapped=True)
+ .. classmethod:: Signature.from_callable(obj, *, follow_wrapped=True)
Return a :class:`Signature` (or its subclass) object for a given callable
``obj``. Pass ``follow_wrapped=False`` to get a signature of ``obj``
.. versionadded:: 3.5
-.. class:: Parameter(name, kind, \*, default=Parameter.empty, annotation=Parameter.empty)
+.. class:: Parameter(name, kind, *, default=Parameter.empty, annotation=Parameter.empty)
Parameter objects are *immutable*. Instead of modifying a Parameter object,
you can use :meth:`Parameter.replace` to create a modified copy.
Before :func:`product` runs, it completely consumes the input iterables,
keeping pools of values in memory to generate the products. Accordingly,
- it only useful with finite inputs.
+ it is only useful with finite inputs.
.. function:: repeat(object[, times])
def dotproduct(vec1, vec2):
return sum(map(operator.mul, vec1, vec2))
+ def convolve(signal, kernel):
+ # See: https://betterexplained.com/articles/intuitive-convolution/
+ # convolve(data, [0.25, 0.25, 0.25, 0.25]) --> Moving average (blur)
+ # convolve(data, [1, -1]) --> 1st finite difference (1st derivative)
+ # convolve(data, [1, -2, 1]) --> 2nd finite difference (2nd derivative)
+ kernel = tuple(kernel)[::-1]
+ n = len(kernel)
+ window = collections.deque([0], maxlen=n) * n
+ for x in chain(signal, repeat(0, n-1)):
+ window.append(x)
+ yield sum(map(operator.mul, kernel, window))
+
def flatten(list_of_lists):
"Flatten one level of nesting"
return chain.from_iterable(list_of_lists)
.. function:: dictConfig(config)
- Takes the logging configuration from a dictionary. The contents of
- this dictionary are described in :ref:`logging-config-dictschema`
- below.
-
- If an error is encountered during configuration, this function will
- raise a :exc:`ValueError`, :exc:`TypeError`, :exc:`AttributeError`
- or :exc:`ImportError` with a suitably descriptive message. The
- following is a (possibly incomplete) list of conditions which will
- raise an error:
-
- * A ``level`` which is not a string or which is a string not
- corresponding to an actual logging level.
- * A ``propagate`` value which is not a boolean.
- * An id which does not have a corresponding destination.
- * A non-existent handler id found during an incremental call.
- * An invalid logger name.
- * Inability to resolve to an internal or external object.
-
- Parsing is performed by the :class:`DictConfigurator` class, whose
- constructor is passed the dictionary used for configuration, and
- has a :meth:`configure` method. The :mod:`logging.config` module
- has a callable attribute :attr:`dictConfigClass`
- which is initially set to :class:`DictConfigurator`.
- You can replace the value of :attr:`dictConfigClass` with a
- suitable implementation of your own.
-
- :func:`dictConfig` calls :attr:`dictConfigClass` passing
- the specified dictionary, and then calls the :meth:`configure` method on
- the returned object to put the configuration into effect::
-
- def dictConfig(config):
- dictConfigClass(config).configure()
-
- For example, a subclass of :class:`DictConfigurator` could call
- ``DictConfigurator.__init__()`` in its own :meth:`__init__()`, then
- set up custom prefixes which would be usable in the subsequent
- :meth:`configure` call. :attr:`dictConfigClass` would be bound to
- this new subclass, and then :func:`dictConfig` could be called exactly as
- in the default, uncustomized state.
+ Takes the logging configuration from a dictionary. The contents of
+ this dictionary are described in :ref:`logging-config-dictschema`
+ below.
+
+ If an error is encountered during configuration, this function will
+ raise a :exc:`ValueError`, :exc:`TypeError`, :exc:`AttributeError`
+ or :exc:`ImportError` with a suitably descriptive message. The
+ following is a (possibly incomplete) list of conditions which will
+ raise an error:
+
+ * A ``level`` which is not a string or which is a string not
+ corresponding to an actual logging level.
+ * A ``propagate`` value which is not a boolean.
+ * An id which does not have a corresponding destination.
+ * A non-existent handler id found during an incremental call.
+ * An invalid logger name.
+ * Inability to resolve to an internal or external object.
+
+ Parsing is performed by the :class:`DictConfigurator` class, whose
+ constructor is passed the dictionary used for configuration, and
+ has a :meth:`configure` method. The :mod:`logging.config` module
+ has a callable attribute :attr:`dictConfigClass`
+ which is initially set to :class:`DictConfigurator`.
+ You can replace the value of :attr:`dictConfigClass` with a
+ suitable implementation of your own.
+
+ :func:`dictConfig` calls :attr:`dictConfigClass` passing
+ the specified dictionary, and then calls the :meth:`configure` method on
+ the returned object to put the configuration into effect::
+
+ def dictConfig(config):
+ dictConfigClass(config).configure()
+
+ For example, a subclass of :class:`DictConfigurator` could call
+ ``DictConfigurator.__init__()`` in its own :meth:`__init__()`, then
+ set up custom prefixes which would be usable in the subsequent
+ :meth:`configure` call. :attr:`dictConfigClass` would be bound to
+ this new subclass, and then :func:`dictConfig` could be called exactly as
+ in the default, uncustomized state.
.. versionadded:: 3.2
suitable value.
.. versionchanged:: 3.7
- The *level* parameter was defaulted to level ``CRITICAL``. See Issue
- #28524 for more information about this change.
+ The *level* parameter was defaulted to level ``CRITICAL``. See
+ :issue:`28524` for more information about this change.
.. function:: addLevelName(level, levelName)
Reading and writing compressed files
------------------------------------
-.. function:: open(filename, mode="rb", \*, format=None, check=-1, preset=None, filters=None, encoding=None, errors=None, newline=None)
+.. function:: open(filename, mode="rb", *, format=None, check=-1, preset=None, filters=None, encoding=None, errors=None, newline=None)
Open an LZMA-compressed file in binary or text mode, returning a :term:`file
object`.
Accepts a :term:`path-like object`.
-.. class:: LZMAFile(filename=None, mode="r", \*, format=None, check=-1, preset=None, filters=None)
+.. class:: LZMAFile(filename=None, mode="r", *, format=None, check=-1, preset=None, filters=None)
Open an LZMA-compressed file in binary mode.
:mod:`multiprocessing.dummy` replicates the API of :mod:`multiprocessing` but is
no more than a wrapper around the :mod:`threading` module.
+.. currentmodule:: multiprocessing.pool
+
+In particular, the ``Pool`` function provided by :mod:`multiprocessing.dummy`
+returns an instance of :class:`ThreadPool`, which is a subclass of
+:class:`Pool` that supports all the same method calls but uses a pool of
+worker threads rather than worker processes.
+
+
+.. class:: ThreadPool([processes[, initializer[, initargs]]])
+
+ A thread pool object which controls a pool of worker threads to which jobs
+ can be submitted. :class:`ThreadPool` instances are fully interface
+ compatible with :class:`Pool` instances, and their resources must also be
+ properly managed, either by using the pool as a context manager or by
+ calling :meth:`~multiprocessing.pool.Pool.close` and
+ :meth:`~multiprocessing.pool.Pool.terminate` manually.
+
+ *processes* is the number of worker threads to use. If *processes* is
+ ``None`` then the number returned by :func:`os.cpu_count` is used.
+
+ If *initializer* is not ``None`` then each worker process will call
+ ``initializer(*initargs)`` when it starts.
+
+ Unlike :class:`Pool`, *maxtasksperchild* and *context* cannot be provided.
+
+ .. note::
+
+ A :class:`ThreadPool` shares the same interface as :class:`Pool`, which
+ is designed around a pool of processes and predates the introduction of
+ the :class:`concurrent.futures` module. As such, it inherits some
+ operations that don't make sense for a pool backed by threads, and it
+ has its own type for representing the status of asynchronous jobs,
+ :class:`AsyncResult`, that is not understood by any other libraries.
+
+ Users should generally prefer to use
+ :class:`concurrent.futures.ThreadPoolExecutor`, which has a simpler
+ interface that was designed around threads from the start, and which
+ returns :class:`concurrent.futures.Future` instances that are
+ compatible with many other libraries, including :mod:`asyncio`.
+
.. _multiprocessing-programming:
Accepts a :term:`path-like object`.
-.. function:: lstat(path, \*, dir_fd=None)
+.. function:: lstat(path, *, dir_fd=None)
Perform the equivalent of an :c:func:`lstat` system call on the given path.
Similar to :func:`~os.stat`, but does not follow symbolic links. Return a
On the first, uncached call, a system call is required on Windows but
not on Unix.
- .. method:: is_dir(\*, follow_symlinks=True)
+ .. method:: is_dir(*, follow_symlinks=True)
Return ``True`` if this entry is a directory or a symbolic link pointing
to a directory; return ``False`` if the entry is or points to any other
This method can raise :exc:`OSError`, such as :exc:`PermissionError`,
but :exc:`FileNotFoundError` is caught and not raised.
- .. method:: is_file(\*, follow_symlinks=True)
+ .. method:: is_file(*, follow_symlinks=True)
Return ``True`` if this entry is a file or a symbolic link pointing to a
file; return ``False`` if the entry is or points to a directory or other
This method can raise :exc:`OSError`, such as :exc:`PermissionError`,
but :exc:`FileNotFoundError` is caught and not raised.
- .. method:: stat(\*, follow_symlinks=True)
+ .. method:: stat(*, follow_symlinks=True)
Return a :class:`stat_result` object for this entry. This method
follows symbolic links by default; to stat a symbolic link add the
for :class:`bytes` paths on Windows.
-.. function:: stat(path, \*, dir_fd=None, follow_symlinks=True)
+.. function:: stat(path, *, dir_fd=None, follow_symlinks=True)
Get the status of a file or a file descriptor. Perform the equivalent of a
:c:func:`stat` system call on the given path. *path* may be specified as
The :mod:`pickle` module provides the following functions to make the pickling
process more convenient:
-.. function:: dump(obj, file, protocol=None, \*, fix_imports=True, buffer_callback=None)
+.. function:: dump(obj, file, protocol=None, *, fix_imports=True, buffer_callback=None)
Write the pickled representation of the object *obj* to the open
:term:`file object` *file*. This is equivalent to
.. versionchanged:: 3.8
The *buffer_callback* argument was added.
-.. function:: dumps(obj, protocol=None, \*, fix_imports=True, buffer_callback=None)
+.. function:: dumps(obj, protocol=None, *, fix_imports=True, buffer_callback=None)
Return the pickled representation of the object *obj* as a :class:`bytes` object,
instead of writing it to a file.
.. versionchanged:: 3.8
The *buffer_callback* argument was added.
-.. function:: load(file, \*, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)
+.. function:: load(file, *, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)
Read the pickled representation of an object from the open :term:`file object`
*file* and return the reconstituted object hierarchy specified therein.
.. versionchanged:: 3.8
The *buffers* argument was added.
-.. function:: loads(data, /, \*, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)
+.. function:: loads(data, /, *, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)
Return the reconstituted object hierarchy of the pickled representation
*data* of an object. *data* must be a :term:`bytes-like object`.
The :mod:`pickle` module exports three classes, :class:`Pickler`,
:class:`Unpickler` and :class:`PickleBuffer`:
-.. class:: Pickler(file, protocol=None, \*, fix_imports=True, buffer_callback=None)
+.. class:: Pickler(file, protocol=None, *, fix_imports=True, buffer_callback=None)
This takes a binary file for writing a pickle data stream.
Use :func:`pickletools.optimize` if you need more compact pickles.
-.. class:: Unpickler(file, \*, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)
+.. class:: Unpickler(file, *, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)
This takes a binary file for reading a pickle data stream.
This module defines the following functions:
-.. function:: load(fp, \*, fmt=None, dict_type=dict)
+.. function:: load(fp, *, fmt=None, dict_type=dict)
Read a plist file. *fp* should be a readable and binary file object.
Return the unpacked root object (which usually is a
.. versionadded:: 3.4
-.. function:: loads(data, \*, fmt=None, dict_type=dict)
+.. function:: loads(data, *, fmt=None, dict_type=dict)
Load a plist from a bytes object. See :func:`load` for an explanation of
the keyword arguments.
.. versionadded:: 3.4
-.. function:: dump(value, fp, \*, fmt=FMT_XML, sort_keys=True, skipkeys=False)
+.. function:: dump(value, fp, *, fmt=FMT_XML, sort_keys=True, skipkeys=False)
Write *value* to a plist file. *Fp* should be a writable, binary
file object.
.. versionadded:: 3.4
-.. function:: dumps(value, \*, fmt=FMT_XML, sort_keys=True, skipkeys=False)
+.. function:: dumps(value, *, fmt=FMT_XML, sort_keys=True, skipkeys=False)
Return *value* as a plist-formatted bytes object. See
the documentation for :func:`dump` for an explanation of the keyword
ordering are identical to the :meth:`~pstats.Stats.print_callers` method.
- .. method:: get_stats_profile()
+ .. method:: get_stats_profile()
This method returns an instance of StatsProfile, which contains a mapping
of function names to instances of FunctionProfile. Each FunctionProfile
instance holds information related to the function's profile such as how
long the function took to run, how many times it was called, etc...
- .. versionadded:: 3.9
- Added the following dataclasses: StatsProfile, FunctionProfile.
- Added the following function: get_stats_profile.
+ .. versionadded:: 3.9
+ Added the following dataclasses: StatsProfile, FunctionProfile.
+ Added the following function: get_stats_profile.
.. _deterministic-profiling:
.. data:: codes
- A dictionary mapping numeric error codes to their string descriptions.
+ A dictionary mapping string descriptions to their error codes.
.. versionadded:: 3.2
.. data:: messages
- A dictionary mapping string descriptions to their error codes.
+ A dictionary mapping numeric error codes to their string descriptions.
.. versionadded:: 3.2
.. function:: getrandbits(k)
- Returns a Python integer with *k* random bits. This method is supplied with
- the MersenneTwister generator and some other generators may also provide it
- as an optional part of the API. When available, :meth:`getrandbits` enables
- :meth:`randrange` to handle arbitrarily large ranges.
+ Returns a non-negative Python integer with *k* random bits. This method
+ is supplied with the MersenneTwister generator and some other generators
+ may also provide it as an optional part of the API. When available,
+ :meth:`getrandbits` enables :meth:`randrange` to handle arbitrarily large
+ ranges.
.. versionchanged:: 3.9
This method now accepts zero for *k*.
copy the file more efficiently. See
:ref:`shutil-platform-dependent-efficient-copy-operations` section.
-.. function:: ignore_patterns(\*patterns)
+.. function:: ignore_patterns(*patterns)
This factory function creates a function that can be used as a callable for
:func:`copytree`\'s *ignore* argument, ignoring files and directories that
Platform-dependent efficient copy operations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Starting from Python 3.8 all functions involving a file copy (:func:`copyfile`,
-:func:`copy`, :func:`copy2`, :func:`copytree`, and :func:`move`) may use
+Starting from Python 3.8, all functions involving a file copy
+(:func:`copyfile`, :func:`~shutil.copy`, :func:`copy2`,
+:func:`copytree`, and :func:`move`) may use
platform-specific "fast-copy" syscalls in order to copy the file more
efficiently (see :issue:`33671`).
"fast-copy" means that the copying operation occurs within the kernel, avoiding
bytes-like object can be used for either type of address when
passing it as an argument.
- .. versionchanged:: 3.3
- Previously, :const:`AF_UNIX` socket paths were assumed to use UTF-8
- encoding.
+ .. versionchanged:: 3.3
+ Previously, :const:`AF_UNIX` socket paths were assumed to use UTF-8
+ encoding.
- .. versionchanged:: 3.5
- Writable :term:`bytes-like object` is now accepted.
+ .. versionchanged:: 3.5
+ Writable :term:`bytes-like object` is now accepted.
.. _host_port:
.. seealso::
- https://github.com/ghaering/pysqlite
- The pysqlite web page -- sqlite3 is developed externally under the name
- "pysqlite".
-
https://www.sqlite.org
The SQLite web page; the documentation describes the syntax and the
available data types for the supported SQL dialect.
*detect_types* defaults to 0 (i. e. off, no type detection), you can set it to
any combination of :const:`PARSE_DECLTYPES` and :const:`PARSE_COLNAMES` to turn
- type detection on.
+ type detection on. Due to SQLite behaviour, types can't be detected for generated
+ fields (for example ``max(data)``), even when *detect_types* parameter is set. In
+ such case, the returned type is :class:`str`.
By default, *check_same_thread* is :const:`True` and only the creating thread may
use the connection. If set :const:`False`, the returned connection may be shared
con.close()
- .. method:: backup(target, *, pages=0, progress=None, name="main", sleep=0.250)
+ .. method:: backup(target, *, pages=-1, progress=None, name="main", sleep=0.250)
This method makes a backup of a SQLite database even while it's being accessed
by other clients, or concurrently by the same connection. The copy will be
.. literalinclude:: ../includes/sqlite3/ctx_manager.py
-Common issues
--------------
-
-Multithreading
-^^^^^^^^^^^^^^
-
-Older SQLite versions had issues with sharing connections between threads.
-That's why the Python module disallows sharing connections and cursors between
-threads. If you still try to do so, you will get an exception at runtime.
-
-The only exception is calling the :meth:`~Connection.interrupt` method, which
-only makes sense to call from a different thread.
-
.. rubric:: Footnotes
.. [#f1] The sqlite3 module is not built with loadable extension support by
.. versionadded:: 3.1
-.. method:: int.to_bytes(length, byteorder, \*, signed=False)
+.. method:: int.to_bytes(length, byteorder, *, signed=False)
Return an array of bytes representing an integer.
.. versionadded:: 3.2
-.. classmethod:: int.from_bytes(bytes, byteorder, \*, signed=False)
+.. classmethod:: int.from_bytes(bytes, byteorder, *, signed=False)
Return the integer represented by the given array of bytes.
.. method:: class.__subclasses__
Each class keeps a list of weak references to its immediate subclasses. This
- method returns a list of all those references still alive.
- Example::
+ method returns a list of all those references still alive. The list is in
+ definition order. Example::
>>> int.__subclasses__()
[<class 'bool'>]
| | this rounds the number to ``p`` significant digits and |
| | then formats the result in either fixed-point format |
| | or in scientific notation, depending on its magnitude. |
+ | | A precision of ``0`` is treated as equivalent to a |
+ | | precision of ``1``. |
| | |
| | The precise rules are as follows: suppose that the |
| | result formatted with presentation type ``'e'`` and |
| | removed if there are no remaining digits following it, |
| | unless the ``'#'`` option is used. |
| | |
+ | | With no precision given, uses a precision of ``6`` |
+ | | significant digits for :class:`float`. For |
+ | | :class:`~decimal.Decimal`, the coefficient of the result |
+ | | is formed from the coefficient digits of the value; |
+ | | scientific notation is used for values smaller than |
+ | | ``1e-6`` in absolute value and values where the place |
+ | | value of the least significant digit is larger than 1, |
+ | | and fixed-point notation is used otherwise. |
+ | | |
| | Positive and negative infinity, positive and negative |
| | zero, and nans, are formatted as ``inf``, ``-inf``, |
| | ``0``, ``-0`` and ``nan`` respectively, regardless of |
| | the precision. |
- | | |
- | | A precision of ``0`` is treated as equivalent to a |
- | | precision of ``1``. With no precision given, uses a |
- | | precision of ``6`` significant digits for |
- | | :class:`float`, and shows all coefficient digits |
- | | for :class:`~decimal.Decimal`. |
+---------+----------------------------------------------------------+
| ``'G'`` | General format. Same as ``'g'`` except switches to |
| | ``'E'`` if the number gets too large. The |
| ``'%'`` | Percentage. Multiplies the number by 100 and displays |
| | in fixed (``'f'``) format, followed by a percent sign. |
+---------+----------------------------------------------------------+
- | None | Similar to ``'g'``, except that fixed-point notation, |
- | | when used, has at least one digit past the decimal point.|
- | | The default precision is as high as needed to represent |
- | | the particular value. The overall effect is to match the |
- | | output of :func:`str` as altered by the other format |
- | | modifiers. |
+ | None | For :class:`float` this is the same as ``'g'``, except |
+ | | that when fixed-point notation is used to format the |
+ | | result, it always includes at least one digit past the |
+ | | decimal point. The precision used is as large as needed |
+ | | to represent the given value faithfully. |
+ | | |
+ | | For :class:`~decimal.Decimal`, this is the same as |
+ | | either ``'g'`` or ``'G'`` depending on the value of |
+ | | ``context.capitals`` for the current decimal context. |
+ | | |
+ | | The overall effect is to match the output of :func:`str` |
+ | | as altered by the other format modifiers. |
+---------+----------------------------------------------------------+
stderr=None, preexec_fn=None, close_fds=True, shell=False, \
cwd=None, env=None, universal_newlines=None, \
startupinfo=None, creationflags=0, restore_signals=True, \
- start_new_session=False, pass_fds=(), \*, group=None, \
+ start_new_session=False, pass_fds=(), *, group=None, \
extra_groups=None, user=None, umask=-1, \
encoding=None, errors=None, text=None)
The arguments shown above are merely some common ones.
The full function signature is largely the same as that of :func:`run` -
most arguments are passed directly through to that interface.
- However, explicitly passing ``input=None`` to inherit the parent's
- standard input file handle is not supported.
+ One API deviation from :func:`run` behavior exists: passing ``input=None``
+ will behave the same as ``input=b''`` (or ``input=''``, depending on other
+ arguments) rather than using the parent's standard input file handle.
By default, this function will return the data as encoded bytes. The actual
encoding of the output data may depend on the command being invoked, so the
Return ``True`` if the symbol is local to its block.
+ .. method:: is_annotated()
+
+ Return ``True`` if the symbol is annotated.
+
+ .. versionadded:: 3.6
+
.. method:: is_free()
Return ``True`` if the symbol is referenced in its block, but not assigned
Notice that on Windows, it's a much smaller set.
-.. function:: get_config_vars(\*args)
+.. function:: get_config_vars(*args)
With no arguments, return a dictionary of all configuration variables
relevant for the current platform.
Added support for :mod:`lzma` compression.
-.. function:: open(name=None, mode='r', fileobj=None, bufsize=10240, \*\*kwargs)
+.. function:: open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs)
Return a :class:`TarFile` object for the pathname *name*. For detailed
information on :class:`TarFile` objects and the keyword arguments that are
Define match test with regular expression *patterns*.
-.. function:: run_unittest(\*classes)
+.. function:: run_unittest(*classes)
Execute :class:`unittest.TestCase` subclasses passed to the function. The
function scans the classes for methods starting with the prefix ``test_``
count information. *timing* enables a timestamp relative to when tracing was
started to be displayed.
- .. method:: run(cmd)
+ .. method:: run(cmd)
- Execute the command and gather statistics from the execution with
- the current tracing parameters. *cmd* must be a string or code object,
- suitable for passing into :func:`exec`.
+ Execute the command and gather statistics from the execution with
+ the current tracing parameters. *cmd* must be a string or code object,
+ suitable for passing into :func:`exec`.
- .. method:: runctx(cmd, globals=None, locals=None)
+ .. method:: runctx(cmd, globals=None, locals=None)
- Execute the command and gather statistics from the execution with the
- current tracing parameters, in the defined global and local
- environments. If not defined, *globals* and *locals* default to empty
- dictionaries.
+ Execute the command and gather statistics from the execution with the
+ current tracing parameters, in the defined global and local
+ environments. If not defined, *globals* and *locals* default to empty
+ dictionaries.
- .. method:: runfunc(func, /, *args, **kwds)
+ .. method:: runfunc(func, /, *args, **kwds)
- Call *func* with the given arguments under control of the :class:`Trace`
- object with the current tracing parameters.
+ Call *func* with the given arguments under control of the :class:`Trace`
+ object with the current tracing parameters.
- .. method:: results()
+ .. method:: results()
- Return a :class:`CoverageResults` object that contains the cumulative
- results of all previous calls to ``run``, ``runctx`` and ``runfunc``
- for the given :class:`Trace` instance. Does not reset the accumulated
- trace results.
+ Return a :class:`CoverageResults` object that contains the cumulative
+ results of all previous calls to ``run``, ``runctx`` and ``runfunc``
+ for the given :class:`Trace` instance. Does not reset the accumulated
+ trace results.
.. class:: CoverageResults
A container for coverage results, created by :meth:`Trace.results`. Should
not be created directly by the user.
- .. method:: update(other)
+ .. method:: update(other)
- Merge in data from another :class:`CoverageResults` object.
+ Merge in data from another :class:`CoverageResults` object.
- .. method:: write_results(show_missing=True, summary=False, coverdir=None)
+ .. method:: write_results(show_missing=True, summary=False, coverdir=None)
- Write coverage results. Set *show_missing* to show lines that had no
- hits. Set *summary* to include in the output the coverage summary per
- module. *coverdir* specifies the directory into which the coverage
- result files will be output. If ``None``, the results for each source
- file are placed in its directory.
+ Write coverage results. Set *show_missing* to show lines that had no
+ hits. Set *summary* to include in the output the coverage summary per
+ module. *coverdir* specifies the directory into which the coverage
+ result files will be output. If ``None``, the results for each source
+ file are placed in its directory.
A simple example demonstrating the use of the programmatic interface::
Return the angle between the line from turtle position to position specified
by (x,y), the vector or the other turtle. This depends on the turtle's start
- orientation which depends on the mode - "standard"/"world" or "logo").
+ orientation which depends on the mode - "standard"/"world" or "logo".
.. doctest::
:skipif: _tkinter is None
Set pencolor to the RGB color represented by *r*, *g*, and *b*. Each of
*r*, *g*, and *b* must be in the range 0..colormode.
- If turtleshape is a polygon, the outline of that polygon is drawn with the
- newly set pencolor.
+ If turtleshape is a polygon, the outline of that polygon is drawn with the
+ newly set pencolor.
.. doctest::
:skipif: _tkinter is None
Set fillcolor to the RGB color represented by *r*, *g*, and *b*. Each of
*r*, *g*, and *b* must be in the range 0..colormode.
- If turtleshape is a polygon, the interior of that polygon is drawn
- with the newly set fillcolor.
+ If turtleshape is a polygon, the interior of that polygon is drawn
+ with the newly set fillcolor.
.. doctest::
:skipif: _tkinter is None
Equivalent to ``pencolor(colorstring1)`` and ``fillcolor(colorstring2)``
and analogously if the other input format is used.
- If turtleshape is a polygon, outline and interior of that polygon is drawn
- with the newly set colors.
+ If turtleshape is a polygon, outline and interior of that polygon is drawn
+ with the newly set colors.
.. doctest::
:skipif: _tkinter is None
:param font: a triple (fontname, fontsize, fonttype)
Write text - the string representation of *arg* - at the current turtle
- position according to *align* ("left", "center" or right") and with the given
+ position according to *align* ("left", "center" or "right") and with the given
font. If *move* is true, the pen is moved to the bottom-right corner of the
text. By default, *move* is ``False``.
:func:`shapesize`.
- "noresize": no adaption of the turtle's appearance takes place.
- resizemode("user") is called by :func:`shapesize` when used with arguments.
+ ``resizemode("user")`` is called by :func:`shapesize` when used with arguments.
.. doctest::
:skipif: _tkinter is None
matrix as a tuple of 4 elements.
Otherwise set the given elements and transform the turtleshape
according to the matrix consisting of first row t11, t12 and
- second row t21, 22. The determinant t11 * t22 - t12 * t21 must not be
+ second row t21, t22. The determinant t11 * t22 - t12 * t21 must not be
zero, otherwise an error is raised.
Modify stretchfactor, shearfactor and tiltangle according to the
given matrix.
:param size: an integer or ``None``
- Set or disable undobuffer. If *size* is an integer an empty undobuffer of
+ Set or disable undobuffer. If *size* is an integer, an empty undobuffer of
given size is installed. *size* gives the maximum number of turtle actions
that can be undone by the :func:`undo` method/function. If *size* is
``None``, the undobuffer is disabled.
existing bindings are removed.
Example for a TurtleScreen instance named ``screen`` and a Turtle instance
- named turtle:
+ named ``turtle``:
.. doctest::
:skipif: _tkinter is None
.. function:: exitonclick()
- Bind bye() method to mouse clicks on the Screen.
+ Bind ``bye()`` method to mouse clicks on the Screen.
If the value "using_IDLE" in the configuration dictionary is ``False``
.. versionadded:: 3.9
+ .. versionchanged:: 3.9.2
+ This type can now be subclassed.
+
.. class:: TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno)
``list[ForwardRef("SomeClass")]``. This class should not be instantiated by
a user, but may be used by introspection tools.
+ .. versionadded:: 3.7.4
+
Constant
--------
now raise :exc:`ValueError`.
-.. function:: parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None)
+.. function:: parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None, separator='&')
Parse a query string given as a string argument (data of type
:mimetype:`application/x-www-form-urlencoded`). Data are returned as a
read. If set, then throws a :exc:`ValueError` if there are more than
*max_num_fields* fields read.
+ The optional argument *separator* is the symbol to use for separating the
+ query arguments. It defaults to ``&``.
+
Use the :func:`urllib.parse.urlencode` function (with the ``doseq``
parameter set to ``True``) to convert such dictionaries into query
strings.
.. versionchanged:: 3.8
Added *max_num_fields* parameter.
+ .. versionchanged:: 3.9.2
+ Added *separator* parameter with the default value of ``&``. Python
+ versions earlier than Python 3.9.2 allowed using both ``;`` and ``&`` as
+ query parameter separator. This has been changed to allow only a single
+ separator key, with ``&`` as the default separator.
+
-.. function:: parse_qsl(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None)
+.. function:: parse_qsl(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None, separator='&')
Parse a query string given as a string argument (data of type
:mimetype:`application/x-www-form-urlencoded`). Data are returned as a list of
read. If set, then throws a :exc:`ValueError` if there are more than
*max_num_fields* fields read.
+ The optional argument *separator* is the symbol to use for separating the query arguments. It defaults to ``&``.
+
Use the :func:`urllib.parse.urlencode` function to convert such lists of pairs into
query strings.
.. versionchanged:: 3.8
Added *max_num_fields* parameter.
+ .. versionchanged:: 3.9.2
+ Added *separator* parameter with the default value of ``&``. Python
+ versions earlier than Python 3.9.2 allowed using both ``;`` and ``&`` as
+ query parameter separator. This has been changed to allow only a single
+ separator key, with ``&`` as the default separator.
+
.. function:: urlunparse(parts)
Available Context Managers
--------------------------
-.. class:: catch_warnings(\*, record=False, module=None)
+.. class:: catch_warnings(*, record=False, module=None)
A context manager that copies and, upon exit, restores the warnings filter
and the :func:`showwarning` function.
.. method:: PyHKEY.__enter__()
- PyHKEY.__exit__(\*exc_info)
+ PyHKEY.__exit__(*exc_info)
The HKEY object implements :meth:`~object.__enter__` and
:meth:`~object.__exit__` and thus supports the context protocol for the
analyze, test, perform and/or display publicly, prepare derivative works,
distribute, and otherwise use Python |release| alone or in any derivative
version, provided, however, that PSF's License Agreement and PSF's notice of
- copyright, i.e., "Copyright © 2001-2020 Python Software Foundation; All Rights
+ copyright, i.e., "Copyright © 2001-2021 Python Software Foundation; All Rights
Reserved" are retained in Python |release| alone or in any derivative version
prepared by Licensee.
expression, that expression is evaluated, and the clause matches the exception
if the resulting object is "compatible" with the exception. An object is
compatible with an exception if it is the class or a base class of the exception
-object or a tuple containing an item compatible with the exception.
+object, or a tuple containing an item that is the class or a base class of
+the exception object.
If no except clause matches the exception, the search for an exception handler
continues in the surrounding code and on the invocation stack. [#]_
.. productionlist:: python-grammar
async_for_stmt: "async" `for_stmt`
-An :term:`asynchronous iterable` is able to call asynchronous code in its
-*iter* implementation, and :term:`asynchronous iterator` can call asynchronous
-code in its *next* method.
+An :term:`asynchronous iterable` provides an ``__aiter__`` method that directly
+returns an :term:`asynchronous iterator`, which can call asynchronous code in
+its ``__anext__`` method.
The ``async for`` statement allows convenient iteration over asynchronous
-iterators.
+iterables.
The following code::
There are two types of integers:
Integers (:class:`int`)
-
These represent numbers in an unlimited range, subject to available (virtual)
memory only. For the purpose of shift and mask operations, a binary
representation is assumed, and negative numbers are represented in a variant of
library/ipaddress,,::,2001:db00::0/ffff:ff00::
library/itertools,,:step,elements from seq[start:stop:step]
library/itertools,,:stop,elements from seq[start:stop:step]
+library/itertools,,::,kernel = tuple(kernel)[::-1]
library/logging.handlers,,:port,host:port
library/mmap,,:i2,obj[i1:i2]
library/multiprocessing,,`,# Add more tasks using `put()`
| | PowerShell | PS C:\\> <venv>\\Scripts\\Activate.ps1 |
+-------------+-----------------+-----------------------------------------+
+When a virtual environment is active, the :envvar:`VIRTUAL_ENV` environment
+variable is set to the path of the virtual environment. This can be used to
+check if one is running inside a virtual environment.
+
You don't specifically *need* to activate an environment; activation just
prepends the virtual environment's binary directory to your path, so that
"python" invokes the virtual environment's Python interpreter and you can run
Instead, it will write to a private copy. If your scripts must modify the
shared locations, you will need to install the full installer.
+For more detail on the technical basis for these limitations, please consult
+Microsoft's documentation on packaged full-trust apps, currently available at
+`docs.microsoft.com/en-us/windows/msix/desktop/desktop-to-uwp-behind-the-scenes
+<https://docs.microsoft.com/en-us/windows/msix/desktop/desktop-to-uwp-behind-the-scenes>`_
+
.. _windows-nuget:
MinGW gcc under Windows" or "Installing Python extension with distutils
and without Microsoft Visual C++" by Sébastien Sauvage, 2003
- `MingW -- Python extensions <http://www.mingw.org/wiki/FAQ#toc14>`_
-
Other Platforms
===============
details, see the documentation for ``loop.create_datagram_endpoint()``.
(Contributed by Kyle Stanley, Antoine Pitrou, and Yury Selivanov in
:issue:`37228`.)
+
+Notable changes in Python 3.6.13
+================================
+
+Earlier Python versions allowed using both ``;`` and ``&`` as
+query parameter separators in :func:`urllib.parse.parse_qs` and
+:func:`urllib.parse.parse_qsl`. Due to security concerns, and to conform with
+newer W3C recommendations, this has been changed to allow only a single
+separator key, with ``&`` as the default. This change also affects
+:func:`cgi.parse` and :func:`cgi.parse_multipart` as they use the affected
+functions internally. For more details, please see their respective
+documentation.
+(Contributed by Adam Goldschmidt, Senthil Kumaran and Ken Jin in :issue:`42967`.)
details, see the documentation for ``loop.create_datagram_endpoint()``.
(Contributed by Kyle Stanley, Antoine Pitrou, and Yury Selivanov in
:issue:`37228`.)
+
+Notable changes in Python 3.7.10
+================================
+
+Earlier Python versions allowed using both ``;`` and ``&`` as
+query parameter separators in :func:`urllib.parse.parse_qs` and
+:func:`urllib.parse.parse_qsl`. Due to security concerns, and to conform with
+newer W3C recommendations, this has been changed to allow only a single
+separator key, with ``&`` as the default. This change also affects
+:func:`cgi.parse` and :func:`cgi.parse_multipart` as they use the affected
+functions internally. For more details, please see their respective
+documentation.
+(Contributed by Adam Goldschmidt, Senthil Kumaran and Ken Jin in :issue:`42967`.)
details, see the documentation for ``loop.create_datagram_endpoint()``.
(Contributed by Kyle Stanley, Antoine Pitrou, and Yury Selivanov in
:issue:`37228`.)
+
+Notable changes in Python 3.8.8
+===============================
+
+Earlier Python versions allowed using both ``;`` and ``&`` as
+query parameter separators in :func:`urllib.parse.parse_qs` and
+:func:`urllib.parse.parse_qsl`. Due to security concerns, and to conform with
+newer W3C recommendations, this has been changed to allow only a single
+separator key, with ``&`` as the default. This change also affects
+:func:`cgi.parse` and :func:`cgi.parse_multipart` as they use the affected
+functions internally. For more details, please see their respective
+documentation.
+(Contributed by Adam Goldschmidt, Senthil Kumaran and Ken Jin in :issue:`42967`.)
version in use at runtime ("weaklinking").
(Contributed by Ronald Oussoren and Lawrence D'Anna in :issue:`41100`.)
+
+Notable changes in Python 3.9.2
+===============================
+
+collections.abc
+---------------
+
+:class:`collections.abc.Callable` generic now flattens type parameters, similar
+to what :data:`typing.Callable` currently does. This means that
+``collections.abc.Callable[[int, str], str]`` will have ``__args__`` of
+``(int, str, str)``; previously this was ``([int, str], str)``. To allow this
+change, :class:`types.GenericAlias` can now be subclassed, and a subclass will
+be returned when subscripting the :class:`collections.abc.Callable` type.
+Code which accesses the arguments via :func:`typing.get_args` or ``__args__``
+need to account for this change. A :exc:`DeprecationWarning` may be emitted for
+invalid forms of parameterizing :class:`collections.abc.Callable` which may have
+passed silently in Python 3.9.1. This :exc:`DeprecationWarning` will
+become a :exc:`TypeError` in Python 3.10.
+(Contributed by Ken Jin in :issue:`42195`.)
+
+urllib.parse
+------------
+
+Earlier Python versions allowed using both ``;`` and ``&`` as
+query parameter separators in :func:`urllib.parse.parse_qs` and
+:func:`urllib.parse.parse_qsl`. Due to security concerns, and to conform with
+newer W3C recommendations, this has been changed to allow only a single
+separator key, with ``&`` as the default. This change also affects
+:func:`cgi.parse` and :func:`cgi.parse_multipart` as they use the affected
+functions internally. For more details, please see their respective
+documentation.
+(Contributed by Adam Goldschmidt, Senthil Kumaran and Ken Jin in :issue:`42967`.)
| a=star_target !',' { a }
| a=star_target b=(',' c=star_target { c })* [','] {
_Py_Tuple(CHECK(_PyPegen_seq_insert_in_front(p, a, b)), Store, EXTRA) }
-star_targets_seq[asdl_seq*]: a=','.star_target+ [','] { a }
+star_targets_list_seq[asdl_seq*]: a=','.star_target+ [','] { a }
+star_targets_tuple_seq[asdl_seq*]:
+ | a=star_target b=(',' c=star_target { c })+ [','] { _PyPegen_seq_insert_in_front(p, a, b) }
+ | a=star_target ',' { _PyPegen_singleton_seq(p, a) }
star_target[expr_ty] (memo):
| '*' a=(!'*' star_target) {
_Py_Starred(CHECK(_PyPegen_set_expr_context(p, a, Store)), Store, EXTRA) }
+ | target_with_star_atom
+target_with_star_atom[expr_ty] (memo):
| a=t_primary '.' b=NAME !t_lookahead { _Py_Attribute(a, b->v.Name.id, Store, EXTRA) }
| a=t_primary '[' b=slices ']' !t_lookahead { _Py_Subscript(a, b, Store, EXTRA) }
| star_atom
star_atom[expr_ty]:
| a=NAME { _PyPegen_set_expr_context(p, a, Store) }
- | '(' a=star_target ')' { _PyPegen_set_expr_context(p, a, Store) }
- | '(' a=[star_targets_seq] ')' { _Py_Tuple(a, Store, EXTRA) }
- | '[' a=[star_targets_seq] ']' { _Py_List(a, Store, EXTRA) }
+ | '(' a=target_with_star_atom ')' { _PyPegen_set_expr_context(p, a, Store) }
+ | '(' a=[star_targets_tuple_seq] ')' { _Py_Tuple(a, Store, EXTRA) }
+ | '[' a=[star_targets_list_seq] ']' { _Py_List(a, Store, EXTRA) }
single_target[expr_ty]:
| single_subscript_attribute_target
{
PyTypeObject *tp;
Py_ssize_t offset;
- vectorcallfunc *ptr;
+ vectorcallfunc ptr;
assert(callable != NULL);
tp = Py_TYPE(callable);
assert(PyCallable_Check(callable));
offset = tp->tp_vectorcall_offset;
assert(offset > 0);
- ptr = (vectorcallfunc *)(((char *)callable) + offset);
- return *ptr;
+ memcpy(&ptr, (char *) callable + offset, sizeof(ptr));
+ return ptr;
}
/* Call the callable object 'callable' with the "vectorcall" calling
*/
#define Py_UNICODE_ISSPACE(ch) \
- ((ch) < 128U ? _Py_ascii_whitespace[(ch)] : _PyUnicode_IsWhitespace(ch))
+ ((Py_UCS4)(ch) < 128U ? _Py_ascii_whitespace[(ch)] : _PyUnicode_IsWhitespace(ch))
#define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch)
#define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch)
Use of this API is DEPRECATED since no size information can be
extracted from the returned data.
-
- *** This API is for interpreter INTERNAL USE ONLY and will likely
- *** be removed or changed for Python 3.1.
-
- *** If you need to access the Unicode object as UTF-8 bytes string,
- *** please use PyUnicode_AsUTF8String() instead.
-
*/
PyAPI_FUNC(const char *) PyUnicode_AsUTF8(PyObject *unicode);
/*--start constants--*/
#define PY_MAJOR_VERSION 3
#define PY_MINOR_VERSION 9
-#define PY_MICRO_VERSION 1
+#define PY_MICRO_VERSION 2
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL
#define PY_RELEASE_SERIAL 0
/* Version as a string */
-#define PY_VERSION "3.9.1"
+#define PY_VERSION "3.9.2"
/*--end constants--*/
/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.
/* Bootstrap __main__ (defined in Modules/main.c) */
PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv);
+PyAPI_FUNC(int) Py_FrozenMain(int argc, char **argv);
+
PyAPI_FUNC(int) Py_BytesMain(int argc, char **argv);
/* In pathconfig.c */
distribute, and otherwise use Python alone or in any derivative version,
provided, however, that PSF's License Agreement and PSF's notice of copyright,
i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Python Software Foundation;
+2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Python Software Foundation;
All Rights Reserved" are retained in Python alone or in any derivative version
prepared by Licensee.
import sys
GenericAlias = type(list[int])
+EllipsisType = type(...)
+def _f(): pass
+FunctionType = type(_f)
+del _f
__all__ = ["Awaitable", "Coroutine",
"AsyncIterable", "AsyncIterator", "AsyncGenerator",
return NotImplemented
+class _CallableGenericAlias(GenericAlias):
+ """ Represent `Callable[argtypes, resulttype]`.
+
+ This sets ``__args__`` to a tuple containing the flattened``argtypes``
+ followed by ``resulttype``.
+
+ Example: ``Callable[[int, str], float]`` sets ``__args__`` to
+ ``(int, str, float)``.
+ """
+
+ __slots__ = ()
+
+ def __new__(cls, origin, args):
+ try:
+ return cls.__create_ga(origin, args)
+ except TypeError as exc:
+ import warnings
+ warnings.warn(f'{str(exc)} '
+ f'(This will raise a TypeError in Python 3.10.)',
+ DeprecationWarning)
+ return GenericAlias(origin, args)
+
+ @classmethod
+ def __create_ga(cls, origin, args):
+ if not isinstance(args, tuple) or len(args) != 2:
+ raise TypeError(
+ "Callable must be used as Callable[[arg, ...], result].")
+ t_args, t_result = args
+ if isinstance(t_args, (list, tuple)):
+ ga_args = tuple(t_args) + (t_result,)
+ # This relaxes what t_args can be on purpose to allow things like
+ # PEP 612 ParamSpec. Responsibility for whether a user is using
+ # Callable[...] properly is deferred to static type checkers.
+ else:
+ ga_args = args
+ return super().__new__(cls, origin, ga_args)
+
+ def __repr__(self):
+ if len(self.__args__) == 2 and self.__args__[0] is Ellipsis:
+ return super().__repr__()
+ return (f'collections.abc.Callable'
+ f'[[{", ".join([_type_repr(a) for a in self.__args__[:-1]])}], '
+ f'{_type_repr(self.__args__[-1])}]')
+
+ def __reduce__(self):
+ args = self.__args__
+ if not (len(args) == 2 and args[0] is Ellipsis):
+ args = list(args[:-1]), args[-1]
+ return _CallableGenericAlias, (Callable, args)
+
+ def __getitem__(self, item):
+ # Called during TypeVar substitution, returns the custom subclass
+ # rather than the default types.GenericAlias object.
+ ga = super().__getitem__(item)
+ args = ga.__args__
+ t_result = args[-1]
+ t_args = args[:-1]
+ args = (t_args, t_result)
+ return _CallableGenericAlias(Callable, args)
+
+
+def _type_repr(obj):
+ """Return the repr() of an object, special-casing types (internal helper).
+
+ Copied from :mod:`typing` since collections.abc
+ shouldn't depend on that module.
+ """
+ if isinstance(obj, GenericAlias):
+ return repr(obj)
+ if isinstance(obj, type):
+ if obj.__module__ == 'builtins':
+ return obj.__qualname__
+ return f'{obj.__module__}.{obj.__qualname__}'
+ if obj is Ellipsis:
+ return '...'
+ if isinstance(obj, FunctionType):
+ return obj.__name__
+ return repr(obj)
+
+
class Callable(metaclass=ABCMeta):
__slots__ = ()
return _check_methods(C, "__call__")
return NotImplemented
- __class_getitem__ = classmethod(GenericAlias)
+ __class_getitem__ = classmethod(_CallableGenericAlias)
### SETS ###
return fut.result()
else:
fut.remove_done_callback(cb)
- fut.cancel()
+ # We must ensure that the task is not running
+ # after wait_for() returns.
+ # See https://bugs.python.org/issue32751
+ await _cancel_and_wait(fut, loop=loop)
raise
if fut.done():
def close(self):
self._callbacks.clear()
- if self._saved_sighandler is not None:
- handler = signal.getsignal(signal.SIGCHLD)
- if handler != self._sig_chld:
- logger.warning("SIGCHLD handler was changed by outside code")
- else:
- signal.signal(signal.SIGCHLD, self._saved_sighandler)
- self._saved_sighandler = None
+ if self._saved_sighandler is None:
+ return
+
+ handler = signal.getsignal(signal.SIGCHLD)
+ if handler != self._sig_chld:
+ logger.warning("SIGCHLD handler was changed by outside code")
+ else:
+ signal.signal(signal.SIGCHLD, self._saved_sighandler)
+ self._saved_sighandler = None
def __enter__(self):
return self
# The reason to do it here is that attach_loop() is called from
# unix policy only for the main thread.
# Main thread is required for subscription on SIGCHLD signal
+ if self._saved_sighandler is not None:
+ return
+
+ self._saved_sighandler = signal.signal(signal.SIGCHLD, self._sig_chld)
if self._saved_sighandler is None:
- self._saved_sighandler = signal.signal(signal.SIGCHLD, self._sig_chld)
- if self._saved_sighandler is None:
- logger.warning("Previous SIGCHLD handler was set by non-Python code, "
- "restore to default handler on watcher close.")
- self._saved_sighandler = signal.SIG_DFL
+ logger.warning("Previous SIGCHLD handler was set by non-Python code, "
+ "restore to default handler on watcher close.")
+ self._saved_sighandler = signal.SIG_DFL
- # Set SA_RESTART to limit EINTR occurrences.
- signal.siginterrupt(signal.SIGCHLD, False)
+ # Set SA_RESTART to limit EINTR occurrences.
+ signal.siginterrupt(signal.SIGCHLD, False)
def _do_waitpid_all(self):
for pid in list(self._callbacks):
global _a85chars, _a85chars2
# Delay the initialization of tables to not waste memory
# if the function is never called
- if _a85chars is None:
+ if _a85chars2 is None:
_a85chars = [bytes((i,)) for i in range(33, 118)]
_a85chars2 = [(a + b) for a in _a85chars for b in _a85chars]
global _b85chars, _b85chars2
# Delay the initialization of tables to not waste memory
# if the function is never called
- if _b85chars is None:
+ if _b85chars2 is None:
_b85chars = [bytes((i,)) for i in _b85alphabet]
_b85chars2 = [(a + b) for a in _b85chars for b in _b85chars]
return _85encode(b, _b85chars, _b85chars2, pad)
'__package__': None,
'__cached__': None,
}
- runctx(code, globs, None, options.outfile, options.sort)
+ try:
+ runctx(code, globs, None, options.outfile, options.sort)
+ except BrokenPipeError as exc:
+ # Prevent "Exception ignored" during interpreter shutdown.
+ sys.stdout = None
+ sys.exit(exc.errno)
else:
parser.print_usage()
return parser
# 0 ==> unlimited input
maxlen = 0
-def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0):
+def parse(fp=None, environ=os.environ, keep_blank_values=0,
+ strict_parsing=0, separator='&'):
"""Parse a query in the environment or from a file (default stdin)
Arguments, all optional:
strict_parsing: flag indicating what to do with parsing errors.
If false (the default), errors are silently ignored.
If true, errors raise a ValueError exception.
+
+ separator: str. The symbol to use for separating the query arguments.
+ Defaults to &.
"""
if fp is None:
fp = sys.stdin
if environ['REQUEST_METHOD'] == 'POST':
ctype, pdict = parse_header(environ['CONTENT_TYPE'])
if ctype == 'multipart/form-data':
- return parse_multipart(fp, pdict)
+ return parse_multipart(fp, pdict, separator=separator)
elif ctype == 'application/x-www-form-urlencoded':
clength = int(environ['CONTENT_LENGTH'])
if maxlen and clength > maxlen:
qs = ""
environ['QUERY_STRING'] = qs # XXX Shouldn't, really
return urllib.parse.parse_qs(qs, keep_blank_values, strict_parsing,
- encoding=encoding)
+ encoding=encoding, separator=separator)
-def parse_multipart(fp, pdict, encoding="utf-8", errors="replace"):
+def parse_multipart(fp, pdict, encoding="utf-8", errors="replace", separator='&'):
"""Parse multipart input.
Arguments:
except KeyError:
pass
fs = FieldStorage(fp, headers=headers, encoding=encoding, errors=errors,
- environ={'REQUEST_METHOD': 'POST'})
+ environ={'REQUEST_METHOD': 'POST'}, separator=separator)
return {k: fs.getlist(k) for k in fs}
def _parseparam(s):
def __init__(self, fp=None, headers=None, outerboundary=b'',
environ=os.environ, keep_blank_values=0, strict_parsing=0,
limit=None, encoding='utf-8', errors='replace',
- max_num_fields=None):
+ max_num_fields=None, separator='&'):
"""Constructor. Read multipart/* until last part.
Arguments, all optional:
self.keep_blank_values = keep_blank_values
self.strict_parsing = strict_parsing
self.max_num_fields = max_num_fields
+ self.separator = separator
if 'REQUEST_METHOD' in environ:
method = environ['REQUEST_METHOD'].upper()
self.qs_on_post = None
query = urllib.parse.parse_qsl(
qs, self.keep_blank_values, self.strict_parsing,
encoding=self.encoding, errors=self.errors,
- max_num_fields=self.max_num_fields)
+ max_num_fields=self.max_num_fields, separator=self.separator)
self.list = [MiniFieldStorage(key, value) for key, value in query]
self.skip_lines()
query = urllib.parse.parse_qsl(
self.qs_on_post, self.keep_blank_values, self.strict_parsing,
encoding=self.encoding, errors=self.errors,
- max_num_fields=self.max_num_fields)
+ max_num_fields=self.max_num_fields, separator=self.separator)
self.list.extend(MiniFieldStorage(key, value) for key, value in query)
klass = self.FieldStorageClass or self.__class__
else self.limit - self.bytes_read
part = klass(self.fp, headers, ib, environ, keep_blank_values,
strict_parsing, limit,
- self.encoding, self.errors, max_num_fields)
+ self.encoding, self.errors, max_num_fields, self.separator)
if max_num_fields is not None:
max_num_fields -= 1
def reset(self):
- """ Flushes and resets the codec buffers used for keeping state.
+ """ Resets the codec buffers used for keeping internal state.
Calling this method should ensure that the data on the
output is put into a clean state, that allows appending
def reset(self):
- """ Resets the codec buffers used for keeping state.
+ """ Resets the codec buffers used for keeping internal state.
Note that no stream repositioning should take place.
This method is primarily intended to be able to recover
namespace = {
'_tuple_new': tuple_new,
- '__builtins__': None,
+ '__builtins__': {},
'__name__': f'namedtuple_{typename}',
}
code = f'lambda _cls, {arg_list}: _tuple_new(_cls, ({arg_list}))'
from _collections_abc import *
from _collections_abc import __all__
+from _collections_abc import _CallableGenericAlias
with self.assertRaises(ZeroDivisionError):
WorseStruct().__setstate__({}, b'foo')
+ def test_parameter_repr(self):
+ from ctypes import (
+ c_bool,
+ c_char,
+ c_wchar,
+ c_byte,
+ c_ubyte,
+ c_short,
+ c_ushort,
+ c_int,
+ c_uint,
+ c_long,
+ c_ulong,
+ c_longlong,
+ c_ulonglong,
+ c_float,
+ c_double,
+ c_longdouble,
+ c_char_p,
+ c_wchar_p,
+ c_void_p,
+ )
+ self.assertRegex(repr(c_bool.from_param(True)), r"^<cparam '\?' at 0x[A-Fa-f0-9]+>$")
+ self.assertEqual(repr(c_char.from_param(97)), "<cparam 'c' ('a')>")
+ self.assertRegex(repr(c_wchar.from_param('a')), r"^<cparam 'u' at 0x[A-Fa-f0-9]+>$")
+ self.assertEqual(repr(c_byte.from_param(98)), "<cparam 'b' (98)>")
+ self.assertEqual(repr(c_ubyte.from_param(98)), "<cparam 'B' (98)>")
+ self.assertEqual(repr(c_short.from_param(511)), "<cparam 'h' (511)>")
+ self.assertEqual(repr(c_ushort.from_param(511)), "<cparam 'H' (511)>")
+ self.assertRegex(repr(c_int.from_param(20000)), r"^<cparam '[li]' \(20000\)>$")
+ self.assertRegex(repr(c_uint.from_param(20000)), r"^<cparam '[LI]' \(20000\)>$")
+ self.assertRegex(repr(c_long.from_param(20000)), r"^<cparam '[li]' \(20000\)>$")
+ self.assertRegex(repr(c_ulong.from_param(20000)), r"^<cparam '[LI]' \(20000\)>$")
+ self.assertRegex(repr(c_longlong.from_param(20000)), r"^<cparam '[liq]' \(20000\)>$")
+ self.assertRegex(repr(c_ulonglong.from_param(20000)), r"^<cparam '[LIQ]' \(20000\)>$")
+ self.assertEqual(repr(c_float.from_param(1.5)), "<cparam 'f' (1.5)>")
+ self.assertEqual(repr(c_double.from_param(1.5)), "<cparam 'd' (1.5)>")
+ self.assertEqual(repr(c_double.from_param(1e300)), "<cparam 'd' (1e+300)>")
+ self.assertRegex(repr(c_longdouble.from_param(1.5)), r"^<cparam ('d' \(1.5\)|'g' at 0x[A-Fa-f0-9]+)>$")
+ self.assertRegex(repr(c_char_p.from_param(b'hihi')), r"^<cparam 'z' \(0x[A-Fa-f0-9]+\)>$")
+ self.assertRegex(repr(c_wchar_p.from_param('hihi')), r"^<cparam 'Z' \(0x[A-Fa-f0-9]+\)>$")
+ self.assertRegex(repr(c_void_p.from_param(0x12)), r"^<cparam 'P' \(0x0*12\)>$")
+
################################################################
if __name__ == '__main__':
# This is again a requirement for a sane tzinfo class.
#
# 4. (x+k).s = x.s
-# This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
+# This follows from #2, and that datetime.timetz+timedelta preserves tzinfo.
#
# 5. (x+k).n = x.n + k
# Again follows from how arithmetic is defined.
global _cfg_target, _cfg_target_split
if _cfg_target is None:
from distutils import sysconfig
- _cfg_target = str(sysconfig.get_config_var(
- 'MACOSX_DEPLOYMENT_TARGET') or '')
+ _cfg_target = sysconfig.get_config_var(
+ 'MACOSX_DEPLOYMENT_TARGET') or ''
if _cfg_target:
_cfg_target_split = [int(x) for x in _cfg_target.split('.')]
if _cfg_target:
deptarget = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
if deptarget:
# increment the minor version number (i.e. 10.6 -> 10.7)
- deptarget = [int(x) for x in str(deptarget).split('.')]
+ deptarget = [int(x) for x in deptarget.split('.')]
deptarget[-1] += 1
deptarget = '.'.join(str(i) for i in deptarget)
self._try_compile_deployment_target('<', deptarget)
# get the deployment target that the interpreter was built with
target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
- target = tuple(map(int, str(target).split('.')[0:2]))
+ target = tuple(map(int, target.split('.')[0:2]))
# format the target value as defined in the Apple
# Availability Macros. We can't use the macro names since
# at least one value we test with will not exist yet.
def _is_descriptor(obj):
- """Returns True if obj is a descriptor, False otherwise."""
+ """
+ Returns True if obj is a descriptor, False otherwise.
+ """
return (
hasattr(obj, '__get__') or
hasattr(obj, '__set__') or
- hasattr(obj, '__delete__'))
-
+ hasattr(obj, '__delete__')
+ )
def _is_dunder(name):
- """Returns True if a __dunder__ name, False otherwise."""
- return (len(name) > 4 and
+ """
+ Returns True if a __dunder__ name, False otherwise.
+ """
+ return (
+ len(name) > 4 and
name[:2] == name[-2:] == '__' and
name[2] != '_' and
- name[-3] != '_')
-
+ name[-3] != '_'
+ )
def _is_sunder(name):
- """Returns True if a _sunder_ name, False otherwise."""
- return (len(name) > 2 and
+ """
+ Returns True if a _sunder_ name, False otherwise.
+ """
+ return (
+ len(name) > 2 and
name[0] == name[-1] == '_' and
name[1:2] != '_' and
- name[-2:-1] != '_')
-
+ name[-2:-1] != '_'
+ )
+
+def _is_private(cls_name, name):
+ # do not use `re` as `re` imports `enum`
+ pattern = '_%s__' % (cls_name, )
+ if (
+ len(name) >= 5
+ and name.startswith(pattern)
+ and name[len(pattern)] != '_'
+ and (name[-1] != '_' or name[-2] != '_')
+ ):
+ return True
+ else:
+ return False
def _make_class_unpicklable(cls):
- """Make the given class un-picklable."""
+ """
+ Make the given class un-picklable.
+ """
def _break_on_call_reduce(self, proto):
raise TypeError('%r cannot be pickled' % self)
cls.__reduce_ex__ = _break_on_call_reduce
class _EnumDict(dict):
- """Track enum member order and ensure member names are not reused.
+ """
+ Track enum member order and ensure member names are not reused.
EnumMeta will use the names found in self._member_names as the
enumeration member names.
-
"""
def __init__(self):
super().__init__()
self._auto_called = False
def __setitem__(self, key, value):
- """Changes anything not dundered or not a descriptor.
+ """
+ Changes anything not dundered or not a descriptor.
If an enum member name is used twice, an error is raised; duplicate
values are not checked for.
Single underscore (sunder) names are reserved.
-
"""
+ if _is_private(self._cls_name, key):
+ import warnings
+ warnings.warn(
+ "private variables, such as %r, will be normal attributes in 3.10"
+ % (key, ),
+ DeprecationWarning,
+ stacklevel=2,
+ )
if _is_sunder(key):
if key not in (
'_order_', '_create_pseudo_member_',
self._ignore = value
already = set(value) & set(self._member_names)
if already:
- raise ValueError('_ignore_ cannot specify already set names: %r' % (already, ))
+ raise ValueError(
+ '_ignore_ cannot specify already set names: %r'
+ % (already, )
+ )
elif _is_dunder(key):
if key == '__order__':
key = '_order_'
raise TypeError('%r already defined as: %r' % (key, self[key]))
if isinstance(value, auto):
if value.value == _auto_null:
- value.value = self._generate_next_value(key, 1, len(self._member_names), self._last_values[:])
+ value.value = self._generate_next_value(
+ key,
+ 1,
+ len(self._member_names),
+ self._last_values[:],
+ )
self._auto_called = True
value = value.value
self._member_names.append(key)
# This is also why there are checks in EnumMeta like `if Enum is not None`
Enum = None
-
class EnumMeta(type):
- """Metaclass for Enum"""
+ """
+ Metaclass for Enum
+ """
@classmethod
- def __prepare__(metacls, cls, bases):
+ def __prepare__(metacls, cls, bases, **kwds):
# check that previous enum members do not exist
metacls._check_for_existing_members(cls, bases)
# create the namespace dict
enum_dict = _EnumDict()
+ enum_dict._cls_name = cls
# inherit previous flags and _generate_next_value_ function
member_type, first_enum = metacls._get_mixins_(cls, bases)
if first_enum is not None:
- enum_dict['_generate_next_value_'] = getattr(first_enum, '_generate_next_value_', None)
+ enum_dict['_generate_next_value_'] = getattr(
+ first_enum, '_generate_next_value_', None,
+ )
return enum_dict
- def __new__(metacls, cls, bases, classdict):
+ def __new__(metacls, cls, bases, classdict, **kwds):
# an Enum class is final once enumeration items have been defined; it
# cannot be mixed with other types (int, float, etc.) if it has an
# inherited __new__ unless a new __new__ is defined (or the resulting
for key in ignore:
classdict.pop(key, None)
member_type, first_enum = metacls._get_mixins_(cls, bases)
- __new__, save_new, use_args = metacls._find_new_(classdict, member_type,
- first_enum)
+ __new__, save_new, use_args = metacls._find_new_(
+ classdict, member_type, first_enum,
+ )
# save enum items into separate mapping so they don't get baked into
# the new class
if '__doc__' not in classdict:
classdict['__doc__'] = 'An enumeration.'
- # create our new Enum type
- enum_class = super().__new__(metacls, cls, bases, classdict)
+ enum_class = super().__new__(metacls, cls, bases, classdict, **kwds)
enum_class._member_names_ = [] # names in definition order
enum_class._member_map_ = {} # name->value map
enum_class._member_type_ = member_type
# save DynamicClassAttribute attributes from super classes so we know
# if we can take the shortcut of storing members in the class dict
- dynamic_attributes = {k for c in enum_class.mro()
- for k, v in c.__dict__.items()
- if isinstance(v, DynamicClassAttribute)}
+ dynamic_attributes = {
+ k for c in enum_class.mro()
+ for k, v in c.__dict__.items()
+ if isinstance(v, DynamicClassAttribute)
+ }
# Reverse value->name map for hashable values.
enum_class._value2member_map_ = {}
return True
def __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1):
- """Either returns an existing member, or creates a new enum class.
+ """
+ Either returns an existing member, or creates a new enum class.
This method is used both when an enum class is given a value to match
to an enumeration member (i.e. Color(3)) and for the functional API
not correct, unpickling will fail in some circumstances.
`type`, if set, will be mixed in as the first base class.
-
"""
if names is None: # simple value lookup
return cls.__new__(cls, value)
# otherwise, functional API: we're creating a new Enum type
- return cls._create_(value, names, module=module, qualname=qualname, type=type, start=start)
+ return cls._create_(
+ value,
+ names,
+ module=module,
+ qualname=qualname,
+ type=type,
+ start=start,
+ )
def __contains__(cls, member):
if not isinstance(member, Enum):
# nicer error message when someone tries to delete an attribute
# (see issue19025).
if attr in cls._member_map_:
- raise AttributeError(
- "%s: cannot delete Enum member." % cls.__name__)
+ raise AttributeError("%s: cannot delete Enum member." % cls.__name__)
super().__delattr__(attr)
def __dir__(self):
- return (['__class__', '__doc__', '__members__', '__module__'] +
- self._member_names_)
+ return (
+ ['__class__', '__doc__', '__members__', '__module__']
+ + self._member_names_
+ )
def __getattr__(cls, name):
- """Return the enum member matching `name`
+ """
+ Return the enum member matching `name`
We use __getattr__ instead of descriptors or inserting into the enum
class' __dict__ in order to support `name` and `value` being both
properties for enum members (which live in the class' __dict__) and
enum members themselves.
-
"""
if _is_dunder(name):
raise AttributeError(name)
return cls._member_map_[name]
def __iter__(cls):
+ """
+ Returns members in definition order.
+ """
return (cls._member_map_[name] for name in cls._member_names_)
def __len__(cls):
@property
def __members__(cls):
- """Returns a mapping of member name->value.
+ """
+ Returns a mapping of member name->value.
This mapping lists all enum members, including aliases. Note that this
is a read-only view of the internal mapping.
-
"""
return MappingProxyType(cls._member_map_)
return "<enum %r>" % cls.__name__
def __reversed__(cls):
+ """
+ Returns members in reverse definition order.
+ """
return (cls._member_map_[name] for name in reversed(cls._member_names_))
def __setattr__(cls, name, value):
- """Block attempts to reassign Enum members.
+ """
+ Block attempts to reassign Enum members.
A simple assignment to the class namespace only changes one of the
several possible ways to get an Enum member from the Enum class,
resulting in an inconsistent Enumeration.
-
"""
member_map = cls.__dict__.get('_member_map_', {})
if name in member_map:
super().__setattr__(name, value)
def _create_(cls, class_name, names, *, module=None, qualname=None, type=None, start=1):
- """Convenience method to create a new Enum class.
+ """
+ Convenience method to create a new Enum class.
`names` can be:
* An iterable of member names. Values are incremented by 1 from `start`.
* An iterable of (member name, value) pairs.
* A mapping of member name -> value pairs.
-
"""
metacls = cls.__class__
bases = (cls, ) if type is None else (type, cls)
for chain in bases:
for base in chain.__mro__:
if issubclass(base, Enum) and base._member_names_:
- raise TypeError("%s: cannot extend enumeration %r" % (class_name, base.__name__))
+ raise TypeError(
+ "%s: cannot extend enumeration %r"
+ % (class_name, base.__name__)
+ )
@staticmethod
def _get_mixins_(class_name, bases):
- """Returns the type for creating enum members, and the first inherited
+ """
+ Returns the type for creating enum members, and the first inherited
enum class.
bases: the tuple of bases that was given to __new__
-
"""
if not bases:
return object, Enum
for base in chain.__mro__:
if base is object:
continue
+ elif issubclass(base, Enum):
+ if base._member_type_ is not object:
+ data_types.append(base._member_type_)
+ break
elif '__new__' in base.__dict__:
if issubclass(base, Enum):
continue
data_types.append(candidate or base)
break
- elif not issubclass(base, Enum):
+ else:
candidate = base
if len(data_types) > 1:
raise TypeError('%r: too many data types: %r' % (class_name, data_types))
@staticmethod
def _find_new_(classdict, member_type, first_enum):
- """Returns the __new__ to be used for creating the enum members.
+ """
+ Returns the __new__ to be used for creating the enum members.
classdict: the class dictionary given to __new__
member_type: the data type whose __new__ will be used by default
first_enum: enumeration to check for an overriding __new__
-
"""
# now find the correct __new__, checking to see of one was defined
# by the user; also check earlier enum classes in case a __new__ was
class Enum(metaclass=EnumMeta):
- """Generic enumeration.
+ """
+ Generic enumeration.
Derive from this class to define new enumerations.
-
"""
def __new__(cls, value):
# all enum instances are actually created during class construction
raise exc
def _generate_next_value_(name, start, count, last_values):
+ """
+ Generate the next value when not given.
+
+ name: the name of the member
+ start: the initial start value or None
+ count: the number of existing members
+ last_value: the last value assigned or None
+ """
for last_value in reversed(last_values):
try:
return last_value + 1
return "%s.%s" % (self.__class__.__name__, self._name_)
def __dir__(self):
+ """
+ Returns all members and all public methods
+ """
added_behavior = [
m
for cls in self.__class__.mro()
for m in cls.__dict__
if m[0] != '_' and m not in self._member_map_
- ]
+ ] + [m for m in self.__dict__ if m[0] != '_']
return (['__class__', '__doc__', '__module__'] + added_behavior)
def __format__(self, format_spec):
+ """
+ Returns format using actual value type unless __str__ has been overridden.
+ """
# mixed-in Enums should use the mixed-in type's __format__, otherwise
# we can get strange results with the Enum name showing up instead of
# the value
# pure Enum branch, or branch with __str__ explicitly overridden
- str_overridden = type(self).__str__ != Enum.__str__
+ str_overridden = type(self).__str__ not in (Enum.__str__, Flag.__str__)
if self._member_type_ is object or str_overridden:
cls = str
val = str(self)
return self.name
class Flag(Enum):
- """Support for flags"""
+ """
+ Support for flags
+ """
def _generate_next_value_(name, start, count, last_values):
"""
@classmethod
def _missing_(cls, value):
+ """
+ Returns member (possibly creating it) if one can be found for value.
+ """
original_value = value
if value < 0:
value = ~value
return pseudo_member
def __contains__(self, other):
+ """
+ Returns True if self has at least the same flags set as other.
+ """
if not isinstance(other, self.__class__):
raise TypeError(
"unsupported operand type(s) for 'in': '%s' and '%s'" % (
class IntFlag(int, Flag):
- """Support for integer-based Flags"""
+ """
+ Support for integer-based Flags
+ """
@classmethod
def _missing_(cls, value):
+ """
+ Returns member (possibly creating it) if one can be found for value.
+ """
if not isinstance(value, int):
raise ValueError("%r is not a valid %s" % (value, cls.__qualname__))
new_member = cls._create_pseudo_member_(value)
@classmethod
def _create_pseudo_member_(cls, value):
+ """
+ Create a composite member iff value contains only members.
+ """
pseudo_member = cls._value2member_map_.get(value, None)
if pseudo_member is None:
need_to_create = [value]
def _high_bit(value):
- """returns index of highest bit, or -1 if value is zero or negative"""
+ """
+ returns index of highest bit, or -1 if value is zero or negative
+ """
return value.bit_length() - 1
def unique(enumeration):
- """Class decorator for enumerations ensuring unique member values."""
+ """
+ Class decorator for enumerations ensuring unique member values.
+ """
duplicates = []
for name, member in enumeration.__members__.items():
if name != member.name:
return enumeration
def _decompose(flag, value):
- """Extract all members from the value."""
+ """
+ Extract all members from the value.
+ """
# _decompose is only called if the value is not named
not_covered = value
negative = value < 0
return re.compile(res).match
def filter(names, pat):
- """Return the subset of the list NAMES that match PAT."""
+ """Construct a list from those elements of the iterable NAMES that match PAT."""
result = []
pat = os.path.normcase(pat)
match = _compile_pattern(pat)
|"[^"]*" # LIT-enclosed value
|(?!['"])[^>\s]* # bare value
)
- (?:\s*,)* # possibly followed by a comma
+ \s* # possibly followed by a space
)?(?:\s|/(?!>))*
)*
)?
the endpoint passed to `set_tunnel`. This done by sending an HTTP
CONNECT request to the proxy server when the connection is established.
- This method must be called before the HTML connection has been
+ This method must be called before the HTTP connection has been
established.
The headers argument should be a mapping of extra HTTP headers to send
-What's New in IDLE 3.9.1
-Released on 2020-12-07?
+What's New in IDLE 3.9.2
+Released on 2021-02-15?
======================================
+bpo-23544: Disable Debug=>Stack Viewer when user code is running or
+Debugger is active, to prevent hang or crash. Patch by Zackery Spytz.
+
+bpo-43008: Make IDLE invoke :func:`sys.excepthook` in normal,
+2-process mode. Patch by Ken Hilton.
+
+bpo-33065: Fix problem debugging user classes with __repr__ method.
+
+bpo-32631: Finish zzdummy example extension module: make menu entries
+work; add docstrings and tests with 100% coverage.
+
+
+What's New in IDLE 3.9.1
+Released on 2020-12-07
+======================================
+
bpo-42508: Keep IDLE running on macOS. Remove obsolete workaround
that prevented running files with shortcuts when using new universal2
installers built on macOS 11.
enclosing block. The number of hint lines is determined by the maxlines
variable in the codecontext section of config-extensions.def. Lines which do
not open blocks are not shown in the context hints pane.
+
+For EditorWindows, <<toggle-code-context>> is bound to CodeContext(self).
+toggle_code_context_event.
"""
import re
from sys import maxsize as INFINITY
-import tkinter
+from tkinter import Frame, Text, TclError
from tkinter.constants import NSEW, SUNKEN
from idlelib.config import idleConf
if self.t1 is not None:
try:
self.text.after_cancel(self.t1)
- except tkinter.TclError: # pragma: no cover
+ except TclError: # pragma: no cover
pass
self.t1 = None
padx += widget.tk.getint(info['padx'])
padx += widget.tk.getint(widget.cget('padx'))
border += widget.tk.getint(widget.cget('border'))
- context = self.context = tkinter.Text(
+ context = self.context = Text(
self.editwin.text_frame,
height=1,
width=1, # Don't request more than we get.
line_number_colors = idleConf.GetHighlight(idleConf.CurrentTheme(),
'linenumber')
- self.cell00 = tkinter.Frame(self.editwin.text_frame,
+ self.cell00 = Frame(self.editwin.text_frame,
bg=line_number_colors['background'])
self.cell00.grid(row=0, column=0, sticky=NSEW)
menu_status = 'Hide'
self.text.after_cancel(self.t1)
self._reset()
menu_status = 'Show'
- self.editwin.update_menu_label(menu='options', index='* Code Context',
+ self.editwin.update_menu_label(menu='options', index='*ode*ontext',
label=f'{menu_status} Code Context')
return "break"
"""
try:
self.context.index("sel.first")
- except tkinter.TclError:
+ except TclError:
lines = len(self.info)
if lines == 1: # No context lines are showing.
newtop = 1
HORIZONTAL, VERTICAL, ANCHOR, ACTIVE, END)
from tkinter.ttk import (Frame, LabelFrame, Button, Checkbutton, Entry, Label,
OptionMenu, Notebook, Radiobutton, Scrollbar, Style)
-import tkinter.colorchooser as tkColorChooser
-import tkinter.font as tkFont
+from tkinter import colorchooser
+import tkinter.font as tkfont
from tkinter import messagebox
from idlelib.config import idleConf, ConfigChanges
font_bold = configured_font[2]=='bold'
# Set sorted no-duplicate editor font selection list and font_name.
- fonts = sorted(set(tkFont.families(self)))
+ fonts = sorted(set(tkfont.families(self)))
for font in fonts:
self.fontlist.insert(END, font)
self.font_name.set(font_name)
Updates font_sample and highlight page highlight_sample.
"""
font_name = self.font_name.get()
- font_weight = tkFont.BOLD if self.font_bold.get() else tkFont.NORMAL
+ font_weight = tkfont.BOLD if self.font_bold.get() else tkfont.NORMAL
new_font = (font_name, self.font_size.get(), font_weight)
self.font_sample['font'] = new_font
self.highlight_sample['font'] = new_font
target = self.highlight_target.get()
prev_color = self.style.lookup(self.frame_color_set['style'],
'background')
- rgbTuplet, color_string = tkColorChooser.askcolor(
+ rgbTuplet, color_string = colorchooser.askcolor(
parent=self, title='Pick new color for : '+target,
initialcolor=prev_color)
if color_string and (color_string != prev_color):
Shell Preferences: Auto-Squeeze Min. Lines is the minimum number of lines
of output to automatically "squeeze".
-'''
+''',
+ 'Extensions': '''
+ZzDummy: This extension is provided as an example for how to create and
+use an extension. Enable indicates whether the extension is active or
+not; likewise enable_editor and enable_shell indicate which windows it
+will be active on. For this extension, z-text is the text that will be
+inserted at or removed from the beginning of the lines of selected text,
+or the current line if no selection.
+''',
}
barrier, in particular frame and traceback objects.
"""
-
+import reprlib
import types
from idlelib import debugger
def dict_item(self, did, key):
dict = dicttable[did]
value = dict[key]
- value = repr(value) ### can't pickle module 'builtins'
+ value = reprlib.repr(value) ### can't pickle module 'builtins'
return value
#----------end class IdbAdapter----------
if __name__ == "__main__":
from unittest import main
- main('idlelib.idle_test.test_debugger', verbosity=2, exit=False)
+ main('idlelib.idle_test.test_debugger_r', verbosity=2, exit=False)
from tkinter import *
from tkinter.font import Font
from tkinter.ttk import Scrollbar
-import tkinter.simpledialog as tkSimpleDialog
-import tkinter.messagebox as tkMessageBox
+from tkinter import simpledialog
+from tkinter import messagebox
from idlelib.config import idleConf
from idlelib import configdialog
return release
-class EditorWindow(object):
+class EditorWindow:
from idlelib.percolator import Percolator
from idlelib.colorizer import ColorDelegator, color_config
from idlelib.undo import UndoDelegator
window.register_callback(self.postwindowsmenu)
# Some abstractions so IDLE extensions are cross-IDE
- self.askyesno = tkMessageBox.askyesno
- self.askinteger = tkSimpleDialog.askinteger
- self.showerror = tkMessageBox.showerror
+ self.askinteger = simpledialog.askinteger
+ self.askyesno = messagebox.askyesno
+ self.showerror = messagebox.showerror
# Add pseudoevents for former extension fixed keys.
# (This probably needs to be done once in the process.)
text.bind("<<toggle-code-context>>",
self.code_context.toggle_code_context_event)
else:
- self.update_menu_state('options', '*Code Context', 'disabled')
+ self.update_menu_state('options', '*ode*ontext', 'disabled')
if self.allow_line_numbers:
self.line_numbers = self.LineNumbers(self)
if idleConf.GetOption('main', 'EditorWindow',
self.toggle_line_numbers_event()
text.bind("<<toggle-line-numbers>>", self.toggle_line_numbers_event)
else:
- self.update_menu_state('options', '*Line Numbers', 'disabled')
+ self.update_menu_state('options', '*ine*umbers', 'disabled')
def handle_winconfig(self, event=None):
self.set_width()
self.menudict = menudict = {}
for name, label in self.menu_specs:
underline, label = prepstr(label)
- menudict[name] = menu = Menu(mbar, name=name, tearoff=0)
+ postcommand = getattr(self, f'{name}_menu_postcommand', None)
+ menudict[name] = menu = Menu(mbar, name=name, tearoff=0,
+ postcommand=postcommand)
mbar.add_cascade(label=label, menu=menu, underline=underline)
if macosx.isCarbonTk():
# Insert the application menu
try:
os.startfile(self.help_url)
except OSError as why:
- tkMessageBox.showerror(title='Document Start Failure',
+ messagebox.showerror(title='Document Start Failure',
message=str(why), parent=self.text)
else:
webbrowser.open(self.help_url)
try:
os.startfile(helpfile)
except OSError as why:
- tkMessageBox.showerror(title='Document Start Failure',
+ messagebox.showerror(title='Document Start Failure',
message=str(why), parent=self.text)
else:
webbrowser.open(helpfile)
except OSError as err:
if not getattr(self.root, "recentfiles_message", False):
self.root.recentfiles_message = True
- tkMessageBox.showwarning(title='IDLE Warning',
+ messagebox.showwarning(title='IDLE Warning',
message="Cannot save Recent Files list to disk.\n"
f" {err}\n"
"Select OK to continue.",
else:
self.line_numbers.show_sidebar()
menu_label = "Hide"
- self.update_menu_label(menu='options', index='*Line Numbers',
+ self.update_menu_label(menu='options', index='*ine*umbers',
label=f'{menu_label} Line Numbers')
# "line.col" -> line, as an int
return m.end(), len(m.group().expandtabs(tabwidth))
-class IndentSearcher(object):
+class IndentSearcher:
# .run() chews over the Text widget, looking for a block opener
# and the stmt following it. Returns a pair,
(There are a few more, but they are rarely useful.)
The extension class must not directly bind Window Manager (e.g. X) events.
-Rather, it must define one or more virtual events, e.g. <<zoom-height>>, and
-corresponding methods, e.g. zoom_height_event(). The virtual events will be
+Rather, it must define one or more virtual events, e.g. <<z-in>>, and
+corresponding methods, e.g. z_in_event(). The virtual events will be
bound to the corresponding methods, and Window Manager events can then be bound
to the virtual events. (This indirection is done so that the key bindings can
easily be changed, and so that other sources of virtual events can exist, such
implement. (They are also not required to create keybindings, but in that
case there must be empty bindings in cofig-extensions.def)
-Here is a complete example:
+Here is a partial example from zzdummy.py:
-class ZoomHeight:
+class ZzDummy:
menudefs = [
- ('edit', [
- None, # Separator
- ('_Zoom Height', '<<zoom-height>>'),
- ])
+ ('format', [
+ ('Z in', '<<z-in>>'),
+ ('Z out', '<<z-out>>'),
+ ] )
]
def __init__(self, editwin):
self.editwin = editwin
- def zoom_height_event(self, event):
+ def z_in_event(self, event=None):
"...Do what you want here..."
The final piece of the puzzle is the file "config-extensions.def", which is
"idlelib.filelist"
import os
-from tkinter import messagebox as tkMessageBox
+from tkinter import messagebox
class FileList:
filename = self.canonize(filename)
if os.path.isdir(filename):
# This can happen when bad filename is passed on command line:
- tkMessageBox.showerror(
+ messagebox.showerror(
"File Error",
"%r is a directory." % (filename,),
master=self.root)
if newkey in self.dict:
conflict = self.dict[newkey]
self.inversedict[conflict] = None
- tkMessageBox.showerror(
+ messagebox.showerror(
"Name Conflict",
"You now have multiple edit windows open for %r" % (filename,),
master=self.root)
class Mbox:
"""Mock for tkinter.messagebox with an Mbox_func for each function.
- This module was 'tkMessageBox' in 2.x; hence the 'import as' in 3.x.
Example usage in test_module.py for testing functions in module.py:
---
from idlelib.idle_test.mock_tk import Mbox
import module
-orig_mbox = module.tkMessageBox
+orig_mbox = module.messagebox
showerror = Mbox.showerror # example, for attribute access in test methods
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
- module.tkMessageBox = Mbox
+ module.messagebox = Mbox
@classmethod
def tearDownClass(cls):
- module.tkMessageBox = orig_mbox
+ module.messagebox = orig_mbox
---
For 'ask' functions, set func.result return value before calling the method
- that uses the message function. When tkMessageBox functions are the
+ that uses the message function. When messagebox functions are the
only gui alls in a method, this replacement makes the method gui-free,
"""
askokcancel = Mbox_func() # True or False
self.assertFalse(acp.open_completions(ac.TAB))
self.text.delete('1.0', 'end')
- class dummy_acw():
+ class dummy_acw:
__init__ = Func()
show_window = Func(result=False)
hide_window = Func()
# Test Class TC is used in multiple get_argspec test methods
-class TC():
+class TC:
'doc'
tip = "(ai=None, *b)"
def __init__(self, ai=None, *b): 'doc'
# open_calltip is about half the code; the others are fairly trivial.
# The default mocks are what are needed for open_calltip.
-class mock_Shell():
+class mock_Shell:
"Return mock sufficient to pass to hyperparser."
def __init__(self, text):
text.tag_prevrange = Mock(return_value=None)
}
code_sample = """\
-class C1():
+class C1:
# Class comment.
def __init__(self, a, b):
self.a = a
with self.assertRaises(AssertionError):
gc(1, stopline=0)
- eq(gc(3), ([(2, 0, 'class C1():', 'class')], 0))
+ eq(gc(3), ([(2, 0, 'class C1:', 'class')], 0))
# Don't return comment.
- eq(gc(4), ([(2, 0, 'class C1():', 'class')], 0))
+ eq(gc(4), ([(2, 0, 'class C1:', 'class')], 0))
# Two indentation levels and no comment.
- eq(gc(5), ([(2, 0, 'class C1():', 'class'),
+ eq(gc(5), ([(2, 0, 'class C1:', 'class'),
(4, 4, ' def __init__(self, a, b):', 'def')], 0))
# Only one 'def' is returned, not both at the same indent level.
- eq(gc(10), ([(2, 0, 'class C1():', 'class'),
+ eq(gc(10), ([(2, 0, 'class C1:', 'class'),
(7, 4, ' def compare(self):', 'def'),
(8, 8, ' if a > b:', 'if')], 0))
# With 'elif', also show the 'if' even though it's at the same level.
- eq(gc(11), ([(2, 0, 'class C1():', 'class'),
+ eq(gc(11), ([(2, 0, 'class C1:', 'class'),
(7, 4, ' def compare(self):', 'def'),
(8, 8, ' if a > b:', 'if'),
(10, 8, ' elif a < b:', 'elif')], 0))
# Set stop_line to not go back to first line in source code.
# Return includes stop_line.
- eq(gc(11, stopline=2), ([(2, 0, 'class C1():', 'class'),
+ eq(gc(11, stopline=2), ([(2, 0, 'class C1:', 'class'),
(7, 4, ' def compare(self):', 'def'),
(8, 8, ' if a > b:', 'if'),
(10, 8, ' elif a < b:', 'elif')], 0))
# Scroll down to line 2.
cc.text.yview(2)
cc.update_code_context()
- eq(cc.info, [(0, -1, '', False), (2, 0, 'class C1():', 'class')])
+ eq(cc.info, [(0, -1, '', False), (2, 0, 'class C1:', 'class')])
eq(cc.topvisible, 3)
- eq(cc.context.get('1.0', 'end-1c'), 'class C1():')
+ eq(cc.context.get('1.0', 'end-1c'), 'class C1:')
# Scroll down to line 3. Since it's a comment, nothing changes.
cc.text.yview(3)
cc.update_code_context()
- eq(cc.info, [(0, -1, '', False), (2, 0, 'class C1():', 'class')])
+ eq(cc.info, [(0, -1, '', False), (2, 0, 'class C1:', 'class')])
eq(cc.topvisible, 4)
- eq(cc.context.get('1.0', 'end-1c'), 'class C1():')
+ eq(cc.context.get('1.0', 'end-1c'), 'class C1:')
# Scroll down to line 4.
cc.text.yview(4)
cc.update_code_context()
eq(cc.info, [(0, -1, '', False),
- (2, 0, 'class C1():', 'class'),
+ (2, 0, 'class C1:', 'class'),
(4, 4, ' def __init__(self, a, b):', 'def')])
eq(cc.topvisible, 5)
- eq(cc.context.get('1.0', 'end-1c'), 'class C1():\n'
+ eq(cc.context.get('1.0', 'end-1c'), 'class C1:\n'
' def __init__(self, a, b):')
# Scroll down to line 11. Last 'def' is removed.
cc.text.yview(11)
cc.update_code_context()
eq(cc.info, [(0, -1, '', False),
- (2, 0, 'class C1():', 'class'),
+ (2, 0, 'class C1:', 'class'),
(7, 4, ' def compare(self):', 'def'),
(8, 8, ' if a > b:', 'if'),
(10, 8, ' elif a < b:', 'elif')])
eq(cc.topvisible, 12)
- eq(cc.context.get('1.0', 'end-1c'), 'class C1():\n'
+ eq(cc.context.get('1.0', 'end-1c'), 'class C1:\n'
' def compare(self):\n'
' if a > b:\n'
' elif a < b:')
cc.update_code_context()
cc.context_depth = 1
eq(cc.info, [(0, -1, '', False),
- (2, 0, 'class C1():', 'class'),
+ (2, 0, 'class C1:', 'class'),
(7, 4, ' def compare(self):', 'def'),
(8, 8, ' if a > b:', 'if'),
(10, 8, ' elif a < b:', 'elif')])
eq(cc.topvisible, 12)
- eq(cc.context.get('1.0', 'end-1c'), 'class C1():\n'
+ eq(cc.context.get('1.0', 'end-1c'), 'class C1:\n'
' def compare(self):\n'
' if a > b:\n'
' elif a < b:')
cc.text.yview(5)
cc.update_code_context()
eq(cc.info, [(0, -1, '', False),
- (2, 0, 'class C1():', 'class'),
+ (2, 0, 'class C1:', 'class'),
(4, 4, ' def __init__(self, a, b):', 'def')])
eq(cc.topvisible, 6)
# context_depth is 1.
# Line 1 is not a BLOCKOPENER.
eq(gli(lines[0]), (codecontext.INFINITY, '', False))
# Line 2 is a BLOCKOPENER without an indent.
- eq(gli(lines[1]), (0, 'class C1():', 'class'))
+ eq(gli(lines[1]), (0, 'class C1:', 'class'))
# Line 3 is not a BLOCKOPENER and does not return the indent level.
eq(gli(lines[2]), (codecontext.INFINITY, ' # Class comment.', False))
# Line 4 is a BLOCKOPENER and is indented.
def test_color(self):
d = self.page
d.on_new_color_set = Func()
- # self.color is only set in get_color through ColorChooser.
+ # self.color is only set in get_color through colorchooser.
d.color.set('green')
self.assertEqual(d.on_new_color_set.called, 1)
del d.on_new_color_set
def test_get_color(self):
eq = self.assertEqual
d = self.page
- orig_chooser = configdialog.tkColorChooser.askcolor
- chooser = configdialog.tkColorChooser.askcolor = Func()
+ orig_chooser = configdialog.colorchooser.askcolor
+ chooser = configdialog.colorchooser.askcolor = Func()
gntn = d.get_new_theme_name = Func()
d.highlight_target.set('Editor Breakpoint')
eq(d.color.get(), '#de0000')
del d.get_new_theme_name
- configdialog.tkColorChooser.askcolor = orig_chooser
+ configdialog.colorchooser.askcolor = orig_chooser
def test_on_new_color_set(self):
d = self.page
# Classes GUIProxy, IdbAdapter, FrameProxy, CodeProxy, DictProxy,
# GUIAdapter, IdbProxy plus 7 module functions.
+class IdbAdapterTest(unittest.TestCase):
+
+ def test_dict_item_noattr(self): # Issue 33065.
+
+ class BinData:
+ def __repr__(self):
+ return self.length
+
+ debugger_r.dicttable[0] = {'BinData': BinData()}
+ idb = debugger_r.IdbAdapter(None)
+ self.assertTrue(idb.dict_item(0, 'BinData'))
+ debugger_r.dicttable.clear()
+
+
if __name__ == '__main__':
unittest.main(verbosity=2)
code_sample = """\
# WS line needed for test.
-class C1():
+class C1:
# Class comment.
def __init__(self, a, b):
self.a = a
self.dialog.winfo_class()
-class Dummy_about_dialog():
+class Dummy_about_dialog:
# Dummy class for testing file display functions.
idle_credits = About.show_idle_credits
idle_readme = About.show_readme
# Reported as 88%; mocking turtledemo absence would have no point.
from idlelib import mainmenu
+import re
import unittest
def test_default_keydefs(self):
self.assertGreaterEqual(len(mainmenu.default_keydefs), 50)
+ def test_tcl_indexes(self):
+ # Test tcl patterns used to find menuitem to alter.
+ # On failure, change pattern here and in function(s).
+ # Patterns here have '.*' for re instead of '*' for tcl.
+ for menu, pattern in (
+ ('debug', '.*tack.*iewer'), # PyShell.debug_menu_postcommand
+ ('options', '.*ode.*ontext'), # EW.__init__, CodeContext.toggle...
+ ('options', '.*ine.*umbers'), # EW.__init__, EW.toggle...event.
+ ):
+ with self.subTest(menu=menu, pattern=pattern):
+ for menutup in mainmenu.menudefs:
+ if menutup[0] == menu:
+ break
+ else:
+ self.assertTrue(0, f"{menu} not in menudefs")
+ self.assertTrue(any(re.search(pattern, menuitem[0])
+ for menuitem in menutup[1]
+ if menuitem is not None), # Separator.
+ f"{pattern} not in {menu}")
+
if __name__ == '__main__':
unittest.main(verbosity=2)
# Split def across lines.
setcode('"""This is a module docstring"""\n'
- 'class C():\n'
+ 'class C:\n'
' def __init__(self, a,\n'
' b=True):\n'
' pass\n'
)
+ pos0, pos = 33, 42 # Start of 'class...', ' def' lines.
# Passing no value or non-callable should fail (issue 32989).
with self.assertRaises(TypeError):
# Make all text look like it's not in a string. This means that it
# found a good start position.
- eq(start(char_in_string_false), 44)
+ eq(start(char_in_string_false), pos)
# If the beginning of the def line is not in a string, then it
# returns that as the index.
- eq(start(is_char_in_string=lambda index: index > 44), 44)
+ eq(start(is_char_in_string=lambda index: index > pos), pos)
# If the beginning of the def line is in a string, then it
# looks for a previous index.
- eq(start(is_char_in_string=lambda index: index >= 44), 33)
+ eq(start(is_char_in_string=lambda index: index >= pos), pos0)
# If everything before the 'def' is in a string, then returns None.
# The non-continuation def line returns 44 (see below).
- eq(start(is_char_in_string=lambda index: index < 44), None)
+ eq(start(is_char_in_string=lambda index: index < pos), None)
# Code without extra line break in def line - mostly returns the same
# values.
setcode('"""This is a module docstring"""\n'
- 'class C():\n'
+ 'class C:\n'
' def __init__(self, a, b=True):\n'
' pass\n'
- )
- eq(start(char_in_string_false), 44)
- eq(start(is_char_in_string=lambda index: index > 44), 44)
- eq(start(is_char_in_string=lambda index: index >= 44), 33)
+ ) # Does not affect class, def positions.
+ eq(start(char_in_string_false), pos)
+ eq(start(is_char_in_string=lambda index: index > pos), pos)
+ eq(start(is_char_in_string=lambda index: index >= pos), pos0)
# When the def line isn't split, this returns which doesn't match the
# split line test.
- eq(start(is_char_in_string=lambda index: index < 44), 44)
+ eq(start(is_char_in_string=lambda index: index < pos), pos)
def test_set_lo(self):
code = (
'"""This is a module docstring"""\n'
- 'class C():\n'
+ 'class C:\n'
' def __init__(self, a,\n'
' b=True):\n'
' pass\n'
)
+ pos = 42
p = self.parser
p.set_code(code)
self.assertEqual(p.code, code)
# An index that is preceded by a newline.
- p.set_lo(44)
- self.assertEqual(p.code, code[44:])
+ p.set_lo(pos)
+ self.assertEqual(p.code, code[pos:])
def test_study1(self):
eq = self.assertEqual
from idlelib.idle_test.mock_tk import Mbox
import idlelib.searchengine as se
-orig_mbox = se.tkMessageBox
+orig_mbox = se.messagebox
showerror = Mbox.showerror
def setUpClass(cls):
cls.root = Tk()
cls.root.withdraw()
- se.tkMessageBox = Mbox
+ se.messagebox = Mbox
cls.engine = se.SearchEngine(cls.root)
cls.dialog = ReplaceDialog(cls.root, cls.engine)
cls.dialog.bell = lambda: None
@classmethod
def tearDownClass(cls):
- se.tkMessageBox = orig_mbox
+ se.messagebox = orig_mbox
del cls.text, cls.dialog, cls.engine
cls.root.destroy()
del cls.root
"Test run, coverage 49%."
from idlelib import run
+import io
+import sys
+from test.support import captured_output, captured_stderr
import unittest
from unittest import mock
+import idlelib
from idlelib.idle_test.mock_idle import Func
-from test.support import captured_output, captured_stderr
-import io
-import sys
+idlelib.testing = True # Use {} for executing test user code.
-class RunTest(unittest.TestCase):
+class PrintExceptionTest(unittest.TestCase):
def test_print_exception_unhashable(self):
class UnhashableException(Exception):
self.assertIn('IndexError', msg)
eq(func.called, 2)
+
+class ExecRuncodeTest(unittest.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.addClassCleanup(setattr,run,'print_exception',run.print_exception)
+ cls.prt = Func() # Need reference.
+ run.print_exception = cls.prt
+ mockrpc = mock.Mock()
+ mockrpc.console.getvar = Func(result=False)
+ cls.ex = run.Executive(mockrpc)
+
+ @classmethod
+ def tearDownClass(cls):
+ assert sys.excepthook == sys.__excepthook__
+
+ def test_exceptions(self):
+ ex = self.ex
+ ex.runcode('1/0')
+ self.assertIs(ex.user_exc_info[0], ZeroDivisionError)
+
+ self.addCleanup(setattr, sys, 'excepthook', sys.__excepthook__)
+ sys.excepthook = lambda t, e, tb: run.print_exception(t)
+ ex.runcode('1/0')
+ self.assertIs(self.prt.args[0], ZeroDivisionError)
+
+ sys.excepthook = lambda: None
+ ex.runcode('1/0')
+ t, e, tb = ex.user_exc_info
+ self.assertIs(t, TypeError)
+ self.assertTrue(isinstance(e.__context__, ZeroDivisionError))
+
+
if __name__ == '__main__':
unittest.main(verbosity=2)
import unittest
# from test.support import requires
from tkinter import BooleanVar, StringVar, TclError # ,Tk, Text
-import tkinter.messagebox as tkMessageBox
+from tkinter import messagebox
from idlelib.idle_test.mock_tk import Var, Mbox
from idlelib.idle_test.mock_tk import Text as mockText
import re
# Replace s-e module tkinter imports other than non-gui TclError.
se.BooleanVar = Var
se.StringVar = Var
- se.tkMessageBox = Mbox
+ se.messagebox = Mbox
def tearDownModule():
# Restore 'just in case', though other tests should also replace.
se.BooleanVar = BooleanVar
se.StringVar = StringVar
- se.tkMessageBox = tkMessageBox
+ se.messagebox = messagebox
class Mock:
expandingbutton.base_text = expandingbutton.text
# Patch the message box module to always return False.
- with patch('idlelib.squeezer.tkMessageBox') as mock_msgbox:
+ with patch('idlelib.squeezer.messagebox') as mock_msgbox:
mock_msgbox.askokcancel.return_value = False
mock_msgbox.askyesno.return_value = False
# Trigger the expand event.
self.assertEqual(expandingbutton.text.get('1.0', 'end-1c'), '')
# Patch the message box module to always return True.
- with patch('idlelib.squeezer.tkMessageBox') as mock_msgbox:
+ with patch('idlelib.squeezer.messagebox') as mock_msgbox:
mock_msgbox.askokcancel.return_value = True
mock_msgbox.askyesno.return_value = True
# Trigger the expand event.
--- /dev/null
+"Test zzdummy, coverage 100%."
+
+from idlelib import zzdummy
+import unittest
+from test.support import requires
+from tkinter import Tk, Text
+from unittest import mock
+from idlelib import config
+from idlelib import editor
+from idlelib import format
+
+
+usercfg = zzdummy.idleConf.userCfg
+testcfg = {
+ 'main': config.IdleUserConfParser(''),
+ 'highlight': config.IdleUserConfParser(''),
+ 'keys': config.IdleUserConfParser(''),
+ 'extensions': config.IdleUserConfParser(''),
+}
+code_sample = """\
+
+class C1():
+ # Class comment.
+ def __init__(self, a, b):
+ self.a = a
+ self.b = b
+"""
+
+
+class DummyEditwin:
+ get_selection_indices = editor.EditorWindow.get_selection_indices
+ def __init__(self, root, text):
+ self.root = root
+ self.top = root
+ self.text = text
+ self.fregion = format.FormatRegion(self)
+ self.text.undo_block_start = mock.Mock()
+ self.text.undo_block_stop = mock.Mock()
+
+
+class ZZDummyTest(unittest.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ requires('gui')
+ root = cls.root = Tk()
+ root.withdraw()
+ text = cls.text = Text(cls.root)
+ cls.editor = DummyEditwin(root, text)
+ zzdummy.idleConf.userCfg = testcfg
+
+ @classmethod
+ def tearDownClass(cls):
+ zzdummy.idleConf.userCfg = usercfg
+ del cls.editor, cls.text
+ cls.root.update_idletasks()
+ for id in cls.root.tk.call('after', 'info'):
+ cls.root.after_cancel(id) # Need for EditorWindow.
+ cls.root.destroy()
+ del cls.root
+
+ def setUp(self):
+ text = self.text
+ text.insert('1.0', code_sample)
+ text.undo_block_start.reset_mock()
+ text.undo_block_stop.reset_mock()
+ zz = self.zz = zzdummy.ZzDummy(self.editor)
+ zzdummy.ZzDummy.ztext = '# ignore #'
+
+ def tearDown(self):
+ self.text.delete('1.0', 'end')
+ del self.zz
+
+ def checklines(self, text, value):
+ # Verify that there are lines being checked.
+ end_line = int(float(text.index('end')))
+
+ # Check each line for the starting text.
+ actual = []
+ for line in range(1, end_line):
+ txt = text.get(f'{line}.0', f'{line}.end')
+ actual.append(txt.startswith(value))
+ return actual
+
+ def test_init(self):
+ zz = self.zz
+ self.assertEqual(zz.editwin, self.editor)
+ self.assertEqual(zz.text, self.editor.text)
+
+ def test_reload(self):
+ self.assertEqual(self.zz.ztext, '# ignore #')
+ testcfg['extensions'].SetOption('ZzDummy', 'z-text', 'spam')
+ zzdummy.ZzDummy.reload()
+ self.assertEqual(self.zz.ztext, 'spam')
+
+ def test_z_in_event(self):
+ eq = self.assertEqual
+ zz = self.zz
+ text = zz.text
+ eq(self.zz.ztext, '# ignore #')
+
+ # No lines have the leading text.
+ expected = [False, False, False, False, False, False, False]
+ actual = self.checklines(text, zz.ztext)
+ eq(expected, actual)
+
+ text.tag_add('sel', '2.0', '4.end')
+ eq(zz.z_in_event(), 'break')
+ expected = [False, True, True, True, False, False, False]
+ actual = self.checklines(text, zz.ztext)
+ eq(expected, actual)
+
+ text.undo_block_start.assert_called_once()
+ text.undo_block_stop.assert_called_once()
+
+ def test_z_out_event(self):
+ eq = self.assertEqual
+ zz = self.zz
+ text = zz.text
+ eq(self.zz.ztext, '# ignore #')
+
+ # Prepend text.
+ text.tag_add('sel', '2.0', '5.end')
+ zz.z_in_event()
+ text.undo_block_start.reset_mock()
+ text.undo_block_stop.reset_mock()
+
+ # Select a few lines to remove text.
+ text.tag_remove('sel', '1.0', 'end')
+ text.tag_add('sel', '3.0', '4.end')
+ eq(zz.z_out_event(), 'break')
+ expected = [False, True, False, False, True, False, False]
+ actual = self.checklines(text, zz.ztext)
+ eq(expected, actual)
+
+ text.undo_block_start.assert_called_once()
+ text.undo_block_stop.assert_called_once()
+
+ def test_roundtrip(self):
+ # Insert and remove to all code should give back original text.
+ zz = self.zz
+ text = zz.text
+
+ text.tag_add('sel', '1.0', 'end-1c')
+ zz.z_in_event()
+ zz.z_out_event()
+
+ self.assertEqual(text.get('1.0', 'end-1c'), code_sample)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
import tempfile
import tokenize
-import tkinter.filedialog as tkFileDialog
-import tkinter.messagebox as tkMessageBox
+from tkinter import filedialog
+from tkinter import messagebox
from tkinter.simpledialog import askstring
import idlelib
eol_convention = f.newlines
converted = True
except OSError as err:
- tkMessageBox.showerror("I/O Error", str(err), parent=self.text)
+ messagebox.showerror("I/O Error", str(err), parent=self.text)
return False
except UnicodeDecodeError:
- tkMessageBox.showerror("Decoding Error",
+ messagebox.showerror("Decoding Error",
"File %s\nFailed to Decode" % filename,
parent=self.text)
return False
# If the file does not contain line separators, it is None.
# If the file contains mixed line separators, it is a tuple.
if eol_convention is not None:
- tkMessageBox.showwarning("Mixed Newlines",
+ messagebox.showwarning("Mixed Newlines",
"Mixed newlines detected.\n"
"The file will be changed on save.",
parent=self.text)
return "yes"
message = "Do you want to save %s before closing?" % (
self.filename or "this untitled document")
- confirm = tkMessageBox.askyesnocancel(
+ confirm = messagebox.askyesnocancel(
title="Save On Close",
message=message,
- default=tkMessageBox.YES,
+ default=messagebox.YES,
parent=self.text)
if confirm:
reply = "yes"
os.fsync(f.fileno())
return True
except OSError as msg:
- tkMessageBox.showerror("I/O Error", str(msg),
+ messagebox.showerror("I/O Error", str(msg),
parent=self.text)
return False
failed = str(err)
except UnicodeEncodeError:
failed = "Invalid encoding '%s'" % enc
- tkMessageBox.showerror(
+ messagebox.showerror(
"I/O Error",
"%s.\nSaving as UTF-8" % failed,
parent=self.text)
return chars.encode('utf-8-sig')
def print_window(self, event):
- confirm = tkMessageBox.askokcancel(
+ confirm = messagebox.askokcancel(
title="Print",
message="Print to Default Printer",
- default=tkMessageBox.OK,
+ default=messagebox.OK,
parent=self.text)
if not confirm:
self.text.focus_set()
status + output
if output:
output = "Printing command: %s\n" % repr(command) + output
- tkMessageBox.showerror("Print status", output, parent=self.text)
+ messagebox.showerror("Print status", output, parent=self.text)
else: #no printing for this platform
message = "Printing is not enabled for this platform: %s" % platform
- tkMessageBox.showinfo("Print status", message, parent=self.text)
+ messagebox.showinfo("Print status", message, parent=self.text)
if tempfilename:
os.unlink(tempfilename)
return "break"
def askopenfile(self):
dir, base = self.defaultfilename("open")
if not self.opendialog:
- self.opendialog = tkFileDialog.Open(parent=self.text,
+ self.opendialog = filedialog.Open(parent=self.text,
filetypes=self.filetypes)
filename = self.opendialog.show(initialdir=dir, initialfile=base)
return filename
def asksavefile(self):
dir, base = self.defaultfilename("save")
if not self.savedialog:
- self.savedialog = tkFileDialog.SaveAs(
+ self.savedialog = filedialog.SaveAs(
parent=self.text,
filetypes=self.filetypes,
defaultextension=self.defaultextension)
except (ImportError, AttributeError, OSError):
pass
-import tkinter.messagebox as tkMessageBox
+from tkinter import messagebox
if TkVersion < 8.5:
root = Tk() # otherwise create root in main
root.withdraw()
from idlelib.run import fix_scaling
fix_scaling(root)
- tkMessageBox.showerror("Idle Cannot Start",
+ messagebox.showerror("Idle Cannot Start",
"Idle requires tcl/tk 8.5+, not %s." % TkVersion,
parent=root)
raise SystemExit(1)
except OSError as err:
if not getattr(self.root, "breakpoint_error_displayed", False):
self.root.breakpoint_error_displayed = True
- tkMessageBox.showerror(title='IDLE Error',
+ messagebox.showerror(title='IDLE Error',
message='Unable to update breakpoint list:\n%s'
% str(err),
parent=self.text)
exec(code, self.locals)
except SystemExit:
if not self.tkconsole.closing:
- if tkMessageBox.askyesno(
+ if messagebox.askyesno(
"Exit?",
"Do you want to exit altogether?",
default="yes",
return self.tkconsole.stderr.write(s)
def display_port_binding_error(self):
- tkMessageBox.showerror(
+ messagebox.showerror(
"Port Binding Error",
"IDLE can't bind to a TCP/IP port, which is necessary to "
"communicate with its Python execution server. This might be "
parent=self.tkconsole.text)
def display_no_subprocess_error(self):
- tkMessageBox.showerror(
+ messagebox.showerror(
"Subprocess Connection Error",
"IDLE's subprocess didn't make connection.\n"
"See the 'Startup failure' section of the IDLE doc, online at\n"
parent=self.tkconsole.text)
def display_executing_dialog(self):
- tkMessageBox.showerror(
+ messagebox.showerror(
"Already executing",
"The Python Shell window is already executing a command; "
"please wait until it is finished.",
def toggle_debugger(self, event=None):
if self.executing:
- tkMessageBox.showerror("Don't debug now",
+ messagebox.showerror("Don't debug now",
"You can only toggle the debugger when idle",
parent=self.text)
self.set_debugger_indicator()
self.showprompt()
self.set_debugger_indicator()
+ def debug_menu_postcommand(self):
+ state = 'disabled' if self.executing else 'normal'
+ self.update_menu_state('debug', '*tack*iewer', state)
+
def beginexecuting(self):
"Helper for ModifiedInterpreter"
self.resetoutput()
def close(self):
"Extend EditorWindow.close()"
if self.executing:
- response = tkMessageBox.askokcancel(
+ response = messagebox.askokcancel(
"Kill?",
"Your program is still running!\n Do you want to kill it?",
default="ok",
(sys.version, sys.platform, self.COPYRIGHT, nosub))
self.text.focus_force()
self.showprompt()
+ # User code should use separate default Tk root window
import tkinter
- tkinter._default_root = None # 03Jan04 KBK What's this?
+ tkinter._support_default_root = True
+ tkinter._default_root = None
return True
def stop_readline(self):
try:
sys.last_traceback
except:
- tkMessageBox.showerror("No stack trace",
+ messagebox.showerror("No stack trace",
"There is no stack trace yet.\n"
"(sys.last_traceback is not defined)",
parent=self.text)
response_queue = queue.Queue(0)
-class SocketIO(object):
+class SocketIO:
nextseq = 0
#----------------- end class SocketIO --------------------
-class RemoteObject(object):
+class RemoteObject:
# Token mix-in class
pass
return RemoteProxy(oid)
-class RemoteProxy(object):
+class RemoteProxy:
def __init__(self, oid):
self.oid = oid
return RPCProxy(self, oid)
-class RPCProxy(object):
+class RPCProxy:
__methods = None
__attributes = None
attributes[name] = 1
-class MethodProxy(object):
+class MethodProxy:
def __init__(self, sockio, oid, name):
self.sockio = sockio
import threading
import warnings
+import idlelib # testing
from idlelib import autocomplete # AutoComplete, fetch_encodings
from idlelib import calltip # Calltip
from idlelib import debugger_r # start_debugger
thread.interrupt_main()
-class Executive(object):
+class Executive:
def __init__(self, rpchandler):
self.rpchandler = rpchandler
- self.locals = __main__.__dict__
- self.calltip = calltip.Calltip()
- self.autocomplete = autocomplete.AutoComplete()
+ if idlelib.testing is False:
+ self.locals = __main__.__dict__
+ self.calltip = calltip.Calltip()
+ self.autocomplete = autocomplete.AutoComplete()
+ else:
+ self.locals = {}
def runcode(self, code):
global interruptable
try:
- self.usr_exc_info = None
+ self.user_exc_info = None
interruptable = True
try:
exec(code, self.locals)
print('SystemExit: ' + str(ob), file=sys.stderr)
# Return to the interactive prompt.
except:
- self.usr_exc_info = sys.exc_info()
+ self.user_exc_info = sys.exc_info() # For testing, hook, viewer.
if quitting:
exit()
- print_exception()
+ if sys.excepthook is sys.__excepthook__:
+ print_exception()
+ else:
+ try:
+ sys.excepthook(*self.user_exc_info)
+ except:
+ self.user_exc_info = sys.exc_info() # For testing.
+ print_exception()
jit = self.rpchandler.console.getvar("<<toggle-jit-stack-viewer>>")
if jit:
self.rpchandler.interp.open_remote_stack_viewer()
return self.autocomplete.fetch_completions(what, mode)
def stackviewer(self, flist_oid=None):
- if self.usr_exc_info:
- typ, val, tb = self.usr_exc_info
+ if self.user_exc_info:
+ typ, val, tb = self.user_exc_info
else:
return None
flist = None
import time
import tokenize
-import tkinter.messagebox as tkMessageBox
+from tkinter import messagebox
from idlelib.config import idleConf
from idlelib import macosx
def ask_save_dialog(self):
msg = "Source Must Be Saved\n" + 5*' ' + "OK to Save?"
- confirm = tkMessageBox.askokcancel(title="Save Before Run or Check",
+ confirm = messagebox.askokcancel(title="Save Before Run or Check",
message=msg,
- default=tkMessageBox.OK,
+ default=messagebox.OK,
parent=self.editwin.text)
return confirm
def errorbox(self, title, message):
# XXX This should really be a function of EditorWindow...
- tkMessageBox.showerror(title, message, parent=self.editwin.text)
+ messagebox.showerror(title, message, parent=self.editwin.text)
self.editwin.text.focus_set()
self.perf = time.perf_counter()
import re
from tkinter import StringVar, BooleanVar, TclError
-import tkinter.messagebox as tkMessageBox
+from tkinter import messagebox
def get(root):
'''Return the singleton SearchEngine instance for the process.
msg = msg + "\nPattern: " + str(pat)
if col is not None:
msg = msg + "\nOffset: " + str(col)
- tkMessageBox.showerror("Regular expression error",
+ messagebox.showerror("Regular expression error",
msg, master=self.root)
def search_text(self, text, prog=None, ok=0):
import re
import tkinter as tk
-import tkinter.messagebox as tkMessageBox
+from tkinter import messagebox
from idlelib.config import idleConf
from idlelib.textview import view_text
if self.is_dangerous is None:
self.set_is_dangerous()
if self.is_dangerous:
- confirm = tkMessageBox.askokcancel(
+ confirm = messagebox.askokcancel(
title="Expand huge output?",
message="\n\n".join([
"The squeezed output is very long: %d lines, %d chars.",
"It is recommended to view or copy the output instead.",
"Really expand?"
]) % (self.numoflines, len(self.s)),
- default=tkMessageBox.CANCEL,
+ default=messagebox.CANCEL,
parent=self.text)
if not confirm:
return "break"
from tkinter import *
-class TooltipBase(object):
+class TooltipBase:
"""abstract base class for tooltips"""
def __init__(self, anchor_widget):
-"Example extension, also used for testing."
+"""Example extension, also used for testing.
+
+See extend.txt for more details on creating an extension.
+See config-extension.def for configuring an extension.
+"""
from idlelib.config import idleConf
+from functools import wraps
+
+
+def format_selection(format_line):
+ "Apply a formatting function to all of the selected lines."
+
+ @wraps(format_line)
+ def apply(self, event=None):
+ head, tail, chars, lines = self.formatter.get_region()
+ for pos in range(len(lines) - 1):
+ line = lines[pos]
+ lines[pos] = format_line(self, line)
+ self.formatter.set_region(head, tail, chars, lines)
+ return 'break'
-ztext = idleConf.GetOption('extensions', 'ZzDummy', 'z-text')
+ return apply
class ZzDummy:
+ """Prepend or remove initial text from selected lines."""
-## menudefs = [
-## ('format', [
-## ('Z in', '<<z-in>>'),
-## ('Z out', '<<z-out>>'),
-## ] )
-## ]
+ # Extend the format menu.
+ menudefs = [
+ ('format', [
+ ('Z in', '<<z-in>>'),
+ ('Z out', '<<z-out>>'),
+ ] )
+ ]
def __init__(self, editwin):
+ "Initialize the settings for this extension."
+ self.editwin = editwin
self.text = editwin.text
- z_in = False
+ self.formatter = editwin.fregion
@classmethod
def reload(cls):
+ "Load class variables from config."
cls.ztext = idleConf.GetOption('extensions', 'ZzDummy', 'z-text')
- def z_in_event(self, event):
+ @format_selection
+ def z_in_event(self, line):
+ """Insert text at the beginning of each selected line.
+
+ This is bound to the <<z-in>> virtual event when the extensions
+ are loaded.
"""
+ return f'{self.ztext}{line}'
+
+ @format_selection
+ def z_out_event(self, line):
+ """Remove specific text from the beginning of each selected line.
+
+ This is bound to the <<z-out>> virtual event when the extensions
+ are loaded.
"""
- text = self.text
- text.undo_block_start()
- for line in range(1, text.index('end')):
- text.insert('%d.0', ztext)
- text.undo_block_stop()
- return "break"
+ zlength = 0 if not line.startswith(self.ztext) else len(self.ztext)
+ return line[zlength:]
- def z_out_event(self, event): pass
ZzDummy.reload()
-##if __name__ == "__main__":
-## import unittest
-## unittest.main('idlelib.idle_test.test_zzdummy',
-## verbosity=2, exit=False)
+
+if __name__ == "__main__":
+ import unittest
+ unittest.main('idlelib.idle_test.test_zzdummy', verbosity=2, exit=False)
async_funcdef: ASYNC funcdef
funcdef: 'def' NAME parameters ['->' test] ':' suite
parameters: '(' [typedargslist] ')'
-typedargslist: ((tfpdef ['=' test] ',')*
- ('*' [tname] (',' tname ['=' test])* [',' ['**' tname [',']]] | '**' tname [','])
- | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
+
+# The following definition for typedarglist is equivalent to this set of rules:
+#
+# arguments = argument (',' argument)*
+# argument = tfpdef ['=' test]
+# kwargs = '**' tname [',']
+# args = '*' [tname]
+# kwonly_kwargs = (',' argument)* [',' [kwargs]]
+# args_kwonly_kwargs = args kwonly_kwargs | kwargs
+# poskeyword_args_kwonly_kwargs = arguments [',' [args_kwonly_kwargs]]
+# typedargslist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs
+# typedarglist = arguments ',' '/' [',' [typedargslist_no_posonly]])|(typedargslist_no_posonly)"
+#
+# It needs to be fully expanded to allow our LL(1) parser to work on it.
+
+typedargslist: tfpdef ['=' test] (',' tfpdef ['=' test])* ',' '/' [
+ ',' [((tfpdef ['=' test] ',')* ('*' [tname] (',' tname ['=' test])*
+ [',' ['**' tname [',']]] | '**' tname [','])
+ | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])]
+ ] | ((tfpdef ['=' test] ',')* ('*' [tname] (',' tname ['=' test])*
+ [',' ['**' tname [',']]] | '**' tname [','])
+ | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
+
tname: NAME [':' test]
tfpdef: tname | '(' tfplist ')'
tfplist: tfpdef (',' tfpdef)* [',']
-varargslist: ((vfpdef ['=' test] ',')*
- ('*' [vname] (',' vname ['=' test])* [',' ['**' vname [',']]] | '**' vname [','])
- | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
+
+# The following definition for varargslist is equivalent to this set of rules:
+#
+# arguments = argument (',' argument )*
+# argument = vfpdef ['=' test]
+# kwargs = '**' vname [',']
+# args = '*' [vname]
+# kwonly_kwargs = (',' argument )* [',' [kwargs]]
+# args_kwonly_kwargs = args kwonly_kwargs | kwargs
+# poskeyword_args_kwonly_kwargs = arguments [',' [args_kwonly_kwargs]]
+# vararglist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs
+# varargslist = arguments ',' '/' [','[(vararglist_no_posonly)]] | (vararglist_no_posonly)
+#
+# It needs to be fully expanded to allow our LL(1) parser to work on it.
+
+varargslist: vfpdef ['=' test ](',' vfpdef ['=' test])* ',' '/' [',' [
+ ((vfpdef ['=' test] ',')* ('*' [vname] (',' vname ['=' test])*
+ [',' ['**' vname [',']]] | '**' vname [','])
+ | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
+ ]] | ((vfpdef ['=' test] ',')*
+ ('*' [vname] (',' vname ['=' test])* [',' ['**' vname [',']]]| '**' vname [','])
+ | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
+
vname: NAME
vfpdef: vname | '(' vfplist ')'
vfplist: vfpdef (',' vfpdef)* [',']
def test_dict_display_2(self):
self.validate("""{**{}, 3:4, **{5:6, 7:8}}""")
+ def test_complex_star_expression(self):
+ self.validate("func(* [] or [1])")
+
+ def test_complex_double_star_expression(self):
+ self.validate("func(**{1: 3} if False else {x: x for x in range(3)})")
+
def test_argument_unpacking_1(self):
self.validate("""f(a, *b, *c, d)""")
class TestNamedAssignments(GrammarTest):
+ """Also known as the walrus operator."""
def test_named_assignment_if(self):
driver.parse_string("if f := x(): pass\n")
driver.parse_string("[(lastNum := num) == 1 for num in [1, 2, 3]]\n")
+class TestPositionalOnlyArgs(GrammarTest):
+
+ def test_one_pos_only_arg(self):
+ driver.parse_string("def one_pos_only_arg(a, /): pass\n")
+
+ def test_all_markers(self):
+ driver.parse_string(
+ "def all_markers(a, b=2, /, c, d=4, *, e=5, f): pass\n")
+
+ def test_all_with_args_and_kwargs(self):
+ driver.parse_string(
+ """def all_markers_with_args_and_kwargs(
+ aa, b, /, _cc, d, *args, e, f_f, **kwargs,
+ ):
+ pass\n""")
+
+ def test_lambda_soup(self):
+ driver.parse_string(
+ "lambda a, b, /, c, d, *args, e, f, **kw: kw\n")
+
+ def test_only_positional_or_keyword(self):
+ driver.parse_string("def func(a,b,/,*,g,e=3): pass\n")
+
+
class TestPickleableException(unittest.TestCase):
def test_ParseError(self):
err = ParseError('msg', 2, None, (1, 'context'))
self.loggerClass = None
self.logRecordFactory = None
+ @property
+ def disable(self):
+ return self._disable
+
+ @disable.setter
+ def disable(self, value):
+ self._disable = _checkLevel(value)
+
def getLogger(self, name):
"""
Get a logger with the specified name (channel name), creating it
sys.argv[:] = args # Hide "pdb.py" and pdb options from argument list
- # Replace pdb's dir with script's dir in front of module search path.
if not run_as_module:
+ mainpyfile = os.path.realpath(mainpyfile)
+ # Replace pdb's dir with script's dir in front of module search path.
sys.path[0] = os.path.dirname(mainpyfile)
# Note on saving/restoring sys.argv: it's a good idea when sys.argv was
):
"""
A uname_result that's largely compatible with a
- simple namedtuple except that 'platform' is
+ simple namedtuple except that 'processor' is
resolved late and cached to avoid calling "uname"
except when needed.
"""
(self.processor,)
)
+ @classmethod
+ def _make(cls, iterable):
+ # override factory to affect length check
+ num_fields = len(cls._fields)
+ result = cls.__new__(cls, *iterable)
+ if len(result) != num_fields + 1:
+ msg = f'Expected {num_fields} arguments, got {len(result)}'
+ raise TypeError(msg)
+ return result
+
def __getitem__(self, key):
- return tuple(iter(self))[key]
+ return tuple(self)[key]
def __len__(self):
return len(tuple(iter(self)))
+ def __reduce__(self):
+ return uname_result, tuple(self)[:len(self._fields)]
+
_uname_cache = None
'__package__': None,
'__cached__': None,
}
- runctx(code, globs, None, options.outfile, options.sort)
+ try:
+ runctx(code, globs, None, options.outfile, options.sort)
+ except BrokenPipeError as exc:
+ # Prevent "Exception ignored" during interpreter shutdown.
+ sys.stdout = None
+ sys.exit(exc.errno)
else:
parser.print_usage()
return parser
# -*- coding: utf-8 -*-
-# Autogenerated by Sphinx on Mon Dec 7 15:00:07 2020
+# Autogenerated by Sphinx on Fri Feb 19 13:29:38 2021
topics = {'assert': 'The "assert" statement\n'
'**********************\n'
'\n'
'\n'
' async_for_stmt ::= "async" for_stmt\n'
'\n'
- 'An *asynchronous iterable* is able to call asynchronous code in '
- 'its\n'
- '*iter* implementation, and *asynchronous iterator* can call\n'
- 'asynchronous code in its *next* method.\n'
+ 'An *asynchronous iterable* provides an "__aiter__" method that\n'
+ 'directly returns an *asynchronous iterator*, which can call\n'
+ 'asynchronous code in its "__anext__" method.\n'
'\n'
'The "async for" statement allows convenient iteration over\n'
- 'asynchronous iterators.\n'
+ 'asynchronous iterables.\n'
'\n'
'The following code:\n'
'\n'
'compatible\n'
'with an exception if it is the class or a base class of the '
'exception\n'
- 'object or a tuple containing an item compatible with the '
- 'exception.\n'
+ 'object, or a tuple containing an item that is the class or a '
+ 'base\n'
+ 'class of the exception object.\n'
'\n'
'If no except clause matches the exception, the search for an '
'exception\n'
'\n'
' async_for_stmt ::= "async" for_stmt\n'
'\n'
- 'An *asynchronous iterable* is able to call asynchronous code in '
- 'its\n'
- '*iter* implementation, and *asynchronous iterator* can call\n'
- 'asynchronous code in its *next* method.\n'
+ 'An *asynchronous iterable* provides an "__aiter__" method that\n'
+ 'directly returns an *asynchronous iterator*, which can call\n'
+ 'asynchronous code in its "__anext__" method.\n'
'\n'
'The "async for" statement allows convenient iteration over\n'
- 'asynchronous iterators.\n'
+ 'asynchronous iterables.\n'
'\n'
'The following code:\n'
'\n'
' | | formats the result in either fixed-point '
'format or in |\n'
' | | scientific notation, depending on its '
- 'magnitude. The |\n'
- ' | | precise rules are as follows: suppose that '
- 'the result |\n'
+ 'magnitude. A |\n'
+ ' | | precision of "0" is treated as equivalent '
+ 'to a precision |\n'
+ ' | | of "1". The precise rules are as follows: '
+ 'suppose that |\n'
+ ' | | the result formatted with presentation '
+ 'type "\'e\'" and |\n'
+ ' | | precision "p-1" would have exponent '
+ '"exp". Then, if "m <= |\n'
+ ' | | exp < p", where "m" is -4 for floats and '
+ '-6 for |\n'
+ ' | | "Decimals", the number is formatted with '
+ 'presentation type |\n'
+ ' | | "\'f\'" and precision "p-1-exp". '
+ 'Otherwise, the number is |\n'
' | | formatted with presentation type "\'e\'" '
- 'and precision "p-1" |\n'
- ' | | would have exponent "exp". Then, if "m <= '
- 'exp < p", where |\n'
- ' | | "m" is -4 for floats and -6 for '
- '"Decimals", the number is |\n'
- ' | | formatted with presentation type "\'f\'" '
'and precision |\n'
- ' | | "p-1-exp". Otherwise, the number is '
- 'formatted with |\n'
- ' | | presentation type "\'e\'" and precision '
- '"p-1". In both cases |\n'
- ' | | insignificant trailing zeros are removed '
- 'from the |\n'
- ' | | significand, and the decimal point is also '
- 'removed if |\n'
- ' | | there are no remaining digits following '
- 'it, unless the |\n'
- ' | | "\'#\'" option is used. Positive and '
- 'negative infinity, |\n'
- ' | | positive and negative zero, and nans, are '
- 'formatted as |\n'
- ' | | "inf", "-inf", "0", "-0" and "nan" '
- 'respectively, |\n'
- ' | | regardless of the precision. A precision '
- 'of "0" is |\n'
- ' | | treated as equivalent to a precision of '
- '"1". With no |\n'
- ' | | precision given, uses a precision of "6" '
- 'significant |\n'
- ' | | digits for "float", and shows all '
- 'coefficient digits for |\n'
- ' | | '
- '"Decimal". '
- '|\n'
+ ' | | "p-1". In both cases insignificant '
+ 'trailing zeros are |\n'
+ ' | | removed from the significand, and the '
+ 'decimal point is |\n'
+ ' | | also removed if there are no remaining '
+ 'digits following |\n'
+ ' | | it, unless the "\'#\'" option is used. '
+ 'With no precision |\n'
+ ' | | given, uses a precision of "6" significant '
+ 'digits for |\n'
+ ' | | "float". For "Decimal", the coefficient of '
+ 'the result is |\n'
+ ' | | formed from the coefficient digits of the '
+ 'value; |\n'
+ ' | | scientific notation is used for values '
+ 'smaller than "1e-6" |\n'
+ ' | | in absolute value and values where the '
+ 'place value of the |\n'
+ ' | | least significant digit is larger than 1, '
+ 'and fixed-point |\n'
+ ' | | notation is used otherwise. Positive and '
+ 'negative |\n'
+ ' | | infinity, positive and negative zero, and '
+ 'nans, are |\n'
+ ' | | formatted as "inf", "-inf", "0", "-0" and '
+ '"nan" |\n'
+ ' | | respectively, regardless of the '
+ 'precision. |\n'
' '
'+-----------+------------------------------------------------------------+\n'
' | "\'G\'" | General format. Same as "\'g\'" except '
'percent sign. |\n'
' '
'+-----------+------------------------------------------------------------+\n'
- ' | None | Similar to "\'g\'", except that '
- 'fixed-point notation, when |\n'
- ' | | used, has at least one digit past the '
- 'decimal point. The |\n'
- ' | | default precision is as high as needed to '
- 'represent the |\n'
- ' | | particular value. The overall effect is to '
- 'match the |\n'
- ' | | output of "str()" as altered by the other '
- 'format |\n'
- ' | | '
- 'modifiers. '
- '|\n'
+ ' | None | For "float" this is the same as "\'g\'", '
+ 'except that when |\n'
+ ' | | fixed-point notation is used to format the '
+ 'result, it |\n'
+ ' | | always includes at least one digit past '
+ 'the decimal point. |\n'
+ ' | | The precision used is as large as needed '
+ 'to represent the |\n'
+ ' | | given value faithfully. For "Decimal", '
+ 'this is the same |\n'
+ ' | | as either "\'g\'" or "\'G\'" depending on '
+ 'the value of |\n'
+ ' | | "context.capitals" for the current decimal '
+ 'context. The |\n'
+ ' | | overall effect is to match the output of '
+ '"str()" as |\n'
+ ' | | altered by the other format '
+ 'modifiers. |\n'
' '
'+-----------+------------------------------------------------------------+\n'
'\n'
'immediate\n'
' subclasses. This method returns a list of all those '
'references\n'
- ' still alive. Example:\n'
+ ' still alive. The list is in definition order. Example:\n'
'\n'
' >>> int.__subclasses__()\n'
" [<class 'bool'>]\n"
'object is “compatible” with the exception. An object is compatible\n'
'with an exception if it is the class or a base class of the '
'exception\n'
- 'object or a tuple containing an item compatible with the exception.\n'
+ 'object, or a tuple containing an item that is the class or a base\n'
+ 'class of the exception object.\n'
'\n'
'If no except clause matches the exception, the search for an '
'exception\n'
' There are two types of integers:\n'
'\n'
' Integers ("int")\n'
- '\n'
' These represent numbers in an unlimited range, subject to\n'
' available (virtual) memory only. For the purpose of '
'shift\n'
"lognormvariate",
"normalvariate",
"paretovariate",
+ "randbytes",
"randint",
"random",
"randrange",
raise TypeError('Counts must be integers')
if total <= 0:
raise ValueError('Total of counts must be greater than zero')
- selections = sample(range(total), k=k)
+ selections = self.sample(range(total), k=k)
bisect = _bisect
return [population[bisect(cum_counts, s)] for s in selections]
randbelow = self._randbelow
# Handle Unix-domain sockets.
try:
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- self.sock.settimeout(self.timeout)
+ if self.timeout is not socket._GLOBAL_DEFAULT_TIMEOUT:
+ self.sock.settimeout(self.timeout)
self.file = None
self.sock.connect(host)
except OSError:
cur.execute(queries[0])
con2.execute("create table bar(x)")
cur.execute(queries[1])
+
+ # Extract from SQLite 3.7.15 changelog:
+ # Avoid invoking the sqlite3_trace() callback multiple times when a
+ # statement is automatically reprepared due to SQLITE_SCHEMA errors.
+ #
+ # See bpo-40810
+ if sqlite.sqlite_version_info < (3, 7, 15):
+ queries.append(queries[-1])
self.assertEqual(traced_statements, queries)
if 'input' in kwargs and kwargs['input'] is None:
# Explicitly passing input=None was previously equivalent to passing an
# empty string. That is maintained here for backwards compatibility.
- kwargs['input'] = '' if kwargs.get('universal_newlines', False) else b''
+ if kwargs.get('universal_newlines') or kwargs.get('text'):
+ empty = ''
+ else:
+ empty = b''
+ kwargs['input'] = empty
return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
**kwargs).stdout
'parse_config_h',
]
+# Keys for get_config_var() that are never converted to Python integers.
+_ALWAYS_STR = {
+ 'MACOSX_DEPLOYMENT_TARGET',
+}
+
_INSTALL_SCHEMES = {
'posix_prefix': {
'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}',
notdone[n] = v
else:
try:
+ if n in _ALWAYS_STR:
+ raise ValueError
+
v = int(v)
except ValueError:
# insert literal `$'
notdone[name] = value
else:
try:
+ if name in _ALWAYS_STR:
+ raise ValueError
value = int(value)
except ValueError:
done[name] = value.strip()
def _init_non_posix(vars):
"""Initialize the module as appropriate for NT"""
# set basic install directories
+ import _imp
vars['LIBDEST'] = get_path('stdlib')
vars['BINLIBDEST'] = get_path('platstdlib')
vars['INCLUDEPY'] = get_path('include')
- vars['EXT_SUFFIX'] = '.pyd'
+ vars['EXT_SUFFIX'] = _imp.extension_suffixes()[0]
vars['EXE'] = '.exe'
vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT
vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable))
if m:
n, v = m.group(1, 2)
try:
+ if n in _ALWAYS_STR:
+ raise ValueError
v = int(v)
except ValueError:
pass
import types
-co = types.CodeType(0, 0, 0, 0, 0, b'\x04\x71\x00\x00',
+co = types.CodeType(0, 0, 0, 0, 0, 0, b'\x04\x00\x71\x00',
(), (), (), '', '', 1, b'')
exec(co)
def close(self):
pass
+ def connect(self, host):
+ pass
+
def socket(family=None, type=None, proto=None):
return MockSocket(family)
# Constants
+_GLOBAL_DEFAULT_TIMEOUT = socket_module._GLOBAL_DEFAULT_TIMEOUT
AF_INET = socket_module.AF_INET
AF_INET6 = socket_module.AF_INET6
SOCK_STREAM = socket_module.SOCK_STREAM
SOL_SOCKET = None
SO_REUSEADDR = None
+
+if hasattr(socket_module, 'AF_UNIX'):
+ AF_UNIX = socket_module.AF_UNIX
return n
+def identity(x):
+ return x
+
+
class UnseekableIO(io.BytesIO):
def peek(self, *args):
raise NotImplementedError
def __getinitargs__(self):
return ()
-class H(object):
+# Simple mutable object.
+class Object:
pass
-# Hashable mutable key
-class K(object):
+# Hashable immutable key object containing unheshable mutable data.
+class K:
def __init__(self, value):
self.value = value
D.__module__ = "__main__"
__main__.E = E
E.__module__ = "__main__"
-__main__.H = H
-H.__module__ = "__main__"
-__main__.K = K
-K.__module__ = "__main__"
class myint(int):
def __init__(self, x):
got = filelike.getvalue()
self.assertEqual(expected, got)
- def test_recursive_list(self):
- l = []
+ def _test_recursive_list(self, cls, aslist=identity, minprotocol=0):
+ # List containing itself.
+ l = cls()
l.append(l)
- for proto in protocols:
+ for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(l, proto)
x = self.loads(s)
- self.assertIsInstance(x, list)
- self.assertEqual(len(x), 1)
- self.assertIs(x[0], x)
+ self.assertIsInstance(x, cls)
+ y = aslist(x)
+ self.assertEqual(len(y), 1)
+ self.assertIs(y[0], x)
- def test_recursive_tuple_and_list(self):
- t = ([],)
+ def test_recursive_list(self):
+ self._test_recursive_list(list)
+
+ def test_recursive_list_subclass(self):
+ self._test_recursive_list(MyList, minprotocol=2)
+
+ def test_recursive_list_like(self):
+ self._test_recursive_list(REX_six, aslist=lambda x: x.items)
+
+ def _test_recursive_tuple_and_list(self, cls, aslist=identity, minprotocol=0):
+ # Tuple containing a list containing the original tuple.
+ t = (cls(),)
t[0].append(t)
- for proto in protocols:
+ for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(t, proto)
x = self.loads(s)
self.assertIsInstance(x, tuple)
self.assertEqual(len(x), 1)
- self.assertIsInstance(x[0], list)
- self.assertEqual(len(x[0]), 1)
- self.assertIs(x[0][0], x)
+ self.assertIsInstance(x[0], cls)
+ y = aslist(x[0])
+ self.assertEqual(len(y), 1)
+ self.assertIs(y[0], x)
+
+ # List containing a tuple containing the original list.
+ t, = t
+ for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
+ s = self.dumps(t, proto)
+ x = self.loads(s)
+ self.assertIsInstance(x, cls)
+ y = aslist(x)
+ self.assertEqual(len(y), 1)
+ self.assertIsInstance(y[0], tuple)
+ self.assertEqual(len(y[0]), 1)
+ self.assertIs(y[0][0], x)
- def test_recursive_dict(self):
- d = {}
+ def test_recursive_tuple_and_list(self):
+ self._test_recursive_tuple_and_list(list)
+
+ def test_recursive_tuple_and_list_subclass(self):
+ self._test_recursive_tuple_and_list(MyList, minprotocol=2)
+
+ def test_recursive_tuple_and_list_like(self):
+ self._test_recursive_tuple_and_list(REX_six, aslist=lambda x: x.items)
+
+ def _test_recursive_dict(self, cls, asdict=identity, minprotocol=0):
+ # Dict containing itself.
+ d = cls()
d[1] = d
- for proto in protocols:
+ for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(d, proto)
x = self.loads(s)
- self.assertIsInstance(x, dict)
- self.assertEqual(list(x.keys()), [1])
- self.assertIs(x[1], x)
+ self.assertIsInstance(x, cls)
+ y = asdict(x)
+ self.assertEqual(list(y.keys()), [1])
+ self.assertIs(y[1], x)
- def test_recursive_dict_key(self):
- d = {}
- k = K(d)
- d[k] = 1
- for proto in protocols:
+ def test_recursive_dict(self):
+ self._test_recursive_dict(dict)
+
+ def test_recursive_dict_subclass(self):
+ self._test_recursive_dict(MyDict, minprotocol=2)
+
+ def test_recursive_dict_like(self):
+ self._test_recursive_dict(REX_seven, asdict=lambda x: x.table)
+
+ def _test_recursive_tuple_and_dict(self, cls, asdict=identity, minprotocol=0):
+ # Tuple containing a dict containing the original tuple.
+ t = (cls(),)
+ t[0][1] = t
+ for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
+ s = self.dumps(t, proto)
+ x = self.loads(s)
+ self.assertIsInstance(x, tuple)
+ self.assertEqual(len(x), 1)
+ self.assertIsInstance(x[0], cls)
+ y = asdict(x[0])
+ self.assertEqual(list(y), [1])
+ self.assertIs(y[1], x)
+
+ # Dict containing a tuple containing the original dict.
+ t, = t
+ for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
+ s = self.dumps(t, proto)
+ x = self.loads(s)
+ self.assertIsInstance(x, cls)
+ y = asdict(x)
+ self.assertEqual(list(y), [1])
+ self.assertIsInstance(y[1], tuple)
+ self.assertEqual(len(y[1]), 1)
+ self.assertIs(y[1][0], x)
+
+ def test_recursive_tuple_and_dict(self):
+ self._test_recursive_tuple_and_dict(dict)
+
+ def test_recursive_tuple_and_dict_subclass(self):
+ self._test_recursive_tuple_and_dict(MyDict, minprotocol=2)
+
+ def test_recursive_tuple_and_dict_like(self):
+ self._test_recursive_tuple_and_dict(REX_seven, asdict=lambda x: x.table)
+
+ def _test_recursive_dict_key(self, cls, asdict=identity, minprotocol=0):
+ # Dict containing an immutable object (as key) containing the original
+ # dict.
+ d = cls()
+ d[K(d)] = 1
+ for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(d, proto)
x = self.loads(s)
- self.assertIsInstance(x, dict)
- self.assertEqual(len(x.keys()), 1)
- self.assertIsInstance(list(x.keys())[0], K)
- self.assertIs(list(x.keys())[0].value, x)
+ self.assertIsInstance(x, cls)
+ y = asdict(x)
+ self.assertEqual(len(y.keys()), 1)
+ self.assertIsInstance(list(y.keys())[0], K)
+ self.assertIs(list(y.keys())[0].value, x)
+
+ def test_recursive_dict_key(self):
+ self._test_recursive_dict_key(dict)
+
+ def test_recursive_dict_subclass_key(self):
+ self._test_recursive_dict_key(MyDict, minprotocol=2)
+
+ def test_recursive_dict_like_key(self):
+ self._test_recursive_dict_key(REX_seven, asdict=lambda x: x.table)
+
+ def _test_recursive_tuple_and_dict_key(self, cls, asdict=identity, minprotocol=0):
+ # Tuple containing a dict containing an immutable object (as key)
+ # containing the original tuple.
+ t = (cls(),)
+ t[0][K(t)] = 1
+ for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
+ s = self.dumps(t, proto)
+ x = self.loads(s)
+ self.assertIsInstance(x, tuple)
+ self.assertEqual(len(x), 1)
+ self.assertIsInstance(x[0], cls)
+ y = asdict(x[0])
+ self.assertEqual(len(y), 1)
+ self.assertIsInstance(list(y.keys())[0], K)
+ self.assertIs(list(y.keys())[0].value, x)
+
+ # Dict containing an immutable object (as key) containing a tuple
+ # containing the original dict.
+ t, = t
+ for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
+ s = self.dumps(t, proto)
+ x = self.loads(s)
+ self.assertIsInstance(x, cls)
+ y = asdict(x)
+ self.assertEqual(len(y), 1)
+ self.assertIsInstance(list(y.keys())[0], K)
+ self.assertIs(list(y.keys())[0].value[0], x)
+
+ def test_recursive_tuple_and_dict_key(self):
+ self._test_recursive_tuple_and_dict_key(dict)
+
+ def test_recursive_tuple_and_dict_subclass_key(self):
+ self._test_recursive_tuple_and_dict_key(MyDict, minprotocol=2)
+
+ def test_recursive_tuple_and_dict_like_key(self):
+ self._test_recursive_tuple_and_dict_key(REX_seven, asdict=lambda x: x.table)
def test_recursive_set(self):
+ # Set containing an immutable object containing the original set.
y = set()
- k = K(y)
- y.add(k)
+ y.add(K(y))
for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(y, proto)
x = self.loads(s)
self.assertIsInstance(list(x)[0], K)
self.assertIs(list(x)[0].value, x)
- def test_recursive_list_subclass(self):
- y = MyList()
- y.append(y)
- for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
+ # Immutable object containing a set containing the original object.
+ y, = y
+ for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(y, proto)
x = self.loads(s)
- self.assertIsInstance(x, MyList)
- self.assertEqual(len(x), 1)
- self.assertIs(x[0], x)
-
- def test_recursive_dict_subclass(self):
- d = MyDict()
- d[1] = d
- for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
- s = self.dumps(d, proto)
- x = self.loads(s)
- self.assertIsInstance(x, MyDict)
- self.assertEqual(list(x.keys()), [1])
- self.assertIs(x[1], x)
-
- def test_recursive_dict_subclass_key(self):
- d = MyDict()
- k = K(d)
- d[k] = 1
- for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
- s = self.dumps(d, proto)
- x = self.loads(s)
- self.assertIsInstance(x, MyDict)
- self.assertEqual(len(list(x.keys())), 1)
- self.assertIsInstance(list(x.keys())[0], K)
- self.assertIs(list(x.keys())[0].value, x)
+ self.assertIsInstance(x, K)
+ self.assertIsInstance(x.value, set)
+ self.assertEqual(len(x.value), 1)
+ self.assertIs(list(x.value)[0], x)
def test_recursive_inst(self):
- i = C()
+ # Mutable object containing itself.
+ i = Object()
i.attr = i
for proto in protocols:
s = self.dumps(i, proto)
x = self.loads(s)
- self.assertIsInstance(x, C)
+ self.assertIsInstance(x, Object)
self.assertEqual(dir(x), dir(i))
self.assertIs(x.attr, x)
def test_recursive_multi(self):
l = []
d = {1:l}
- i = C()
+ i = Object()
i.attr = d
l.append(i)
for proto in protocols:
self.assertEqual(len(x), 1)
self.assertEqual(dir(x[0]), dir(i))
self.assertEqual(list(x[0].attr.keys()), [1])
- self.assertTrue(x[0].attr[1] is x)
-
- def check_recursive_collection_and_inst(self, factory):
- h = H()
- y = factory([h])
- h.attr = y
+ self.assertIs(x[0].attr[1], x)
+
+ def _test_recursive_collection_and_inst(self, factory):
+ # Mutable object containing a collection containing the original
+ # object.
+ o = Object()
+ o.attr = factory([o])
+ t = type(o.attr)
for proto in protocols:
- s = self.dumps(y, proto)
+ s = self.dumps(o, proto)
x = self.loads(s)
- self.assertIsInstance(x, type(y))
+ self.assertIsInstance(x.attr, t)
+ self.assertEqual(len(x.attr), 1)
+ self.assertIsInstance(list(x.attr)[0], Object)
+ self.assertIs(list(x.attr)[0], x)
+
+ # Collection containing a mutable object containing the original
+ # collection.
+ o = o.attr
+ for proto in protocols:
+ s = self.dumps(o, proto)
+ x = self.loads(s)
+ self.assertIsInstance(x, t)
self.assertEqual(len(x), 1)
- self.assertIsInstance(list(x)[0], H)
+ self.assertIsInstance(list(x)[0], Object)
self.assertIs(list(x)[0].attr, x)
def test_recursive_list_and_inst(self):
- self.check_recursive_collection_and_inst(list)
+ self._test_recursive_collection_and_inst(list)
def test_recursive_tuple_and_inst(self):
- self.check_recursive_collection_and_inst(tuple)
+ self._test_recursive_collection_and_inst(tuple)
def test_recursive_dict_and_inst(self):
- self.check_recursive_collection_and_inst(dict.fromkeys)
+ self._test_recursive_collection_and_inst(dict.fromkeys)
def test_recursive_set_and_inst(self):
- self.check_recursive_collection_and_inst(set)
+ self._test_recursive_collection_and_inst(set)
def test_recursive_frozenset_and_inst(self):
- self.check_recursive_collection_and_inst(frozenset)
+ self._test_recursive_collection_and_inst(frozenset)
def test_recursive_list_subclass_and_inst(self):
- self.check_recursive_collection_and_inst(MyList)
+ self._test_recursive_collection_and_inst(MyList)
def test_recursive_tuple_subclass_and_inst(self):
- self.check_recursive_collection_and_inst(MyTuple)
+ self._test_recursive_collection_and_inst(MyTuple)
def test_recursive_dict_subclass_and_inst(self):
- self.check_recursive_collection_and_inst(MyDict.fromkeys)
+ self._test_recursive_collection_and_inst(MyDict.fromkeys)
def test_recursive_set_subclass_and_inst(self):
- self.check_recursive_collection_and_inst(MySet)
+ self._test_recursive_collection_and_inst(MySet)
def test_recursive_frozenset_subclass_and_inst(self):
- self.check_recursive_collection_and_inst(MyFrozenSet)
+ self._test_recursive_collection_and_inst(MyFrozenSet)
+
+ def test_recursive_inst_state(self):
+ # Mutable object containing itself.
+ y = REX_state()
+ y.state = y
+ for proto in protocols:
+ s = self.dumps(y, proto)
+ x = self.loads(s)
+ self.assertIsInstance(x, REX_state)
+ self.assertIs(x.state, x)
+
+ def test_recursive_tuple_and_inst_state(self):
+ # Tuple containing a mutable object containing the original tuple.
+ t = (REX_state(),)
+ t[0].state = t
+ for proto in protocols:
+ s = self.dumps(t, proto)
+ x = self.loads(s)
+ self.assertIsInstance(x, tuple)
+ self.assertEqual(len(x), 1)
+ self.assertIsInstance(x[0], REX_state)
+ self.assertIs(x[0].state, x)
+
+ # Mutable object containing a tuple containing the object.
+ t, = t
+ for proto in protocols:
+ s = self.dumps(t, proto)
+ x = self.loads(s)
+ self.assertIsInstance(x, REX_state)
+ self.assertIsInstance(x.state, tuple)
+ self.assertEqual(len(x.state), 1)
+ self.assertIs(x.state[0], x)
def test_unicode(self):
endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
def __reduce__(self):
return type(self), (), None, None, iter(self.table.items())
+class REX_state(object):
+ """This class is used to check the 3th argument (state) of
+ the reduce protocol.
+ """
+ def __init__(self, state=None):
+ self.state = state
+ def __eq__(self, other):
+ return type(self) is type(other) and self.state == other.state
+ def __setstate__(self, state):
+ self.state = state
+ def __reduce__(self):
+ return type(self), (), self.state
+
# Test classes for newobj
--- /dev/null
+import asyncio
+import unittest
+import time
+
+def tearDownModule():
+ asyncio.set_event_loop_policy(None)
+
+
+class SlowTask:
+ """ Task will run for this defined time, ignoring cancel requests """
+ TASK_TIMEOUT = 0.2
+
+ def __init__(self):
+ self.exited = False
+
+ async def run(self):
+ exitat = time.monotonic() + self.TASK_TIMEOUT
+
+ while True:
+ tosleep = exitat - time.monotonic()
+ if tosleep <= 0:
+ break
+
+ try:
+ await asyncio.sleep(tosleep)
+ except asyncio.CancelledError:
+ pass
+
+ self.exited = True
+
+class AsyncioWaitForTest(unittest.TestCase):
+
+ async def atest_asyncio_wait_for_cancelled(self):
+ t = SlowTask()
+
+ waitfortask = asyncio.create_task(asyncio.wait_for(t.run(), t.TASK_TIMEOUT * 2))
+ await asyncio.sleep(0)
+ waitfortask.cancel()
+ await asyncio.wait({waitfortask})
+
+ self.assertTrue(t.exited)
+
+ def test_asyncio_wait_for_cancelled(self):
+ asyncio.run(self.atest_asyncio_wait_for_cancelled())
+
+ async def atest_asyncio_wait_for_timeout(self):
+ t = SlowTask()
+
+ try:
+ await asyncio.wait_for(t.run(), t.TASK_TIMEOUT / 2)
+ except asyncio.TimeoutError:
+ pass
+
+ self.assertTrue(t.exited)
+
+ def test_asyncio_wait_for_timeout(self):
+ asyncio.run(self.atest_asyncio_wait_for_timeout())
+
+
+if __name__ == '__main__':
+ unittest.main()
import collections
import decimal
import fractions
+import gc
import io
import locale
import os
self.assertIs(cm.exception, exception)
+ @support.cpython_only
+ def test_zip_result_gc(self):
+ # bpo-42536: zip's tuple-reuse speed trick breaks the GC's assumptions
+ # about what can be untracked. Make sure we re-track result tuples
+ # whenever we reuse them.
+ it = zip([[]])
+ gc.collect()
+ # That GC collection probably untracked the recycled internal result
+ # tuple, which is initialized to (None,). Make sure it's re-tracked when
+ # it's mutated and returned from __next__:
+ self.assertTrue(gc.is_tracked(next(it)))
+
def test_format(self):
# Test the basic machinery of the format() builtin. Don't test
# the specifics of the various formatters
("", ValueError("bad query field: ''")),
("&", ValueError("bad query field: ''")),
("&&", ValueError("bad query field: ''")),
- (";", ValueError("bad query field: ''")),
- (";&;", ValueError("bad query field: ''")),
# Should the next few really be valid?
("=", {}),
("=&=", {}),
- ("=;=", {}),
# This rest seem to make sense
("=a", {'': ['a']}),
("&=a", ValueError("bad query field: ''")),
("a=a+b&b=b+c", {'a': ['a b'], 'b': ['b c']}),
("a=a+b&a=b+a", {'a': ['a b', 'b a']}),
("x=1&y=2.0&z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}),
- ("x=1;y=2.0&z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}),
- ("x=1;y=2.0;z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}),
("Hbc5161168c542333633315dee1182227:key_store_seqid=400006&cuyer=r&view=bustomer&order_id=0bb2e248638833d48cb7fed300000f1b&expire=964546263&lobale=en-US&kid=130003.300038&ss=env",
{'Hbc5161168c542333633315dee1182227:key_store_seqid': ['400006'],
'cuyer': ['r'],
else:
self.assertEqual(fs.getvalue(key), expect_val[0])
+ def test_separator(self):
+ parse_semicolon = [
+ ("x=1;y=2.0", {'x': ['1'], 'y': ['2.0']}),
+ ("x=1;y=2.0;z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}),
+ (";", ValueError("bad query field: ''")),
+ (";;", ValueError("bad query field: ''")),
+ ("=;a", ValueError("bad query field: 'a'")),
+ (";b=a", ValueError("bad query field: ''")),
+ ("b;=a", ValueError("bad query field: 'b'")),
+ ("a=a+b;b=b+c", {'a': ['a b'], 'b': ['b c']}),
+ ("a=a+b;a=b+a", {'a': ['a b', 'b a']}),
+ ]
+ for orig, expect in parse_semicolon:
+ env = {'QUERY_STRING': orig}
+ fs = cgi.FieldStorage(separator=';', environ=env)
+ if isinstance(expect, dict):
+ for key in expect.keys():
+ expect_val = expect[key]
+ self.assertIn(key, fs)
+ if len(expect_val) > 1:
+ self.assertEqual(fs.getvalue(key), expect_val)
+ else:
+ self.assertEqual(fs.getvalue(key), expect_val[0])
+
def test_log(self):
cgi.log("Testing")
self.assertEqual(np.x, 1)
self.assertEqual(np.y, 2)
+ def test_new_builtins_issue_43102(self):
+ self.assertEqual(
+ namedtuple('C', ()).__new__.__globals__['__builtins__'],
+ {})
+
################################################################################
### Abstract Base Classes
-#
-# Test script for the curses module
-#
-# This script doesn't actually display anything very coherent. but it
-# does call (nearly) every method and function.
-#
-# Functions not tested: {def,reset}_{shell,prog}_mode, getch(), getstr(),
-# init_color()
-# Only called, not tested: getmouse(), ungetmouse()
-#
-
+import functools
+import inspect
import os
import string
import sys
# Optionally test curses module. This currently requires that the
# 'curses' resource be given on the regrtest command line using the -u
# option. If not available, nothing after this line will be executed.
-import inspect
requires('curses')
# If either of these don't exist, skip the tests.
return unittest.skipUnless(hasattr(curses, name),
'requires curses.%s' % name)
+def requires_curses_window_meth(name):
+ def deco(test):
+ @functools.wraps(test)
+ def wrapped(self, *args, **kwargs):
+ if not hasattr(self.stdscr, name):
+ raise unittest.SkipTest('requires curses.window.%s' % name)
+ test(self, *args, **kwargs)
+ return wrapped
+ return deco
+
+
+def requires_colors(test):
+ @functools.wraps(test)
+ def wrapped(self, *args, **kwargs):
+ if not curses.has_colors():
+ self.skipTest('requires colors support')
+ curses.start_color()
+ test(self, *args, **kwargs)
+ return wrapped
+
term = os.environ.get('TERM')
+SHORT_MAX = 0x7fff
# If newterm was supported we could use it instead of initscr and not exit
@unittest.skipIf(not term or term == 'unknown',
@classmethod
def setUpClass(cls):
- if not sys.__stdout__.isatty():
- # Temporary skip tests on non-tty
- raise unittest.SkipTest('sys.__stdout__ is not a tty')
- cls.tmp = tempfile.TemporaryFile()
- fd = cls.tmp.fileno()
- else:
- cls.tmp = None
- fd = sys.__stdout__.fileno()
+ if verbose:
+ print(f'TERM={term}', file=sys.stderr, flush=True)
# testing setupterm() inside initscr/endwin
# causes terminal breakage
- curses.setupterm(fd=fd)
-
- @classmethod
- def tearDownClass(cls):
- if cls.tmp:
- cls.tmp.close()
- del cls.tmp
+ stdout_fd = sys.__stdout__.fileno()
+ curses.setupterm(fd=stdout_fd)
def setUp(self):
+ self.isatty = True
+ self.output = sys.__stdout__
+ stdout_fd = sys.__stdout__.fileno()
+ if not sys.__stdout__.isatty():
+ # initstr() unconditionally uses C stdout.
+ # If it is redirected to file or pipe, try to attach it
+ # to terminal.
+ # First, save a copy of the file descriptor of stdout, so it
+ # can be restored after finishing the test.
+ dup_fd = os.dup(stdout_fd)
+ self.addCleanup(os.close, dup_fd)
+ self.addCleanup(os.dup2, dup_fd, stdout_fd)
+
+ if sys.__stderr__.isatty():
+ # If stderr is connected to terminal, use it.
+ tmp = sys.__stderr__
+ self.output = sys.__stderr__
+ else:
+ try:
+ # Try to open the terminal device.
+ tmp = open('/dev/tty', 'wb', buffering=0)
+ except OSError:
+ # As a fallback, use regular file to write control codes.
+ # Some functions (like savetty) will not work, but at
+ # least the garbage control sequences will not be mixed
+ # with the testing report.
+ tmp = tempfile.TemporaryFile(mode='wb', buffering=0)
+ self.isatty = False
+ self.addCleanup(tmp.close)
+ self.output = None
+ os.dup2(tmp.fileno(), stdout_fd)
+
self.save_signals = SaveSignals()
self.save_signals.save()
- if verbose:
+ self.addCleanup(self.save_signals.restore)
+ if verbose and self.output is not None:
# just to make the test output a little more readable
- print()
+ sys.stderr.flush()
+ sys.stdout.flush()
+ print(file=self.output, flush=True)
self.stdscr = curses.initscr()
- curses.savetty()
+ if self.isatty:
+ curses.savetty()
+ self.addCleanup(curses.endwin)
+ self.addCleanup(curses.resetty)
+ self.stdscr.erase()
+
+ @requires_curses_func('filter')
+ def test_filter(self):
+ # TODO: Should be called before initscr() or newterm() are called.
+ # TODO: nofilter()
+ curses.filter()
+
+ @requires_curses_func('use_env')
+ def test_use_env(self):
+ # TODO: Should be called before initscr() or newterm() are called.
+ # TODO: use_tioctl()
+ curses.use_env(False)
+ curses.use_env(True)
+
+ def test_create_windows(self):
+ win = curses.newwin(5, 10)
+ self.assertEqual(win.getbegyx(), (0, 0))
+ self.assertEqual(win.getparyx(), (-1, -1))
+ self.assertEqual(win.getmaxyx(), (5, 10))
+
+ win = curses.newwin(10, 15, 2, 5)
+ self.assertEqual(win.getbegyx(), (2, 5))
+ self.assertEqual(win.getparyx(), (-1, -1))
+ self.assertEqual(win.getmaxyx(), (10, 15))
+
+ win2 = win.subwin(3, 7)
+ self.assertEqual(win2.getbegyx(), (3, 7))
+ self.assertEqual(win2.getparyx(), (1, 2))
+ self.assertEqual(win2.getmaxyx(), (9, 13))
+
+ win2 = win.subwin(5, 10, 3, 7)
+ self.assertEqual(win2.getbegyx(), (3, 7))
+ self.assertEqual(win2.getparyx(), (1, 2))
+ self.assertEqual(win2.getmaxyx(), (5, 10))
+
+ win3 = win.derwin(2, 3)
+ self.assertEqual(win3.getbegyx(), (4, 8))
+ self.assertEqual(win3.getparyx(), (2, 3))
+ self.assertEqual(win3.getmaxyx(), (8, 12))
+
+ win3 = win.derwin(6, 11, 2, 3)
+ self.assertEqual(win3.getbegyx(), (4, 8))
+ self.assertEqual(win3.getparyx(), (2, 3))
+ self.assertEqual(win3.getmaxyx(), (6, 11))
+
+ win.mvwin(0, 1)
+ self.assertEqual(win.getbegyx(), (0, 1))
+ self.assertEqual(win.getparyx(), (-1, -1))
+ self.assertEqual(win.getmaxyx(), (10, 15))
+ self.assertEqual(win2.getbegyx(), (3, 7))
+ self.assertEqual(win2.getparyx(), (1, 2))
+ self.assertEqual(win2.getmaxyx(), (5, 10))
+ self.assertEqual(win3.getbegyx(), (4, 8))
+ self.assertEqual(win3.getparyx(), (2, 3))
+ self.assertEqual(win3.getmaxyx(), (6, 11))
+
+ win2.mvderwin(2, 1)
+ self.assertEqual(win2.getbegyx(), (3, 7))
+ self.assertEqual(win2.getparyx(), (2, 1))
+ self.assertEqual(win2.getmaxyx(), (5, 10))
+
+ win3.mvderwin(2, 1)
+ self.assertEqual(win3.getbegyx(), (4, 8))
+ self.assertEqual(win3.getparyx(), (2, 1))
+ self.assertEqual(win3.getmaxyx(), (6, 11))
+
+ def test_move_cursor(self):
+ stdscr = self.stdscr
+ win = stdscr.subwin(10, 15, 2, 5)
+ stdscr.move(1, 2)
+ win.move(2, 4)
+ self.assertEqual(stdscr.getyx(), (1, 2))
+ self.assertEqual(win.getyx(), (2, 4))
- def tearDown(self):
- curses.resetty()
- curses.endwin()
- self.save_signals.restore()
+ win.cursyncup()
+ self.assertEqual(stdscr.getyx(), (4, 9))
+
+ def test_refresh_control(self):
+ stdscr = self.stdscr
+ # touchwin()/untouchwin()/is_wintouched()
+ stdscr.refresh()
+ self.assertIs(stdscr.is_wintouched(), False)
+ stdscr.touchwin()
+ self.assertIs(stdscr.is_wintouched(), True)
+ stdscr.refresh()
+ self.assertIs(stdscr.is_wintouched(), False)
+ stdscr.touchwin()
+ self.assertIs(stdscr.is_wintouched(), True)
+ stdscr.untouchwin()
+ self.assertIs(stdscr.is_wintouched(), False)
+
+ # touchline()/untouchline()/is_linetouched()
+ stdscr.touchline(5, 2)
+ self.assertIs(stdscr.is_linetouched(5), True)
+ self.assertIs(stdscr.is_linetouched(6), True)
+ self.assertIs(stdscr.is_wintouched(), True)
+ stdscr.touchline(5, 1, False)
+ self.assertIs(stdscr.is_linetouched(5), False)
+
+ # syncup()
+ win = stdscr.subwin(10, 15, 2, 5)
+ win2 = win.subwin(5, 10, 3, 7)
+ win2.touchwin()
+ stdscr.untouchwin()
+ win2.syncup()
+ self.assertIs(win.is_wintouched(), True)
+ self.assertIs(stdscr.is_wintouched(), True)
+
+ # syncdown()
+ stdscr.touchwin()
+ win.untouchwin()
+ win2.untouchwin()
+ win2.syncdown()
+ self.assertIs(win2.is_wintouched(), True)
+
+ # syncok()
+ if hasattr(stdscr, 'syncok') and not sys.platform.startswith("sunos"):
+ win.untouchwin()
+ stdscr.untouchwin()
+ for syncok in [False, True]:
+ win2.syncok(syncok)
+ win2.addch('a')
+ self.assertIs(win.is_wintouched(), syncok)
+ self.assertIs(stdscr.is_wintouched(), syncok)
+
+ def test_output_character(self):
+ stdscr = self.stdscr
+ encoding = stdscr.encoding
+ # addch()
+ stdscr.refresh()
+ stdscr.move(0, 0)
+ stdscr.addch('A')
+ stdscr.addch(b'A')
+ stdscr.addch(65)
+ c = '\u20ac'
+ try:
+ stdscr.addch(c)
+ except UnicodeEncodeError:
+ self.assertRaises(UnicodeEncodeError, c.encode, encoding)
+ except OverflowError:
+ encoded = c.encode(encoding)
+ self.assertNotEqual(len(encoded), 1, repr(encoded))
+ stdscr.addch('A', curses.A_BOLD)
+ stdscr.addch(1, 2, 'A')
+ stdscr.addch(2, 3, 'A', curses.A_BOLD)
+ self.assertIs(stdscr.is_wintouched(), True)
+
+ # echochar()
+ stdscr.refresh()
+ stdscr.move(0, 0)
+ stdscr.echochar('A')
+ stdscr.echochar(b'A')
+ stdscr.echochar(65)
+ with self.assertRaises((UnicodeEncodeError, OverflowError)):
+ stdscr.echochar('\u20ac')
+ stdscr.echochar('A', curses.A_BOLD)
+ self.assertIs(stdscr.is_wintouched(), False)
+
+ def test_output_string(self):
+ stdscr = self.stdscr
+ encoding = stdscr.encoding
+ # addstr()/insstr()
+ for func in [stdscr.addstr, stdscr.insstr]:
+ with self.subTest(func.__qualname__):
+ stdscr.move(0, 0)
+ func('abcd')
+ func(b'abcd')
+ s = 'àßçđ'
+ try:
+ func(s)
+ except UnicodeEncodeError:
+ self.assertRaises(UnicodeEncodeError, s.encode, encoding)
+ func('abcd', curses.A_BOLD)
+ func(1, 2, 'abcd')
+ func(2, 3, 'abcd', curses.A_BOLD)
+
+ # addnstr()/insnstr()
+ for func in [stdscr.addnstr, stdscr.insnstr]:
+ with self.subTest(func.__qualname__):
+ stdscr.move(0, 0)
+ func('1234', 3)
+ func(b'1234', 3)
+ s = '\u0661\u0662\u0663\u0664'
+ try:
+ func(s, 3)
+ except UnicodeEncodeError:
+ self.assertRaises(UnicodeEncodeError, s.encode, encoding)
+ func('1234', 5)
+ func('1234', 3, curses.A_BOLD)
+ func(1, 2, '1234', 3)
+ func(2, 3, '1234', 3, curses.A_BOLD)
+
+ def test_output_string_embedded_null_chars(self):
+ # reject embedded null bytes and characters
+ stdscr = self.stdscr
+ for arg in ['a\0', b'a\0']:
+ with self.subTest(arg=arg):
+ self.assertRaises(ValueError, stdscr.addstr, arg)
+ self.assertRaises(ValueError, stdscr.addnstr, arg, 1)
+ self.assertRaises(ValueError, stdscr.insstr, arg)
+ self.assertRaises(ValueError, stdscr.insnstr, arg, 1)
- def test_window_funcs(self):
- "Test the methods of windows"
+ def test_read_from_window(self):
stdscr = self.stdscr
- win = curses.newwin(10,10)
- win = curses.newwin(5,5, 5,5)
- win2 = curses.newwin(15,15, 5,5)
-
- for meth in [stdscr.addch, stdscr.addstr]:
- for args in [('a',), ('a', curses.A_BOLD),
- (4,4, 'a'), (5,5, 'a', curses.A_BOLD)]:
- with self.subTest(meth=meth.__qualname__, args=args):
- meth(*args)
-
- for meth in [stdscr.clear, stdscr.clrtobot,
- stdscr.clrtoeol, stdscr.cursyncup, stdscr.delch,
- stdscr.deleteln, stdscr.erase, stdscr.getbegyx,
- stdscr.getbkgd, stdscr.getkey, stdscr.getmaxyx,
- stdscr.getparyx, stdscr.getyx, stdscr.inch,
- stdscr.insertln, stdscr.instr, stdscr.is_wintouched,
- win.noutrefresh, stdscr.redrawwin, stdscr.refresh,
- stdscr.standout, stdscr.standend, stdscr.syncdown,
- stdscr.syncup, stdscr.touchwin, stdscr.untouchwin]:
- with self.subTest(meth=meth.__qualname__):
- meth()
-
- stdscr.addnstr('1234', 3)
- stdscr.addnstr('1234', 3, curses.A_BOLD)
- stdscr.addnstr(4,4, '1234', 3)
- stdscr.addnstr(5,5, '1234', 3, curses.A_BOLD)
-
- stdscr.attron(curses.A_BOLD)
- stdscr.attroff(curses.A_BOLD)
- stdscr.attrset(curses.A_BOLD)
- stdscr.bkgd(' ')
- stdscr.bkgd(' ', curses.A_REVERSE)
- stdscr.bkgdset(' ')
- stdscr.bkgdset(' ', curses.A_REVERSE)
+ stdscr.addstr(0, 1, 'ABCD', curses.A_BOLD)
+ # inch()
+ stdscr.move(0, 1)
+ self.assertEqual(stdscr.inch(), 65 | curses.A_BOLD)
+ self.assertEqual(stdscr.inch(0, 3), 67 | curses.A_BOLD)
+ stdscr.move(0, 0)
+ # instr()
+ self.assertEqual(stdscr.instr()[:6], b' ABCD ')
+ self.assertEqual(stdscr.instr(3)[:6], b' AB')
+ self.assertEqual(stdscr.instr(0, 2)[:4], b'BCD ')
+ self.assertEqual(stdscr.instr(0, 2, 4), b'BCD ')
+ self.assertRaises(ValueError, stdscr.instr, -2)
+ self.assertRaises(ValueError, stdscr.instr, 0, 2, -2)
+
+ def test_getch(self):
+ win = curses.newwin(5, 12, 5, 2)
+
+ # TODO: Test with real input by writing to master fd.
+ for c in 'spam\n'[::-1]:
+ curses.ungetch(c)
+ self.assertEqual(win.getch(3, 1), b's'[0])
+ self.assertEqual(win.getyx(), (3, 1))
+ self.assertEqual(win.getch(3, 4), b'p'[0])
+ self.assertEqual(win.getyx(), (3, 4))
+ self.assertEqual(win.getch(), b'a'[0])
+ self.assertEqual(win.getyx(), (3, 4))
+ self.assertEqual(win.getch(), b'm'[0])
+ self.assertEqual(win.getch(), b'\n'[0])
+
+ def test_getstr(self):
+ win = curses.newwin(5, 12, 5, 2)
+ curses.echo()
+ self.addCleanup(curses.noecho)
+
+ self.assertRaises(ValueError, win.getstr, -400)
+ self.assertRaises(ValueError, win.getstr, 2, 3, -400)
+
+ # TODO: Test with real input by writing to master fd.
+ for c in 'Lorem\nipsum\ndolor\nsit\namet\n'[::-1]:
+ curses.ungetch(c)
+ self.assertEqual(win.getstr(3, 1, 2), b'Lo')
+ self.assertEqual(win.instr(3, 0), b' Lo ')
+ self.assertEqual(win.getstr(3, 5, 10), b'ipsum')
+ self.assertEqual(win.instr(3, 0), b' Lo ipsum ')
+ self.assertEqual(win.getstr(1, 5), b'dolor')
+ self.assertEqual(win.instr(1, 0), b' dolor ')
+ self.assertEqual(win.getstr(2), b'si')
+ self.assertEqual(win.instr(1, 0), b'si dolor ')
+ self.assertEqual(win.getstr(), b'amet')
+ self.assertEqual(win.instr(1, 0), b'amet dolor ')
+
+ def test_clear(self):
+ win = curses.newwin(5, 15, 5, 2)
+ lorem_ipsum(win)
+
+ win.move(0, 8)
+ win.clrtoeol()
+ self.assertEqual(win.instr(0, 0).rstrip(), b'Lorem ip')
+ self.assertEqual(win.instr(1, 0).rstrip(), b'dolor sit amet,')
+
+ win.move(0, 3)
+ win.clrtobot()
+ self.assertEqual(win.instr(0, 0).rstrip(), b'Lor')
+ self.assertEqual(win.instr(1, 0).rstrip(), b'')
+
+ for func in [win.erase, win.clear]:
+ lorem_ipsum(win)
+ func()
+ self.assertEqual(win.instr(0, 0).rstrip(), b'')
+ self.assertEqual(win.instr(1, 0).rstrip(), b'')
+
+ def test_insert_delete(self):
+ win = curses.newwin(5, 15, 5, 2)
+ lorem_ipsum(win)
+
+ win.move(0, 2)
+ win.delch()
+ self.assertEqual(win.instr(0, 0), b'Loem ipsum ')
+ win.delch(0, 7)
+ self.assertEqual(win.instr(0, 0), b'Loem ipum ')
+
+ win.move(1, 5)
+ win.deleteln()
+ self.assertEqual(win.instr(0, 0), b'Loem ipum ')
+ self.assertEqual(win.instr(1, 0), b'consectetur ')
+ self.assertEqual(win.instr(2, 0), b'adipiscing elit')
+ self.assertEqual(win.instr(3, 0), b'sed do eiusmod ')
+ self.assertEqual(win.instr(4, 0), b' ')
+
+ win.move(1, 5)
+ win.insertln()
+ self.assertEqual(win.instr(0, 0), b'Loem ipum ')
+ self.assertEqual(win.instr(1, 0), b' ')
+ self.assertEqual(win.instr(2, 0), b'consectetur ')
+
+ win.clear()
+ lorem_ipsum(win)
+ win.move(1, 5)
+ win.insdelln(2)
+ self.assertEqual(win.instr(0, 0), b'Lorem ipsum ')
+ self.assertEqual(win.instr(1, 0), b' ')
+ self.assertEqual(win.instr(2, 0), b' ')
+ self.assertEqual(win.instr(3, 0), b'dolor sit amet,')
+
+ win.clear()
+ lorem_ipsum(win)
+ win.move(1, 5)
+ win.insdelln(-2)
+ self.assertEqual(win.instr(0, 0), b'Lorem ipsum ')
+ self.assertEqual(win.instr(1, 0), b'adipiscing elit')
+ self.assertEqual(win.instr(2, 0), b'sed do eiusmod ')
+ self.assertEqual(win.instr(3, 0), b' ')
+
+ def test_scroll(self):
+ win = curses.newwin(5, 15, 5, 2)
+ lorem_ipsum(win)
+ win.scrollok(True)
+ win.scroll()
+ self.assertEqual(win.instr(0, 0), b'dolor sit amet,')
+ win.scroll(2)
+ self.assertEqual(win.instr(0, 0), b'adipiscing elit')
+ win.scroll(-3)
+ self.assertEqual(win.instr(0, 0), b' ')
+ self.assertEqual(win.instr(2, 0), b' ')
+ self.assertEqual(win.instr(3, 0), b'adipiscing elit')
+ win.scrollok(False)
+
+ def test_attributes(self):
+ # TODO: attr_get(), attr_set(), ...
+ win = curses.newwin(5, 15, 5, 2)
+ win.attron(curses.A_BOLD)
+ win.attroff(curses.A_BOLD)
+ win.attrset(curses.A_BOLD)
+
+ win.standout()
+ win.standend()
+
+ @requires_curses_window_meth('chgat')
+ def test_chgat(self):
+ win = curses.newwin(5, 15, 5, 2)
+ win.addstr(2, 0, 'Lorem ipsum')
+ win.addstr(3, 0, 'dolor sit amet')
+
+ win.move(2, 8)
+ win.chgat(curses.A_BLINK)
+ self.assertEqual(win.inch(2, 7), b'p'[0])
+ self.assertEqual(win.inch(2, 8), b's'[0] | curses.A_BLINK)
+ self.assertEqual(win.inch(2, 14), b' '[0] | curses.A_BLINK)
+
+ win.move(2, 1)
+ win.chgat(3, curses.A_BOLD)
+ self.assertEqual(win.inch(2, 0), b'L'[0])
+ self.assertEqual(win.inch(2, 1), b'o'[0] | curses.A_BOLD)
+ self.assertEqual(win.inch(2, 3), b'e'[0] | curses.A_BOLD)
+ self.assertEqual(win.inch(2, 4), b'm'[0])
+
+ win.chgat(3, 2, curses.A_UNDERLINE)
+ self.assertEqual(win.inch(3, 1), b'o'[0])
+ self.assertEqual(win.inch(3, 2), b'l'[0] | curses.A_UNDERLINE)
+ self.assertEqual(win.inch(3, 14), b' '[0] | curses.A_UNDERLINE)
+
+ win.chgat(3, 4, 7, curses.A_BLINK)
+ self.assertEqual(win.inch(3, 3), b'o'[0] | curses.A_UNDERLINE)
+ self.assertEqual(win.inch(3, 4), b'r'[0] | curses.A_BLINK)
+ self.assertEqual(win.inch(3, 10), b'a'[0] | curses.A_BLINK)
+ self.assertEqual(win.inch(3, 11), b'm'[0] | curses.A_UNDERLINE)
+ self.assertEqual(win.inch(3, 14), b' '[0] | curses.A_UNDERLINE)
+
+ def test_background(self):
+ win = curses.newwin(5, 15, 5, 2)
+ win.addstr(0, 0, 'Lorem ipsum')
+
+ self.assertIn(win.getbkgd(), (0, 32))
+
+ # bkgdset()
+ win.bkgdset('_')
+ self.assertEqual(win.getbkgd(), b'_'[0])
+ win.bkgdset(b'#')
+ self.assertEqual(win.getbkgd(), b'#'[0])
+ win.bkgdset(65)
+ self.assertEqual(win.getbkgd(), 65)
+ win.bkgdset(0)
+ self.assertEqual(win.getbkgd(), 32)
+
+ win.bkgdset('#', curses.A_REVERSE)
+ self.assertEqual(win.getbkgd(), b'#'[0] | curses.A_REVERSE)
+ self.assertEqual(win.inch(0, 0), b'L'[0])
+ self.assertEqual(win.inch(0, 5), b' '[0])
+ win.bkgdset(0)
+
+ # bkgd()
+ win.bkgd('_')
+ self.assertEqual(win.getbkgd(), b'_'[0])
+ self.assertEqual(win.inch(0, 0), b'L'[0])
+ self.assertEqual(win.inch(0, 5), b'_'[0])
+
+ win.bkgd('#', curses.A_REVERSE)
+ self.assertEqual(win.getbkgd(), b'#'[0] | curses.A_REVERSE)
+ self.assertEqual(win.inch(0, 0), b'L'[0] | curses.A_REVERSE)
+ self.assertEqual(win.inch(0, 5), b'#'[0] | curses.A_REVERSE)
+
+ def test_overlay(self):
+ srcwin = curses.newwin(5, 18, 3, 4)
+ lorem_ipsum(srcwin)
+ dstwin = curses.newwin(7, 17, 5, 7)
+ for i in range(6):
+ dstwin.addstr(i, 0, '_'*17)
+
+ srcwin.overlay(dstwin)
+ self.assertEqual(dstwin.instr(0, 0), b'sectetur_________')
+ self.assertEqual(dstwin.instr(1, 0), b'piscing_elit,____')
+ self.assertEqual(dstwin.instr(2, 0), b'_do_eiusmod______')
+ self.assertEqual(dstwin.instr(3, 0), b'_________________')
+
+ srcwin.overwrite(dstwin)
+ self.assertEqual(dstwin.instr(0, 0), b'sectetur __')
+ self.assertEqual(dstwin.instr(1, 0), b'piscing elit, __')
+ self.assertEqual(dstwin.instr(2, 0), b' do eiusmod __')
+ self.assertEqual(dstwin.instr(3, 0), b'_________________')
+
+ srcwin.overlay(dstwin, 1, 4, 3, 2, 4, 11)
+ self.assertEqual(dstwin.instr(3, 0), b'__r_sit_amet_____')
+ self.assertEqual(dstwin.instr(4, 0), b'__ectetur________')
+ self.assertEqual(dstwin.instr(5, 0), b'_________________')
+
+ srcwin.overwrite(dstwin, 1, 4, 3, 2, 4, 11)
+ self.assertEqual(dstwin.instr(3, 0), b'__r sit amet_____')
+ self.assertEqual(dstwin.instr(4, 0), b'__ectetur _____')
+ self.assertEqual(dstwin.instr(5, 0), b'_________________')
+
+ def test_refresh(self):
+ win = curses.newwin(5, 15, 2, 5)
+ win.noutrefresh()
+ win.redrawln(1, 2)
+ win.redrawwin()
+ win.refresh()
+ curses.doupdate()
+
+ @requires_curses_window_meth('resize')
+ def test_resize(self):
+ win = curses.newwin(5, 15, 2, 5)
+ win.resize(4, 20)
+ self.assertEqual(win.getmaxyx(), (4, 20))
+ win.resize(5, 15)
+ self.assertEqual(win.getmaxyx(), (5, 15))
+
+ @requires_curses_window_meth('enclose')
+ def test_enclose(self):
+ win = curses.newwin(5, 15, 2, 5)
+ # TODO: Return bool instead of 1/0
+ self.assertTrue(win.enclose(2, 5))
+ self.assertFalse(win.enclose(1, 5))
+ self.assertFalse(win.enclose(2, 4))
+ self.assertTrue(win.enclose(6, 19))
+ self.assertFalse(win.enclose(7, 19))
+ self.assertFalse(win.enclose(6, 20))
+
+ def test_putwin(self):
+ win = curses.newwin(5, 12, 1, 2)
+ win.addstr(2, 1, 'Lorem ipsum')
+ with tempfile.TemporaryFile() as f:
+ win.putwin(f)
+ del win
+ f.seek(0)
+ win = curses.getwin(f)
+ self.assertEqual(win.getbegyx(), (1, 2))
+ self.assertEqual(win.getmaxyx(), (5, 12))
+ self.assertEqual(win.instr(2, 0), b' Lorem ipsum')
- win.border(65, 66, 67, 68,
- 69, 70, 71, 72)
+ def test_borders_and_lines(self):
+ win = curses.newwin(5, 10, 5, 2)
win.border('|', '!', '-', '_',
'+', '\\', '#', '/')
- with self.assertRaises(TypeError,
- msg="Expected win.border() to raise TypeError"):
- win.border(65, 66, 67, 68,
- 69, [], 71, 72)
-
- win.box(65, 67)
- win.box('!', '_')
+ self.assertEqual(win.instr(0, 0), b'+--------\\')
+ self.assertEqual(win.instr(1, 0), b'| !')
+ self.assertEqual(win.instr(4, 0), b'#________/')
+ win.border(b'|', b'!', b'-', b'_',
+ b'+', b'\\', b'#', b'/')
+ win.border(65, 66, 67, 68,
+ 69, 70, 71, 72)
+ self.assertRaises(TypeError, win.border,
+ 65, 66, 67, 68, 69, [], 71, 72)
+ self.assertRaises(TypeError, win.border,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73)
+ self.assertRaises(TypeError, win.border,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73)
+ win.border(65, 66, 67, 68, 69, 70, 71)
+ win.border(65, 66, 67, 68, 69, 70)
+ win.border(65, 66, 67, 68, 69)
+ win.border(65, 66, 67, 68)
+ win.border(65, 66, 67)
+ win.border(65, 66)
+ win.border(65)
+ win.border()
+
+ win.box(':', '~')
+ self.assertEqual(win.instr(0, 1, 8), b'~~~~~~~~')
+ self.assertEqual(win.instr(1, 0), b': :')
+ self.assertEqual(win.instr(4, 1, 8), b'~~~~~~~~')
win.box(b':', b'~')
+ win.box(65, 67)
self.assertRaises(TypeError, win.box, 65, 66, 67)
self.assertRaises(TypeError, win.box, 65)
win.box()
- stdscr.clearok(1)
+ win.move(1, 2)
+ win.hline('-', 5)
+ self.assertEqual(win.instr(1, 1, 7), b' ----- ')
+ win.hline(b'-', 5)
+ win.hline(45, 5)
+ win.hline('-', 5, curses.A_BOLD)
+ win.hline(1, 1, '-', 5)
+ win.hline(1, 1, '-', 5, curses.A_BOLD)
+
+ win.move(1, 2)
+ win.vline('a', 3)
+ win.vline(b'a', 3)
+ win.vline(97, 3)
+ win.vline('a', 3, curses.A_STANDOUT)
+ win.vline(1, 1, 'a', 3)
+ win.vline(1, 1, ';', 2, curses.A_STANDOUT)
+ self.assertEqual(win.inch(1, 1), b';'[0] | curses.A_STANDOUT)
+ self.assertEqual(win.inch(2, 1), b';'[0] | curses.A_STANDOUT)
+ self.assertEqual(win.inch(3, 1), b'a'[0])
+
+ def test_unctrl(self):
+ # TODO: wunctrl()
+ self.assertEqual(curses.unctrl(b'A'), b'A')
+ self.assertEqual(curses.unctrl('A'), b'A')
+ self.assertEqual(curses.unctrl(65), b'A')
+ self.assertEqual(curses.unctrl(b'\n'), b'^J')
+ self.assertEqual(curses.unctrl('\n'), b'^J')
+ self.assertEqual(curses.unctrl(10), b'^J')
+ self.assertRaises(TypeError, curses.unctrl, b'')
+ self.assertRaises(TypeError, curses.unctrl, b'AB')
+ self.assertRaises(TypeError, curses.unctrl, '')
+ self.assertRaises(TypeError, curses.unctrl, 'AB')
+ self.assertRaises(OverflowError, curses.unctrl, 2**64)
+
+ def test_endwin(self):
+ if not self.isatty:
+ self.skipTest('requires terminal')
+ self.assertIs(curses.isendwin(), False)
+ curses.endwin()
+ self.assertIs(curses.isendwin(), True)
+ curses.doupdate()
+ self.assertIs(curses.isendwin(), False)
+
+ def test_terminfo(self):
+ self.assertIsInstance(curses.tigetflag('hc'), int)
+ self.assertEqual(curses.tigetflag('cols'), -1)
+ self.assertEqual(curses.tigetflag('cr'), -1)
+
+ self.assertIsInstance(curses.tigetnum('cols'), int)
+ self.assertEqual(curses.tigetnum('hc'), -2)
+ self.assertEqual(curses.tigetnum('cr'), -2)
+
+ self.assertIsInstance(curses.tigetstr('cr'), (bytes, type(None)))
+ self.assertIsNone(curses.tigetstr('hc'))
+ self.assertIsNone(curses.tigetstr('cols'))
+
+ cud = curses.tigetstr('cud')
+ if cud is not None:
+ # See issue10570.
+ self.assertIsInstance(cud, bytes)
+ curses.tparm(cud, 2)
+ cud_2 = curses.tparm(cud, 2)
+ self.assertIsInstance(cud_2, bytes)
+ curses.putp(cud_2)
+
+ curses.putp(b'abc\n')
+
+ def test_misc_module_funcs(self):
+ curses.delay_output(1)
+ curses.flushinp()
+
+ curses.doupdate()
+ self.assertIs(curses.isendwin(), False)
- win4 = stdscr.derwin(2,2)
- win4 = stdscr.derwin(1,1, 5,5)
- win4.mvderwin(9,9)
+ curses.napms(100)
+
+ curses.newpad(50, 50)
+
+ def test_env_queries(self):
+ # TODO: term_attrs(), erasewchar(), killwchar()
+ self.assertIsInstance(curses.termname(), bytes)
+ self.assertIsInstance(curses.longname(), bytes)
+ self.assertIsInstance(curses.baudrate(), int)
+ self.assertIsInstance(curses.has_ic(), bool)
+ self.assertIsInstance(curses.has_il(), bool)
+ self.assertIsInstance(curses.termattrs(), int)
+
+ c = curses.killchar()
+ self.assertIsInstance(c, bytes)
+ self.assertEqual(len(c), 1)
+ c = curses.erasechar()
+ self.assertIsInstance(c, bytes)
+ self.assertEqual(len(c), 1)
+
+ def test_output_options(self):
+ stdscr = self.stdscr
+
+ stdscr.clearok(True)
+ stdscr.clearok(False)
- stdscr.echochar('a')
- stdscr.echochar('a', curses.A_BOLD)
- stdscr.hline('-', 5)
- stdscr.hline('-', 5, curses.A_BOLD)
- stdscr.hline(1,1,'-', 5)
- stdscr.hline(1,1,'-', 5, curses.A_BOLD)
+ stdscr.idcok(True)
+ stdscr.idcok(False)
+
+ stdscr.idlok(False)
+ stdscr.idlok(True)
- stdscr.idcok(1)
- stdscr.idlok(1)
if hasattr(stdscr, 'immedok'):
- stdscr.immedok(1)
- stdscr.immedok(0)
- stdscr.insch('c')
- stdscr.insdelln(1)
- stdscr.insnstr('abc', 3)
- stdscr.insnstr('abc', 3, curses.A_BOLD)
- stdscr.insnstr(5, 5, 'abc', 3)
- stdscr.insnstr(5, 5, 'abc', 3, curses.A_BOLD)
-
- stdscr.insstr('def')
- stdscr.insstr('def', curses.A_BOLD)
- stdscr.insstr(5, 5, 'def')
- stdscr.insstr(5, 5, 'def', curses.A_BOLD)
- stdscr.is_linetouched(0)
- stdscr.keypad(1)
- stdscr.leaveok(1)
- stdscr.move(3,3)
- win.mvwin(2,2)
- stdscr.nodelay(1)
- stdscr.notimeout(1)
- win2.overlay(win)
- win2.overwrite(win)
- win2.overlay(win, 1, 2, 2, 1, 3, 3)
- win2.overwrite(win, 1, 2, 2, 1, 3, 3)
- stdscr.redrawln(1,2)
-
- stdscr.scrollok(1)
- stdscr.scroll()
- stdscr.scroll(2)
- stdscr.scroll(-3)
-
- stdscr.move(12, 2)
- stdscr.setscrreg(10,15)
- win3 = stdscr.subwin(10,10)
- win3 = stdscr.subwin(10,10, 5,5)
- if hasattr(stdscr, 'syncok') and not sys.platform.startswith("sunos"):
- stdscr.syncok(1)
- stdscr.timeout(5)
- stdscr.touchline(5,5)
- stdscr.touchline(5,5,0)
- stdscr.vline('a', 3)
- stdscr.vline('a', 3, curses.A_STANDOUT)
- if hasattr(stdscr, 'chgat'):
- stdscr.chgat(5, 2, 3, curses.A_BLINK)
- stdscr.chgat(3, curses.A_BOLD)
- stdscr.chgat(5, 8, curses.A_UNDERLINE)
- stdscr.chgat(curses.A_BLINK)
- stdscr.refresh()
+ stdscr.immedok(True)
+ stdscr.immedok(False)
- stdscr.vline(1,1, 'a', 3)
- stdscr.vline(1,1, 'a', 3, curses.A_STANDOUT)
+ stdscr.leaveok(True)
+ stdscr.leaveok(False)
- if hasattr(stdscr, 'resize'):
- stdscr.resize(25, 80)
- if hasattr(stdscr, 'enclose'):
- stdscr.enclose(10, 10)
+ stdscr.scrollok(True)
+ stdscr.scrollok(False)
- self.assertRaises(ValueError, stdscr.getstr, -400)
- self.assertRaises(ValueError, stdscr.getstr, 2, 3, -400)
- self.assertRaises(ValueError, stdscr.instr, -2)
- self.assertRaises(ValueError, stdscr.instr, 2, 3, -2)
+ stdscr.setscrreg(5, 10)
- def test_embedded_null_chars(self):
- # reject embedded null bytes and characters
+ curses.nonl()
+ curses.nl(True)
+ curses.nl(False)
+ curses.nl()
+
+
+ def test_input_options(self):
stdscr = self.stdscr
- for arg in ['a', b'a']:
- with self.subTest(arg=arg):
- self.assertRaises(ValueError, stdscr.addstr, 'a\0')
- self.assertRaises(ValueError, stdscr.addnstr, 'a\0', 1)
- self.assertRaises(ValueError, stdscr.insstr, 'a\0')
- self.assertRaises(ValueError, stdscr.insnstr, 'a\0', 1)
-
- def test_module_funcs(self):
- "Test module-level functions"
- for func in [curses.baudrate, curses.beep, curses.can_change_color,
- curses.cbreak, curses.def_prog_mode, curses.doupdate,
- curses.flash, curses.flushinp,
- curses.has_colors, curses.has_ic, curses.has_il,
- curses.isendwin, curses.killchar, curses.longname,
- curses.nocbreak, curses.noecho, curses.nonl,
- curses.noqiflush, curses.noraw,
- curses.reset_prog_mode, curses.termattrs,
- curses.termname, curses.erasechar]:
- with self.subTest(func=func.__qualname__):
- func()
- if hasattr(curses, 'filter'):
- curses.filter()
- if hasattr(curses, 'getsyx'):
- curses.getsyx()
-
- # Functions that actually need arguments
- if curses.tigetstr("cnorm"):
- curses.curs_set(1)
- curses.delay_output(1)
- curses.echo() ; curses.echo(1)
- with tempfile.TemporaryFile() as f:
- self.stdscr.putwin(f)
- f.seek(0)
- curses.getwin(f)
+ if self.isatty:
+ curses.nocbreak()
+ curses.cbreak()
+ curses.cbreak(False)
+ curses.cbreak(True)
+
+ curses.intrflush(True)
+ curses.intrflush(False)
+
+ curses.raw()
+ curses.raw(False)
+ curses.raw(True)
+ curses.noraw()
+ curses.noecho()
+ curses.echo()
+ curses.echo(False)
+ curses.echo(True)
+
+ curses.halfdelay(255)
curses.halfdelay(1)
- curses.intrflush(1)
- curses.meta(1)
- curses.napms(100)
- curses.newpad(50,50)
- win = curses.newwin(5,5)
- win = curses.newwin(5,5, 1,1)
- curses.nl() ; curses.nl(1)
- curses.putp(b'abc')
+
+ stdscr.keypad(True)
+ stdscr.keypad(False)
+
+ curses.meta(True)
+ curses.meta(False)
+
+ stdscr.nodelay(True)
+ stdscr.nodelay(False)
+
+ curses.noqiflush()
+ curses.qiflush(True)
+ curses.qiflush(False)
curses.qiflush()
- curses.raw() ; curses.raw(1)
+
+ stdscr.notimeout(True)
+ stdscr.notimeout(False)
+
+ stdscr.timeout(-1)
+ stdscr.timeout(0)
+ stdscr.timeout(5)
+
+ @requires_curses_func('typeahead')
+ def test_typeahead(self):
+ curses.typeahead(sys.__stdin__.fileno())
+ curses.typeahead(-1)
+
+ def test_prog_mode(self):
+ if not self.isatty:
+ self.skipTest('requires terminal')
+ curses.def_prog_mode()
+ curses.reset_prog_mode()
+
+ def test_beep(self):
+ if (curses.tigetstr("bel") is not None
+ or curses.tigetstr("flash") is not None):
+ curses.beep()
+ else:
+ try:
+ curses.beep()
+ except curses.error:
+ self.skipTest('beep() failed')
+
+ def test_flash(self):
+ if (curses.tigetstr("bel") is not None
+ or curses.tigetstr("flash") is not None):
+ curses.flash()
+ else:
+ try:
+ curses.flash()
+ except curses.error:
+ self.skipTest('flash() failed')
+
+ def test_curs_set(self):
+ for vis, cap in [(0, 'civis'), (2, 'cvvis'), (1, 'cnorm')]:
+ if curses.tigetstr(cap) is not None:
+ curses.curs_set(vis)
+ else:
+ try:
+ curses.curs_set(vis)
+ except curses.error:
+ pass
+
+ @requires_curses_func('get_escdelay')
+ def test_escdelay(self):
+ escdelay = curses.get_escdelay()
+ self.assertIsInstance(escdelay, int)
curses.set_escdelay(25)
self.assertEqual(curses.get_escdelay(), 25)
+ curses.set_escdelay(escdelay)
+
+ @requires_curses_func('get_tabsize')
+ def test_tabsize(self):
+ tabsize = curses.get_tabsize()
+ self.assertIsInstance(tabsize, int)
curses.set_tabsize(4)
self.assertEqual(curses.get_tabsize(), 4)
- if hasattr(curses, 'setsyx'):
- curses.setsyx(5,5)
- curses.tigetflag('hc')
- curses.tigetnum('co')
- curses.tigetstr('cr')
- curses.tparm(b'cr')
- if hasattr(curses, 'typeahead'):
- curses.typeahead(sys.__stdin__.fileno())
- curses.unctrl('a')
- curses.ungetch('a')
- if hasattr(curses, 'use_env'):
- curses.use_env(1)
-
- # Functions only available on a few platforms
- def test_colors_funcs(self):
+ curses.set_tabsize(tabsize)
+
+ @requires_curses_func('getsyx')
+ def test_getsyx(self):
+ y, x = curses.getsyx()
+ self.assertIsInstance(y, int)
+ self.assertIsInstance(x, int)
+ curses.setsyx(4, 5)
+ self.assertEqual(curses.getsyx(), (4, 5))
+
+ def bad_colors(self):
+ return (-2**31 - 1, 2**31, -2**63 - 1, 2**63, 2**64)
+
+ def bad_pairs(self):
+ return (-2**31 - 1, 2**31, -2**63 - 1, 2**63, 2**64)
+
+ def test_has_colors(self):
+ self.assertIsInstance(curses.has_colors(), bool)
+ self.assertIsInstance(curses.can_change_color(), bool)
+
+ def test_start_color(self):
if not curses.has_colors():
self.skipTest('requires colors support')
curses.start_color()
- curses.init_pair(2, 1,1)
- curses.color_content(1)
- curses.color_pair(2)
- curses.pair_content(curses.COLOR_PAIRS - 1)
- curses.pair_number(0)
-
- if hasattr(curses, 'use_default_colors'):
+ if verbose:
+ print(f'COLORS = {curses.COLORS}', file=sys.stderr)
+ print(f'COLOR_PAIRS = {curses.COLOR_PAIRS}', file=sys.stderr)
+
+ @requires_colors
+ def test_color_content(self):
+ self.assertEqual(curses.color_content(curses.COLOR_BLACK), (0, 0, 0))
+ curses.color_content(0)
+ maxcolor = min(curses.COLORS - 1, SHORT_MAX)
+ curses.color_content(maxcolor)
+
+ for color in self.bad_colors():
+ self.assertRaises(OverflowError, curses.color_content, color)
+ if curses.COLORS <= SHORT_MAX:
+ self.assertRaises(curses.error, curses.color_content, curses.COLORS)
+ self.assertRaises(curses.error, curses.color_content, -1)
+
+ @requires_colors
+ def test_init_color(self):
+ if not curses.can_change_color():
+ self.skipTest('cannot change color')
+
+ old = curses.color_content(0)
+ try:
+ curses.init_color(0, *old)
+ except curses.error:
+ self.skipTest('cannot change color (init_color() failed)')
+ self.addCleanup(curses.init_color, 0, *old)
+ curses.init_color(0, 0, 0, 0)
+ self.assertEqual(curses.color_content(0), (0, 0, 0))
+ curses.init_color(0, 1000, 1000, 1000)
+ self.assertEqual(curses.color_content(0), (1000, 1000, 1000))
+
+ maxcolor = min(curses.COLORS - 1, SHORT_MAX)
+ old = curses.color_content(maxcolor)
+ curses.init_color(maxcolor, *old)
+ self.addCleanup(curses.init_color, maxcolor, *old)
+ curses.init_color(maxcolor, 0, 500, 1000)
+ self.assertEqual(curses.color_content(maxcolor), (0, 500, 1000))
+
+ for color in self.bad_colors():
+ self.assertRaises(OverflowError, curses.init_color, color, 0, 0, 0)
+ if curses.COLORS <= SHORT_MAX:
+ self.assertRaises(curses.error, curses.init_color, curses.COLORS, 0, 0, 0)
+ self.assertRaises(curses.error, curses.init_color, -1, 0, 0, 0)
+ for comp in (-1, 1001):
+ self.assertRaises(curses.error, curses.init_color, 0, comp, 0, 0)
+ self.assertRaises(curses.error, curses.init_color, 0, 0, comp, 0)
+ self.assertRaises(curses.error, curses.init_color, 0, 0, 0, comp)
+
+ def get_pair_limit(self):
+ return min(curses.COLOR_PAIRS, SHORT_MAX)
+
+ @requires_colors
+ def test_pair_content(self):
+ if not hasattr(curses, 'use_default_colors'):
+ self.assertEqual(curses.pair_content(0),
+ (curses.COLOR_WHITE, curses.COLOR_BLACK))
+ curses.pair_content(0)
+ maxpair = self.get_pair_limit() - 1
+ if maxpair > 0:
+ curses.pair_content(maxpair)
+
+ for pair in self.bad_pairs():
+ self.assertRaises(OverflowError, curses.pair_content, pair)
+ self.assertRaises(curses.error, curses.pair_content, -1)
+
+ @requires_colors
+ def test_init_pair(self):
+ old = curses.pair_content(1)
+ curses.init_pair(1, *old)
+ self.addCleanup(curses.init_pair, 1, *old)
+
+ curses.init_pair(1, 0, 0)
+ self.assertEqual(curses.pair_content(1), (0, 0))
+ maxcolor = min(curses.COLORS - 1, SHORT_MAX)
+ curses.init_pair(1, maxcolor, 0)
+ self.assertEqual(curses.pair_content(1), (maxcolor, 0))
+ curses.init_pair(1, 0, maxcolor)
+ self.assertEqual(curses.pair_content(1), (0, maxcolor))
+ maxpair = self.get_pair_limit() - 1
+ if maxpair > 1:
+ curses.init_pair(maxpair, 0, 0)
+ self.assertEqual(curses.pair_content(maxpair), (0, 0))
+
+ for pair in self.bad_pairs():
+ self.assertRaises(OverflowError, curses.init_pair, pair, 0, 0)
+ self.assertRaises(curses.error, curses.init_pair, -1, 0, 0)
+ for color in self.bad_colors():
+ self.assertRaises(OverflowError, curses.init_pair, 1, color, 0)
+ self.assertRaises(OverflowError, curses.init_pair, 1, 0, color)
+ if curses.COLORS <= SHORT_MAX:
+ self.assertRaises(curses.error, curses.init_pair, 1, curses.COLORS, 0)
+ self.assertRaises(curses.error, curses.init_pair, 1, 0, curses.COLORS)
+
+ @requires_colors
+ def test_color_attrs(self):
+ for pair in 0, 1, 255:
+ attr = curses.color_pair(pair)
+ self.assertEqual(curses.pair_number(attr), pair, attr)
+ self.assertEqual(curses.pair_number(attr | curses.A_BOLD), pair)
+ self.assertEqual(curses.color_pair(0), 0)
+ self.assertEqual(curses.pair_number(0), 0)
+
+ @requires_curses_func('use_default_colors')
+ @requires_colors
+ def test_use_default_colors(self):
+ old = curses.pair_content(0)
+ try:
curses.use_default_colors()
+ except curses.error:
+ self.skipTest('cannot change color (use_default_colors() failed)')
+ self.assertEqual(curses.pair_content(0), (-1, -1))
+ self.assertIn(old, [(curses.COLOR_WHITE, curses.COLOR_BLACK), (-1, -1), (0, 0)])
- @requires_curses_func('keyname')
def test_keyname(self):
- curses.keyname(13)
+ # TODO: key_name()
+ self.assertEqual(curses.keyname(65), b'A')
+ self.assertEqual(curses.keyname(13), b'^M')
+ self.assertEqual(curses.keyname(127), b'^?')
+ self.assertEqual(curses.keyname(0), b'^@')
+ self.assertRaises(ValueError, curses.keyname, -1)
+ self.assertIsInstance(curses.keyname(256), bytes)
@requires_curses_func('has_key')
def test_has_key(self):
@requires_curses_func('is_term_resized')
def test_is_term_resized(self):
- curses.is_term_resized(*self.stdscr.getmaxyx())
+ lines, cols = curses.LINES, curses.COLS
+ self.assertIs(curses.is_term_resized(lines, cols), False)
+ self.assertIs(curses.is_term_resized(lines-1, cols-1), True)
@requires_curses_func('resize_term')
def test_resize_term(self):
- curses.resize_term(*self.stdscr.getmaxyx())
+ curses.update_lines_cols()
+ lines, cols = curses.LINES, curses.COLS
+ new_lines = lines - 1
+ new_cols = cols + 1
+ curses.resize_term(new_lines, new_cols)
+ self.assertEqual(curses.LINES, new_lines)
+ self.assertEqual(curses.COLS, new_cols)
+
+ curses.resize_term(lines, cols)
+ self.assertEqual(curses.LINES, lines)
+ self.assertEqual(curses.COLS, cols)
@requires_curses_func('resizeterm')
def test_resizeterm(self):
- stdscr = self.stdscr
+ curses.update_lines_cols()
lines, cols = curses.LINES, curses.COLS
new_lines = lines - 1
new_cols = cols + 1
curses.resizeterm(new_lines, new_cols)
-
self.assertEqual(curses.LINES, new_lines)
self.assertEqual(curses.COLS, new_cols)
+ curses.resizeterm(lines, cols)
+ self.assertEqual(curses.LINES, lines)
+ self.assertEqual(curses.COLS, cols)
+
+ def test_ungetch(self):
+ curses.ungetch(b'A')
+ self.assertEqual(self.stdscr.getkey(), 'A')
+ curses.ungetch('B')
+ self.assertEqual(self.stdscr.getkey(), 'B')
+ curses.ungetch(67)
+ self.assertEqual(self.stdscr.getkey(), 'C')
+
def test_issue6243(self):
curses.ungetch(1025)
self.stdscr.getkey()
read = stdscr.get_wch()
self.assertEqual(read, ch)
- def test_issue10570(self):
- b = curses.tparm(curses.tigetstr("cup"), 5, 3)
- self.assertIs(type(b), bytes)
-
def test_encoding(self):
stdscr = self.stdscr
import codecs
human_readable_signature = stdscr.addch.__doc__.split("\n")[0]
self.assertIn("[y, x,]", human_readable_signature)
+ @requires_curses_window_meth('resize')
def test_issue13051(self):
- stdscr = self.stdscr
- if not hasattr(stdscr, 'resize'):
- raise unittest.SkipTest('requires curses.window.resize')
- box = curses.textpad.Textbox(stdscr, insert_mode=True)
- lines, cols = stdscr.getmaxyx()
- stdscr.resize(lines-2, cols-2)
+ win = curses.newwin(5, 15, 2, 5)
+ box = curses.textpad.Textbox(win, insert_mode=True)
+ lines, cols = win.getmaxyx()
+ win.resize(lines-2, cols-2)
# this may cause infinite recursion, leading to a RuntimeError
box._insert_printable_char('a')
class MiscTests(unittest.TestCase):
- @requires_curses_func('update_lines_cols')
def test_update_lines_cols(self):
- # this doesn't actually test that LINES and COLS are updated,
- # because we can't automate changing them. See Issue #4254 for
- # a manual test script. We can only test that the function
- # can be called.
curses.update_lines_cols()
+ lines, cols = curses.LINES, curses.COLS
+ curses.LINES = curses.COLS = 0
+ curses.update_lines_cols()
+ self.assertEqual(curses.LINES, lines)
+ self.assertEqual(curses.COLS, cols)
@requires_curses_func('ncurses_version')
def test_ncurses_version(self):
v = curses.ncurses_version
+ if verbose:
+ print(f'ncurses_version = {curses.ncurses_version}', flush=True)
self.assertIsInstance(v[:], tuple)
self.assertEqual(len(v), 3)
self.assertIsInstance(v[0], int)
self.assertGreaterEqual(v.minor, 0)
self.assertGreaterEqual(v.patch, 0)
+
class TestAscii(unittest.TestCase):
def test_controlnames(self):
self.assertEqual(unctrl(ord('\xc1')), '!A')
+def lorem_ipsum(win):
+ text = [
+ 'Lorem ipsum',
+ 'dolor sit amet,',
+ 'consectetur',
+ 'adipiscing elit,',
+ 'sed do eiusmod',
+ 'tempor incididunt',
+ 'ut labore et',
+ 'dolore magna',
+ 'aliqua.',
+ ]
+ maxy, maxx = win.getmaxyx()
+ for y, line in enumerate(text[:maxy]):
+ win.addstr(y, 0, line[:maxx - (y == maxy - 1)])
+
if __name__ == '__main__':
unittest.main()
import itertools
import math
import pickle
+import random
+import string
import sys
import types
import unittest
self.fail("inheriting from ModuleType and str at the same time "
"should fail")
+ # Issue 34805: Verify that definition order is retained
+ def random_name():
+ return ''.join(random.choices(string.ascii_letters, k=10))
+ class A:
+ pass
+ subclasses = [type(random_name(), (A,), {}) for i in range(100)]
+ self.assertEqual(A.__subclasses__(), subclasses)
+
def test_multiple_inheritance(self):
# Testing multiple inheritance...
class C(object):
d = CustomReversedDict(pairs)
self.assertEqual(pairs[::-1], list(dict(d).items()))
+ @support.cpython_only
+ def test_dict_items_result_gc(self):
+ # bpo-42536: dict.items's tuple-reuse speed trick breaks the GC's
+ # assumptions about what can be untracked. Make sure we re-track result
+ # tuples whenever we reuse them.
+ it = iter({None: []}.items())
+ gc.collect()
+ # That GC collection probably untracked the recycled internal result
+ # tuple, which is initialized to (None, None). Make sure it's re-tracked
+ # when it's mutated and returned from __next__:
+ self.assertTrue(gc.is_tracked(next(it)))
+
+ @support.cpython_only
+ def test_dict_items_result_gc(self):
+ # Same as test_dict_items_result_gc above, but reversed.
+ it = reversed({None: []}.items())
+ gc.collect()
+ self.assertTrue(gc.is_tracked(next(it)))
+
class CAPITest(unittest.TestCase):
set(['__class__', '__doc__', '__module__', 'name', 'value', 'invisible']),
)
+ def test_dir_on_sub_with_behavior_including_instance_dict_on_super(self):
+ # see issue40084
+ class SuperEnum(IntEnum):
+ def __new__(cls, value, description=""):
+ obj = int.__new__(cls, value)
+ obj._value_ = value
+ obj.description = description
+ return obj
+ class SubEnum(SuperEnum):
+ sample = 5
+ self.assertTrue({'description'} <= set(dir(SubEnum.sample)))
+
def test_enum_in_enum_out(self):
Season = self.Season
self.assertIs(Season(Season.WINTER), Season.WINTER)
class Test1Enum(MyMethodEnum, int, MyStrEnum):
One = 1
Two = 2
+ self.assertTrue(Test1Enum._member_type_ is int)
self.assertEqual(str(Test1Enum.One), 'MyStr')
+ self.assertEqual(format(Test1Enum.One, ''), 'MyStr')
#
class Test2Enum(MyStrEnum, MyMethodEnum):
One = 1
Two = 2
self.assertEqual(str(Test2Enum.One), 'MyStr')
+ self.assertEqual(format(Test1Enum.One, ''), 'MyStr')
def test_inherited_data_type(self):
class HexInt(int):
class auto_enum(type(Enum)):
def __new__(metacls, cls, bases, classdict):
temp = type(classdict)()
+ temp._cls_name = cls
names = set(classdict._member_names)
i = 0
for k in classdict._member_names:
REVERT_ALL = "REVERT_ALL"
RETRY = "RETRY"
+ def test_multiple_mixin_inherited(self):
+ class MyInt(int):
+ def __new__(cls, value):
+ return super().__new__(cls, value)
+
+ class HexMixin:
+ def __repr__(self):
+ return hex(self)
+
+ class MyIntEnum(HexMixin, MyInt, enum.Enum):
+ pass
+
+ class Foo(MyIntEnum):
+ TEST = 1
+ self.assertTrue(isinstance(Foo.TEST, MyInt))
+ self.assertEqual(repr(Foo.TEST), "0x1")
+
+ class Fee(MyIntEnum):
+ TEST = 1
+ def __new__(cls, value):
+ value += 1
+ member = int.__new__(cls, value)
+ member._value_ = value
+ return member
+ self.assertEqual(Fee.TEST, 2)
+
def test_empty_globals(self):
# bpo-35717: sys._getframe(2).f_globals['__name__'] fails with KeyError
# when using compile and exec because f_globals is empty
local_ls = {}
exec(code, global_ns, local_ls)
+ @unittest.skipUnless(
+ sys.version_info[:2] == (3, 9),
+ 'private variables are now normal attributes',
+ )
+ def test_warning_for_private_variables(self):
+ with self.assertWarns(DeprecationWarning):
+ class Private(Enum):
+ __corporal = 'Radar'
+ self.assertEqual(Private._Private__corporal.value, 'Radar')
+ try:
+ with self.assertWarns(DeprecationWarning):
+ class Private(Enum):
+ __major_ = 'Hoolihan'
+ except ValueError:
+ pass
+
class TestOrder(unittest.TestCase):
self.assertEqual(repr(~(Open.RO | Open.CE)), '<Open.AC: 3>')
self.assertEqual(repr(~(Open.WO | Open.CE)), '<Open.RW: 2>')
+ def test_format(self):
+ Perm = self.Perm
+ self.assertEqual(format(Perm.R, ''), 'Perm.R')
+ self.assertEqual(format(Perm.R | Perm.X, ''), 'Perm.R|X')
+
def test_or(self):
Perm = self.Perm
for i in Perm:
'at least one thread failed while creating composite members')
self.assertEqual(256, len(seen), 'too many composite members created')
+ def test_init_subclass(self):
+ class MyEnum(Flag):
+ def __init_subclass__(cls, **kwds):
+ super().__init_subclass__(**kwds)
+ self.assertFalse(cls.__dict__.get('_test', False))
+ cls._test1 = 'MyEnum'
+ #
+ class TheirEnum(MyEnum):
+ def __init_subclass__(cls, **kwds):
+ super(TheirEnum, cls).__init_subclass__(**kwds)
+ cls._test2 = 'TheirEnum'
+ class WhoseEnum(TheirEnum):
+ def __init_subclass__(cls, **kwds):
+ pass
+ class NoEnum(WhoseEnum):
+ ONE = 1
+ self.assertEqual(TheirEnum.__dict__['_test1'], 'MyEnum')
+ self.assertEqual(WhoseEnum.__dict__['_test1'], 'MyEnum')
+ self.assertEqual(WhoseEnum.__dict__['_test2'], 'TheirEnum')
+ self.assertFalse(NoEnum.__dict__.get('_test1', False))
+ self.assertFalse(NoEnum.__dict__.get('_test2', False))
+ #
+ class OurEnum(MyEnum):
+ def __init_subclass__(cls, **kwds):
+ cls._test2 = 'OurEnum'
+ class WhereEnum(OurEnum):
+ def __init_subclass__(cls, **kwds):
+ pass
+ class NeverEnum(WhereEnum):
+ ONE = 1
+ self.assertEqual(OurEnum.__dict__['_test1'], 'MyEnum')
+ self.assertFalse(WhereEnum.__dict__.get('_test1', False))
+ self.assertEqual(WhereEnum.__dict__['_test2'], 'OurEnum')
+ self.assertFalse(NeverEnum.__dict__.get('_test1', False))
+ self.assertFalse(NeverEnum.__dict__.get('_test2', False))
+
class TestIntFlag(unittest.TestCase):
"""Tests of the IntFlags."""
def test_type(self):
Perm = self.Perm
+ self.assertTrue(Perm._member_type_ is int)
Open = self.Open
for f in Perm:
self.assertTrue(isinstance(f, Perm))
self.assertEqual(repr(~(Open.WO | Open.CE)), '<Open.RW: -524290>')
self.assertEqual(repr(Open(~4)), '<Open.CE|AC|RW|WO: -5>')
+ def test_format(self):
+ Perm = self.Perm
+ self.assertEqual(format(Perm.R, ''), '4')
+ self.assertEqual(format(Perm.R | Perm.X, ''), '5')
+
def test_or(self):
Perm = self.Perm
for i in Perm:
import operator
import sys
import pickle
+import gc
from test import support
self.assertEqual(len(set(map(id, list(enumerate(self.seq))))), len(self.seq))
self.assertEqual(len(set(map(id, enumerate(self.seq)))), min(1,len(self.seq)))
+ @support.cpython_only
+ def test_enumerate_result_gc(self):
+ # bpo-42536: enumerate's tuple-reuse speed trick breaks the GC's
+ # assumptions about what can be untracked. Make sure we re-track result
+ # tuples whenever we reuse them.
+ it = self.enum([[]])
+ gc.collect()
+ # That GC collection probably untracked the recycled internal result
+ # tuple, which is initialized to (None, None). Make sure it's re-tracked
+ # when it's mutated and returned from __next__:
+ self.assertTrue(gc.is_tracked(next(it)))
+
class MyEnum(enumerate):
pass
self.fail("epoll on closed fd didn't raise EBADF")
def test_control_and_wait(self):
+ # create the epoll object
client, server = self._connected_pair()
-
ep = select.epoll(16)
ep.register(server.fileno(),
select.EPOLLIN | select.EPOLLOUT | select.EPOLLET)
ep.register(client.fileno(),
select.EPOLLIN | select.EPOLLOUT | select.EPOLLET)
+ # EPOLLOUT
now = time.monotonic()
events = ep.poll(1, 4)
then = time.monotonic()
self.assertFalse(then - now > 0.1, then - now)
- events.sort()
expected = [(client.fileno(), select.EPOLLOUT),
(server.fileno(), select.EPOLLOUT)]
- expected.sort()
-
- self.assertEqual(events, expected)
+ self.assertEqual(sorted(events), sorted(expected))
- events = ep.poll(timeout=2.1, maxevents=4)
+ # no event
+ events = ep.poll(timeout=0.1, maxevents=4)
self.assertFalse(events)
- client.send(b"Hello!")
- server.send(b"world!!!")
+ # send: EPOLLIN and EPOLLOUT
+ client.sendall(b"Hello!")
+ server.sendall(b"world!!!")
now = time.monotonic()
- events = ep.poll(1, 4)
+ events = ep.poll(1.0, 4)
then = time.monotonic()
self.assertFalse(then - now > 0.01)
- events.sort()
expected = [(client.fileno(), select.EPOLLIN | select.EPOLLOUT),
(server.fileno(), select.EPOLLIN | select.EPOLLOUT)]
- expected.sort()
-
- self.assertEqual(events, expected)
+ self.assertEqual(sorted(events), sorted(expected))
+ # unregister, modify
ep.unregister(client.fileno())
ep.modify(server.fileno(), select.EPOLLOUT)
now = time.monotonic()
self.assertEqual(binop.left.col_offset, 4)
self.assertEqual(binop.right.col_offset, 7)
+ def test_ast_line_numbers_with_parentheses(self):
+ expr = """
+x = (
+ f" {test(t)}"
+)"""
+ t = ast.parse(expr)
+ self.assertEqual(type(t), ast.Module)
+ self.assertEqual(len(t.body), 1)
+ # check the test(t) location
+ call = t.body[0].value.values[1].value
+ self.assertEqual(type(call), ast.Call)
+ self.assertEqual(call.lineno, 3)
+ self.assertEqual(call.end_lineno, 3)
+ self.assertEqual(call.col_offset, 8)
+ self.assertEqual(call.end_col_offset, 15)
+
+ expr = """
+x = (
+ 'PERL_MM_OPT', (
+ f'wat'
+ f'some_string={f(x)} '
+ f'wat'
+ ),
+)
+"""
+ t = ast.parse(expr)
+ self.assertEqual(type(t), ast.Module)
+ self.assertEqual(len(t.body), 1)
+ # check the fstring
+ fstring = t.body[0].value.elts[1]
+ self.assertEqual(type(fstring), ast.JoinedStr)
+ self.assertEqual(len(fstring.values), 3)
+ wat1, middle, wat2 = fstring.values
+ # check the first wat
+ self.assertEqual(type(wat1), ast.Constant)
+ self.assertEqual(wat1.lineno, 4)
+ self.assertEqual(wat1.end_lineno, 6)
+ self.assertEqual(wat1.col_offset, 12)
+ self.assertEqual(wat1.end_col_offset, 18)
+ # check the call
+ call = middle.value
+ self.assertEqual(type(call), ast.Call)
+ self.assertEqual(call.lineno, 5)
+ self.assertEqual(call.end_lineno, 5)
+ self.assertEqual(call.col_offset, 27)
+ self.assertEqual(call.end_col_offset, 31)
+ # check the second wat
+ self.assertEqual(type(wat2), ast.Constant)
+ self.assertEqual(wat2.lineno, 4)
+ self.assertEqual(wat2.end_lineno, 6)
+ self.assertEqual(wat2.col_offset, 12)
+ self.assertEqual(wat2.end_col_offset, 18)
+
def test_docstring(self):
def f():
f'''Not a docstring'''
Iterable, Iterator,
Reversible,
Container, Collection,
- Callable,
Mailbox, _PartialFile,
ContextVar, Token,
Field,
with self.assertRaises(TypeError):
GenericAlias(bad=float)
+ def test_subclassing_types_genericalias(self):
+ class SubClass(GenericAlias): ...
+ alias = SubClass(list, int)
+ class Bad(GenericAlias):
+ def __new__(cls, *args, **kwargs):
+ super().__new__(cls, *args, **kwargs)
+
+ self.assertEqual(alias, list[int])
+ with self.assertRaises(TypeError):
+ Bad(list, int, bad=int)
+
+ def test_abc_callable(self):
+ # A separate test is needed for Callable since it uses a subclass of
+ # GenericAlias.
+ alias = Callable[[int, str], float]
+ with self.subTest("Testing subscription"):
+ self.assertIs(alias.__origin__, Callable)
+ self.assertEqual(alias.__args__, (int, str, float))
+ self.assertEqual(alias.__parameters__, ())
+
+ with self.subTest("Testing instance checks"):
+ self.assertIsInstance(alias, GenericAlias)
+
+ with self.subTest("Testing weakref"):
+ self.assertEqual(ref(alias)(), alias)
+
+ with self.subTest("Testing pickling"):
+ s = pickle.dumps(alias)
+ loaded = pickle.loads(s)
+ self.assertEqual(alias.__origin__, loaded.__origin__)
+ self.assertEqual(alias.__args__, loaded.__args__)
+ self.assertEqual(alias.__parameters__, loaded.__parameters__)
+
+ with self.subTest("Testing TypeVar substitution"):
+ C1 = Callable[[int, T], T]
+ C2 = Callable[[K, T], V]
+ C3 = Callable[..., T]
+ self.assertEqual(C1[str], Callable[[int, str], str])
+ self.assertEqual(C2[int, float, str], Callable[[int, float], str])
+ self.assertEqual(C3[int], Callable[..., int])
+
+ # multi chaining
+ C4 = C2[int, V, str]
+ self.assertEqual(repr(C4).split(".")[-1], "Callable[[int, ~V], str]")
+ self.assertEqual(repr(C4[dict]).split(".")[-1], "Callable[[int, dict], str]")
+ self.assertEqual(C4[dict], Callable[[int, dict], str])
+
+ with self.subTest("Testing type erasure"):
+ class C1(Callable):
+ def __call__(self):
+ return None
+ a = C1[[int], T]
+ self.assertIs(a().__class__, C1)
+ self.assertEqual(a().__orig_class__, C1[[int], T])
+
+ # bpo-42195
+ with self.subTest("Testing collections.abc.Callable's consistency "
+ "with typing.Callable"):
+ c1 = typing.Callable[[int, str], dict]
+ c2 = Callable[[int, str], dict]
+ self.assertEqual(c1.__args__, c2.__args__)
+ self.assertEqual(hash(c1.__args__), hash(c2.__args__))
+
if __name__ == "__main__":
unittest.main()
self._run_check('<!spacer type="block" height="25">',
[('comment', 'spacer type="block" height="25"')])
- def test_with_unquoted_attributes(self):
- # see #12008
- html = ("<html><body bgcolor=d0ca90 text='181008'>"
- "<table cellspacing=0 cellpadding=1 width=100% ><tr>"
- "<td align=left><font size=-1>"
- "- <a href=/rabota/><span class=en> software-and-i</span></a>"
- "- <a href='/1/'><span class=en> library</span></a></table>")
- expected = [
- ('starttag', 'html', []),
- ('starttag', 'body', [('bgcolor', 'd0ca90'), ('text', '181008')]),
- ('starttag', 'table',
- [('cellspacing', '0'), ('cellpadding', '1'), ('width', '100%')]),
- ('starttag', 'tr', []),
- ('starttag', 'td', [('align', 'left')]),
- ('starttag', 'font', [('size', '-1')]),
- ('data', '- '), ('starttag', 'a', [('href', '/rabota/')]),
- ('starttag', 'span', [('class', 'en')]), ('data', ' software-and-i'),
- ('endtag', 'span'), ('endtag', 'a'),
- ('data', '- '), ('starttag', 'a', [('href', '/1/')]),
- ('starttag', 'span', [('class', 'en')]), ('data', ' library'),
- ('endtag', 'span'), ('endtag', 'a'), ('endtag', 'table')
- ]
- self._run_check(html, expected)
-
- def test_comma_between_attributes(self):
- self._run_check('<form action="/xxx.php?a=1&b=2&", '
- 'method="post">', [
- ('starttag', 'form',
- [('action', '/xxx.php?a=1&b=2&'),
- (',', None), ('method', 'post')])])
-
- def test_weird_chars_in_unquoted_attribute_values(self):
- self._run_check('<form action=bogus|&#()value>', [
- ('starttag', 'form',
- [('action', 'bogus|&#()value')])])
-
def test_invalid_end_tags(self):
# A collection of broken end tags. <br> is used as separator.
# see http://www.w3.org/TR/html5/tokenization.html#end-tag-open-state
[("href", "http://www.example.org/\">;")]),
("data", "spam"), ("endtag", "a")])
+ def test_with_unquoted_attributes(self):
+ # see #12008
+ html = ("<html><body bgcolor=d0ca90 text='181008'>"
+ "<table cellspacing=0 cellpadding=1 width=100% ><tr>"
+ "<td align=left><font size=-1>"
+ "- <a href=/rabota/><span class=en> software-and-i</span></a>"
+ "- <a href='/1/'><span class=en> library</span></a></table>")
+ expected = [
+ ('starttag', 'html', []),
+ ('starttag', 'body', [('bgcolor', 'd0ca90'), ('text', '181008')]),
+ ('starttag', 'table',
+ [('cellspacing', '0'), ('cellpadding', '1'), ('width', '100%')]),
+ ('starttag', 'tr', []),
+ ('starttag', 'td', [('align', 'left')]),
+ ('starttag', 'font', [('size', '-1')]),
+ ('data', '- '), ('starttag', 'a', [('href', '/rabota/')]),
+ ('starttag', 'span', [('class', 'en')]), ('data', ' software-and-i'),
+ ('endtag', 'span'), ('endtag', 'a'),
+ ('data', '- '), ('starttag', 'a', [('href', '/1/')]),
+ ('starttag', 'span', [('class', 'en')]), ('data', ' library'),
+ ('endtag', 'span'), ('endtag', 'a'), ('endtag', 'table')
+ ]
+ self._run_check(html, expected)
+
+ def test_comma_between_attributes(self):
+ # see bpo 41478
+ # HTMLParser preserves duplicate attributes, leaving the task of
+ # removing duplicate attributes to a conformant html tree builder
+ html = ('<div class=bar,baz=asd>' # between attrs (unquoted)
+ '<div class="bar",baz="asd">' # between attrs (quoted)
+ '<div class=bar, baz=asd,>' # after values (unquoted)
+ '<div class="bar", baz="asd",>' # after values (quoted)
+ '<div class="bar",>' # one comma values (quoted)
+ '<div class=,bar baz=,asd>' # before values (unquoted)
+ '<div class=,"bar" baz=,"asd">' # before values (quoted)
+ '<div ,class=bar ,baz=asd>' # before names
+ '<div class,="bar" baz,="asd">' # after names
+ )
+ expected = [
+ ('starttag', 'div', [('class', 'bar,baz=asd'),]),
+ ('starttag', 'div', [('class', 'bar'), (',baz', 'asd')]),
+ ('starttag', 'div', [('class', 'bar,'), ('baz', 'asd,')]),
+ ('starttag', 'div', [('class', 'bar'), (',', None),
+ ('baz', 'asd'), (',', None)]),
+ ('starttag', 'div', [('class', 'bar'), (',', None)]),
+ ('starttag', 'div', [('class', ',bar'), ('baz', ',asd')]),
+ ('starttag', 'div', [('class', ',"bar"'), ('baz', ',"asd"')]),
+ ('starttag', 'div', [(',class', 'bar'), (',baz', 'asd')]),
+ ('starttag', 'div', [('class,', 'bar'), ('baz,', 'asd')]),
+ ]
+ self._run_check(html, expected)
+
+ def test_weird_chars_in_unquoted_attribute_values(self):
+ self._run_check('<form action=bogus|&#()value>', [
+ ('starttag', 'form',
+ [('action', 'bogus|&#()value')])])
if __name__ == "__main__":
unittest.main()
import errno
-from http import client
+from http import client, HTTPStatus
import io
import itertools
import os
class BasicTest(TestCase):
+ def test_dir_with_added_behavior_on_status(self):
+ # see issue40084
+ self.assertTrue({'description', 'name', 'phrase', 'value'} <= set(dir(HTTPStatus(404))))
+
def test_status_lines(self):
# Test HTTP status lines
if __name__ == '__main__':
tk.NoDefaultRoot()
unittest.main(exit=False)
- tk._support_default_root = 1
+ tk._support_default_root = True
tk._default_root = None
import sys
import struct
import threading
+import gc
+
maxsize = support.MAX_Py_ssize_t
minsize = -maxsize-1
self.assertRaises(StopIteration, next, f(lambda x:x, []))
self.assertRaises(StopIteration, next, f(lambda x:x, StopNow()))
+ @support.cpython_only
+ def test_combinations_result_gc(self):
+ # bpo-42536: combinations's tuple-reuse speed trick breaks the GC's
+ # assumptions about what can be untracked. Make sure we re-track result
+ # tuples whenever we reuse them.
+ it = combinations([None, []], 1)
+ next(it)
+ gc.collect()
+ # That GC collection probably untracked the recycled internal result
+ # tuple, which has the value (None,). Make sure it's re-tracked when
+ # it's mutated and returned from __next__:
+ self.assertTrue(gc.is_tracked(next(it)))
+
+ @support.cpython_only
+ def test_combinations_with_replacement_result_gc(self):
+ # Ditto for combinations_with_replacement.
+ it = combinations_with_replacement([None, []], 1)
+ next(it)
+ gc.collect()
+ self.assertTrue(gc.is_tracked(next(it)))
+
+ @support.cpython_only
+ def test_permutations_result_gc(self):
+ # Ditto for permutations.
+ it = permutations([None, []], 1)
+ next(it)
+ gc.collect()
+ self.assertTrue(gc.is_tracked(next(it)))
+
+ @support.cpython_only
+ def test_product_result_gc(self):
+ # Ditto for product.
+ it = product([None, []])
+ next(it)
+ gc.collect()
+ self.assertTrue(gc.is_tracked(next(it)))
+
+ @support.cpython_only
+ def test_zip_longest_result_gc(self):
+ # Ditto for zip_longest.
+ it = zip_longest([[]])
+ gc.collect()
+ self.assertTrue(gc.is_tracked(next(it)))
+
+
class TestExamples(unittest.TestCase):
def test_accumulate(self):
logging.disable(83)
self.assertEqual(logging.root.manager.disable, 83)
+ self.assertRaises(ValueError, logging.disable, "doesnotexists")
+
+ class _NotAnIntOrString:
+ pass
+
+ self.assertRaises(TypeError, logging.disable, _NotAnIntOrString())
+
+ logging.disable("WARN")
+
# test the default value introduced in 3.7
# (Issue #28524)
logging.disable()
desc = self.server.description(self.GROUP_NAME)
_check_desc(desc)
# Another sanity check
- self.assertIn("Python", desc)
+ self.assertIn(self.DESC, desc)
# With a pattern
desc = self.server.description(self.GROUP_PAT)
_check_desc(desc)
NNTP_HOST = 'news.trigofacile.com'
GROUP_NAME = 'fr.comp.lang.python'
GROUP_PAT = 'fr.comp.lang.*'
+ DESC = 'Python'
NNTP_CLASS = NNTP
# 400 connections per day are accepted from each IP address."
NNTP_HOST = 'nntp.aioe.org'
- GROUP_NAME = 'comp.lang.python'
- GROUP_PAT = 'comp.lang.*'
+ # bpo-42794: aioe.test is one of the official groups on this server
+ # used for testing: https://news.aioe.org/manual/aioe-hierarchy/
+ GROUP_NAME = 'aioe.test'
+ GROUP_PAT = 'aioe.*'
+ DESC = 'test'
NNTP_CLASS = getattr(nntplib, 'NNTP_SSL', None)
with self.assertRaises(ValueError):
a |= "BAD"
+ @support.cpython_only
+ def test_ordered_dict_items_result_gc(self):
+ # bpo-42536: OrderedDict.items's tuple-reuse speed trick breaks the GC's
+ # assumptions about what can be untracked. Make sure we re-track result
+ # tuples whenever we reuse them.
+ it = iter(self.OrderedDict({None: []}).items())
+ gc.collect()
+ # That GC collection probably untracked the recycled internal result
+ # tuple, which is initialized to (None, None). Make sure it's re-tracked
+ # when it's mutated and returned from __next__:
+ self.assertTrue(gc.is_tracked(next(it)))
class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase):
self.assertEqual(fcntl.fcntl(fd, fcntl.F_GETFD) & fcntl.FD_CLOEXEC,
0)
+ @unittest.skipUnless(hasattr(os, 'O_PATH'), "need os.O_PATH")
+ def test_get_set_inheritable_o_path(self):
+ fd = os.open(__file__, os.O_PATH)
+ self.addCleanup(os.close, fd)
+ self.assertEqual(os.get_inheritable(fd), False)
+
+ os.set_inheritable(fd, True)
+ self.assertEqual(os.get_inheritable(fd), True)
+
+ os.set_inheritable(fd, False)
+ self.assertEqual(os.get_inheritable(fd), False)
+
+ def test_get_set_inheritable_badf(self):
+ fd = support.make_bad_fd()
+
+ with self.assertRaises(OSError) as ctx:
+ os.get_inheritable(fd)
+ self.assertEqual(ctx.exception.errno, errno.EBADF)
+
+ with self.assertRaises(OSError) as ctx:
+ os.set_inheritable(fd, True)
+ self.assertEqual(ctx.exception.errno, errno.EBADF)
+
+ with self.assertRaises(OSError) as ctx:
+ os.set_inheritable(fd, False)
+ self.assertEqual(ctx.exception.errno, errno.EBADF)
+
def test_open(self):
fd = os.open(__file__, os.O_RDONLY)
self.addCleanup(os.close, fd)
'(Pdb) ',
])
+
+ def test_issue42384(self):
+ '''When running `python foo.py` sys.path[0] is an absolute path. `python -m pdb foo.py` should behave the same'''
+ script = textwrap.dedent("""
+ import sys
+ print('sys.path[0] is', sys.path[0])
+ """)
+ commands = 'c\nq'
+
+ with support.temp_cwd() as cwd:
+ expected = f'(Pdb) sys.path[0] is {os.path.realpath(cwd)}'
+
+ stdout, stderr = self.run_pdb_script(script, commands)
+
+ self.assertEqual(stdout.split('\n')[2].rstrip('\r'), expected)
+
+ @support.skip_unless_symlink
+ def test_issue42384_symlink(self):
+ '''When running `python foo.py` sys.path[0] resolves symlinks. `python -m pdb foo.py` should behave the same'''
+ script = textwrap.dedent("""
+ import sys
+ print('sys.path[0] is', sys.path[0])
+ """)
+ commands = 'c\nq'
+
+ with support.temp_cwd() as cwd:
+ cwd = os.path.realpath(cwd)
+ dir_one = os.path.join(cwd, 'dir_one')
+ dir_two = os.path.join(cwd, 'dir_two')
+ expected = f'(Pdb) sys.path[0] is {dir_one}'
+
+ os.mkdir(dir_one)
+ with open(os.path.join(dir_one, 'foo.py'), 'w') as f:
+ f.write(script)
+ os.mkdir(dir_two)
+ os.symlink(os.path.join(dir_one, 'foo.py'), os.path.join(dir_two, 'foo.py'))
+
+ stdout, stderr = self._run_pdb([os.path.join('dir_two', 'foo.py')], commands)
+
+ self.assertEqual(stdout.split('\n')[2].rstrip('\r'), expected)
+
+ def test_issue42383(self):
+ with support.temp_cwd() as cwd:
+ with open('foo.py', 'w') as f:
+ s = textwrap.dedent("""
+ print('The correct file was executed')
+
+ import os
+ os.chdir("subdir")
+ """)
+ f.write(s)
+
+ subdir = os.path.join(cwd, 'subdir')
+ os.mkdir(subdir)
+ os.mkdir(os.path.join(subdir, 'subdir'))
+ wrong_file = os.path.join(subdir, 'foo.py')
+
+ with open(wrong_file, 'w') as f:
+ f.write('print("The wrong file was executed")')
+
+ stdout, stderr = self._run_pdb(['foo.py'], 'c\nc\nq')
+ expected = '(Pdb) The correct file was executed'
+ self.assertEqual(stdout.split('\n')[6].rstrip('\r'), expected)
+
+
def load_tests(*args):
from test import test_pdb
suites = [
import os
+import copy
+import pickle
import platform
import subprocess
import sys
)
self.assertEqual(tuple(res), expected)
+ def test_uname_replace(self):
+ res = platform.uname()
+ new = res._replace(
+ system='system', node='node', release='release',
+ version='version', machine='machine')
+ self.assertEqual(new.system, 'system')
+ self.assertEqual(new.node, 'node')
+ self.assertEqual(new.release, 'release')
+ self.assertEqual(new.version, 'version')
+ self.assertEqual(new.machine, 'machine')
+ # processor cannot be replaced
+ self.assertEqual(new.processor, res.processor)
+
+ def test_uname_copy(self):
+ uname = platform.uname()
+ self.assertEqual(copy.copy(uname), uname)
+ self.assertEqual(copy.deepcopy(uname), uname)
+
+ def test_uname_pickle(self):
+ orig = platform.uname()
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+ with self.subTest(protocol=proto):
+ pickled = pickle.dumps(orig, proto)
+ restored = pickle.loads(pickled)
+ self.assertEqual(restored, orig)
+
+ def test_uname_slices(self):
+ res = platform.uname()
+ expected = tuple(res)
+ self.assertEqual(res[:], expected)
+ self.assertEqual(res[:5], expected[:5])
+
@unittest.skipIf(sys.platform in ['win32', 'OpenVMS'], "uname -p not used")
def test_uname_processor(self):
"""
if sys.platform == 'darwin':
import sysconfig
dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
- if tuple(int(n) for n in str(dt).split('.')[0:2]) < (10, 6):
+ if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
# 'id -G' and 'os.getgroups()' should return the same
with self.assertRaises(ValueError):
sample(['red', 'green', 'blue'], counts=[1, 2, 3, 4], k=2) # too many counts
- def test_sample_counts_equivalence(self):
- # Test the documented strong equivalence to a sample with repeated elements.
- # We run this test on random.Random() which makes deterministic selections
- # for a given seed value.
- sample = random.sample
- seed = random.seed
-
- colors = ['red', 'green', 'blue', 'orange', 'black', 'amber']
- counts = [500, 200, 20, 10, 5, 1 ]
- k = 700
- seed(8675309)
- s1 = sample(colors, counts=counts, k=k)
- seed(8675309)
- expanded = [color for (color, count) in zip(colors, counts) for i in range(count)]
- self.assertEqual(len(expanded), sum(counts))
- s2 = sample(expanded, k=k)
- self.assertEqual(s1, s2)
-
- pop = 'abcdefghi'
- counts = [10, 9, 8, 7, 6, 5, 4, 3, 2]
- seed(8675309)
- s1 = ''.join(sample(pop, counts=counts, k=30))
- expanded = ''.join([letter for (letter, count) in zip(pop, counts) for i in range(count)])
- seed(8675309)
- s2 = ''.join(sample(expanded, k=30))
- self.assertEqual(s1, s2)
-
def test_choices(self):
choices = self.gen.choices
data = ['red', 'green', 'blue', 'yellow']
self.assertEqual(self.gen.randbytes(n),
gen2.getrandbits(n * 8).to_bytes(n, 'little'))
+ def test_sample_counts_equivalence(self):
+ # Test the documented strong equivalence to a sample with repeated elements.
+ # We run this test on random.Random() which makes deterministic selections
+ # for a given seed value.
+ sample = self.gen.sample
+ seed = self.gen.seed
+
+ colors = ['red', 'green', 'blue', 'orange', 'black', 'amber']
+ counts = [500, 200, 20, 10, 5, 1 ]
+ k = 700
+ seed(8675309)
+ s1 = sample(colors, counts=counts, k=k)
+ seed(8675309)
+ expanded = [color for (color, count) in zip(colors, counts) for i in range(count)]
+ self.assertEqual(len(expanded), sum(counts))
+ s2 = sample(expanded, k=k)
+ self.assertEqual(s1, s2)
+
+ pop = 'abcdefghi'
+ counts = [10, 9, 8, 7, 6, 5, 4, 3, 2]
+ seed(8675309)
+ s1 = ''.join(sample(pop, counts=counts, k=30))
+ expanded = ''.join([letter for (letter, count) in zip(pop, counts) for i in range(count)])
+ seed(8675309)
+ s2 = ''.join(sample(expanded, k=30))
+ self.assertEqual(s1, s2)
+
def gamma(z, sqrt2pi=(2.0*pi)**0.5):
# Reflection to right half of complex plane
client = smtplib.LMTP
+ @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), "test requires Unix domain socket")
+ def testUnixDomainSocketTimeoutDefault(self):
+ local_host = '/some/local/lmtp/delivery/program'
+ mock_socket.reply_with(b"220 Hello world")
+ try:
+ client = self.client(local_host, self.port)
+ finally:
+ mock_socket.setdefaulttimeout(None)
+ self.assertIsNone(client.sock.gettimeout())
+ client.close()
+
def testTimeoutZero(self):
super().testTimeoutZero()
local_host = '/some/local/lmtp/delivery/program'
input=b'pear')
self.assertIn(b'PEAR', output)
+ def test_check_output_input_none(self):
+ """input=None has a legacy meaning of input='' on check_output."""
+ output = subprocess.check_output(
+ [sys.executable, "-c",
+ "import sys; print('XX' if sys.stdin.read() else '')"],
+ input=None)
+ self.assertNotIn(b'XX', output)
+
+ def test_check_output_input_none_text(self):
+ output = subprocess.check_output(
+ [sys.executable, "-c",
+ "import sys; print('XX' if sys.stdin.read() else '')"],
+ input=None, text=True)
+ self.assertNotIn('XX', output)
+
+ def test_check_output_input_none_universal_newlines(self):
+ output = subprocess.check_output(
+ [sys.executable, "-c",
+ "import sys; print('XX' if sys.stdin.read() else '')"],
+ input=None, universal_newlines=True)
+ self.assertNotIn('XX', output)
+
def test_check_output_stdout_arg(self):
# check_output() refuses to accept 'stdout' argument
with self.assertRaises(ValueError) as c:
@unittest.skipIf(sysconfig.get_config_var('EXT_SUFFIX') is None,
'EXT_SUFFIX required for this test')
- def test_SO_in_vars(self):
+ def test_EXT_SUFFIX_in_vars(self):
+ import _imp
vars = sysconfig.get_config_vars()
self.assertIsNotNone(vars['SO'])
self.assertEqual(vars['SO'], vars['EXT_SUFFIX'])
+ self.assertEqual(vars['EXT_SUFFIX'], _imp.extension_suffixes()[0])
@unittest.skipUnless(sys.platform == 'linux' and
hasattr(sys.implementation, '_multiarch'),
import unittest
+import locale
import re
import subprocess
import sys
tcl = self.interp
self.assertEqual(tcl.eval('set a "a\\0b"'), 'a\x00b')
+ def test_eval_surrogates_in_result(self):
+ tcl = self.interp
+ self.assertIn(tcl.eval(r'set a "<\ud83d\udcbb>"'), '<\U0001f4bb>')
+
def testEvalException(self):
tcl = self.interp
self.assertRaises(TclError,tcl.eval,'set a')
def get_integers(self):
integers = (0, 1, -1, 2**31-1, -2**31, 2**31, -2**31-1, 2**63-1, -2**63)
- # bignum was added in Tcl 8.5, but its support is able only since 8.5.8
- if (get_tk_patchlevel() >= (8, 6, 0, 'final') or
- (8, 5, 8) <= get_tk_patchlevel() < (8, 6)):
- integers += (2**63, -2**63-1, 2**1000, -2**1000)
+ # bignum was added in Tcl 8.5, but its support is able only since 8.5.8.
+ # Actually it is determined at compile time, so using get_tk_patchlevel()
+ # is not reliable.
+ # TODO: expose full static version.
+ if tcl_version >= (8, 5):
+ v = get_tk_patchlevel()
+ if v >= (8, 6, 0, 'final') or (8, 5, 8) <= v < (8, 6):
+ integers += (2**63, -2**63-1, 2**1000, -2**1000)
return integers
def test_getint(self):
def testEvalFile(self):
tcl = self.interp
- with open(support.TESTFN, 'w') as f:
- self.addCleanup(support.unlink, support.TESTFN)
+ filename = support.TESTFN_ASCII
+ self.addCleanup(support.unlink, filename)
+ with open(filename, 'w') as f:
f.write("""set a 1
set b 2
set c [ expr $a + $b ]
""")
- tcl.evalfile(support.TESTFN)
+ tcl.evalfile(filename)
self.assertEqual(tcl.eval('set a'),'1')
self.assertEqual(tcl.eval('set b'),'2')
self.assertEqual(tcl.eval('set c'),'3')
def test_evalfile_null_in_result(self):
tcl = self.interp
- with open(support.TESTFN, 'w') as f:
- self.addCleanup(support.unlink, support.TESTFN)
+ filename = support.TESTFN_ASCII
+ self.addCleanup(support.unlink, filename)
+ with open(filename, 'w') as f:
f.write("""
set a "a\0b"
set b "a\\0b"
""")
- tcl.evalfile(support.TESTFN)
+ tcl.evalfile(filename)
self.assertEqual(tcl.eval('set a'), 'a\x00b')
self.assertEqual(tcl.eval('set b'), 'a\x00b')
+ def test_evalfile_surrogates_in_result(self):
+ tcl = self.interp
+ encoding = tcl.call('encoding', 'system')
+ self.addCleanup(tcl.call, 'encoding', 'system', encoding)
+ tcl.call('encoding', 'system', 'utf-8')
+
+ filename = support.TESTFN_ASCII
+ self.addCleanup(support.unlink, filename)
+ with open(filename, 'wb') as f:
+ f.write(b"""
+ set a "<\xed\xa0\xbd\xed\xb2\xbb>"
+ set b "<\\ud83d\\udcbb>"
+ """)
+ tcl.evalfile(filename)
+ self.assertEqual(tcl.eval('set a'), '<\U0001f4bb>')
+ self.assertEqual(tcl.eval('set b'), '<\U0001f4bb>')
+
def testEvalFileException(self):
tcl = self.interp
filename = "doesnotexists"
else:
self.assertEqual(result, str(i))
self.assertIsInstance(result, str)
- if tcl_version < (8, 5): # bignum was added in Tcl 8.5
+ if get_tk_patchlevel() < (8, 5): # bignum was added in Tcl 8.5
self.assertRaises(TclError, tcl.call, 'expr', str(2**1000))
def test_passing_values(self):
self.assertEqual(passValue('str\x00ing\u20ac'), 'str\x00ing\u20ac')
self.assertEqual(passValue('str\x00ing\U0001f4bb'),
'str\x00ing\U0001f4bb')
+ if sys.platform != 'win32':
+ self.assertEqual(passValue('<\udce2\udc82\udcac>'),
+ '<\u20ac>')
+ self.assertEqual(passValue('<\udced\udca0\udcbd\udced\udcb2\udcbb>'),
+ '<\U0001f4bb>')
self.assertEqual(passValue(b'str\x00ing'),
b'str\x00ing' if self.wantobjects else 'str\x00ing')
self.assertEqual(passValue(b'str\xc0\x80ing'),
check('string\xbd')
check('string\u20ac')
check('string\U0001f4bb')
+ if sys.platform != 'win32':
+ check('<\udce2\udc82\udcac>', '<\u20ac>')
+ check('<\udced\udca0\udcbd\udced\udcb2\udcbb>', '<\U0001f4bb>')
check('')
check(b'string', 'string')
check(b'string\xe2\x82\xac', 'string\xe2\x82\xac')
('a \u20ac', ('a', '\u20ac')),
('a \U0001f4bb', ('a', '\U0001f4bb')),
(b'a \xe2\x82\xac', ('a', '\u20ac')),
+ (b'a \xf0\x9f\x92\xbb', ('a', '\U0001f4bb')),
+ (b'a \xed\xa0\xbd\xed\xb2\xbb', ('a', '\U0001f4bb')),
(b'a\xc0\x80b c\xc0\x80d', ('a\x00b', 'c\x00d')),
('a {b c}', ('a', 'b c')),
(r'a b\ c', ('a', 'b c')),
msg = self.get_report(e).splitlines()
self.assertEqual(msg[-2], ' ^')
+ def test_syntax_error_no_lineno(self):
+ # See #34463.
+
+ # Without filename
+ e = SyntaxError('bad syntax')
+ msg = self.get_report(e).splitlines()
+ self.assertEqual(msg,
+ ['SyntaxError: bad syntax'])
+ e.lineno = 100
+ msg = self.get_report(e).splitlines()
+ self.assertEqual(msg,
+ [' File "<string>", line 100', 'SyntaxError: bad syntax'])
+
+ # With filename
+ e = SyntaxError('bad syntax')
+ e.filename = 'myfile.py'
+
+ msg = self.get_report(e).splitlines()
+ self.assertEqual(msg,
+ ['SyntaxError: bad syntax (myfile.py)'])
+ e.lineno = 100
+ msg = self.get_report(e).splitlines()
+ self.assertEqual(msg,
+ [' File "myfile.py", line 100', 'SyntaxError: bad syntax'])
+
def test_message_none(self):
# A message that looks like "None" should not be treated specially
err = self.get_report(Exception(None))
return traceback_lineno(filename, 0)
+class TestTraceback(unittest.TestCase):
+ def test_repr(self):
+ def get_repr(*args) -> str:
+ return repr(tracemalloc.Traceback(*args))
+
+ self.assertEqual(get_repr(()), "<Traceback ()>")
+ self.assertEqual(get_repr((), 0), "<Traceback () total_nframe=0>")
+
+ frames = (("f1", 1), ("f2", 2))
+ exp_repr_frames = (
+ "(<Frame filename='f2' lineno=2>,"
+ " <Frame filename='f1' lineno=1>)"
+ )
+ self.assertEqual(get_repr(frames),
+ f"<Traceback {exp_repr_frames}>")
+ self.assertEqual(get_repr(frames, 2),
+ f"<Traceback {exp_repr_frames} total_nframe=2>")
+
+
class TestTracemallocEnabled(unittest.TestCase):
def setUp(self):
if tracemalloc.is_tracing():
def test_main():
support.run_unittest(
+ TestTraceback,
TestTracemallocEnabled,
TestSnapshot,
TestFilters,
type(c)()
def test_callable_wrong_forms(self):
- with self.assertRaises(TypeError):
- Callable[[...], int]
- with self.assertRaises(TypeError):
- Callable[(), int]
- with self.assertRaises(TypeError):
- Callable[[()], int]
- with self.assertRaises(TypeError):
- Callable[[int, 1], 2]
with self.assertRaises(TypeError):
Callable[int]
self.assertEqual(get_args(Callable), ())
self.assertEqual(get_args(list[int]), (int,))
self.assertEqual(get_args(list), ())
+ self.assertEqual(get_args(collections.abc.Callable[[int], str]), ([int], str))
+ self.assertEqual(get_args(collections.abc.Callable[..., str]), (..., str))
+ self.assertEqual(get_args(collections.abc.Callable[[], str]), ([], str))
+ self.assertEqual(get_args(collections.abc.Callable[[int], str]),
+ get_args(Callable[[int], str]))
class CollectionsAbcTests(BaseTestCase):
self.assertEqual(D(), {})
self.assertEqual(D(x=1), {'x': 1})
self.assertEqual(D.__total__, False)
+ self.assertEqual(D.__required_keys__, frozenset())
+ self.assertEqual(D.__optional_keys__, {'x'})
self.assertEqual(Options(), {})
self.assertEqual(Options(log_level=2), {'log_level': 2})
self.assertEqual(Options.__total__, False)
+ self.assertEqual(Options.__required_keys__, frozenset())
+ self.assertEqual(Options.__optional_keys__, {'log_level', 'log_path'})
def test_optional_keys(self):
class Point2Dor3D(Point2D, total=False):
...
SyntaxError: can't use starred expression here
+ >>> (*x),y = 1, 2 # doctest:+ELLIPSIS
+ Traceback (most recent call last):
+ ...
+ SyntaxError: can't use starred expression here
+
+ >>> (((*x))),y = 1, 2 # doctest:+ELLIPSIS
+ Traceback (most recent call last):
+ ...
+ SyntaxError: can't use starred expression here
+
+ >>> z,(*x),y = 1, 2, 4 # doctest:+ELLIPSIS
+ Traceback (most recent call last):
+ ...
+ SyntaxError: can't use starred expression here
+
+ >>> z,(*x) = 1, 2 # doctest:+ELLIPSIS
+ Traceback (most recent call last):
+ ...
+ SyntaxError: can't use starred expression here
+
+ >>> ((*x),y) = 1, 2 # doctest:+ELLIPSIS
+ Traceback (most recent call last):
+ ...
+ SyntaxError: can't use starred expression here
+
Some size constraints (all fail.)
>>> s = ", ".join("a%d" % i for i in range(1<<8)) + ", *rest = range(1<<8 + 1)"
('ftp', 'joe', 'password', 'proxy.example.com')),
# Test for no trailing '/' case
('http://joe:password@proxy.example.com',
- ('http', 'joe', 'password', 'proxy.example.com'))
+ ('http', 'joe', 'password', 'proxy.example.com')),
+ # Testcases with '/' character in username, password
+ ('http://user/name:password@localhost:22',
+ ('http', 'user/name', 'password', 'localhost:22')),
+ ('http://username:pass/word@localhost:22',
+ ('http', 'username', 'pass/word', 'localhost:22')),
+ ('http://user/name:pass/word@localhost:22',
+ ('http', 'user/name', 'pass/word', 'localhost:22')),
]
+
for tc, expected in parse_proxy_test_cases:
self.assertEqual(_parse_proxy(tc), expected)
(b"&a=b", [(b'a', b'b')]),
(b"a=a+b&b=b+c", [(b'a', b'a b'), (b'b', b'b c')]),
(b"a=1&a=2", [(b'a', b'1'), (b'a', b'2')]),
- (";", []),
- (";;", []),
- (";a=b", [('a', 'b')]),
- ("a=a+b;b=b+c", [('a', 'a b'), ('b', 'b c')]),
- ("a=1;a=2", [('a', '1'), ('a', '2')]),
- (b";", []),
- (b";;", []),
- (b";a=b", [(b'a', b'b')]),
- (b"a=a+b;b=b+c", [(b'a', b'a b'), (b'b', b'b c')]),
- (b"a=1;a=2", [(b'a', b'1'), (b'a', b'2')]),
+ (";a=b", [(';a', 'b')]),
+ ("a=a+b;b=b+c", [('a', 'a b;b=b c')]),
+ (b";a=b", [(b';a', b'b')]),
+ (b"a=a+b;b=b+c", [(b'a', b'a b;b=b c')]),
]
# Each parse_qs testcase is a two-tuple that contains
(b"&a=b", {b'a': [b'b']}),
(b"a=a+b&b=b+c", {b'a': [b'a b'], b'b': [b'b c']}),
(b"a=1&a=2", {b'a': [b'1', b'2']}),
- (";", {}),
- (";;", {}),
- (";a=b", {'a': ['b']}),
- ("a=a+b;b=b+c", {'a': ['a b'], 'b': ['b c']}),
- ("a=1;a=2", {'a': ['1', '2']}),
- (b";", {}),
- (b";;", {}),
- (b";a=b", {b'a': [b'b']}),
- (b"a=a+b;b=b+c", {b'a': [b'a b'], b'b': [b'b c']}),
- (b"a=1;a=2", {b'a': [b'1', b'2']}),
+ (";a=b", {';a': ['b']}),
+ ("a=a+b;b=b+c", {'a': ['a b;b=b c']}),
+ (b";a=b", {b';a': [b'b']}),
+ (b"a=a+b;b=b+c", {b'a':[ b'a b;b=b c']}),
]
class UrlParseTestCase(unittest.TestCase):
def test_parse_qsl_max_num_fields(self):
with self.assertRaises(ValueError):
urllib.parse.parse_qs('&'.join(['a=a']*11), max_num_fields=10)
- with self.assertRaises(ValueError):
- urllib.parse.parse_qs(';'.join(['a=a']*11), max_num_fields=10)
urllib.parse.parse_qs('&'.join(['a=a']*10), max_num_fields=10)
+ def test_parse_qs_separator(self):
+ parse_qs_semicolon_cases = [
+ (";", {}),
+ (";;", {}),
+ (";a=b", {'a': ['b']}),
+ ("a=a+b;b=b+c", {'a': ['a b'], 'b': ['b c']}),
+ ("a=1;a=2", {'a': ['1', '2']}),
+ (b";", {}),
+ (b";;", {}),
+ (b";a=b", {b'a': [b'b']}),
+ (b"a=a+b;b=b+c", {b'a': [b'a b'], b'b': [b'b c']}),
+ (b"a=1;a=2", {b'a': [b'1', b'2']}),
+ ]
+ for orig, expect in parse_qs_semicolon_cases:
+ with self.subTest(f"Original: {orig!r}, Expected: {expect!r}"):
+ result = urllib.parse.parse_qs(orig, separator=';')
+ self.assertEqual(result, expect, "Error parsing %r" % orig)
+
+
+ def test_parse_qsl_separator(self):
+ parse_qsl_semicolon_cases = [
+ (";", []),
+ (";;", []),
+ (";a=b", [('a', 'b')]),
+ ("a=a+b;b=b+c", [('a', 'a b'), ('b', 'b c')]),
+ ("a=1;a=2", [('a', '1'), ('a', '2')]),
+ (b";", []),
+ (b";;", []),
+ (b";a=b", [(b'a', b'b')]),
+ (b"a=a+b;b=b+c", [(b'a', b'a b'), (b'b', b'b c')]),
+ (b"a=1;a=2", [(b'a', b'1'), (b'a', b'2')]),
+ ]
+ for orig, expect in parse_qsl_semicolon_cases:
+ with self.subTest(f"Original: {orig!r}, Expected: {expect!r}"):
+ result = urllib.parse.parse_qsl(orig, separator=';')
+ self.assertEqual(result, expect, "Error parsing %r" % orig)
+
+
def test_urlencode_sequences(self):
# Other tests incidentally urlencode things; test non-covered cases:
# Sequence and object values.
)
-_support_default_root = 1
+_support_default_root = True
_default_root = None
Call this function to inhibit that the first instance of
Tk is used for windows without an explicit parent window.
"""
- global _support_default_root
- _support_default_root = 0
- global _default_root
+ global _support_default_root, _default_root
+ _support_default_root = False
+ # Delete, so any use of _default_root will immediately raise an exception.
+ # Rebind before deletion, so repeated calls will not fail.
_default_root = None
del _default_root
+def _get_default_root(what=None):
+ if not _support_default_root:
+ raise RuntimeError("No master specified and tkinter is "
+ "configured to not support default root")
+ if not _default_root:
+ if what:
+ raise RuntimeError(f"Too early to {what}: no default root window")
+ root = Tk()
+ assert _default_root is root
+ return _default_root
+
+
def _tkerror(err):
"""Internal function."""
pass
raise TypeError("name must be a string")
global _varnum
if not master:
- master = _default_root
+ master = _get_default_root('create variable')
self._root = master._root()
self._tk = master.tk
if name:
self._tk.call("trace", "vinfo", self._name))]
def __eq__(self, other):
- """Comparison for equality (==).
-
- Note: if the Variable's master matters to behavior
- also compare self._master == other._master
- """
if not isinstance(other, Variable):
return NotImplemented
- return self.__class__.__name__ == other.__class__.__name__ \
- and self._name == other._name
+ return (self._name == other._name
+ and self.__class__.__name__ == other.__class__.__name__
+ and self._tk == other._tk)
class StringVar(Variable):
def mainloop(n=0):
"""Run the main loop of Tcl."""
- _default_root.tk.mainloop(n)
+ _get_default_root('run the main loop').tk.mainloop(n)
getint = int
def getboolean(s):
- """Convert true and false to integer values 1 and 0."""
+ """Convert Tcl object to True or False."""
try:
- return _default_root.tk.getboolean(s)
+ return _get_default_root('use getboolean()').tk.getboolean(s)
except TclError:
raise ValueError("invalid literal for getboolean()")
self.tk.call('winfo', 'reqwidth', self._w))
def winfo_rgb(self, color):
- """Return tuple of decimal values for red, green, blue for
- COLOR in this widget."""
+ """Return a tuple of integer RGB values in range(65536) for color in this widget."""
return self._getints(
self.tk.call('winfo', 'rgb', self._w, color))
is the name of the widget class."""
self.master = None
self.children = {}
- self._tkloaded = 0
+ self._tkloaded = False
# to avoid recursions in the getattr code in case of failure, we
# ensure that self.tk is always _something_.
self.tk = None
self._loadtk()
def _loadtk(self):
- self._tkloaded = 1
+ self._tkloaded = True
global _default_root
# Version sanity checks
tk_version = self.tk.getvar('tk_version')
def _setup(self, master, cnf):
"""Internal function. Sets up information about children."""
- if _support_default_root:
- global _default_root
- if not master:
- if not _default_root:
- _default_root = Tk()
- master = _default_root
+ if not master:
+ master = _get_default_root()
self.master = master
self.tk = master.tk
name = None
def __init__(self, imgtype, name=None, cnf={}, master=None, **kw):
self.name = None
if not master:
- master = _default_root
- if not master:
- raise RuntimeError('Too early to create image')
+ master = _get_default_root('create image')
self.tk = getattr(master, 'tk', master)
if not name:
Image._last_id += 1
def image_names():
- return _default_root.tk.splitlist(_default_root.tk.call('image', 'names'))
+ tk = _get_default_root('use image_names()').tk
+ return tk.splitlist(tk.call('image', 'names'))
def image_types():
- return _default_root.tk.splitlist(_default_root.tk.call('image', 'types'))
+ tk = _get_default_root('use image_types()').tk
+ return tk.splitlist(tk.call('image', 'types'))
class Spinbox(Widget, XView):
# fixed initialcolor handling in August 1998
#
-#
-# options (all have default values):
-#
-# - initialcolor: color to mark as selected when dialog is displayed
-# (given as an RGB triplet or a Tk color string)
-#
-# - parent: which window to place the dialog on top of
-#
-# - title: dialog title
-#
from tkinter.commondialog import Dialog
__all__ = ["Chooser", "askcolor"]
-#
-# color chooser class
-
class Chooser(Dialog):
- "Ask for a color"
+ """Create a dialog for the tk_chooseColor command.
+
+ Args:
+ master: The master widget for this dialog. If not provided,
+ defaults to options['parent'] (if defined).
+ options: Dictionary of options for the tk_chooseColor call.
+ initialcolor: Specifies the selected color when the
+ dialog is first displayed. This can be a tk color
+ string or a 3-tuple of ints in the range (0, 255)
+ for an RGB triplet.
+ parent: The parent window of the color dialog. The
+ color dialog is displayed on top of this.
+ title: A string for the title of the dialog box.
+ """
command = "tk_chooseColor"
def _fixoptions(self):
+ """Ensure initialcolor is a tk color string.
+
+ Convert initialcolor from a RGB triplet to a color string.
+ """
try:
- # make sure initialcolor is a tk color string
color = self.options["initialcolor"]
if isinstance(color, tuple):
- # assume an RGB triplet
+ # Assume an RGB triplet.
self.options["initialcolor"] = "#%02x%02x%02x" % color
except KeyError:
pass
def _fixresult(self, widget, result):
- # result can be somethings: an empty tuple, an empty string or
- # a Tcl_Obj, so this somewhat weird check handles that
+ """Adjust result returned from call to tk_chooseColor.
+
+ Return both an RGB tuple of ints in the range (0, 255) and the
+ tk color string in the form #rrggbb.
+ """
+ # Result can be many things: an empty tuple, an empty string, or
+ # a _tkinter.Tcl_Obj, so this somewhat weird check handles that.
if not result or not str(result):
- return None, None # canceled
+ return None, None # canceled
- # to simplify application code, the color chooser returns
- # an RGB tuple together with the Tk color string
+ # To simplify application code, the color chooser returns
+ # an RGB tuple together with the Tk color string.
r, g, b = widget.winfo_rgb(result)
- return (r/256, g/256, b/256), str(result)
+ return (r//256, g//256, b//256), str(result)
#
# convenience stuff
-def askcolor(color = None, **options):
- "Ask for a color"
+def askcolor(color=None, **options):
+ """Display dialog window for selection of a color.
+
+ Convenience wrapper for the Chooser class. Displays the color
+ chooser dialog with color as the initial value.
+ """
if color:
options = options.copy()
command = None
def __init__(self, master=None, **options):
+ if not master:
+ master = options.get('parent')
self.master = master
self.options = options
- if not master and options.get('parent'):
- self.master = options['parent']
def _fixoptions(self):
pass # hook
def __init__(self, root=None, font=None, name=None, exists=False,
**options):
if not root:
- root = tkinter._default_root
+ root = tkinter._get_default_root('use font')
tk = getattr(root, 'tk', root)
if font:
# get actual settings corresponding to the given font
def __eq__(self, other):
if not isinstance(other, Font):
return NotImplemented
- return self.name == other.name
+ return self.name == other.name and self._tk == other._tk
def __getitem__(self, key):
return self.cget(key)
def families(root=None, displayof=None):
"Get font families (as a tuple)"
if not root:
- root = tkinter._default_root
+ root = tkinter._get_default_root('use font.families()')
args = ()
if displayof:
args = ('-displayof', displayof)
def names(root=None):
"Get names of defined fonts (as a tuple)"
if not root:
- root = tkinter._default_root
+ root = tkinter._get_default_root('use font.names()')
return root.tk.splitlist(root.tk.call("font", "names"))
"""
from tkinter import *
-from tkinter import messagebox
-
-import tkinter # used at _QueryDialog for tkinter._default_root
+from tkinter import messagebox, _get_default_root
class SimpleDialog:
title -- the dialog title
'''
- Toplevel.__init__(self, parent)
+ master = parent
+ if not master:
+ master = _get_default_root('create dialog window')
+
+ Toplevel.__init__(self, master)
self.withdraw() # remain invisible for now
- # If the master is not viewable, don't
+ # If the parent is not viewable, don't
# make the child transient, or else it
# would be opened withdrawn
- if parent.winfo_viewable():
+ if parent is not None and parent.winfo_viewable():
self.transient(parent)
if title:
self.protocol("WM_DELETE_WINDOW", self.cancel)
- if self.parent is not None:
+ if parent is not None:
self.geometry("+%d+%d" % (parent.winfo_rootx()+50,
parent.winfo_rooty()+50))
minvalue = None, maxvalue = None,
parent = None):
- if not parent:
- parent = tkinter._default_root
-
self.prompt = prompt
self.minvalue = minvalue
self.maxvalue = maxvalue
w.destroy()
self.root.withdraw()
+
+class AbstractDefaultRootTest:
+
+ def setUp(self):
+ self._old_support_default_root = tkinter._support_default_root
+ destroy_default_root()
+ tkinter._support_default_root = True
+ self.wantobjects = tkinter.wantobjects
+
+ def tearDown(self):
+ destroy_default_root()
+ tkinter._default_root = None
+ tkinter._support_default_root = self._old_support_default_root
+
+ def _test_widget(self, constructor):
+ # no master passing
+ x = constructor()
+ self.assertIsNotNone(tkinter._default_root)
+ self.assertIs(x.master, tkinter._default_root)
+ self.assertIs(x.tk, tkinter._default_root.tk)
+ x.destroy()
+ destroy_default_root()
+ tkinter.NoDefaultRoot()
+ self.assertRaises(RuntimeError, constructor)
+ self.assertFalse(hasattr(tkinter, '_default_root'))
+
+
def destroy_default_root():
if getattr(tkinter, '_default_root', None):
tkinter._default_root.update_idletasks()
--- /dev/null
+import unittest
+import tkinter
+from test.support import requires, run_unittest, swap_attr
+from tkinter.test.support import AbstractTkTest
+from tkinter import colorchooser
+
+requires('gui')
+
+
+class ChooserTest(AbstractTkTest, unittest.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ AbstractTkTest.setUpClass.__func__(cls)
+ cls.cc = colorchooser.Chooser(initialcolor='dark blue slate')
+
+ def test_fixoptions(self):
+ cc = self.cc
+ cc._fixoptions()
+ self.assertEqual(cc.options['initialcolor'], 'dark blue slate')
+
+ cc.options['initialcolor'] = '#D2D269691E1E'
+ cc._fixoptions()
+ self.assertEqual(cc.options['initialcolor'], '#D2D269691E1E')
+
+ cc.options['initialcolor'] = (210, 105, 30)
+ cc._fixoptions()
+ self.assertEqual(cc.options['initialcolor'], '#d2691e')
+
+ def test_fixresult(self):
+ cc = self.cc
+ self.assertEqual(cc._fixresult(self.root, ()), (None, None))
+ self.assertEqual(cc._fixresult(self.root, ''), (None, None))
+ self.assertEqual(cc._fixresult(self.root, 'chocolate'),
+ ((210, 105, 30), 'chocolate'))
+ self.assertEqual(cc._fixresult(self.root, '#4a3c8c'),
+ ((74, 60, 140), '#4a3c8c'))
+
+
+tests_gui = (ChooserTest,)
+
+if __name__ == "__main__":
+ run_unittest(*tests_gui)
import tkinter
from tkinter import font
from test.support import requires, run_unittest, gc_collect, ALWAYS_EQ
-from tkinter.test.support import AbstractTkTest
+from tkinter.test.support import AbstractTkTest, AbstractDefaultRootTest
requires('gui')
self.assertEqual(self.font.name, fontname)
self.assertEqual(str(self.font), fontname)
- def test_eq(self):
+ def test_equality(self):
font1 = font.Font(root=self.root, name=fontname, exists=True)
font2 = font.Font(root=self.root, name=fontname, exists=True)
self.assertIsNot(font1, font2)
self.assertEqual(font1, font2)
self.assertNotEqual(font1, font1.copy())
+
self.assertNotEqual(font1, 0)
self.assertEqual(font1, ALWAYS_EQ)
+ root2 = tkinter.Tk()
+ self.addCleanup(root2.destroy)
+ font3 = font.Font(root=root2, name=fontname, exists=True)
+ self.assertEqual(str(font1), str(font3))
+ self.assertNotEqual(font1, font3)
+
def test_measure(self):
self.assertIsInstance(self.font.measure('abc'), int)
self.assertTrue(name)
self.assertIn(fontname, names)
-tests_gui = (FontTest, )
+
+class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
+
+ def test_families(self):
+ self.assertRaises(RuntimeError, font.families)
+ root = tkinter.Tk()
+ families = font.families()
+ self.assertIsInstance(families, tuple)
+ self.assertTrue(families)
+ for family in families:
+ self.assertIsInstance(family, str)
+ self.assertTrue(family)
+ root.destroy()
+ tkinter.NoDefaultRoot()
+ self.assertRaises(RuntimeError, font.families)
+
+ def test_names(self):
+ self.assertRaises(RuntimeError, font.names)
+ root = tkinter.Tk()
+ names = font.names()
+ self.assertIsInstance(names, tuple)
+ self.assertTrue(names)
+ for name in names:
+ self.assertIsInstance(name, str)
+ self.assertTrue(name)
+ self.assertIn(fontname, names)
+ root.destroy()
+ tkinter.NoDefaultRoot()
+ self.assertRaises(RuntimeError, font.names)
+
+
+tests_gui = (FontTest, DefaultRootTest)
if __name__ == "__main__":
run_unittest(*tests_gui)
import unittest
import tkinter
from test import support
-from tkinter.test.support import AbstractTkTest, requires_tcl
+from tkinter.test.support import AbstractTkTest, AbstractDefaultRootTest, requires_tcl
support.requires('gui')
self.assertIsInstance(image_names, tuple)
+class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
+
+ def test_image_types(self):
+ self.assertRaises(RuntimeError, tkinter.image_types)
+ root = tkinter.Tk()
+ image_types = tkinter.image_types()
+ self.assertIsInstance(image_types, tuple)
+ self.assertIn('photo', image_types)
+ self.assertIn('bitmap', image_types)
+ root.destroy()
+ tkinter.NoDefaultRoot()
+ self.assertRaises(RuntimeError, tkinter.image_types)
+
+ def test_image_names(self):
+ self.assertRaises(RuntimeError, tkinter.image_names)
+ root = tkinter.Tk()
+ image_names = tkinter.image_names()
+ self.assertIsInstance(image_names, tuple)
+ root.destroy()
+ tkinter.NoDefaultRoot()
+ self.assertRaises(RuntimeError, tkinter.image_names)
+
+ def test_image_create_bitmap(self):
+ self.assertRaises(RuntimeError, tkinter.BitmapImage)
+ root = tkinter.Tk()
+ image = tkinter.BitmapImage()
+ self.assertIn(image.name, tkinter.image_names())
+ root.destroy()
+ tkinter.NoDefaultRoot()
+ self.assertRaises(RuntimeError, tkinter.BitmapImage)
+
+ def test_image_create_photo(self):
+ self.assertRaises(RuntimeError, tkinter.PhotoImage)
+ root = tkinter.Tk()
+ image = tkinter.PhotoImage()
+ self.assertIn(image.name, tkinter.image_names())
+ root.destroy()
+ tkinter.NoDefaultRoot()
+ self.assertRaises(RuntimeError, tkinter.PhotoImage)
+
+
class BitmapImageTest(AbstractTkTest, unittest.TestCase):
@classmethod
self.assertEqual(image.transparency_get(4, 6), False)
-tests_gui = (MiscTest, BitmapImageTest, PhotoImageTest,)
+tests_gui = (MiscTest, DefaultRootTest, BitmapImageTest, PhotoImageTest,)
if __name__ == "__main__":
support.run_unittest(*tests_gui)
import unittest
import tkinter
from test import support
-from tkinter.test.support import AbstractTkTest
+from tkinter.test.support import AbstractTkTest, AbstractDefaultRootTest
support.requires('gui')
with self.assertRaises(tkinter.TclError):
root.clipboard_get()
+ def test_winfo_rgb(self):
+ root = self.root
+ rgb = root.winfo_rgb
+
+ # Color name.
+ self.assertEqual(rgb('red'), (65535, 0, 0))
+ self.assertEqual(rgb('dark slate blue'), (18504, 15677, 35723))
+ # #RGB - extends each 4-bit hex value to be 16-bit.
+ self.assertEqual(rgb('#F0F'), (0xFFFF, 0x0000, 0xFFFF))
+ # #RRGGBB - extends each 8-bit hex value to be 16-bit.
+ self.assertEqual(rgb('#4a3c8c'), (0x4a4a, 0x3c3c, 0x8c8c))
+ # #RRRRGGGGBBBB
+ self.assertEqual(rgb('#dede14143939'), (0xdede, 0x1414, 0x3939))
+ # Invalid string.
+ with self.assertRaises(tkinter.TclError):
+ rgb('#123456789a')
+ # RGB triplet is invalid input.
+ with self.assertRaises(tkinter.TclError):
+ rgb((111, 78, 55))
+
def test_event_repr_defaults(self):
e = tkinter.Event()
e.serial = 12345
" num=3 delta=-1 focus=True"
" x=10 y=20 width=300 height=200>")
-tests_gui = (MiscTest, )
+ def test_getboolean(self):
+ for v in 'true', 'yes', 'on', '1', 't', 'y', 1, True:
+ self.assertIs(self.root.getboolean(v), True)
+ for v in 'false', 'no', 'off', '0', 'f', 'n', 0, False:
+ self.assertIs(self.root.getboolean(v), False)
+ self.assertRaises(ValueError, self.root.getboolean, 'yea')
+ self.assertRaises(ValueError, self.root.getboolean, '')
+ self.assertRaises(TypeError, self.root.getboolean, None)
+ self.assertRaises(TypeError, self.root.getboolean, ())
+
+ def test_mainloop(self):
+ log = []
+ def callback():
+ log.append(1)
+ self.root.after(100, self.root.quit)
+ self.root.after(100, callback)
+ self.root.mainloop(1)
+ self.assertEqual(log, [])
+ self.root.mainloop(0)
+ self.assertEqual(log, [1])
+ self.assertTrue(self.root.winfo_exists())
+
+
+class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
+
+ def test_default_root(self):
+ self.assertIs(tkinter._support_default_root, True)
+ self.assertIsNone(tkinter._default_root)
+ root = tkinter.Tk()
+ root2 = tkinter.Tk()
+ root3 = tkinter.Tk()
+ self.assertIs(tkinter._default_root, root)
+ root2.destroy()
+ self.assertIs(tkinter._default_root, root)
+ root.destroy()
+ self.assertIsNone(tkinter._default_root)
+ root3.destroy()
+ self.assertIsNone(tkinter._default_root)
+
+ def test_no_default_root(self):
+ self.assertIs(tkinter._support_default_root, True)
+ self.assertIsNone(tkinter._default_root)
+ root = tkinter.Tk()
+ self.assertIs(tkinter._default_root, root)
+ tkinter.NoDefaultRoot()
+ self.assertIs(tkinter._support_default_root, False)
+ self.assertFalse(hasattr(tkinter, '_default_root'))
+ # repeated call is no-op
+ tkinter.NoDefaultRoot()
+ self.assertIs(tkinter._support_default_root, False)
+ self.assertFalse(hasattr(tkinter, '_default_root'))
+ root.destroy()
+ self.assertIs(tkinter._support_default_root, False)
+ self.assertFalse(hasattr(tkinter, '_default_root'))
+ root = tkinter.Tk()
+ self.assertIs(tkinter._support_default_root, False)
+ self.assertFalse(hasattr(tkinter, '_default_root'))
+ root.destroy()
+
+ def test_getboolean(self):
+ self.assertRaises(RuntimeError, tkinter.getboolean, '1')
+ root = tkinter.Tk()
+ self.assertIs(tkinter.getboolean('1'), True)
+ self.assertRaises(ValueError, tkinter.getboolean, 'yea')
+ root.destroy()
+ tkinter.NoDefaultRoot()
+ self.assertRaises(RuntimeError, tkinter.getboolean, '1')
+
+ def test_mainloop(self):
+ self.assertRaises(RuntimeError, tkinter.mainloop)
+ root = tkinter.Tk()
+ root.after_idle(root.quit)
+ tkinter.mainloop()
+ root.destroy()
+ tkinter.NoDefaultRoot()
+ self.assertRaises(RuntimeError, tkinter.mainloop)
+
+
+tests_gui = (MiscTest, DefaultRootTest)
if __name__ == "__main__":
support.run_unittest(*tests_gui)
--- /dev/null
+import unittest
+import tkinter
+from test.support import requires, run_unittest, swap_attr
+from tkinter.test.support import AbstractDefaultRootTest
+from tkinter.simpledialog import Dialog, askinteger
+
+requires('gui')
+
+
+class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
+
+ def test_askinteger(self):
+ self.assertRaises(RuntimeError, askinteger, "Go To Line", "Line number")
+ root = tkinter.Tk()
+ with swap_attr(Dialog, 'wait_window', lambda self, w: w.destroy()):
+ askinteger("Go To Line", "Line number")
+ root.destroy()
+ tkinter.NoDefaultRoot()
+ self.assertRaises(RuntimeError, askinteger, "Go To Line", "Line number")
+
+
+tests_gui = (DefaultRootTest,)
+
+if __name__ == "__main__":
+ run_unittest(*tests_gui)
import unittest
import gc
+import tkinter
from tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl,
TclError)
from test.support import ALWAYS_EQ
+from tkinter.test.support import AbstractDefaultRootTest
class Var(Variable):
del v2
self.assertFalse(self.info_exists("name"))
- def test___eq__(self):
+ def test_equality(self):
# values doesn't matter, only class and name are checked
v1 = Variable(self.root, name="abc")
v2 = Variable(self.root, name="abc")
self.assertIsNot(v1, v2)
self.assertEqual(v1, v2)
- v3 = StringVar(self.root, name="abc")
+ v3 = Variable(self.root, name="cba")
self.assertNotEqual(v1, v3)
+ v4 = StringVar(self.root, name="abc")
+ self.assertEqual(str(v1), str(v4))
+ self.assertNotEqual(v1, v4)
+
V = type('Variable', (), {})
self.assertNotEqual(v1, V())
self.assertNotEqual(v1, object())
self.assertEqual(v1, ALWAYS_EQ)
+ root2 = tkinter.Tk()
+ self.addCleanup(root2.destroy)
+ v5 = Variable(root2, name="abc")
+ self.assertEqual(str(v1), str(v5))
+ self.assertNotEqual(v1, v5)
+
def test_invalid_name(self):
with self.assertRaises(TypeError):
Variable(self.root, name=123)
v.get()
+class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
+
+ def test_variable(self):
+ self.assertRaises(RuntimeError, Variable)
+ root = tkinter.Tk()
+ v = Variable()
+ v.set("value")
+ self.assertEqual(v.get(), "value")
+ root.destroy()
+ tkinter.NoDefaultRoot()
+ self.assertRaises(RuntimeError, Variable)
+
+
tests_gui = (TestVariable, TestStringVar, TestIntVar,
- TestDoubleVar, TestBooleanVar)
+ TestDoubleVar, TestBooleanVar, DefaultRootTest)
if __name__ == "__main__":
import tkinter
from tkinter import TclError
import os
-import sys
from test.support import requires
from tkinter.test.support import (tcl_version, requires_tcl,
- get_tk_patchlevel, widget_eq)
+ get_tk_patchlevel, widget_eq,
+ AbstractDefaultRootTest)
from tkinter.test.widget_tests import (
add_standard_options, noconv, pixels_round,
AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests,
class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests):
_conv_pad_pixels = noconv
- def test_class(self):
+ def test_configure_class(self):
widget = self.create()
self.assertEqual(widget['class'],
widget.__class__.__name__.title())
widget2 = self.create(class_='Foo')
self.assertEqual(widget2['class'], 'Foo')
- def test_colormap(self):
+ def test_configure_colormap(self):
widget = self.create()
self.assertEqual(widget['colormap'], '')
self.checkInvalidParam(widget, 'colormap', 'new',
widget2 = self.create(colormap='new')
self.assertEqual(widget2['colormap'], 'new')
- def test_container(self):
+ def test_configure_container(self):
widget = self.create()
self.assertEqual(widget['container'], 0 if self.wantobjects else '0')
self.checkInvalidParam(widget, 'container', 1,
widget2 = self.create(container=True)
self.assertEqual(widget2['container'], 1 if self.wantobjects else '1')
- def test_visual(self):
+ def test_configure_visual(self):
widget = self.create()
self.assertEqual(widget['visual'], '')
self.checkInvalidParam(widget, 'visual', 'default',
def create(self, **kwargs):
return tkinter.Toplevel(self.root, **kwargs)
- def test_menu(self):
+ def test_configure_menu(self):
widget = self.create()
menu = tkinter.Menu(self.root)
self.checkParam(widget, 'menu', menu, eq=widget_eq)
self.checkParam(widget, 'menu', '')
- def test_screen(self):
+ def test_configure_screen(self):
widget = self.create()
self.assertEqual(widget['screen'], '')
try:
widget2 = self.create(screen=display)
self.assertEqual(widget2['screen'], display)
- def test_use(self):
+ def test_configure_use(self):
widget = self.create()
self.assertEqual(widget['use'], '')
parent = self.create(container=True)
def create(self, **kwargs):
return tkinter.LabelFrame(self.root, **kwargs)
- def test_labelanchor(self):
+ def test_configure_labelanchor(self):
widget = self.create()
self.checkEnumParam(widget, 'labelanchor',
'e', 'en', 'es', 'n', 'ne', 'nw',
's', 'se', 'sw', 'w', 'wn', 'ws')
self.checkInvalidParam(widget, 'labelanchor', 'center')
- def test_labelwidget(self):
+ def test_configure_labelwidget(self):
widget = self.create()
label = tkinter.Label(self.root, text='Mupp', name='foo')
self.checkParam(widget, 'labelwidget', label, expected='.foo')
class AbstractLabelTest(AbstractWidgetTest, IntegerSizeTests):
_conv_pixels = noconv
- def test_highlightthickness(self):
+ def test_configure_highlightthickness(self):
widget = self.create()
self.checkPixelsParam(widget, 'highlightthickness',
0, 1.3, 2.6, 6, -2, '10p')
def create(self, **kwargs):
return tkinter.Button(self.root, **kwargs)
- def test_default(self):
+ def test_configure_default(self):
widget = self.create()
self.checkEnumParam(widget, 'default', 'active', 'disabled', 'normal')
return tkinter.Checkbutton(self.root, **kwargs)
- def test_offvalue(self):
+ def test_configure_offvalue(self):
widget = self.create()
self.checkParams(widget, 'offvalue', 1, 2.3, '', 'any string')
- def test_onvalue(self):
+ def test_configure_onvalue(self):
widget = self.create()
self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string')
def create(self, **kwargs):
return tkinter.Radiobutton(self.root, **kwargs)
- def test_value(self):
+ def test_configure_value(self):
widget = self.create()
self.checkParams(widget, 'value', 1, 2.3, '', 'any string')
def create(self, **kwargs):
return tkinter.Menubutton(self.root, **kwargs)
- def test_direction(self):
+ def test_configure_direction(self):
widget = self.create()
self.checkEnumParam(widget, 'direction',
'above', 'below', 'flush', 'left', 'right')
- def test_height(self):
+ def test_configure_height(self):
widget = self.create()
self.checkIntegerParam(widget, 'height', 100, -100, 0, conv=str)
- test_highlightthickness = StandardOptionsTests.test_highlightthickness
+ test_configure_highlightthickness = \
+ StandardOptionsTests.test_configure_highlightthickness
- @unittest.skipIf(sys.platform == 'darwin',
- 'crashes with Cocoa Tk (issue19733)')
- def test_image(self):
+ def test_configure_image(self):
widget = self.create()
image = tkinter.PhotoImage(master=self.root, name='image1')
self.checkParam(widget, 'image', image, conv=str)
if errmsg is not None:
self.assertEqual(str(cm.exception), errmsg)
- def test_menu(self):
+ def test_configure_menu(self):
widget = self.create()
menu = tkinter.Menu(widget, name='menu')
self.checkParam(widget, 'menu', menu, eq=widget_eq)
menu.destroy()
- def test_padx(self):
+ def test_configure_padx(self):
widget = self.create()
self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, '12m')
self.checkParam(widget, 'padx', -2, expected=0)
- def test_pady(self):
+ def test_configure_pady(self):
widget = self.create()
self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, '12m')
self.checkParam(widget, 'pady', -2, expected=0)
- def test_width(self):
+ def test_configure_width(self):
widget = self.create()
self.checkIntegerParam(widget, 'width', 402, -402, 0, conv=str)
def create(self, **kwargs):
return tkinter.Entry(self.root, **kwargs)
- def test_disabledbackground(self):
+ def test_configure_disabledbackground(self):
widget = self.create()
self.checkColorParam(widget, 'disabledbackground')
- def test_insertborderwidth(self):
+ def test_configure_insertborderwidth(self):
widget = self.create(insertwidth=100)
self.checkPixelsParam(widget, 'insertborderwidth',
0, 1.3, 2.6, 6, -2, '10p')
# insertborderwidth is bounded above by a half of insertwidth.
self.checkParam(widget, 'insertborderwidth', 60, expected=100//2)
- def test_insertwidth(self):
+ def test_configure_insertwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'insertwidth', 1.3, 3.6, '10p')
self.checkParam(widget, 'insertwidth', 0.1, expected=2)
else:
self.checkParam(widget, 'insertwidth', 0.9, expected=1)
- def test_invalidcommand(self):
+ def test_configure_invalidcommand(self):
widget = self.create()
self.checkCommandParam(widget, 'invalidcommand')
self.checkCommandParam(widget, 'invcmd')
- def test_readonlybackground(self):
+ def test_configure_readonlybackground(self):
widget = self.create()
self.checkColorParam(widget, 'readonlybackground')
- def test_show(self):
+ def test_configure_show(self):
widget = self.create()
self.checkParam(widget, 'show', '*')
self.checkParam(widget, 'show', '')
self.checkParam(widget, 'show', ' ')
- def test_state(self):
+ def test_configure_state(self):
widget = self.create()
self.checkEnumParam(widget, 'state',
'disabled', 'normal', 'readonly')
- def test_validate(self):
+ def test_configure_validate(self):
widget = self.create()
self.checkEnumParam(widget, 'validate',
'all', 'key', 'focus', 'focusin', 'focusout', 'none')
- def test_validatecommand(self):
+ def test_configure_validatecommand(self):
widget = self.create()
self.checkCommandParam(widget, 'validatecommand')
self.checkCommandParam(widget, 'vcmd')
def create(self, **kwargs):
return tkinter.Spinbox(self.root, **kwargs)
- test_show = None
+ test_configure_show = None
- def test_buttonbackground(self):
+ def test_configure_buttonbackground(self):
widget = self.create()
self.checkColorParam(widget, 'buttonbackground')
- def test_buttoncursor(self):
+ def test_configure_buttoncursor(self):
widget = self.create()
self.checkCursorParam(widget, 'buttoncursor')
- def test_buttondownrelief(self):
+ def test_configure_buttondownrelief(self):
widget = self.create()
self.checkReliefParam(widget, 'buttondownrelief')
- def test_buttonuprelief(self):
+ def test_configure_buttonuprelief(self):
widget = self.create()
self.checkReliefParam(widget, 'buttonuprelief')
- def test_format(self):
+ def test_configure_format(self):
widget = self.create()
self.checkParam(widget, 'format', '%2f')
self.checkParam(widget, 'format', '%2.2f')
self.checkParam(widget, 'format', '%09.200f')
self.checkInvalidParam(widget, 'format', '%d')
- def test_from(self):
+ def test_configure_from(self):
widget = self.create()
self.checkParam(widget, 'to', 100.0)
self.checkFloatParam(widget, 'from', -10, 10.2, 11.7)
self.checkInvalidParam(widget, 'from', 200,
errmsg='-to value must be greater than -from value')
- def test_increment(self):
+ def test_configure_increment(self):
widget = self.create()
self.checkFloatParam(widget, 'increment', -1, 1, 10.2, 12.8, 0)
- def test_to(self):
+ def test_configure_to(self):
widget = self.create()
self.checkParam(widget, 'from', -100.0)
self.checkFloatParam(widget, 'to', -10, 10.2, 11.7)
self.checkInvalidParam(widget, 'to', -200,
errmsg='-to value must be greater than -from value')
- def test_values(self):
+ def test_configure_values(self):
# XXX
widget = self.create()
self.assertEqual(widget['values'], '')
expected='42 3.14 {} {any string}')
self.checkParam(widget, 'values', '')
- def test_wrap(self):
+ def test_configure_wrap(self):
widget = self.create()
self.checkBooleanParam(widget, 'wrap')
def create(self, **kwargs):
return tkinter.Text(self.root, **kwargs)
- def test_autoseparators(self):
+ def test_configure_autoseparators(self):
widget = self.create()
self.checkBooleanParam(widget, 'autoseparators')
@requires_tcl(8, 5)
- def test_blockcursor(self):
+ def test_configure_blockcursor(self):
widget = self.create()
self.checkBooleanParam(widget, 'blockcursor')
@requires_tcl(8, 5)
- def test_endline(self):
+ def test_configure_endline(self):
widget = self.create()
text = '\n'.join('Line %d' for i in range(100))
widget.insert('end', text)
self.checkInvalidParam(widget, 'endline', 10,
errmsg='-startline must be less than or equal to -endline')
- def test_height(self):
+ def test_configure_height(self):
widget = self.create()
self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, '3c')
self.checkParam(widget, 'height', -100, expected=1)
self.checkParam(widget, 'height', 0, expected=1)
- def test_maxundo(self):
+ def test_configure_maxundo(self):
widget = self.create()
self.checkIntegerParam(widget, 'maxundo', 0, 5, -1)
@requires_tcl(8, 5)
- def test_inactiveselectbackground(self):
+ def test_configure_inactiveselectbackground(self):
widget = self.create()
self.checkColorParam(widget, 'inactiveselectbackground')
@requires_tcl(8, 6)
- def test_insertunfocussed(self):
+ def test_configure_insertunfocussed(self):
widget = self.create()
self.checkEnumParam(widget, 'insertunfocussed',
'hollow', 'none', 'solid')
- def test_selectborderwidth(self):
+ def test_configure_selectborderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'selectborderwidth',
1.3, 2.6, -2, '10p', conv=noconv,
keep_orig=tcl_version >= (8, 5))
- def test_spacing1(self):
+ def test_configure_spacing1(self):
widget = self.create()
self.checkPixelsParam(widget, 'spacing1', 20, 21.4, 22.6, '0.5c')
self.checkParam(widget, 'spacing1', -5, expected=0)
- def test_spacing2(self):
+ def test_configure_spacing2(self):
widget = self.create()
self.checkPixelsParam(widget, 'spacing2', 5, 6.4, 7.6, '0.1c')
self.checkParam(widget, 'spacing2', -1, expected=0)
- def test_spacing3(self):
+ def test_configure_spacing3(self):
widget = self.create()
self.checkPixelsParam(widget, 'spacing3', 20, 21.4, 22.6, '0.5c')
self.checkParam(widget, 'spacing3', -10, expected=0)
@requires_tcl(8, 5)
- def test_startline(self):
+ def test_configure_startline(self):
widget = self.create()
text = '\n'.join('Line %d' for i in range(100))
widget.insert('end', text)
self.checkInvalidParam(widget, 'startline', 70,
errmsg='-startline must be less than or equal to -endline')
- def test_state(self):
+ def test_configure_state(self):
widget = self.create()
if tcl_version < (8, 5):
self.checkParams(widget, 'state', 'disabled', 'normal')
else:
self.checkEnumParam(widget, 'state', 'disabled', 'normal')
- def test_tabs(self):
+ def test_configure_tabs(self):
widget = self.create()
if get_tk_patchlevel() < (8, 5, 11):
self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i'),
keep_orig=tcl_version >= (8, 5))
@requires_tcl(8, 5)
- def test_tabstyle(self):
+ def test_configure_tabstyle(self):
widget = self.create()
self.checkEnumParam(widget, 'tabstyle', 'tabular', 'wordprocessor')
- def test_undo(self):
+ def test_configure_undo(self):
widget = self.create()
self.checkBooleanParam(widget, 'undo')
- def test_width(self):
+ def test_configure_width(self):
widget = self.create()
self.checkIntegerParam(widget, 'width', 402)
self.checkParam(widget, 'width', -402, expected=1)
self.checkParam(widget, 'width', 0, expected=1)
- def test_wrap(self):
+ def test_configure_wrap(self):
widget = self.create()
if tcl_version < (8, 5):
self.checkParams(widget, 'wrap', 'char', 'none', 'word')
def create(self, **kwargs):
return tkinter.Canvas(self.root, **kwargs)
- def test_closeenough(self):
+ def test_configure_closeenough(self):
widget = self.create()
self.checkFloatParam(widget, 'closeenough', 24, 2.4, 3.6, -3,
conv=float)
- def test_confine(self):
+ def test_configure_confine(self):
widget = self.create()
self.checkBooleanParam(widget, 'confine')
- def test_offset(self):
+ def test_configure_offset(self):
widget = self.create()
self.assertEqual(widget['offset'], '0,0')
self.checkParams(widget, 'offset',
self.checkParam(widget, 'offset', '#5,6')
self.checkInvalidParam(widget, 'offset', 'spam')
- def test_scrollregion(self):
+ def test_configure_scrollregion(self):
widget = self.create()
self.checkParam(widget, 'scrollregion', '0 0 200 150')
self.checkParam(widget, 'scrollregion', (0, 0, 200, 150),
self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200))
self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200, 150, 0))
- def test_state(self):
+ def test_configure_state(self):
widget = self.create()
self.checkEnumParam(widget, 'state', 'disabled', 'normal',
errmsg='bad state value "{}": must be normal or disabled')
- def test_xscrollincrement(self):
+ def test_configure_xscrollincrement(self):
widget = self.create()
self.checkPixelsParam(widget, 'xscrollincrement',
40, 0, 41.2, 43.6, -40, '0.5i')
- def test_yscrollincrement(self):
+ def test_configure_yscrollincrement(self):
widget = self.create()
self.checkPixelsParam(widget, 'yscrollincrement',
10, 0, 11.2, 13.6, -10, '0.1i')
def create(self, **kwargs):
return tkinter.Listbox(self.root, **kwargs)
- def test_activestyle(self):
+ def test_configure_activestyle(self):
widget = self.create()
self.checkEnumParam(widget, 'activestyle',
'dotbox', 'none', 'underline')
- test_justify = requires_tcl(8, 6, 5)(StandardOptionsTests.test_justify)
+ test_justify = requires_tcl(8, 6, 5)(StandardOptionsTests.test_configure_justify)
- def test_listvariable(self):
+ def test_configure_listvariable(self):
widget = self.create()
var = tkinter.DoubleVar(self.root)
self.checkVariableParam(widget, 'listvariable', var)
- def test_selectmode(self):
+ def test_configure_selectmode(self):
widget = self.create()
self.checkParam(widget, 'selectmode', 'single')
self.checkParam(widget, 'selectmode', 'browse')
self.checkParam(widget, 'selectmode', 'multiple')
self.checkParam(widget, 'selectmode', 'extended')
- def test_state(self):
+ def test_configure_state(self):
widget = self.create()
self.checkEnumParam(widget, 'state', 'disabled', 'normal')
def create(self, **kwargs):
return tkinter.Scale(self.root, **kwargs)
- def test_bigincrement(self):
+ def test_configure_bigincrement(self):
widget = self.create()
self.checkFloatParam(widget, 'bigincrement', 12.4, 23.6, -5)
- def test_digits(self):
+ def test_configure_digits(self):
widget = self.create()
self.checkIntegerParam(widget, 'digits', 5, 0)
- def test_from(self):
+ def test_configure_from(self):
widget = self.create()
conv = False if get_tk_patchlevel() >= (8, 6, 10) else float_round
self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=conv)
- def test_label(self):
+ def test_configure_label(self):
widget = self.create()
self.checkParam(widget, 'label', 'any string')
self.checkParam(widget, 'label', '')
- def test_length(self):
+ def test_configure_length(self):
widget = self.create()
self.checkPixelsParam(widget, 'length', 130, 131.2, 135.6, '5i')
- def test_resolution(self):
+ def test_configure_resolution(self):
widget = self.create()
self.checkFloatParam(widget, 'resolution', 4.2, 0, 6.7, -2)
- def test_showvalue(self):
+ def test_configure_showvalue(self):
widget = self.create()
self.checkBooleanParam(widget, 'showvalue')
- def test_sliderlength(self):
+ def test_configure_sliderlength(self):
widget = self.create()
self.checkPixelsParam(widget, 'sliderlength',
10, 11.2, 15.6, -3, '3m')
- def test_sliderrelief(self):
+ def test_configure_sliderrelief(self):
widget = self.create()
self.checkReliefParam(widget, 'sliderrelief')
- def test_tickinterval(self):
+ def test_configure_tickinterval(self):
widget = self.create()
self.checkFloatParam(widget, 'tickinterval', 1, 4.3, 7.6, 0,
conv=float_round)
self.checkParam(widget, 'tickinterval', -2, expected=2,
conv=float_round)
- def test_to(self):
+ def test_configure_to(self):
widget = self.create()
self.checkFloatParam(widget, 'to', 300, 14.9, 15.1, -10,
conv=float_round)
def create(self, **kwargs):
return tkinter.Scrollbar(self.root, **kwargs)
- def test_activerelief(self):
+ def test_configure_activerelief(self):
widget = self.create()
self.checkReliefParam(widget, 'activerelief')
- def test_elementborderwidth(self):
+ def test_configure_elementborderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'elementborderwidth', 4.3, 5.6, -2, '1m')
- def test_orient(self):
+ def test_configure_orient(self):
widget = self.create()
self.checkEnumParam(widget, 'orient', 'vertical', 'horizontal',
errmsg='bad orientation "{}": must be vertical or horizontal')
def create(self, **kwargs):
return tkinter.PanedWindow(self.root, **kwargs)
- def test_handlepad(self):
+ def test_configure_handlepad(self):
widget = self.create()
self.checkPixelsParam(widget, 'handlepad', 5, 6.4, 7.6, -3, '1m')
- def test_handlesize(self):
+ def test_configure_handlesize(self):
widget = self.create()
self.checkPixelsParam(widget, 'handlesize', 8, 9.4, 10.6, -3, '2m',
conv=noconv)
- def test_height(self):
+ def test_configure_height(self):
widget = self.create()
self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i',
conv=noconv)
- def test_opaqueresize(self):
+ def test_configure_opaqueresize(self):
widget = self.create()
self.checkBooleanParam(widget, 'opaqueresize')
@requires_tcl(8, 6, 5)
- def test_proxybackground(self):
+ def test_configure_proxybackground(self):
widget = self.create()
self.checkColorParam(widget, 'proxybackground')
@requires_tcl(8, 6, 5)
- def test_proxyborderwidth(self):
+ def test_configure_proxyborderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'proxyborderwidth',
0, 1.3, 2.9, 6, -2, '10p',
conv=noconv)
@requires_tcl(8, 6, 5)
- def test_proxyrelief(self):
+ def test_configure_proxyrelief(self):
widget = self.create()
self.checkReliefParam(widget, 'proxyrelief')
- def test_sashcursor(self):
+ def test_configure_sashcursor(self):
widget = self.create()
self.checkCursorParam(widget, 'sashcursor')
- def test_sashpad(self):
+ def test_configure_sashpad(self):
widget = self.create()
self.checkPixelsParam(widget, 'sashpad', 8, 1.3, 2.6, -2, '2m')
- def test_sashrelief(self):
+ def test_configure_sashrelief(self):
widget = self.create()
self.checkReliefParam(widget, 'sashrelief')
- def test_sashwidth(self):
+ def test_configure_sashwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'sashwidth', 10, 11.1, 15.6, -3, '1m',
conv=noconv)
- def test_showhandle(self):
+ def test_configure_showhandle(self):
widget = self.create()
self.checkBooleanParam(widget, 'showhandle')
- def test_width(self):
+ def test_configure_width(self):
widget = self.create()
self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i',
conv=noconv)
def create(self, **kwargs):
return tkinter.Menu(self.root, **kwargs)
- def test_postcommand(self):
+ def test_configure_postcommand(self):
widget = self.create()
self.checkCommandParam(widget, 'postcommand')
- def test_tearoff(self):
+ def test_configure_tearoff(self):
widget = self.create()
self.checkBooleanParam(widget, 'tearoff')
- def test_tearoffcommand(self):
+ def test_configure_tearoffcommand(self):
widget = self.create()
self.checkCommandParam(widget, 'tearoffcommand')
- def test_title(self):
+ def test_configure_title(self):
widget = self.create()
self.checkParam(widget, 'title', 'any string')
- def test_type(self):
+ def test_configure_type(self):
widget = self.create()
self.checkEnumParam(widget, 'type',
'normal', 'tearoff', 'menubar')
def create(self, **kwargs):
return tkinter.Message(self.root, **kwargs)
- def test_aspect(self):
+ def test_configure_aspect(self):
widget = self.create()
self.checkIntegerParam(widget, 'aspect', 250, 0, -300)
+class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
+
+ def test_frame(self):
+ self._test_widget(tkinter.Frame)
+
+ def test_label(self):
+ self._test_widget(tkinter.Label)
+
+
tests_gui = (
ButtonTest, CanvasTest, CheckbuttonTest, EntryTest,
FrameTest, LabelFrameTest,LabelTest, ListboxTest,
MenubuttonTest, MenuTest, MessageTest, OptionMenuTest,
PanedWindowTest, RadiobuttonTest, ScaleTest, ScrollbarTest,
- SpinboxTest, TextTest, ToplevelTest,
+ SpinboxTest, TextTest, ToplevelTest, DefaultRootTest,
)
if __name__ == '__main__':
import unittest
import tkinter
from tkinter import ttk
-from test.support import requires, run_unittest, swap_attr
-from tkinter.test.support import AbstractTkTest, destroy_default_root
+from test.support import requires, run_unittest
+from tkinter.test.support import AbstractTkTest, AbstractDefaultRootTest
requires('gui')
if hasattr(sys, 'last_type'):
self.assertNotEqual(sys.last_type, tkinter.TclError)
-
- def test_initialization_no_master(self):
- # no master passing
- with swap_attr(tkinter, '_default_root', None), \
- swap_attr(tkinter, '_support_default_root', True):
- try:
- x = ttk.LabeledScale()
- self.assertIsNotNone(tkinter._default_root)
- self.assertEqual(x.master, tkinter._default_root)
- self.assertEqual(x.tk, tkinter._default_root.tk)
- x.destroy()
- finally:
- destroy_default_root()
-
def test_initialization(self):
# master passing
master = tkinter.Frame(self.root)
optmenu2.destroy()
-tests_gui = (LabeledScaleTest, OptionMenuTest)
+class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
+
+ def test_labeledscale(self):
+ self._test_widget(ttk.LabeledScale)
+
+
+tests_gui = (LabeledScaleTest, OptionMenuTest, DefaultRootTest)
if __name__ == "__main__":
run_unittest(*tests_gui)
from tkinter.test.test_ttk.test_functions import MockTclObj
from tkinter.test.support import (AbstractTkTest, tcl_version, get_tk_patchlevel,
- simulate_mouse_click)
+ simulate_mouse_click, AbstractDefaultRootTest)
from tkinter.test.widget_tests import (add_standard_options, noconv,
AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests,
setUpModule)
class StandardTtkOptionsTests(StandardOptionsTests):
- def test_class(self):
+ def test_configure_class(self):
widget = self.create()
self.assertEqual(widget['class'], '')
errmsg='attempt to change read-only option'
widget2 = self.create(class_='Foo')
self.assertEqual(widget2['class'], 'Foo')
- def test_padding(self):
+ def test_configure_padding(self):
widget = self.create()
self.checkParam(widget, 'padding', 0, expected=('0',))
self.checkParam(widget, 'padding', 5, expected=('5',))
self.checkParam(widget, 'padding', ('5p', '6p', '7p', '8p'))
self.checkParam(widget, 'padding', (), expected='')
- def test_style(self):
+ def test_configure_style(self):
widget = self.create()
self.assertEqual(widget['style'], '')
errmsg = 'Layout Foo not found'
def create(self, **kwargs):
return ttk.LabelFrame(self.root, **kwargs)
- def test_labelanchor(self):
+ def test_configure_labelanchor(self):
widget = self.create()
self.checkEnumParam(widget, 'labelanchor',
'e', 'en', 'es', 'n', 'ne', 'nw', 's', 'se', 'sw', 'w', 'wn', 'ws',
errmsg='Bad label anchor specification {}')
self.checkInvalidParam(widget, 'labelanchor', 'center')
- def test_labelwidget(self):
+ def test_configure_labelwidget(self):
widget = self.create()
label = ttk.Label(self.root, text='Mupp', name='foo')
self.checkParam(widget, 'labelwidget', label, expected='.foo')
self.checkInvalidParam(widget, name, 'spam',
errmsg='image "spam" doesn\'t exist')
- def test_compound(self):
+ def test_configure_compound(self):
widget = self.create()
self.checkEnumParam(widget, 'compound',
'none', 'text', 'image', 'center',
'top', 'bottom', 'left', 'right')
- def test_state(self):
+ def test_configure_state(self):
widget = self.create()
self.checkParams(widget, 'state', 'active', 'disabled', 'normal')
- def test_width(self):
+ def test_configure_width(self):
widget = self.create()
self.checkParams(widget, 'width', 402, -402, 0)
def create(self, **kwargs):
return ttk.Label(self.root, **kwargs)
- def test_font(self):
+ def test_configure_font(self):
widget = self.create()
self.checkParam(widget, 'font',
'-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*')
def create(self, **kwargs):
return ttk.Button(self.root, **kwargs)
- def test_default(self):
+ def test_configure_default(self):
widget = self.create()
self.checkEnumParam(widget, 'default', 'normal', 'active', 'disabled')
def create(self, **kwargs):
return ttk.Checkbutton(self.root, **kwargs)
- def test_offvalue(self):
+ def test_configure_offvalue(self):
widget = self.create()
self.checkParams(widget, 'offvalue', 1, 2.3, '', 'any string')
- def test_onvalue(self):
+ def test_configure_onvalue(self):
widget = self.create()
self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string')
def create(self, **kwargs):
return ttk.Entry(self.root, **kwargs)
- def test_invalidcommand(self):
+ def test_configure_invalidcommand(self):
widget = self.create()
self.checkCommandParam(widget, 'invalidcommand')
- def test_show(self):
+ def test_configure_show(self):
widget = self.create()
self.checkParam(widget, 'show', '*')
self.checkParam(widget, 'show', '')
self.checkParam(widget, 'show', ' ')
- def test_state(self):
+ def test_configure_state(self):
widget = self.create()
self.checkParams(widget, 'state',
'disabled', 'normal', 'readonly')
- def test_validate(self):
+ def test_configure_validate(self):
widget = self.create()
self.checkEnumParam(widget, 'validate',
'all', 'key', 'focus', 'focusin', 'focusout', 'none')
- def test_validatecommand(self):
+ def test_configure_validatecommand(self):
widget = self.create()
self.checkCommandParam(widget, 'validatecommand')
def create(self, **kwargs):
return ttk.Combobox(self.root, **kwargs)
- def test_height(self):
+ def test_configure_height(self):
widget = self.create()
self.checkParams(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i')
self.assertTrue(success)
- def test_postcommand(self):
+ def test_configure_postcommand(self):
success = []
self.combo['postcommand'] = lambda: success.append(True)
self.assertEqual(len(success), 1)
- def test_values(self):
+ def test_configure_values(self):
def check_get_current(getval, currval):
self.assertEqual(self.combo.get(), getval)
self.assertEqual(self.combo.current(), currval)
def create(self, **kwargs):
return ttk.PanedWindow(self.root, **kwargs)
- def test_orient(self):
+ def test_configure_orient(self):
widget = self.create()
self.assertEqual(str(widget['orient']), 'vertical')
errmsg='attempt to change read-only option'
def create(self, **kwargs):
return ttk.Radiobutton(self.root, **kwargs)
- def test_value(self):
+ def test_configure_value(self):
widget = self.create()
self.checkParams(widget, 'value', 1, 2.3, '', 'any string')
- def test_invoke(self):
+ def test_configure_invoke(self):
success = []
def cb_test():
success.append(1)
self.checkEnumParam(widget, 'direction',
'above', 'below', 'left', 'right', 'flush')
- def test_menu(self):
+ def test_configure_menu(self):
widget = self.create()
menu = tkinter.Menu(widget, name='menu')
self.checkParam(widget, 'menu', menu, conv=str)
def create(self, **kwargs):
return ttk.Scale(self.root, **kwargs)
- def test_from(self):
+ def test_configure_from(self):
widget = self.create()
self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=False)
- def test_length(self):
+ def test_configure_length(self):
widget = self.create()
self.checkPixelsParam(widget, 'length', 130, 131.2, 135.6, '5i')
- def test_to(self):
+ def test_configure_to(self):
widget = self.create()
self.checkFloatParam(widget, 'to', 300, 14.9, 15.1, -10, conv=False)
- def test_value(self):
+ def test_configure_value(self):
widget = self.create()
self.checkFloatParam(widget, 'value', 300, 14.9, 15.1, -10, conv=False)
def create(self, **kwargs):
return ttk.Progressbar(self.root, **kwargs)
- def test_length(self):
+ def test_configure_length(self):
widget = self.create()
self.checkPixelsParam(widget, 'length', 100.1, 56.7, '2i')
- def test_maximum(self):
+ def test_configure_maximum(self):
widget = self.create()
self.checkFloatParam(widget, 'maximum', 150.2, 77.7, 0, -10, conv=False)
- def test_mode(self):
+ def test_configure_mode(self):
widget = self.create()
self.checkEnumParam(widget, 'mode', 'determinate', 'indeterminate')
- def test_phase(self):
+ def test_configure_phase(self):
# XXX
pass
- def test_value(self):
+ def test_configure_value(self):
widget = self.create()
self.checkFloatParam(widget, 'value', 150.2, 77.7, 0, -10,
conv=False)
self.assertEqual(self.nb.tab(self.child1, 'text'), 'abc')
- def test_tabs(self):
+ def test_configure_tabs(self):
self.assertEqual(len(self.nb.tabs()), 2)
self.nb.forget(self.child1)
self.spin.event_generate('<ButtonRelease-1>', x=x, y=y)
self.spin.update_idletasks()
- def test_command(self):
+ def test_configure_command(self):
success = []
self.spin['command'] = lambda: success.append(True)
self.spin.update()
self.assertEqual(len(success), 2)
- def test_to(self):
+ def test_configure_to(self):
self.spin['from'] = 0
self.spin['to'] = 5
self.spin.set(4)
self._click_increment_arrow() # 5
self.assertEqual(self.spin.get(), '5')
- def test_from(self):
+ def test_configure_from(self):
self.spin['from'] = 1
self.spin['to'] = 10
self.spin.set(2)
self._click_decrement_arrow() # 1
self.assertEqual(self.spin.get(), '1')
- def test_increment(self):
+ def test_configure_increment(self):
self.spin['from'] = 0
self.spin['to'] = 10
self.spin['increment'] = 4
self._click_decrement_arrow() # 3
self.assertEqual(self.spin.get(), '3')
- def test_format(self):
+ def test_configure_format(self):
self.spin.set(1)
self.spin['format'] = '%10.3f'
self.spin.update()
self.assertTrue('.' not in value)
self.assertEqual(len(value), 1)
- def test_wrap(self):
+ def test_configure_wrap(self):
self.spin['to'] = 10
self.spin['from'] = 1
self.spin.set(1)
self._click_decrement_arrow()
self.assertEqual(self.spin.get(), '1')
- def test_values(self):
+ def test_configure_values(self):
self.assertEqual(self.spin['values'],
() if tcl_version < (8, 5) else '')
self.checkParam(self.spin, 'values', 'mon tue wed thur',
def create(self, **kwargs):
return ttk.Treeview(self.root, **kwargs)
- def test_columns(self):
+ def test_configure_columns(self):
widget = self.create()
self.checkParam(widget, 'columns', 'a b c',
expected=('a', 'b', 'c'))
self.checkParam(widget, 'columns', ('a', 'b', 'c'))
self.checkParam(widget, 'columns', '')
- def test_displaycolumns(self):
+ def test_configure_displaycolumns(self):
widget = self.create()
widget['columns'] = ('a', 'b', 'c')
self.checkParam(widget, 'displaycolumns', 'b a c',
self.checkInvalidParam(widget, 'displaycolumns', (1, -2),
errmsg='Column index -2 out of bounds')
- def test_height(self):
+ def test_configure_height(self):
widget = self.create()
self.checkPixelsParam(widget, 'height', 100, -100, 0, '3c', conv=False)
self.checkPixelsParam(widget, 'height', 101.2, 102.6, conv=noconv)
- def test_selectmode(self):
+ def test_configure_selectmode(self):
widget = self.create()
self.checkEnumParam(widget, 'selectmode',
'none', 'browse', 'extended')
- def test_show(self):
+ def test_configure_show(self):
widget = self.create()
self.checkParam(widget, 'show', 'tree headings',
expected=('tree', 'headings'))
def create(self, **kwargs):
return ttk.Sizegrip(self.root, **kwargs)
+
+class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
+
+ def test_frame(self):
+ self._test_widget(ttk.Frame)
+
+ def test_label(self):
+ self._test_widget(ttk.Label)
+
+
tests_gui = (
ButtonTest, CheckbuttonTest, ComboboxTest, EntryTest,
FrameTest, LabelFrameTest, LabelTest, MenubuttonTest,
NotebookTest, PanedWindowTest, ProgressbarTest,
RadiobuttonTest, ScaleTest, ScrollbarTest, SeparatorTest,
- SizegripTest, SpinboxTest, TreeviewTest, WidgetTest,
+ SizegripTest, SpinboxTest, TreeviewTest, WidgetTest, DefaultRootTest,
)
if __name__ == "__main__":
# Common tests for test_tkinter/test_widgets.py and test_ttk/test_widgets.py
import unittest
-import sys
import tkinter
from tkinter.test.support import (AbstractTkTest, tcl_version, requires_tcl,
get_tk_patchlevel, pixels_conv, tcl_obj_eq)
'underline', 'wraplength', 'xscrollcommand', 'yscrollcommand',
)
- def test_activebackground(self):
+ def test_configure_activebackground(self):
widget = self.create()
self.checkColorParam(widget, 'activebackground')
- def test_activeborderwidth(self):
+ def test_configure_activeborderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'activeborderwidth',
0, 1.3, 2.9, 6, -2, '10p')
- def test_activeforeground(self):
+ def test_configure_activeforeground(self):
widget = self.create()
self.checkColorParam(widget, 'activeforeground')
- def test_anchor(self):
+ def test_configure_anchor(self):
widget = self.create()
self.checkEnumParam(widget, 'anchor',
'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center')
- def test_background(self):
+ def test_configure_background(self):
widget = self.create()
self.checkColorParam(widget, 'background')
if 'bg' in self.OPTIONS:
self.checkColorParam(widget, 'bg')
- def test_bitmap(self):
+ def test_configure_bitmap(self):
widget = self.create()
self.checkParam(widget, 'bitmap', 'questhead')
self.checkParam(widget, 'bitmap', 'gray50')
self.checkInvalidParam(widget, 'bitmap', 'spam',
errmsg='bitmap "spam" not defined')
- def test_borderwidth(self):
+ def test_configure_borderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'borderwidth',
0, 1.3, 2.6, 6, -2, '10p')
if 'bd' in self.OPTIONS:
self.checkPixelsParam(widget, 'bd', 0, 1.3, 2.6, 6, -2, '10p')
- def test_compound(self):
+ def test_configure_compound(self):
widget = self.create()
self.checkEnumParam(widget, 'compound',
'bottom', 'center', 'left', 'none', 'right', 'top')
- def test_cursor(self):
+ def test_configure_cursor(self):
widget = self.create()
self.checkCursorParam(widget, 'cursor')
- def test_disabledforeground(self):
+ def test_configure_disabledforeground(self):
widget = self.create()
self.checkColorParam(widget, 'disabledforeground')
- def test_exportselection(self):
+ def test_configure_exportselection(self):
widget = self.create()
self.checkBooleanParam(widget, 'exportselection')
- def test_font(self):
+ def test_configure_font(self):
widget = self.create()
self.checkParam(widget, 'font',
'-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*')
self.checkInvalidParam(widget, 'font', '',
errmsg='font "" doesn\'t exist')
- def test_foreground(self):
+ def test_configure_foreground(self):
widget = self.create()
self.checkColorParam(widget, 'foreground')
if 'fg' in self.OPTIONS:
self.checkColorParam(widget, 'fg')
- def test_highlightbackground(self):
+ def test_configure_highlightbackground(self):
widget = self.create()
self.checkColorParam(widget, 'highlightbackground')
- def test_highlightcolor(self):
+ def test_configure_highlightcolor(self):
widget = self.create()
self.checkColorParam(widget, 'highlightcolor')
- def test_highlightthickness(self):
+ def test_configure_highlightthickness(self):
widget = self.create()
self.checkPixelsParam(widget, 'highlightthickness',
0, 1.3, 2.6, 6, '10p')
self.checkParam(widget, 'highlightthickness', -2, expected=0,
conv=self._conv_pixels)
- @unittest.skipIf(sys.platform == 'darwin',
- 'crashes with Cocoa Tk (issue19733)')
- def test_image(self):
+ def test_configure_image(self):
widget = self.create()
self.checkImageParam(widget, 'image')
- def test_insertbackground(self):
+ def test_configure_insertbackground(self):
widget = self.create()
self.checkColorParam(widget, 'insertbackground')
- def test_insertborderwidth(self):
+ def test_configure_insertborderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'insertborderwidth',
0, 1.3, 2.6, 6, -2, '10p')
- def test_insertofftime(self):
+ def test_configure_insertofftime(self):
widget = self.create()
self.checkIntegerParam(widget, 'insertofftime', 100)
- def test_insertontime(self):
+ def test_configure_insertontime(self):
widget = self.create()
self.checkIntegerParam(widget, 'insertontime', 100)
- def test_insertwidth(self):
+ def test_configure_insertwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'insertwidth', 1.3, 2.6, -2, '10p')
- def test_jump(self):
+ def test_configure_jump(self):
widget = self.create()
self.checkBooleanParam(widget, 'jump')
- def test_justify(self):
+ def test_configure_justify(self):
widget = self.create()
self.checkEnumParam(widget, 'justify', 'left', 'right', 'center',
errmsg='bad justification "{}": must be '
errmsg='ambiguous justification "": must be '
'left, right, or center')
- def test_orient(self):
+ def test_configure_orient(self):
widget = self.create()
self.assertEqual(str(widget['orient']), self.default_orient)
self.checkEnumParam(widget, 'orient', 'horizontal', 'vertical')
- def test_padx(self):
+ def test_configure_padx(self):
widget = self.create()
self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, -2, '12m',
conv=self._conv_pad_pixels)
- def test_pady(self):
+ def test_configure_pady(self):
widget = self.create()
self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, -2, '12m',
conv=self._conv_pad_pixels)
- def test_relief(self):
+ def test_configure_relief(self):
widget = self.create()
self.checkReliefParam(widget, 'relief')
- def test_repeatdelay(self):
+ def test_configure_repeatdelay(self):
widget = self.create()
self.checkIntegerParam(widget, 'repeatdelay', -500, 500)
- def test_repeatinterval(self):
+ def test_configure_repeatinterval(self):
widget = self.create()
self.checkIntegerParam(widget, 'repeatinterval', -500, 500)
- def test_selectbackground(self):
+ def test_configure_selectbackground(self):
widget = self.create()
self.checkColorParam(widget, 'selectbackground')
- def test_selectborderwidth(self):
+ def test_configure_selectborderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'selectborderwidth', 1.3, 2.6, -2, '10p')
- def test_selectforeground(self):
+ def test_configure_selectforeground(self):
widget = self.create()
self.checkColorParam(widget, 'selectforeground')
- def test_setgrid(self):
+ def test_configure_setgrid(self):
widget = self.create()
self.checkBooleanParam(widget, 'setgrid')
- def test_state(self):
+ def test_configure_state(self):
widget = self.create()
self.checkEnumParam(widget, 'state', 'active', 'disabled', 'normal')
- def test_takefocus(self):
+ def test_configure_takefocus(self):
widget = self.create()
self.checkParams(widget, 'takefocus', '0', '1', '')
- def test_text(self):
+ def test_configure_text(self):
widget = self.create()
self.checkParams(widget, 'text', '', 'any string')
- def test_textvariable(self):
+ def test_configure_textvariable(self):
widget = self.create()
var = tkinter.StringVar(self.root)
self.checkVariableParam(widget, 'textvariable', var)
- def test_troughcolor(self):
+ def test_configure_troughcolor(self):
widget = self.create()
self.checkColorParam(widget, 'troughcolor')
- def test_underline(self):
+ def test_configure_underline(self):
widget = self.create()
self.checkIntegerParam(widget, 'underline', 0, 1, 10)
- def test_wraplength(self):
+ def test_configure_wraplength(self):
widget = self.create()
self.checkPixelsParam(widget, 'wraplength', 100)
- def test_xscrollcommand(self):
+ def test_configure_xscrollcommand(self):
widget = self.create()
self.checkCommandParam(widget, 'xscrollcommand')
- def test_yscrollcommand(self):
+ def test_configure_yscrollcommand(self):
widget = self.create()
self.checkCommandParam(widget, 'yscrollcommand')
# non-standard but common options
- def test_command(self):
+ def test_configure_command(self):
widget = self.create()
self.checkCommandParam(widget, 'command')
- def test_indicatoron(self):
+ def test_configure_indicatoron(self):
widget = self.create()
self.checkBooleanParam(widget, 'indicatoron')
- def test_offrelief(self):
+ def test_configure_offrelief(self):
widget = self.create()
self.checkReliefParam(widget, 'offrelief')
- def test_overrelief(self):
+ def test_configure_overrelief(self):
widget = self.create()
self.checkReliefParam(widget, 'overrelief')
- def test_selectcolor(self):
+ def test_configure_selectcolor(self):
widget = self.create()
self.checkColorParam(widget, 'selectcolor')
- def test_selectimage(self):
+ def test_configure_selectimage(self):
widget = self.create()
self.checkImageParam(widget, 'selectimage')
@requires_tcl(8, 5)
- def test_tristateimage(self):
+ def test_configure_tristateimage(self):
widget = self.create()
self.checkImageParam(widget, 'tristateimage')
@requires_tcl(8, 5)
- def test_tristatevalue(self):
+ def test_configure_tristatevalue(self):
widget = self.create()
self.checkParam(widget, 'tristatevalue', 'unknowable')
- def test_variable(self):
+ def test_configure_variable(self):
widget = self.create()
var = tkinter.DoubleVar(self.root)
self.checkVariableParam(widget, 'variable', var)
class IntegerSizeTests:
- def test_height(self):
+ def test_configure_height(self):
widget = self.create()
self.checkIntegerParam(widget, 'height', 100, -100, 0)
- def test_width(self):
+ def test_configure_width(self):
widget = self.create()
self.checkIntegerParam(widget, 'width', 402, -402, 0)
class PixelSizeTests:
- def test_height(self):
+ def test_configure_height(self):
widget = self.create()
self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '3c')
- def test_width(self):
+ def test_configure_width(self):
widget = self.create()
self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i')
def add_standard_options(*source_classes):
- # This decorator adds test_xxx methods from source classes for every xxx
- # option in the OPTIONS class attribute if they are not defined explicitly.
+ # This decorator adds test_configure_xxx methods from source classes for
+ # every xxx option in the OPTIONS class attribute if they are not defined
+ # explicitly.
def decorator(cls):
for option in cls.OPTIONS:
- methodname = 'test_' + option
+ methodname = 'test_configure_' + option
if not hasattr(cls, methodname):
for source_class in source_classes:
if hasattr(source_class, methodname):
# These are missing from Tkinter
def image_create(self, imgtype, cnf={}, master=None, **kw):
if not master:
- master = tkinter._default_root
- if not master:
- raise RuntimeError('Too early to create image')
+ master = self
if kw and cnf: cnf = _cnfmerge((cnf, kw))
elif kw: cnf = kw
options = ()
elif 'refwindow' in cnf:
master = cnf['refwindow']
else:
- master = tkinter._default_root
- if not master:
- raise RuntimeError("Too early to create display style: "
- "no root window")
+ master = tkinter._get_default_root('create display style')
self.tk = master.tk
self.stylename = self.tk.call('tixDisplayStyle', itemtype,
*self._options(cnf,kw) )
If it is not allowed to use the default root and master is None,
RuntimeError is raised."""
if master is None:
- if tkinter._support_default_root:
- master = tkinter._default_root or tkinter.Tk()
- else:
- raise RuntimeError(
- "No master specified and tkinter is "
- "configured to not support default root")
+ master = tkinter._get_default_root()
return master
scale_side = 'bottom' if self._label_top else 'top'
label_side = 'top' if scale_side == 'bottom' else 'bottom'
self.scale.pack(side=scale_side, fill='x')
- tmp = Label(self).pack(side=label_side) # place holder
+ # Dummy required to make frame correct height
+ dummy = Label(self)
+ dummy.pack(side=label_side)
+ dummy.lower()
self.label.place(anchor='n' if label_side == 'top' else 's')
# update the label as scale or variable changes
if exc_type and issubclass(exc_type, SyntaxError):
# Handle SyntaxError's specially
self.filename = exc_value.filename
- self.lineno = str(exc_value.lineno)
+ lno = exc_value.lineno
+ self.lineno = str(lno) if lno is not None else None
self.text = exc_value.text
self.offset = exc_value.offset
self.msg = exc_value.msg
def _format_syntax_error(self, stype):
"""Format SyntaxError exceptions (internal helper)."""
# Show exactly where the problem was found.
- filename = self.filename or "<string>"
- lineno = str(self.lineno) or '?'
- yield ' File "{}", line {}\n'.format(filename, lineno)
+ filename_suffix = ''
+ if self.lineno is not None:
+ yield ' File "{}", line {}\n'.format(
+ self.filename or "<string>", self.lineno)
+ elif self.filename is not None:
+ filename_suffix = ' ({})'.format(self.filename)
text = self.text
if text is not None:
caretspace = ((c if c.isspace() else ' ') for c in ltext[:caret])
yield ' {}^\n'.format(''.join(caretspace))
msg = self.msg or "<no detail available>"
- yield "{}: {}\n".format(stype, msg)
+ yield "{}: {}{}\n".format(stype, msg, filename_suffix)
def format(self, *, chain=True):
"""Format the exception.
return str(self[0])
def __repr__(self):
- s = "<Traceback %r" % tuple(self)
+ s = f"<Traceback {tuple(self)}"
if self._total_nframe is None:
s += ">"
else:
# legitimate imports of those modules.
+def _type_convert(arg):
+ """For converting None to type(None), and strings to ForwardRef."""
+ if arg is None:
+ return type(None)
+ if isinstance(arg, str):
+ return ForwardRef(arg)
+ return arg
+
+
def _type_check(arg, msg, is_argument=True):
"""Check that the argument is a type, and return it (internal helper).
if is_argument:
invalid_generic_forms = invalid_generic_forms + (ClassVar, Final)
- if arg is None:
- return type(None)
- if isinstance(arg, str):
- return ForwardRef(arg)
+ arg = _type_convert(arg)
if (isinstance(arg, _GenericAlias) and
arg.__origin__ in invalid_generic_forms):
raise TypeError(f"{arg} is not valid as type argument")
raise TypeError("Callable must be used as "
"Callable[[arg, ...], result].")
args, result = params
- if args is Ellipsis:
- params = (Ellipsis, result)
- else:
- if not isinstance(args, list):
- raise TypeError(f"Callable[args, result]: args must be a list."
- f" Got {args}")
+ # This relaxes what args can be on purpose to allow things like
+ # PEP 612 ParamSpec. Responsibility for whether a user is using
+ # Callable[...] properly is deferred to static type checkers.
+ if isinstance(args, list):
params = (tuple(args), result)
+ else:
+ params = (args, result)
return self.__getitem_inner__(params)
@_tp_cache
result = _type_check(result, msg)
if args is Ellipsis:
return self.copy_with((_TypingEllipsis, result))
- msg = "Callable[[arg, ...], result]: each arg must be a type."
- args = tuple(_type_check(arg, msg) for arg in args)
+ if not isinstance(args, tuple):
+ args = (args,)
+ args = tuple(_type_convert(arg) for arg in args)
params = args + (result,)
return self.copy_with(params)
"""
if isinstance(tp, _AnnotatedAlias):
return (tp.__origin__,) + tp.__metadata__
- if isinstance(tp, _GenericAlias):
+ if isinstance(tp, (_GenericAlias, GenericAlias)):
res = tp.__args__
if tp.__origin__ is collections.abc.Callable and res[0] is not Ellipsis:
res = (list(res[:-1]), res[-1])
return res
- if isinstance(tp, GenericAlias):
- return tp.__args__
return ()
raise TypeError("TypedDict takes either a dict or keyword arguments,"
" but not both")
- ns = {'__annotations__': dict(fields), '__total__': total}
+ ns = {'__annotations__': dict(fields)}
try:
# Setting correct module is necessary to make typed dict classes pickleable.
ns['__module__'] = sys._getframe(1).f_globals.get('__name__', '__main__')
except (AttributeError, ValueError):
pass
- return _TypedDictMeta(typename, (), ns)
+ return _TypedDictMeta(typename, (), ns, total=total)
_TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {})
TypedDict.__mro_entries__ = lambda bases: (_TypedDict,)
ret = await awaitable
if not fut.cancelled():
fut.set_result(ret)
- except asyncio.CancelledError:
+ except (SystemExit, KeyboardInterrupt):
raise
- except Exception as ex:
+ except (BaseException, asyncio.CancelledError) as ex:
if not fut.cancelled():
fut.set_exception(ex)
# Check if spec is an async object or function
bound_args = _MOCK_SIG.bind_partial(cls, *args, **kw).arguments
spec_arg = bound_args.get('spec_set', bound_args.get('spec'))
- if spec_arg and _is_async_obj(spec_arg):
+ if spec_arg is not None and _is_async_obj(spec_arg):
bases = (AsyncMockMixin, cls)
new = type(cls.__name__, bases, {'__doc__': cls.__doc__})
instance = _safe_super(NonCallableMock, cls).__new__(new)
'async_cleanup 2',
'sync_cleanup 1'])
+ def test_base_exception_from_async_method(self):
+ events = []
+ class Test(unittest.IsolatedAsyncioTestCase):
+ async def test_base(self):
+ events.append("test_base")
+ raise BaseException()
+ events.append("not it")
+
+ async def test_no_err(self):
+ events.append("test_no_err")
+
+ async def test_cancel(self):
+ raise asyncio.CancelledError()
+
+ test = Test("test_base")
+ output = test.run()
+ self.assertFalse(output.wasSuccessful())
+
+ test = Test("test_no_err")
+ test.run()
+ self.assertEqual(events, ['test_base', 'test_no_err'])
+
+ test = Test("test_cancel")
+ output = test.run()
+ self.assertFalse(output.wasSuccessful())
+
+
if __name__ == "__main__":
unittest.main()
obj = mock(spec=Something)
self.assertIsInstance(obj, Something)
+ def test_bool_not_called_when_passing_spec_arg(self):
+ class Something:
+ def __init__(self):
+ self.obj_with_bool_func = unittest.mock.MagicMock()
+
+ obj = Something()
+ with unittest.mock.patch.object(obj, 'obj_with_bool_func', autospec=True): pass
+
+ self.assertEqual(obj.obj_with_bool_func.__bool__.call_count, 0)
+
if __name__ == '__main__':
unittest.main()
def parse_qs(qs, keep_blank_values=False, strict_parsing=False,
- encoding='utf-8', errors='replace', max_num_fields=None):
+ encoding='utf-8', errors='replace', max_num_fields=None, separator='&'):
"""Parse a query given as a string argument.
Arguments:
max_num_fields: int. If set, then throws a ValueError if there
are more than n fields read by parse_qsl().
+ separator: str. The symbol to use for separating the query arguments.
+ Defaults to &.
+
Returns a dictionary.
"""
parsed_result = {}
pairs = parse_qsl(qs, keep_blank_values, strict_parsing,
encoding=encoding, errors=errors,
- max_num_fields=max_num_fields)
+ max_num_fields=max_num_fields, separator=separator)
for name, value in pairs:
if name in parsed_result:
parsed_result[name].append(value)
def parse_qsl(qs, keep_blank_values=False, strict_parsing=False,
- encoding='utf-8', errors='replace', max_num_fields=None):
+ encoding='utf-8', errors='replace', max_num_fields=None, separator='&'):
"""Parse a query given as a string argument.
Arguments:
max_num_fields: int. If set, then throws a ValueError
if there are more than n fields read by parse_qsl().
+ separator: str. The symbol to use for separating the query arguments.
+ Defaults to &.
+
Returns a list, as G-d intended.
"""
qs, _coerce_result = _coerce_args(qs)
+ if not separator or (not isinstance(separator, (str, bytes))):
+ raise ValueError("Separator must be of type string or bytes.")
+
# If max_num_fields is defined then check that the number of fields
# is less than max_num_fields. This prevents a memory exhaustion DOS
# attack via post bodies with many fields.
if max_num_fields is not None:
- num_fields = 1 + qs.count('&') + qs.count(';')
+ num_fields = 1 + qs.count(separator)
if max_num_fields < num_fields:
raise ValueError('Max number of fields exceeded')
- pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')]
+ pairs = [s1 for s1 in qs.split(separator)]
r = []
for name_value in pairs:
if not name_value and not strict_parsing:
raise ValueError("proxy URL with no authority: %r" % proxy)
# We have an authority, so for RFC 3986-compliant URLs (by ss 3.
# and 3.3.), path is empty or starts with '/'
- end = r_scheme.find("/", 2)
+ if '@' in r_scheme:
+ host_separator = r_scheme.find('@')
+ end = r_scheme.find("/", host_separator)
+ else:
+ end = r_scheme.find("/", 2)
if end == -1:
end = None
authority = r_scheme[2:end]
result.extend([
dict(
- name="OpenSSL 1.1.1g",
- url="https://www.openssl.org/source/openssl-1.1.1g.tar.gz",
- checksum='76766e98997660138cdaf13a187bd234',
+ name="OpenSSL 1.1.1i",
+ url="https://www.openssl.org/source/openssl-1.1.1i.tar.gz",
+ checksum='08987c3cf125202e2b0840035efb392c',
buildrecipe=build_universal_openssl,
configure=None,
install=None,
- patches=[
- "openssl-mac-arm64.patch",
- ],
),
])
tk_patches = ['tk868_on_10_8_10_9.patch']
else:
- tcl_tk_ver='8.6.10'
- tcl_checksum='97c55573f8520bcab74e21bfd8d0aadc'
+ tcl_tk_ver='8.6.11'
+ tcl_checksum='8a4c004f48984a03a7747e9ba06e4da4'
- tk_checksum='602a47ad9ecac7bf655ada729d140a94'
+ tk_checksum='c7ee71a2d05bba78dfffd76528dc17c6'
tk_patches = [ ]
),
),
dict(
- name="SQLite 3.33.0",
- url="https://sqlite.org/2020/sqlite-autoconf-3330000.tar.gz",
- checksum='842a8a100d7b01b09e543deb2b7951dd',
+ name="SQLite 3.34.0",
+ url="https://sqlite.org/2020/sqlite-autoconf-3340000.tar.gz",
+ checksum='7f33c9db7b713957fcb9271fe9049fef',
extra_cflags=('-Os '
'-DSQLITE_ENABLE_FTS5 '
'-DSQLITE_ENABLE_FTS4 '
if not os.path.exists(htmlDir):
# Create virtual environment for docs builds with blurb and sphinx
runCommand('make venv')
- runCommand('venv/bin/python3 -m pip install -U Sphinx==2.3.1')
runCommand('make html PYTHON=venv/bin/python')
os.rename(htmlDir, docdir)
os.chdir(curDir)
if os.path.exists(outdir):
shutil.rmtree(outdir)
- # We used to use the deployment target as the last characters of the
+ # We used to use the deployment target as the last characters of the
# installer file name. With the introduction of weaklinked installer
# variants, we may have two variants with the same file name, i.e.
# both ending in '10.9'. To avoid this, we now use the major/minor
+++ /dev/null
-diff -ur openssl-1.1.1g-orig/Configurations/10-main.conf openssl-1.1.1g/Configurations/10-main.conf
---- openssl-1.1.1g-orig/Configurations/10-main.conf 2020-04-21 14:22:39.000000000 +0200
-+++ openssl-1.1.1g/Configurations/10-main.conf 2020-07-26 12:21:32.000000000 +0200
-@@ -1557,6 +1557,14 @@
- bn_ops => "SIXTY_FOUR_BIT_LONG",
- perlasm_scheme => "macosx",
- },
-+ "darwin64-arm64-cc" => {
-+ inherit_from => [ "darwin-common", asm("aarch64_asm") ],
-+ CFLAGS => add("-Wall"),
-+ cflags => add("-arch arm64"),
-+ lib_cppflags => add("-DL_ENDIAN"),
-+ bn_ops => "SIXTY_FOUR_BIT_LONG",
-+ perlasm_scheme => "ios64",
-+ },
-
- ##### GNU Hurd
- "hurd-x86" => {
-diff -ur openssl-1.1.1g-orig/config openssl-1.1.1g/config
---- openssl-1.1.1g-orig/config 2020-04-21 14:22:39.000000000 +0200
-+++ openssl-1.1.1g/config 2020-07-26 12:21:59.000000000 +0200
-@@ -255,6 +255,9 @@
- ;;
- x86_64)
- echo "x86_64-apple-darwin${VERSION}"
-+ ;;
-+ arm64)
-+ echo "arm64-apple-darwin${VERSION}"
- ;;
- *)
- echo "i686-apple-darwin${VERSION}"
-@@ -497,6 +500,9 @@
- else
- OUT="darwin64-x86_64-cc"
- fi ;;
-+ x86_64-apple-darwin*)
-+ OUT="darwin64-arm64-cc"
-+ ;;
- armv6+7-*-iphoneos)
- __CNF_CFLAGS="$__CNF_CFLAGS -arch armv6 -arch armv7"
- __CNF_CXXFLAGS="$__CNF_CXXFLAGS -arch armv6 -arch armv7"
# Make sure the directory ${PYTHON_ROOT}/bin is on the users PATH.
BSH="`basename "${theShell}"`"
case "${BSH}" in
-bash|ksh|sh|*csh|zsh)
+bash|ksh|sh|*csh|zsh|fish)
if [ `id -ur` = 0 ]; then
P=`su - ${USER} -c 'echo A-X-4-X@@$PATH@@X-4-X-A' | grep 'A-X-4-X@@.*@@X-4-X-A' | sed -e 's/^A-X-4-X@@//g' -e 's/@@X-4-X-A$//g'`
else
PR="${HOME}/.bash_profile"
fi
;;
+fish)
+ CONFIG_DIR="${HOME}/.config/fish"
+ RC="${CONFIG_DIR}/config.fish"
+ mkdir -p "$CONFIG_DIR"
+ if [ -f "${RC}" ]; then
+ cp -fp "${RC}" "${RC}.pysave"
+ fi
+ echo "" >> "${RC}"
+ echo "# Setting PATH for Python ${PYVER}" >> "${RC}"
+ echo "# The original version is saved in ${RC}.pysave" >> "${RC}"
+ echo "set -x PATH \"${PYTHON_ROOT}/bin\" \"\$PATH\"" >> "${RC}"
+ if [ `id -ur` = 0 ]; then
+ chown "${USER}" "${RC}"
+ fi
+ exit 0
+ ;;
zsh)
PR="${HOME}/.zprofile"
;;
<key>CFBundleExecutable</key>
<string>IDLE</string>
<key>CFBundleGetInfoString</key>
- <string>%version%, © 2001-2020 Python Software Foundation</string>
+ <string>%version%, © 2001-2021 Python Software Foundation</string>
<key>CFBundleIconFile</key>
<string>IDLE.icns</string>
<key>CFBundleIdentifier</key>
<key>CFBundleExecutable</key>
<string>Python Launcher</string>
<key>CFBundleGetInfoString</key>
- <string>%VERSION%, © 2001-2020 Python Software Foundation</string>
+ <string>%VERSION%, © 2001-2021 Python Software Foundation</string>
<key>CFBundleIconFile</key>
<string>PythonLauncher.icns</string>
<key>CFBundleIdentifier</key>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
- <string>%version%, (c) 2001-2020 Python Software Foundation.</string>
+ <string>%version%, (c) 2001-2021 Python Software Foundation.</string>
<key>CFBundleName</key>
<string>Python</string>
<key>CFBundlePackageType</key>
Carl Friedrich Bolz-Tereick
Forest Bond
Gregory Bond
+Angelin Booz
Médéric Boquien
Matias Bordese
Jonas Borgström
Kevin Rodgers
Sean Rodman
Giampaolo Rodola
+Dustin Rodrigues
Mauro S. M. Rodrigues
Elson Rodriguez
Adi Roiban
Frank Stajano
Joel Stanley
Kyle Stanley
+Brandon Stansbury
Anthony Starks
David Steele
Oliver Steele
Barry Warsaw
Steve Waterbury
Bob Watson
+Colin Watson
David Watson
Aaron Watters
Henrik Weber
Python News
+++++++++++
+What's New in Python 3.9.2 final?
+=================================
+
+*Release date: 2021-02-19*
+
+Windows
+-------
+
+- bpo-43155: :c:func:`PyCMethod_New` is now present in ``python3.lib``.
+
+
+What's New in Python 3.9.2 release candidate 1?
+===============================================
+
+*Release date: 2021-02-16*
+
+Security
+--------
+
+- bpo-42967: Fix web cache poisoning vulnerability by defaulting the query
+ args separator to ``&``, and allowing the user to choose a custom
+ separator.
+
+- bpo-42938: Avoid static buffers when computing the repr of
+ :class:`ctypes.c_double` and :class:`ctypes.c_longdouble` values.
+
+Core and Builtins
+-----------------
+
+- bpo-42819: :mod:`readline`: Explicitly disable bracketed paste in the
+ interactive interpreter, even if it's set in the inputrc, is enabled by
+ default (eg GNU Readline 8.1), or a user calls
+ ``readline.read_init_file()``. The Python REPL has not implemented
+ bracketed paste support. Also, bracketed mode writes the ``"\x1b[?2004h"``
+ escape sequence into stdout which causes test failures in applications
+ that don't support it. It can still be explicitly enabled by calling
+ ``readline.parse_and_bind("set enable-bracketed-paste on")``. Patch by
+ Dustin Rodrigues.
+
+- bpo-42806: Fix the column offsets for f-strings :mod:`ast` nodes
+ surrounded by parentheses and for nodes that spawn multiple lines. Patch
+ by Pablo Galindo.
+
+- bpo-40631: Fix regression where a single parenthesized starred expression
+ was a valid assignment target.
+
+- bpo-32381: Fix encoding name when running a ``.pyc`` file on Windows:
+ :c:func:`PyRun_SimpleFileExFlags()` now uses the correct encoding to
+ decode the filename.
+
+- bpo-42536: Several built-in and standard library types now ensure that
+ their internal result tuples are always tracked by the :term:`garbage
+ collector <garbage collection>`:
+
+ - :meth:`collections.OrderedDict.items() <collections.OrderedDict>`
+
+ - :meth:`dict.items`
+
+ - :func:`enumerate`
+
+ - :func:`functools.reduce`
+
+ - :func:`itertools.combinations`
+
+ - :func:`itertools.combinations_with_replacement`
+
+ - :func:`itertools.permutations`
+
+ - :func:`itertools.product`
+
+ - :func:`itertools.zip_longest`
+
+ - :func:`zip`
+
+ Previously, they could have become untracked by a prior garbage
+ collection. Patch by Brandt Bucher.
+
+- bpo-42195: The ``__args__`` of the parameterized generics for
+ :data:`typing.Callable` and :class:`collections.abc.Callable` are now
+ consistent. The ``__args__`` for :class:`collections.abc.Callable` are
+ now flattened while :data:`typing.Callable`'s have not changed. To allow
+ this change, :class:`types.GenericAlias` can now be subclassed and
+ ``collections.abc.Callable``'s ``__class_getitem__`` will now return a
+ subclass of ``types.GenericAlias``. Tests for typing were also updated to
+ not subclass things like ``Callable[..., T]`` as that is not a valid base
+ class. Finally, both types no longer validate their ``argtypes``, in
+ ``Callable[[argtypes], resulttype]`` to prepare for :pep:`612`. Patch by
+ Ken Jin.
+
+Library
+-------
+
+- bpo-43102: The namedtuple __new__ method had its __builtins__ set to None
+ instead of an actual dictionary. This created problems for introspection
+ tools.
+
+- bpo-43108: Fixed a reference leak in the :mod:`curses` module. Patch by
+ Pablo Galindo
+
+- bpo-42944: Fix ``random.Random.sample`` when ``counts`` argument is not
+ ``None``.
+
+- bpo-42931: Add :func:`randbytes` to ``random.__all__``.
+
+- bpo-42780: Fix os.set_inheritable() for O_PATH file descriptors on Linux.
+
+- bpo-42851: remove __init_subclass__ support for Enum members
+
+- bpo-41748: Fix HTMLParser parsing rules for element attributes containing
+ commas with spaces. Patch by Karl Dubost.
+
+- bpo-42759: Fixed equality comparison of :class:`tkinter.Variable` and
+ :class:`tkinter.font.Font`. Objects which belong to different Tcl
+ interpreters are now always different, even if they have the same name.
+
+- bpo-42756: Configure LMTP Unix-domain socket to use socket global default
+ timeout when a timeout is not explicitly provided.
+
+- bpo-23328: Allow / character in username, password fields on _PROXY
+ envars.
+
+- bpo-42655: :mod:`subprocess` *extra_groups* is now correctly passed into
+ setgroups() system call.
+
+- bpo-42727: ``EnumMeta.__prepare__`` now accepts ``**kwds`` to properly
+ support ``__init_subclass__``
+
+- bpo-42681: Fixed range checks for color and pair numbers in :mod:`curses`.
+
+- bpo-37961: Fix crash in :func:`tracemalloc.Traceback.__repr__` (regressed
+ in Python 3.9).
+
+- bpo-42630: :mod:`tkinter` functions and constructors which need a default
+ root window raise now :exc:`RuntimeError` with descriptive message instead
+ of obscure :exc:`AttributeError` or :exc:`NameError` if it is not created
+ yet or cannot be created automatically.
+
+- bpo-42644: `logging.disable` will now validate the types and value of its
+ parameter. It also now accepts strings representing the levels (as does
+ `loging.setLevel`) instead of only the numerical values.
+
+- bpo-36541: Fixed lib2to3.pgen2 to be able to parse PEP-570 positional only
+ argument syntax.
+
+- bpo-42517: Enum: private names will raise a DeprecationWarning; in 3.10
+ they will become normal attributes
+
+- bpo-42678: `Enum`: call `__init_subclass__` after members have been added
+
+- bpo-42532: Remove unexpected call of ``__bool__`` when passing a
+ ``spec_arg`` argument to a Mock.
+
+- bpo-42388: Fix subprocess.check_output(..., input=None) behavior when
+ text=True to be consistent with that of the documentation and
+ universal_newlines=True.
+
+- bpo-34463: Fixed discrepancy between :mod:`traceback` and the interpreter
+ in formatting of SyntaxError with lineno not set (:mod:`traceback` was
+ changed to match interpreter).
+
+- bpo-42375: subprocess module update for DragonFlyBSD support.
+
+- bpo-42384: Make pdb populate sys.path[0] exactly the same as regular
+ python execution.
+
+- bpo-42383: Fix pdb: previously pdb would fail to restart the debugging
+ target if it was specified using a relative path and the current directory
+ changed.
+
+- bpo-42318: Fixed support of non-BMP characters in :mod:`tkinter` on macOS.
+
+- bpo-42163: Restore compatibility for ``uname_result`` around deepcopy and
+ _replace.
+
+- bpo-39825: Windows: Change ``sysconfig.get_config_var('EXT_SUFFIX')`` to
+ the expected full ``platform_tag.extension`` format. Previously it was
+ hard-coded to ``.pyd``, now it is compatible with ``distutils.sysconfig``
+ and will result in something like ``.cp38-win_amd64.pyd``. This brings
+ windows into conformance with the other platforms.
+
+- bpo-42059: :class:`typing.TypedDict` types created using the alternative
+ call-style syntax now correctly respect the ``total`` keyword argument
+ when setting their ``__required_keys__`` and ``__optional_keys__`` class
+ attributes.
+
+- bpo-39101: Fixed tests using IsolatedAsyncioTestCase from hanging on
+ BaseExceptions.
+
+- bpo-42005: Fix CLI of :mod:`cProfile` and :mod:`profile` to catch
+ :exc:`BrokenPipeError`.
+
+- bpo-41907: fix `format()` behavior for `IntFlag`
+
+- bpo-41889: Enum: fix regression involving inheriting a multiply-inherited
+ enum
+
+- bpo-41891: Ensure asyncio.wait_for waits for task completion
+
+- bpo-41604: Don't decrement the reference count of the previous user_ptr
+ when set_panel_userptr fails.
+
+- bpo-40219: Lowered :class:`tkinter.ttk.LabeledScale` dummy widget to
+ prevent hiding part of the content label.
+
+- bpo-40084: Fix ``Enum.__dir__``: dir(Enum.member) now includes attributes
+ as well as methods.
+
+- bpo-39068: Fix initialization race condition in :func:`a85encode` and
+ :func:`b85encode` in :mod:`base64`. Patch by Brandon Stansbury.
+
+- bpo-33289: Correct call to :mod:`tkinter.colorchooser` to return RGB
+ triplet of ints instead of floats. Patch by Cheryl Sabella.
+
+Documentation
+-------------
+
+- bpo-40304: Fix doc for type(name, bases, dict). Patch by Boris
+ Verkhovskiy and Éric Araujo.
+
+- bpo-42811: Updated importlib.utils.resolve_name() doc to use
+ __spec__.parent instead of __package__. (Thanks Yair Frid.)
+
+- bpo-17140: Add documentation for the
+ :class:`multiprocessing.pool.ThreadPool` class.
+
+Tests
+-----
+
+- bpo-42794: Update test_nntplib to use offical group name of news.aioe.org
+ for testing. Patch by Dong-hee Na.
+
+- bpo-40810: In :mod:`sqlite3`, fix ``CheckTraceCallbackContent`` for SQLite
+ pre 3.7.15.
+
+Build
+-----
+
+- bpo-43174: Windows build now uses ``/utf-8`` compiler option.
+
+- bpo-42692: Fix __builtin_available check on older compilers. Patch by
+ Joshua Root.
+
+- bpo-42604: Now all platforms use a value for the "EXT_SUFFIX" build
+ variable derived from SOABI (for instance in freeBSD, "EXT_SUFFIX" is now
+ ".cpython-310d.so" instead of ".so"). Previosuly only Linux, Mac and
+ VxWorks were using a value for "EXT_SUFFIX" that included "SOABI".
+
+- bpo-42598: Fix implicit function declarations in configure which could
+ have resulted in incorrect configuration checks. Patch contributed by
+ Joshua Root.
+
+- bpo-29076: Add fish shell support to macOS installer.
+
+Windows
+-------
+
+- bpo-41837: Updated Windows installer to include OpenSSL 1.1.1i
+
+- bpo-42584: Upgrade Windows installer to use SQLite 3.34.0.
+
+macOS
+-----
+
+- bpo-42504: Ensure that the value of
+ sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') is always a string,
+ even in when the value is parsable as an integer.
+
+- bpo-42361: Update macOS installer build to use Tcl/Tk 8.6.11 (rc2,
+ expected to be final release).
+
+- bpo-41837: Update macOS installer build to use OpenSSL 1.1.1i.
+
+- bpo-42584: Update macOS installer to use SQLite 3.34.0.
+
+IDLE
+----
+
+- bpo-43008: Make IDLE invoke :func:`sys.excepthook` in normal, 2-process
+ mode. Patch by Ken Hilton.
+
+- bpo-33065: Fix problem debugging user classes with __repr__ method.
+
+- bpo-23544: Disable Debug=>Stack Viewer when user code is running or
+ Debugger is active, to prevent hang or crash. Patch by Zackery Spytz.
+
+- bpo-32631: Finish zzdummy example extension module: make menu entries
+ work; add docstrings and tests with 100% coverage.
+
+Tools/Demos
+-----------
+
+- bpo-42726: Fixed Python 3 compatibility issue with gdb/libpython.py
+ handling of attribute dictionaries.
+
+- bpo-42613: Fix ``freeze.py`` tool to use the prope config and library
+ directories. Patch by Victor Stinner.
+
+C API
+-----
+
+- bpo-43030: Fixed a compiler warning in :c:func:`Py_UNICODE_ISSPACE()` on
+ platforms with signed ``wchar_t``.
+
+- bpo-42591: Export the :c:func:`Py_FrozenMain` function: fix a Python 3.9.0
+ regression. Python 3.9 uses ``-fvisibility=hidden`` and the function was
+ not exported explicitly and so not exported.
+
+- bpo-40052: Fix an alignment build warning/error in function
+ ``PyVectorcall_Function()``. Patch by Andreas Schneider, Antoine Pitrou
+ and Petr Viktorin.
+
+
What's New in Python 3.9.1 final?
=================================
rules that only generate better error messages to gain performance. If
there's a parse failure, run the parser a second time with those enabled.
-- bpo-41910: Document the default implementation of `object.__eq__`.
-
- bpo-42057: Fix peephole optimizer misoptimize conditional jump +
JUMP_IF_NOT_EXC_MATCH pair.
- bpo-41316: Fix the :mod:`tarfile` module to write only basename of TAR
file to GZIP compression header.
-- bpo-16936: Allow ``ctypes.wintypes`` to be imported on non-Windows
+- bpo-16396: Allow ``ctypes.wintypes`` to be imported on non-Windows
systems.
- bpo-40592: :func:`shutil.which` now ignores empty entries in
- bpo-42061: Document __format__ functionality for IP addresses.
+- bpo-41910: Document the default implementation of `object.__eq__`.
+
- bpo-42010: Clarify that subscription expressions are also valid for
certain :term:`classes <class>` and :term:`types <type>` in the standard
library, and for user-defined classes and types if the classmethod
static PyObject *
PyCArg_repr(PyCArgObject *self)
{
- char buffer[256];
switch(self->tag) {
case 'b':
case 'B':
- sprintf(buffer, "<cparam '%c' (%d)>",
+ return PyUnicode_FromFormat("<cparam '%c' (%d)>",
self->tag, self->value.b);
- break;
case 'h':
case 'H':
- sprintf(buffer, "<cparam '%c' (%d)>",
+ return PyUnicode_FromFormat("<cparam '%c' (%d)>",
self->tag, self->value.h);
- break;
case 'i':
case 'I':
- sprintf(buffer, "<cparam '%c' (%d)>",
+ return PyUnicode_FromFormat("<cparam '%c' (%d)>",
self->tag, self->value.i);
- break;
case 'l':
case 'L':
- sprintf(buffer, "<cparam '%c' (%ld)>",
+ return PyUnicode_FromFormat("<cparam '%c' (%ld)>",
self->tag, self->value.l);
- break;
case 'q':
case 'Q':
- sprintf(buffer,
-#ifdef MS_WIN32
- "<cparam '%c' (%I64d)>",
-#else
- "<cparam '%c' (%lld)>",
-#endif
+ return PyUnicode_FromFormat("<cparam '%c' (%lld)>",
self->tag, self->value.q);
- break;
case 'd':
- sprintf(buffer, "<cparam '%c' (%f)>",
- self->tag, self->value.d);
- break;
- case 'f':
- sprintf(buffer, "<cparam '%c' (%f)>",
- self->tag, self->value.f);
- break;
-
+ case 'f': {
+ PyObject *f = PyFloat_FromDouble((self->tag == 'f') ? self->value.f : self->value.d);
+ if (f == NULL) {
+ return NULL;
+ }
+ PyObject *result = PyUnicode_FromFormat("<cparam '%c' (%R)>", self->tag, f);
+ Py_DECREF(f);
+ return result;
+ }
case 'c':
if (is_literal_char((unsigned char)self->value.c)) {
- sprintf(buffer, "<cparam '%c' ('%c')>",
+ return PyUnicode_FromFormat("<cparam '%c' ('%c')>",
self->tag, self->value.c);
}
else {
- sprintf(buffer, "<cparam '%c' ('\\x%02x')>",
+ return PyUnicode_FromFormat("<cparam '%c' ('\\x%02x')>",
self->tag, (unsigned char)self->value.c);
}
- break;
/* Hm, are these 'z' and 'Z' codes useful at all?
Shouldn't they be replaced by the functionality of c_string
case 'z':
case 'Z':
case 'P':
- sprintf(buffer, "<cparam '%c' (%p)>",
+ return PyUnicode_FromFormat("<cparam '%c' (%p)>",
self->tag, self->value.p);
break;
default:
if (is_literal_char((unsigned char)self->tag)) {
- sprintf(buffer, "<cparam '%c' at %p>",
+ return PyUnicode_FromFormat("<cparam '%c' at %p>",
(unsigned char)self->tag, (void *)self);
}
else {
- sprintf(buffer, "<cparam 0x%02x at %p>",
+ return PyUnicode_FromFormat("<cparam 0x%02x at %p>",
(unsigned char)self->tag, (void *)self);
}
- break;
}
- return PyUnicode_FromString(buffer);
}
static PyMemberDef PyCArgType_members[] = {
/* put the item back into the free list */
void Py_ffi_closure_free(void *p)
{
-#if USING_APPLE_OS_LIBFFI && HAVE_FFI_CLOSURE_ALLOC
+#if HAVE_FFI_CLOSURE_ALLOC
+#if USING_APPLE_OS_LIBFFI
if (__builtin_available(macos 10.15, ios 13, watchos 6, tvos 13, *)) {
+#endif
ffi_closure_free(p);
return;
+#if USING_APPLE_OS_LIBFFI
}
+#endif
#endif
ITEM *item = (ITEM *)p;
item->next = free_list;
/* return one item from the free list, allocating more if needed */
void *Py_ffi_closure_alloc(size_t size, void** codeloc)
{
-#if USING_APPLE_OS_LIBFFI && HAVE_FFI_CLOSURE_ALLOC
+#if HAVE_FFI_CLOSURE_ALLOC
+#if USING_APPLE_OS_LIBFFI
if (__builtin_available(macos 10.15, ios 13, watchos 6, tvos 13, *)) {
+#endif
return ffi_closure_alloc(size, codeloc);
+#if USING_APPLE_OS_LIBFFI
}
+#endif
#endif
ITEM *item;
if (!free_list)
/* In case of an ncurses error, decref the new object again */
Py_DECREF(obj);
}
- Py_XDECREF(oldobj);
+ else {
+ Py_XDECREF(oldobj);
+ }
return PyCursesCheckERR(rc, "set_panel_userptr");
}
/* Utility Functions */
-static inline int
-color_pair_to_attr(short color_number)
-{
- return ((int)color_number << 8);
-}
-
-static inline short
-attr_to_color_pair(int attr)
-{
- return (short)((attr & A_COLOR) >> 8);
-}
-
/*
* Check the return code from a curses function and return None
* or raise an exception as appropriate. These are exported using the
*bytes = obj;
/* check for embedded null bytes */
if (PyBytes_AsStringAndSize(*bytes, &str, NULL) < 0) {
+ Py_DECREF(obj);
return 0;
}
return 1;
if (type == 2) {
funcname = "add_wch";
wstr[1] = L'\0';
- setcchar(&wcval, wstr, attr, attr_to_color_pair(attr), NULL);
+ setcchar(&wcval, wstr, attr, PAIR_NUMBER(attr), NULL);
if (coordinates_group)
rtn = mvwadd_wch(self->win,y,x, &wcval);
else {
#else
strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL);
#endif
- if (strtype == 0)
+ if (strtype == 0) {
return NULL;
+ }
if (use_attr) {
attr_old = getattrs(self->win);
(void)wattrset(self->win,attr);
_curses.color_content
color_number: short
- The number of the color (0 - COLORS).
+ The number of the color (0 - (COLORS-1)).
/
Return the red, green, and blue (RGB) components of the specified color.
static PyObject *
_curses_color_content_impl(PyObject *module, short color_number)
-/*[clinic end generated code: output=cb15cf3120d4bfc1 input=5555abb1c11e11b7]*/
+/*[clinic end generated code: output=cb15cf3120d4bfc1 input=630f6737514db6ad]*/
{
short r,g,b;
PyCursesInitialised;
PyCursesInitialisedColor;
- if (color_content(color_number, &r, &g, &b) != ERR)
- return Py_BuildValue("(iii)", r, g, b);
- else {
- PyErr_SetString(PyCursesError,
- "Argument 1 was out of range. Check value of COLORS.");
+ if (color_content(color_number, &r, &g, &b) == ERR) {
+ if (color_number >= COLORS) {
+ PyErr_SetString(PyCursesError,
+ "Argument 1 was out of range. Check value of COLORS.");
+ }
+ else {
+ PyErr_SetString(PyCursesError, "color_content() returned ERR");
+ }
return NULL;
}
+
+ return Py_BuildValue("(iii)", r, g, b);
}
/*[clinic input]
_curses.color_pair
- color_number: short
- The number of the color (0 - COLORS).
+ pair_number: short
+ The number of the color pair.
/
Return the attribute value for displaying text in the specified color.
[clinic start generated code]*/
static PyObject *
-_curses_color_pair_impl(PyObject *module, short color_number)
-/*[clinic end generated code: output=6a84cb6b29ecaf9a input=a9d3eb6f50e4dc12]*/
+_curses_color_pair_impl(PyObject *module, short pair_number)
+/*[clinic end generated code: output=ce609d238b70dc11 input=8dd0d5da94cb15b5]*/
{
PyCursesInitialised;
PyCursesInitialisedColor;
- return PyLong_FromLong(color_pair_to_attr(color_number));
+ return PyLong_FromLong(COLOR_PAIR(pair_number));
}
/*[clinic input]
_curses.init_color
color_number: short
- The number of the color to be changed (0 - COLORS).
+ The number of the color to be changed (0 - (COLORS-1)).
r: short
Red component (0 - 1000).
g: short
When init_color() is used, all occurrences of that color on the screen
immediately change to the new definition. This function is a no-op on
-most terminals; it is active only if can_change_color() returns 1.
+most terminals; it is active only if can_change_color() returns true.
[clinic start generated code]*/
static PyObject *
_curses_init_color_impl(PyObject *module, short color_number, short r,
short g, short b)
-/*[clinic end generated code: output=280236f5efe9776a input=f3a05bd38f619175]*/
+/*[clinic end generated code: output=280236f5efe9776a input=128601b5dc76d548]*/
{
PyCursesInitialised;
PyCursesInitialisedColor;
pair_number: short
The number of the color-pair to be changed (1 - (COLOR_PAIRS-1)).
fg: short
- Foreground color number (0 - COLORS).
+ Foreground color number (-1 - (COLORS-1)).
bg: short
- Background color number (0 - COLORS).
+ Background color number (-1 - (COLORS-1)).
/
Change the definition of a color-pair.
static PyObject *
_curses_init_pair_impl(PyObject *module, short pair_number, short fg,
short bg)
-/*[clinic end generated code: output=9c2ce39c22f376b6 input=c9f0b11b17a2ac6d]*/
+/*[clinic end generated code: output=9c2ce39c22f376b6 input=12c320ec14396ea2]*/
{
PyCursesInitialised;
PyCursesInitialisedColor;
PyCursesInitialised;
PyCursesInitialisedColor;
- if (pair_content(pair_number, &f, &b)==ERR) {
- PyErr_SetString(PyCursesError,
- "Argument 1 was out of range. (1..COLOR_PAIRS-1)");
+ if (pair_content(pair_number, &f, &b) == ERR) {
+ if (pair_number >= COLOR_PAIRS) {
+ PyErr_SetString(PyCursesError,
+ "Argument 1 was out of range. (0..COLOR_PAIRS-1)");
+ }
+ else {
+ PyErr_SetString(PyCursesError, "pair_content() returned ERR");
+ }
return NULL;
}
PyCursesInitialised;
PyCursesInitialisedColor;
- return PyLong_FromLong(attr_to_color_pair(attr));
+ return PyLong_FromLong(PAIR_NUMBER(attr));
}
/*[clinic input]
#include "Python.h"
+#include "pycore_object.h" // _PyObject_GC_TRACK
#include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_tupleobject.h"
#include "structmember.h" // PyMemberDef
if ((result = PyObject_Call(func, args, NULL)) == NULL) {
goto Fail;
}
+ // bpo-42536: The GC may have untracked this args tuple. Since we're
+ // recycling it, make sure it's tracked again:
+ if (!_PyObject_GC_IS_TRACKED(args)) {
+ _PyObject_GC_TRACK(args);
+ }
}
}
# endif
#endif
-#if defined(__FreeBSD__) || (defined(__APPLE__) && defined(__MACH__))
+#if defined(__FreeBSD__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__DragonFly__)
# define FD_DIR "/dev/fd"
#else
# define FD_DIR "/proc/self/fd"
}
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(__DragonFly__)
/* When /dev/fd isn't mounted it is often a static directory populated
- * with 0 1 2 or entries for 0 .. 63 on FreeBSD, NetBSD and OpenBSD.
+ * with 0 1 2 or entries for 0 .. 63 on FreeBSD, NetBSD, OpenBSD and DragonFlyBSD.
* NetBSD and OpenBSD have a /proc fs available (though not necessarily
* mounted) and do not have fdescfs for /dev/fd. MacOS X has a devfs
* that properly supports /dev/fd.
++start_fd;
#endif
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(__DragonFly__)
if (!_is_fdescfs_mounted_on_dev_fd())
proc_fd_dir = NULL;
else
if (groups_list != Py_None) {
#ifdef HAVE_SETGROUPS
Py_ssize_t i;
- unsigned long gid;
+ gid_t gid;
if (!PyList_Check(groups_list)) {
PyErr_SetString(PyExc_TypeError,
Py_DECREF(elem);
goto cleanup;
} else {
- /* In posixmodule.c UnsignedLong is used as a fallback value
- * if the value provided does not fit in a Long. Since we are
- * already doing the bounds checking on the Python side, we
- * can go directly to an UnsignedLong here. */
if (!_Py_Gid_Converter(elem, &gid)) {
Py_DECREF(elem);
PyErr_SetString(PyExc_ValueError, "invalid group id");
(callable != Py_None) ? callable : NULL,
(callable != Py_None) ? pysqlite_collation_callback : NULL);
if (rc != SQLITE_OK) {
- PyDict_DelItem(self->collations, uppercase_name);
+ if (callable != Py_None) {
+ if (PyDict_DelItem(self->collations, uppercase_name) < 0) {
+ PyErr_Clear();
+ }
+ }
_pysqlite_seterror(self->db, NULL);
goto finally;
}
}
if (!multiple) {
- Py_DECREF(self->lastrowid);
Py_BEGIN_ALLOW_THREADS
lastrowid = sqlite3_last_insert_rowid(self->connection->db);
Py_END_ALLOW_THREADS
- self->lastrowid = PyLong_FromLongLong(lastrowid);
+ Py_SETREF(self->lastrowid, PyLong_FromLongLong(lastrowid));
+ if (self->lastrowid == NULL) {
+ goto error;
+ }
}
if (rc == SQLITE_ROW) {
}
while ((row = pysqlite_cursor_iternext(self))) {
- PyList_Append(list, row);
- Py_XDECREF(row);
+ if (PyList_Append(list, row) < 0) {
+ Py_DECREF(row);
+ break;
+ }
+ Py_DECREF(row);
if (++counter == maxrows) {
break;
}
while ((row = pysqlite_cursor_iternext(self))) {
- PyList_Append(list, row);
- Py_XDECREF(row);
+ if (PyList_Append(list, row) < 0) {
+ Py_DECREF(row);
+ break;
+ }
+ Py_DECREF(row);
}
if (PyErr_Occurred()) {
char *buf = NULL;
PyErr_Clear();
- /* Tcl encodes null character as \xc0\x80 */
+ /* Tcl encodes null character as \xc0\x80.
+ https://en.wikipedia.org/wiki/UTF-8#Modified_UTF-8 */
if (memchr(s, '\xc0', size)) {
char *q;
const char *e = s + size;
if (buf != NULL) {
PyMem_Free(buf);
}
+ if (r == NULL || PyUnicode_KIND(r) == PyUnicode_1BYTE_KIND) {
+ return r;
+ }
+
+ /* In CESU-8 non-BMP characters are represented as a surrogate pair,
+ like in UTF-16, and then each surrogate code point is encoded in UTF-8.
+ https://en.wikipedia.org/wiki/CESU-8 */
+ Py_ssize_t len = PyUnicode_GET_LENGTH(r);
+ Py_ssize_t i, j;
+ /* All encoded surrogate characters start with \xED. */
+ i = PyUnicode_FindChar(r, 0xdcED, 0, len, 1);
+ if (i == -2) {
+ Py_DECREF(r);
+ return NULL;
+ }
+ if (i == -1) {
+ return r;
+ }
+ Py_UCS4 *u = PyUnicode_AsUCS4Copy(r);
+ Py_DECREF(r);
+ if (u == NULL) {
+ return NULL;
+ }
+ Py_UCS4 ch;
+ for (j = i; i < len; i++, u[j++] = ch) {
+ Py_UCS4 ch1, ch2, ch3, high, low;
+ /* Low surrogates U+D800 - U+DBFF are encoded as
+ \xED\xA0\x80 - \xED\xAF\xBF. */
+ ch1 = ch = u[i];
+ if (ch1 != 0xdcED) continue;
+ ch2 = u[i + 1];
+ if (!(0xdcA0 <= ch2 && ch2 <= 0xdcAF)) continue;
+ ch3 = u[i + 2];
+ if (!(0xdc80 <= ch3 && ch3 <= 0xdcBF)) continue;
+ high = 0xD000 | ((ch2 & 0x3F) << 6) | (ch3 & 0x3F);
+ assert(Py_UNICODE_IS_HIGH_SURROGATE(high));
+ /* High surrogates U+DC00 - U+DFFF are encoded as
+ \xED\xB0\x80 - \xED\xBF\xBF. */
+ ch1 = u[i + 3];
+ if (ch1 != 0xdcED) continue;
+ ch2 = u[i + 4];
+ if (!(0xdcB0 <= ch2 && ch2 <= 0xdcBF)) continue;
+ ch3 = u[i + 5];
+ if (!(0xdc80 <= ch3 && ch3 <= 0xdcBF)) continue;
+ low = 0xD000 | ((ch2 & 0x3F) << 6) | (ch3 & 0x3F);
+ assert(Py_UNICODE_IS_HIGH_SURROGATE(high));
+ ch = Py_UNICODE_JOIN_SURROGATES(high, low);
+ i += 5;
+ }
+ r = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, u, j);
+ PyMem_Free(u);
return r;
}
static size_t
_bisect(const int64_t value, const int64_t *arr, size_t size);
-static void
+static int
eject_from_strong_cache(const PyTypeObject *const type, PyObject *key);
static void
clear_strong_cache(const PyTypeObject *const type);
update_strong_cache(const PyTypeObject *const type, PyObject *key,
PyObject *zone);
static PyObject *
-zone_from_strong_cache(const PyTypeObject *const type, PyObject *key);
+zone_from_strong_cache(const PyTypeObject *const type, PyObject *const key);
static PyObject *
zoneinfo_new_instance(PyTypeObject *type, PyObject *key)
}
PyObject *instance = zone_from_strong_cache(type, key);
- if (instance != NULL) {
+ if (instance != NULL || PyErr_Occurred()) {
return instance;
}
while ((item = PyIter_Next(iter))) {
// Remove from strong cache
- eject_from_strong_cache(type, item);
+ if (eject_from_strong_cache(type, item) < 0) {
+ Py_DECREF(item);
+ break;
+ }
// Remove from weak cache
PyObject *tmp = PyObject_CallMethodObjArgs(weak_cache, pop, item,
// Load the transition indices and list
self->trans_list_utc =
PyMem_Malloc(self->num_transitions * sizeof(int64_t));
+ if (self->trans_list_utc == NULL) {
+ goto error;
+ }
trans_idx = PyMem_Malloc(self->num_transitions * sizeof(Py_ssize_t));
+ if (trans_idx == NULL) {
+ goto error;
+ }
for (size_t i = 0; i < self->num_transitions; ++i) {
PyObject *num = PyTuple_GetItem(trans_utc, i);
// Build _ttinfo objects from utcoff, dstoff and abbr
self->_ttinfos = PyMem_Malloc(self->num_ttinfos * sizeof(_ttinfo));
+ if (self->_ttinfos == NULL) {
+ goto error;
+ }
for (size_t i = 0; i < self->num_ttinfos; ++i) {
PyObject *tzname = PyTuple_GetItem(abbr, i);
if (tzname == NULL) {
// Build our mapping from transition to the ttinfo that applies
self->trans_ttinfos =
PyMem_Calloc(self->num_transitions, sizeof(_ttinfo *));
+ if (self->trans_ttinfos == NULL) {
+ goto error;
+ }
for (size_t i = 0; i < self->num_transitions; ++i) {
size_t ttinfo_idx = trans_idx[i];
assert(ttinfo_idx < self->num_ttinfos);
return -1;
}
- // day is an unsigned integer, so day < 0 should always return false, but
- // if day's type changes to a signed integer *without* changing this value,
- // it may create a bug. Considering that the compiler should be able to
- // optimize out the first comparison if day is an unsigned integer anyway,
- // we will leave this comparison in place and disable the compiler warning.
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wtype-limits"
- if (day < 0 || day > 6) {
-#pragma GCC diagnostic pop
+ // If the 'day' parameter type is changed to a signed type,
+ // "day < 0" check must be added.
+ if (/* day < 0 || */ day > 6) {
PyErr_Format(PyExc_ValueError, "Day must be in [0, 6]");
return -1;
}
{
const StrongCacheNode *node = root;
while (node != NULL) {
- if (PyObject_RichCompareBool(key, node->key, Py_EQ)) {
+ int rv = PyObject_RichCompareBool(key, node->key, Py_EQ);
+ if (rv < 0) {
+ return NULL;
+ }
+ if (rv) {
return (StrongCacheNode *)node;
}
*
* This function is used to enable the per-key functionality in clear_cache.
*/
-static void
+static int
eject_from_strong_cache(const PyTypeObject *const type, PyObject *key)
{
if (type != &PyZoneInfo_ZoneInfoType) {
- return;
+ return 0;
}
StrongCacheNode *node = find_in_strong_cache(ZONEINFO_STRONG_CACHE, key);
strong_cache_node_free(node);
}
+ else if (PyErr_Occurred()) {
+ return -1;
+ }
+ return 0;
}
/* Moves a node to the front of the LRU cache.
return NULL;
}
- PyObject_SetAttrString((PyObject *)cls, "_weak_cache", weak_cache);
+ if (PyObject_SetAttrString((PyObject *)cls, "_weak_cache",
+ weak_cache) < 0) {
+ Py_DECREF(weak_cache);
+ return NULL;
+ }
Py_DECREF(weak_cache);
Py_RETURN_NONE;
}
zoneinfomodule_exec(PyObject *m)
{
PyDateTime_IMPORT;
+ if (PyDateTimeAPI == NULL) {
+ goto error;
+ }
PyZoneInfo_ZoneInfoType.tp_base = PyDateTimeAPI->TZInfoType;
if (PyType_Ready(&PyZoneInfo_ZoneInfoType) < 0) {
goto error;
"Return the red, green, and blue (RGB) components of the specified color.\n"
"\n"
" color_number\n"
-" The number of the color (0 - COLORS).\n"
+" The number of the color (0 - (COLORS-1)).\n"
"\n"
"A 3-tuple is returned, containing the R, G, B values for the given color,\n"
"which will be between 0 (no component) and 1000 (maximum amount of component).");
}
PyDoc_STRVAR(_curses_color_pair__doc__,
-"color_pair($module, color_number, /)\n"
+"color_pair($module, pair_number, /)\n"
"--\n"
"\n"
"Return the attribute value for displaying text in the specified color.\n"
"\n"
-" color_number\n"
-" The number of the color (0 - COLORS).\n"
+" pair_number\n"
+" The number of the color pair.\n"
"\n"
"This attribute value can be combined with A_STANDOUT, A_REVERSE, and the\n"
"other A_* attributes. pair_number() is the counterpart to this function.");
{"color_pair", (PyCFunction)_curses_color_pair, METH_O, _curses_color_pair__doc__},
static PyObject *
-_curses_color_pair_impl(PyObject *module, short color_number);
+_curses_color_pair_impl(PyObject *module, short pair_number);
static PyObject *
_curses_color_pair(PyObject *module, PyObject *arg)
{
PyObject *return_value = NULL;
- short color_number;
+ short pair_number;
if (PyFloat_Check(arg)) {
PyErr_SetString(PyExc_TypeError,
goto exit;
}
else {
- color_number = (short) ival;
+ pair_number = (short) ival;
}
}
- return_value = _curses_color_pair_impl(module, color_number);
+ return_value = _curses_color_pair_impl(module, pair_number);
exit:
return return_value;
"Change the definition of a color.\n"
"\n"
" color_number\n"
-" The number of the color to be changed (0 - COLORS).\n"
+" The number of the color to be changed (0 - (COLORS-1)).\n"
" r\n"
" Red component (0 - 1000).\n"
" g\n"
"\n"
"When init_color() is used, all occurrences of that color on the screen\n"
"immediately change to the new definition. This function is a no-op on\n"
-"most terminals; it is active only if can_change_color() returns 1.");
+"most terminals; it is active only if can_change_color() returns true.");
#define _CURSES_INIT_COLOR_METHODDEF \
{"init_color", (PyCFunction)(void(*)(void))_curses_init_color, METH_FASTCALL, _curses_init_color__doc__},
" pair_number\n"
" The number of the color-pair to be changed (1 - (COLOR_PAIRS-1)).\n"
" fg\n"
-" Foreground color number (0 - COLORS).\n"
+" Foreground color number (-1 - (COLORS-1)).\n"
" bg\n"
-" Background color number (0 - COLORS).\n"
+" Background color number (-1 - (COLORS-1)).\n"
"\n"
"If the color-pair was previously initialized, the screen is refreshed and\n"
"all occurrences of that color-pair are changed to the new definition.");
#ifndef _CURSES_USE_DEFAULT_COLORS_METHODDEF
#define _CURSES_USE_DEFAULT_COLORS_METHODDEF
#endif /* !defined(_CURSES_USE_DEFAULT_COLORS_METHODDEF) */
-/*[clinic end generated code: output=b53652f8acafd817 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=5e739120041df368 input=a9049054013a1b77]*/
#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "pycore_tupleobject.h"
+#include "pycore_object.h" // _PyObject_GC_TRACK()
#include <stddef.h> // offsetof()
/* Itertools module written and maintained
lz->result = result;
Py_DECREF(old_result);
}
+ // bpo-42536: The GC may have untracked this result tuple. Since we're
+ // recycling it, make sure it's tracked again:
+ else if (!_PyObject_GC_IS_TRACKED(result)) {
+ _PyObject_GC_TRACK(result);
+ }
/* Now, we've got the only copy so we can update it in-place */
assert (npools==0 || Py_REFCNT(result) == 1);
co->result = result;
Py_DECREF(old_result);
}
+ // bpo-42536: The GC may have untracked this result tuple. Since we're
+ // recycling it, make sure it's tracked again:
+ else if (!_PyObject_GC_IS_TRACKED(result)) {
+ _PyObject_GC_TRACK(result);
+ }
/* Now, we've got the only copy so we can update it in-place
* CPython's empty tuple is a singleton and cached in
* PyTuple's freelist.
co->result = result;
Py_DECREF(old_result);
}
+ // bpo-42536: The GC may have untracked this result tuple. Since we're
+ // recycling it, make sure it's tracked again:
+ else if (!_PyObject_GC_IS_TRACKED(result)) {
+ _PyObject_GC_TRACK(result);
+ }
/* Now, we've got the only copy so we can update it in-place CPython's
empty tuple is a singleton and cached in PyTuple's freelist. */
assert(r == 0 || Py_REFCNT(result) == 1);
po->result = result;
Py_DECREF(old_result);
}
+ // bpo-42536: The GC may have untracked this result tuple. Since we're
+ // recycling it, make sure it's tracked again:
+ else if (!_PyObject_GC_IS_TRACKED(result)) {
+ _PyObject_GC_TRACK(result);
+ }
/* Now, we've got the only copy so we can update it in-place */
assert(r == 0 || Py_REFCNT(result) == 1);
PyTuple_SET_ITEM(result, i, item);
Py_DECREF(olditem);
}
+ // bpo-42536: The GC may have untracked this result tuple. Since we're
+ // recycling it, make sure it's tracked again:
+ if (!_PyObject_GC_IS_TRACKED(result)) {
+ _PyObject_GC_TRACK(result);
+ }
} else {
result = PyTuple_New(tuplesize);
if (result == NULL)
* The library is free for all purposes without any express
* guarantee it works.
*
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ * Tom St Denis, tomstdenis@gmail.com, https://www.libtom.net
*/
/* rotate the hard way (platform optimizations could be done) */
*/
#if defined(__APPLE__)
-#if defined(__has_builtin) && __has_builtin(__builtin_available)
+#if defined(__has_builtin)
+#if __has_builtin(__builtin_available)
+#define HAVE_BUILTIN_AVAILABLE 1
+#endif
+#endif
+
+#ifdef HAVE_BUILTIN_AVAILABLE
# define HAVE_FSTATAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
# define HAVE_FACCESSAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
# define HAVE_FCHMODAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
}
int
-_Py_Uid_Converter(PyObject *obj, void *p)
+_Py_Uid_Converter(PyObject *obj, uid_t *p)
{
uid_t uid;
PyObject *index;
success:
Py_DECREF(index);
- *(uid_t *)p = uid;
+ *p = uid;
return 1;
underflow:
}
int
-_Py_Gid_Converter(PyObject *obj, void *p)
+_Py_Gid_Converter(PyObject *obj, gid_t *p)
{
gid_t gid;
PyObject *index;
success:
Py_DECREF(index);
- *(gid_t *)p = gid;
+ *p = gid;
return 1;
underflow:
#ifndef MS_WINDOWS
PyAPI_FUNC(PyObject *) _PyLong_FromUid(uid_t);
PyAPI_FUNC(PyObject *) _PyLong_FromGid(gid_t);
-PyAPI_FUNC(int) _Py_Uid_Converter(PyObject *, void *);
-PyAPI_FUNC(int) _Py_Gid_Converter(PyObject *, void *);
+PyAPI_FUNC(int) _Py_Uid_Converter(PyObject *, uid_t *);
+PyAPI_FUNC(int) _Py_Gid_Converter(PyObject *, gid_t *);
#endif /* MS_WINDOWS */
#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \
}
+/*
+Explicitly disable bracketed paste in the interactive interpreter, even if it's
+set in the inputrc, is enabled by default (eg GNU Readline 8.1), or a user calls
+readline.read_init_file(). The Python REPL has not implemented bracketed
+paste support. Also, bracketed mode writes the "\x1b[?2004h" escape sequence
+into stdout which causes test failures in applications that don't support it.
+It can still be explicitly enabled by calling readline.parse_and_bind("set
+enable-bracketed-paste on"). See bpo-42819 for more details.
+
+This should be removed if bracketed paste mode is implemented (bpo-39820).
+*/
+
+static void
+disable_bracketed_paste(void)
+{
+ if (!using_libedit_emulation) {
+ rl_variable_bind ("enable-bracketed-paste", "off");
+ }
+}
+
/* Exported function to send one line to readline's init file parser */
static PyObject *
errno = rl_read_init_file(NULL);
if (errno)
return PyErr_SetFromErrno(PyExc_OSError);
+ disable_bracketed_paste();
Py_RETURN_NONE;
}
else
rl_initialize();
+ disable_bracketed_paste();
+
RESTORE_LOCALE(saved_locale)
return 0;
}
* The library is free for all purposes without any express
* guarantee it works.
*
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ * Tom St Denis, tomstdenis@gmail.com, https://www.libtom.net
*/
/* rotate the hard way (platform optimizations could be done) */
* The library is free for all purposes without any express
* guarantee it works.
*
- * Tom St Denis, tomstdenis@iahu.ca, http://libtom.org
+ * Tom St Denis, tomstdenis@iahu.ca, https://www.libtom.net
*/
* The library is free for all purposes without any express
* guarantee it works.
*
- * Tom St Denis, tomstdenis@iahu.ca, http://libtom.org
+ * Tom St Denis, tomstdenis@iahu.ca, https://www.libtom.net
*/
PyDoc_STRVAR(getsockname_doc,
"getsockname() -> address info\n\
\n\
-Return the address of the local endpoint. For IP sockets, the address\n\
-info is a pair (hostaddr, port).");
+Return the address of the local endpoint. The format depends on the\n\
+address family. For IPv4 sockets, the address info is a pair\n\
+(hostaddr, port).");
#ifdef HAVE_GETPEERNAME /* Cray APP doesn't have this :-( */
PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs)
{
PyThreadState *tstate = _PyThreadState_GET();
+ vectorcallfunc func;
/* get vectorcallfunc as in PyVectorcall_Function, but without
* the Py_TPFLAGS_HAVE_VECTORCALL check */
Py_TYPE(callable)->tp_name);
return NULL;
}
- vectorcallfunc func = *(vectorcallfunc *)(((char *)callable) + offset);
+ memcpy(&func, (char *) callable + offset, sizeof(func));
if (func == NULL) {
_PyErr_Format(tstate, PyExc_TypeError,
"'%.200s' object does not support vectorcall",
Py_INCREF(result);
Py_DECREF(oldkey);
Py_DECREF(oldvalue);
+ // bpo-42536: The GC may have untracked this result tuple. Since we're
+ // recycling it, make sure it's tracked again:
+ if (!_PyObject_GC_IS_TRACKED(result)) {
+ _PyObject_GC_TRACK(result);
+ }
}
else {
result = PyTuple_New(2);
Py_INCREF(result);
Py_DECREF(oldkey);
Py_DECREF(oldvalue);
+ // bpo-42536: The GC may have untracked this result tuple. Since
+ // we're recycling it, make sure it's tracked again:
+ if (!_PyObject_GC_IS_TRACKED(result)) {
+ _PyObject_GC_TRACK(result);
+ }
}
else {
result = PyTuple_New(2);
/* enumerate object */
#include "Python.h"
+#include "pycore_object.h" // _PyObject_GC_TRACK()
#include "clinic/enumobject.c.h"
PyTuple_SET_ITEM(result, 1, next_item);
Py_DECREF(old_index);
Py_DECREF(old_item);
+ // bpo-42536: The GC may have untracked this result tuple. Since we're
+ // recycling it, make sure it's tracked again:
+ if (!_PyObject_GC_IS_TRACKED(result)) {
+ _PyObject_GC_TRACK(result);
+ }
return result;
}
result = PyTuple_New(2);
PyTuple_SET_ITEM(result, 1, next_item);
Py_DECREF(old_index);
Py_DECREF(old_item);
+ // bpo-42536: The GC may have untracked this result tuple. Since we're
+ // recycling it, make sure it's tracked again:
+ if (!_PyObject_GC_IS_TRACKED(result)) {
+ _PyObject_GC_TRACK(result);
+ }
return result;
}
result = PyTuple_New(2);
do { \
PyObject *_code = PyLong_FromLong(CODE); \
assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
- if (!_code || PyDict_SetItem(errnomap, _code, PyExc_ ## TYPE)) \
+ if (!_code || PyDict_SetItem(errnomap, _code, PyExc_ ## TYPE)) { \
+ Py_XDECREF(_code); \
return _PyStatus_ERR("errmap insertion problem."); \
+ } \
Py_DECREF(_code); \
} while (0)
static PyObject *
ga_richcompare(PyObject *a, PyObject *b, int op)
{
- if (!Py_IS_TYPE(a, &Py_GenericAliasType) ||
- !Py_IS_TYPE(b, &Py_GenericAliasType) ||
+ if (!PyObject_TypeCheck(a, &Py_GenericAliasType) ||
+ !PyObject_TypeCheck(b, &Py_GenericAliasType) ||
(op != Py_EQ && op != Py_NE))
{
Py_RETURN_NOTIMPLEMENTED;
{0}
};
+/* A helper function to create GenericAlias' args tuple and set its attributes.
+ * Returns 1 on success, 0 on failure.
+ */
+static inline int
+setup_ga(gaobject *alias, PyObject *origin, PyObject *args) {
+ if (!PyTuple_Check(args)) {
+ args = PyTuple_Pack(1, args);
+ if (args == NULL) {
+ return 0;
+ }
+ }
+ else {
+ Py_INCREF(args);
+ }
+
+ Py_INCREF(origin);
+ alias->origin = origin;
+ alias->args = args;
+ alias->parameters = NULL;
+ alias->weakreflist = NULL;
+ return 1;
+}
+
static PyObject *
ga_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
}
PyObject *origin = PyTuple_GET_ITEM(args, 0);
PyObject *arguments = PyTuple_GET_ITEM(args, 1);
- return Py_GenericAlias(origin, arguments);
+ gaobject *self = (gaobject *)type->tp_alloc(type, 0);
+ if (self == NULL) {
+ return NULL;
+ }
+ if (!setup_ga(self, origin, arguments)) {
+ type->tp_free((PyObject *)self);
+ return NULL;
+ }
+ return (PyObject *)self;
}
// TODO:
.tp_hash = ga_hash,
.tp_call = ga_call,
.tp_getattro = ga_getattro,
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
.tp_traverse = ga_traverse,
.tp_richcompare = ga_richcompare,
.tp_weaklistoffset = offsetof(gaobject, weakreflist),
PyObject *
Py_GenericAlias(PyObject *origin, PyObject *args)
{
- if (!PyTuple_Check(args)) {
- args = PyTuple_Pack(1, args);
- if (args == NULL) {
- return NULL;
- }
- }
- else {
- Py_INCREF(args);
- }
-
gaobject *alias = PyObject_GC_New(gaobject, &Py_GenericAliasType);
if (alias == NULL) {
- Py_DECREF(args);
return NULL;
}
-
- Py_INCREF(origin);
- alias->origin = origin;
- alias->args = args;
- alias->parameters = NULL;
- alias->weakreflist = NULL;
+ if (!setup_ga(alias, origin, args)) {
+ PyObject_GC_Del((PyObject *)alias);
+ return NULL;
+ }
_PyObject_GC_TRACK(alias);
return (PyObject *)alias;
}
Py_INCREF(result);
Py_DECREF(PyTuple_GET_ITEM(result, 0)); /* borrowed */
Py_DECREF(PyTuple_GET_ITEM(result, 1)); /* borrowed */
+ // bpo-42536: The GC may have untracked this result tuple. Since we're
+ // recycling it, make sure it's tracked again:
+ if (!_PyObject_GC_IS_TRACKED(result)) {
+ _PyObject_GC_TRACK(result);
+ }
}
else {
result = PyTuple_New(2);
PyCFunction_GetSelf=python39.PyCFunction_GetSelf
PyCFunction_New=python39.PyCFunction_New
PyCFunction_NewEx=python39.PyCFunction_NewEx
+ PyCMethod_New=python39.PyCMethod_New
PyCFunction_Type=python39.PyCFunction_Type DATA
PyCallIter_New=python39.PyCallIter_New
PyCallIter_Type=python39.PyCallIter_Type DATA
PyFloat_GetMax=python39.PyFloat_GetMax
PyFloat_GetMin=python39.PyFloat_GetMin
PyFloat_Type=python39.PyFloat_Type DATA
+ PyFrame_GetCode=python39.PyFrame_GetCode
+ PyFrame_GetLineNumber=python39.PyFrame_GetLineNumber
PyFrozenSet_New=python39.PyFrozenSet_New
PyFrozenSet_Type=python39.PyFrozenSet_Type DATA
PyGC_Collect=python39.PyGC_Collect
PyObject_CallFunctionObjArgs=python39.PyObject_CallFunctionObjArgs
PyObject_CallMethod=python39.PyObject_CallMethod
PyObject_CallMethodObjArgs=python39.PyObject_CallMethodObjArgs
+ PyObject_CallNoArgs=python39.PyObject_CallNoArgs
PyObject_CallObject=python39.PyObject_CallObject
PyObject_Calloc=python39.PyObject_Calloc
PyObject_CheckReadBuffer=python39.PyObject_CheckReadBuffer
PyThreadState_DeleteCurrent=python39.PyThreadState_DeleteCurrent
PyThreadState_Get=python39.PyThreadState_Get
PyThreadState_GetDict=python39.PyThreadState_GetDict
+ PyThreadState_GetFrame=python39.PyThreadState_GetFrame
+ PyThreadState_GetID=python39.PyThreadState_GetID
+ PyThreadState_GetInterpreter=python39.PyThreadState_GetInterpreter
PyThreadState_New=python39.PyThreadState_New
PyThreadState_SetAsyncExc=python39.PyThreadState_SetAsyncExc
PyThreadState_Swap=python39.PyThreadState_Swap
#include "winver.h"
#define PYTHON_COMPANY "Python Software Foundation"
-#define PYTHON_COPYRIGHT "Copyright \xA9 2001-2016 Python Software Foundation. Copyright \xA9 2000 BeOpen.com. Copyright \xA9 1995-2001 CNRI. Copyright \xA9 1991-1995 SMC."
+#define PYTHON_COPYRIGHT "Copyright \xA9 2001-2021 Python Software Foundation. Copyright \xA9 2000 BeOpen.com. Copyright \xA9 1995-2001 CNRI. Copyright \xA9 1991-1995 SMC."
#define MS_WINDOWS
#include "modsupport.h"
set libraries=\r
set libraries=%libraries% bzip2-1.0.6\r
if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi\r
-if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1g\r
-set libraries=%libraries% sqlite-3.33.0.0\r
+if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1i\r
+set libraries=%libraries% sqlite-3.34.0.0\r
if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.9.0\r
if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.9.0\r
if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tix-8.4.3.6\r
\r
set binaries=\r
if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi\r
-if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1g\r
+if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1i\r
if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.9.0\r
if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06\r
\r
<WholeProgramOptimization>true</WholeProgramOptimization>\r
<InlineFunctionExpansion Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OnlyExplicitInline</InlineFunctionExpansion>\r
<InlineFunctionExpansion Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OnlyExplicitInline</InlineFunctionExpansion>\r
+ <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>\r
</ClCompile>\r
<ClCompile Condition="$(Configuration) == 'Debug'">\r
<Optimization>Disabled</Optimization>\r
<ExternalsDir>$(EXTERNALS_DIR)</ExternalsDir>\r
<ExternalsDir Condition="$(ExternalsDir) == ''">$([System.IO.Path]::GetFullPath(`$(PySourcePath)externals`))</ExternalsDir>\r
<ExternalsDir Condition="!HasTrailingSlash($(ExternalsDir))">$(ExternalsDir)\</ExternalsDir>\r
- <sqlite3Dir>$(ExternalsDir)sqlite-3.33.0.0\</sqlite3Dir>\r
+ <sqlite3Dir>$(ExternalsDir)sqlite-3.34.0.0\</sqlite3Dir>\r
<bz2Dir>$(ExternalsDir)bzip2-1.0.6\</bz2Dir>\r
<lzmaDir>$(ExternalsDir)xz-5.2.2\</lzmaDir>\r
<libffiDir>$(ExternalsDir)libffi\</libffiDir>\r
<libffiOutDir>$(ExternalsDir)libffi\$(ArchName)\</libffiOutDir>\r
<libffiIncludeDir>$(libffiOutDir)include</libffiIncludeDir>\r
- <opensslDir>$(ExternalsDir)openssl-1.1.1g\</opensslDir>\r
- <opensslOutDir>$(ExternalsDir)openssl-bin-1.1.1g\$(ArchName)\</opensslOutDir>\r
+ <opensslDir>$(ExternalsDir)openssl-1.1.1i\</opensslDir>\r
+ <opensslOutDir>$(ExternalsDir)openssl-bin-1.1.1i\$(ArchName)\</opensslOutDir>\r
<opensslIncludeDir>$(opensslOutDir)include</opensslIncludeDir>\r
<nasmDir>$(ExternalsDir)\nasm-2.11.06\</nasmDir>\r
<zlibDir>$(ExternalsDir)\zlib-1.2.11\</zlibDir>\r
Homepage:\r
http://tukaani.org/xz/\r
_ssl\r
- Python wrapper for version 1.1.1c of the OpenSSL secure sockets\r
+ Python wrapper for version 1.1.1i of the OpenSSL secure sockets\r
library, which is downloaded from our binaries repository at\r
https://github.com/python/cpython-bin-deps.\r
\r
again when building.\r
\r
_sqlite3\r
- Wraps SQLite 3.33.0, which is itself built by sqlite3.vcxproj\r
+ Wraps SQLite 3.34.0, which is itself built by sqlite3.vcxproj\r
Homepage:\r
http://www.sqlite.org/\r
_tkinter\r
#define kwarg_or_starred_type 1126
#define kwarg_or_double_starred_type 1127
#define star_targets_type 1128
-#define star_targets_seq_type 1129
-#define star_target_type 1130
-#define star_atom_type 1131
-#define single_target_type 1132
-#define single_subscript_attribute_target_type 1133
-#define del_targets_type 1134
-#define del_target_type 1135
-#define del_t_atom_type 1136
-#define targets_type 1137
-#define target_type 1138
-#define t_primary_type 1139 // Left-recursive
-#define t_lookahead_type 1140
-#define t_atom_type 1141
-#define invalid_arguments_type 1142
-#define invalid_kwarg_type 1143
-#define invalid_named_expression_type 1144
-#define invalid_assignment_type 1145
-#define invalid_ann_assign_target_type 1146
-#define invalid_del_stmt_type 1147
-#define invalid_block_type 1148
-#define invalid_primary_type 1149 // Left-recursive
-#define invalid_comprehension_type 1150
-#define invalid_dict_comprehension_type 1151
-#define invalid_parameters_type 1152
-#define invalid_lambda_parameters_type 1153
-#define invalid_star_etc_type 1154
-#define invalid_lambda_star_etc_type 1155
-#define invalid_double_type_comments_type 1156
-#define invalid_with_item_type 1157
-#define invalid_for_target_type 1158
-#define invalid_group_type 1159
-#define invalid_import_from_targets_type 1160
-#define _loop0_1_type 1161
-#define _loop0_2_type 1162
-#define _loop0_4_type 1163
-#define _gather_3_type 1164
-#define _loop0_6_type 1165
-#define _gather_5_type 1166
-#define _loop0_8_type 1167
-#define _gather_7_type 1168
-#define _loop0_10_type 1169
-#define _gather_9_type 1170
-#define _loop1_11_type 1171
-#define _loop0_13_type 1172
-#define _gather_12_type 1173
-#define _tmp_14_type 1174
-#define _tmp_15_type 1175
-#define _tmp_16_type 1176
-#define _tmp_17_type 1177
-#define _tmp_18_type 1178
-#define _tmp_19_type 1179
-#define _tmp_20_type 1180
-#define _tmp_21_type 1181
-#define _loop1_22_type 1182
-#define _tmp_23_type 1183
-#define _tmp_24_type 1184
-#define _loop0_26_type 1185
-#define _gather_25_type 1186
-#define _loop0_28_type 1187
-#define _gather_27_type 1188
-#define _tmp_29_type 1189
-#define _tmp_30_type 1190
-#define _loop0_31_type 1191
-#define _loop1_32_type 1192
-#define _loop0_34_type 1193
-#define _gather_33_type 1194
-#define _tmp_35_type 1195
-#define _loop0_37_type 1196
-#define _gather_36_type 1197
-#define _tmp_38_type 1198
-#define _loop0_40_type 1199
-#define _gather_39_type 1200
-#define _loop0_42_type 1201
-#define _gather_41_type 1202
-#define _loop0_44_type 1203
-#define _gather_43_type 1204
-#define _loop0_46_type 1205
-#define _gather_45_type 1206
-#define _tmp_47_type 1207
-#define _loop1_48_type 1208
-#define _tmp_49_type 1209
-#define _tmp_50_type 1210
-#define _tmp_51_type 1211
-#define _tmp_52_type 1212
-#define _tmp_53_type 1213
-#define _loop0_54_type 1214
-#define _loop0_55_type 1215
-#define _loop0_56_type 1216
-#define _loop1_57_type 1217
-#define _loop0_58_type 1218
-#define _loop1_59_type 1219
-#define _loop1_60_type 1220
-#define _loop1_61_type 1221
-#define _loop0_62_type 1222
-#define _loop1_63_type 1223
-#define _loop0_64_type 1224
-#define _loop1_65_type 1225
-#define _loop0_66_type 1226
-#define _loop1_67_type 1227
-#define _loop1_68_type 1228
-#define _tmp_69_type 1229
-#define _loop1_70_type 1230
-#define _loop0_72_type 1231
-#define _gather_71_type 1232
-#define _loop1_73_type 1233
-#define _loop0_74_type 1234
-#define _loop0_75_type 1235
-#define _loop0_76_type 1236
-#define _loop1_77_type 1237
-#define _loop0_78_type 1238
-#define _loop1_79_type 1239
-#define _loop1_80_type 1240
-#define _loop1_81_type 1241
-#define _loop0_82_type 1242
-#define _loop1_83_type 1243
-#define _loop0_84_type 1244
-#define _loop1_85_type 1245
-#define _loop0_86_type 1246
-#define _loop1_87_type 1247
-#define _loop1_88_type 1248
-#define _loop1_89_type 1249
-#define _loop1_90_type 1250
-#define _tmp_91_type 1251
-#define _loop0_93_type 1252
-#define _gather_92_type 1253
-#define _tmp_94_type 1254
-#define _tmp_95_type 1255
-#define _tmp_96_type 1256
-#define _tmp_97_type 1257
-#define _loop1_98_type 1258
-#define _tmp_99_type 1259
-#define _tmp_100_type 1260
-#define _loop0_102_type 1261
-#define _gather_101_type 1262
-#define _loop1_103_type 1263
-#define _loop0_104_type 1264
-#define _loop0_105_type 1265
-#define _loop0_107_type 1266
-#define _gather_106_type 1267
-#define _tmp_108_type 1268
-#define _loop0_110_type 1269
-#define _gather_109_type 1270
-#define _loop0_112_type 1271
-#define _gather_111_type 1272
-#define _loop0_114_type 1273
-#define _gather_113_type 1274
-#define _loop0_116_type 1275
-#define _gather_115_type 1276
-#define _loop0_117_type 1277
-#define _loop0_119_type 1278
-#define _gather_118_type 1279
-#define _tmp_120_type 1280
-#define _loop0_122_type 1281
-#define _gather_121_type 1282
-#define _loop0_124_type 1283
-#define _gather_123_type 1284
-#define _tmp_125_type 1285
-#define _loop0_126_type 1286
-#define _loop0_127_type 1287
-#define _loop0_128_type 1288
-#define _tmp_129_type 1289
-#define _tmp_130_type 1290
-#define _loop0_131_type 1291
-#define _tmp_132_type 1292
-#define _loop0_133_type 1293
-#define _tmp_134_type 1294
-#define _tmp_135_type 1295
-#define _tmp_136_type 1296
-#define _tmp_137_type 1297
-#define _tmp_138_type 1298
-#define _tmp_139_type 1299
-#define _tmp_140_type 1300
-#define _tmp_141_type 1301
-#define _tmp_142_type 1302
-#define _tmp_143_type 1303
-#define _tmp_144_type 1304
-#define _tmp_145_type 1305
-#define _tmp_146_type 1306
-#define _tmp_147_type 1307
-#define _tmp_148_type 1308
-#define _tmp_149_type 1309
-#define _tmp_150_type 1310
-#define _loop1_151_type 1311
-#define _loop1_152_type 1312
-#define _tmp_153_type 1313
-#define _tmp_154_type 1314
+#define star_targets_list_seq_type 1129
+#define star_targets_tuple_seq_type 1130
+#define star_target_type 1131
+#define target_with_star_atom_type 1132
+#define star_atom_type 1133
+#define single_target_type 1134
+#define single_subscript_attribute_target_type 1135
+#define del_targets_type 1136
+#define del_target_type 1137
+#define del_t_atom_type 1138
+#define targets_type 1139
+#define target_type 1140
+#define t_primary_type 1141 // Left-recursive
+#define t_lookahead_type 1142
+#define t_atom_type 1143
+#define invalid_arguments_type 1144
+#define invalid_kwarg_type 1145
+#define invalid_named_expression_type 1146
+#define invalid_assignment_type 1147
+#define invalid_ann_assign_target_type 1148
+#define invalid_del_stmt_type 1149
+#define invalid_block_type 1150
+#define invalid_primary_type 1151 // Left-recursive
+#define invalid_comprehension_type 1152
+#define invalid_dict_comprehension_type 1153
+#define invalid_parameters_type 1154
+#define invalid_lambda_parameters_type 1155
+#define invalid_star_etc_type 1156
+#define invalid_lambda_star_etc_type 1157
+#define invalid_double_type_comments_type 1158
+#define invalid_with_item_type 1159
+#define invalid_for_target_type 1160
+#define invalid_group_type 1161
+#define invalid_import_from_targets_type 1162
+#define _loop0_1_type 1163
+#define _loop0_2_type 1164
+#define _loop0_4_type 1165
+#define _gather_3_type 1166
+#define _loop0_6_type 1167
+#define _gather_5_type 1168
+#define _loop0_8_type 1169
+#define _gather_7_type 1170
+#define _loop0_10_type 1171
+#define _gather_9_type 1172
+#define _loop1_11_type 1173
+#define _loop0_13_type 1174
+#define _gather_12_type 1175
+#define _tmp_14_type 1176
+#define _tmp_15_type 1177
+#define _tmp_16_type 1178
+#define _tmp_17_type 1179
+#define _tmp_18_type 1180
+#define _tmp_19_type 1181
+#define _tmp_20_type 1182
+#define _tmp_21_type 1183
+#define _loop1_22_type 1184
+#define _tmp_23_type 1185
+#define _tmp_24_type 1186
+#define _loop0_26_type 1187
+#define _gather_25_type 1188
+#define _loop0_28_type 1189
+#define _gather_27_type 1190
+#define _tmp_29_type 1191
+#define _tmp_30_type 1192
+#define _loop0_31_type 1193
+#define _loop1_32_type 1194
+#define _loop0_34_type 1195
+#define _gather_33_type 1196
+#define _tmp_35_type 1197
+#define _loop0_37_type 1198
+#define _gather_36_type 1199
+#define _tmp_38_type 1200
+#define _loop0_40_type 1201
+#define _gather_39_type 1202
+#define _loop0_42_type 1203
+#define _gather_41_type 1204
+#define _loop0_44_type 1205
+#define _gather_43_type 1206
+#define _loop0_46_type 1207
+#define _gather_45_type 1208
+#define _tmp_47_type 1209
+#define _loop1_48_type 1210
+#define _tmp_49_type 1211
+#define _tmp_50_type 1212
+#define _tmp_51_type 1213
+#define _tmp_52_type 1214
+#define _tmp_53_type 1215
+#define _loop0_54_type 1216
+#define _loop0_55_type 1217
+#define _loop0_56_type 1218
+#define _loop1_57_type 1219
+#define _loop0_58_type 1220
+#define _loop1_59_type 1221
+#define _loop1_60_type 1222
+#define _loop1_61_type 1223
+#define _loop0_62_type 1224
+#define _loop1_63_type 1225
+#define _loop0_64_type 1226
+#define _loop1_65_type 1227
+#define _loop0_66_type 1228
+#define _loop1_67_type 1229
+#define _loop1_68_type 1230
+#define _tmp_69_type 1231
+#define _loop1_70_type 1232
+#define _loop0_72_type 1233
+#define _gather_71_type 1234
+#define _loop1_73_type 1235
+#define _loop0_74_type 1236
+#define _loop0_75_type 1237
+#define _loop0_76_type 1238
+#define _loop1_77_type 1239
+#define _loop0_78_type 1240
+#define _loop1_79_type 1241
+#define _loop1_80_type 1242
+#define _loop1_81_type 1243
+#define _loop0_82_type 1244
+#define _loop1_83_type 1245
+#define _loop0_84_type 1246
+#define _loop1_85_type 1247
+#define _loop0_86_type 1248
+#define _loop1_87_type 1249
+#define _loop1_88_type 1250
+#define _loop1_89_type 1251
+#define _loop1_90_type 1252
+#define _tmp_91_type 1253
+#define _loop0_93_type 1254
+#define _gather_92_type 1255
+#define _tmp_94_type 1256
+#define _tmp_95_type 1257
+#define _tmp_96_type 1258
+#define _tmp_97_type 1259
+#define _loop1_98_type 1260
+#define _tmp_99_type 1261
+#define _tmp_100_type 1262
+#define _loop0_102_type 1263
+#define _gather_101_type 1264
+#define _loop1_103_type 1265
+#define _loop0_104_type 1266
+#define _loop0_105_type 1267
+#define _loop0_107_type 1268
+#define _gather_106_type 1269
+#define _tmp_108_type 1270
+#define _loop0_110_type 1271
+#define _gather_109_type 1272
+#define _loop0_112_type 1273
+#define _gather_111_type 1274
+#define _loop0_114_type 1275
+#define _gather_113_type 1276
+#define _loop0_116_type 1277
+#define _gather_115_type 1278
+#define _loop0_117_type 1279
+#define _loop0_119_type 1280
+#define _gather_118_type 1281
+#define _loop1_120_type 1282
+#define _tmp_121_type 1283
+#define _loop0_123_type 1284
+#define _gather_122_type 1285
+#define _loop0_125_type 1286
+#define _gather_124_type 1287
+#define _tmp_126_type 1288
+#define _loop0_127_type 1289
+#define _loop0_128_type 1290
+#define _loop0_129_type 1291
+#define _tmp_130_type 1292
+#define _tmp_131_type 1293
+#define _loop0_132_type 1294
+#define _tmp_133_type 1295
+#define _loop0_134_type 1296
+#define _tmp_135_type 1297
+#define _tmp_136_type 1298
+#define _tmp_137_type 1299
+#define _tmp_138_type 1300
+#define _tmp_139_type 1301
+#define _tmp_140_type 1302
+#define _tmp_141_type 1303
+#define _tmp_142_type 1304
+#define _tmp_143_type 1305
+#define _tmp_144_type 1306
+#define _tmp_145_type 1307
+#define _tmp_146_type 1308
+#define _tmp_147_type 1309
+#define _tmp_148_type 1310
+#define _tmp_149_type 1311
+#define _tmp_150_type 1312
+#define _tmp_151_type 1313
+#define _tmp_152_type 1314
+#define _loop1_153_type 1315
+#define _loop1_154_type 1316
+#define _tmp_155_type 1317
+#define _tmp_156_type 1318
static mod_ty file_rule(Parser *p);
static mod_ty interactive_rule(Parser *p);
static KeywordOrStarred* kwarg_or_starred_rule(Parser *p);
static KeywordOrStarred* kwarg_or_double_starred_rule(Parser *p);
static expr_ty star_targets_rule(Parser *p);
-static asdl_seq* star_targets_seq_rule(Parser *p);
+static asdl_seq* star_targets_list_seq_rule(Parser *p);
+static asdl_seq* star_targets_tuple_seq_rule(Parser *p);
static expr_ty star_target_rule(Parser *p);
+static expr_ty target_with_star_atom_rule(Parser *p);
static expr_ty star_atom_rule(Parser *p);
static expr_ty single_target_rule(Parser *p);
static expr_ty single_subscript_attribute_target_rule(Parser *p);
static asdl_seq *_loop0_117_rule(Parser *p);
static asdl_seq *_loop0_119_rule(Parser *p);
static asdl_seq *_gather_118_rule(Parser *p);
-static void *_tmp_120_rule(Parser *p);
-static asdl_seq *_loop0_122_rule(Parser *p);
-static asdl_seq *_gather_121_rule(Parser *p);
-static asdl_seq *_loop0_124_rule(Parser *p);
-static asdl_seq *_gather_123_rule(Parser *p);
-static void *_tmp_125_rule(Parser *p);
-static asdl_seq *_loop0_126_rule(Parser *p);
+static asdl_seq *_loop1_120_rule(Parser *p);
+static void *_tmp_121_rule(Parser *p);
+static asdl_seq *_loop0_123_rule(Parser *p);
+static asdl_seq *_gather_122_rule(Parser *p);
+static asdl_seq *_loop0_125_rule(Parser *p);
+static asdl_seq *_gather_124_rule(Parser *p);
+static void *_tmp_126_rule(Parser *p);
static asdl_seq *_loop0_127_rule(Parser *p);
static asdl_seq *_loop0_128_rule(Parser *p);
-static void *_tmp_129_rule(Parser *p);
+static asdl_seq *_loop0_129_rule(Parser *p);
static void *_tmp_130_rule(Parser *p);
-static asdl_seq *_loop0_131_rule(Parser *p);
-static void *_tmp_132_rule(Parser *p);
-static asdl_seq *_loop0_133_rule(Parser *p);
-static void *_tmp_134_rule(Parser *p);
+static void *_tmp_131_rule(Parser *p);
+static asdl_seq *_loop0_132_rule(Parser *p);
+static void *_tmp_133_rule(Parser *p);
+static asdl_seq *_loop0_134_rule(Parser *p);
static void *_tmp_135_rule(Parser *p);
static void *_tmp_136_rule(Parser *p);
static void *_tmp_137_rule(Parser *p);
static void *_tmp_148_rule(Parser *p);
static void *_tmp_149_rule(Parser *p);
static void *_tmp_150_rule(Parser *p);
-static asdl_seq *_loop1_151_rule(Parser *p);
-static asdl_seq *_loop1_152_rule(Parser *p);
-static void *_tmp_153_rule(Parser *p);
-static void *_tmp_154_rule(Parser *p);
+static void *_tmp_151_rule(Parser *p);
+static void *_tmp_152_rule(Parser *p);
+static asdl_seq *_loop1_153_rule(Parser *p);
+static asdl_seq *_loop1_154_rule(Parser *p);
+static void *_tmp_155_rule(Parser *p);
+static void *_tmp_156_rule(Parser *p);
// file: statements? $
return _res;
}
-// star_targets_seq: ','.star_target+ ','?
+// star_targets_list_seq: ','.star_target+ ','?
static asdl_seq*
-star_targets_seq_rule(Parser *p)
+star_targets_list_seq_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> star_targets_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.star_target+ ','?"));
+ D(fprintf(stderr, "%*c> star_targets_list_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.star_target+ ','?"));
void *_opt_var;
UNUSED(_opt_var); // Silence compiler warnings
asdl_seq * a;
(_opt_var = _PyPegen_expect_token(p, 12), 1) // ','?
)
{
- D(fprintf(stderr, "%*c+ star_targets_seq[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.star_target+ ','?"));
+ D(fprintf(stderr, "%*c+ star_targets_list_seq[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.star_target+ ','?"));
_res = a;
if (_res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s star_targets_seq[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s star_targets_list_seq[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.star_target+ ','?"));
}
_res = NULL;
return _res;
}
-// star_target:
-// | '*' (!'*' star_target)
-// | t_primary '.' NAME !t_lookahead
-// | t_primary '[' slices ']' !t_lookahead
-// | star_atom
+// star_targets_tuple_seq: star_target ((',' star_target))+ ','? | star_target ','
+static asdl_seq*
+star_targets_tuple_seq_rule(Parser *p)
+{
+ D(p->level++);
+ if (p->error_indicator) {
+ D(p->level--);
+ return NULL;
+ }
+ asdl_seq* _res = NULL;
+ int _mark = p->mark;
+ { // star_target ((',' star_target))+ ','?
+ if (p->error_indicator) {
+ D(p->level--);
+ return NULL;
+ }
+ D(fprintf(stderr, "%*c> star_targets_tuple_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target ((',' star_target))+ ','?"));
+ void *_opt_var;
+ UNUSED(_opt_var); // Silence compiler warnings
+ expr_ty a;
+ asdl_seq * b;
+ if (
+ (a = star_target_rule(p)) // star_target
+ &&
+ (b = _loop1_120_rule(p)) // ((',' star_target))+
+ &&
+ (_opt_var = _PyPegen_expect_token(p, 12), 1) // ','?
+ )
+ {
+ D(fprintf(stderr, "%*c+ star_targets_tuple_seq[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target ((',' star_target))+ ','?"));
+ _res = _PyPegen_seq_insert_in_front ( p , a , b );
+ if (_res == NULL && PyErr_Occurred()) {
+ p->error_indicator = 1;
+ D(p->level--);
+ return NULL;
+ }
+ goto done;
+ }
+ p->mark = _mark;
+ D(fprintf(stderr, "%*c%s star_targets_tuple_seq[%d-%d]: %s failed!\n", p->level, ' ',
+ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target ((',' star_target))+ ','?"));
+ }
+ { // star_target ','
+ if (p->error_indicator) {
+ D(p->level--);
+ return NULL;
+ }
+ D(fprintf(stderr, "%*c> star_targets_tuple_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target ','"));
+ Token * _literal;
+ expr_ty a;
+ if (
+ (a = star_target_rule(p)) // star_target
+ &&
+ (_literal = _PyPegen_expect_token(p, 12)) // token=','
+ )
+ {
+ D(fprintf(stderr, "%*c+ star_targets_tuple_seq[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target ','"));
+ _res = _PyPegen_singleton_seq ( p , a );
+ if (_res == NULL && PyErr_Occurred()) {
+ p->error_indicator = 1;
+ D(p->level--);
+ return NULL;
+ }
+ goto done;
+ }
+ p->mark = _mark;
+ D(fprintf(stderr, "%*c%s star_targets_tuple_seq[%d-%d]: %s failed!\n", p->level, ' ',
+ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target ','"));
+ }
+ _res = NULL;
+ done:
+ D(p->level--);
+ return _res;
+}
+
+// star_target: '*' (!'*' star_target) | target_with_star_atom
static expr_ty
star_target_rule(Parser *p)
{
if (
(_literal = _PyPegen_expect_token(p, 16)) // token='*'
&&
- (a = _tmp_120_rule(p)) // !'*' star_target
+ (a = _tmp_121_rule(p)) // !'*' star_target
)
{
D(fprintf(stderr, "%*c+ star_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (!'*' star_target)"));
D(fprintf(stderr, "%*c%s star_target[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' (!'*' star_target)"));
}
+ { // target_with_star_atom
+ if (p->error_indicator) {
+ D(p->level--);
+ return NULL;
+ }
+ D(fprintf(stderr, "%*c> star_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "target_with_star_atom"));
+ expr_ty target_with_star_atom_var;
+ if (
+ (target_with_star_atom_var = target_with_star_atom_rule(p)) // target_with_star_atom
+ )
+ {
+ D(fprintf(stderr, "%*c+ star_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "target_with_star_atom"));
+ _res = target_with_star_atom_var;
+ goto done;
+ }
+ p->mark = _mark;
+ D(fprintf(stderr, "%*c%s star_target[%d-%d]: %s failed!\n", p->level, ' ',
+ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "target_with_star_atom"));
+ }
+ _res = NULL;
+ done:
+ _PyPegen_insert_memo(p, _mark, star_target_type, _res);
+ D(p->level--);
+ return _res;
+}
+
+// target_with_star_atom:
+// | t_primary '.' NAME !t_lookahead
+// | t_primary '[' slices ']' !t_lookahead
+// | star_atom
+static expr_ty
+target_with_star_atom_rule(Parser *p)
+{
+ D(p->level++);
+ if (p->error_indicator) {
+ D(p->level--);
+ return NULL;
+ }
+ expr_ty _res = NULL;
+ if (_PyPegen_is_memoized(p, target_with_star_atom_type, &_res)) {
+ D(p->level--);
+ return _res;
+ }
+ int _mark = p->mark;
+ if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
+ p->error_indicator = 1;
+ D(p->level--);
+ return NULL;
+ }
+ int _start_lineno = p->tokens[_mark]->lineno;
+ UNUSED(_start_lineno); // Only used by EXTRA macro
+ int _start_col_offset = p->tokens[_mark]->col_offset;
+ UNUSED(_start_col_offset); // Only used by EXTRA macro
{ // t_primary '.' NAME !t_lookahead
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> star_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead"));
+ D(fprintf(stderr, "%*c> target_with_star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead"));
Token * _literal;
expr_ty a;
expr_ty b;
_PyPegen_lookahead(0, t_lookahead_rule, p)
)
{
- D(fprintf(stderr, "%*c+ star_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead"));
+ D(fprintf(stderr, "%*c+ target_with_star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead"));
Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
if (_token == NULL) {
D(p->level--);
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s star_target[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s target_with_star_atom[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '.' NAME !t_lookahead"));
}
{ // t_primary '[' slices ']' !t_lookahead
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> star_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead"));
+ D(fprintf(stderr, "%*c> target_with_star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead"));
Token * _literal;
Token * _literal_1;
expr_ty a;
_PyPegen_lookahead(0, t_lookahead_rule, p)
)
{
- D(fprintf(stderr, "%*c+ star_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead"));
+ D(fprintf(stderr, "%*c+ target_with_star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead"));
Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
if (_token == NULL) {
D(p->level--);
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s star_target[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s target_with_star_atom[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "t_primary '[' slices ']' !t_lookahead"));
}
{ // star_atom
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> star_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_atom"));
+ D(fprintf(stderr, "%*c> target_with_star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_atom"));
expr_ty star_atom_var;
if (
(star_atom_var = star_atom_rule(p)) // star_atom
)
{
- D(fprintf(stderr, "%*c+ star_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_atom"));
+ D(fprintf(stderr, "%*c+ target_with_star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_atom"));
_res = star_atom_var;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s star_target[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s target_with_star_atom[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_atom"));
}
_res = NULL;
done:
- _PyPegen_insert_memo(p, _mark, star_target_type, _res);
+ _PyPegen_insert_memo(p, _mark, target_with_star_atom_type, _res);
D(p->level--);
return _res;
}
// star_atom:
// | NAME
-// | '(' star_target ')'
-// | '(' star_targets_seq? ')'
-// | '[' star_targets_seq? ']'
+// | '(' target_with_star_atom ')'
+// | '(' star_targets_tuple_seq? ')'
+// | '[' star_targets_list_seq? ']'
static expr_ty
star_atom_rule(Parser *p)
{
D(fprintf(stderr, "%*c%s star_atom[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME"));
}
- { // '(' star_target ')'
+ { // '(' target_with_star_atom ')'
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' star_target ')'"));
+ D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' target_with_star_atom ')'"));
Token * _literal;
Token * _literal_1;
expr_ty a;
if (
(_literal = _PyPegen_expect_token(p, 7)) // token='('
&&
- (a = star_target_rule(p)) // star_target
+ (a = target_with_star_atom_rule(p)) // target_with_star_atom
&&
(_literal_1 = _PyPegen_expect_token(p, 8)) // token=')'
)
{
- D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' star_target ')'"));
+ D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' target_with_star_atom ')'"));
_res = _PyPegen_set_expr_context ( p , a , Store );
if (_res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
}
p->mark = _mark;
D(fprintf(stderr, "%*c%s star_atom[%d-%d]: %s failed!\n", p->level, ' ',
- p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' star_target ')'"));
+ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' target_with_star_atom ')'"));
}
- { // '(' star_targets_seq? ')'
+ { // '(' star_targets_tuple_seq? ')'
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' star_targets_seq? ')'"));
+ D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' star_targets_tuple_seq? ')'"));
Token * _literal;
Token * _literal_1;
void *a;
if (
(_literal = _PyPegen_expect_token(p, 7)) // token='('
&&
- (a = star_targets_seq_rule(p), 1) // star_targets_seq?
+ (a = star_targets_tuple_seq_rule(p), 1) // star_targets_tuple_seq?
&&
(_literal_1 = _PyPegen_expect_token(p, 8)) // token=')'
)
{
- D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' star_targets_seq? ')'"));
+ D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' star_targets_tuple_seq? ')'"));
Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
if (_token == NULL) {
D(p->level--);
}
p->mark = _mark;
D(fprintf(stderr, "%*c%s star_atom[%d-%d]: %s failed!\n", p->level, ' ',
- p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' star_targets_seq? ')'"));
+ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' star_targets_tuple_seq? ')'"));
}
- { // '[' star_targets_seq? ']'
+ { // '[' star_targets_list_seq? ']'
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' star_targets_seq? ']'"));
+ D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' star_targets_list_seq? ']'"));
Token * _literal;
Token * _literal_1;
void *a;
if (
(_literal = _PyPegen_expect_token(p, 9)) // token='['
&&
- (a = star_targets_seq_rule(p), 1) // star_targets_seq?
+ (a = star_targets_list_seq_rule(p), 1) // star_targets_list_seq?
&&
(_literal_1 = _PyPegen_expect_token(p, 10)) // token=']'
)
{
- D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' star_targets_seq? ']'"));
+ D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' star_targets_list_seq? ']'"));
Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
if (_token == NULL) {
D(p->level--);
}
p->mark = _mark;
D(fprintf(stderr, "%*c%s star_atom[%d-%d]: %s failed!\n", p->level, ' ',
- p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'[' star_targets_seq? ']'"));
+ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'[' star_targets_list_seq? ']'"));
}
_res = NULL;
done:
UNUSED(_opt_var); // Silence compiler warnings
asdl_seq * a;
if (
- (a = _gather_121_rule(p)) // ','.del_target+
+ (a = _gather_122_rule(p)) // ','.del_target+
&&
(_opt_var = _PyPegen_expect_token(p, 12), 1) // ','?
)
UNUSED(_opt_var); // Silence compiler warnings
asdl_seq * a;
if (
- (a = _gather_123_rule(p)) // ','.target+
+ (a = _gather_124_rule(p)) // ','.target+
&&
(_opt_var = _PyPegen_expect_token(p, 12), 1) // ','?
)
&&
(_literal = _PyPegen_expect_token(p, 12)) // token=','
&&
- (_opt_var = _tmp_125_rule(p), 1) // [args | expression for_if_clauses]
+ (_opt_var = _tmp_126_rule(p), 1) // [args | expression for_if_clauses]
)
{
D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses ',' [args | expression for_if_clauses]"));
D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions* ':' expression"));
Token * _literal;
Token * _literal_1;
- asdl_seq * _loop0_126_var;
+ asdl_seq * _loop0_127_var;
expr_ty a;
expr_ty expression_var;
if (
&&
(_literal = _PyPegen_expect_token(p, 12)) // token=','
&&
- (_loop0_126_var = _loop0_126_rule(p)) // star_named_expressions*
+ (_loop0_127_var = _loop0_127_rule(p)) // star_named_expressions*
&&
(_literal_1 = _PyPegen_expect_token(p, 11)) // token=':'
&&
}
D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* star_expressions '='"));
Token * _literal;
- asdl_seq * _loop0_127_var;
+ asdl_seq * _loop0_128_var;
expr_ty a;
if (
- (_loop0_127_var = _loop0_127_rule(p)) // ((star_targets '='))*
+ (_loop0_128_var = _loop0_128_rule(p)) // ((star_targets '='))*
&&
(a = star_expressions_rule(p)) // star_expressions
&&
}
D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* yield_expr '='"));
Token * _literal;
- asdl_seq * _loop0_128_var;
+ asdl_seq * _loop0_129_var;
expr_ty a;
if (
- (_loop0_128_var = _loop0_128_rule(p)) // ((star_targets '='))*
+ (_loop0_129_var = _loop0_129_rule(p)) // ((star_targets '='))*
&&
(a = yield_expr_rule(p)) // yield_expr
&&
return NULL;
}
D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)"));
- void *_tmp_129_var;
+ void *_tmp_130_var;
expr_ty a;
AugOperator* augassign_var;
if (
&&
(augassign_var = augassign_rule(p)) // augassign
&&
- (_tmp_129_var = _tmp_129_rule(p)) // yield_expr | star_expressions
+ (_tmp_130_var = _tmp_130_rule(p)) // yield_expr | star_expressions
)
{
D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)"));
return NULL;
}
D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses"));
- void *_tmp_130_var;
+ void *_tmp_131_var;
expr_ty a;
asdl_seq* for_if_clauses_var;
if (
- (_tmp_130_var = _tmp_130_rule(p)) // '[' | '(' | '{'
+ (_tmp_131_var = _tmp_131_rule(p)) // '[' | '(' | '{'
&&
(a = starred_expression_rule(p)) // starred_expression
&&
return NULL;
}
D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* (slash_with_default | param_with_default+) param_no_default"));
- asdl_seq * _loop0_131_var;
- void *_tmp_132_var;
+ asdl_seq * _loop0_132_var;
+ void *_tmp_133_var;
arg_ty param_no_default_var;
if (
- (_loop0_131_var = _loop0_131_rule(p)) // param_no_default*
+ (_loop0_132_var = _loop0_132_rule(p)) // param_no_default*
&&
- (_tmp_132_var = _tmp_132_rule(p)) // slash_with_default | param_with_default+
+ (_tmp_133_var = _tmp_133_rule(p)) // slash_with_default | param_with_default+
&&
(param_no_default_var = param_no_default_rule(p)) // param_no_default
)
return NULL;
}
D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* (lambda_slash_with_default | lambda_param_with_default+) lambda_param_no_default"));
- asdl_seq * _loop0_133_var;
- void *_tmp_134_var;
+ asdl_seq * _loop0_134_var;
+ void *_tmp_135_var;
arg_ty lambda_param_no_default_var;
if (
- (_loop0_133_var = _loop0_133_rule(p)) // lambda_param_no_default*
+ (_loop0_134_var = _loop0_134_rule(p)) // lambda_param_no_default*
&&
- (_tmp_134_var = _tmp_134_rule(p)) // lambda_slash_with_default | lambda_param_with_default+
+ (_tmp_135_var = _tmp_135_rule(p)) // lambda_slash_with_default | lambda_param_with_default+
&&
(lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default
)
}
D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))"));
Token * _literal;
- void *_tmp_135_var;
+ void *_tmp_136_var;
if (
(_literal = _PyPegen_expect_token(p, 16)) // token='*'
&&
- (_tmp_135_var = _tmp_135_rule(p)) // ')' | ',' (')' | '**')
+ (_tmp_136_var = _tmp_136_rule(p)) // ')' | ',' (')' | '**')
)
{
D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))"));
}
D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))"));
Token * _literal;
- void *_tmp_136_var;
+ void *_tmp_137_var;
if (
(_literal = _PyPegen_expect_token(p, 16)) // token='*'
&&
- (_tmp_136_var = _tmp_136_rule(p)) // ':' | ',' (':' | '**')
+ (_tmp_137_var = _tmp_137_rule(p)) // ':' | ',' (':' | '**')
)
{
D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))"));
return NULL;
}
D(fprintf(stderr, "%*c> _loop1_22[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')"));
- void *_tmp_137_var;
+ void *_tmp_138_var;
while (
- (_tmp_137_var = _tmp_137_rule(p)) // star_targets '='
+ (_tmp_138_var = _tmp_138_rule(p)) // star_targets '='
)
{
- _res = _tmp_137_var;
+ _res = _tmp_138_var;
if (_n == _children_capacity) {
_children_capacity *= 2;
void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
return NULL;
}
D(fprintf(stderr, "%*c> _loop0_31[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')"));
- void *_tmp_138_var;
+ void *_tmp_139_var;
while (
- (_tmp_138_var = _tmp_138_rule(p)) // '.' | '...'
+ (_tmp_139_var = _tmp_139_rule(p)) // '.' | '...'
)
{
- _res = _tmp_138_var;
+ _res = _tmp_139_var;
if (_n == _children_capacity) {
_children_capacity *= 2;
void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
return NULL;
}
D(fprintf(stderr, "%*c> _loop1_32[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')"));
- void *_tmp_139_var;
+ void *_tmp_140_var;
while (
- (_tmp_139_var = _tmp_139_rule(p)) // '.' | '...'
+ (_tmp_140_var = _tmp_140_rule(p)) // '.' | '...'
)
{
- _res = _tmp_139_var;
+ _res = _tmp_140_var;
if (_n == _children_capacity) {
_children_capacity *= 2;
void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
return NULL;
}
D(fprintf(stderr, "%*c> _loop1_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)"));
- void *_tmp_140_var;
+ void *_tmp_141_var;
while (
- (_tmp_140_var = _tmp_140_rule(p)) // '@' named_expression NEWLINE
+ (_tmp_141_var = _tmp_141_rule(p)) // '@' named_expression NEWLINE
)
{
- _res = _tmp_140_var;
+ _res = _tmp_141_var;
if (_n == _children_capacity) {
_children_capacity *= 2;
void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
return NULL;
}
D(fprintf(stderr, "%*c> _loop1_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)"));
- void *_tmp_141_var;
+ void *_tmp_142_var;
while (
- (_tmp_141_var = _tmp_141_rule(p)) // ',' star_expression
+ (_tmp_142_var = _tmp_142_rule(p)) // ',' star_expression
)
{
- _res = _tmp_141_var;
+ _res = _tmp_142_var;
if (_n == _children_capacity) {
_children_capacity *= 2;
void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
return NULL;
}
D(fprintf(stderr, "%*c> _loop1_73[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)"));
- void *_tmp_142_var;
+ void *_tmp_143_var;
while (
- (_tmp_142_var = _tmp_142_rule(p)) // ',' expression
+ (_tmp_143_var = _tmp_143_rule(p)) // ',' expression
)
{
- _res = _tmp_142_var;
+ _res = _tmp_143_var;
if (_n == _children_capacity) {
_children_capacity *= 2;
void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
return NULL;
}
D(fprintf(stderr, "%*c> _loop1_88[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)"));
- void *_tmp_143_var;
+ void *_tmp_144_var;
while (
- (_tmp_143_var = _tmp_143_rule(p)) // 'or' conjunction
+ (_tmp_144_var = _tmp_144_rule(p)) // 'or' conjunction
)
{
- _res = _tmp_143_var;
+ _res = _tmp_144_var;
if (_n == _children_capacity) {
_children_capacity *= 2;
void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
return NULL;
}
D(fprintf(stderr, "%*c> _loop1_89[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)"));
- void *_tmp_144_var;
+ void *_tmp_145_var;
while (
- (_tmp_144_var = _tmp_144_rule(p)) // 'and' inversion
+ (_tmp_145_var = _tmp_145_rule(p)) // 'and' inversion
)
{
- _res = _tmp_144_var;
+ _res = _tmp_145_var;
if (_n == _children_capacity) {
_children_capacity *= 2;
void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
return NULL;
}
D(fprintf(stderr, "%*c> _loop0_104[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)"));
- void *_tmp_145_var;
+ void *_tmp_146_var;
while (
- (_tmp_145_var = _tmp_145_rule(p)) // 'if' disjunction
+ (_tmp_146_var = _tmp_146_rule(p)) // 'if' disjunction
)
{
- _res = _tmp_145_var;
+ _res = _tmp_146_var;
if (_n == _children_capacity) {
_children_capacity *= 2;
void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
return NULL;
}
D(fprintf(stderr, "%*c> _loop0_105[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)"));
- void *_tmp_146_var;
+ void *_tmp_147_var;
while (
- (_tmp_146_var = _tmp_146_rule(p)) // 'if' disjunction
+ (_tmp_147_var = _tmp_147_rule(p)) // 'if' disjunction
)
{
- _res = _tmp_146_var;
+ _res = _tmp_147_var;
if (_n == _children_capacity) {
_children_capacity *= 2;
void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
while (
(_literal = _PyPegen_expect_token(p, 12)) // token=','
&&
- (elem = _tmp_147_rule(p)) // starred_expression | named_expression !'='
+ (elem = _tmp_148_rule(p)) // starred_expression | named_expression !'='
)
{
_res = elem;
void *elem;
asdl_seq * seq;
if (
- (elem = _tmp_147_rule(p)) // starred_expression | named_expression !'='
+ (elem = _tmp_148_rule(p)) // starred_expression | named_expression !'='
&&
(seq = _loop0_107_rule(p)) // _loop0_107
)
return NULL;
}
D(fprintf(stderr, "%*c> _loop0_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)"));
- void *_tmp_148_var;
+ void *_tmp_149_var;
while (
- (_tmp_148_var = _tmp_148_rule(p)) // ',' star_target
+ (_tmp_149_var = _tmp_149_rule(p)) // ',' star_target
)
{
- _res = _tmp_148_var;
+ _res = _tmp_149_var;
if (_n == _children_capacity) {
_children_capacity *= 2;
void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
return _res;
}
-// _tmp_120: !'*' star_target
+// _loop1_120: (',' star_target)
+static asdl_seq *
+_loop1_120_rule(Parser *p)
+{
+ D(p->level++);
+ if (p->error_indicator) {
+ D(p->level--);
+ return NULL;
+ }
+ void *_res = NULL;
+ int _mark = p->mark;
+ int _start_mark = p->mark;
+ void **_children = PyMem_Malloc(sizeof(void *));
+ if (!_children) {
+ p->error_indicator = 1;
+ PyErr_NoMemory();
+ D(p->level--);
+ return NULL;
+ }
+ ssize_t _children_capacity = 1;
+ ssize_t _n = 0;
+ { // (',' star_target)
+ if (p->error_indicator) {
+ D(p->level--);
+ return NULL;
+ }
+ D(fprintf(stderr, "%*c> _loop1_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)"));
+ void *_tmp_150_var;
+ while (
+ (_tmp_150_var = _tmp_150_rule(p)) // ',' star_target
+ )
+ {
+ _res = _tmp_150_var;
+ if (_n == _children_capacity) {
+ _children_capacity *= 2;
+ void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
+ if (!_new_children) {
+ p->error_indicator = 1;
+ PyErr_NoMemory();
+ D(p->level--);
+ return NULL;
+ }
+ _children = _new_children;
+ }
+ _children[_n++] = _res;
+ _mark = p->mark;
+ }
+ p->mark = _mark;
+ D(fprintf(stderr, "%*c%s _loop1_120[%d-%d]: %s failed!\n", p->level, ' ',
+ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_target)"));
+ }
+ if (_n == 0 || p->error_indicator) {
+ PyMem_Free(_children);
+ D(p->level--);
+ return NULL;
+ }
+ asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
+ if (!_seq) {
+ PyMem_Free(_children);
+ p->error_indicator = 1;
+ PyErr_NoMemory();
+ D(p->level--);
+ return NULL;
+ }
+ for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
+ PyMem_Free(_children);
+ _PyPegen_insert_memo(p, _start_mark, _loop1_120_type, _seq);
+ D(p->level--);
+ return _seq;
+}
+
+// _tmp_121: !'*' star_target
static void *
-_tmp_120_rule(Parser *p)
+_tmp_121_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!'*' star_target"));
+ D(fprintf(stderr, "%*c> _tmp_121[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!'*' star_target"));
expr_ty star_target_var;
if (
_PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 16) // token='*'
(star_target_var = star_target_rule(p)) // star_target
)
{
- D(fprintf(stderr, "%*c+ _tmp_120[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!'*' star_target"));
+ D(fprintf(stderr, "%*c+ _tmp_121[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!'*' star_target"));
_res = star_target_var;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_120[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_121[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "!'*' star_target"));
}
_res = NULL;
return _res;
}
-// _loop0_122: ',' del_target
+// _loop0_123: ',' del_target
static asdl_seq *
-_loop0_122_rule(Parser *p)
+_loop0_123_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _loop0_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' del_target"));
+ D(fprintf(stderr, "%*c> _loop0_123[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' del_target"));
Token * _literal;
expr_ty elem;
while (
_mark = p->mark;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _loop0_122[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _loop0_123[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' del_target"));
}
asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
}
for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
PyMem_Free(_children);
- _PyPegen_insert_memo(p, _start_mark, _loop0_122_type, _seq);
+ _PyPegen_insert_memo(p, _start_mark, _loop0_123_type, _seq);
D(p->level--);
return _seq;
}
-// _gather_121: del_target _loop0_122
+// _gather_122: del_target _loop0_123
static asdl_seq *
-_gather_121_rule(Parser *p)
+_gather_122_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
}
asdl_seq * _res = NULL;
int _mark = p->mark;
- { // del_target _loop0_122
+ { // del_target _loop0_123
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _gather_121[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_target _loop0_122"));
+ D(fprintf(stderr, "%*c> _gather_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_target _loop0_123"));
expr_ty elem;
asdl_seq * seq;
if (
(elem = del_target_rule(p)) // del_target
&&
- (seq = _loop0_122_rule(p)) // _loop0_122
+ (seq = _loop0_123_rule(p)) // _loop0_123
)
{
- D(fprintf(stderr, "%*c+ _gather_121[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "del_target _loop0_122"));
+ D(fprintf(stderr, "%*c+ _gather_122[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "del_target _loop0_123"));
_res = _PyPegen_seq_insert_in_front(p, elem, seq);
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _gather_121[%d-%d]: %s failed!\n", p->level, ' ',
- p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "del_target _loop0_122"));
+ D(fprintf(stderr, "%*c%s _gather_122[%d-%d]: %s failed!\n", p->level, ' ',
+ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "del_target _loop0_123"));
}
_res = NULL;
done:
return _res;
}
-// _loop0_124: ',' target
+// _loop0_125: ',' target
static asdl_seq *
-_loop0_124_rule(Parser *p)
+_loop0_125_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _loop0_124[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' target"));
+ D(fprintf(stderr, "%*c> _loop0_125[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' target"));
Token * _literal;
expr_ty elem;
while (
_mark = p->mark;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _loop0_124[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _loop0_125[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' target"));
}
asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
}
for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
PyMem_Free(_children);
- _PyPegen_insert_memo(p, _start_mark, _loop0_124_type, _seq);
+ _PyPegen_insert_memo(p, _start_mark, _loop0_125_type, _seq);
D(p->level--);
return _seq;
}
-// _gather_123: target _loop0_124
+// _gather_124: target _loop0_125
static asdl_seq *
-_gather_123_rule(Parser *p)
+_gather_124_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
}
asdl_seq * _res = NULL;
int _mark = p->mark;
- { // target _loop0_124
+ { // target _loop0_125
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _gather_123[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "target _loop0_124"));
+ D(fprintf(stderr, "%*c> _gather_124[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "target _loop0_125"));
expr_ty elem;
asdl_seq * seq;
if (
(elem = target_rule(p)) // target
&&
- (seq = _loop0_124_rule(p)) // _loop0_124
+ (seq = _loop0_125_rule(p)) // _loop0_125
)
{
- D(fprintf(stderr, "%*c+ _gather_123[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "target _loop0_124"));
+ D(fprintf(stderr, "%*c+ _gather_124[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "target _loop0_125"));
_res = _PyPegen_seq_insert_in_front(p, elem, seq);
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _gather_123[%d-%d]: %s failed!\n", p->level, ' ',
- p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "target _loop0_124"));
+ D(fprintf(stderr, "%*c%s _gather_124[%d-%d]: %s failed!\n", p->level, ' ',
+ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "target _loop0_125"));
}
_res = NULL;
done:
return _res;
}
-// _tmp_125: args | expression for_if_clauses
+// _tmp_126: args | expression for_if_clauses
static void *
-_tmp_125_rule(Parser *p)
+_tmp_126_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_125[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args"));
+ D(fprintf(stderr, "%*c> _tmp_126[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args"));
expr_ty args_var;
if (
(args_var = args_rule(p)) // args
)
{
- D(fprintf(stderr, "%*c+ _tmp_125[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args"));
+ D(fprintf(stderr, "%*c+ _tmp_126[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args"));
_res = args_var;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_125[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_126[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args"));
}
{ // expression for_if_clauses
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_125[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses"));
+ D(fprintf(stderr, "%*c> _tmp_126[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses"));
expr_ty expression_var;
asdl_seq* for_if_clauses_var;
if (
(for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses
)
{
- D(fprintf(stderr, "%*c+ _tmp_125[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses"));
+ D(fprintf(stderr, "%*c+ _tmp_126[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses"));
_res = _PyPegen_dummy_name(p, expression_var, for_if_clauses_var);
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_125[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_126[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression for_if_clauses"));
}
_res = NULL;
return _res;
}
-// _loop0_126: star_named_expressions
+// _loop0_127: star_named_expressions
static asdl_seq *
-_loop0_126_rule(Parser *p)
+_loop0_127_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _loop0_126[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions"));
+ D(fprintf(stderr, "%*c> _loop0_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions"));
asdl_seq* star_named_expressions_var;
while (
(star_named_expressions_var = star_named_expressions_rule(p)) // star_named_expressions
_mark = p->mark;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _loop0_126[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _loop0_127[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expressions"));
}
asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
}
for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
PyMem_Free(_children);
- _PyPegen_insert_memo(p, _start_mark, _loop0_126_type, _seq);
+ _PyPegen_insert_memo(p, _start_mark, _loop0_127_type, _seq);
D(p->level--);
return _seq;
}
-// _loop0_127: (star_targets '=')
+// _loop0_128: (star_targets '=')
static asdl_seq *
-_loop0_127_rule(Parser *p)
+_loop0_128_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _loop0_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')"));
- void *_tmp_149_var;
+ D(fprintf(stderr, "%*c> _loop0_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')"));
+ void *_tmp_151_var;
while (
- (_tmp_149_var = _tmp_149_rule(p)) // star_targets '='
+ (_tmp_151_var = _tmp_151_rule(p)) // star_targets '='
)
{
- _res = _tmp_149_var;
+ _res = _tmp_151_var;
if (_n == _children_capacity) {
_children_capacity *= 2;
void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
_mark = p->mark;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _loop0_127[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _loop0_128[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')"));
}
asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
}
for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
PyMem_Free(_children);
- _PyPegen_insert_memo(p, _start_mark, _loop0_127_type, _seq);
+ _PyPegen_insert_memo(p, _start_mark, _loop0_128_type, _seq);
D(p->level--);
return _seq;
}
-// _loop0_128: (star_targets '=')
+// _loop0_129: (star_targets '=')
static asdl_seq *
-_loop0_128_rule(Parser *p)
+_loop0_129_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _loop0_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')"));
- void *_tmp_150_var;
+ D(fprintf(stderr, "%*c> _loop0_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')"));
+ void *_tmp_152_var;
while (
- (_tmp_150_var = _tmp_150_rule(p)) // star_targets '='
+ (_tmp_152_var = _tmp_152_rule(p)) // star_targets '='
)
{
- _res = _tmp_150_var;
+ _res = _tmp_152_var;
if (_n == _children_capacity) {
_children_capacity *= 2;
void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
_mark = p->mark;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _loop0_128[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _loop0_129[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')"));
}
asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
}
for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
PyMem_Free(_children);
- _PyPegen_insert_memo(p, _start_mark, _loop0_128_type, _seq);
+ _PyPegen_insert_memo(p, _start_mark, _loop0_129_type, _seq);
D(p->level--);
return _seq;
}
-// _tmp_129: yield_expr | star_expressions
+// _tmp_130: yield_expr | star_expressions
static void *
-_tmp_129_rule(Parser *p)
+_tmp_130_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+ D(fprintf(stderr, "%*c> _tmp_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
expr_ty yield_expr_var;
if (
(yield_expr_var = yield_expr_rule(p)) // yield_expr
)
{
- D(fprintf(stderr, "%*c+ _tmp_129[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+ D(fprintf(stderr, "%*c+ _tmp_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
_res = yield_expr_var;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_129[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_130[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr"));
}
{ // star_expressions
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+ D(fprintf(stderr, "%*c> _tmp_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
expr_ty star_expressions_var;
if (
(star_expressions_var = star_expressions_rule(p)) // star_expressions
)
{
- D(fprintf(stderr, "%*c+ _tmp_129[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+ D(fprintf(stderr, "%*c+ _tmp_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
_res = star_expressions_var;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_129[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_130[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions"));
}
_res = NULL;
return _res;
}
-// _tmp_130: '[' | '(' | '{'
+// _tmp_131: '[' | '(' | '{'
static void *
-_tmp_130_rule(Parser *p)
+_tmp_131_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['"));
+ D(fprintf(stderr, "%*c> _tmp_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['"));
Token * _literal;
if (
(_literal = _PyPegen_expect_token(p, 9)) // token='['
)
{
- D(fprintf(stderr, "%*c+ _tmp_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['"));
+ D(fprintf(stderr, "%*c+ _tmp_131[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['"));
_res = _literal;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_130[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_131[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['"));
}
{ // '('
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('"));
+ D(fprintf(stderr, "%*c> _tmp_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('"));
Token * _literal;
if (
(_literal = _PyPegen_expect_token(p, 7)) // token='('
)
{
- D(fprintf(stderr, "%*c+ _tmp_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('"));
+ D(fprintf(stderr, "%*c+ _tmp_131[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('"));
_res = _literal;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_130[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_131[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('"));
}
{ // '{'
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'"));
+ D(fprintf(stderr, "%*c> _tmp_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'"));
Token * _literal;
if (
(_literal = _PyPegen_expect_token(p, 25)) // token='{'
)
{
- D(fprintf(stderr, "%*c+ _tmp_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'"));
+ D(fprintf(stderr, "%*c+ _tmp_131[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'"));
_res = _literal;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_130[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_131[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'"));
}
_res = NULL;
return _res;
}
-// _loop0_131: param_no_default
+// _loop0_132: param_no_default
static asdl_seq *
-_loop0_131_rule(Parser *p)
+_loop0_132_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _loop0_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
+ D(fprintf(stderr, "%*c> _loop0_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
arg_ty param_no_default_var;
while (
(param_no_default_var = param_no_default_rule(p)) // param_no_default
_mark = p->mark;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _loop0_131[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _loop0_132[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default"));
}
asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
}
for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
PyMem_Free(_children);
- _PyPegen_insert_memo(p, _start_mark, _loop0_131_type, _seq);
+ _PyPegen_insert_memo(p, _start_mark, _loop0_132_type, _seq);
D(p->level--);
return _seq;
}
-// _tmp_132: slash_with_default | param_with_default+
+// _tmp_133: slash_with_default | param_with_default+
static void *
-_tmp_132_rule(Parser *p)
+_tmp_133_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default"));
+ D(fprintf(stderr, "%*c> _tmp_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default"));
SlashWithDefault* slash_with_default_var;
if (
(slash_with_default_var = slash_with_default_rule(p)) // slash_with_default
)
{
- D(fprintf(stderr, "%*c+ _tmp_132[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default"));
+ D(fprintf(stderr, "%*c+ _tmp_133[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default"));
_res = slash_with_default_var;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_132[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_133[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default"));
}
{ // param_with_default+
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+"));
- asdl_seq * _loop1_151_var;
+ D(fprintf(stderr, "%*c> _tmp_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+"));
+ asdl_seq * _loop1_153_var;
if (
- (_loop1_151_var = _loop1_151_rule(p)) // param_with_default+
+ (_loop1_153_var = _loop1_153_rule(p)) // param_with_default+
)
{
- D(fprintf(stderr, "%*c+ _tmp_132[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+"));
- _res = _loop1_151_var;
+ D(fprintf(stderr, "%*c+ _tmp_133[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+"));
+ _res = _loop1_153_var;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_132[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_133[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default+"));
}
_res = NULL;
return _res;
}
-// _loop0_133: lambda_param_no_default
+// _loop0_134: lambda_param_no_default
static asdl_seq *
-_loop0_133_rule(Parser *p)
+_loop0_134_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _loop0_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
+ D(fprintf(stderr, "%*c> _loop0_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
arg_ty lambda_param_no_default_var;
while (
(lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default
_mark = p->mark;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _loop0_133[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _loop0_134[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default"));
}
asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
}
for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
PyMem_Free(_children);
- _PyPegen_insert_memo(p, _start_mark, _loop0_133_type, _seq);
+ _PyPegen_insert_memo(p, _start_mark, _loop0_134_type, _seq);
D(p->level--);
return _seq;
}
-// _tmp_134: lambda_slash_with_default | lambda_param_with_default+
+// _tmp_135: lambda_slash_with_default | lambda_param_with_default+
static void *
-_tmp_134_rule(Parser *p)
+_tmp_135_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default"));
+ D(fprintf(stderr, "%*c> _tmp_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default"));
SlashWithDefault* lambda_slash_with_default_var;
if (
(lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default
)
{
- D(fprintf(stderr, "%*c+ _tmp_134[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default"));
+ D(fprintf(stderr, "%*c+ _tmp_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default"));
_res = lambda_slash_with_default_var;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_134[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_135[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default"));
}
{ // lambda_param_with_default+
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+"));
- asdl_seq * _loop1_152_var;
+ D(fprintf(stderr, "%*c> _tmp_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+"));
+ asdl_seq * _loop1_154_var;
if (
- (_loop1_152_var = _loop1_152_rule(p)) // lambda_param_with_default+
+ (_loop1_154_var = _loop1_154_rule(p)) // lambda_param_with_default+
)
{
- D(fprintf(stderr, "%*c+ _tmp_134[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+"));
- _res = _loop1_152_var;
+ D(fprintf(stderr, "%*c+ _tmp_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+"));
+ _res = _loop1_154_var;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_134[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_135[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default+"));
}
_res = NULL;
return _res;
}
-// _tmp_135: ')' | ',' (')' | '**')
+// _tmp_136: ')' | ',' (')' | '**')
static void *
-_tmp_135_rule(Parser *p)
+_tmp_136_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'"));
+ D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'"));
Token * _literal;
if (
(_literal = _PyPegen_expect_token(p, 8)) // token=')'
)
{
- D(fprintf(stderr, "%*c+ _tmp_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'"));
+ D(fprintf(stderr, "%*c+ _tmp_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'"));
_res = _literal;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_135[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_136[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'"));
}
{ // ',' (')' | '**')
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')"));
+ D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')"));
Token * _literal;
- void *_tmp_153_var;
+ void *_tmp_155_var;
if (
(_literal = _PyPegen_expect_token(p, 12)) // token=','
&&
- (_tmp_153_var = _tmp_153_rule(p)) // ')' | '**'
+ (_tmp_155_var = _tmp_155_rule(p)) // ')' | '**'
)
{
- D(fprintf(stderr, "%*c+ _tmp_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')"));
- _res = _PyPegen_dummy_name(p, _literal, _tmp_153_var);
+ D(fprintf(stderr, "%*c+ _tmp_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')"));
+ _res = _PyPegen_dummy_name(p, _literal, _tmp_155_var);
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_135[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_136[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')"));
}
_res = NULL;
return _res;
}
-// _tmp_136: ':' | ',' (':' | '**')
+// _tmp_137: ':' | ',' (':' | '**')
static void *
-_tmp_136_rule(Parser *p)
+_tmp_137_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
+ D(fprintf(stderr, "%*c> _tmp_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
Token * _literal;
if (
(_literal = _PyPegen_expect_token(p, 11)) // token=':'
)
{
- D(fprintf(stderr, "%*c+ _tmp_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
+ D(fprintf(stderr, "%*c+ _tmp_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
_res = _literal;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_136[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_137[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'"));
}
{ // ',' (':' | '**')
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')"));
+ D(fprintf(stderr, "%*c> _tmp_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')"));
Token * _literal;
- void *_tmp_154_var;
+ void *_tmp_156_var;
if (
(_literal = _PyPegen_expect_token(p, 12)) // token=','
&&
- (_tmp_154_var = _tmp_154_rule(p)) // ':' | '**'
+ (_tmp_156_var = _tmp_156_rule(p)) // ':' | '**'
)
{
- D(fprintf(stderr, "%*c+ _tmp_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')"));
- _res = _PyPegen_dummy_name(p, _literal, _tmp_154_var);
+ D(fprintf(stderr, "%*c+ _tmp_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')"));
+ _res = _PyPegen_dummy_name(p, _literal, _tmp_156_var);
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_136[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_137[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (':' | '**')"));
}
_res = NULL;
return _res;
}
-// _tmp_137: star_targets '='
+// _tmp_138: star_targets '='
static void *
-_tmp_137_rule(Parser *p)
+_tmp_138_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
+ D(fprintf(stderr, "%*c> _tmp_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
Token * _literal;
expr_ty z;
if (
(_literal = _PyPegen_expect_token(p, 22)) // token='='
)
{
- D(fprintf(stderr, "%*c+ _tmp_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
+ D(fprintf(stderr, "%*c+ _tmp_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
_res = z;
if (_res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_137[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_138[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='"));
}
_res = NULL;
return _res;
}
-// _tmp_138: '.' | '...'
+// _tmp_139: '.' | '...'
static void *
-_tmp_138_rule(Parser *p)
+_tmp_139_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'"));
+ D(fprintf(stderr, "%*c> _tmp_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'"));
Token * _literal;
if (
(_literal = _PyPegen_expect_token(p, 23)) // token='.'
)
{
- D(fprintf(stderr, "%*c+ _tmp_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'"));
+ D(fprintf(stderr, "%*c+ _tmp_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'"));
_res = _literal;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_138[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_139[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'"));
}
{ // '...'
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'"));
+ D(fprintf(stderr, "%*c> _tmp_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'"));
Token * _literal;
if (
(_literal = _PyPegen_expect_token(p, 52)) // token='...'
)
{
- D(fprintf(stderr, "%*c+ _tmp_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'"));
+ D(fprintf(stderr, "%*c+ _tmp_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'"));
_res = _literal;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_138[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_139[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'"));
}
_res = NULL;
return _res;
}
-// _tmp_139: '.' | '...'
+// _tmp_140: '.' | '...'
static void *
-_tmp_139_rule(Parser *p)
+_tmp_140_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'"));
+ D(fprintf(stderr, "%*c> _tmp_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'"));
Token * _literal;
if (
(_literal = _PyPegen_expect_token(p, 23)) // token='.'
)
{
- D(fprintf(stderr, "%*c+ _tmp_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'"));
+ D(fprintf(stderr, "%*c+ _tmp_140[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'"));
_res = _literal;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_139[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_140[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'"));
}
{ // '...'
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'"));
+ D(fprintf(stderr, "%*c> _tmp_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'"));
Token * _literal;
if (
(_literal = _PyPegen_expect_token(p, 52)) // token='...'
)
{
- D(fprintf(stderr, "%*c+ _tmp_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'"));
+ D(fprintf(stderr, "%*c+ _tmp_140[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'"));
_res = _literal;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_139[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_140[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'"));
}
_res = NULL;
return _res;
}
-// _tmp_140: '@' named_expression NEWLINE
+// _tmp_141: '@' named_expression NEWLINE
static void *
-_tmp_140_rule(Parser *p)
+_tmp_141_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE"));
+ D(fprintf(stderr, "%*c> _tmp_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE"));
Token * _literal;
expr_ty f;
Token * newline_var;
(newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE'
)
{
- D(fprintf(stderr, "%*c+ _tmp_140[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE"));
+ D(fprintf(stderr, "%*c+ _tmp_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE"));
_res = f;
if (_res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_140[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_141[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@' named_expression NEWLINE"));
}
_res = NULL;
return _res;
}
-// _tmp_141: ',' star_expression
+// _tmp_142: ',' star_expression
static void *
-_tmp_141_rule(Parser *p)
+_tmp_142_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression"));
+ D(fprintf(stderr, "%*c> _tmp_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression"));
Token * _literal;
expr_ty c;
if (
(c = star_expression_rule(p)) // star_expression
)
{
- D(fprintf(stderr, "%*c+ _tmp_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression"));
+ D(fprintf(stderr, "%*c+ _tmp_142[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression"));
_res = c;
if (_res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_141[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_142[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_expression"));
}
_res = NULL;
return _res;
}
-// _tmp_142: ',' expression
+// _tmp_143: ',' expression
static void *
-_tmp_142_rule(Parser *p)
+_tmp_143_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
+ D(fprintf(stderr, "%*c> _tmp_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
Token * _literal;
expr_ty c;
if (
(c = expression_rule(p)) // expression
)
{
- D(fprintf(stderr, "%*c+ _tmp_142[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression"));
+ D(fprintf(stderr, "%*c+ _tmp_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression"));
_res = c;
if (_res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_142[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_143[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression"));
}
_res = NULL;
return _res;
}
-// _tmp_143: 'or' conjunction
+// _tmp_144: 'or' conjunction
static void *
-_tmp_143_rule(Parser *p)
+_tmp_144_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction"));
+ D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction"));
Token * _keyword;
expr_ty c;
if (
(c = conjunction_rule(p)) // conjunction
)
{
- D(fprintf(stderr, "%*c+ _tmp_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction"));
+ D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction"));
_res = c;
if (_res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_143[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'or' conjunction"));
}
_res = NULL;
return _res;
}
-// _tmp_144: 'and' inversion
+// _tmp_145: 'and' inversion
static void *
-_tmp_144_rule(Parser *p)
+_tmp_145_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion"));
+ D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion"));
Token * _keyword;
expr_ty c;
if (
(c = inversion_rule(p)) // inversion
)
{
- D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion"));
+ D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion"));
_res = c;
if (_res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'and' inversion"));
}
_res = NULL;
return _res;
}
-// _tmp_145: 'if' disjunction
+// _tmp_146: 'if' disjunction
static void *
-_tmp_145_rule(Parser *p)
+_tmp_146_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
+ D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
Token * _keyword;
expr_ty z;
if (
(z = disjunction_rule(p)) // disjunction
)
{
- D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
+ D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
_res = z;
if (_res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_146[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction"));
}
_res = NULL;
return _res;
}
-// _tmp_146: 'if' disjunction
+// _tmp_147: 'if' disjunction
static void *
-_tmp_146_rule(Parser *p)
+_tmp_147_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
+ D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
Token * _keyword;
expr_ty z;
if (
(z = disjunction_rule(p)) // disjunction
)
{
- D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
+ D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
_res = z;
if (_res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_146[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction"));
}
_res = NULL;
return _res;
}
-// _tmp_147: starred_expression | named_expression !'='
+// _tmp_148: starred_expression | named_expression !'='
static void *
-_tmp_147_rule(Parser *p)
+_tmp_148_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression"));
+ D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression"));
expr_ty starred_expression_var;
if (
(starred_expression_var = starred_expression_rule(p)) // starred_expression
)
{
- D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression"));
+ D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression"));
_res = starred_expression_var;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression"));
}
{ // named_expression !'='
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression !'='"));
+ D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression !'='"));
expr_ty named_expression_var;
if (
(named_expression_var = named_expression_rule(p)) // named_expression
_PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='='
)
{
- D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "named_expression !'='"));
+ D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "named_expression !'='"));
_res = named_expression_var;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "named_expression !'='"));
}
_res = NULL;
return _res;
}
-// _tmp_148: ',' star_target
+// _tmp_149: ',' star_target
static void *
-_tmp_148_rule(Parser *p)
+_tmp_149_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target"));
+ D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target"));
Token * _literal;
expr_ty c;
if (
(c = star_target_rule(p)) // star_target
)
{
- D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target"));
+ D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target"));
_res = c;
if (_res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target"));
}
_res = NULL;
return _res;
}
-// _tmp_149: star_targets '='
+// _tmp_150: ',' star_target
static void *
-_tmp_149_rule(Parser *p)
+_tmp_150_rule(Parser *p)
+{
+ D(p->level++);
+ if (p->error_indicator) {
+ D(p->level--);
+ return NULL;
+ }
+ void * _res = NULL;
+ int _mark = p->mark;
+ { // ',' star_target
+ if (p->error_indicator) {
+ D(p->level--);
+ return NULL;
+ }
+ D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target"));
+ Token * _literal;
+ expr_ty c;
+ if (
+ (_literal = _PyPegen_expect_token(p, 12)) // token=','
+ &&
+ (c = star_target_rule(p)) // star_target
+ )
+ {
+ D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target"));
+ _res = c;
+ if (_res == NULL && PyErr_Occurred()) {
+ p->error_indicator = 1;
+ D(p->level--);
+ return NULL;
+ }
+ goto done;
+ }
+ p->mark = _mark;
+ D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ',
+ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target"));
+ }
+ _res = NULL;
+ done:
+ D(p->level--);
+ return _res;
+}
+
+// _tmp_151: star_targets '='
+static void *
+_tmp_151_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
+ D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
Token * _literal;
expr_ty star_targets_var;
if (
(_literal = _PyPegen_expect_token(p, 22)) // token='='
)
{
- D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
+ D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
_res = _PyPegen_dummy_name(p, star_targets_var, _literal);
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='"));
}
_res = NULL;
return _res;
}
-// _tmp_150: star_targets '='
+// _tmp_152: star_targets '='
static void *
-_tmp_150_rule(Parser *p)
+_tmp_152_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
+ D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
Token * _literal;
expr_ty star_targets_var;
if (
(_literal = _PyPegen_expect_token(p, 22)) // token='='
)
{
- D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
+ D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
_res = _PyPegen_dummy_name(p, star_targets_var, _literal);
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='"));
}
_res = NULL;
return _res;
}
-// _loop1_151: param_with_default
+// _loop1_153: param_with_default
static asdl_seq *
-_loop1_151_rule(Parser *p)
+_loop1_153_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _loop1_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default"));
+ D(fprintf(stderr, "%*c> _loop1_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default"));
NameDefaultPair* param_with_default_var;
while (
(param_with_default_var = param_with_default_rule(p)) // param_with_default
_mark = p->mark;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _loop1_151[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _loop1_153[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default"));
}
if (_n == 0 || p->error_indicator) {
}
for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
PyMem_Free(_children);
- _PyPegen_insert_memo(p, _start_mark, _loop1_151_type, _seq);
+ _PyPegen_insert_memo(p, _start_mark, _loop1_153_type, _seq);
D(p->level--);
return _seq;
}
-// _loop1_152: lambda_param_with_default
+// _loop1_154: lambda_param_with_default
static asdl_seq *
-_loop1_152_rule(Parser *p)
+_loop1_154_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _loop1_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
+ D(fprintf(stderr, "%*c> _loop1_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
NameDefaultPair* lambda_param_with_default_var;
while (
(lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default
_mark = p->mark;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _loop1_152[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _loop1_154[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default"));
}
if (_n == 0 || p->error_indicator) {
}
for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
PyMem_Free(_children);
- _PyPegen_insert_memo(p, _start_mark, _loop1_152_type, _seq);
+ _PyPegen_insert_memo(p, _start_mark, _loop1_154_type, _seq);
D(p->level--);
return _seq;
}
-// _tmp_153: ')' | '**'
+// _tmp_155: ')' | '**'
static void *
-_tmp_153_rule(Parser *p)
+_tmp_155_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'"));
+ D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'"));
Token * _literal;
if (
(_literal = _PyPegen_expect_token(p, 8)) // token=')'
)
{
- D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'"));
+ D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'"));
_res = _literal;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'"));
}
{ // '**'
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'"));
+ D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'"));
Token * _literal;
if (
(_literal = _PyPegen_expect_token(p, 35)) // token='**'
)
{
- D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'"));
+ D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'"));
_res = _literal;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'"));
}
_res = NULL;
return _res;
}
-// _tmp_154: ':' | '**'
+// _tmp_156: ':' | '**'
static void *
-_tmp_154_rule(Parser *p)
+_tmp_156_rule(Parser *p)
{
D(p->level++);
if (p->error_indicator) {
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
+ D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
Token * _literal;
if (
(_literal = _PyPegen_expect_token(p, 11)) // token=':'
)
{
- D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
+ D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
_res = _literal;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'"));
}
{ // '**'
D(p->level--);
return NULL;
}
- D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'"));
+ D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'"));
Token * _literal;
if (
(_literal = _PyPegen_expect_token(p, 35)) // token='**'
)
{
- D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'"));
+ D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'"));
_res = _literal;
goto done;
}
p->mark = _mark;
- D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ',
+ D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'"));
}
_res = NULL;
Parser *p2 = _PyPegen_Parser_New(tok, Py_fstring_input, p->flags, p->feature_version,
NULL, p->arena);
p2->starting_lineno = t->lineno + lines - 1;
- p2->starting_col_offset = p->tok->first_lineno == p->tok->lineno ? t->col_offset + cols : cols;
+ p2->starting_col_offset = t->col_offset + cols;
expr = _PyPegen_run_parser(p2);
PyTuple_SET_ITEM(result, i, item);
Py_DECREF(olditem);
}
+ // bpo-42536: The GC may have untracked this result tuple. Since we're
+ // recycling it, make sure it's tracked again:
+ if (!_PyObject_GC_IS_TRACKED(result)) {
+ _PyObject_GC_TRACK(result);
+ }
} else {
result = PyTuple_New(tuplesize);
if (result == NULL)
return 0;
}
+#ifdef __linux__
+ if (errno == EBADF) {
+ // On Linux, ioctl(FIOCLEX) will fail with EBADF for O_PATH file descriptors
+ // Fall through to the fcntl() path
+ }
+ else
+#endif
if (errno != ENOTTY && errno != EACCES) {
if (raise)
PyErr_SetFromErrno(PyExc_OSError);
static const char cprt[] =
"\
-Copyright (c) 2001-2020 Python Software Foundation.\n\
+Copyright (c) 2001-2021 Python Software Foundation.\n\
All Rights Reserved.\n\
\n\
Copyright (c) 2000 BeOpen.com.\n\
static void flush_io(void);
static PyObject *run_mod(mod_ty, PyObject *, PyObject *, PyObject *,
PyCompilerFlags *, PyArena *);
-static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,
+static PyObject *run_pyc_file(FILE *, PyObject *, PyObject *,
PyCompilerFlags *);
static void err_input(perrdetail *);
static void err_free(perrdetail *);
static int PyRun_InteractiveOneObjectEx(FILE *, PyObject *, PyCompilerFlags *);
+static PyObject* pyrun_file(FILE *fp, PyObject *filename, int start,
+ PyObject *globals, PyObject *locals, int closeit,
+ PyCompilerFlags *flags);
+
/* Parse input from a file and execute it */
int
the file type, and, if we may close it, at the first few bytes. */
static int
-maybe_pyc_file(FILE *fp, const char* filename, const char* ext, int closeit)
+maybe_pyc_file(FILE *fp, PyObject *filename, int closeit)
{
- if (strcmp(ext, ".pyc") == 0)
+ PyObject *ext = PyUnicode_FromString(".pyc");
+ if (ext == NULL) {
+ return -1;
+ }
+ Py_ssize_t endswith = PyUnicode_Tailmatch(filename, ext, 0, PY_SSIZE_T_MAX, +1);
+ Py_DECREF(ext);
+ if (endswith) {
return 1;
+ }
/* Only look into the file if we are allowed to close it, since
it then should also be seekable. */
- if (closeit) {
- /* Read only two bytes of the magic. If the file was opened in
- text mode, the bytes 3 and 4 of the magic (\r\n) might not
- be read as they are on disk. */
- unsigned int halfmagic = PyImport_GetMagicNumber() & 0xFFFF;
- unsigned char buf[2];
- /* Mess: In case of -x, the stream is NOT at its start now,
- and ungetc() was used to push back the first newline,
- which makes the current stream position formally undefined,
- and a x-platform nightmare.
- Unfortunately, we have no direct way to know whether -x
- was specified. So we use a terrible hack: if the current
- stream position is not 0, we assume -x was specified, and
- give up. Bug 132850 on SourceForge spells out the
- hopelessness of trying anything else (fseek and ftell
- don't work predictably x-platform for text-mode files).
- */
- int ispyc = 0;
- if (ftell(fp) == 0) {
- if (fread(buf, 1, 2, fp) == 2 &&
- ((unsigned int)buf[1]<<8 | buf[0]) == halfmagic)
- ispyc = 1;
- rewind(fp);
- }
- return ispyc;
+ if (!closeit) {
+ return 0;
}
- return 0;
+
+ /* Read only two bytes of the magic. If the file was opened in
+ text mode, the bytes 3 and 4 of the magic (\r\n) might not
+ be read as they are on disk. */
+ unsigned int halfmagic = PyImport_GetMagicNumber() & 0xFFFF;
+ unsigned char buf[2];
+ /* Mess: In case of -x, the stream is NOT at its start now,
+ and ungetc() was used to push back the first newline,
+ which makes the current stream position formally undefined,
+ and a x-platform nightmare.
+ Unfortunately, we have no direct way to know whether -x
+ was specified. So we use a terrible hack: if the current
+ stream position is not 0, we assume -x was specified, and
+ give up. Bug 132850 on SourceForge spells out the
+ hopelessness of trying anything else (fseek and ftell
+ don't work predictably x-platform for text-mode files).
+ */
+ int ispyc = 0;
+ if (ftell(fp) == 0) {
+ if (fread(buf, 1, 2, fp) == 2 &&
+ ((unsigned int)buf[1]<<8 | buf[0]) == halfmagic)
+ ispyc = 1;
+ rewind(fp);
+ }
+ return ispyc;
}
+
static int
-set_main_loader(PyObject *d, const char *filename, const char *loader_name)
+set_main_loader(PyObject *d, PyObject *filename, const char *loader_name)
{
- PyObject *filename_obj, *bootstrap, *loader_type = NULL, *loader;
- int result = 0;
-
- filename_obj = PyUnicode_DecodeFSDefault(filename);
- if (filename_obj == NULL)
- return -1;
PyInterpreterState *interp = _PyInterpreterState_GET();
- bootstrap = PyObject_GetAttrString(interp->importlib,
- "_bootstrap_external");
- if (bootstrap != NULL) {
- loader_type = PyObject_GetAttrString(bootstrap, loader_name);
- Py_DECREF(bootstrap);
+ PyObject *bootstrap = PyObject_GetAttrString(interp->importlib,
+ "_bootstrap_external");
+ if (bootstrap == NULL) {
+ return -1;
}
+
+ PyObject *loader_type = PyObject_GetAttrString(bootstrap, loader_name);
+ Py_DECREF(bootstrap);
if (loader_type == NULL) {
- Py_DECREF(filename_obj);
return -1;
}
- loader = PyObject_CallFunction(loader_type, "sN", "__main__", filename_obj);
+
+ PyObject *loader = PyObject_CallFunction(loader_type,
+ "sO", "__main__", filename);
Py_DECREF(loader_type);
if (loader == NULL) {
return -1;
}
+
if (PyDict_SetItemString(d, "__loader__", loader) < 0) {
- result = -1;
+ Py_DECREF(loader);
+ return -1;
}
Py_DECREF(loader);
- return result;
+ return 0;
}
-int
-PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
- PyCompilerFlags *flags)
+
+static int
+pyrun_simple_file(FILE *fp, PyObject *filename, int closeit,
+ PyCompilerFlags *flags)
{
PyObject *m, *d, *v;
- const char *ext;
int set_file_name = 0, ret = -1;
- size_t len;
m = PyImport_AddModule("__main__");
if (m == NULL)
Py_INCREF(m);
d = PyModule_GetDict(m);
if (PyDict_GetItemString(d, "__file__") == NULL) {
- PyObject *f;
- f = PyUnicode_DecodeFSDefault(filename);
- if (f == NULL)
- goto done;
- if (PyDict_SetItemString(d, "__file__", f) < 0) {
- Py_DECREF(f);
+ if (PyDict_SetItemString(d, "__file__", filename) < 0) {
goto done;
}
if (PyDict_SetItemString(d, "__cached__", Py_None) < 0) {
- Py_DECREF(f);
goto done;
}
set_file_name = 1;
- Py_DECREF(f);
}
- len = strlen(filename);
- ext = filename + len - (len > 4 ? 4 : 0);
- if (maybe_pyc_file(fp, filename, ext, closeit)) {
+
+ int pyc = maybe_pyc_file(fp, filename, closeit);
+ if (pyc < 0) {
+ goto done;
+ }
+
+ if (pyc) {
FILE *pyc_fp;
/* Try to run a pyc file. First, re-open in binary */
- if (closeit)
+ if (closeit) {
fclose(fp);
- if ((pyc_fp = _Py_fopen(filename, "rb")) == NULL) {
+ }
+
+ pyc_fp = _Py_fopen_obj(filename, "rb");
+ if (pyc_fp == NULL) {
fprintf(stderr, "python: Can't reopen .pyc file\n");
goto done;
}
fclose(pyc_fp);
goto done;
}
- v = run_pyc_file(pyc_fp, filename, d, d, flags);
+ v = run_pyc_file(pyc_fp, d, d, flags);
} else {
/* When running from stdin, leave __main__.__loader__ alone */
- if (strcmp(filename, "<stdin>") != 0 &&
+ if (PyUnicode_CompareWithASCIIString(filename, "<stdin>") != 0 &&
set_main_loader(d, filename, "SourceFileLoader") < 0) {
fprintf(stderr, "python: failed to set __main__.__loader__\n");
ret = -1;
goto done;
}
- v = PyRun_FileExFlags(fp, filename, Py_file_input, d, d,
- closeit, flags);
+ v = pyrun_file(fp, filename, Py_file_input, d, d,
+ closeit, flags);
}
flush_io();
if (v == NULL) {
return ret;
}
+
+int
+PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
+ PyCompilerFlags *flags)
+{
+ PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename);
+ if (filename_obj == NULL) {
+ return -1;
+ }
+ int res = pyrun_simple_file(fp, filename_obj, closeit, flags);
+ Py_DECREF(filename_obj);
+ return res;
+}
+
+
int
PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)
{
return ret;
}
-PyObject *
-PyRun_FileExFlags(FILE *fp, const char *filename_str, int start, PyObject *globals,
- PyObject *locals, int closeit, PyCompilerFlags *flags)
+
+static PyObject *
+pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals,
+ PyObject *locals, int closeit, PyCompilerFlags *flags)
{
- PyObject *ret = NULL;
+ PyArena *arena = PyArena_New();
+ if (arena == NULL) {
+ return NULL;
+ }
+
mod_ty mod;
- PyArena *arena = NULL;
- PyObject *filename;
int use_peg = _PyInterpreterState_GET()->config._use_peg_parser;
-
- filename = PyUnicode_DecodeFSDefault(filename_str);
- if (filename == NULL)
- goto exit;
-
- arena = PyArena_New();
- if (arena == NULL)
- goto exit;
-
if (use_peg) {
mod = PyPegen_ASTFromFileObject(fp, filename, start, NULL, NULL, NULL,
flags, NULL, arena);
flags, NULL, arena);
}
- if (closeit)
+ if (closeit) {
fclose(fp);
- if (mod == NULL) {
- goto exit;
}
- ret = run_mod(mod, filename, globals, locals, flags, arena);
-exit:
- Py_XDECREF(filename);
- if (arena != NULL)
- PyArena_Free(arena);
+ PyObject *ret;
+ if (mod != NULL) {
+ ret = run_mod(mod, filename, globals, locals, flags, arena);
+ }
+ else {
+ ret = NULL;
+ }
+ PyArena_Free(arena);
+
return ret;
}
+
+PyObject *
+PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals,
+ PyObject *locals, int closeit, PyCompilerFlags *flags)
+{
+ PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename);
+ if (filename_obj == NULL) {
+ return NULL;
+ }
+
+ PyObject *res = pyrun_file(fp, filename_obj, start, globals,
+ locals, closeit, flags);
+ Py_DECREF(filename_obj);
+ return res;
+
+}
+
+
static void
flush_io(void)
{
}
static PyObject *
-run_pyc_file(FILE *fp, const char *filename, PyObject *globals,
- PyObject *locals, PyCompilerFlags *flags)
+run_pyc_file(FILE *fp, PyObject *globals, PyObject *locals,
+ PyCompilerFlags *flags)
{
PyThreadState *tstate = _PyThreadState_GET();
PyCodeObject *co;
return err;
}
-/* Reverse a string. For example, "abcd" becomes "dcba".
+/* Format an integer in range [0; 0xffffffff] to decimal and write it
+ into the file fd.
This function is signal safe. */
-This is Python version 3.9.1
+This is Python version 3.9.2
============================
.. image:: https://travis-ci.org/python/cpython.svg?branch=3.9
:target: https://python.zulipchat.com
-Copyright (c) 2001-2020 Python Software Foundation. All rights reserved.
+Copyright (c) 2001-2021 Python Software Foundation. All rights reserved.
See the end of this file for further copyright and license information.
Copyright and License Information
---------------------------------
-Copyright (c) 2001-2020 Python Software Foundation. All rights reserved.
+Copyright (c) 2001-2021 Python Software Foundation. All rights reserved.
Copyright (c) 2000 BeOpen.com. All rights reserved.
import getopt
import os
import sys
+import sysconfig
# Import the freeze-private modules
extensions_c = 'frozen_extensions.c'
if ishome:
print("(Using Python source directory)")
- binlib = exec_prefix
+ configdir = exec_prefix
incldir = os.path.join(prefix, 'Include')
config_h_dir = exec_prefix
config_c_in = os.path.join(prefix, 'Modules', 'config.c.in')
if win:
frozendllmain_c = os.path.join(exec_prefix, 'Pc\\frozen_dllmain.c')
else:
- binlib = os.path.join(exec_prefix,
- 'lib', 'python%s' % version,
- 'config-%s' % flagged_version)
+ configdir = sysconfig.get_config_var('LIBPL')
incldir = os.path.join(prefix, 'include', 'python%s' % flagged_version)
config_h_dir = os.path.join(exec_prefix, 'include',
'python%s' % flagged_version)
- config_c_in = os.path.join(binlib, 'config.c.in')
- frozenmain_c = os.path.join(binlib, 'frozenmain.c')
- makefile_in = os.path.join(binlib, 'Makefile')
- frozendllmain_c = os.path.join(binlib, 'frozen_dllmain.c')
+ config_c_in = os.path.join(configdir, 'config.c.in')
+ frozenmain_c = os.path.join(configdir, 'frozenmain.c')
+ makefile_in = os.path.join(configdir, 'Makefile')
+ frozendllmain_c = os.path.join(configdir, 'frozen_dllmain.c')
+ libdir = sysconfig.get_config_var('LIBDIR')
supp_sources = []
defines = []
includes = ['-I' + incldir, '-I' + config_h_dir]
# sanity check of directories and files
- check_dirs = [prefix, exec_prefix, binlib, incldir]
+ check_dirs = [prefix, exec_prefix, configdir, incldir]
if not win:
# These are not directories on Windows.
check_dirs = check_dirs + extensions
cflags = ['$(OPT)']
cppflags = defines + includes
- libs = [os.path.join(binlib, '$(LDLIBRARY)')]
+ libs = [os.path.join(libdir, '$(LDLIBRARY)')]
somevars = {}
if os.path.exists(makefile_in):
def __repr__(self):
if isinstance(self.attrdict, dict):
kwargs = ', '.join(["%s=%r" % (arg, val)
- for arg, val in self.attrdict.iteritems()])
+ for arg, val in self.attrdict.items()])
return '<%s(%s) at remote 0x%x>' % (self.cl_name,
kwargs, self.address)
else:
$d = "$target/$($p[0])/"\r
& $plink -batch $user@$server mkdir $d\r
& $plink -batch $user@$server chgrp downloads $d\r
- & $plink -batch $user@$server chmod g-x,o+rx $d\r
+ & $plink -batch $user@$server chmod o+rx $d\r
& $pscp -batch $chm.FullName "$user@${server}:$d"\r
if (-not $?) { throw "Failed to upload $chm" }\r
\r
$sd = "$d$($a.Name)$($p[1])/"\r
& $plink -batch $user@$server mkdir $sd\r
& $plink -batch $user@$server chgrp downloads $sd\r
- & $plink -batch $user@$server chmod g-x,o+rx $sd\r
+ & $plink -batch $user@$server chmod o+rx $sd\r
& $pscp -batch $msi.FullName "$user@${server}:$sd"\r
if (-not $?) { throw "Failed to upload $msi" }\r
& $plink -batch $user@$server chgrp downloads $sd*\r
else:
# Is there already a default root for Tk, say because we're
# running under Guido's IDE? :-) Two conditions say no, either the
- # import fails or _default_root is None.
- tkroot = None
- try:
- from Tkinter import _default_root
- tkroot = self.__tkroot = _default_root
- except ImportError:
- pass
+ # _default_root is None or it is unset.
+ tkroot = getattr(tkinter, '_default_root', None)
if not tkroot:
- tkroot = self.__tkroot = Tk(className='Pynche')
+ tkroot = Tk(className='Pynche')
+ self.__tkroot = tkroot
# but this isn't our top level widget, so make it invisible
tkroot.withdraw()
# create the menubar
main() {
pthread_attr_t attr;
pthread_t id;
- if (pthread_attr_init(&attr)) exit(-1);
- if (pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)) exit(-1);
- if (pthread_create(&id, &attr, foo, NULL)) exit(-1);
- exit(0);
+ if (pthread_attr_init(&attr)) return (-1);
+ if (pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)) return (-1);
+ if (pthread_create(&id, &attr, foo, NULL)) return (-1);
+ return (0);
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
int main()
{
/* Success: exit code 0 */
- exit((((wchar_t) -1) < ((wchar_t) 0)) ? 0 : 1);
+ return ((((wchar_t) -1) < ((wchar_t) 0)) ? 0 : 1);
}
_ACEOF
fi
-
-case $ac_sys_system in
- Linux*|GNU*|Darwin|VxWorks)
- EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX};;
- *)
- EXT_SUFFIX=${SHLIB_SUFFIX};;
-esac
+EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX}
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking LDVERSION" >&5
$as_echo_n "checking LDVERSION... " >&6; }
int main()
{
- exit(((-1)>>3 == -1) ? 0 : 1);
+ return (((-1)>>3 == -1) ? 0 : 1);
}
_ACEOF
/* end confdefs.h. */
#include <poll.h>
+#include <unistd.h>
int main()
{
main() {
pthread_attr_t attr;
pthread_t id;
- if (pthread_attr_init(&attr)) exit(-1);
- if (pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)) exit(-1);
- if (pthread_create(&id, &attr, foo, NULL)) exit(-1);
- exit(0);
+ if (pthread_attr_init(&attr)) return (-1);
+ if (pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)) return (-1);
+ if (pthread_create(&id, &attr, foo, NULL)) return (-1);
+ return (0);
}]])],
[ac_cv_pthread_system_supported=yes],
[ac_cv_pthread_system_supported=no],
int main()
{
/* Success: exit code 0 */
- exit((((wchar_t) -1) < ((wchar_t) 0)) ? 0 : 1);
+ return ((((wchar_t) -1) < ((wchar_t) 0)) ? 0 : 1);
}
]])],
[ac_cv_wchar_t_signed=yes],
fi
AC_SUBST(EXT_SUFFIX)
-case $ac_sys_system in
- Linux*|GNU*|Darwin|VxWorks)
- EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX};;
- *)
- EXT_SUFFIX=${SHLIB_SUFFIX};;
-esac
+EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX}
AC_MSG_CHECKING(LDVERSION)
LDVERSION='$(VERSION)$(ABIFLAGS)'
AC_RUN_IFELSE([AC_LANG_SOURCE([[
int main()
{
- exit(((-1)>>3 == -1) ? 0 : 1);
+ return (((-1)>>3 == -1) ? 0 : 1);
}
]])],
[ac_cv_rshift_extends_sign=yes],
AC_CACHE_VAL(ac_cv_broken_poll,
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <poll.h>
+#include <unistd.h>
int main()
{
os_release = int(os.uname()[2].split('.')[0])
dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
if (dep_target and
- (tuple(int(n) for n in str(dep_target).split('.')[0:2])
+ (tuple(int(n) for n in dep_target.split('.')[0:2])
< (10, 5) ) ):
os_release = 8
if os_release < 9: