summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Doc/c-api/exceptions.rst10
-rw-r--r--Doc/faq/general.rst14
-rw-r--r--Doc/howto/clinic.rst8
-rw-r--r--Doc/library/asyncio-eventloop.rst26
-rw-r--r--Doc/library/asyncio-protocol.rst187
-rw-r--r--Doc/library/asyncio-stream.rst244
-rw-r--r--Doc/library/asyncio-sync.rst47
-rw-r--r--Doc/library/asyncio.rst1
-rw-r--r--Doc/library/concurrent.futures.rst3
-rw-r--r--Doc/library/importlib.rst34
-rw-r--r--Doc/library/inspect.rst3
-rw-r--r--Doc/library/selectors.rst4
-rw-r--r--Doc/whatsnew/3.3.rst2
-rw-r--r--Doc/whatsnew/3.4.rst8
-rw-r--r--Include/object.h7
-rw-r--r--Lib/asyncio/__init__.py14
-rw-r--r--Lib/asyncio/base_events.py3
-rw-r--r--Lib/asyncio/base_subprocess.py1
-rw-r--r--Lib/asyncio/locks.py82
-rw-r--r--Lib/asyncio/proactor_events.py2
-rw-r--r--Lib/asyncio/queues.py28
-rw-r--r--Lib/asyncio/selector_events.py3
-rw-r--r--Lib/asyncio/streams.py43
-rw-r--r--Lib/asyncio/tasks.py6
-rw-r--r--Lib/asyncio/test_utils.py4
-rw-r--r--Lib/asyncio/unix_events.py47
-rw-r--r--Lib/asyncio/windows_events.py3
-rw-r--r--Lib/codecs.py13
-rw-r--r--Lib/concurrent/futures/_base.py6
-rw-r--r--Lib/contextlib.py4
-rw-r--r--Lib/ensurepip/__init__.py4
-rw-r--r--Lib/ensurepip/_bundled/pip-1.5.2-py2.py3-none-any.whl (renamed from Lib/ensurepip/_bundled/pip-1.5-py2.py3-none-any.whl)bin957957 -> 1167543 bytes
-rw-r--r--Lib/ensurepip/_bundled/setuptools-2.1-py2.py3-none-any.whl (renamed from Lib/ensurepip/_bundled/setuptools-2.0.2-py2.py3-none-any.whl)bin540179 -> 540293 bytes
-rw-r--r--Lib/http/server.py24
-rw-r--r--Lib/idlelib/EditorWindow.py3
-rw-r--r--Lib/idlelib/idle_test/test_calltips.py1
-rw-r--r--Lib/imghdr.py20
-rw-r--r--Lib/importlib/__init__.py46
-rw-r--r--Lib/importlib/util.py72
-rw-r--r--Lib/inspect.py32
-rw-r--r--Lib/mailcap.py4
-rw-r--r--Lib/mimetypes.py7
-rw-r--r--Lib/pkgutil.py2
-rw-r--r--Lib/pyclbr.py4
-rwxr-xr-xLib/pydoc.py13
-rw-r--r--Lib/runpy.py26
-rw-r--r--Lib/selectors.py33
-rw-r--r--Lib/test/imghdrdata/python.bmpbin0 -> 1162 bytes
-rw-r--r--Lib/test/imghdrdata/python.gifbin0 -> 610 bytes
-rw-r--r--Lib/test/imghdrdata/python.jpgbin0 -> 543 bytes
-rw-r--r--Lib/test/imghdrdata/python.pbm3
-rw-r--r--Lib/test/imghdrdata/python.pgmbin0 -> 269 bytes
-rw-r--r--Lib/test/imghdrdata/python.pngbin0 -> 1020 bytes
-rw-r--r--Lib/test/imghdrdata/python.ppmbin0 -> 781 bytes
-rw-r--r--Lib/test/imghdrdata/python.rasbin0 -> 1056 bytes
-rw-r--r--Lib/test/imghdrdata/python.sgibin0 -> 1967 bytes
-rw-r--r--Lib/test/imghdrdata/python.tiffbin0 -> 1326 bytes
-rw-r--r--Lib/test/imghdrdata/python.xbm6
-rw-r--r--Lib/test/test_asyncio/test_base_events.py95
-rw-r--r--Lib/test/test_asyncio/test_events.py280
-rw-r--r--Lib/test/test_asyncio/test_futures.py99
-rw-r--r--Lib/test/test_asyncio/test_locks.py278
-rw-r--r--Lib/test/test_asyncio/test_queues.py166
-rw-r--r--Lib/test/test_asyncio/test_selector_events.py77
-rw-r--r--Lib/test/test_asyncio/test_streams.py118
-rw-r--r--Lib/test/test_asyncio/test_tasks.py623
-rw-r--r--Lib/test/test_asyncio/test_transports.py14
-rw-r--r--Lib/test/test_asyncio/test_unix_events.py51
-rw-r--r--Lib/test/test_asyncio/test_windows_events.py25
-rw-r--r--Lib/test/test_capi.py6
-rw-r--r--Lib/test/test_codecs.py37
-rw-r--r--Lib/test/test_concurrent_futures.py7
-rw-r--r--Lib/test/test_contextlib.py58
-rw-r--r--Lib/test/test_curses.py4
-rw-r--r--Lib/test/test_epoll.py11
-rw-r--r--Lib/test/test_generators.py4
-rw-r--r--Lib/test/test_genexps.py4
-rw-r--r--Lib/test/test_imghdr.py131
-rw-r--r--Lib/test/test_importlib/test_api.py151
-rw-r--r--Lib/test/test_importlib/test_util.py147
-rw-r--r--Lib/test/test_importlib/util.py34
-rw-r--r--Lib/test/test_inspect.py98
-rw-r--r--Lib/test/test_selectors.py19
-rw-r--r--Lib/test/test_sundry.py2
-rw-r--r--Lib/test/test_tcl.py39
-rw-r--r--Lib/test/test_telnetlib.py4
-rw-r--r--Lib/unittest/mock.py19
-rw-r--r--Lib/wsgiref/__init__.py2
-rw-r--r--Lib/xml/etree/ElementInclude.py9
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS98
-rw-r--r--Modules/_bz2module.c159
-rw-r--r--Modules/_cryptmodule.c4
-rwxr-xr-x[-rw-r--r--]Modules/_ctypes/libffi/build-ios.sh0
-rwxr-xr-x[-rw-r--r--]Modules/_ctypes/libffi/libtool-ldflags0
-rwxr-xr-x[-rw-r--r--]Modules/_ctypes/libffi/msvcc.sh0
-rwxr-xr-x[-rw-r--r--]Modules/_ctypes/libffi/src/arm/gentramp.sh0
-rw-r--r--Modules/_cursesmodule.c12
-rw-r--r--Modules/_datetimemodule.c16
-rw-r--r--Modules/_dbmmodule.c14
-rw-r--r--Modules/_lzmamodule.c349
-rw-r--r--Modules/_lzmamodule.clinic.c231
-rw-r--r--Modules/_opcode.c4
-rw-r--r--Modules/_pickle.c145
-rw-r--r--Modules/_sre.c11
-rw-r--r--Modules/_testcapimodule.c8
-rw-r--r--Modules/_weakref.c4
-rw-r--r--Modules/audioop.c1078
-rw-r--r--Modules/binascii.c637
-rw-r--r--Modules/clinic/_bz2module.c.h152
-rw-r--r--Modules/clinic/_lzmamodule.c.h231
-rw-r--r--Modules/clinic/audioop.c.h836
-rw-r--r--Modules/clinic/binascii.c.h450
-rw-r--r--Modules/clinic/zlibmodule.c.h411
-rw-r--r--Modules/posixmodule.c12
-rw-r--r--Modules/readline.c8
-rw-r--r--Modules/selectmodule.c4
-rw-r--r--Modules/unicodedata.c15
-rw-r--r--Modules/zlibmodule.c511
-rw-r--r--Objects/descrobject.c55
-rw-r--r--Objects/dictobject.c76
-rw-r--r--Objects/exceptions.c7
-rw-r--r--Objects/methodobject.c67
-rw-r--r--Objects/typeobject.c245
-rw-r--r--Objects/unicodeobject.c10
-rw-r--r--Python/bltinmodule.c2
-rw-r--r--Python/import.c48
-rwxr-xr-xTools/clinic/clinic.py606
128 files changed, 6884 insertions, 3402 deletions
diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst
index 8658a58541..d4065e08c9 100644
--- a/Doc/c-api/exceptions.rst
+++ b/Doc/c-api/exceptions.rst
@@ -90,6 +90,16 @@ in various ways. There is a separate error indicator for each thread.
the class in that case. If the values are already normalized, nothing happens.
The delayed normalization is implemented to improve performance.
+ .. note::
+
+ This function *does not* implicitly set the ``__traceback__``
+ attribute on the exception value. If setting the traceback
+ appropriately is desired, the following additional snippet is needed::
+
+ if (tb != NULL) {
+ PyException_SetTraceback(val, tb);
+ }
+
.. c:function:: void PyErr_Clear()
diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst
index 9a893eca2f..da2c933207 100644
--- a/Doc/faq/general.rst
+++ b/Doc/faq/general.rst
@@ -181,8 +181,8 @@ at http://docs.python.org/. PDF, plain text, and downloadable HTML versions are
also available at http://docs.python.org/download.html.
The documentation is written in reStructuredText and processed by `the Sphinx
-documentation tool <http://sphinx.pocoo.org/>`__. The reStructuredText source
-for the documentation is part of the Python source distribution.
+documentation tool <http://sphinx-doc.org/>`__. The reStructuredText source for
+the documentation is part of the Python source distribution.
I've never programmed before. Is there a Python tutorial?
@@ -268,9 +268,13 @@ Python references; or perhaps search for "Python" and "language".
Where in the world is www.python.org located?
---------------------------------------------
-It's currently in Amsterdam, graciously hosted by `XS4ALL
-<http://www.xs4all.nl>`_. Thanks to Thomas Wouters for his work in arranging
-python.org's hosting.
+The Python project's infrastructure is located all over the world.
+`www.python.org <http://www.python.org>`_ is currently in Amsterdam, graciously
+hosted by `XS4ALL <http://www.xs4all.nl>`_. `Upfront Systems
+<http://www.upfrontsystems.co.za>`_ hosts `bugs.python.org
+<http://bugs.python.org>`_. Most other Python services like `PyPI
+<https://pypi.python.org>`_ and hg.python.org are hosted by `Oregon State
+University Open Source Lab <https://osuosl.org>`_.
Why is it called Python?
diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst
index 20477db994..bfae20e7c9 100644
--- a/Doc/howto/clinic.rst
+++ b/Doc/howto/clinic.rst
@@ -1,6 +1,6 @@
-======================
+**********************
Argument Clinic How-To
-======================
+**********************
:author: Larry Hastings
@@ -23,7 +23,6 @@ Argument Clinic How-To
version of Argument Clinic that ships with CPython 3.5 *could*
be totally incompatible and break all your code.
-============================
The Goals Of Argument Clinic
============================
@@ -75,7 +74,6 @@ and it should be able to do many interesting and smart
things with all the information you give it.
-========================
Basic Concepts And Usage
========================
@@ -131,7 +129,6 @@ For the sake of clarity, here's the terminology we'll use with Argument Clinic:
a block.)
-==============================
Converting Your First Function
==============================
@@ -533,7 +530,6 @@ Let's dive in!
Congratulations, you've ported your first function to work with Argument Clinic!
-===============
Advanced Topics
===============
diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst
index 56ede5ccc7..953fa49386 100644
--- a/Doc/library/asyncio-eventloop.rst
+++ b/Doc/library/asyncio-eventloop.rst
@@ -213,6 +213,11 @@ Creating connections
to bind the socket to locally. The *local_host* and *local_port*
are looked up using getaddrinfo(), similarly to *host* and *port*.
+ .. seealso::
+
+ The :func:`open_connection` function can be used to get a pair of
+ (:class:`StreamReader`, :class:`StreamWriter`) instead of a protocol.
+
Creating listening connections
------------------------------
@@ -251,6 +256,11 @@ Creating listening connections
This method returns a :ref:`coroutine object <coroutine>`.
+ .. seealso::
+
+ The function :func:`start_server` creates a (:class:`StreamReader`,
+ :class:`StreamWriter`) pair and calls back a function with this pair.
+
.. method:: BaseEventLoop.create_datagram_endpoint(protocol_factory, local_addr=None, remote_addr=None, \*, family=0, proto=0, flags=0)
Create datagram connection.
@@ -334,6 +344,22 @@ pool of processes). By default, an event loop uses a thread pool executor
Set the default executor used by :meth:`run_in_executor`.
+Server
+------
+
+.. class:: AbstractServer
+
+ Abstract server returned by :func:`BaseEventLoop.create_server`.
+
+ .. method:: close()
+
+ Stop serving. This leaves existing connections open.
+
+ .. method:: wait_closed()
+
+ Coroutine to wait until service is closed.
+
+
.. _asyncio-hello-world-callback:
Example: Hello World (callback)
diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst
index 4672e58776..8eb1d680fb 100644
--- a/Doc/library/asyncio-protocol.rst
+++ b/Doc/library/asyncio-protocol.rst
@@ -1,8 +1,8 @@
.. currentmodule:: asyncio
-++++++++++++++++++++++++
-Transports and protocols
-++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++
+Transports and protocols (low-level API)
++++++++++++++++++++++++++++++++++++++++++
.. _transport:
@@ -228,114 +228,6 @@ BaseSubprocessTransport
stop the subprocess.
-StreamWriter
-------------
-
-.. class:: StreamWriter(transport, protocol, reader, loop)
-
- Wraps a Transport.
-
- This exposes :meth:`write`, :meth:`writelines`, :meth:`can_write_eof()`,
- :meth:`write_eof`, :meth:`get_extra_info` and :meth:`close`. It adds
- :meth:`drain` which returns an optional :class:`Future` on which you can
- wait for flow control. It also adds a transport attribute which references
- the :class:`Transport` directly.
-
- .. attribute:: transport
-
- Transport.
-
- .. method:: close()
-
- Close the transport: see :meth:`BaseTransport.close`.
-
- .. method:: drain()
-
- This method has an unusual return value.
-
- The intended use is to write::
-
- w.write(data)
- yield from w.drain()
-
- When there's nothing to wait for, :meth:`drain()` returns ``()``, and the
- yield-from continues immediately. When the transport buffer is full (the
- protocol is paused), :meth:`drain` creates and returns a
- :class:`Future` and the yield-from will block until
- that Future is completed, which will happen when the buffer is
- (partially) drained and the protocol is resumed.
-
- .. method:: get_extra_info(name, default=None)
-
- Return optional transport information: see
- :meth:`BaseTransport.get_extra_info`.
-
- .. method:: write(data)
-
- Write some *data* bytes to the transport: see
- :meth:`WriteTransport.write`.
-
- .. method:: writelines(data)
-
- Write a list (or any iterable) of data bytes to the transport:
- see :meth:`WriteTransport.writelines`.
-
- .. method:: can_write_eof()
-
- Return :const:`True` if the transport supports :meth:`write_eof`,
- :const:`False` if not. See :meth:`WriteTransport.can_write_eof`.
-
- .. method:: write_eof()
-
- Close the write end of the transport after flushing buffered data:
- see :meth:`WriteTransport.write_eof`.
-
-
-StreamReader
-------------
-
-.. class:: StreamReader(limit=_DEFAULT_LIMIT, loop=None)
-
- .. method:: exception()
-
- Get the exception.
-
- .. method:: feed_eof()
-
- XXX
-
- .. method:: feed_data(data)
-
- XXX
-
- .. method:: set_exception(exc)
-
- Set the exception.
-
- .. method:: set_transport(transport)
-
- Set the transport.
-
- .. method:: read(n=-1)
-
- XXX
-
- This method returns a :ref:`coroutine object <coroutine>`.
-
- .. method:: readline()
-
- XXX
-
- This method returns a :ref:`coroutine object <coroutine>`.
-
- .. method:: readexactly(n)
-
- XXX
-
- This method returns a :ref:`coroutine object <coroutine>`.
-
-
-
.. _protocol:
Protocols
@@ -511,73 +403,16 @@ buffer size reaches the low-water mark.
mark is zero.
-Server
-------
-
-.. class:: AbstractServer
-
- Abstract server returned by :func:`BaseEventLoop.create_server`.
-
- .. method:: close()
-
- Stop serving. This leaves existing connections open.
-
- .. method:: wait_closed()
-
- Coroutine to wait until service is closed.
-
-
-Network functions
-=================
-
-.. function:: open_connection(host=None, port=None, *, loop=None, limit=_DEFAULT_LIMIT, **kwds)
-
- A wrapper for :meth:`~BaseEventLoop.create_connection()` returning a (reader,
- writer) pair.
-
- The reader returned is a :class:`StreamReader` instance; the writer is a
- transport.
-
- The arguments are all the usual arguments to
- :meth:`BaseEventLoop.create_connection` except *protocol_factory*; most
- common are positional host and port, with various optional keyword arguments
- following.
-
- Additional optional keyword arguments are *loop* (to set the event loop
- instance to use) and *limit* (to set the buffer limit passed to the
- StreamReader).
-
- (If you want to customize the :class:`StreamReader` and/or
- :class:`StreamReaderProtocol` classes, just copy the code -- there's really
- nothing special here except some convenience.)
-
- This function returns a :ref:`coroutine object <coroutine>`.
-
-.. function:: start_server(client_connected_cb, host=None, port=None, *, loop=None, limit=_DEFAULT_LIMIT, **kwds)
-
- Start a socket server, call back for each client connected.
-
- The first parameter, *client_connected_cb*, takes two parameters:
- *client_reader*, *client_writer*. *client_reader* is a
- :class:`StreamReader` object, while *client_writer* is a
- :class:`StreamWriter` object. This parameter can either be a plain callback
- function or a :ref:`coroutine function <coroutine>`; if it is a coroutine
- function, it will be automatically converted into a :class:`Task`.
-
- The rest of the arguments are all the usual arguments to
- :meth:`~BaseEventLoop.create_server()` except *protocol_factory*; most
- common are positional host and port, with various optional keyword arguments
- following. The return value is the same as
- :meth:`~BaseEventLoop.create_server()`.
-
- Additional optional keyword arguments are *loop* (to set the event loop
- instance to use) and *limit* (to set the buffer limit passed to the
- :class:`StreamReader`).
+Coroutines and protocols
+------------------------
- The return value is the same as :meth:`~BaseEventLoop.create_server()`, i.e.
- a :class:`AbstractServer` object which can be used to stop the service.
+Coroutines can be scheduled in a protocol method using :func:`async`, but there
+is not guarantee on the execution order. Protocols are not aware of coroutines
+created in protocol methods and so will not wait for them.
- This function returns a :ref:`coroutine object <coroutine>`.
+To have a reliable execution order, use :ref:`stream objects <streams>` in a
+coroutine with ``yield from``. For example, the :meth:`StreamWriter.drain`
+coroutine can be used to wait until the write buffer is flushed.
Protocol example: TCP echo server and client
diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst
new file mode 100644
index 0000000000..27aae32d0f
--- /dev/null
+++ b/Doc/library/asyncio-stream.rst
@@ -0,0 +1,244 @@
+.. currentmodule:: asyncio
+
+.. _streams:
+
+++++++++++++++++++++++++
+Streams (high-level API)
+++++++++++++++++++++++++
+
+Stream functions
+================
+
+.. function:: open_connection(host=None, port=None, *, loop=None, limit=_DEFAULT_LIMIT, **kwds)
+
+ A wrapper for :meth:`~BaseEventLoop.create_connection()` returning a (reader,
+ writer) pair.
+
+ The reader returned is a :class:`StreamReader` instance; the writer is
+ a :class:`StreamWriter` instance.
+
+ The arguments are all the usual arguments to
+ :meth:`BaseEventLoop.create_connection` except *protocol_factory*; most
+ common are positional host and port, with various optional keyword arguments
+ following.
+
+ Additional optional keyword arguments are *loop* (to set the event loop
+ instance to use) and *limit* (to set the buffer limit passed to the
+ :class:`StreamReader`).
+
+ (If you want to customize the :class:`StreamReader` and/or
+ :class:`StreamReaderProtocol` classes, just copy the code -- there's really
+ nothing special here except some convenience.)
+
+ This function returns a :ref:`coroutine object <coroutine>`.
+
+.. function:: start_server(client_connected_cb, host=None, port=None, *, loop=None, limit=_DEFAULT_LIMIT, **kwds)
+
+ Start a socket server, call back for each client connected.
+
+ The first parameter, *client_connected_cb*, takes two parameters:
+ *client_reader*, *client_writer*. *client_reader* is a
+ :class:`StreamReader` object, while *client_writer* is a
+ :class:`StreamWriter` object. This parameter can either be a plain callback
+ function or a :ref:`coroutine function <coroutine>`; if it is a coroutine
+ function, it will be automatically converted into a :class:`Task`.
+
+ The rest of the arguments are all the usual arguments to
+ :meth:`~BaseEventLoop.create_server()` except *protocol_factory*; most
+ common are positional host and port, with various optional keyword arguments
+ following. The return value is the same as
+ :meth:`~BaseEventLoop.create_server()`.
+
+ Additional optional keyword arguments are *loop* (to set the event loop
+ instance to use) and *limit* (to set the buffer limit passed to the
+ :class:`StreamReader`).
+
+ The return value is the same as :meth:`~BaseEventLoop.create_server()`, i.e.
+ a :class:`AbstractServer` object which can be used to stop the service.
+
+ This function returns a :ref:`coroutine object <coroutine>`.
+
+
+StreamReader
+============
+
+.. class:: StreamReader(limit=_DEFAULT_LIMIT, loop=None)
+
+ .. method:: exception()
+
+ Get the exception.
+
+ .. method:: feed_eof()
+
+ XXX
+
+ .. method:: feed_data(data)
+
+ XXX
+
+ .. method:: set_exception(exc)
+
+ Set the exception.
+
+ .. method:: set_transport(transport)
+
+ Set the transport.
+
+ .. method:: read(n=-1)
+
+ XXX
+
+ This method returns a :ref:`coroutine object <coroutine>`.
+
+ .. method:: readline()
+
+ XXX
+
+ This method returns a :ref:`coroutine object <coroutine>`.
+
+ .. method:: readexactly(n)
+
+ XXX
+
+ This method returns a :ref:`coroutine object <coroutine>`.
+
+
+StreamWriter
+============
+
+.. class:: StreamWriter(transport, protocol, reader, loop)
+
+ Wraps a Transport.
+
+ This exposes :meth:`write`, :meth:`writelines`, :meth:`can_write_eof()`,
+ :meth:`write_eof`, :meth:`get_extra_info` and :meth:`close`. It adds
+ :meth:`drain` which returns an optional :class:`Future` on which you can
+ wait for flow control. It also adds a transport attribute which references
+ the :class:`Transport` directly.
+
+ .. attribute:: transport
+
+ Transport.
+
+ .. method:: close()
+
+ Close the transport: see :meth:`BaseTransport.close`.
+
+ .. method:: drain()
+
+ Wait until the write buffer of the underlying transport is flushed.
+
+ This method has an unusual return value. The intended use is to write::
+
+ w.write(data)
+ yield from w.drain()
+
+ When there's nothing to wait for, :meth:`drain()` returns ``()``, and the
+ yield-from continues immediately. When the transport buffer is full (the
+ protocol is paused), :meth:`drain` creates and returns a
+ :class:`Future` and the yield-from will block until
+ that Future is completed, which will happen when the buffer is
+ (partially) drained and the protocol is resumed.
+
+ .. method:: get_extra_info(name, default=None)
+
+ Return optional transport information: see
+ :meth:`BaseTransport.get_extra_info`.
+
+ .. method:: write(data)
+
+ Write some *data* bytes to the transport: see
+ :meth:`WriteTransport.write`.
+
+ .. method:: writelines(data)
+
+ Write a list (or any iterable) of data bytes to the transport:
+ see :meth:`WriteTransport.writelines`.
+
+ .. method:: can_write_eof()
+
+ Return :const:`True` if the transport supports :meth:`write_eof`,
+ :const:`False` if not. See :meth:`WriteTransport.can_write_eof`.
+
+ .. method:: write_eof()
+
+ Close the write end of the transport after flushing buffered data:
+ see :meth:`WriteTransport.write_eof`.
+
+
+StreamReaderProtocol
+====================
+
+.. class:: StreamReaderProtocol(stream_reader, client_connected_cb=None, loop=None)
+
+ Trivial helper class to adapt between :class:`Protocol` and
+ :class:`StreamReader`. Sublclass of :class:`Protocol`.
+
+ *stream_reader* is a :class:`StreamReader` instance, *client_connected_cb*
+ is an optional function called with (stream_reader, stream_writer) when a
+ connection is made, *loop* is the event loop instance to use.
+
+ (This is a helper class instead of making :class:`StreamReader` itself a
+ :class:`Protocol` subclass, because the :class:`StreamReader` has other
+ potential uses, and to prevent the user of the :class:`StreamReader` to
+ accidentally call inappropriate methods of the protocol.)
+
+ .. method:: connection_made(transport)
+
+ XXX
+
+ .. method:: connection_lost(exc)
+
+ XXX
+
+ .. method:: data_received(data)
+
+ XXX
+
+ .. method:: eof_received()
+
+ XXX
+
+ .. method:: pause_writing()
+
+ XXX
+
+ .. method:: resume_writing()
+
+ XXX
+
+
+Example
+=======
+
+Simple example querying HTTP headers of the URL passed on the command line::
+
+ import asyncio
+ import urllib.parse
+ import sys
+
+ @asyncio.coroutine
+ def print_http_headers(url):
+ url = urllib.parse.urlsplit(url)
+ reader, writer = yield from asyncio.open_connection(url.hostname, 80)
+ query = ('HEAD {url.path} HTTP/1.0\r\n'
+ 'Host: {url.hostname}\r\n'
+ '\r\n').format(url=url)
+ writer.write(query.encode('latin-1'))
+ while True:
+ line = yield from reader.readline()
+ if not line:
+ break
+ line = line.decode('latin1').rstrip()
+ if line:
+ print('HTTP header> %s' % line)
+
+ url = sys.argv[1]
+ loop = asyncio.get_event_loop()
+ task = asyncio.async(print_http_headers(url))
+ loop.run_until_complete(task)
+
+Usage::
+
+ python example.py http://example.com/path/page.html
+
diff --git a/Doc/library/asyncio-sync.rst b/Doc/library/asyncio-sync.rst
index 96ea012f71..e125951a22 100644
--- a/Doc/library/asyncio-sync.rst
+++ b/Doc/library/asyncio-sync.rst
@@ -7,6 +7,9 @@ Synchronization primitives
Locks
-----
+Lock
+^^^^
+
.. class:: Lock(\*, loop=None)
Primitive lock objects.
@@ -85,6 +88,9 @@ Locks
There is no return value.
+Event
+^^^^^
+
.. class:: Event(\*, loop=None)
An Event implementation, asynchronous equivalent to :class:`threading.Event`.
@@ -121,6 +127,9 @@ Locks
This method returns a :ref:`coroutine object <coroutine>`.
+Condition
+^^^^^^^^^
+
.. class:: Condition(\*, loop=None)
A Condition implementation, asynchronous equivalent to
@@ -181,6 +190,9 @@ Locks
Semaphores
----------
+Semaphore
+^^^^^^^^^
+
.. class:: Semaphore(value=1, \*, loop=None)
A Semaphore implementation.
@@ -218,6 +230,9 @@ Semaphores
larger than zero again, wake up that coroutine.
+BoundedSemaphore
+^^^^^^^^^^^^^^^^
+
.. class:: BoundedSemaphore(value=1, \*, loop=None)
A bounded semaphore implementation. Inherit from :class:`Semaphore`.
@@ -229,6 +244,9 @@ Semaphores
Queues
------
+Queue
+^^^^^
+
.. class:: Queue(maxsize=0, \*, loop=None)
A queue, useful for coordinating producer and consumer coroutines.
@@ -268,7 +286,7 @@ Queues
Remove and return an item from the queue.
Return an item if one is immediately available, else raise
- :exc:`~queue.Empty`.
+ :exc:`QueueEmpty`.
.. method:: put(item)
@@ -283,7 +301,7 @@ Queues
Put an item into the queue without blocking.
- If no free slot is immediately available, raise :exc:`~queue.Full`.
+ If no free slot is immediately available, raise :exc:`QueueFull`.
.. method:: qsize()
@@ -294,6 +312,9 @@ Queues
Number of items allowed in the queue.
+PriorityQueue
+^^^^^^^^^^^^^
+
.. class:: PriorityQueue
A subclass of :class:`Queue`; retrieves entries in priority order (lowest
@@ -302,12 +323,18 @@ Queues
Entries are typically tuples of the form: (priority number, data).
+LifoQueue
+^^^^^^^^^
+
.. class:: LifoQueue
A subclass of :class:`Queue` that retrieves most recently added entries
first.
+JoinableQueue
+^^^^^^^^^^^^^
+
.. class:: JoinableQueue
A subclass of :class:`Queue` with :meth:`task_done` and :meth:`join`
@@ -340,3 +367,19 @@ Queues
Raises :exc:`ValueError` if called more times than there were items
placed in the queue.
+
+Exceptions
+^^^^^^^^^^
+
+.. exception:: QueueEmpty
+
+ Exception raised when non-blocking :meth:`~Queue.get` (or
+ :meth:`~Queue.get_nowait`) is called
+ on a :class:`Queue` object which is empty.
+
+
+.. exception:: QueueFull
+
+ Exception raised when non-blocking :meth:`~Queue.put` (or
+ :meth:`~Queue.put_nowait`) is called
+ on a :class:`Queue` object which is full.
diff --git a/Doc/library/asyncio.rst b/Doc/library/asyncio.rst
index 2e0e0d5940..64e751ba3f 100644
--- a/Doc/library/asyncio.rst
+++ b/Doc/library/asyncio.rst
@@ -47,6 +47,7 @@ Table of content:
asyncio-eventloop.rst
asyncio-task.rst
asyncio-protocol.rst
+ asyncio-stream.rst
asyncio-sync.rst
asyncio-dev.rst
diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst
index 93538e4a73..0495737e8b 100644
--- a/Doc/library/concurrent.futures.rst
+++ b/Doc/library/concurrent.futures.rst
@@ -371,7 +371,8 @@ Module Functions
Returns an iterator over the :class:`Future` instances (possibly created by
different :class:`Executor` instances) given by *fs* that yields futures as
- they complete (finished or were cancelled). Any futures that completed
+ they complete (finished or were cancelled). Any futures given by *fs* that
+ are duplicated will be returned once. Any futures that completed
before :func:`as_completed` is called will be yielded first. The returned
iterator raises a :exc:`TimeoutError` if :meth:`~iterator.__next__` is
called and the result isn't available after *timeout* seconds from the
diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
index a3373e0bb8..e2c826c153 100644
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -89,22 +89,6 @@ Functions
.. versionchanged:: 3.3
Parent packages are automatically imported.
-.. function:: find_spec(name, path=None)
-
- Find the :term:`spec <module spec>` for a module, optionally within the
- specified *path*. If the module is in :attr:`sys.modules`, then
- ``sys.modules[name].__spec__`` is returned (unless the spec would be
- ``None`` or is not set, in which case :exc:`ValueError` is raised).
- Otherwise a search using :attr:`sys.meta_path` is done. ``None`` is
- returned if no spec is found.
-
- A dotted name does not have its parent implicitly imported as that requires
- loading them and that may not be desired. To properly import a submodule you
- will need to import all parent packages of the submodule and use the correct
- argument to *path*.
-
- .. versionadded:: 3.4
-
.. function:: find_loader(name, path=None)
Find the loader for a module, optionally within the specified *path*. If the
@@ -125,7 +109,7 @@ Functions
attribute is set to ``None``.
.. deprecated:: 3.4
- Use :func:`find_spec` instead.
+ Use :func:`importlib.util.find_spec` instead.
.. function:: invalidate_caches()
@@ -1111,6 +1095,22 @@ an :term:`importer`.
.. versionadded:: 3.3
+.. function:: find_spec(name, package=None)
+
+ Find the :term:`spec <module spec>` for a module, optionally relative to
+ the specified **package** name. If the module is in :attr:`sys.modules`,
+ then ``sys.modules[name].__spec__`` is returned (unless the spec would be
+ ``None`` or is not set, in which case :exc:`ValueError` is raised).
+ Otherwise a search using :attr:`sys.meta_path` is done. ``None`` is
+ returned if no spec is found.
+
+ If **name** is for a submodule (contains a dot), the parent module is
+ automatically imported.
+
+ **name** and **package** work the same as for :func:`import_module`.
+
+ .. versionadded:: 3.4
+
.. decorator:: module_for_loader
A :term:`decorator` for :meth:`importlib.abc.Loader.load_module`
diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst
index 4290aeb7c4..0695610960 100644
--- a/Doc/library/inspect.rst
+++ b/Doc/library/inspect.rst
@@ -429,6 +429,9 @@ function.
Accepts a wide range of python callables, from plain functions and classes to
:func:`functools.partial` objects.
+ Raises :exc:`ValueError` if no signature can be provided, and
+ :exc:`TypeError` if that type of object is not supported.
+
.. note::
Some callables may not be introspectable in certain implementations of
diff --git a/Doc/library/selectors.rst b/Doc/library/selectors.rst
index 98377c890f..4c322bd75a 100644
--- a/Doc/library/selectors.rst
+++ b/Doc/library/selectors.rst
@@ -98,6 +98,10 @@ below:
:class:`BaseSelector` and its concrete implementations support the
:term:`context manager` protocol.
+ .. attribute:: resolution
+
+ Resolution of the selector in seconds.
+
.. method:: register(fileobj, events, data=None)
Register a file object for selection, monitoring it for I/O events.
diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst
index b44a2fea41..cda63e4928 100644
--- a/Doc/whatsnew/3.3.rst
+++ b/Doc/whatsnew/3.3.rst
@@ -1767,7 +1767,7 @@ sched
select
------
-Solaris and derivatives platforms have a new class :class:`select.devpoll`
+Solaris and derivative platforms have a new class :class:`select.devpoll`
for high performance asynchronous sockets via :file:`/dev/poll`.
(Contributed by Jesús Cea Avión in :issue:`6397`.)
diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst
index 5d397fec26..1d889653d9 100644
--- a/Doc/whatsnew/3.4.rst
+++ b/Doc/whatsnew/3.4.rst
@@ -264,6 +264,9 @@ name of the codec responsible for producing the error::
>>> import codecs
>>> codecs.decode(b"abcdefgh", "hex")
+ Traceback (most recent call last):
+ File "/usr/lib/python3.4/encodings/hex_codec.py", line 20, in hex_decode
+ return (binascii.a2b_hex(input), len(input))
binascii.Error: Non-hexadecimal digit found
The above exception was the direct cause of the following exception:
@@ -273,6 +276,11 @@ name of the codec responsible for producing the error::
binascii.Error: decoding with 'hex' codec failed (Error: Non-hexadecimal digit found)
>>> codecs.encode("hello", "bz2")
+ Traceback (most recent call last):
+ File "/usr/lib/python3.4/encodings/bz2_codec.py", line 17, in bz2_encode
+ return (bz2.compress(input), len(input))
+ File "/usr/lib/python3.4/bz2.py", line 498, in compress
+ return comp.compress(data) + comp.flush()
TypeError: 'str' does not support the buffer interface
The above exception was the direct cause of the following exception:
diff --git a/Include/object.h b/Include/object.h
index a27846543e..015d216993 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -492,6 +492,13 @@ PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *
PyAPI_FUNC(unsigned int) PyType_ClearCache(void);
PyAPI_FUNC(void) PyType_Modified(PyTypeObject *);
+#ifndef Py_LIMITED_API
+PyAPI_FUNC(PyObject *)
+_PyType_GetDocFromInternalDoc(const char *, const char *);
+PyAPI_FUNC(PyObject *)
+_PyType_GetTextSignatureFromInternalDoc(const char *, const char *);
+#endif
+
/* Generic operations on objects */
struct _Py_Identifier;
#ifndef Py_LIMITED_API
diff --git a/Lib/asyncio/__init__.py b/Lib/asyncio/__init__.py
index 0d288d5a02..eb22c385b8 100644
--- a/Lib/asyncio/__init__.py
+++ b/Lib/asyncio/__init__.py
@@ -18,13 +18,14 @@ if sys.platform == 'win32':
import _overlapped # Will also be exported.
# This relies on each of the submodules having an __all__ variable.
-from .futures import *
from .events import *
+from .futures import *
from .locks import *
-from .transports import *
from .protocols import *
+from .queues import *
from .streams import *
from .tasks import *
+from .transports import *
if sys.platform == 'win32': # pragma: no cover
from .windows_events import *
@@ -32,10 +33,11 @@ else:
from .unix_events import * # pragma: no cover
-__all__ = (futures.__all__ +
- events.__all__ +
+__all__ = (events.__all__ +
+ futures.__all__ +
locks.__all__ +
- transports.__all__ +
protocols.__all__ +
+ queues.__all__ +
streams.__all__ +
- tasks.__all__)
+ tasks.__all__ +
+ transports.__all__)
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index 72201aa590..5694f296fb 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -96,6 +96,7 @@ class BaseEventLoop(events.AbstractEventLoop):
self._default_executor = None
self._internal_fds = 0
self._running = False
+ self._granularity = time.get_clock_info('monotonic').resolution
def _make_socket_transport(self, sock, protocol, waiter=None, *,
extra=None, server=None):
@@ -628,7 +629,7 @@ class BaseEventLoop(events.AbstractEventLoop):
self._process_events(event_list)
# Handle 'later' callbacks that are ready.
- now = self.time()
+ now = self.time() + self._granularity
while self._scheduled:
handle = self._scheduled[0]
if handle._when > now:
diff --git a/Lib/asyncio/base_subprocess.py b/Lib/asyncio/base_subprocess.py
index d15fb159d9..c5efda79b1 100644
--- a/Lib/asyncio/base_subprocess.py
+++ b/Lib/asyncio/base_subprocess.py
@@ -114,7 +114,6 @@ class BaseSubprocessTransport(transports.SubprocessTransport):
assert returncode is not None, returncode
assert self._returncode is None, self._returncode
self._returncode = returncode
- self._loop._subprocess_closed(self)
self._call(self._protocol.process_exited)
self._try_finish()
diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py
index 9fdb93745b..29c4434a62 100644
--- a/Lib/asyncio/locks.py
+++ b/Lib/asyncio/locks.py
@@ -9,6 +9,36 @@ from . import futures
from . import tasks
+class _ContextManager:
+ """Context manager.
+
+ This enables the following idiom for acquiring and releasing a
+ lock around a block:
+
+ with (yield from lock):
+ <block>
+
+ while failing loudly when accidentally using:
+
+ with lock:
+ <block>
+ """
+
+ def __init__(self, lock):
+ self._lock = lock
+
+ def __enter__(self):
+ # We have no use for the "as ..." clause in the with
+ # statement for locks.
+ return None
+
+ def __exit__(self, *args):
+ try:
+ self._lock.release()
+ finally:
+ self._lock = None # Crudely prevent reuse.
+
+
class Lock:
"""Primitive lock objects.
@@ -124,17 +154,29 @@ class Lock:
raise RuntimeError('Lock is not acquired.')
def __enter__(self):
- if not self._locked:
- raise RuntimeError(
- '"yield from" should be used as context manager expression')
- return True
+ raise RuntimeError(
+ '"yield from" should be used as context manager expression')
def __exit__(self, *args):
- self.release()
+ # This must exist because __enter__ exists, even though that
+ # always raises; that's how the with-statement works.
+ pass
def __iter__(self):
+ # This is not a coroutine. It is meant to enable the idiom:
+ #
+ # with (yield from lock):
+ # <block>
+ #
+ # as an alternative to:
+ #
+ # yield from lock.acquire()
+ # try:
+ # <block>
+ # finally:
+ # lock.release()
yield from self.acquire()
- return self
+ return _ContextManager(self)
class Event:
@@ -311,14 +353,16 @@ class Condition:
self.notify(len(self._waiters))
def __enter__(self):
- return self._lock.__enter__()
+ raise RuntimeError(
+ '"yield from" should be used as context manager expression')
def __exit__(self, *args):
- return self._lock.__exit__(*args)
+ pass
def __iter__(self):
+ # See comment in Lock.__iter__().
yield from self.acquire()
- return self
+ return _ContextManager(self)
class Semaphore:
@@ -341,7 +385,6 @@ class Semaphore:
raise ValueError("Semaphore initial value must be >= 0")
self._value = value
self._waiters = collections.deque()
- self._locked = (value == 0)
if loop is not None:
self._loop = loop
else:
@@ -349,7 +392,7 @@ class Semaphore:
def __repr__(self):
res = super().__repr__()
- extra = 'locked' if self._locked else 'unlocked,value:{}'.format(
+ extra = 'locked' if self.locked() else 'unlocked,value:{}'.format(
self._value)
if self._waiters:
extra = '{},waiters:{}'.format(extra, len(self._waiters))
@@ -357,7 +400,7 @@ class Semaphore:
def locked(self):
"""Returns True if semaphore can not be acquired immediately."""
- return self._locked
+ return self._value == 0
@tasks.coroutine
def acquire(self):
@@ -371,8 +414,6 @@ class Semaphore:
"""
if not self._waiters and self._value > 0:
self._value -= 1
- if self._value == 0:
- self._locked = True
return True
fut = futures.Future(loop=self._loop)
@@ -380,8 +421,6 @@ class Semaphore:
try:
yield from fut
self._value -= 1
- if self._value == 0:
- self._locked = True
return True
finally:
self._waiters.remove(fut)
@@ -392,23 +431,22 @@ class Semaphore:
become larger than zero again, wake up that coroutine.
"""
self._value += 1
- self._locked = False
for waiter in self._waiters:
if not waiter.done():
waiter.set_result(True)
break
def __enter__(self):
- # TODO: This is questionable. How do we know the user actually
- # wrote "with (yield from sema)" instead of "with sema"?
- return True
+ raise RuntimeError(
+ '"yield from" should be used as context manager expression')
def __exit__(self, *args):
- self.release()
+ pass
def __iter__(self):
+ # See comment in Lock.__iter__().
yield from self.acquire()
- return self
+ return _ContextManager(self)
class BoundedSemaphore(Semaphore):
diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py
index ba5169e9d8..3b44f24835 100644
--- a/Lib/asyncio/proactor_events.py
+++ b/Lib/asyncio/proactor_events.py
@@ -4,6 +4,8 @@ A proactor is a "notify-on-completion" multiplexer. Currently a
proactor is only implemented on Windows with IOCP.
"""
+__all__ = ['BaseProactorEventLoop']
+
import socket
from . import base_events
diff --git a/Lib/asyncio/queues.py b/Lib/asyncio/queues.py
index e900278fb7..bd62c606c0 100644
--- a/Lib/asyncio/queues.py
+++ b/Lib/asyncio/queues.py
@@ -1,11 +1,10 @@
"""Queues"""
__all__ = ['Queue', 'PriorityQueue', 'LifoQueue', 'JoinableQueue',
- 'Full', 'Empty']
+ 'QueueFull', 'QueueEmpty']
import collections
import heapq
-import queue
from . import events
from . import futures
@@ -13,9 +12,20 @@ from . import locks
from .tasks import coroutine
-# Re-export queue.Full and .Empty exceptions.
-Full = queue.Full
-Empty = queue.Empty
+class QueueEmpty(Exception):
+ 'Exception raised by Queue.get(block=0)/get_nowait().'
+ pass
+
+
+class QueueFull(Exception):
+ 'Exception raised by Queue.put(block=0)/put_nowait().'
+ pass
+
+
+# Un-exported aliases for temporary backward compatibility.
+# Will disappear soon.
+Full = QueueFull
+Empty = QueueEmpty
class Queue:
@@ -134,7 +144,7 @@ class Queue:
def put_nowait(self, item):
"""Put an item into the queue without blocking.
- If no free slot is immediately available, raise Full.
+ If no free slot is immediately available, raise QueueFull.
"""
self._consume_done_getters()
if self._getters:
@@ -149,7 +159,7 @@ class Queue:
getter.set_result(self._get())
elif self._maxsize > 0 and self._maxsize == self.qsize():
- raise Full
+ raise QueueFull
else:
self._put(item)
@@ -184,7 +194,7 @@ class Queue:
def get_nowait(self):
"""Remove and return an item from the queue.
- Return an item if one is immediately available, else raise Empty.
+ Return an item if one is immediately available, else raise QueueEmpty.
"""
self._consume_done_putters()
if self._putters:
@@ -199,7 +209,7 @@ class Queue:
elif self.qsize():
return self._get()
else:
- raise Empty
+ raise QueueEmpty
class PriorityQueue(Queue):
diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py
index 19caf79d05..94408f82b4 100644
--- a/Lib/asyncio/selector_events.py
+++ b/Lib/asyncio/selector_events.py
@@ -4,6 +4,8 @@ A selector is a "notify-when-ready" multiplexer. For a subclass which
also includes support for signal handling, see the unix_events sub-module.
"""
+__all__ = ['BaseSelectorEventLoop']
+
import collections
import errno
import socket
@@ -34,6 +36,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
selector = selectors.DefaultSelector()
logger.debug('Using selector: %s', selector.__class__.__name__)
self._selector = selector
+ self._granularity = max(selector.resolution, self._granularity)
self._make_self_pipe()
def _make_socket_transport(self, sock, protocol, waiter=None, *,
diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py
index f01f8629a7..10d3591fba 100644
--- a/Lib/asyncio/streams.py
+++ b/Lib/asyncio/streams.py
@@ -1,7 +1,7 @@
"""Stream-related things."""
__all__ = ['StreamReader', 'StreamWriter', 'StreamReaderProtocol',
- 'open_connection', 'start_server',
+ 'open_connection', 'start_server', 'IncompleteReadError',
]
import collections
@@ -14,6 +14,19 @@ from . import tasks
_DEFAULT_LIMIT = 2**16
+class IncompleteReadError(EOFError):
+ """
+ Incomplete read error. Attributes:
+
+ - partial: read bytes string before the end of stream was reached
+ - expected: total number of expected bytes
+ """
+ def __init__(self, partial, expected):
+ EOFError.__init__(self, "%s bytes read on a total of %s expected bytes"
+ % (len(partial), expected))
+ self.partial = partial
+ self.expected = expected
+
@tasks.coroutine
def open_connection(host=None, port=None, *,
@@ -21,7 +34,7 @@ def open_connection(host=None, port=None, *,
"""A wrapper for create_connection() returning a (reader, writer) pair.
The reader returned is a StreamReader instance; the writer is a
- Transport.
+ StreamWriter instance.
The arguments are all the usual arguments to create_connection()
except protocol_factory; most common are positional host and port,
@@ -284,6 +297,16 @@ class StreamReader:
else:
self._paused = True
+ def _create_waiter(self, func_name):
+ # StreamReader uses a future to link the protocol feed_data() method
+ # to a read coroutine. Running two read coroutines at the same time
+ # would have an unexpected behaviour. It would not possible to know
+ # which coroutine would get the next data.
+ if self._waiter is not None:
+ raise RuntimeError('%s() called while another coroutine is '
+ 'already waiting for incoming data' % func_name)
+ return futures.Future(loop=self._loop)
+
@tasks.coroutine
def readline(self):
if self._exception is not None:
@@ -318,8 +341,7 @@ class StreamReader:
break
if not_enough:
- assert self._waiter is None
- self._waiter = futures.Future(loop=self._loop)
+ self._waiter = self._create_waiter('readline')
try:
yield from self._waiter
finally:
@@ -341,16 +363,14 @@ class StreamReader:
if n < 0:
while not self._eof:
- assert not self._waiter
- self._waiter = futures.Future(loop=self._loop)
+ self._waiter = self._create_waiter('read')
try:
yield from self._waiter
finally:
self._waiter = None
else:
if not self._byte_count and not self._eof:
- assert not self._waiter
- self._waiter = futures.Future(loop=self._loop)
+ self._waiter = self._create_waiter('read')
try:
yield from self._waiter
finally:
@@ -396,12 +416,9 @@ class StreamReader:
while n > 0:
block = yield from self.read(n)
if not block:
- break
+ partial = b''.join(blocks)
+ raise IncompleteReadError(partial, len(partial) + n)
blocks.append(block)
n -= len(block)
- # TODO: Raise EOFError if we break before n == 0? (That would
- # be a change in specification, but I've always had to add an
- # explicit size check to the caller.)
-
return b''.join(blocks)
diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py
index 42413dc00f..b52933fc6c 100644
--- a/Lib/asyncio/tasks.py
+++ b/Lib/asyncio/tasks.py
@@ -382,8 +382,9 @@ def wait_for(fut, timeout, *, loop=None):
Coroutine will be wrapped in Task.
- Returns result of the Future or coroutine. Raises TimeoutError when
- timeout occurs.
+ Returns result of the Future or coroutine. When a timeout occurs,
+ it cancels the task and raises TimeoutError. To avoid the task
+ cancellation, wrap it in shield().
Usage:
@@ -405,6 +406,7 @@ def wait_for(fut, timeout, *, loop=None):
return fut.result()
else:
fut.remove_done_callback(cb)
+ fut.cancel()
raise futures.TimeoutError()
finally:
timeout_handle.cancel()
diff --git a/Lib/asyncio/test_utils.py b/Lib/asyncio/test_utils.py
index ccb445418d..42b9cd75ae 100644
--- a/Lib/asyncio/test_utils.py
+++ b/Lib/asyncio/test_utils.py
@@ -144,6 +144,10 @@ class TestSelector(selectors.BaseSelector):
def __init__(self):
self.keys = {}
+ @property
+ def resolution(self):
+ return 1e-3
+
def register(self, fileobj, events, data=None):
key = selectors.SelectorKey(fileobj, 0, events, data)
self.keys[fileobj] = key
diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
index 24da3274f8..219c88a0ff 100644
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -169,9 +169,6 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
def _child_watcher_callback(self, pid, returncode, transp):
self.call_soon_threadsafe(transp._process_exited, returncode)
- def _subprocess_closed(self, transp):
- pass
-
def _set_nonblocking(fd):
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
@@ -259,9 +256,11 @@ class _UnixWritePipeTransport(transports.WriteTransport):
self._fileno = pipe.fileno()
mode = os.fstat(self._fileno).st_mode
is_socket = stat.S_ISSOCK(mode)
- is_pipe = stat.S_ISFIFO(mode)
- if not (is_socket or is_pipe):
- raise ValueError("Pipe transport is for pipes/sockets only.")
+ if not (is_socket or
+ stat.S_ISFIFO(mode) or
+ stat.S_ISCHR(mode)):
+ raise ValueError("Pipe transport is only for "
+ "pipes, sockets and character devices")
_set_nonblocking(self._fileno)
self._protocol = protocol
self._buffer = []
@@ -639,22 +638,16 @@ class FastChildWatcher(BaseChildWatcher):
def add_child_handler(self, pid, callback, *args):
assert self._forks, "Must use the context manager"
+ with self._lock:
+ try:
+ returncode = self._zombies.pop(pid)
+ except KeyError:
+ # The child is running.
+ self._callbacks[pid] = callback, args
+ return
- self._callbacks[pid] = callback, args
-
- try:
- # Ensure that the child is not already terminated.
- # (raise KeyError if still alive)
- returncode = self._zombies.pop(pid)
-
- # Child is dead, therefore we can fire the callback immediately.
- # First we remove it from the dict.
- # (raise KeyError if .remove_child_handler() was called in-between)
- del self._callbacks[pid]
- except KeyError:
- pass
- else:
- callback(pid, returncode, *args)
+ # The child is dead already. We can fire the callback.
+ callback(pid, returncode, *args)
def remove_child_handler(self, pid):
try:
@@ -679,16 +672,18 @@ class FastChildWatcher(BaseChildWatcher):
returncode = self._compute_returncode(status)
- try:
- callback, args = self._callbacks.pop(pid)
- except KeyError:
- # unknown child
- with self._lock:
+ with self._lock:
+ try:
+ callback, args = self._callbacks.pop(pid)
+ except KeyError:
+ # unknown child
if self._forks:
# It may not be registered yet.
self._zombies[pid] = returncode
continue
+ callback = None
+ if callback is None:
logger.warning(
"Caught subprocess termination from unknown pid: "
"%d -> %d", pid, returncode)
diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py
index 2e9ec69734..3c21e43bd6 100644
--- a/Lib/asyncio/windows_events.py
+++ b/Lib/asyncio/windows_events.py
@@ -178,9 +178,6 @@ class ProactorEventLoop(proactor_events.BaseProactorEventLoop):
yield from transp._post_init()
return transp
- def _subprocess_closed(self, transport):
- pass
-
class IocpProactor:
"""Proactor implementation using IOCP."""
diff --git a/Lib/codecs.py b/Lib/codecs.py
index 2e2e7555a4..c2065dafa2 100644
--- a/Lib/codecs.py
+++ b/Lib/codecs.py
@@ -475,15 +475,12 @@ class StreamReader(Codec):
# read until we get the required number of characters (if available)
while True:
# can the request be satisfied from the character buffer?
- if chars < 0:
- if size < 0:
- if self.charbuffer:
- break
- elif len(self.charbuffer) >= size:
- break
- else:
+ if chars >= 0:
if len(self.charbuffer) >= chars:
break
+ elif size >= 0:
+ if len(self.charbuffer) >= size:
+ break
# we need more data
if size < 0:
newdata = self.stream.read()
@@ -491,6 +488,8 @@ class StreamReader(Codec):
newdata = self.stream.read(size)
# decode bytes (those remaining from the last call included)
data = self.bytebuffer + newdata
+ if not data:
+ break
try:
newchars, decodedbytes = self.decode(data, self.errors)
except UnicodeDecodeError as exc:
diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py
index 3d0328049f..c3b1f017e0 100644
--- a/Lib/concurrent/futures/_base.py
+++ b/Lib/concurrent/futures/_base.py
@@ -181,7 +181,8 @@ def as_completed(fs, timeout=None):
Returns:
An iterator that yields the given Futures as they complete (finished or
- cancelled).
+ cancelled). If any given Futures are duplicated, they will be returned
+ once.
Raises:
TimeoutError: If the entire result iterator could not be generated
@@ -190,11 +191,12 @@ def as_completed(fs, timeout=None):
if timeout is not None:
end_time = timeout + time.time()
+ fs = set(fs)
with _AcquireFutures(fs):
finished = set(
f for f in fs
if f._state in [CANCELLED_AND_NOTIFIED, FINISHED])
- pending = set(fs) - finished
+ pending = fs - finished
waiter = _create_and_install_waiters(fs, _AS_COMPLETED)
try:
diff --git a/Lib/contextlib.py b/Lib/contextlib.py
index ca7a79ddd1..82ee955a8b 100644
--- a/Lib/contextlib.py
+++ b/Lib/contextlib.py
@@ -298,7 +298,7 @@ class ExitStack(object):
# we were actually nesting multiple with statements
frame_exc = sys.exc_info()[1]
def _fix_exception_context(new_exc, old_exc):
- # Context isn't what we want, so find the end of the chain
+ # Context may not be correct, so find the end of the chain
while 1:
exc_context = new_exc.__context__
if exc_context is old_exc:
@@ -306,8 +306,6 @@ class ExitStack(object):
return
if exc_context is None or exc_context is frame_exc:
break
- details = id(new_exc), id(old_exc), id(exc_context)
- raise Exception(str(details))
new_exc = exc_context
# Change the end of the chain to point to the exception
# we expect it to reference
diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py
index 26d411f619..fe51fde2d2 100644
--- a/Lib/ensurepip/__init__.py
+++ b/Lib/ensurepip/__init__.py
@@ -8,9 +8,9 @@ import tempfile
__all__ = ["version", "bootstrap"]
-_SETUPTOOLS_VERSION = "2.0.2"
+_SETUPTOOLS_VERSION = "2.1"
-_PIP_VERSION = "1.5"
+_PIP_VERSION = "1.5.2"
# pip currently requires ssl support, so we try to provide a nicer
# error message when that is missing (http://bugs.python.org/issue19744)
diff --git a/Lib/ensurepip/_bundled/pip-1.5-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/pip-1.5.2-py2.py3-none-any.whl
index dd7ca2e634..9133eed971 100644
--- a/Lib/ensurepip/_bundled/pip-1.5-py2.py3-none-any.whl
+++ b/Lib/ensurepip/_bundled/pip-1.5.2-py2.py3-none-any.whl
Binary files differ
diff --git a/Lib/ensurepip/_bundled/setuptools-2.0.2-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-2.1-py2.py3-none-any.whl
index 267eeff238..ed77b59e63 100644
--- a/Lib/ensurepip/_bundled/setuptools-2.0.2-py2.py3-none-any.whl
+++ b/Lib/ensurepip/_bundled/setuptools-2.1-py2.py3-none-any.whl
Binary files differ
diff --git a/Lib/http/server.py b/Lib/http/server.py
index f17074700d..f019bd9fc3 100644
--- a/Lib/http/server.py
+++ b/Lib/http/server.py
@@ -678,8 +678,10 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
"""Serve a GET request."""
f = self.send_head()
if f:
- self.copyfile(f, self.wfile)
- f.close()
+ try:
+ self.copyfile(f, self.wfile)
+ finally:
+ f.close()
def do_HEAD(self):
"""Serve a HEAD request."""
@@ -720,13 +722,17 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
except OSError:
self.send_error(404, "File not found")
return None
- self.send_response(200)
- self.send_header("Content-type", ctype)
- fs = os.fstat(f.fileno())
- self.send_header("Content-Length", str(fs[6]))
- self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
- self.end_headers()
- return f
+ try:
+ self.send_response(200)
+ self.send_header("Content-type", ctype)
+ fs = os.fstat(f.fileno())
+ self.send_header("Content-Length", str(fs[6]))
+ self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
+ self.end_headers()
+ return f
+ except:
+ f.close()
+ raise
def list_directory(self, path):
"""Helper to produce a directory listing (absent index.html).
diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py
index 390ffab9b7..d18305783a 100644
--- a/Lib/idlelib/EditorWindow.py
+++ b/Lib/idlelib/EditorWindow.py
@@ -1,5 +1,6 @@
import importlib
import importlib.abc
+import importlib.util
import os
from platform import python_version
import re
@@ -660,7 +661,7 @@ class EditorWindow(object):
return
# XXX Ought to insert current file's directory in front of path
try:
- spec = importlib.find_spec(name)
+ spec = importlib.util.find_spec(name)
except (ValueError, ImportError) as msg:
tkMessageBox.showerror("Import error", str(msg), parent=self.text)
return
diff --git a/Lib/idlelib/idle_test/test_calltips.py b/Lib/idlelib/idle_test/test_calltips.py
index f27994f3f9..4bf5e7e5dc 100644
--- a/Lib/idlelib/idle_test/test_calltips.py
+++ b/Lib/idlelib/idle_test/test_calltips.py
@@ -66,7 +66,6 @@ class Get_signatureTest(unittest.TestCase):
gtest(SB(), default_tip)
def test_signature_wrap(self):
- #print(signature(textwrap.TextWrapper))
self.assertEqual(signature(textwrap.TextWrapper), '''\
(width=70, initial_indent='', subsequent_indent='', expand_tabs=True,
replace_whitespace=True, fix_sentence_endings=False, break_long_words=True,
diff --git a/Lib/imghdr.py b/Lib/imghdr.py
index 0cba063a9c..add2ea8898 100644
--- a/Lib/imghdr.py
+++ b/Lib/imghdr.py
@@ -7,18 +7,16 @@ __all__ = ["what"]
#-------------------------#
def what(file, h=None):
- if h is None:
- if isinstance(file, str):
- f = open(file, 'rb')
- h = f.read(32)
- else:
- location = file.tell()
- h = file.read(32)
- file.seek(location)
- f = None
- else:
- f = None
+ f = None
try:
+ if h is None:
+ if isinstance(file, str):
+ f = open(file, 'rb')
+ h = f.read(32)
+ else:
+ location = file.tell()
+ h = file.read(32)
+ file.seek(location)
for tf in tests:
res = tf(h, f)
if res:
diff --git a/Lib/importlib/__init__.py b/Lib/importlib/__init__.py
index c66e46cc93..f6adc5cdcf 100644
--- a/Lib/importlib/__init__.py
+++ b/Lib/importlib/__init__.py
@@ -11,8 +11,6 @@ __all__ = ['__import__', 'import_module', 'invalidate_caches', 'reload']
# initialised below if the frozen one is not available).
import _imp # Just the builtin component, NOT the full Python module
import sys
-import types
-import warnings
try:
import _frozen_importlib as _bootstrap
@@ -34,6 +32,10 @@ _r_long = _bootstrap._r_long
# Fully bootstrapped at this point, import whatever you like, circular
# dependencies and startup overhead minimisation permitting :)
+import types
+import warnings
+
+
# Public API #########################################################
from ._bootstrap import __import__
@@ -47,47 +49,16 @@ def invalidate_caches():
finder.invalidate_caches()
-def find_spec(name, path=None):
- """Return the spec for the specified module.
-
- First, sys.modules is checked to see if the module was already imported. If
- so, then sys.modules[name].__spec__ is returned. If that happens to be
- set to None, then ValueError is raised. If the module is not in
- sys.modules, then sys.meta_path is searched for a suitable spec with the
- value of 'path' given to the finders. None is returned if no spec could
- be found.
-
- Dotted names do not have their parent packages implicitly imported. You will
- most likely need to explicitly import all parent packages in the proper
- order for a submodule to get the correct spec.
-
- """
- if name not in sys.modules:
- return _bootstrap._find_spec(name, path)
- else:
- module = sys.modules[name]
- if module is None:
- return None
- try:
- spec = module.__spec__
- except AttributeError:
- raise ValueError('{}.__spec__ is not set'.format(name))
- else:
- if spec is None:
- raise ValueError('{}.__spec__ is None'.format(name))
- return spec
-
-
def find_loader(name, path=None):
"""Return the loader for the specified module.
This is a backward-compatible wrapper around find_spec().
- This function is deprecated in favor of importlib.find_spec().
+ This function is deprecated in favor of importlib.util.find_spec().
"""
- warnings.warn('Use importlib.find_spec() instead.', DeprecationWarning,
- stacklevel=2)
+ warnings.warn('Use importlib.util.find_spec() instead.',
+ DeprecationWarning, stacklevel=2)
try:
loader = sys.modules[name].__loader__
if loader is None:
@@ -167,7 +138,8 @@ def reload(module):
pkgpath = parent.__path__
else:
pkgpath = None
- spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, module)
+ target = module
+ spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, target)
methods = _bootstrap._SpecMethods(spec)
methods.exec(module)
# The module may have replaced itself in sys.modules!
diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py
index 42fc9eae93..6d73b1d7b6 100644
--- a/Lib/importlib/util.py
+++ b/Lib/importlib/util.py
@@ -7,6 +7,7 @@ from ._bootstrap import source_from_cache
from ._bootstrap import spec_from_loader
from ._bootstrap import spec_from_file_location
from ._bootstrap import _resolve_name
+from ._bootstrap import _find_spec
from contextlib import contextmanager
import functools
@@ -29,6 +30,77 @@ def resolve_name(name, package):
return _resolve_name(name[level:], package, level)
+def _find_spec_from_path(name, path=None):
+ """Return the spec for the specified module.
+
+ First, sys.modules is checked to see if the module was already imported. If
+ so, then sys.modules[name].__spec__ is returned. If that happens to be
+ set to None, then ValueError is raised. If the module is not in
+ sys.modules, then sys.meta_path is searched for a suitable spec with the
+ value of 'path' given to the finders. None is returned if no spec could
+ be found.
+
+ Dotted names do not have their parent packages implicitly imported. You will
+ most likely need to explicitly import all parent packages in the proper
+ order for a submodule to get the correct spec.
+
+ """
+ if name not in sys.modules:
+ return _find_spec(name, path)
+ else:
+ module = sys.modules[name]
+ if module is None:
+ return None
+ try:
+ spec = module.__spec__
+ except AttributeError:
+ raise ValueError('{}.__spec__ is not set'.format(name))
+ else:
+ if spec is None:
+ raise ValueError('{}.__spec__ is None'.format(name))
+ return spec
+
+
+def find_spec(name, package=None):
+ """Return the spec for the specified module.
+
+ First, sys.modules is checked to see if the module was already imported. If
+ so, then sys.modules[name].__spec__ is returned. If that happens to be
+ set to None, then ValueError is raised. If the module is not in
+ sys.modules, then sys.meta_path is searched for a suitable spec with the
+ value of 'path' given to the finders. None is returned if no spec could
+ be found.
+
+ If the name is for submodule (contains a dot), the parent module is
+ automatically imported.
+
+ The name and package arguments work the same as importlib.import_module().
+ In other words, relative module names (with leading dots) work.
+
+ """
+ fullname = resolve_name(name, package) if name.startswith('.') else name
+ if fullname not in sys.modules:
+ parent_name = fullname.rpartition('.')[0]
+ if parent_name:
+ # Use builtins.__import__() in case someone replaced it.
+ parent = __import__(parent_name, fromlist=['__path__'])
+ return _find_spec(fullname, parent.__path__)
+ else:
+ return _find_spec(fullname, None)
+ else:
+ module = sys.modules[fullname]
+ if module is None:
+ return None
+ try:
+ spec = module.__spec__
+ except AttributeError:
+ raise ValueError('{}.__spec__ is not set'.format(name))
+ else:
+ if spec is None:
+ raise ValueError('{}.__spec__ is None'.format(name))
+ return spec
+
+
@contextmanager
def _module_to_load(name):
is_reload = name in sys.modules
diff --git a/Lib/inspect.py b/Lib/inspect.py
index d6bd8cdb62..781a5320a0 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -1419,9 +1419,11 @@ def getgeneratorlocals(generator):
_WrapperDescriptor = type(type.__call__)
_MethodWrapper = type(all.__call__)
+_ClassMethodWrapper = type(int.__dict__['from_bytes'])
_NonUserDefinedCallables = (_WrapperDescriptor,
_MethodWrapper,
+ _ClassMethodWrapper,
types.BuiltinFunctionType)
@@ -1443,6 +1445,13 @@ def signature(obj):
if not callable(obj):
raise TypeError('{!r} is not a callable object'.format(obj))
+ if (isinstance(obj, _NonUserDefinedCallables) or
+ ismethoddescriptor(obj) or
+ isinstance(obj, type)):
+ sig = Signature.from_builtin(obj)
+ if sig:
+ return sig
+
if isinstance(obj, types.MethodType):
# In this case we skip the first parameter of the underlying
# function (usually `self` or `cls`).
@@ -1460,13 +1469,9 @@ def signature(obj):
if sig is not None:
return sig
-
if isinstance(obj, types.FunctionType):
return Signature.from_function(obj)
- if isinstance(obj, types.BuiltinFunctionType):
- return Signature.from_builtin(obj)
-
if isinstance(obj, functools.partial):
sig = signature(obj.func)
@@ -2033,7 +2038,7 @@ class Signature:
name = parse_name(name_node)
if name is invalid:
return None
- if default_node:
+ if default_node and default_node is not _empty:
try:
default_node = RewriteSymbolics().visit(default_node)
o = ast.literal_eval(default_node)
@@ -2066,6 +2071,23 @@ class Signature:
kind = Parameter.VAR_KEYWORD
p(f.args.kwarg, empty)
+ if parameters and (hasattr(func, '__self__') or
+ isinstance(func, _WrapperDescriptor,) or
+ ismethoddescriptor(func)
+ ):
+ name = parameters[0].name
+ if name not in ('self', 'module', 'type'):
+ pass
+ elif getattr(func, '__self__', None):
+ # strip off self (it's already been bound)
+ p = parameters.pop(0)
+ if not p.name in ('self', 'module', 'type'):
+ raise ValueError('Unexpected name ' + repr(p.name) + ', expected self/module/cls/type')
+ else:
+ # for builtins, self parameter is always positional-only!
+ p = parameters[0].replace(kind=Parameter.POSITIONAL_ONLY)
+ parameters[0] = p
+
return cls(parameters, return_annotation=cls.empty)
diff --git a/Lib/mailcap.py b/Lib/mailcap.py
index bd61b0b0ae..97e303522c 100644
--- a/Lib/mailcap.py
+++ b/Lib/mailcap.py
@@ -22,8 +22,8 @@ def getcaps():
fp = open(mailcap, 'r')
except OSError:
continue
- morecaps = readmailcapfile(fp)
- fp.close()
+ with fp:
+ morecaps = readmailcapfile(fp)
for key, value in morecaps.items():
if not key in caps:
caps[key] = value
diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py
index d7161f8134..b98c8749f6 100644
--- a/Lib/mimetypes.py
+++ b/Lib/mimetypes.py
@@ -363,9 +363,10 @@ def read_mime_types(file):
f = open(file)
except OSError:
return None
- db = MimeTypes()
- db.readfp(f, True)
- return db.types_map[True]
+ with f:
+ db = MimeTypes()
+ db.readfp(f, True)
+ return db.types_map[True]
def _default_mime_types():
diff --git a/Lib/pkgutil.py b/Lib/pkgutil.py
index 7beae1203a..326657aa88 100644
--- a/Lib/pkgutil.py
+++ b/Lib/pkgutil.py
@@ -611,7 +611,7 @@ def get_data(package, resource):
which does not support get_data(), then None is returned.
"""
- spec = importlib.find_spec(package)
+ spec = importlib.util.find_spec(package)
if spec is None:
return None
loader = spec.loader
diff --git a/Lib/pyclbr.py b/Lib/pyclbr.py
index a8d2b1fe56..dd58ada0aa 100644
--- a/Lib/pyclbr.py
+++ b/Lib/pyclbr.py
@@ -42,7 +42,7 @@ Instances of this class have the following instance variables:
import io
import os
import sys
-import importlib
+import importlib.util
import tokenize
from token import NAME, DEDENT, OP
from operator import itemgetter
@@ -141,7 +141,7 @@ def _readmodule(module, path, inpackage=None):
else:
search_path = path + sys.path
# XXX This will change once issue19944 lands.
- spec = importlib.find_spec(fullmodule, search_path)
+ spec = importlib.util._find_spec_from_path(fullmodule, search_path)
fname = spec.loader.get_filename(fullmodule)
_modules[fullmodule] = dict
if spec.loader.is_package(fullmodule):
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index 9f626929e2..cf164ccfca 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -925,7 +925,10 @@ class HTMLDoc(Doc):
anchor, name, reallink)
argspec = None
if inspect.isfunction(object) or inspect.isbuiltin(object):
- signature = inspect.signature(object)
+ try:
+ signature = inspect.signature(object)
+ except (ValueError, TypeError):
+ signature = None
if signature:
argspec = str(signature)
if realname == '<lambda>':
@@ -1319,8 +1322,12 @@ location listed above.
skipdocs = 1
title = self.bold(name) + ' = ' + realname
argspec = None
- if inspect.isfunction(object) or inspect.isbuiltin(object):
- signature = inspect.signature(object)
+
+ if inspect.isroutine(object):
+ try:
+ signature = inspect.signature(object)
+ except (ValueError, TypeError):
+ signature = None
if signature:
argspec = str(signature)
if realname == '<lambda>':
diff --git a/Lib/runpy.py b/Lib/runpy.py
index dc08f4eae9..577deb29b8 100644
--- a/Lib/runpy.py
+++ b/Lib/runpy.py
@@ -13,9 +13,8 @@ importers when locating support scripts as well as when importing modules.
import os
import sys
import importlib.machinery # importlib first so we can test #15386 via -m
+import importlib.util
import types
-from importlib import find_spec
-from importlib.util import spec_from_loader
from pkgutil import read_code, get_importer
__all__ = [
@@ -100,33 +99,16 @@ def _run_module_code(code, init_globals=None,
# may be cleared when the temporary module goes away
return mod_globals.copy()
-
-def _fixed_find_spec(mod_name):
- # find_spec has the same annoying behaviour as find_loader did (it
- # fails to work properly for dotted names), so this is a fixed version
- # ala pkgutil.get_loader
- if mod_name.startswith('.'):
- msg = "Relative module name {!r} not supported".format(mod_name)
- raise ImportError(msg)
- path = None
- pkg_name = mod_name.rpartition(".")[0]
- if pkg_name:
- pkg = importlib.import_module(pkg_name)
- path = getattr(pkg, "__path__", None)
- if path is None:
- return None
+# Helper to get the loader, code and filename for a module
+def _get_module_details(mod_name):
try:
- return importlib.find_spec(mod_name, path)
+ spec = importlib.util.find_spec(mod_name)
except (ImportError, AttributeError, TypeError, ValueError) as ex:
# This hack fixes an impedance mismatch between pkgutil and
# importlib, where the latter raises other errors for cases where
# pkgutil previously raised ImportError
msg = "Error while finding spec for {!r} ({}: {})"
raise ImportError(msg.format(mod_name, type(ex), ex)) from ex
-
-# Helper to get the loader, code and filename for a module
-def _get_module_details(mod_name):
- spec = _fixed_find_spec(mod_name)
if spec is None:
raise ImportError("No module named %s" % mod_name)
if spec.submodule_search_locations is not None:
diff --git a/Lib/selectors.py b/Lib/selectors.py
index 1bdf972cdf..b1b530afcb 100644
--- a/Lib/selectors.py
+++ b/Lib/selectors.py
@@ -5,10 +5,9 @@ This module allows high-level and efficient I/O multiplexing, built upon the
"""
-from abc import ABCMeta, abstractmethod
+from abc import ABCMeta, abstractmethod, abstractproperty
from collections import namedtuple, Mapping
import functools
-import math
import select
import sys
@@ -83,6 +82,11 @@ class BaseSelector(metaclass=ABCMeta):
performant implementation on the current platform.
"""
+ @abstractproperty
+ def resolution(self):
+ """Resolution of the selector in seconds"""
+ return None
+
@abstractmethod
def register(self, fileobj, events, data=None):
"""Register a file object.
@@ -284,6 +288,10 @@ class SelectSelector(_BaseSelectorImpl):
self._readers = set()
self._writers = set()
+ @property
+ def resolution(self):
+ return 1e-6
+
def register(self, fileobj, events, data=None):
key = super().register(fileobj, events, data)
if events & EVENT_READ:
@@ -336,6 +344,10 @@ if hasattr(select, 'poll'):
super().__init__()
self._poll = select.poll()
+ @property
+ def resolution(self):
+ return 1e-3
+
def register(self, fileobj, events, data=None):
key = super().register(fileobj, events, data)
poll_events = 0
@@ -357,9 +369,8 @@ if hasattr(select, 'poll'):
elif timeout <= 0:
timeout = 0
else:
- # poll() has a resolution of 1 millisecond, round away from
- # zero to wait *at least* timeout seconds.
- timeout = int(math.ceil(timeout * 1e3))
+ # Round towards zero
+ timeout = int(timeout * 1000)
ready = []
try:
fd_event_list = self._poll.poll(timeout)
@@ -387,6 +398,10 @@ if hasattr(select, 'epoll'):
super().__init__()
self._epoll = select.epoll()
+ @property
+ def resolution(self):
+ return 1e-3
+
def fileno(self):
return self._epoll.fileno()
@@ -415,10 +430,6 @@ if hasattr(select, 'epoll'):
timeout = -1
elif timeout <= 0:
timeout = 0
- else:
- # epoll_wait() has a resolution of 1 millisecond, round away
- # from zero to wait *at least* timeout seconds.
- timeout = math.ceil(timeout * 1e3) * 1e-3
max_ev = len(self._fd_to_key)
ready = []
try:
@@ -451,6 +462,10 @@ if hasattr(select, 'kqueue'):
super().__init__()
self._kqueue = select.kqueue()
+ @property
+ def resolution(self):
+ return 1e-9
+
def fileno(self):
return self._kqueue.fileno()
diff --git a/Lib/test/imghdrdata/python.bmp b/Lib/test/imghdrdata/python.bmp
new file mode 100644
index 0000000000..675f95191a
--- /dev/null
+++ b/Lib/test/imghdrdata/python.bmp
Binary files differ
diff --git a/Lib/test/imghdrdata/python.gif b/Lib/test/imghdrdata/python.gif
new file mode 100644
index 0000000000..96fd9fef76
--- /dev/null
+++ b/Lib/test/imghdrdata/python.gif
Binary files differ
diff --git a/Lib/test/imghdrdata/python.jpg b/Lib/test/imghdrdata/python.jpg
new file mode 100644
index 0000000000..21222c09f5
--- /dev/null
+++ b/Lib/test/imghdrdata/python.jpg
Binary files differ
diff --git a/Lib/test/imghdrdata/python.pbm b/Lib/test/imghdrdata/python.pbm
new file mode 100644
index 0000000000..1848ba7ff0
--- /dev/null
+++ b/Lib/test/imghdrdata/python.pbm
@@ -0,0 +1,3 @@
+P4
+16 16
+ûñ¿úßÕ­±[ñ¥a_ÁX°°ðððð?ÿÿ \ No newline at end of file
diff --git a/Lib/test/imghdrdata/python.pgm b/Lib/test/imghdrdata/python.pgm
new file mode 100644
index 0000000000..8349f2a53a
--- /dev/null
+++ b/Lib/test/imghdrdata/python.pgm
Binary files differ
diff --git a/Lib/test/imghdrdata/python.png b/Lib/test/imghdrdata/python.png
new file mode 100644
index 0000000000..1a987f79fc
--- /dev/null
+++ b/Lib/test/imghdrdata/python.png
Binary files differ
diff --git a/Lib/test/imghdrdata/python.ppm b/Lib/test/imghdrdata/python.ppm
new file mode 100644
index 0000000000..7d9cdb3215
--- /dev/null
+++ b/Lib/test/imghdrdata/python.ppm
Binary files differ
diff --git a/Lib/test/imghdrdata/python.ras b/Lib/test/imghdrdata/python.ras
new file mode 100644
index 0000000000..130e96f817
--- /dev/null
+++ b/Lib/test/imghdrdata/python.ras
Binary files differ
diff --git a/Lib/test/imghdrdata/python.sgi b/Lib/test/imghdrdata/python.sgi
new file mode 100644
index 0000000000..ffe9081c7a
--- /dev/null
+++ b/Lib/test/imghdrdata/python.sgi
Binary files differ
diff --git a/Lib/test/imghdrdata/python.tiff b/Lib/test/imghdrdata/python.tiff
new file mode 100644
index 0000000000..39d0bfcec0
--- /dev/null
+++ b/Lib/test/imghdrdata/python.tiff
Binary files differ
diff --git a/Lib/test/imghdrdata/python.xbm b/Lib/test/imghdrdata/python.xbm
new file mode 100644
index 0000000000..cfbee2e980
--- /dev/null
+++ b/Lib/test/imghdrdata/python.xbm
@@ -0,0 +1,6 @@
+#define python_width 16
+#define python_height 16
+static char python_bits[] = {
+ 0xDF, 0xFE, 0x8F, 0xFD, 0x5F, 0xFB, 0xAB, 0xFE, 0xB5, 0x8D, 0xDA, 0x8F,
+ 0xA5, 0x86, 0xFA, 0x83, 0x1A, 0x80, 0x0D, 0x80, 0x0D, 0x80, 0x0F, 0xE0,
+ 0x0F, 0xF8, 0x0F, 0xF8, 0x0F, 0xFC, 0xFF, 0xFF, };
diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py
index 96f29750c7..9c2bda1f96 100644
--- a/Lib/test/test_asyncio/test_base_events.py
+++ b/Lib/test/test_asyncio/test_base_events.py
@@ -8,12 +8,9 @@ import unittest
import unittest.mock
from test.support import find_unused_port, IPV6_ENABLED
+import asyncio
from asyncio import base_events
from asyncio import constants
-from asyncio import events
-from asyncio import futures
-from asyncio import protocols
-from asyncio import tasks
from asyncio import test_utils
@@ -22,7 +19,7 @@ class BaseEventLoopTests(unittest.TestCase):
def setUp(self):
self.loop = base_events.BaseEventLoop()
self.loop._selector = unittest.mock.Mock()
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
def test_not_implemented(self):
m = unittest.mock.Mock()
@@ -51,20 +48,20 @@ class BaseEventLoopTests(unittest.TestCase):
self.assertRaises(NotImplementedError, next, iter(gen))
def test__add_callback_handle(self):
- h = events.Handle(lambda: False, ())
+ h = asyncio.Handle(lambda: False, ())
self.loop._add_callback(h)
self.assertFalse(self.loop._scheduled)
self.assertIn(h, self.loop._ready)
def test__add_callback_timer(self):
- h = events.TimerHandle(time.monotonic()+10, lambda: False, ())
+ h = asyncio.TimerHandle(time.monotonic()+10, lambda: False, ())
self.loop._add_callback(h)
self.assertIn(h, self.loop._scheduled)
def test__add_callback_cancelled_handle(self):
- h = events.Handle(lambda: False, ())
+ h = asyncio.Handle(lambda: False, ())
h.cancel()
self.loop._add_callback(h)
@@ -90,7 +87,7 @@ class BaseEventLoopTests(unittest.TestCase):
h = self.loop.call_soon(cb)
self.assertEqual(h._callback, cb)
- self.assertIsInstance(h, events.Handle)
+ self.assertIsInstance(h, asyncio.Handle)
self.assertIn(h, self.loop._ready)
def test_call_later(self):
@@ -98,7 +95,7 @@ class BaseEventLoopTests(unittest.TestCase):
pass
h = self.loop.call_later(10.0, cb)
- self.assertIsInstance(h, events.TimerHandle)
+ self.assertIsInstance(h, asyncio.TimerHandle)
self.assertIn(h, self.loop._scheduled)
self.assertNotIn(h, self.loop._ready)
@@ -132,27 +129,27 @@ class BaseEventLoopTests(unittest.TestCase):
self.assertRaises(
AssertionError, self.loop.run_in_executor,
- None, events.Handle(cb, ()), ('',))
+ None, asyncio.Handle(cb, ()), ('',))
self.assertRaises(
AssertionError, self.loop.run_in_executor,
- None, events.TimerHandle(10, cb, ()))
+ None, asyncio.TimerHandle(10, cb, ()))
def test_run_once_in_executor_cancelled(self):
def cb():
pass
- h = events.Handle(cb, ())
+ h = asyncio.Handle(cb, ())
h.cancel()
f = self.loop.run_in_executor(None, h)
- self.assertIsInstance(f, futures.Future)
+ self.assertIsInstance(f, asyncio.Future)
self.assertTrue(f.done())
self.assertIsNone(f.result())
def test_run_once_in_executor_plain(self):
def cb():
pass
- h = events.Handle(cb, ())
- f = futures.Future(loop=self.loop)
+ h = asyncio.Handle(cb, ())
+ f = asyncio.Future(loop=self.loop)
executor = unittest.mock.Mock()
executor.submit.return_value = f
@@ -170,8 +167,8 @@ class BaseEventLoopTests(unittest.TestCase):
f.cancel() # Don't complain about abandoned Future.
def test__run_once(self):
- h1 = events.TimerHandle(time.monotonic() + 5.0, lambda: True, ())
- h2 = events.TimerHandle(time.monotonic() + 10.0, lambda: True, ())
+ h1 = asyncio.TimerHandle(time.monotonic() + 5.0, lambda: True, ())
+ h2 = asyncio.TimerHandle(time.monotonic() + 10.0, lambda: True, ())
h1.cancel()
@@ -202,14 +199,14 @@ class BaseEventLoopTests(unittest.TestCase):
m_logging.DEBUG = logging.DEBUG
self.loop._scheduled.append(
- events.TimerHandle(11.0, lambda: True, ()))
+ asyncio.TimerHandle(11.0, lambda: True, ()))
self.loop._process_events = unittest.mock.Mock()
self.loop._run_once()
self.assertEqual(logging.INFO, m_logging.log.call_args[0][0])
idx = -1
data = [10.0, 10.0, 10.3, 13.0]
- self.loop._scheduled = [events.TimerHandle(11.0, lambda:True, ())]
+ self.loop._scheduled = [asyncio.TimerHandle(11.0, lambda:True, ())]
self.loop._run_once()
self.assertEqual(logging.DEBUG, m_logging.log.call_args[0][0])
@@ -222,7 +219,7 @@ class BaseEventLoopTests(unittest.TestCase):
processed = True
handle = loop.call_soon(lambda: True)
- h = events.TimerHandle(time.monotonic() - 1, cb, (self.loop,))
+ h = asyncio.TimerHandle(time.monotonic() - 1, cb, (self.loop,))
self.loop._process_events = unittest.mock.Mock()
self.loop._scheduled.append(h)
@@ -236,14 +233,14 @@ class BaseEventLoopTests(unittest.TestCase):
TypeError, self.loop.run_until_complete, 'blah')
-class MyProto(protocols.Protocol):
+class MyProto(asyncio.Protocol):
done = None
def __init__(self, create_future=False):
self.state = 'INITIAL'
self.nbytes = 0
if create_future:
- self.done = futures.Future()
+ self.done = asyncio.Future()
def connection_made(self, transport):
self.transport = transport
@@ -266,14 +263,14 @@ class MyProto(protocols.Protocol):
self.done.set_result(None)
-class MyDatagramProto(protocols.DatagramProtocol):
+class MyDatagramProto(asyncio.DatagramProtocol):
done = None
def __init__(self, create_future=False):
self.state = 'INITIAL'
self.nbytes = 0
if create_future:
- self.done = futures.Future()
+ self.done = asyncio.Future()
def connection_made(self, transport):
self.transport = transport
@@ -297,8 +294,8 @@ class MyDatagramProto(protocols.DatagramProtocol):
class BaseEventLoopWithSelectorTests(unittest.TestCase):
def setUp(self):
- self.loop = events.new_event_loop()
- events.set_event_loop(None)
+ self.loop = asyncio.new_event_loop()
+ asyncio.set_event_loop(None)
def tearDown(self):
self.loop.close()
@@ -306,17 +303,17 @@ class BaseEventLoopWithSelectorTests(unittest.TestCase):
@unittest.mock.patch('asyncio.base_events.socket')
def test_create_connection_multiple_errors(self, m_socket):
- class MyProto(protocols.Protocol):
+ class MyProto(asyncio.Protocol):
pass
- @tasks.coroutine
+ @asyncio.coroutine
def getaddrinfo(*args, **kw):
yield from []
return [(2, 1, 6, '', ('107.6.106.82', 80)),
(2, 1, 6, '', ('107.6.106.82', 80))]
def getaddrinfo_task(*args, **kwds):
- return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop)
+ return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop)
idx = -1
errors = ['err1', 'err2']
@@ -346,12 +343,12 @@ class BaseEventLoopWithSelectorTests(unittest.TestCase):
self.assertRaises(ValueError, self.loop.run_until_complete, coro)
def test_create_connection_no_getaddrinfo(self):
- @tasks.coroutine
+ @asyncio.coroutine
def getaddrinfo(*args, **kw):
yield from []
def getaddrinfo_task(*args, **kwds):
- return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop)
+ return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop)
self.loop.getaddrinfo = getaddrinfo_task
coro = self.loop.create_connection(MyProto, 'example.com', 80)
@@ -359,13 +356,13 @@ class BaseEventLoopWithSelectorTests(unittest.TestCase):
OSError, self.loop.run_until_complete, coro)
def test_create_connection_connect_err(self):
- @tasks.coroutine
+ @asyncio.coroutine
def getaddrinfo(*args, **kw):
yield from []
return [(2, 1, 6, '', ('107.6.106.82', 80))]
def getaddrinfo_task(*args, **kwds):
- return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop)
+ return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop)
self.loop.getaddrinfo = getaddrinfo_task
self.loop.sock_connect = unittest.mock.Mock()
@@ -376,13 +373,13 @@ class BaseEventLoopWithSelectorTests(unittest.TestCase):
OSError, self.loop.run_until_complete, coro)
def test_create_connection_multiple(self):
- @tasks.coroutine
+ @asyncio.coroutine
def getaddrinfo(*args, **kw):
return [(2, 1, 6, '', ('0.0.0.1', 80)),
(2, 1, 6, '', ('0.0.0.2', 80))]
def getaddrinfo_task(*args, **kwds):
- return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop)
+ return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop)
self.loop.getaddrinfo = getaddrinfo_task
self.loop.sock_connect = unittest.mock.Mock()
@@ -404,13 +401,13 @@ class BaseEventLoopWithSelectorTests(unittest.TestCase):
m_socket.socket.return_value.bind = bind
- @tasks.coroutine
+ @asyncio.coroutine
def getaddrinfo(*args, **kw):
return [(2, 1, 6, '', ('0.0.0.1', 80)),
(2, 1, 6, '', ('0.0.0.2', 80))]
def getaddrinfo_task(*args, **kwds):
- return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop)
+ return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop)
self.loop.getaddrinfo = getaddrinfo_task
self.loop.sock_connect = unittest.mock.Mock()
@@ -426,7 +423,7 @@ class BaseEventLoopWithSelectorTests(unittest.TestCase):
self.assertTrue(m_socket.socket.return_value.close.called)
def test_create_connection_no_local_addr(self):
- @tasks.coroutine
+ @asyncio.coroutine
def getaddrinfo(host, *args, **kw):
if host == 'example.com':
return [(2, 1, 6, '', ('107.6.106.82', 80)),
@@ -435,7 +432,7 @@ class BaseEventLoopWithSelectorTests(unittest.TestCase):
return []
def getaddrinfo_task(*args, **kwds):
- return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop)
+ return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop)
self.loop.getaddrinfo = getaddrinfo_task
coro = self.loop.create_connection(
@@ -448,7 +445,7 @@ class BaseEventLoopWithSelectorTests(unittest.TestCase):
self.loop.getaddrinfo = unittest.mock.Mock()
def mock_getaddrinfo(*args, **kwds):
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
f.set_result([(socket.AF_INET, socket.SOCK_STREAM,
socket.SOL_TCP, '', ('1.2.3.4', 80))])
return f
@@ -527,14 +524,14 @@ class BaseEventLoopWithSelectorTests(unittest.TestCase):
# if host is empty string use None instead
host = object()
- @tasks.coroutine
+ @asyncio.coroutine
def getaddrinfo(*args, **kw):
nonlocal host
host = args[0]
yield from []
def getaddrinfo_task(*args, **kwds):
- return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop)
+ return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop)
self.loop.getaddrinfo = getaddrinfo_task
fut = self.loop.create_server(MyProto, '', 0)
@@ -596,7 +593,7 @@ class BaseEventLoopWithSelectorTests(unittest.TestCase):
self.loop.sock_connect.side_effect = OSError
coro = self.loop.create_datagram_endpoint(
- protocols.DatagramProtocol, remote_addr=('127.0.0.1', 0))
+ asyncio.DatagramProtocol, remote_addr=('127.0.0.1', 0))
self.assertRaises(
OSError, self.loop.run_until_complete, coro)
@@ -606,19 +603,19 @@ class BaseEventLoopWithSelectorTests(unittest.TestCase):
m_socket.socket.side_effect = OSError
coro = self.loop.create_datagram_endpoint(
- protocols.DatagramProtocol, family=socket.AF_INET)
+ asyncio.DatagramProtocol, family=socket.AF_INET)
self.assertRaises(
OSError, self.loop.run_until_complete, coro)
coro = self.loop.create_datagram_endpoint(
- protocols.DatagramProtocol, local_addr=('127.0.0.1', 0))
+ asyncio.DatagramProtocol, local_addr=('127.0.0.1', 0))
self.assertRaises(
OSError, self.loop.run_until_complete, coro)
@unittest.skipUnless(IPV6_ENABLED, 'IPv6 not supported or enabled')
def test_create_datagram_endpoint_no_matching_family(self):
coro = self.loop.create_datagram_endpoint(
- protocols.DatagramProtocol,
+ asyncio.DatagramProtocol,
remote_addr=('127.0.0.1', 0), local_addr=('::1', 0))
self.assertRaises(
ValueError, self.loop.run_until_complete, coro)
@@ -628,7 +625,7 @@ class BaseEventLoopWithSelectorTests(unittest.TestCase):
m_socket.socket.return_value.setblocking.side_effect = OSError
coro = self.loop.create_datagram_endpoint(
- protocols.DatagramProtocol, family=socket.AF_INET)
+ asyncio.DatagramProtocol, family=socket.AF_INET)
self.assertRaises(
OSError, self.loop.run_until_complete, coro)
self.assertTrue(
@@ -636,7 +633,7 @@ class BaseEventLoopWithSelectorTests(unittest.TestCase):
def test_create_datagram_endpoint_noaddr_nofamily(self):
coro = self.loop.create_datagram_endpoint(
- protocols.DatagramProtocol)
+ asyncio.DatagramProtocol)
self.assertRaises(ValueError, self.loop.run_until_complete, coro)
@unittest.mock.patch('asyncio.base_events.socket')
diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py
index 2e1dfebf34..fe5b2246ee 100644
--- a/Lib/test/test_asyncio/test_events.py
+++ b/Lib/test/test_asyncio/test_events.py
@@ -23,14 +23,10 @@ import unittest.mock
from test import support # find_unused_port, IPV6_ENABLED, TEST_HOME_DIR
-from asyncio import futures
+import asyncio
from asyncio import events
-from asyncio import transports
-from asyncio import protocols
from asyncio import selector_events
-from asyncio import tasks
from asyncio import test_utils
-from asyncio import locks
def data_file(filename):
@@ -49,7 +45,7 @@ SIGNED_CERTFILE = data_file('keycert3.pem')
SIGNING_CA = data_file('pycacert.pem')
-class MyProto(protocols.Protocol):
+class MyProto(asyncio.Protocol):
done = None
def __init__(self, loop=None):
@@ -57,7 +53,7 @@ class MyProto(protocols.Protocol):
self.state = 'INITIAL'
self.nbytes = 0
if loop is not None:
- self.done = futures.Future(loop=loop)
+ self.done = asyncio.Future(loop=loop)
def connection_made(self, transport):
self.transport = transport
@@ -80,14 +76,14 @@ class MyProto(protocols.Protocol):
self.done.set_result(None)
-class MyDatagramProto(protocols.DatagramProtocol):
+class MyDatagramProto(asyncio.DatagramProtocol):
done = None
def __init__(self, loop=None):
self.state = 'INITIAL'
self.nbytes = 0
if loop is not None:
- self.done = futures.Future(loop=loop)
+ self.done = asyncio.Future(loop=loop)
def connection_made(self, transport):
self.transport = transport
@@ -108,7 +104,7 @@ class MyDatagramProto(protocols.DatagramProtocol):
self.done.set_result(None)
-class MyReadPipeProto(protocols.Protocol):
+class MyReadPipeProto(asyncio.Protocol):
done = None
def __init__(self, loop=None):
@@ -116,7 +112,7 @@ class MyReadPipeProto(protocols.Protocol):
self.nbytes = 0
self.transport = None
if loop is not None:
- self.done = futures.Future(loop=loop)
+ self.done = asyncio.Future(loop=loop)
def connection_made(self, transport):
self.transport = transport
@@ -140,14 +136,14 @@ class MyReadPipeProto(protocols.Protocol):
self.done.set_result(None)
-class MyWritePipeProto(protocols.BaseProtocol):
+class MyWritePipeProto(asyncio.BaseProtocol):
done = None
def __init__(self, loop=None):
self.state = 'INITIAL'
self.transport = None
if loop is not None:
- self.done = futures.Future(loop=loop)
+ self.done = asyncio.Future(loop=loop)
def connection_made(self, transport):
self.transport = transport
@@ -161,18 +157,18 @@ class MyWritePipeProto(protocols.BaseProtocol):
self.done.set_result(None)
-class MySubprocessProtocol(protocols.SubprocessProtocol):
+class MySubprocessProtocol(asyncio.SubprocessProtocol):
def __init__(self, loop):
self.state = 'INITIAL'
self.transport = None
- self.connected = futures.Future(loop=loop)
- self.completed = futures.Future(loop=loop)
- self.disconnects = {fd: futures.Future(loop=loop) for fd in range(3)}
+ self.connected = asyncio.Future(loop=loop)
+ self.completed = asyncio.Future(loop=loop)
+ self.disconnects = {fd: asyncio.Future(loop=loop) for fd in range(3)}
self.data = {1: b'', 2: b''}
self.returncode = None
- self.got_data = {1: locks.Event(loop=loop),
- 2: locks.Event(loop=loop)}
+ self.got_data = {1: asyncio.Event(loop=loop),
+ 2: asyncio.Event(loop=loop)}
def connection_made(self, transport):
self.transport = transport
@@ -207,7 +203,7 @@ class EventLoopTestsMixin:
def setUp(self):
super().setUp()
self.loop = self.create_event_loop()
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
def tearDown(self):
# just in case if we have transport close callbacks
@@ -218,11 +214,11 @@ class EventLoopTestsMixin:
super().tearDown()
def test_run_until_complete_nesting(self):
- @tasks.coroutine
+ @asyncio.coroutine
def coro1():
yield
- @tasks.coroutine
+ @asyncio.coroutine
def coro2():
self.assertTrue(self.loop.is_running())
self.loop.run_until_complete(coro1())
@@ -235,15 +231,15 @@ class EventLoopTestsMixin:
def test_run_until_complete(self):
t0 = self.loop.time()
- self.loop.run_until_complete(tasks.sleep(0.1, loop=self.loop))
+ self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
t1 = self.loop.time()
self.assertTrue(0.08 <= t1-t0 <= 0.8, t1-t0)
def test_run_until_complete_stopped(self):
- @tasks.coroutine
+ @asyncio.coroutine
def cb():
self.loop.stop()
- yield from tasks.sleep(0.1, loop=self.loop)
+ yield from asyncio.sleep(0.1, loop=self.loop)
task = cb()
self.assertRaises(RuntimeError,
self.loop.run_until_complete, task)
@@ -494,8 +490,8 @@ class EventLoopTestsMixin:
f = self.loop.create_connection(
lambda: MyProto(loop=self.loop), *httpd.address)
tr, pr = self.loop.run_until_complete(f)
- self.assertIsInstance(tr, transports.Transport)
- self.assertIsInstance(pr, protocols.Protocol)
+ self.assertIsInstance(tr, asyncio.Transport)
+ self.assertIsInstance(pr, asyncio.Protocol)
self.loop.run_until_complete(pr.done)
self.assertGreater(pr.nbytes, 0)
tr.close()
@@ -522,8 +518,8 @@ class EventLoopTestsMixin:
f = self.loop.create_connection(
lambda: MyProto(loop=self.loop), sock=sock)
tr, pr = self.loop.run_until_complete(f)
- self.assertIsInstance(tr, transports.Transport)
- self.assertIsInstance(pr, protocols.Protocol)
+ self.assertIsInstance(tr, asyncio.Transport)
+ self.assertIsInstance(pr, asyncio.Protocol)
self.loop.run_until_complete(pr.done)
self.assertGreater(pr.nbytes, 0)
tr.close()
@@ -535,8 +531,8 @@ class EventLoopTestsMixin:
lambda: MyProto(loop=self.loop), *httpd.address,
ssl=test_utils.dummy_ssl_context())
tr, pr = self.loop.run_until_complete(f)
- self.assertIsInstance(tr, transports.Transport)
- self.assertIsInstance(pr, protocols.Protocol)
+ self.assertIsInstance(tr, asyncio.Transport)
+ self.assertIsInstance(pr, asyncio.Protocol)
self.assertTrue('ssl' in tr.__class__.__name__.lower())
self.assertIsNotNone(tr.get_extra_info('sockname'))
self.loop.run_until_complete(pr.done)
@@ -762,7 +758,7 @@ class EventLoopTestsMixin:
server.close()
def test_create_server_sock(self):
- proto = futures.Future(loop=self.loop)
+ proto = asyncio.Future(loop=self.loop)
class TestMyProto(MyProto):
def connection_made(self, transport):
@@ -805,7 +801,7 @@ class EventLoopTestsMixin:
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 not supported or enabled')
def test_create_server_dual_stack(self):
- f_proto = futures.Future(loop=self.loop)
+ f_proto = asyncio.Future(loop=self.loop)
class TestMyProto(MyProto):
def connection_made(self, transport):
@@ -834,7 +830,7 @@ class EventLoopTestsMixin:
proto.transport.close()
client.close()
- f_proto = futures.Future(loop=self.loop)
+ f_proto = asyncio.Future(loop=self.loop)
client = socket.socket(socket.AF_INET6)
client.connect(('::1', port))
client.send(b'xxx')
@@ -929,7 +925,7 @@ class EventLoopTestsMixin:
rpipe, wpipe = os.pipe()
pipeobj = io.open(rpipe, 'rb', 1024)
- @tasks.coroutine
+ @asyncio.coroutine
def connect():
t, p = yield from self.loop.connect_read_pipe(factory, pipeobj)
self.assertIs(p, proto)
@@ -968,7 +964,7 @@ class EventLoopTestsMixin:
master, slave = os.openpty()
master_read_obj = io.open(master, 'rb', 0)
- @tasks.coroutine
+ @asyncio.coroutine
def connect():
t, p = yield from self.loop.connect_read_pipe(factory,
master_read_obj)
@@ -1009,7 +1005,7 @@ class EventLoopTestsMixin:
rpipe, wpipe = os.pipe()
pipeobj = io.open(wpipe, 'wb', 1024)
- @tasks.coroutine
+ @asyncio.coroutine
def connect():
nonlocal transport
t, p = yield from self.loop.connect_write_pipe(factory, pipeobj)
@@ -1055,7 +1051,7 @@ class EventLoopTestsMixin:
rsock, wsock = test_utils.socketpair()
pipeobj = io.open(wsock.detach(), 'wb', 1024)
- @tasks.coroutine
+ @asyncio.coroutine
def connect():
nonlocal transport
t, p = yield from self.loop.connect_write_pipe(factory,
@@ -1077,6 +1073,53 @@ class EventLoopTestsMixin:
self.loop.run_until_complete(proto.done)
self.assertEqual('CLOSED', proto.state)
+ @unittest.skipUnless(sys.platform != 'win32',
+ "Don't support pipes for Windows")
+ def test_write_pty(self):
+ proto = None
+ transport = None
+
+ def factory():
+ nonlocal proto
+ proto = MyWritePipeProto(loop=self.loop)
+ return proto
+
+ master, slave = os.openpty()
+ slave_write_obj = io.open(slave, 'wb', 0)
+
+ @asyncio.coroutine
+ def connect():
+ nonlocal transport
+ t, p = yield from self.loop.connect_write_pipe(factory,
+ slave_write_obj)
+ self.assertIs(p, proto)
+ self.assertIs(t, proto.transport)
+ self.assertEqual('CONNECTED', proto.state)
+ transport = t
+
+ self.loop.run_until_complete(connect())
+
+ transport.write(b'1')
+ test_utils.run_briefly(self.loop)
+ data = os.read(master, 1024)
+ self.assertEqual(b'1', data)
+
+ transport.write(b'2345')
+ test_utils.run_briefly(self.loop)
+ data = os.read(master, 1024)
+ self.assertEqual(b'2345', data)
+ self.assertEqual('CONNECTED', proto.state)
+
+ os.close(master)
+
+ # extra info is available
+ self.assertIsNotNone(proto.transport.get_extra_info('pipe'))
+
+ # close connection
+ proto.transport.close()
+ self.loop.run_until_complete(proto.done)
+ self.assertEqual('CLOSED', proto.state)
+
def test_prompt_cancellation(self):
r, w = test_utils.socketpair()
r.setblocking(False)
@@ -1085,12 +1128,12 @@ class EventLoopTestsMixin:
if ov is not None:
self.assertTrue(ov.pending)
- @tasks.coroutine
+ @asyncio.coroutine
def main():
try:
self.loop.call_soon(f.cancel)
yield from f
- except futures.CancelledError:
+ except asyncio.CancelledError:
res = 'cancelled'
else:
res = None
@@ -1099,13 +1142,13 @@ class EventLoopTestsMixin:
return res
start = time.monotonic()
- t = tasks.Task(main(), loop=self.loop)
+ t = asyncio.Task(main(), loop=self.loop)
self.loop.run_forever()
elapsed = time.monotonic() - start
self.assertLess(elapsed, 0.1)
self.assertEqual(t.result(), 'cancelled')
- self.assertRaises(futures.CancelledError, f.result)
+ self.assertRaises(asyncio.CancelledError, f.result)
if ov is not None:
self.assertFalse(ov.pending)
self.loop._stop_serving(r)
@@ -1113,6 +1156,29 @@ class EventLoopTestsMixin:
r.close()
w.close()
+ def test_timeout_rounding(self):
+ def _run_once():
+ self.loop._run_once_counter += 1
+ orig_run_once()
+
+ orig_run_once = self.loop._run_once
+ self.loop._run_once_counter = 0
+ self.loop._run_once = _run_once
+ calls = []
+
+ @asyncio.coroutine
+ def wait():
+ loop = self.loop
+ calls.append(loop._run_once_counter)
+ yield from asyncio.sleep(loop._granularity * 10, loop=loop)
+ calls.append(loop._run_once_counter)
+ yield from asyncio.sleep(loop._granularity / 10, loop=loop)
+ calls.append(loop._run_once_counter)
+
+ self.loop.run_until_complete(wait())
+ calls.append(self.loop._run_once_counter)
+ self.assertEqual(calls, [1, 3, 5, 6])
+
class SubprocessTestsMixin:
@@ -1136,7 +1202,7 @@ class SubprocessTestsMixin:
prog = os.path.join(os.path.dirname(__file__), 'echo.py')
- @tasks.coroutine
+ @asyncio.coroutine
def connect():
nonlocal proto, transp
transp, proto = yield from self.loop.subprocess_exec(
@@ -1162,7 +1228,7 @@ class SubprocessTestsMixin:
prog = os.path.join(os.path.dirname(__file__), 'echo.py')
- @tasks.coroutine
+ @asyncio.coroutine
def connect():
nonlocal proto, transp
transp, proto = yield from self.loop.subprocess_exec(
@@ -1194,7 +1260,7 @@ class SubprocessTestsMixin:
proto = None
transp = None
- @tasks.coroutine
+ @asyncio.coroutine
def connect():
nonlocal proto, transp
transp, proto = yield from self.loop.subprocess_shell(
@@ -1215,7 +1281,7 @@ class SubprocessTestsMixin:
def test_subprocess_exitcode(self):
proto = None
- @tasks.coroutine
+ @asyncio.coroutine
def connect():
nonlocal proto
transp, proto = yield from self.loop.subprocess_shell(
@@ -1231,7 +1297,7 @@ class SubprocessTestsMixin:
proto = None
transp = None
- @tasks.coroutine
+ @asyncio.coroutine
def connect():
nonlocal proto, transp
transp, proto = yield from self.loop.subprocess_shell(
@@ -1253,7 +1319,7 @@ class SubprocessTestsMixin:
prog = os.path.join(os.path.dirname(__file__), 'echo.py')
- @tasks.coroutine
+ @asyncio.coroutine
def connect():
nonlocal proto, transp
transp, proto = yield from self.loop.subprocess_exec(
@@ -1274,7 +1340,7 @@ class SubprocessTestsMixin:
prog = os.path.join(os.path.dirname(__file__), 'echo.py')
- @tasks.coroutine
+ @asyncio.coroutine
def connect():
nonlocal proto, transp
transp, proto = yield from self.loop.subprocess_exec(
@@ -1296,7 +1362,7 @@ class SubprocessTestsMixin:
prog = os.path.join(os.path.dirname(__file__), 'echo.py')
- @tasks.coroutine
+ @asyncio.coroutine
def connect():
nonlocal proto, transp
transp, proto = yield from self.loop.subprocess_exec(
@@ -1317,7 +1383,7 @@ class SubprocessTestsMixin:
prog = os.path.join(os.path.dirname(__file__), 'echo2.py')
- @tasks.coroutine
+ @asyncio.coroutine
def connect():
nonlocal proto, transp
transp, proto = yield from self.loop.subprocess_exec(
@@ -1344,7 +1410,7 @@ class SubprocessTestsMixin:
prog = os.path.join(os.path.dirname(__file__), 'echo2.py')
- @tasks.coroutine
+ @asyncio.coroutine
def connect():
nonlocal proto, transp
transp, proto = yield from self.loop.subprocess_exec(
@@ -1374,7 +1440,7 @@ class SubprocessTestsMixin:
prog = os.path.join(os.path.dirname(__file__), 'echo3.py')
- @tasks.coroutine
+ @asyncio.coroutine
def connect():
nonlocal proto, transp
transp, proto = yield from self.loop.subprocess_exec(
@@ -1411,7 +1477,7 @@ class SubprocessTestsMixin:
proto = None
transp = None
- @tasks.coroutine
+ @asyncio.coroutine
def connect():
nonlocal proto
# start the new process in a new session
@@ -1427,19 +1493,18 @@ class SubprocessTestsMixin:
if sys.platform == 'win32':
- from asyncio import windows_events
class SelectEventLoopTests(EventLoopTestsMixin, unittest.TestCase):
def create_event_loop(self):
- return windows_events.SelectorEventLoop()
+ return asyncio.SelectorEventLoop()
class ProactorEventLoopTests(EventLoopTestsMixin,
SubprocessTestsMixin,
unittest.TestCase):
def create_event_loop(self):
- return windows_events.ProactorEventLoop()
+ return asyncio.ProactorEventLoop()
def test_create_ssl_connection(self):
raise unittest.SkipTest("IocpEventLoop incompatible with SSL")
@@ -1473,17 +1538,16 @@ if sys.platform == 'win32':
"IocpEventLoop does not have create_datagram_endpoint()")
else:
from asyncio import selectors
- from asyncio import unix_events
class UnixEventLoopTestsMixin(EventLoopTestsMixin):
def setUp(self):
super().setUp()
- watcher = unix_events.SafeChildWatcher()
+ watcher = asyncio.SafeChildWatcher()
watcher.attach_loop(self.loop)
- events.set_child_watcher(watcher)
+ asyncio.set_child_watcher(watcher)
def tearDown(self):
- events.set_child_watcher(None)
+ asyncio.set_child_watcher(None)
super().tearDown()
if hasattr(selectors, 'KqueueSelector'):
@@ -1492,16 +1556,28 @@ else:
unittest.TestCase):
def create_event_loop(self):
- return unix_events.SelectorEventLoop(
+ return asyncio.SelectorEventLoop(
selectors.KqueueSelector())
+ # kqueue doesn't support character devices (PTY) on Mac OS X older
+ # than 10.9 (Maverick)
+ @support.requires_mac_ver(10, 9)
+ def test_read_pty_output(self):
+ super().test_read_pty_output()
+
+ # kqueue doesn't support character devices (PTY) on Mac OS X older
+ # than 10.9 (Maverick)
+ @support.requires_mac_ver(10, 9)
+ def test_write_pty(self):
+ super().test_write_pty()
+
if hasattr(selectors, 'EpollSelector'):
class EPollEventLoopTests(UnixEventLoopTestsMixin,
SubprocessTestsMixin,
unittest.TestCase):
def create_event_loop(self):
- return unix_events.SelectorEventLoop(selectors.EpollSelector())
+ return asyncio.SelectorEventLoop(selectors.EpollSelector())
if hasattr(selectors, 'PollSelector'):
class PollEventLoopTests(UnixEventLoopTestsMixin,
@@ -1509,7 +1585,7 @@ else:
unittest.TestCase):
def create_event_loop(self):
- return unix_events.SelectorEventLoop(selectors.PollSelector())
+ return asyncio.SelectorEventLoop(selectors.PollSelector())
# Should always exist.
class SelectEventLoopTests(UnixEventLoopTestsMixin,
@@ -1517,7 +1593,7 @@ else:
unittest.TestCase):
def create_event_loop(self):
- return unix_events.SelectorEventLoop(selectors.SelectSelector())
+ return asyncio.SelectorEventLoop(selectors.SelectSelector())
class HandleTests(unittest.TestCase):
@@ -1527,7 +1603,7 @@ class HandleTests(unittest.TestCase):
return args
args = ()
- h = events.Handle(callback, args)
+ h = asyncio.Handle(callback, args)
self.assertIs(h._callback, callback)
self.assertIs(h._args, args)
self.assertFalse(h._cancelled)
@@ -1550,16 +1626,16 @@ class HandleTests(unittest.TestCase):
def test_make_handle(self):
def callback(*args):
return args
- h1 = events.Handle(callback, ())
+ h1 = asyncio.Handle(callback, ())
self.assertRaises(
- AssertionError, events.make_handle, h1, ())
+ AssertionError, asyncio.events.make_handle, h1, ())
@unittest.mock.patch('asyncio.events.logger')
def test_callback_with_exception(self, log):
def callback():
raise ValueError()
- h = events.Handle(callback, ())
+ h = asyncio.Handle(callback, ())
h._run()
self.assertTrue(log.exception.called)
@@ -1568,7 +1644,7 @@ class TimerTests(unittest.TestCase):
def test_hash(self):
when = time.monotonic()
- h = events.TimerHandle(when, lambda: False, ())
+ h = asyncio.TimerHandle(when, lambda: False, ())
self.assertEqual(hash(h), hash(when))
def test_timer(self):
@@ -1577,7 +1653,7 @@ class TimerTests(unittest.TestCase):
args = ()
when = time.monotonic()
- h = events.TimerHandle(when, callback, args)
+ h = asyncio.TimerHandle(when, callback, args)
self.assertIs(h._callback, callback)
self.assertIs(h._args, args)
self.assertFalse(h._cancelled)
@@ -1592,7 +1668,7 @@ class TimerTests(unittest.TestCase):
self.assertTrue(r.endswith('())<cancelled>'), r)
self.assertRaises(AssertionError,
- events.TimerHandle, None, callback, args)
+ asyncio.TimerHandle, None, callback, args)
def test_timer_comparison(self):
def callback(*args):
@@ -1600,8 +1676,8 @@ class TimerTests(unittest.TestCase):
when = time.monotonic()
- h1 = events.TimerHandle(when, callback, ())
- h2 = events.TimerHandle(when, callback, ())
+ h1 = asyncio.TimerHandle(when, callback, ())
+ h2 = asyncio.TimerHandle(when, callback, ())
# TODO: Use assertLess etc.
self.assertFalse(h1 < h2)
self.assertFalse(h2 < h1)
@@ -1617,8 +1693,8 @@ class TimerTests(unittest.TestCase):
h2.cancel()
self.assertFalse(h1 == h2)
- h1 = events.TimerHandle(when, callback, ())
- h2 = events.TimerHandle(when + 10.0, callback, ())
+ h1 = asyncio.TimerHandle(when, callback, ())
+ h2 = asyncio.TimerHandle(when + 10.0, callback, ())
self.assertTrue(h1 < h2)
self.assertFalse(h2 < h1)
self.assertTrue(h1 <= h2)
@@ -1630,7 +1706,7 @@ class TimerTests(unittest.TestCase):
self.assertFalse(h1 == h2)
self.assertTrue(h1 != h2)
- h3 = events.Handle(callback, ())
+ h3 = asyncio.Handle(callback, ())
self.assertIs(NotImplemented, h1.__eq__(h3))
self.assertIs(NotImplemented, h1.__ne__(h3))
@@ -1639,7 +1715,7 @@ class AbstractEventLoopTests(unittest.TestCase):
def test_not_implemented(self):
f = unittest.mock.Mock()
- loop = events.AbstractEventLoop()
+ loop = asyncio.AbstractEventLoop()
self.assertRaises(
NotImplementedError, loop.run_forever)
self.assertRaises(
@@ -1713,19 +1789,19 @@ class ProtocolsAbsTests(unittest.TestCase):
def test_empty(self):
f = unittest.mock.Mock()
- p = protocols.Protocol()
+ p = asyncio.Protocol()
self.assertIsNone(p.connection_made(f))
self.assertIsNone(p.connection_lost(f))
self.assertIsNone(p.data_received(f))
self.assertIsNone(p.eof_received())
- dp = protocols.DatagramProtocol()
+ dp = asyncio.DatagramProtocol()
self.assertIsNone(dp.connection_made(f))
self.assertIsNone(dp.connection_lost(f))
self.assertIsNone(dp.error_received(f))
self.assertIsNone(dp.datagram_received(f, f))
- sp = protocols.SubprocessProtocol()
+ sp = asyncio.SubprocessProtocol()
self.assertIsNone(sp.connection_made(f))
self.assertIsNone(sp.connection_lost(f))
self.assertIsNone(sp.pipe_data_received(1, f))
@@ -1735,16 +1811,8 @@ class ProtocolsAbsTests(unittest.TestCase):
class PolicyTests(unittest.TestCase):
- def create_policy(self):
- if sys.platform == "win32":
- from asyncio import windows_events
- return windows_events.DefaultEventLoopPolicy()
- else:
- from asyncio import unix_events
- return unix_events.DefaultEventLoopPolicy()
-
def test_event_loop_policy(self):
- policy = events.AbstractEventLoopPolicy()
+ policy = asyncio.AbstractEventLoopPolicy()
self.assertRaises(NotImplementedError, policy.get_event_loop)
self.assertRaises(NotImplementedError, policy.set_event_loop, object())
self.assertRaises(NotImplementedError, policy.new_event_loop)
@@ -1753,18 +1821,18 @@ class PolicyTests(unittest.TestCase):
object())
def test_get_event_loop(self):
- policy = self.create_policy()
+ policy = asyncio.DefaultEventLoopPolicy()
self.assertIsNone(policy._local._loop)
loop = policy.get_event_loop()
- self.assertIsInstance(loop, events.AbstractEventLoop)
+ self.assertIsInstance(loop, asyncio.AbstractEventLoop)
self.assertIs(policy._local._loop, loop)
self.assertIs(loop, policy.get_event_loop())
loop.close()
def test_get_event_loop_calls_set_event_loop(self):
- policy = self.create_policy()
+ policy = asyncio.DefaultEventLoopPolicy()
with unittest.mock.patch.object(
policy, "set_event_loop",
@@ -1780,7 +1848,7 @@ class PolicyTests(unittest.TestCase):
loop.close()
def test_get_event_loop_after_set_none(self):
- policy = self.create_policy()
+ policy = asyncio.DefaultEventLoopPolicy()
policy.set_event_loop(None)
self.assertRaises(AssertionError, policy.get_event_loop)
@@ -1788,7 +1856,7 @@ class PolicyTests(unittest.TestCase):
def test_get_event_loop_thread(self, m_current_thread):
def f():
- policy = self.create_policy()
+ policy = asyncio.DefaultEventLoopPolicy()
self.assertRaises(AssertionError, policy.get_event_loop)
th = threading.Thread(target=f)
@@ -1796,14 +1864,14 @@ class PolicyTests(unittest.TestCase):
th.join()
def test_new_event_loop(self):
- policy = self.create_policy()
+ policy = asyncio.DefaultEventLoopPolicy()
loop = policy.new_event_loop()
- self.assertIsInstance(loop, events.AbstractEventLoop)
+ self.assertIsInstance(loop, asyncio.AbstractEventLoop)
loop.close()
def test_set_event_loop(self):
- policy = self.create_policy()
+ policy = asyncio.DefaultEventLoopPolicy()
old_loop = policy.get_event_loop()
self.assertRaises(AssertionError, policy.set_event_loop, object())
@@ -1816,19 +1884,19 @@ class PolicyTests(unittest.TestCase):
old_loop.close()
def test_get_event_loop_policy(self):
- policy = events.get_event_loop_policy()
- self.assertIsInstance(policy, events.AbstractEventLoopPolicy)
- self.assertIs(policy, events.get_event_loop_policy())
+ policy = asyncio.get_event_loop_policy()
+ self.assertIsInstance(policy, asyncio.AbstractEventLoopPolicy)
+ self.assertIs(policy, asyncio.get_event_loop_policy())
def test_set_event_loop_policy(self):
self.assertRaises(
- AssertionError, events.set_event_loop_policy, object())
+ AssertionError, asyncio.set_event_loop_policy, object())
- old_policy = events.get_event_loop_policy()
+ old_policy = asyncio.get_event_loop_policy()
- policy = self.create_policy()
- events.set_event_loop_policy(policy)
- self.assertIs(policy, events.get_event_loop_policy())
+ policy = asyncio.DefaultEventLoopPolicy()
+ asyncio.set_event_loop_policy(policy)
+ self.assertIs(policy, asyncio.get_event_loop_policy())
self.assertIsNot(policy, old_policy)
diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py
index e35fcf0708..d3a741254f 100644
--- a/Lib/test/test_asyncio/test_futures.py
+++ b/Lib/test/test_asyncio/test_futures.py
@@ -5,8 +5,7 @@ import threading
import unittest
import unittest.mock
-from asyncio import events
-from asyncio import futures
+import asyncio
from asyncio import test_utils
@@ -18,13 +17,13 @@ class FutureTests(unittest.TestCase):
def setUp(self):
self.loop = test_utils.TestLoop()
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
def tearDown(self):
self.loop.close()
def test_initial_state(self):
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
self.assertFalse(f.cancelled())
self.assertFalse(f.done())
f.cancel()
@@ -32,56 +31,56 @@ class FutureTests(unittest.TestCase):
def test_init_constructor_default_loop(self):
try:
- events.set_event_loop(self.loop)
- f = futures.Future()
+ asyncio.set_event_loop(self.loop)
+ f = asyncio.Future()
self.assertIs(f._loop, self.loop)
finally:
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
def test_constructor_positional(self):
# Make sure Future does't accept a positional argument
- self.assertRaises(TypeError, futures.Future, 42)
+ self.assertRaises(TypeError, asyncio.Future, 42)
def test_cancel(self):
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
self.assertTrue(f.cancel())
self.assertTrue(f.cancelled())
self.assertTrue(f.done())
- self.assertRaises(futures.CancelledError, f.result)
- self.assertRaises(futures.CancelledError, f.exception)
- self.assertRaises(futures.InvalidStateError, f.set_result, None)
- self.assertRaises(futures.InvalidStateError, f.set_exception, None)
+ self.assertRaises(asyncio.CancelledError, f.result)
+ self.assertRaises(asyncio.CancelledError, f.exception)
+ self.assertRaises(asyncio.InvalidStateError, f.set_result, None)
+ self.assertRaises(asyncio.InvalidStateError, f.set_exception, None)
self.assertFalse(f.cancel())
def test_result(self):
- f = futures.Future(loop=self.loop)
- self.assertRaises(futures.InvalidStateError, f.result)
+ f = asyncio.Future(loop=self.loop)
+ self.assertRaises(asyncio.InvalidStateError, f.result)
f.set_result(42)
self.assertFalse(f.cancelled())
self.assertTrue(f.done())
self.assertEqual(f.result(), 42)
self.assertEqual(f.exception(), None)
- self.assertRaises(futures.InvalidStateError, f.set_result, None)
- self.assertRaises(futures.InvalidStateError, f.set_exception, None)
+ self.assertRaises(asyncio.InvalidStateError, f.set_result, None)
+ self.assertRaises(asyncio.InvalidStateError, f.set_exception, None)
self.assertFalse(f.cancel())
def test_exception(self):
exc = RuntimeError()
- f = futures.Future(loop=self.loop)
- self.assertRaises(futures.InvalidStateError, f.exception)
+ f = asyncio.Future(loop=self.loop)
+ self.assertRaises(asyncio.InvalidStateError, f.exception)
f.set_exception(exc)
self.assertFalse(f.cancelled())
self.assertTrue(f.done())
self.assertRaises(RuntimeError, f.result)
self.assertEqual(f.exception(), exc)
- self.assertRaises(futures.InvalidStateError, f.set_result, None)
- self.assertRaises(futures.InvalidStateError, f.set_exception, None)
+ self.assertRaises(asyncio.InvalidStateError, f.set_result, None)
+ self.assertRaises(asyncio.InvalidStateError, f.set_exception, None)
self.assertFalse(f.cancel())
def test_yield_from_twice(self):
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
def fixture():
yield 'A'
@@ -99,32 +98,32 @@ class FutureTests(unittest.TestCase):
self.assertEqual(next(g), ('C', 42)) # yield 'C', y.
def test_repr(self):
- f_pending = futures.Future(loop=self.loop)
+ f_pending = asyncio.Future(loop=self.loop)
self.assertEqual(repr(f_pending), 'Future<PENDING>')
f_pending.cancel()
- f_cancelled = futures.Future(loop=self.loop)
+ f_cancelled = asyncio.Future(loop=self.loop)
f_cancelled.cancel()
self.assertEqual(repr(f_cancelled), 'Future<CANCELLED>')
- f_result = futures.Future(loop=self.loop)
+ f_result = asyncio.Future(loop=self.loop)
f_result.set_result(4)
self.assertEqual(repr(f_result), 'Future<result=4>')
self.assertEqual(f_result.result(), 4)
exc = RuntimeError()
- f_exception = futures.Future(loop=self.loop)
+ f_exception = asyncio.Future(loop=self.loop)
f_exception.set_exception(exc)
self.assertEqual(repr(f_exception), 'Future<exception=RuntimeError()>')
self.assertIs(f_exception.exception(), exc)
- f_few_callbacks = futures.Future(loop=self.loop)
+ f_few_callbacks = asyncio.Future(loop=self.loop)
f_few_callbacks.add_done_callback(_fakefunc)
self.assertIn('Future<PENDING, [<function _fakefunc',
repr(f_few_callbacks))
f_few_callbacks.cancel()
- f_many_callbacks = futures.Future(loop=self.loop)
+ f_many_callbacks = asyncio.Future(loop=self.loop)
for i in range(20):
f_many_callbacks.add_done_callback(_fakefunc)
r = repr(f_many_callbacks)
@@ -135,31 +134,31 @@ class FutureTests(unittest.TestCase):
def test_copy_state(self):
# Test the internal _copy_state method since it's being directly
# invoked in other modules.
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
f.set_result(10)
- newf = futures.Future(loop=self.loop)
+ newf = asyncio.Future(loop=self.loop)
newf._copy_state(f)
self.assertTrue(newf.done())
self.assertEqual(newf.result(), 10)
- f_exception = futures.Future(loop=self.loop)
+ f_exception = asyncio.Future(loop=self.loop)
f_exception.set_exception(RuntimeError())
- newf_exception = futures.Future(loop=self.loop)
+ newf_exception = asyncio.Future(loop=self.loop)
newf_exception._copy_state(f_exception)
self.assertTrue(newf_exception.done())
self.assertRaises(RuntimeError, newf_exception.result)
- f_cancelled = futures.Future(loop=self.loop)
+ f_cancelled = asyncio.Future(loop=self.loop)
f_cancelled.cancel()
- newf_cancelled = futures.Future(loop=self.loop)
+ newf_cancelled = asyncio.Future(loop=self.loop)
newf_cancelled._copy_state(f_cancelled)
self.assertTrue(newf_cancelled.cancelled())
def test_iter(self):
- fut = futures.Future(loop=self.loop)
+ fut = asyncio.Future(loop=self.loop)
def coro():
yield from fut
@@ -172,20 +171,20 @@ class FutureTests(unittest.TestCase):
@unittest.mock.patch('asyncio.futures.logger')
def test_tb_logger_abandoned(self, m_log):
- fut = futures.Future(loop=self.loop)
+ fut = asyncio.Future(loop=self.loop)
del fut
self.assertFalse(m_log.error.called)
@unittest.mock.patch('asyncio.futures.logger')
def test_tb_logger_result_unretrieved(self, m_log):
- fut = futures.Future(loop=self.loop)
+ fut = asyncio.Future(loop=self.loop)
fut.set_result(42)
del fut
self.assertFalse(m_log.error.called)
@unittest.mock.patch('asyncio.futures.logger')
def test_tb_logger_result_retrieved(self, m_log):
- fut = futures.Future(loop=self.loop)
+ fut = asyncio.Future(loop=self.loop)
fut.set_result(42)
fut.result()
del fut
@@ -193,7 +192,7 @@ class FutureTests(unittest.TestCase):
@unittest.mock.patch('asyncio.futures.logger')
def test_tb_logger_exception_unretrieved(self, m_log):
- fut = futures.Future(loop=self.loop)
+ fut = asyncio.Future(loop=self.loop)
fut.set_exception(RuntimeError('boom'))
del fut
test_utils.run_briefly(self.loop)
@@ -201,7 +200,7 @@ class FutureTests(unittest.TestCase):
@unittest.mock.patch('asyncio.futures.logger')
def test_tb_logger_exception_retrieved(self, m_log):
- fut = futures.Future(loop=self.loop)
+ fut = asyncio.Future(loop=self.loop)
fut.set_exception(RuntimeError('boom'))
fut.exception()
del fut
@@ -209,7 +208,7 @@ class FutureTests(unittest.TestCase):
@unittest.mock.patch('asyncio.futures.logger')
def test_tb_logger_exception_result_retrieved(self, m_log):
- fut = futures.Future(loop=self.loop)
+ fut = asyncio.Future(loop=self.loop)
fut.set_exception(RuntimeError('boom'))
self.assertRaises(RuntimeError, fut.result)
del fut
@@ -221,15 +220,15 @@ class FutureTests(unittest.TestCase):
return (arg, threading.get_ident())
ex = concurrent.futures.ThreadPoolExecutor(1)
f1 = ex.submit(run, 'oi')
- f2 = futures.wrap_future(f1, loop=self.loop)
+ f2 = asyncio.wrap_future(f1, loop=self.loop)
res, ident = self.loop.run_until_complete(f2)
- self.assertIsInstance(f2, futures.Future)
+ self.assertIsInstance(f2, asyncio.Future)
self.assertEqual(res, 'oi')
self.assertNotEqual(ident, threading.get_ident())
def test_wrap_future_future(self):
- f1 = futures.Future(loop=self.loop)
- f2 = futures.wrap_future(f1)
+ f1 = asyncio.Future(loop=self.loop)
+ f2 = asyncio.wrap_future(f1)
self.assertIs(f1, f2)
@unittest.mock.patch('asyncio.futures.events')
@@ -238,12 +237,12 @@ class FutureTests(unittest.TestCase):
return (arg, threading.get_ident())
ex = concurrent.futures.ThreadPoolExecutor(1)
f1 = ex.submit(run, 'oi')
- f2 = futures.wrap_future(f1)
+ f2 = asyncio.wrap_future(f1)
self.assertIs(m_events.get_event_loop.return_value, f2._loop)
def test_wrap_future_cancel(self):
f1 = concurrent.futures.Future()
- f2 = futures.wrap_future(f1, loop=self.loop)
+ f2 = asyncio.wrap_future(f1, loop=self.loop)
f2.cancel()
test_utils.run_briefly(self.loop)
self.assertTrue(f1.cancelled())
@@ -251,7 +250,7 @@ class FutureTests(unittest.TestCase):
def test_wrap_future_cancel2(self):
f1 = concurrent.futures.Future()
- f2 = futures.wrap_future(f1, loop=self.loop)
+ f2 = asyncio.wrap_future(f1, loop=self.loop)
f1.set_result(42)
f2.cancel()
test_utils.run_briefly(self.loop)
@@ -264,7 +263,7 @@ class FutureDoneCallbackTests(unittest.TestCase):
def setUp(self):
self.loop = test_utils.TestLoop()
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
def tearDown(self):
self.loop.close()
@@ -279,7 +278,7 @@ class FutureDoneCallbackTests(unittest.TestCase):
return bag_appender
def _new_future(self):
- return futures.Future(loop=self.loop)
+ return asyncio.Future(loop=self.loop)
def test_callbacks_invoked_on_set_result(self):
bag = []
diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py
index df106e0d15..0975f49711 100644
--- a/Lib/test/test_asyncio/test_locks.py
+++ b/Lib/test/test_asyncio/test_locks.py
@@ -4,10 +4,7 @@ import unittest
import unittest.mock
import re
-from asyncio import events
-from asyncio import futures
-from asyncio import locks
-from asyncio import tasks
+import asyncio
from asyncio import test_utils
@@ -24,33 +21,33 @@ class LockTests(unittest.TestCase):
def setUp(self):
self.loop = test_utils.TestLoop()
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
def tearDown(self):
self.loop.close()
def test_ctor_loop(self):
loop = unittest.mock.Mock()
- lock = locks.Lock(loop=loop)
+ lock = asyncio.Lock(loop=loop)
self.assertIs(lock._loop, loop)
- lock = locks.Lock(loop=self.loop)
+ lock = asyncio.Lock(loop=self.loop)
self.assertIs(lock._loop, self.loop)
def test_ctor_noloop(self):
try:
- events.set_event_loop(self.loop)
- lock = locks.Lock()
+ asyncio.set_event_loop(self.loop)
+ lock = asyncio.Lock()
self.assertIs(lock._loop, self.loop)
finally:
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
def test_repr(self):
- lock = locks.Lock(loop=self.loop)
+ lock = asyncio.Lock(loop=self.loop)
self.assertTrue(repr(lock).endswith('[unlocked]>'))
self.assertTrue(RGX_REPR.match(repr(lock)))
- @tasks.coroutine
+ @asyncio.coroutine
def acquire_lock():
yield from lock
@@ -59,9 +56,9 @@ class LockTests(unittest.TestCase):
self.assertTrue(RGX_REPR.match(repr(lock)))
def test_lock(self):
- lock = locks.Lock(loop=self.loop)
+ lock = asyncio.Lock(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def acquire_lock():
return (yield from lock)
@@ -74,31 +71,31 @@ class LockTests(unittest.TestCase):
self.assertFalse(lock.locked())
def test_acquire(self):
- lock = locks.Lock(loop=self.loop)
+ lock = asyncio.Lock(loop=self.loop)
result = []
self.assertTrue(self.loop.run_until_complete(lock.acquire()))
- @tasks.coroutine
+ @asyncio.coroutine
def c1(result):
if (yield from lock.acquire()):
result.append(1)
return True
- @tasks.coroutine
+ @asyncio.coroutine
def c2(result):
if (yield from lock.acquire()):
result.append(2)
return True
- @tasks.coroutine
+ @asyncio.coroutine
def c3(result):
if (yield from lock.acquire()):
result.append(3)
return True
- t1 = tasks.Task(c1(result), loop=self.loop)
- t2 = tasks.Task(c2(result), loop=self.loop)
+ t1 = asyncio.Task(c1(result), loop=self.loop)
+ t2 = asyncio.Task(c2(result), loop=self.loop)
test_utils.run_briefly(self.loop)
self.assertEqual([], result)
@@ -110,7 +107,7 @@ class LockTests(unittest.TestCase):
test_utils.run_briefly(self.loop)
self.assertEqual([1], result)
- t3 = tasks.Task(c3(result), loop=self.loop)
+ t3 = asyncio.Task(c3(result), loop=self.loop)
lock.release()
test_utils.run_briefly(self.loop)
@@ -128,13 +125,13 @@ class LockTests(unittest.TestCase):
self.assertTrue(t3.result())
def test_acquire_cancel(self):
- lock = locks.Lock(loop=self.loop)
+ lock = asyncio.Lock(loop=self.loop)
self.assertTrue(self.loop.run_until_complete(lock.acquire()))
- task = tasks.Task(lock.acquire(), loop=self.loop)
+ task = asyncio.Task(lock.acquire(), loop=self.loop)
self.loop.call_soon(task.cancel)
self.assertRaises(
- futures.CancelledError,
+ asyncio.CancelledError,
self.loop.run_until_complete, task)
self.assertFalse(lock._waiters)
@@ -153,9 +150,9 @@ class LockTests(unittest.TestCase):
# B's waiter; instead, it should move on to C's waiter.
# Setup: A has the lock, b and c are waiting.
- lock = locks.Lock(loop=self.loop)
+ lock = asyncio.Lock(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def lockit(name, blocker):
yield from lock.acquire()
try:
@@ -164,14 +161,14 @@ class LockTests(unittest.TestCase):
finally:
lock.release()
- fa = futures.Future(loop=self.loop)
- ta = tasks.Task(lockit('A', fa), loop=self.loop)
+ fa = asyncio.Future(loop=self.loop)
+ ta = asyncio.Task(lockit('A', fa), loop=self.loop)
test_utils.run_briefly(self.loop)
self.assertTrue(lock.locked())
- tb = tasks.Task(lockit('B', None), loop=self.loop)
+ tb = asyncio.Task(lockit('B', None), loop=self.loop)
test_utils.run_briefly(self.loop)
self.assertEqual(len(lock._waiters), 1)
- tc = tasks.Task(lockit('C', None), loop=self.loop)
+ tc = asyncio.Task(lockit('C', None), loop=self.loop)
test_utils.run_briefly(self.loop)
self.assertEqual(len(lock._waiters), 2)
@@ -187,12 +184,12 @@ class LockTests(unittest.TestCase):
self.assertTrue(tc.done())
def test_release_not_acquired(self):
- lock = locks.Lock(loop=self.loop)
+ lock = asyncio.Lock(loop=self.loop)
self.assertRaises(RuntimeError, lock.release)
def test_release_no_waiters(self):
- lock = locks.Lock(loop=self.loop)
+ lock = asyncio.Lock(loop=self.loop)
self.loop.run_until_complete(lock.acquire())
self.assertTrue(lock.locked())
@@ -200,9 +197,9 @@ class LockTests(unittest.TestCase):
self.assertFalse(lock.locked())
def test_context_manager(self):
- lock = locks.Lock(loop=self.loop)
+ lock = asyncio.Lock(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def acquire_lock():
return (yield from lock)
@@ -211,8 +208,26 @@ class LockTests(unittest.TestCase):
self.assertFalse(lock.locked())
+ def test_context_manager_cant_reuse(self):
+ lock = asyncio.Lock(loop=self.loop)
+
+ @asyncio.coroutine
+ def acquire_lock():
+ return (yield from lock)
+
+ # This spells "yield from lock" outside a generator.
+ cm = self.loop.run_until_complete(acquire_lock())
+ with cm:
+ self.assertTrue(lock.locked())
+
+ self.assertFalse(lock.locked())
+
+ with self.assertRaises(AttributeError):
+ with cm:
+ pass
+
def test_context_manager_no_yield(self):
- lock = locks.Lock(loop=self.loop)
+ lock = asyncio.Lock(loop=self.loop)
try:
with lock:
@@ -222,34 +237,36 @@ class LockTests(unittest.TestCase):
str(err),
'"yield from" should be used as context manager expression')
+ self.assertFalse(lock.locked())
+
class EventTests(unittest.TestCase):
def setUp(self):
self.loop = test_utils.TestLoop()
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
def tearDown(self):
self.loop.close()
def test_ctor_loop(self):
loop = unittest.mock.Mock()
- ev = locks.Event(loop=loop)
+ ev = asyncio.Event(loop=loop)
self.assertIs(ev._loop, loop)
- ev = locks.Event(loop=self.loop)
+ ev = asyncio.Event(loop=self.loop)
self.assertIs(ev._loop, self.loop)
def test_ctor_noloop(self):
try:
- events.set_event_loop(self.loop)
- ev = locks.Event()
+ asyncio.set_event_loop(self.loop)
+ ev = asyncio.Event()
self.assertIs(ev._loop, self.loop)
finally:
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
def test_repr(self):
- ev = locks.Event(loop=self.loop)
+ ev = asyncio.Event(loop=self.loop)
self.assertTrue(repr(ev).endswith('[unset]>'))
match = RGX_REPR.match(repr(ev))
self.assertEqual(match.group('extras'), 'unset')
@@ -263,33 +280,33 @@ class EventTests(unittest.TestCase):
self.assertTrue(RGX_REPR.match(repr(ev)))
def test_wait(self):
- ev = locks.Event(loop=self.loop)
+ ev = asyncio.Event(loop=self.loop)
self.assertFalse(ev.is_set())
result = []
- @tasks.coroutine
+ @asyncio.coroutine
def c1(result):
if (yield from ev.wait()):
result.append(1)
- @tasks.coroutine
+ @asyncio.coroutine
def c2(result):
if (yield from ev.wait()):
result.append(2)
- @tasks.coroutine
+ @asyncio.coroutine
def c3(result):
if (yield from ev.wait()):
result.append(3)
- t1 = tasks.Task(c1(result), loop=self.loop)
- t2 = tasks.Task(c2(result), loop=self.loop)
+ t1 = asyncio.Task(c1(result), loop=self.loop)
+ t2 = asyncio.Task(c2(result), loop=self.loop)
test_utils.run_briefly(self.loop)
self.assertEqual([], result)
- t3 = tasks.Task(c3(result), loop=self.loop)
+ t3 = asyncio.Task(c3(result), loop=self.loop)
ev.set()
test_utils.run_briefly(self.loop)
@@ -303,24 +320,24 @@ class EventTests(unittest.TestCase):
self.assertIsNone(t3.result())
def test_wait_on_set(self):
- ev = locks.Event(loop=self.loop)
+ ev = asyncio.Event(loop=self.loop)
ev.set()
res = self.loop.run_until_complete(ev.wait())
self.assertTrue(res)
def test_wait_cancel(self):
- ev = locks.Event(loop=self.loop)
+ ev = asyncio.Event(loop=self.loop)
- wait = tasks.Task(ev.wait(), loop=self.loop)
+ wait = asyncio.Task(ev.wait(), loop=self.loop)
self.loop.call_soon(wait.cancel)
self.assertRaises(
- futures.CancelledError,
+ asyncio.CancelledError,
self.loop.run_until_complete, wait)
self.assertFalse(ev._waiters)
def test_clear(self):
- ev = locks.Event(loop=self.loop)
+ ev = asyncio.Event(loop=self.loop)
self.assertFalse(ev.is_set())
ev.set()
@@ -330,16 +347,16 @@ class EventTests(unittest.TestCase):
self.assertFalse(ev.is_set())
def test_clear_with_waiters(self):
- ev = locks.Event(loop=self.loop)
+ ev = asyncio.Event(loop=self.loop)
result = []
- @tasks.coroutine
+ @asyncio.coroutine
def c1(result):
if (yield from ev.wait()):
result.append(1)
return True
- t = tasks.Task(c1(result), loop=self.loop)
+ t = asyncio.Task(c1(result), loop=self.loop)
test_utils.run_briefly(self.loop)
self.assertEqual([], result)
@@ -363,55 +380,55 @@ class ConditionTests(unittest.TestCase):
def setUp(self):
self.loop = test_utils.TestLoop()
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
def tearDown(self):
self.loop.close()
def test_ctor_loop(self):
loop = unittest.mock.Mock()
- cond = locks.Condition(loop=loop)
+ cond = asyncio.Condition(loop=loop)
self.assertIs(cond._loop, loop)
- cond = locks.Condition(loop=self.loop)
+ cond = asyncio.Condition(loop=self.loop)
self.assertIs(cond._loop, self.loop)
def test_ctor_noloop(self):
try:
- events.set_event_loop(self.loop)
- cond = locks.Condition()
+ asyncio.set_event_loop(self.loop)
+ cond = asyncio.Condition()
self.assertIs(cond._loop, self.loop)
finally:
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
def test_wait(self):
- cond = locks.Condition(loop=self.loop)
+ cond = asyncio.Condition(loop=self.loop)
result = []
- @tasks.coroutine
+ @asyncio.coroutine
def c1(result):
yield from cond.acquire()
if (yield from cond.wait()):
result.append(1)
return True
- @tasks.coroutine
+ @asyncio.coroutine
def c2(result):
yield from cond.acquire()
if (yield from cond.wait()):
result.append(2)
return True
- @tasks.coroutine
+ @asyncio.coroutine
def c3(result):
yield from cond.acquire()
if (yield from cond.wait()):
result.append(3)
return True
- t1 = tasks.Task(c1(result), loop=self.loop)
- t2 = tasks.Task(c2(result), loop=self.loop)
- t3 = tasks.Task(c3(result), loop=self.loop)
+ t1 = asyncio.Task(c1(result), loop=self.loop)
+ t2 = asyncio.Task(c2(result), loop=self.loop)
+ t3 = asyncio.Task(c3(result), loop=self.loop)
test_utils.run_briefly(self.loop)
self.assertEqual([], result)
@@ -451,25 +468,25 @@ class ConditionTests(unittest.TestCase):
self.assertTrue(t3.result())
def test_wait_cancel(self):
- cond = locks.Condition(loop=self.loop)
+ cond = asyncio.Condition(loop=self.loop)
self.loop.run_until_complete(cond.acquire())
- wait = tasks.Task(cond.wait(), loop=self.loop)
+ wait = asyncio.Task(cond.wait(), loop=self.loop)
self.loop.call_soon(wait.cancel)
self.assertRaises(
- futures.CancelledError,
+ asyncio.CancelledError,
self.loop.run_until_complete, wait)
self.assertFalse(cond._waiters)
self.assertTrue(cond.locked())
def test_wait_unacquired(self):
- cond = locks.Condition(loop=self.loop)
+ cond = asyncio.Condition(loop=self.loop)
self.assertRaises(
RuntimeError,
self.loop.run_until_complete, cond.wait())
def test_wait_for(self):
- cond = locks.Condition(loop=self.loop)
+ cond = asyncio.Condition(loop=self.loop)
presult = False
def predicate():
@@ -477,7 +494,7 @@ class ConditionTests(unittest.TestCase):
result = []
- @tasks.coroutine
+ @asyncio.coroutine
def c1(result):
yield from cond.acquire()
if (yield from cond.wait_for(predicate)):
@@ -485,7 +502,7 @@ class ConditionTests(unittest.TestCase):
cond.release()
return True
- t = tasks.Task(c1(result), loop=self.loop)
+ t = asyncio.Task(c1(result), loop=self.loop)
test_utils.run_briefly(self.loop)
self.assertEqual([], result)
@@ -507,7 +524,7 @@ class ConditionTests(unittest.TestCase):
self.assertTrue(t.result())
def test_wait_for_unacquired(self):
- cond = locks.Condition(loop=self.loop)
+ cond = asyncio.Condition(loop=self.loop)
# predicate can return true immediately
res = self.loop.run_until_complete(cond.wait_for(lambda: [1, 2, 3]))
@@ -519,10 +536,10 @@ class ConditionTests(unittest.TestCase):
cond.wait_for(lambda: False))
def test_notify(self):
- cond = locks.Condition(loop=self.loop)
+ cond = asyncio.Condition(loop=self.loop)
result = []
- @tasks.coroutine
+ @asyncio.coroutine
def c1(result):
yield from cond.acquire()
if (yield from cond.wait()):
@@ -530,7 +547,7 @@ class ConditionTests(unittest.TestCase):
cond.release()
return True
- @tasks.coroutine
+ @asyncio.coroutine
def c2(result):
yield from cond.acquire()
if (yield from cond.wait()):
@@ -538,7 +555,7 @@ class ConditionTests(unittest.TestCase):
cond.release()
return True
- @tasks.coroutine
+ @asyncio.coroutine
def c3(result):
yield from cond.acquire()
if (yield from cond.wait()):
@@ -546,9 +563,9 @@ class ConditionTests(unittest.TestCase):
cond.release()
return True
- t1 = tasks.Task(c1(result), loop=self.loop)
- t2 = tasks.Task(c2(result), loop=self.loop)
- t3 = tasks.Task(c3(result), loop=self.loop)
+ t1 = asyncio.Task(c1(result), loop=self.loop)
+ t2 = asyncio.Task(c2(result), loop=self.loop)
+ t3 = asyncio.Task(c3(result), loop=self.loop)
test_utils.run_briefly(self.loop)
self.assertEqual([], result)
@@ -574,11 +591,11 @@ class ConditionTests(unittest.TestCase):
self.assertTrue(t3.result())
def test_notify_all(self):
- cond = locks.Condition(loop=self.loop)
+ cond = asyncio.Condition(loop=self.loop)
result = []
- @tasks.coroutine
+ @asyncio.coroutine
def c1(result):
yield from cond.acquire()
if (yield from cond.wait()):
@@ -586,7 +603,7 @@ class ConditionTests(unittest.TestCase):
cond.release()
return True
- @tasks.coroutine
+ @asyncio.coroutine
def c2(result):
yield from cond.acquire()
if (yield from cond.wait()):
@@ -594,8 +611,8 @@ class ConditionTests(unittest.TestCase):
cond.release()
return True
- t1 = tasks.Task(c1(result), loop=self.loop)
- t2 = tasks.Task(c2(result), loop=self.loop)
+ t1 = asyncio.Task(c1(result), loop=self.loop)
+ t2 = asyncio.Task(c2(result), loop=self.loop)
test_utils.run_briefly(self.loop)
self.assertEqual([], result)
@@ -612,15 +629,15 @@ class ConditionTests(unittest.TestCase):
self.assertTrue(t2.result())
def test_notify_unacquired(self):
- cond = locks.Condition(loop=self.loop)
+ cond = asyncio.Condition(loop=self.loop)
self.assertRaises(RuntimeError, cond.notify)
def test_notify_all_unacquired(self):
- cond = locks.Condition(loop=self.loop)
+ cond = asyncio.Condition(loop=self.loop)
self.assertRaises(RuntimeError, cond.notify_all)
def test_repr(self):
- cond = locks.Condition(loop=self.loop)
+ cond = asyncio.Condition(loop=self.loop)
self.assertTrue('unlocked' in repr(cond))
self.assertTrue(RGX_REPR.match(repr(cond)))
@@ -636,9 +653,9 @@ class ConditionTests(unittest.TestCase):
self.assertTrue(RGX_REPR.match(repr(cond)))
def test_context_manager(self):
- cond = locks.Condition(loop=self.loop)
+ cond = asyncio.Condition(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def acquire_cond():
return (yield from cond)
@@ -648,7 +665,7 @@ class ConditionTests(unittest.TestCase):
self.assertFalse(cond.locked())
def test_context_manager_no_yield(self):
- cond = locks.Condition(loop=self.loop)
+ cond = asyncio.Condition(loop=self.loop)
try:
with cond:
@@ -658,38 +675,40 @@ class ConditionTests(unittest.TestCase):
str(err),
'"yield from" should be used as context manager expression')
+ self.assertFalse(cond.locked())
+
class SemaphoreTests(unittest.TestCase):
def setUp(self):
self.loop = test_utils.TestLoop()
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
def tearDown(self):
self.loop.close()
def test_ctor_loop(self):
loop = unittest.mock.Mock()
- sem = locks.Semaphore(loop=loop)
+ sem = asyncio.Semaphore(loop=loop)
self.assertIs(sem._loop, loop)
- sem = locks.Semaphore(loop=self.loop)
+ sem = asyncio.Semaphore(loop=self.loop)
self.assertIs(sem._loop, self.loop)
def test_ctor_noloop(self):
try:
- events.set_event_loop(self.loop)
- sem = locks.Semaphore()
+ asyncio.set_event_loop(self.loop)
+ sem = asyncio.Semaphore()
self.assertIs(sem._loop, self.loop)
finally:
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
def test_initial_value_zero(self):
- sem = locks.Semaphore(0, loop=self.loop)
+ sem = asyncio.Semaphore(0, loop=self.loop)
self.assertTrue(sem.locked())
def test_repr(self):
- sem = locks.Semaphore(loop=self.loop)
+ sem = asyncio.Semaphore(loop=self.loop)
self.assertTrue(repr(sem).endswith('[unlocked,value:1]>'))
self.assertTrue(RGX_REPR.match(repr(sem)))
@@ -707,10 +726,10 @@ class SemaphoreTests(unittest.TestCase):
self.assertTrue(RGX_REPR.match(repr(sem)))
def test_semaphore(self):
- sem = locks.Semaphore(loop=self.loop)
+ sem = asyncio.Semaphore(loop=self.loop)
self.assertEqual(1, sem._value)
- @tasks.coroutine
+ @asyncio.coroutine
def acquire_lock():
return (yield from sem)
@@ -725,43 +744,43 @@ class SemaphoreTests(unittest.TestCase):
self.assertEqual(1, sem._value)
def test_semaphore_value(self):
- self.assertRaises(ValueError, locks.Semaphore, -1)
+ self.assertRaises(ValueError, asyncio.Semaphore, -1)
def test_acquire(self):
- sem = locks.Semaphore(3, loop=self.loop)
+ sem = asyncio.Semaphore(3, loop=self.loop)
result = []
self.assertTrue(self.loop.run_until_complete(sem.acquire()))
self.assertTrue(self.loop.run_until_complete(sem.acquire()))
self.assertFalse(sem.locked())
- @tasks.coroutine
+ @asyncio.coroutine
def c1(result):
yield from sem.acquire()
result.append(1)
return True
- @tasks.coroutine
+ @asyncio.coroutine
def c2(result):
yield from sem.acquire()
result.append(2)
return True
- @tasks.coroutine
+ @asyncio.coroutine
def c3(result):
yield from sem.acquire()
result.append(3)
return True
- @tasks.coroutine
+ @asyncio.coroutine
def c4(result):
yield from sem.acquire()
result.append(4)
return True
- t1 = tasks.Task(c1(result), loop=self.loop)
- t2 = tasks.Task(c2(result), loop=self.loop)
- t3 = tasks.Task(c3(result), loop=self.loop)
+ t1 = asyncio.Task(c1(result), loop=self.loop)
+ t2 = asyncio.Task(c2(result), loop=self.loop)
+ t3 = asyncio.Task(c3(result), loop=self.loop)
test_utils.run_briefly(self.loop)
self.assertEqual([1], result)
@@ -769,7 +788,7 @@ class SemaphoreTests(unittest.TestCase):
self.assertEqual(2, len(sem._waiters))
self.assertEqual(0, sem._value)
- t4 = tasks.Task(c4(result), loop=self.loop)
+ t4 = asyncio.Task(c4(result), loop=self.loop)
sem.release()
sem.release()
@@ -794,23 +813,23 @@ class SemaphoreTests(unittest.TestCase):
sem.release()
def test_acquire_cancel(self):
- sem = locks.Semaphore(loop=self.loop)
+ sem = asyncio.Semaphore(loop=self.loop)
self.loop.run_until_complete(sem.acquire())
- acquire = tasks.Task(sem.acquire(), loop=self.loop)
+ acquire = asyncio.Task(sem.acquire(), loop=self.loop)
self.loop.call_soon(acquire.cancel)
self.assertRaises(
- futures.CancelledError,
+ asyncio.CancelledError,
self.loop.run_until_complete, acquire)
self.assertFalse(sem._waiters)
def test_release_not_acquired(self):
- sem = locks.BoundedSemaphore(loop=self.loop)
+ sem = asyncio.BoundedSemaphore(loop=self.loop)
self.assertRaises(ValueError, sem.release)
def test_release_no_waiters(self):
- sem = locks.Semaphore(loop=self.loop)
+ sem = asyncio.Semaphore(loop=self.loop)
self.loop.run_until_complete(sem.acquire())
self.assertTrue(sem.locked())
@@ -818,9 +837,9 @@ class SemaphoreTests(unittest.TestCase):
self.assertFalse(sem.locked())
def test_context_manager(self):
- sem = locks.Semaphore(2, loop=self.loop)
+ sem = asyncio.Semaphore(2, loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def acquire_lock():
return (yield from sem)
@@ -833,6 +852,19 @@ class SemaphoreTests(unittest.TestCase):
self.assertEqual(2, sem._value)
+ def test_context_manager_no_yield(self):
+ sem = asyncio.Semaphore(2, loop=self.loop)
+
+ try:
+ with sem:
+ self.fail('RuntimeError is not raised in with expression')
+ except RuntimeError as err:
+ self.assertEqual(
+ str(err),
+ '"yield from" should be used as context manager expression')
+
+ self.assertEqual(2, sem._value)
+
if __name__ == '__main__':
unittest.main()
diff --git a/Lib/test/test_asyncio/test_queues.py b/Lib/test/test_asyncio/test_queues.py
index 8af4ee7f9b..fc2bf460b8 100644
--- a/Lib/test/test_asyncio/test_queues.py
+++ b/Lib/test/test_asyncio/test_queues.py
@@ -3,11 +3,7 @@
import unittest
import unittest.mock
-from asyncio import events
-from asyncio import futures
-from asyncio import locks
-from asyncio import queues
-from asyncio import tasks
+import asyncio
from asyncio import test_utils
@@ -15,7 +11,7 @@ class _QueueTestBase(unittest.TestCase):
def setUp(self):
self.loop = test_utils.TestLoop()
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
def tearDown(self):
self.loop.close()
@@ -39,57 +35,57 @@ class QueueBasicTests(_QueueTestBase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- q = queues.Queue(loop=loop)
+ q = asyncio.Queue(loop=loop)
self.assertTrue(fn(q).startswith('<Queue'), fn(q))
id_is_present = hex(id(q)) in fn(q)
self.assertEqual(expect_id, id_is_present)
- @tasks.coroutine
+ @asyncio.coroutine
def add_getter():
- q = queues.Queue(loop=loop)
+ q = asyncio.Queue(loop=loop)
# Start a task that waits to get.
- tasks.Task(q.get(), loop=loop)
+ asyncio.Task(q.get(), loop=loop)
# Let it start waiting.
- yield from tasks.sleep(0.1, loop=loop)
+ yield from asyncio.sleep(0.1, loop=loop)
self.assertTrue('_getters[1]' in fn(q))
# resume q.get coroutine to finish generator
q.put_nowait(0)
loop.run_until_complete(add_getter())
- @tasks.coroutine
+ @asyncio.coroutine
def add_putter():
- q = queues.Queue(maxsize=1, loop=loop)
+ q = asyncio.Queue(maxsize=1, loop=loop)
q.put_nowait(1)
# Start a task that waits to put.
- tasks.Task(q.put(2), loop=loop)
+ asyncio.Task(q.put(2), loop=loop)
# Let it start waiting.
- yield from tasks.sleep(0.1, loop=loop)
+ yield from asyncio.sleep(0.1, loop=loop)
self.assertTrue('_putters[1]' in fn(q))
# resume q.put coroutine to finish generator
q.get_nowait()
loop.run_until_complete(add_putter())
- q = queues.Queue(loop=loop)
+ q = asyncio.Queue(loop=loop)
q.put_nowait(1)
self.assertTrue('_queue=[1]' in fn(q))
def test_ctor_loop(self):
loop = unittest.mock.Mock()
- q = queues.Queue(loop=loop)
+ q = asyncio.Queue(loop=loop)
self.assertIs(q._loop, loop)
- q = queues.Queue(loop=self.loop)
+ q = asyncio.Queue(loop=self.loop)
self.assertIs(q._loop, self.loop)
def test_ctor_noloop(self):
try:
- events.set_event_loop(self.loop)
- q = queues.Queue()
+ asyncio.set_event_loop(self.loop)
+ q = asyncio.Queue()
self.assertIs(q._loop, self.loop)
finally:
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
def test_repr(self):
self._test_repr_or_str(repr, True)
@@ -98,7 +94,7 @@ class QueueBasicTests(_QueueTestBase):
self._test_repr_or_str(str, False)
def test_empty(self):
- q = queues.Queue(loop=self.loop)
+ q = asyncio.Queue(loop=self.loop)
self.assertTrue(q.empty())
q.put_nowait(1)
self.assertFalse(q.empty())
@@ -106,15 +102,15 @@ class QueueBasicTests(_QueueTestBase):
self.assertTrue(q.empty())
def test_full(self):
- q = queues.Queue(loop=self.loop)
+ q = asyncio.Queue(loop=self.loop)
self.assertFalse(q.full())
- q = queues.Queue(maxsize=1, loop=self.loop)
+ q = asyncio.Queue(maxsize=1, loop=self.loop)
q.put_nowait(1)
self.assertTrue(q.full())
def test_order(self):
- q = queues.Queue(loop=self.loop)
+ q = asyncio.Queue(loop=self.loop)
for i in [1, 3, 2]:
q.put_nowait(i)
@@ -133,28 +129,28 @@ class QueueBasicTests(_QueueTestBase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- q = queues.Queue(maxsize=2, loop=loop)
+ q = asyncio.Queue(maxsize=2, loop=loop)
self.assertEqual(2, q.maxsize)
have_been_put = []
- @tasks.coroutine
+ @asyncio.coroutine
def putter():
for i in range(3):
yield from q.put(i)
have_been_put.append(i)
return True
- @tasks.coroutine
+ @asyncio.coroutine
def test():
- t = tasks.Task(putter(), loop=loop)
- yield from tasks.sleep(0.01, loop=loop)
+ t = asyncio.Task(putter(), loop=loop)
+ yield from asyncio.sleep(0.01, loop=loop)
# The putter is blocked after putting two items.
self.assertEqual([0, 1], have_been_put)
self.assertEqual(0, q.get_nowait())
# Let the putter resume and put last item.
- yield from tasks.sleep(0.01, loop=loop)
+ yield from asyncio.sleep(0.01, loop=loop)
self.assertEqual([0, 1, 2], have_been_put)
self.assertEqual(1, q.get_nowait())
self.assertEqual(2, q.get_nowait())
@@ -169,10 +165,10 @@ class QueueBasicTests(_QueueTestBase):
class QueueGetTests(_QueueTestBase):
def test_blocking_get(self):
- q = queues.Queue(loop=self.loop)
+ q = asyncio.Queue(loop=self.loop)
q.put_nowait(1)
- @tasks.coroutine
+ @asyncio.coroutine
def queue_get():
return (yield from q.get())
@@ -180,10 +176,10 @@ class QueueGetTests(_QueueTestBase):
self.assertEqual(1, res)
def test_get_with_putters(self):
- q = queues.Queue(1, loop=self.loop)
+ q = asyncio.Queue(1, loop=self.loop)
q.put_nowait(1)
- waiter = futures.Future(loop=self.loop)
+ waiter = asyncio.Future(loop=self.loop)
q._putters.append((2, waiter))
res = self.loop.run_until_complete(q.get())
@@ -201,11 +197,11 @@ class QueueGetTests(_QueueTestBase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- q = queues.Queue(loop=loop)
- started = locks.Event(loop=loop)
+ q = asyncio.Queue(loop=loop)
+ started = asyncio.Event(loop=loop)
finished = False
- @tasks.coroutine
+ @asyncio.coroutine
def queue_get():
nonlocal finished
started.set()
@@ -213,10 +209,10 @@ class QueueGetTests(_QueueTestBase):
finished = True
return res
- @tasks.coroutine
+ @asyncio.coroutine
def queue_put():
loop.call_later(0.01, q.put_nowait, 1)
- queue_get_task = tasks.Task(queue_get(), loop=loop)
+ queue_get_task = asyncio.Task(queue_get(), loop=loop)
yield from started.wait()
self.assertFalse(finished)
res = yield from queue_get_task
@@ -228,13 +224,13 @@ class QueueGetTests(_QueueTestBase):
self.assertAlmostEqual(0.01, loop.time())
def test_nonblocking_get(self):
- q = queues.Queue(loop=self.loop)
+ q = asyncio.Queue(loop=self.loop)
q.put_nowait(1)
self.assertEqual(1, q.get_nowait())
def test_nonblocking_get_exception(self):
- q = queues.Queue(loop=self.loop)
- self.assertRaises(queues.Empty, q.get_nowait)
+ q = asyncio.Queue(loop=self.loop)
+ self.assertRaises(asyncio.QueueEmpty, q.get_nowait)
def test_get_cancelled(self):
@@ -248,16 +244,16 @@ class QueueGetTests(_QueueTestBase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- q = queues.Queue(loop=loop)
+ q = asyncio.Queue(loop=loop)
- @tasks.coroutine
+ @asyncio.coroutine
def queue_get():
- return (yield from tasks.wait_for(q.get(), 0.051, loop=loop))
+ return (yield from asyncio.wait_for(q.get(), 0.051, loop=loop))
- @tasks.coroutine
+ @asyncio.coroutine
def test():
- get_task = tasks.Task(queue_get(), loop=loop)
- yield from tasks.sleep(0.01, loop=loop) # let the task start
+ get_task = asyncio.Task(queue_get(), loop=loop)
+ yield from asyncio.sleep(0.01, loop=loop) # let the task start
q.put_nowait(1)
return (yield from get_task)
@@ -265,10 +261,10 @@ class QueueGetTests(_QueueTestBase):
self.assertAlmostEqual(0.06, loop.time())
def test_get_cancelled_race(self):
- q = queues.Queue(loop=self.loop)
+ q = asyncio.Queue(loop=self.loop)
- t1 = tasks.Task(q.get(), loop=self.loop)
- t2 = tasks.Task(q.get(), loop=self.loop)
+ t1 = asyncio.Task(q.get(), loop=self.loop)
+ t2 = asyncio.Task(q.get(), loop=self.loop)
test_utils.run_briefly(self.loop)
t1.cancel()
@@ -279,9 +275,9 @@ class QueueGetTests(_QueueTestBase):
self.assertEqual(t2.result(), 'a')
def test_get_with_waiting_putters(self):
- q = queues.Queue(loop=self.loop, maxsize=1)
- tasks.Task(q.put('a'), loop=self.loop)
- tasks.Task(q.put('b'), loop=self.loop)
+ q = asyncio.Queue(loop=self.loop, maxsize=1)
+ asyncio.Task(q.put('a'), loop=self.loop)
+ asyncio.Task(q.put('b'), loop=self.loop)
test_utils.run_briefly(self.loop)
self.assertEqual(self.loop.run_until_complete(q.get()), 'a')
self.assertEqual(self.loop.run_until_complete(q.get()), 'b')
@@ -290,9 +286,9 @@ class QueueGetTests(_QueueTestBase):
class QueuePutTests(_QueueTestBase):
def test_blocking_put(self):
- q = queues.Queue(loop=self.loop)
+ q = asyncio.Queue(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def queue_put():
# No maxsize, won't block.
yield from q.put(1)
@@ -309,11 +305,11 @@ class QueuePutTests(_QueueTestBase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- q = queues.Queue(maxsize=1, loop=loop)
- started = locks.Event(loop=loop)
+ q = asyncio.Queue(maxsize=1, loop=loop)
+ started = asyncio.Event(loop=loop)
finished = False
- @tasks.coroutine
+ @asyncio.coroutine
def queue_put():
nonlocal finished
started.set()
@@ -321,10 +317,10 @@ class QueuePutTests(_QueueTestBase):
yield from q.put(2)
finished = True
- @tasks.coroutine
+ @asyncio.coroutine
def queue_get():
loop.call_later(0.01, q.get_nowait)
- queue_put_task = tasks.Task(queue_put(), loop=loop)
+ queue_put_task = asyncio.Task(queue_put(), loop=loop)
yield from started.wait()
self.assertFalse(finished)
yield from queue_put_task
@@ -334,38 +330,38 @@ class QueuePutTests(_QueueTestBase):
self.assertAlmostEqual(0.01, loop.time())
def test_nonblocking_put(self):
- q = queues.Queue(loop=self.loop)
+ q = asyncio.Queue(loop=self.loop)
q.put_nowait(1)
self.assertEqual(1, q.get_nowait())
def test_nonblocking_put_exception(self):
- q = queues.Queue(maxsize=1, loop=self.loop)
+ q = asyncio.Queue(maxsize=1, loop=self.loop)
q.put_nowait(1)
- self.assertRaises(queues.Full, q.put_nowait, 2)
+ self.assertRaises(asyncio.QueueFull, q.put_nowait, 2)
def test_put_cancelled(self):
- q = queues.Queue(loop=self.loop)
+ q = asyncio.Queue(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def queue_put():
yield from q.put(1)
return True
- @tasks.coroutine
+ @asyncio.coroutine
def test():
return (yield from q.get())
- t = tasks.Task(queue_put(), loop=self.loop)
+ t = asyncio.Task(queue_put(), loop=self.loop)
self.assertEqual(1, self.loop.run_until_complete(test()))
self.assertTrue(t.done())
self.assertTrue(t.result())
def test_put_cancelled_race(self):
- q = queues.Queue(loop=self.loop, maxsize=1)
+ q = asyncio.Queue(loop=self.loop, maxsize=1)
- tasks.Task(q.put('a'), loop=self.loop)
- tasks.Task(q.put('c'), loop=self.loop)
- t = tasks.Task(q.put('b'), loop=self.loop)
+ asyncio.Task(q.put('a'), loop=self.loop)
+ asyncio.Task(q.put('c'), loop=self.loop)
+ t = asyncio.Task(q.put('b'), loop=self.loop)
test_utils.run_briefly(self.loop)
t.cancel()
@@ -375,8 +371,8 @@ class QueuePutTests(_QueueTestBase):
self.assertEqual(q.get_nowait(), 'c')
def test_put_with_waiting_getters(self):
- q = queues.Queue(loop=self.loop)
- t = tasks.Task(q.get(), loop=self.loop)
+ q = asyncio.Queue(loop=self.loop)
+ t = asyncio.Task(q.get(), loop=self.loop)
test_utils.run_briefly(self.loop)
self.loop.run_until_complete(q.put('a'))
self.assertEqual(self.loop.run_until_complete(t), 'a')
@@ -385,7 +381,7 @@ class QueuePutTests(_QueueTestBase):
class LifoQueueTests(_QueueTestBase):
def test_order(self):
- q = queues.LifoQueue(loop=self.loop)
+ q = asyncio.LifoQueue(loop=self.loop)
for i in [1, 3, 2]:
q.put_nowait(i)
@@ -396,7 +392,7 @@ class LifoQueueTests(_QueueTestBase):
class PriorityQueueTests(_QueueTestBase):
def test_order(self):
- q = queues.PriorityQueue(loop=self.loop)
+ q = asyncio.PriorityQueue(loop=self.loop)
for i in [1, 3, 2]:
q.put_nowait(i)
@@ -407,11 +403,11 @@ class PriorityQueueTests(_QueueTestBase):
class JoinableQueueTests(_QueueTestBase):
def test_task_done_underflow(self):
- q = queues.JoinableQueue(loop=self.loop)
+ q = asyncio.JoinableQueue(loop=self.loop)
self.assertRaises(ValueError, q.task_done)
def test_task_done(self):
- q = queues.JoinableQueue(loop=self.loop)
+ q = asyncio.JoinableQueue(loop=self.loop)
for i in range(100):
q.put_nowait(i)
@@ -421,7 +417,7 @@ class JoinableQueueTests(_QueueTestBase):
# Join the queue and assert all items have been processed.
running = True
- @tasks.coroutine
+ @asyncio.coroutine
def worker():
nonlocal accumulator
@@ -430,10 +426,10 @@ class JoinableQueueTests(_QueueTestBase):
accumulator += item
q.task_done()
- @tasks.coroutine
+ @asyncio.coroutine
def test():
for _ in range(2):
- tasks.Task(worker(), loop=self.loop)
+ asyncio.Task(worker(), loop=self.loop)
yield from q.join()
@@ -446,12 +442,12 @@ class JoinableQueueTests(_QueueTestBase):
q.put_nowait(0)
def test_join_empty_queue(self):
- q = queues.JoinableQueue(loop=self.loop)
+ q = asyncio.JoinableQueue(loop=self.loop)
# Test that a queue join()s successfully, and before anything else
# (done twice for insurance).
- @tasks.coroutine
+ @asyncio.coroutine
def join():
yield from q.join()
yield from q.join()
@@ -459,7 +455,7 @@ class JoinableQueueTests(_QueueTestBase):
self.loop.run_until_complete(join())
def test_format(self):
- q = queues.JoinableQueue(loop=self.loop)
+ q = asyncio.JoinableQueue(loop=self.loop)
self.assertEqual(q._format(), 'maxsize=0')
q._unfinished_tasks = 2
diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py
index 38aa766998..4c81e75d22 100644
--- a/Lib/test/test_asyncio/test_selector_events.py
+++ b/Lib/test/test_asyncio/test_selector_events.py
@@ -13,10 +13,9 @@ try:
except ImportError:
ssl = None
-from asyncio import futures
+import asyncio
from asyncio import selectors
from asyncio import test_utils
-from asyncio.protocols import DatagramProtocol, Protocol
from asyncio.selector_events import BaseSelectorEventLoop
from asyncio.selector_events import _SelectorTransport
from asyncio.selector_events import _SelectorSslTransport
@@ -39,7 +38,9 @@ def list_to_buffer(l=()):
class BaseSelectorEventLoopTests(unittest.TestCase):
def setUp(self):
- self.loop = TestBaseSelectorEventLoop(unittest.mock.Mock())
+ selector = unittest.mock.Mock()
+ selector.resolution = 1e-3
+ self.loop = TestBaseSelectorEventLoop(selector)
def test_make_socket_transport(self):
m = unittest.mock.Mock()
@@ -125,13 +126,13 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
self.loop._sock_recv = unittest.mock.Mock()
f = self.loop.sock_recv(sock, 1024)
- self.assertIsInstance(f, futures.Future)
+ self.assertIsInstance(f, asyncio.Future)
self.loop._sock_recv.assert_called_with(f, False, sock, 1024)
def test__sock_recv_canceled_fut(self):
sock = unittest.mock.Mock()
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
f.cancel()
self.loop._sock_recv(f, False, sock, 1024)
@@ -141,7 +142,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
sock = unittest.mock.Mock()
sock.fileno.return_value = 10
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
f.cancel()
self.loop.remove_reader = unittest.mock.Mock()
@@ -149,7 +150,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
self.assertEqual((10,), self.loop.remove_reader.call_args[0])
def test__sock_recv_tryagain(self):
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
sock = unittest.mock.Mock()
sock.fileno.return_value = 10
sock.recv.side_effect = BlockingIOError
@@ -160,7 +161,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
self.loop.add_reader.call_args[0])
def test__sock_recv_exception(self):
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
sock = unittest.mock.Mock()
sock.fileno.return_value = 10
err = sock.recv.side_effect = OSError()
@@ -173,7 +174,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
self.loop._sock_sendall = unittest.mock.Mock()
f = self.loop.sock_sendall(sock, b'data')
- self.assertIsInstance(f, futures.Future)
+ self.assertIsInstance(f, asyncio.Future)
self.assertEqual(
(f, False, sock, b'data'),
self.loop._sock_sendall.call_args[0])
@@ -183,7 +184,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
self.loop._sock_sendall = unittest.mock.Mock()
f = self.loop.sock_sendall(sock, b'')
- self.assertIsInstance(f, futures.Future)
+ self.assertIsInstance(f, asyncio.Future)
self.assertTrue(f.done())
self.assertIsNone(f.result())
self.assertFalse(self.loop._sock_sendall.called)
@@ -191,7 +192,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
def test__sock_sendall_canceled_fut(self):
sock = unittest.mock.Mock()
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
f.cancel()
self.loop._sock_sendall(f, False, sock, b'data')
@@ -201,7 +202,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
sock = unittest.mock.Mock()
sock.fileno.return_value = 10
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
f.cancel()
self.loop.remove_writer = unittest.mock.Mock()
@@ -209,7 +210,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
self.assertEqual((10,), self.loop.remove_writer.call_args[0])
def test__sock_sendall_tryagain(self):
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
sock = unittest.mock.Mock()
sock.fileno.return_value = 10
sock.send.side_effect = BlockingIOError
@@ -221,7 +222,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
self.loop.add_writer.call_args[0])
def test__sock_sendall_interrupted(self):
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
sock = unittest.mock.Mock()
sock.fileno.return_value = 10
sock.send.side_effect = InterruptedError
@@ -233,7 +234,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
self.loop.add_writer.call_args[0])
def test__sock_sendall_exception(self):
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
sock = unittest.mock.Mock()
sock.fileno.return_value = 10
err = sock.send.side_effect = OSError()
@@ -244,7 +245,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
def test__sock_sendall(self):
sock = unittest.mock.Mock()
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
sock.fileno.return_value = 10
sock.send.return_value = 4
@@ -255,7 +256,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
def test__sock_sendall_partial(self):
sock = unittest.mock.Mock()
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
sock.fileno.return_value = 10
sock.send.return_value = 2
@@ -269,7 +270,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
def test__sock_sendall_none(self):
sock = unittest.mock.Mock()
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
sock.fileno.return_value = 10
sock.send.return_value = 0
@@ -285,13 +286,13 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
self.loop._sock_connect = unittest.mock.Mock()
f = self.loop.sock_connect(sock, ('127.0.0.1', 8080))
- self.assertIsInstance(f, futures.Future)
+ self.assertIsInstance(f, asyncio.Future)
self.assertEqual(
(f, False, sock, ('127.0.0.1', 8080)),
self.loop._sock_connect.call_args[0])
def test__sock_connect(self):
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
sock = unittest.mock.Mock()
sock.fileno.return_value = 10
@@ -304,7 +305,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
def test__sock_connect_canceled_fut(self):
sock = unittest.mock.Mock()
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
f.cancel()
self.loop._sock_connect(f, False, sock, ('127.0.0.1', 8080))
@@ -314,7 +315,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
sock = unittest.mock.Mock()
sock.fileno.return_value = 10
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
f.cancel()
self.loop.remove_writer = unittest.mock.Mock()
@@ -322,7 +323,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
self.assertEqual((10,), self.loop.remove_writer.call_args[0])
def test__sock_connect_tryagain(self):
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
sock = unittest.mock.Mock()
sock.fileno.return_value = 10
sock.getsockopt.return_value = errno.EAGAIN
@@ -337,7 +338,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
self.loop.add_writer.call_args[0])
def test__sock_connect_exception(self):
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
sock = unittest.mock.Mock()
sock.fileno.return_value = 10
sock.getsockopt.return_value = errno.ENOTCONN
@@ -351,12 +352,12 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
self.loop._sock_accept = unittest.mock.Mock()
f = self.loop.sock_accept(sock)
- self.assertIsInstance(f, futures.Future)
+ self.assertIsInstance(f, asyncio.Future)
self.assertEqual(
(f, False, sock), self.loop._sock_accept.call_args[0])
def test__sock_accept(self):
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
conn = unittest.mock.Mock()
@@ -372,7 +373,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
def test__sock_accept_canceled_fut(self):
sock = unittest.mock.Mock()
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
f.cancel()
self.loop._sock_accept(f, False, sock)
@@ -382,7 +383,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
sock = unittest.mock.Mock()
sock.fileno.return_value = 10
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
f.cancel()
self.loop.remove_reader = unittest.mock.Mock()
@@ -390,7 +391,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
self.assertEqual((10,), self.loop.remove_reader.call_args[0])
def test__sock_accept_tryagain(self):
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
sock = unittest.mock.Mock()
sock.fileno.return_value = 10
sock.accept.side_effect = BlockingIOError
@@ -402,7 +403,7 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
self.loop.add_reader.call_args[0])
def test__sock_accept_exception(self):
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
sock = unittest.mock.Mock()
sock.fileno.return_value = 10
err = sock.accept.side_effect = OSError()
@@ -585,7 +586,7 @@ class SelectorTransportTests(unittest.TestCase):
def setUp(self):
self.loop = test_utils.TestLoop()
- self.protocol = test_utils.make_test_protocol(Protocol)
+ self.protocol = test_utils.make_test_protocol(asyncio.Protocol)
self.sock = unittest.mock.Mock(socket.socket)
self.sock.fileno.return_value = 7
@@ -672,7 +673,7 @@ class SelectorSocketTransportTests(unittest.TestCase):
def setUp(self):
self.loop = test_utils.TestLoop()
- self.protocol = test_utils.make_test_protocol(Protocol)
+ self.protocol = test_utils.make_test_protocol(asyncio.Protocol)
self.sock = unittest.mock.Mock(socket.socket)
self.sock_fd = self.sock.fileno.return_value = 7
@@ -684,7 +685,7 @@ class SelectorSocketTransportTests(unittest.TestCase):
self.protocol.connection_made.assert_called_with(tr)
def test_ctor_with_waiter(self):
- fut = futures.Future(loop=self.loop)
+ fut = asyncio.Future(loop=self.loop)
_SelectorSocketTransport(
self.loop, self.sock, self.protocol, fut)
@@ -1037,7 +1038,7 @@ class SelectorSslTransportTests(unittest.TestCase):
def setUp(self):
self.loop = test_utils.TestLoop()
- self.protocol = test_utils.make_test_protocol(Protocol)
+ self.protocol = test_utils.make_test_protocol(asyncio.Protocol)
self.sock = unittest.mock.Mock(socket.socket)
self.sock.fileno.return_value = 7
self.sslsock = unittest.mock.Mock()
@@ -1055,7 +1056,7 @@ class SelectorSslTransportTests(unittest.TestCase):
return transport
def test_on_handshake(self):
- waiter = futures.Future(loop=self.loop)
+ waiter = asyncio.Future(loop=self.loop)
tr = _SelectorSslTransport(
self.loop, self.sock, self.protocol, self.sslcontext,
waiter=waiter)
@@ -1083,7 +1084,7 @@ class SelectorSslTransportTests(unittest.TestCase):
self.sslsock.do_handshake.side_effect = exc
transport = _SelectorSslTransport(
self.loop, self.sock, self.protocol, self.sslcontext)
- transport._waiter = futures.Future(loop=self.loop)
+ transport._waiter = asyncio.Future(loop=self.loop)
transport._on_handshake()
self.assertTrue(self.sslsock.close.called)
self.assertTrue(transport._waiter.done())
@@ -1092,7 +1093,7 @@ class SelectorSslTransportTests(unittest.TestCase):
def test_on_handshake_base_exc(self):
transport = _SelectorSslTransport(
self.loop, self.sock, self.protocol, self.sslcontext)
- transport._waiter = futures.Future(loop=self.loop)
+ transport._waiter = asyncio.Future(loop=self.loop)
exc = BaseException()
self.sslsock.do_handshake.side_effect = exc
self.assertRaises(BaseException, transport._on_handshake)
@@ -1366,7 +1367,7 @@ class SelectorDatagramTransportTests(unittest.TestCase):
def setUp(self):
self.loop = test_utils.TestLoop()
- self.protocol = test_utils.make_test_protocol(DatagramProtocol)
+ self.protocol = test_utils.make_test_protocol(asyncio.DatagramProtocol)
self.sock = unittest.mock.Mock(spec_set=socket.socket)
self.sock.fileno.return_value = 7
diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py
index 5516c15873..2e4f99f85f 100644
--- a/Lib/test/test_asyncio/test_streams.py
+++ b/Lib/test/test_asyncio/test_streams.py
@@ -8,9 +8,7 @@ try:
except ImportError:
ssl = None
-from asyncio import events
-from asyncio import streams
-from asyncio import tasks
+import asyncio
from asyncio import test_utils
@@ -19,8 +17,8 @@ class StreamReaderTests(unittest.TestCase):
DATA = b'line1\nline2\nline3\n'
def setUp(self):
- self.loop = events.new_event_loop()
- events.set_event_loop(None)
+ self.loop = asyncio.new_event_loop()
+ asyncio.set_event_loop(None)
def tearDown(self):
# just in case if we have transport close callbacks
@@ -31,12 +29,12 @@ class StreamReaderTests(unittest.TestCase):
@unittest.mock.patch('asyncio.streams.events')
def test_ctor_global_loop(self, m_events):
- stream = streams.StreamReader()
+ stream = asyncio.StreamReader()
self.assertIs(stream._loop, m_events.get_event_loop.return_value)
def test_open_connection(self):
with test_utils.run_test_server() as httpd:
- f = streams.open_connection(*httpd.address, loop=self.loop)
+ f = asyncio.open_connection(*httpd.address, loop=self.loop)
reader, writer = self.loop.run_until_complete(f)
writer.write(b'GET / HTTP/1.0\r\n\r\n')
f = reader.readline()
@@ -52,12 +50,12 @@ class StreamReaderTests(unittest.TestCase):
def test_open_connection_no_loop_ssl(self):
with test_utils.run_test_server(use_ssl=True) as httpd:
try:
- events.set_event_loop(self.loop)
- f = streams.open_connection(*httpd.address,
+ asyncio.set_event_loop(self.loop)
+ f = asyncio.open_connection(*httpd.address,
ssl=test_utils.dummy_ssl_context())
reader, writer = self.loop.run_until_complete(f)
finally:
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
writer.write(b'GET / HTTP/1.0\r\n\r\n')
f = reader.read()
data = self.loop.run_until_complete(f)
@@ -67,7 +65,7 @@ class StreamReaderTests(unittest.TestCase):
def test_open_connection_error(self):
with test_utils.run_test_server() as httpd:
- f = streams.open_connection(*httpd.address, loop=self.loop)
+ f = asyncio.open_connection(*httpd.address, loop=self.loop)
reader, writer = self.loop.run_until_complete(f)
writer._protocol.connection_lost(ZeroDivisionError())
f = reader.read()
@@ -78,20 +76,20 @@ class StreamReaderTests(unittest.TestCase):
test_utils.run_briefly(self.loop)
def test_feed_empty_data(self):
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
stream.feed_data(b'')
self.assertEqual(0, stream._byte_count)
def test_feed_data_byte_count(self):
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
stream.feed_data(self.DATA)
self.assertEqual(len(self.DATA), stream._byte_count)
def test_read_zero(self):
# Read zero bytes.
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
stream.feed_data(self.DATA)
data = self.loop.run_until_complete(stream.read(0))
@@ -100,8 +98,8 @@ class StreamReaderTests(unittest.TestCase):
def test_read(self):
# Read bytes.
- stream = streams.StreamReader(loop=self.loop)
- read_task = tasks.Task(stream.read(30), loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
+ read_task = asyncio.Task(stream.read(30), loop=self.loop)
def cb():
stream.feed_data(self.DATA)
@@ -113,7 +111,7 @@ class StreamReaderTests(unittest.TestCase):
def test_read_line_breaks(self):
# Read bytes without line breaks.
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
stream.feed_data(b'line1')
stream.feed_data(b'line2')
@@ -124,8 +122,8 @@ class StreamReaderTests(unittest.TestCase):
def test_read_eof(self):
# Read bytes, stop at eof.
- stream = streams.StreamReader(loop=self.loop)
- read_task = tasks.Task(stream.read(1024), loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
+ read_task = asyncio.Task(stream.read(1024), loop=self.loop)
def cb():
stream.feed_eof()
@@ -137,8 +135,8 @@ class StreamReaderTests(unittest.TestCase):
def test_read_until_eof(self):
# Read all bytes until eof.
- stream = streams.StreamReader(loop=self.loop)
- read_task = tasks.Task(stream.read(-1), loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
+ read_task = asyncio.Task(stream.read(-1), loop=self.loop)
def cb():
stream.feed_data(b'chunk1\n')
@@ -152,7 +150,7 @@ class StreamReaderTests(unittest.TestCase):
self.assertFalse(stream._byte_count)
def test_read_exception(self):
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
stream.feed_data(b'line\n')
data = self.loop.run_until_complete(stream.read(2))
@@ -164,9 +162,9 @@ class StreamReaderTests(unittest.TestCase):
def test_readline(self):
# Read one line.
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
stream.feed_data(b'chunk1 ')
- read_task = tasks.Task(stream.readline(), loop=self.loop)
+ read_task = asyncio.Task(stream.readline(), loop=self.loop)
def cb():
stream.feed_data(b'chunk2 ')
@@ -179,7 +177,7 @@ class StreamReaderTests(unittest.TestCase):
self.assertEqual(len(b'\n chunk4')-1, stream._byte_count)
def test_readline_limit_with_existing_data(self):
- stream = streams.StreamReader(3, loop=self.loop)
+ stream = asyncio.StreamReader(3, loop=self.loop)
stream.feed_data(b'li')
stream.feed_data(b'ne1\nline2\n')
@@ -187,7 +185,7 @@ class StreamReaderTests(unittest.TestCase):
ValueError, self.loop.run_until_complete, stream.readline())
self.assertEqual([b'line2\n'], list(stream._buffer))
- stream = streams.StreamReader(3, loop=self.loop)
+ stream = asyncio.StreamReader(3, loop=self.loop)
stream.feed_data(b'li')
stream.feed_data(b'ne1')
stream.feed_data(b'li')
@@ -198,7 +196,7 @@ class StreamReaderTests(unittest.TestCase):
self.assertEqual(2, stream._byte_count)
def test_readline_limit(self):
- stream = streams.StreamReader(7, loop=self.loop)
+ stream = asyncio.StreamReader(7, loop=self.loop)
def cb():
stream.feed_data(b'chunk1')
@@ -213,7 +211,7 @@ class StreamReaderTests(unittest.TestCase):
self.assertEqual(7, stream._byte_count)
def test_readline_line_byte_count(self):
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
stream.feed_data(self.DATA[:6])
stream.feed_data(self.DATA[6:])
@@ -223,7 +221,7 @@ class StreamReaderTests(unittest.TestCase):
self.assertEqual(len(self.DATA) - len(b'line1\n'), stream._byte_count)
def test_readline_eof(self):
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
stream.feed_data(b'some data')
stream.feed_eof()
@@ -231,14 +229,14 @@ class StreamReaderTests(unittest.TestCase):
self.assertEqual(b'some data', line)
def test_readline_empty_eof(self):
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
stream.feed_eof()
line = self.loop.run_until_complete(stream.readline())
self.assertEqual(b'', line)
def test_readline_read_byte_count(self):
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
stream.feed_data(self.DATA)
self.loop.run_until_complete(stream.readline())
@@ -251,7 +249,7 @@ class StreamReaderTests(unittest.TestCase):
stream._byte_count)
def test_readline_exception(self):
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
stream.feed_data(b'line\n')
data = self.loop.run_until_complete(stream.readline())
@@ -263,7 +261,7 @@ class StreamReaderTests(unittest.TestCase):
def test_readexactly_zero_or_less(self):
# Read exact number of bytes (zero or less).
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
stream.feed_data(self.DATA)
data = self.loop.run_until_complete(stream.readexactly(0))
@@ -276,10 +274,10 @@ class StreamReaderTests(unittest.TestCase):
def test_readexactly(self):
# Read exact number of bytes.
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
n = 2 * len(self.DATA)
- read_task = tasks.Task(stream.readexactly(n), loop=self.loop)
+ read_task = asyncio.Task(stream.readexactly(n), loop=self.loop)
def cb():
stream.feed_data(self.DATA)
@@ -293,21 +291,25 @@ class StreamReaderTests(unittest.TestCase):
def test_readexactly_eof(self):
# Read exact number of bytes (eof).
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
n = 2 * len(self.DATA)
- read_task = tasks.Task(stream.readexactly(n), loop=self.loop)
+ read_task = asyncio.Task(stream.readexactly(n), loop=self.loop)
def cb():
stream.feed_data(self.DATA)
stream.feed_eof()
self.loop.call_soon(cb)
- data = self.loop.run_until_complete(read_task)
- self.assertEqual(self.DATA, data)
+ with self.assertRaises(asyncio.IncompleteReadError) as cm:
+ self.loop.run_until_complete(read_task)
+ self.assertEqual(cm.exception.partial, self.DATA)
+ self.assertEqual(cm.exception.expected, n)
+ self.assertEqual(str(cm.exception),
+ '18 bytes read on a total of 36 expected bytes')
self.assertFalse(stream._byte_count)
def test_readexactly_exception(self):
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
stream.feed_data(b'line\n')
data = self.loop.run_until_complete(stream.readexactly(2))
@@ -318,7 +320,7 @@ class StreamReaderTests(unittest.TestCase):
ValueError, self.loop.run_until_complete, stream.readexactly(2))
def test_exception(self):
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
self.assertIsNone(stream.exception())
exc = ValueError()
@@ -326,31 +328,31 @@ class StreamReaderTests(unittest.TestCase):
self.assertIs(stream.exception(), exc)
def test_exception_waiter(self):
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def set_err():
stream.set_exception(ValueError())
- @tasks.coroutine
+ @asyncio.coroutine
def readline():
yield from stream.readline()
- t1 = tasks.Task(stream.readline(), loop=self.loop)
- t2 = tasks.Task(set_err(), loop=self.loop)
+ t1 = asyncio.Task(stream.readline(), loop=self.loop)
+ t2 = asyncio.Task(set_err(), loop=self.loop)
- self.loop.run_until_complete(tasks.wait([t1, t2], loop=self.loop))
+ self.loop.run_until_complete(asyncio.wait([t1, t2], loop=self.loop))
self.assertRaises(ValueError, t1.result)
def test_exception_cancel(self):
- stream = streams.StreamReader(loop=self.loop)
+ stream = asyncio.StreamReader(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def read_a_line():
yield from stream.readline()
- t = tasks.Task(read_a_line(), loop=self.loop)
+ t = asyncio.Task(read_a_line(), loop=self.loop)
test_utils.run_briefly(self.loop)
t.cancel()
test_utils.run_briefly(self.loop)
@@ -367,19 +369,19 @@ class StreamReaderTests(unittest.TestCase):
self.server = None
self.loop = loop
- @tasks.coroutine
+ @asyncio.coroutine
def handle_client(self, client_reader, client_writer):
data = yield from client_reader.readline()
client_writer.write(data)
def start(self):
self.server = self.loop.run_until_complete(
- streams.start_server(self.handle_client,
+ asyncio.start_server(self.handle_client,
'127.0.0.1', 12345,
loop=self.loop))
def handle_client_callback(self, client_reader, client_writer):
- task = tasks.Task(client_reader.readline(), loop=self.loop)
+ task = asyncio.Task(client_reader.readline(), loop=self.loop)
def done(task):
client_writer.write(task.result())
@@ -388,7 +390,7 @@ class StreamReaderTests(unittest.TestCase):
def start_callback(self):
self.server = self.loop.run_until_complete(
- streams.start_server(self.handle_client_callback,
+ asyncio.start_server(self.handle_client_callback,
'127.0.0.1', 12345,
loop=self.loop))
@@ -398,9 +400,9 @@ class StreamReaderTests(unittest.TestCase):
self.loop.run_until_complete(self.server.wait_closed())
self.server = None
- @tasks.coroutine
+ @asyncio.coroutine
def client():
- reader, writer = yield from streams.open_connection(
+ reader, writer = yield from asyncio.open_connection(
'127.0.0.1', 12345, loop=self.loop)
# send a line
writer.write(b"hello world!\n")
@@ -412,7 +414,7 @@ class StreamReaderTests(unittest.TestCase):
# test the server variant with a coroutine as client handler
server = MyServer(self.loop)
server.start()
- msg = self.loop.run_until_complete(tasks.Task(client(),
+ msg = self.loop.run_until_complete(asyncio.Task(client(),
loop=self.loop))
server.stop()
self.assertEqual(msg, b"hello world!\n")
@@ -420,7 +422,7 @@ class StreamReaderTests(unittest.TestCase):
# test the server variant with a callback as client handler
server = MyServer(self.loop)
server.start_callback()
- msg = self.loop.run_until_complete(tasks.Task(client(),
+ msg = self.loop.run_until_complete(asyncio.Task(client(),
loop=self.loop))
server.stop()
self.assertEqual(msg, b"hello world!\n")
diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py
index 79a25d298f..dbf130c1dd 100644
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -5,9 +5,7 @@ import unittest
import unittest.mock
from unittest.mock import Mock
-from asyncio import events
-from asyncio import futures
-from asyncio import tasks
+import asyncio
from asyncio import test_utils
@@ -24,115 +22,115 @@ class TaskTests(unittest.TestCase):
def setUp(self):
self.loop = test_utils.TestLoop()
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
def tearDown(self):
self.loop.close()
gc.collect()
def test_task_class(self):
- @tasks.coroutine
+ @asyncio.coroutine
def notmuch():
return 'ok'
- t = tasks.Task(notmuch(), loop=self.loop)
+ t = asyncio.Task(notmuch(), loop=self.loop)
self.loop.run_until_complete(t)
self.assertTrue(t.done())
self.assertEqual(t.result(), 'ok')
self.assertIs(t._loop, self.loop)
- loop = events.new_event_loop()
- t = tasks.Task(notmuch(), loop=loop)
+ loop = asyncio.new_event_loop()
+ t = asyncio.Task(notmuch(), loop=loop)
self.assertIs(t._loop, loop)
loop.close()
def test_async_coroutine(self):
- @tasks.coroutine
+ @asyncio.coroutine
def notmuch():
return 'ok'
- t = tasks.async(notmuch(), loop=self.loop)
+ t = asyncio.async(notmuch(), loop=self.loop)
self.loop.run_until_complete(t)
self.assertTrue(t.done())
self.assertEqual(t.result(), 'ok')
self.assertIs(t._loop, self.loop)
- loop = events.new_event_loop()
- t = tasks.async(notmuch(), loop=loop)
+ loop = asyncio.new_event_loop()
+ t = asyncio.async(notmuch(), loop=loop)
self.assertIs(t._loop, loop)
loop.close()
def test_async_future(self):
- f_orig = futures.Future(loop=self.loop)
+ f_orig = asyncio.Future(loop=self.loop)
f_orig.set_result('ko')
- f = tasks.async(f_orig)
+ f = asyncio.async(f_orig)
self.loop.run_until_complete(f)
self.assertTrue(f.done())
self.assertEqual(f.result(), 'ko')
self.assertIs(f, f_orig)
- loop = events.new_event_loop()
+ loop = asyncio.new_event_loop()
with self.assertRaises(ValueError):
- f = tasks.async(f_orig, loop=loop)
+ f = asyncio.async(f_orig, loop=loop)
loop.close()
- f = tasks.async(f_orig, loop=self.loop)
+ f = asyncio.async(f_orig, loop=self.loop)
self.assertIs(f, f_orig)
def test_async_task(self):
- @tasks.coroutine
+ @asyncio.coroutine
def notmuch():
return 'ok'
- t_orig = tasks.Task(notmuch(), loop=self.loop)
- t = tasks.async(t_orig)
+ t_orig = asyncio.Task(notmuch(), loop=self.loop)
+ t = asyncio.async(t_orig)
self.loop.run_until_complete(t)
self.assertTrue(t.done())
self.assertEqual(t.result(), 'ok')
self.assertIs(t, t_orig)
- loop = events.new_event_loop()
+ loop = asyncio.new_event_loop()
with self.assertRaises(ValueError):
- t = tasks.async(t_orig, loop=loop)
+ t = asyncio.async(t_orig, loop=loop)
loop.close()
- t = tasks.async(t_orig, loop=self.loop)
+ t = asyncio.async(t_orig, loop=self.loop)
self.assertIs(t, t_orig)
def test_async_neither(self):
with self.assertRaises(TypeError):
- tasks.async('ok')
+ asyncio.async('ok')
def test_task_repr(self):
- @tasks.coroutine
+ @asyncio.coroutine
def notmuch():
yield from []
return 'abc'
- t = tasks.Task(notmuch(), loop=self.loop)
+ t = asyncio.Task(notmuch(), loop=self.loop)
t.add_done_callback(Dummy())
self.assertEqual(repr(t), 'Task(<notmuch>)<PENDING, [Dummy()]>')
t.cancel() # Does not take immediate effect!
self.assertEqual(repr(t), 'Task(<notmuch>)<CANCELLING, [Dummy()]>')
- self.assertRaises(futures.CancelledError,
+ self.assertRaises(asyncio.CancelledError,
self.loop.run_until_complete, t)
self.assertEqual(repr(t), 'Task(<notmuch>)<CANCELLED>')
- t = tasks.Task(notmuch(), loop=self.loop)
+ t = asyncio.Task(notmuch(), loop=self.loop)
self.loop.run_until_complete(t)
self.assertEqual(repr(t), "Task(<notmuch>)<result='abc'>")
def test_task_repr_custom(self):
- @tasks.coroutine
+ @asyncio.coroutine
def coro():
pass
- class T(futures.Future):
+ class T(asyncio.Future):
def __repr__(self):
return 'T[]'
- class MyTask(tasks.Task, T):
+ class MyTask(asyncio.Task, T):
def __repr__(self):
return super().__repr__()
@@ -142,17 +140,17 @@ class TaskTests(unittest.TestCase):
gen.close()
def test_task_basics(self):
- @tasks.coroutine
+ @asyncio.coroutine
def outer():
a = yield from inner1()
b = yield from inner2()
return a+b
- @tasks.coroutine
+ @asyncio.coroutine
def inner1():
return 42
- @tasks.coroutine
+ @asyncio.coroutine
def inner2():
return 1000
@@ -169,66 +167,66 @@ class TaskTests(unittest.TestCase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- @tasks.coroutine
+ @asyncio.coroutine
def task():
- yield from tasks.sleep(10.0, loop=loop)
+ yield from asyncio.sleep(10.0, loop=loop)
return 12
- t = tasks.Task(task(), loop=loop)
+ t = asyncio.Task(task(), loop=loop)
loop.call_soon(t.cancel)
- with self.assertRaises(futures.CancelledError):
+ with self.assertRaises(asyncio.CancelledError):
loop.run_until_complete(t)
self.assertTrue(t.done())
self.assertTrue(t.cancelled())
self.assertFalse(t.cancel())
def test_cancel_yield(self):
- @tasks.coroutine
+ @asyncio.coroutine
def task():
yield
yield
return 12
- t = tasks.Task(task(), loop=self.loop)
+ t = asyncio.Task(task(), loop=self.loop)
test_utils.run_briefly(self.loop) # start coro
t.cancel()
self.assertRaises(
- futures.CancelledError, self.loop.run_until_complete, t)
+ asyncio.CancelledError, self.loop.run_until_complete, t)
self.assertTrue(t.done())
self.assertTrue(t.cancelled())
self.assertFalse(t.cancel())
def test_cancel_inner_future(self):
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def task():
yield from f
return 12
- t = tasks.Task(task(), loop=self.loop)
+ t = asyncio.Task(task(), loop=self.loop)
test_utils.run_briefly(self.loop) # start task
f.cancel()
- with self.assertRaises(futures.CancelledError):
+ with self.assertRaises(asyncio.CancelledError):
self.loop.run_until_complete(t)
self.assertTrue(f.cancelled())
self.assertTrue(t.cancelled())
def test_cancel_both_task_and_inner_future(self):
- f = futures.Future(loop=self.loop)
+ f = asyncio.Future(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def task():
yield from f
return 12
- t = tasks.Task(task(), loop=self.loop)
+ t = asyncio.Task(task(), loop=self.loop)
test_utils.run_briefly(self.loop)
f.cancel()
t.cancel()
- with self.assertRaises(futures.CancelledError):
+ with self.assertRaises(asyncio.CancelledError):
self.loop.run_until_complete(t)
self.assertTrue(t.done())
@@ -236,18 +234,18 @@ class TaskTests(unittest.TestCase):
self.assertTrue(t.cancelled())
def test_cancel_task_catching(self):
- fut1 = futures.Future(loop=self.loop)
- fut2 = futures.Future(loop=self.loop)
+ fut1 = asyncio.Future(loop=self.loop)
+ fut2 = asyncio.Future(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def task():
yield from fut1
try:
yield from fut2
- except futures.CancelledError:
+ except asyncio.CancelledError:
return 42
- t = tasks.Task(task(), loop=self.loop)
+ t = asyncio.Task(task(), loop=self.loop)
test_utils.run_briefly(self.loop)
self.assertIs(t._fut_waiter, fut1) # White-box test.
fut1.set_result(None)
@@ -260,21 +258,21 @@ class TaskTests(unittest.TestCase):
self.assertFalse(t.cancelled())
def test_cancel_task_ignoring(self):
- fut1 = futures.Future(loop=self.loop)
- fut2 = futures.Future(loop=self.loop)
- fut3 = futures.Future(loop=self.loop)
+ fut1 = asyncio.Future(loop=self.loop)
+ fut2 = asyncio.Future(loop=self.loop)
+ fut3 = asyncio.Future(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def task():
yield from fut1
try:
yield from fut2
- except futures.CancelledError:
+ except asyncio.CancelledError:
pass
res = yield from fut3
return res
- t = tasks.Task(task(), loop=self.loop)
+ t = asyncio.Task(task(), loop=self.loop)
test_utils.run_briefly(self.loop)
self.assertIs(t._fut_waiter, fut1) # White-box test.
fut1.set_result(None)
@@ -291,20 +289,20 @@ class TaskTests(unittest.TestCase):
self.assertFalse(t.cancelled())
def test_cancel_current_task(self):
- loop = events.new_event_loop()
+ loop = asyncio.new_event_loop()
self.addCleanup(loop.close)
- @tasks.coroutine
+ @asyncio.coroutine
def task():
t.cancel()
self.assertTrue(t._must_cancel) # White-box test.
# The sleep should be cancelled immediately.
- yield from tasks.sleep(100, loop=loop)
+ yield from asyncio.sleep(100, loop=loop)
return 12
- t = tasks.Task(task(), loop=loop)
+ t = asyncio.Task(task(), loop=loop)
self.assertRaises(
- futures.CancelledError, loop.run_until_complete, t)
+ asyncio.CancelledError, loop.run_until_complete, t)
self.assertTrue(t.done())
self.assertFalse(t._must_cancel) # White-box test.
self.assertFalse(t.cancel())
@@ -326,17 +324,17 @@ class TaskTests(unittest.TestCase):
x = 0
waiters = []
- @tasks.coroutine
+ @asyncio.coroutine
def task():
nonlocal x
while x < 10:
- waiters.append(tasks.sleep(0.1, loop=loop))
+ waiters.append(asyncio.sleep(0.1, loop=loop))
yield from waiters[-1]
x += 1
if x == 2:
loop.stop()
- t = tasks.Task(task(), loop=loop)
+ t = asyncio.Task(task(), loop=loop)
self.assertRaises(
RuntimeError, loop.run_until_complete, t)
self.assertFalse(t.done())
@@ -355,30 +353,32 @@ class TaskTests(unittest.TestCase):
when = yield 0
self.assertAlmostEqual(0.1, when)
when = yield 0.1
- self.assertAlmostEqual(0.4, when)
- yield 0.1
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- @tasks.coroutine
+ foo_running = None
+
+ @asyncio.coroutine
def foo():
- yield from tasks.sleep(0.2, loop=loop)
+ nonlocal foo_running
+ foo_running = True
+ try:
+ yield from asyncio.sleep(0.2, loop=loop)
+ finally:
+ foo_running = False
return 'done'
- fut = tasks.Task(foo(), loop=loop)
+ fut = asyncio.Task(foo(), loop=loop)
- with self.assertRaises(futures.TimeoutError):
- loop.run_until_complete(tasks.wait_for(fut, 0.1, loop=loop))
-
- self.assertFalse(fut.done())
+ with self.assertRaises(asyncio.TimeoutError):
+ loop.run_until_complete(asyncio.wait_for(fut, 0.1, loop=loop))
+ self.assertTrue(fut.done())
+ # it should have been cancelled due to the timeout
+ self.assertTrue(fut.cancelled())
self.assertAlmostEqual(0.1, loop.time())
+ self.assertEqual(foo_running, False)
- # wait for result
- res = loop.run_until_complete(
- tasks.wait_for(fut, 0.3, loop=loop))
- self.assertEqual(res, 'done')
- self.assertAlmostEqual(0.2, loop.time())
def test_wait_for_with_global_loop(self):
@@ -392,25 +392,22 @@ class TaskTests(unittest.TestCase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- @tasks.coroutine
+ @asyncio.coroutine
def foo():
- yield from tasks.sleep(0.2, loop=loop)
+ yield from asyncio.sleep(0.2, loop=loop)
return 'done'
- events.set_event_loop(loop)
+ asyncio.set_event_loop(loop)
try:
- fut = tasks.Task(foo(), loop=loop)
- with self.assertRaises(futures.TimeoutError):
- loop.run_until_complete(tasks.wait_for(fut, 0.01))
+ fut = asyncio.Task(foo(), loop=loop)
+ with self.assertRaises(asyncio.TimeoutError):
+ loop.run_until_complete(asyncio.wait_for(fut, 0.01))
finally:
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
self.assertAlmostEqual(0.01, loop.time())
- self.assertFalse(fut.done())
-
- # move forward to close generator
- loop.advance_time(10)
- loop.run_until_complete(fut)
+ self.assertTrue(fut.done())
+ self.assertTrue(fut.cancelled())
def test_wait(self):
@@ -424,22 +421,22 @@ class TaskTests(unittest.TestCase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- a = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop)
- b = tasks.Task(tasks.sleep(0.15, loop=loop), loop=loop)
+ a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
+ b = asyncio.Task(asyncio.sleep(0.15, loop=loop), loop=loop)
- @tasks.coroutine
+ @asyncio.coroutine
def foo():
- done, pending = yield from tasks.wait([b, a], loop=loop)
+ done, pending = yield from asyncio.wait([b, a], loop=loop)
self.assertEqual(done, set([a, b]))
self.assertEqual(pending, set())
return 42
- res = loop.run_until_complete(tasks.Task(foo(), loop=loop))
+ res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
self.assertEqual(res, 42)
self.assertAlmostEqual(0.15, loop.time())
# Doing it again should take no time and exercise a different path.
- res = loop.run_until_complete(tasks.Task(foo(), loop=loop))
+ res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
self.assertAlmostEqual(0.15, loop.time())
self.assertEqual(res, 42)
@@ -455,33 +452,33 @@ class TaskTests(unittest.TestCase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- a = tasks.Task(tasks.sleep(0.01, loop=loop), loop=loop)
- b = tasks.Task(tasks.sleep(0.015, loop=loop), loop=loop)
+ a = asyncio.Task(asyncio.sleep(0.01, loop=loop), loop=loop)
+ b = asyncio.Task(asyncio.sleep(0.015, loop=loop), loop=loop)
- @tasks.coroutine
+ @asyncio.coroutine
def foo():
- done, pending = yield from tasks.wait([b, a])
+ done, pending = yield from asyncio.wait([b, a])
self.assertEqual(done, set([a, b]))
self.assertEqual(pending, set())
return 42
- events.set_event_loop(loop)
+ asyncio.set_event_loop(loop)
try:
res = loop.run_until_complete(
- tasks.Task(foo(), loop=loop))
+ asyncio.Task(foo(), loop=loop))
finally:
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
self.assertEqual(res, 42)
def test_wait_errors(self):
self.assertRaises(
ValueError, self.loop.run_until_complete,
- tasks.wait(set(), loop=self.loop))
+ asyncio.wait(set(), loop=self.loop))
self.assertRaises(
ValueError, self.loop.run_until_complete,
- tasks.wait([tasks.sleep(10.0, loop=self.loop)],
+ asyncio.wait([asyncio.sleep(10.0, loop=self.loop)],
return_when=-1, loop=self.loop))
def test_wait_first_completed(self):
@@ -496,10 +493,10 @@ class TaskTests(unittest.TestCase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- a = tasks.Task(tasks.sleep(10.0, loop=loop), loop=loop)
- b = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop)
- task = tasks.Task(
- tasks.wait([b, a], return_when=tasks.FIRST_COMPLETED,
+ a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop)
+ b = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
+ task = asyncio.Task(
+ asyncio.wait([b, a], return_when=asyncio.FIRST_COMPLETED,
loop=loop),
loop=loop)
@@ -513,25 +510,25 @@ class TaskTests(unittest.TestCase):
# move forward to close generator
loop.advance_time(10)
- loop.run_until_complete(tasks.wait([a, b], loop=loop))
+ loop.run_until_complete(asyncio.wait([a, b], loop=loop))
def test_wait_really_done(self):
# there is possibility that some tasks in the pending list
# became done but their callbacks haven't all been called yet
- @tasks.coroutine
+ @asyncio.coroutine
def coro1():
yield
- @tasks.coroutine
+ @asyncio.coroutine
def coro2():
yield
yield
- a = tasks.Task(coro1(), loop=self.loop)
- b = tasks.Task(coro2(), loop=self.loop)
- task = tasks.Task(
- tasks.wait([b, a], return_when=tasks.FIRST_COMPLETED,
+ a = asyncio.Task(coro1(), loop=self.loop)
+ b = asyncio.Task(coro2(), loop=self.loop)
+ task = asyncio.Task(
+ asyncio.wait([b, a], return_when=asyncio.FIRST_COMPLETED,
loop=self.loop),
loop=self.loop)
@@ -553,15 +550,15 @@ class TaskTests(unittest.TestCase):
self.addCleanup(loop.close)
# first_exception, task already has exception
- a = tasks.Task(tasks.sleep(10.0, loop=loop), loop=loop)
+ a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop)
- @tasks.coroutine
+ @asyncio.coroutine
def exc():
raise ZeroDivisionError('err')
- b = tasks.Task(exc(), loop=loop)
- task = tasks.Task(
- tasks.wait([b, a], return_when=tasks.FIRST_EXCEPTION,
+ b = asyncio.Task(exc(), loop=loop)
+ task = asyncio.Task(
+ asyncio.wait([b, a], return_when=asyncio.FIRST_EXCEPTION,
loop=loop),
loop=loop)
@@ -572,7 +569,7 @@ class TaskTests(unittest.TestCase):
# move forward to close generator
loop.advance_time(10)
- loop.run_until_complete(tasks.wait([a, b], loop=loop))
+ loop.run_until_complete(asyncio.wait([a, b], loop=loop))
def test_wait_first_exception_in_wait(self):
@@ -587,15 +584,15 @@ class TaskTests(unittest.TestCase):
self.addCleanup(loop.close)
# first_exception, exception during waiting
- a = tasks.Task(tasks.sleep(10.0, loop=loop), loop=loop)
+ a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop)
- @tasks.coroutine
+ @asyncio.coroutine
def exc():
- yield from tasks.sleep(0.01, loop=loop)
+ yield from asyncio.sleep(0.01, loop=loop)
raise ZeroDivisionError('err')
- b = tasks.Task(exc(), loop=loop)
- task = tasks.wait([b, a], return_when=tasks.FIRST_EXCEPTION,
+ b = asyncio.Task(exc(), loop=loop)
+ task = asyncio.wait([b, a], return_when=asyncio.FIRST_EXCEPTION,
loop=loop)
done, pending = loop.run_until_complete(task)
@@ -605,7 +602,7 @@ class TaskTests(unittest.TestCase):
# move forward to close generator
loop.advance_time(10)
- loop.run_until_complete(tasks.wait([a, b], loop=loop))
+ loop.run_until_complete(asyncio.wait([a, b], loop=loop))
def test_wait_with_exception(self):
@@ -619,27 +616,27 @@ class TaskTests(unittest.TestCase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- a = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop)
+ a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
- @tasks.coroutine
+ @asyncio.coroutine
def sleeper():
- yield from tasks.sleep(0.15, loop=loop)
+ yield from asyncio.sleep(0.15, loop=loop)
raise ZeroDivisionError('really')
- b = tasks.Task(sleeper(), loop=loop)
+ b = asyncio.Task(sleeper(), loop=loop)
- @tasks.coroutine
+ @asyncio.coroutine
def foo():
- done, pending = yield from tasks.wait([b, a], loop=loop)
+ done, pending = yield from asyncio.wait([b, a], loop=loop)
self.assertEqual(len(done), 2)
self.assertEqual(pending, set())
errors = set(f for f in done if f.exception() is not None)
self.assertEqual(len(errors), 1)
- loop.run_until_complete(tasks.Task(foo(), loop=loop))
+ loop.run_until_complete(asyncio.Task(foo(), loop=loop))
self.assertAlmostEqual(0.15, loop.time())
- loop.run_until_complete(tasks.Task(foo(), loop=loop))
+ loop.run_until_complete(asyncio.Task(foo(), loop=loop))
self.assertAlmostEqual(0.15, loop.time())
def test_wait_with_timeout(self):
@@ -656,22 +653,22 @@ class TaskTests(unittest.TestCase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- a = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop)
- b = tasks.Task(tasks.sleep(0.15, loop=loop), loop=loop)
+ a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
+ b = asyncio.Task(asyncio.sleep(0.15, loop=loop), loop=loop)
- @tasks.coroutine
+ @asyncio.coroutine
def foo():
- done, pending = yield from tasks.wait([b, a], timeout=0.11,
+ done, pending = yield from asyncio.wait([b, a], timeout=0.11,
loop=loop)
self.assertEqual(done, set([a]))
self.assertEqual(pending, set([b]))
- loop.run_until_complete(tasks.Task(foo(), loop=loop))
+ loop.run_until_complete(asyncio.Task(foo(), loop=loop))
self.assertAlmostEqual(0.11, loop.time())
# move forward to close generator
loop.advance_time(10)
- loop.run_until_complete(tasks.wait([a, b], loop=loop))
+ loop.run_until_complete(asyncio.wait([a, b], loop=loop))
def test_wait_concurrent_complete(self):
@@ -687,11 +684,11 @@ class TaskTests(unittest.TestCase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- a = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop)
- b = tasks.Task(tasks.sleep(0.15, loop=loop), loop=loop)
+ a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
+ b = asyncio.Task(asyncio.sleep(0.15, loop=loop), loop=loop)
done, pending = loop.run_until_complete(
- tasks.wait([b, a], timeout=0.1, loop=loop))
+ asyncio.wait([b, a], timeout=0.1, loop=loop))
self.assertEqual(done, set([a]))
self.assertEqual(pending, set([b]))
@@ -699,7 +696,7 @@ class TaskTests(unittest.TestCase):
# move forward to close generator
loop.advance_time(10)
- loop.run_until_complete(tasks.wait([a, b], loop=loop))
+ loop.run_until_complete(asyncio.wait([a, b], loop=loop))
def test_as_completed(self):
@@ -714,10 +711,10 @@ class TaskTests(unittest.TestCase):
completed = set()
time_shifted = False
- @tasks.coroutine
+ @asyncio.coroutine
def sleeper(dt, x):
nonlocal time_shifted
- yield from tasks.sleep(dt, loop=loop)
+ yield from asyncio.sleep(dt, loop=loop)
completed.add(x)
if not time_shifted and 'a' in completed and 'b' in completed:
time_shifted = True
@@ -728,21 +725,21 @@ class TaskTests(unittest.TestCase):
b = sleeper(0.01, 'b')
c = sleeper(0.15, 'c')
- @tasks.coroutine
+ @asyncio.coroutine
def foo():
values = []
- for f in tasks.as_completed([b, c, a], loop=loop):
+ for f in asyncio.as_completed([b, c, a], loop=loop):
values.append((yield from f))
return values
- res = loop.run_until_complete(tasks.Task(foo(), loop=loop))
+ res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
self.assertAlmostEqual(0.15, loop.time())
self.assertTrue('a' in res[:2])
self.assertTrue('b' in res[:2])
self.assertEqual(res[2], 'c')
# Doing it again should take no time and exercise a different path.
- res = loop.run_until_complete(tasks.Task(foo(), loop=loop))
+ res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
self.assertAlmostEqual(0.15, loop.time())
def test_as_completed_with_timeout(self):
@@ -761,30 +758,30 @@ class TaskTests(unittest.TestCase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- a = tasks.sleep(0.1, 'a', loop=loop)
- b = tasks.sleep(0.15, 'b', loop=loop)
+ a = asyncio.sleep(0.1, 'a', loop=loop)
+ b = asyncio.sleep(0.15, 'b', loop=loop)
- @tasks.coroutine
+ @asyncio.coroutine
def foo():
values = []
- for f in tasks.as_completed([a, b], timeout=0.12, loop=loop):
+ for f in asyncio.as_completed([a, b], timeout=0.12, loop=loop):
try:
v = yield from f
values.append((1, v))
- except futures.TimeoutError as exc:
+ except asyncio.TimeoutError as exc:
values.append((2, exc))
return values
- res = loop.run_until_complete(tasks.Task(foo(), loop=loop))
+ res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
self.assertEqual(len(res), 2, res)
self.assertEqual(res[0], (1, 'a'))
self.assertEqual(res[1][0], 2)
- self.assertIsInstance(res[1][1], futures.TimeoutError)
+ self.assertIsInstance(res[1][1], asyncio.TimeoutError)
self.assertAlmostEqual(0.12, loop.time())
# move forward to close generator
loop.advance_time(10)
- loop.run_until_complete(tasks.wait([a, b], loop=loop))
+ loop.run_until_complete(asyncio.wait([a, b], loop=loop))
def test_as_completed_reverse_wait(self):
@@ -796,10 +793,10 @@ class TaskTests(unittest.TestCase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- a = tasks.sleep(0.05, 'a', loop=loop)
- b = tasks.sleep(0.10, 'b', loop=loop)
+ a = asyncio.sleep(0.05, 'a', loop=loop)
+ b = asyncio.sleep(0.10, 'b', loop=loop)
fs = {a, b}
- futs = list(tasks.as_completed(fs, loop=loop))
+ futs = list(asyncio.as_completed(fs, loop=loop))
self.assertEqual(len(futs), 2)
x = loop.run_until_complete(futs[1])
@@ -822,12 +819,12 @@ class TaskTests(unittest.TestCase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- a = tasks.sleep(0.05, 'a', loop=loop)
- b = tasks.sleep(0.05, 'b', loop=loop)
+ a = asyncio.sleep(0.05, 'a', loop=loop)
+ b = asyncio.sleep(0.05, 'b', loop=loop)
fs = {a, b}
- futs = list(tasks.as_completed(fs, loop=loop))
+ futs = list(asyncio.as_completed(fs, loop=loop))
self.assertEqual(len(futs), 2)
- waiter = tasks.wait(futs, loop=loop)
+ waiter = asyncio.wait(futs, loop=loop)
done, pending = loop.run_until_complete(waiter)
self.assertEqual(set(f.result() for f in done), {'a', 'b'})
@@ -843,13 +840,13 @@ class TaskTests(unittest.TestCase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- @tasks.coroutine
+ @asyncio.coroutine
def sleeper(dt, arg):
- yield from tasks.sleep(dt/2, loop=loop)
- res = yield from tasks.sleep(dt/2, arg, loop=loop)
+ yield from asyncio.sleep(dt/2, loop=loop)
+ res = yield from asyncio.sleep(dt/2, arg, loop=loop)
return res
- t = tasks.Task(sleeper(0.1, 'yeah'), loop=loop)
+ t = asyncio.Task(sleeper(0.1, 'yeah'), loop=loop)
loop.run_until_complete(t)
self.assertTrue(t.done())
self.assertEqual(t.result(), 'yeah')
@@ -865,7 +862,7 @@ class TaskTests(unittest.TestCase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- t = tasks.Task(tasks.sleep(10.0, 'yeah', loop=loop),
+ t = asyncio.Task(asyncio.sleep(10.0, 'yeah', loop=loop),
loop=loop)
handle = None
@@ -899,19 +896,19 @@ class TaskTests(unittest.TestCase):
sleepfut = None
- @tasks.coroutine
+ @asyncio.coroutine
def sleep(dt):
nonlocal sleepfut
- sleepfut = tasks.sleep(dt, loop=loop)
+ sleepfut = asyncio.sleep(dt, loop=loop)
yield from sleepfut
- @tasks.coroutine
+ @asyncio.coroutine
def doit():
- sleeper = tasks.Task(sleep(5000), loop=loop)
+ sleeper = asyncio.Task(sleep(5000), loop=loop)
loop.call_later(0.1, sleeper.cancel)
try:
yield from sleeper
- except futures.CancelledError:
+ except asyncio.CancelledError:
return 'cancelled'
else:
return 'slept in'
@@ -921,37 +918,37 @@ class TaskTests(unittest.TestCase):
self.assertAlmostEqual(0.1, loop.time())
def test_task_cancel_waiter_future(self):
- fut = futures.Future(loop=self.loop)
+ fut = asyncio.Future(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def coro():
yield from fut
- task = tasks.Task(coro(), loop=self.loop)
+ task = asyncio.Task(coro(), loop=self.loop)
test_utils.run_briefly(self.loop)
self.assertIs(task._fut_waiter, fut)
task.cancel()
test_utils.run_briefly(self.loop)
self.assertRaises(
- futures.CancelledError, self.loop.run_until_complete, task)
+ asyncio.CancelledError, self.loop.run_until_complete, task)
self.assertIsNone(task._fut_waiter)
self.assertTrue(fut.cancelled())
def test_step_in_completed_task(self):
- @tasks.coroutine
+ @asyncio.coroutine
def notmuch():
return 'ko'
gen = notmuch()
- task = tasks.Task(gen, loop=self.loop)
+ task = asyncio.Task(gen, loop=self.loop)
task.set_result('ok')
self.assertRaises(AssertionError, task._step)
gen.close()
def test_step_result(self):
- @tasks.coroutine
+ @asyncio.coroutine
def notmuch():
yield None
yield 1
@@ -963,7 +960,7 @@ class TaskTests(unittest.TestCase):
def test_step_result_future(self):
# If coroutine returns future, task waits on this future.
- class Fut(futures.Future):
+ class Fut(asyncio.Future):
def __init__(self, *args, **kwds):
self.cb_added = False
super().__init__(*args, **kwds)
@@ -975,12 +972,12 @@ class TaskTests(unittest.TestCase):
fut = Fut(loop=self.loop)
result = None
- @tasks.coroutine
+ @asyncio.coroutine
def wait_for_future():
nonlocal result
result = yield from fut
- t = tasks.Task(wait_for_future(), loop=self.loop)
+ t = asyncio.Task(wait_for_future(), loop=self.loop)
test_utils.run_briefly(self.loop)
self.assertTrue(fut.cb_added)
@@ -992,11 +989,11 @@ class TaskTests(unittest.TestCase):
self.assertIsNone(t.result())
def test_step_with_baseexception(self):
- @tasks.coroutine
+ @asyncio.coroutine
def notmutch():
raise BaseException()
- task = tasks.Task(notmutch(), loop=self.loop)
+ task = asyncio.Task(notmutch(), loop=self.loop)
self.assertRaises(BaseException, task._step)
self.assertTrue(task.done())
@@ -1012,20 +1009,20 @@ class TaskTests(unittest.TestCase):
loop = test_utils.TestLoop(gen)
self.addCleanup(loop.close)
- @tasks.coroutine
+ @asyncio.coroutine
def sleeper():
- yield from tasks.sleep(10, loop=loop)
+ yield from asyncio.sleep(10, loop=loop)
base_exc = BaseException()
- @tasks.coroutine
+ @asyncio.coroutine
def notmutch():
try:
yield from sleeper()
- except futures.CancelledError:
+ except asyncio.CancelledError:
raise base_exc
- task = tasks.Task(notmutch(), loop=loop)
+ task = asyncio.Task(notmutch(), loop=loop)
test_utils.run_briefly(loop)
task.cancel()
@@ -1041,21 +1038,21 @@ class TaskTests(unittest.TestCase):
def fn():
pass
- self.assertFalse(tasks.iscoroutinefunction(fn))
+ self.assertFalse(asyncio.iscoroutinefunction(fn))
def fn1():
yield
- self.assertFalse(tasks.iscoroutinefunction(fn1))
+ self.assertFalse(asyncio.iscoroutinefunction(fn1))
- @tasks.coroutine
+ @asyncio.coroutine
def fn2():
yield
- self.assertTrue(tasks.iscoroutinefunction(fn2))
+ self.assertTrue(asyncio.iscoroutinefunction(fn2))
def test_yield_vs_yield_from(self):
- fut = futures.Future(loop=self.loop)
+ fut = asyncio.Future(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def wait_for_future():
yield fut
@@ -1066,11 +1063,11 @@ class TaskTests(unittest.TestCase):
self.assertFalse(fut.done())
def test_yield_vs_yield_from_generator(self):
- @tasks.coroutine
+ @asyncio.coroutine
def coro():
yield
- @tasks.coroutine
+ @asyncio.coroutine
def wait_for_future():
gen = coro()
try:
@@ -1084,72 +1081,72 @@ class TaskTests(unittest.TestCase):
self.loop.run_until_complete, task)
def test_coroutine_non_gen_function(self):
- @tasks.coroutine
+ @asyncio.coroutine
def func():
return 'test'
- self.assertTrue(tasks.iscoroutinefunction(func))
+ self.assertTrue(asyncio.iscoroutinefunction(func))
coro = func()
- self.assertTrue(tasks.iscoroutine(coro))
+ self.assertTrue(asyncio.iscoroutine(coro))
res = self.loop.run_until_complete(coro)
self.assertEqual(res, 'test')
def test_coroutine_non_gen_function_return_future(self):
- fut = futures.Future(loop=self.loop)
+ fut = asyncio.Future(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def func():
return fut
- @tasks.coroutine
+ @asyncio.coroutine
def coro():
fut.set_result('test')
- t1 = tasks.Task(func(), loop=self.loop)
- t2 = tasks.Task(coro(), loop=self.loop)
+ t1 = asyncio.Task(func(), loop=self.loop)
+ t2 = asyncio.Task(coro(), loop=self.loop)
res = self.loop.run_until_complete(t1)
self.assertEqual(res, 'test')
self.assertIsNone(t2.result())
def test_current_task(self):
- self.assertIsNone(tasks.Task.current_task(loop=self.loop))
+ self.assertIsNone(asyncio.Task.current_task(loop=self.loop))
- @tasks.coroutine
+ @asyncio.coroutine
def coro(loop):
- self.assertTrue(tasks.Task.current_task(loop=loop) is task)
+ self.assertTrue(asyncio.Task.current_task(loop=loop) is task)
- task = tasks.Task(coro(self.loop), loop=self.loop)
+ task = asyncio.Task(coro(self.loop), loop=self.loop)
self.loop.run_until_complete(task)
- self.assertIsNone(tasks.Task.current_task(loop=self.loop))
+ self.assertIsNone(asyncio.Task.current_task(loop=self.loop))
def test_current_task_with_interleaving_tasks(self):
- self.assertIsNone(tasks.Task.current_task(loop=self.loop))
+ self.assertIsNone(asyncio.Task.current_task(loop=self.loop))
- fut1 = futures.Future(loop=self.loop)
- fut2 = futures.Future(loop=self.loop)
+ fut1 = asyncio.Future(loop=self.loop)
+ fut2 = asyncio.Future(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def coro1(loop):
- self.assertTrue(tasks.Task.current_task(loop=loop) is task1)
+ self.assertTrue(asyncio.Task.current_task(loop=loop) is task1)
yield from fut1
- self.assertTrue(tasks.Task.current_task(loop=loop) is task1)
+ self.assertTrue(asyncio.Task.current_task(loop=loop) is task1)
fut2.set_result(True)
- @tasks.coroutine
+ @asyncio.coroutine
def coro2(loop):
- self.assertTrue(tasks.Task.current_task(loop=loop) is task2)
+ self.assertTrue(asyncio.Task.current_task(loop=loop) is task2)
fut1.set_result(True)
yield from fut2
- self.assertTrue(tasks.Task.current_task(loop=loop) is task2)
+ self.assertTrue(asyncio.Task.current_task(loop=loop) is task2)
- task1 = tasks.Task(coro1(self.loop), loop=self.loop)
- task2 = tasks.Task(coro2(self.loop), loop=self.loop)
+ task1 = asyncio.Task(coro1(self.loop), loop=self.loop)
+ task2 = asyncio.Task(coro2(self.loop), loop=self.loop)
- self.loop.run_until_complete(tasks.wait((task1, task2),
+ self.loop.run_until_complete(asyncio.wait((task1, task2),
loop=self.loop))
- self.assertIsNone(tasks.Task.current_task(loop=self.loop))
+ self.assertIsNone(asyncio.Task.current_task(loop=self.loop))
# Some thorough tests for cancellation propagation through
# coroutines, tasks and wait().
@@ -1157,30 +1154,30 @@ class TaskTests(unittest.TestCase):
def test_yield_future_passes_cancel(self):
# Cancelling outer() cancels inner() cancels waiter.
proof = 0
- waiter = futures.Future(loop=self.loop)
+ waiter = asyncio.Future(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def inner():
nonlocal proof
try:
yield from waiter
- except futures.CancelledError:
+ except asyncio.CancelledError:
proof += 1
raise
else:
self.fail('got past sleep() in inner()')
- @tasks.coroutine
+ @asyncio.coroutine
def outer():
nonlocal proof
try:
yield from inner()
- except futures.CancelledError:
+ except asyncio.CancelledError:
proof += 100 # Expect this path.
else:
proof += 10
- f = tasks.async(outer(), loop=self.loop)
+ f = asyncio.async(outer(), loop=self.loop)
test_utils.run_briefly(self.loop)
f.cancel()
self.loop.run_until_complete(f)
@@ -1191,39 +1188,39 @@ class TaskTests(unittest.TestCase):
# Cancelling outer() makes wait() return early, leaves inner()
# running.
proof = 0
- waiter = futures.Future(loop=self.loop)
+ waiter = asyncio.Future(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def inner():
nonlocal proof
yield from waiter
proof += 1
- @tasks.coroutine
+ @asyncio.coroutine
def outer():
nonlocal proof
- d, p = yield from tasks.wait([inner()], loop=self.loop)
+ d, p = yield from asyncio.wait([inner()], loop=self.loop)
proof += 100
- f = tasks.async(outer(), loop=self.loop)
+ f = asyncio.async(outer(), loop=self.loop)
test_utils.run_briefly(self.loop)
f.cancel()
self.assertRaises(
- futures.CancelledError, self.loop.run_until_complete, f)
+ asyncio.CancelledError, self.loop.run_until_complete, f)
waiter.set_result(None)
test_utils.run_briefly(self.loop)
self.assertEqual(proof, 1)
def test_shield_result(self):
- inner = futures.Future(loop=self.loop)
- outer = tasks.shield(inner)
+ inner = asyncio.Future(loop=self.loop)
+ outer = asyncio.shield(inner)
inner.set_result(42)
res = self.loop.run_until_complete(outer)
self.assertEqual(res, 42)
def test_shield_exception(self):
- inner = futures.Future(loop=self.loop)
- outer = tasks.shield(inner)
+ inner = asyncio.Future(loop=self.loop)
+ outer = asyncio.shield(inner)
test_utils.run_briefly(self.loop)
exc = RuntimeError('expected')
inner.set_exception(exc)
@@ -1231,50 +1228,50 @@ class TaskTests(unittest.TestCase):
self.assertIs(outer.exception(), exc)
def test_shield_cancel(self):
- inner = futures.Future(loop=self.loop)
- outer = tasks.shield(inner)
+ inner = asyncio.Future(loop=self.loop)
+ outer = asyncio.shield(inner)
test_utils.run_briefly(self.loop)
inner.cancel()
test_utils.run_briefly(self.loop)
self.assertTrue(outer.cancelled())
def test_shield_shortcut(self):
- fut = futures.Future(loop=self.loop)
+ fut = asyncio.Future(loop=self.loop)
fut.set_result(42)
- res = self.loop.run_until_complete(tasks.shield(fut))
+ res = self.loop.run_until_complete(asyncio.shield(fut))
self.assertEqual(res, 42)
def test_shield_effect(self):
# Cancelling outer() does not affect inner().
proof = 0
- waiter = futures.Future(loop=self.loop)
+ waiter = asyncio.Future(loop=self.loop)
- @tasks.coroutine
+ @asyncio.coroutine
def inner():
nonlocal proof
yield from waiter
proof += 1
- @tasks.coroutine
+ @asyncio.coroutine
def outer():
nonlocal proof
- yield from tasks.shield(inner(), loop=self.loop)
+ yield from asyncio.shield(inner(), loop=self.loop)
proof += 100
- f = tasks.async(outer(), loop=self.loop)
+ f = asyncio.async(outer(), loop=self.loop)
test_utils.run_briefly(self.loop)
f.cancel()
- with self.assertRaises(futures.CancelledError):
+ with self.assertRaises(asyncio.CancelledError):
self.loop.run_until_complete(f)
waiter.set_result(None)
test_utils.run_briefly(self.loop)
self.assertEqual(proof, 1)
def test_shield_gather(self):
- child1 = futures.Future(loop=self.loop)
- child2 = futures.Future(loop=self.loop)
- parent = tasks.gather(child1, child2, loop=self.loop)
- outer = tasks.shield(parent, loop=self.loop)
+ child1 = asyncio.Future(loop=self.loop)
+ child2 = asyncio.Future(loop=self.loop)
+ parent = asyncio.gather(child1, child2, loop=self.loop)
+ outer = asyncio.shield(parent, loop=self.loop)
test_utils.run_briefly(self.loop)
outer.cancel()
test_utils.run_briefly(self.loop)
@@ -1285,16 +1282,16 @@ class TaskTests(unittest.TestCase):
self.assertEqual(parent.result(), [1, 2])
def test_gather_shield(self):
- child1 = futures.Future(loop=self.loop)
- child2 = futures.Future(loop=self.loop)
- inner1 = tasks.shield(child1, loop=self.loop)
- inner2 = tasks.shield(child2, loop=self.loop)
- parent = tasks.gather(inner1, inner2, loop=self.loop)
+ child1 = asyncio.Future(loop=self.loop)
+ child2 = asyncio.Future(loop=self.loop)
+ inner1 = asyncio.shield(child1, loop=self.loop)
+ inner2 = asyncio.shield(child2, loop=self.loop)
+ parent = asyncio.gather(inner1, inner2, loop=self.loop)
test_utils.run_briefly(self.loop)
parent.cancel()
# This should cancel inner1 and inner2 but bot child1 and child2.
test_utils.run_briefly(self.loop)
- self.assertIsInstance(parent.exception(), futures.CancelledError)
+ self.assertIsInstance(parent.exception(), asyncio.CancelledError)
self.assertTrue(inner1.cancelled())
self.assertTrue(inner2.cancelled())
child1.set_result(1)
@@ -1317,8 +1314,8 @@ class GatherTestsBase:
test_utils.run_briefly(loop)
def _check_success(self, **kwargs):
- a, b, c = [futures.Future(loop=self.one_loop) for i in range(3)]
- fut = tasks.gather(*self.wrap_futures(a, b, c), **kwargs)
+ a, b, c = [asyncio.Future(loop=self.one_loop) for i in range(3)]
+ fut = asyncio.gather(*self.wrap_futures(a, b, c), **kwargs)
cb = Mock()
fut.add_done_callback(cb)
b.set_result(1)
@@ -1339,8 +1336,8 @@ class GatherTestsBase:
self._check_success(return_exceptions=True)
def test_one_exception(self):
- a, b, c, d, e = [futures.Future(loop=self.one_loop) for i in range(5)]
- fut = tasks.gather(*self.wrap_futures(a, b, c, d, e))
+ a, b, c, d, e = [asyncio.Future(loop=self.one_loop) for i in range(5)]
+ fut = asyncio.gather(*self.wrap_futures(a, b, c, d, e))
cb = Mock()
fut.add_done_callback(cb)
exc = ZeroDivisionError()
@@ -1357,8 +1354,8 @@ class GatherTestsBase:
e.exception()
def test_return_exceptions(self):
- a, b, c, d = [futures.Future(loop=self.one_loop) for i in range(4)]
- fut = tasks.gather(*self.wrap_futures(a, b, c, d),
+ a, b, c, d = [asyncio.Future(loop=self.one_loop) for i in range(4)]
+ fut = asyncio.gather(*self.wrap_futures(a, b, c, d),
return_exceptions=True)
cb = Mock()
fut.add_done_callback(cb)
@@ -1382,15 +1379,15 @@ class FutureGatherTests(GatherTestsBase, unittest.TestCase):
return futures
def _check_empty_sequence(self, seq_or_iter):
- events.set_event_loop(self.one_loop)
- self.addCleanup(events.set_event_loop, None)
- fut = tasks.gather(*seq_or_iter)
- self.assertIsInstance(fut, futures.Future)
+ asyncio.set_event_loop(self.one_loop)
+ self.addCleanup(asyncio.set_event_loop, None)
+ fut = asyncio.gather(*seq_or_iter)
+ self.assertIsInstance(fut, asyncio.Future)
self.assertIs(fut._loop, self.one_loop)
self._run_loop(self.one_loop)
self.assertTrue(fut.done())
self.assertEqual(fut.result(), [])
- fut = tasks.gather(*seq_or_iter, loop=self.other_loop)
+ fut = asyncio.gather(*seq_or_iter, loop=self.other_loop)
self.assertIs(fut._loop, self.other_loop)
def test_constructor_empty_sequence(self):
@@ -1400,27 +1397,27 @@ class FutureGatherTests(GatherTestsBase, unittest.TestCase):
self._check_empty_sequence(iter(""))
def test_constructor_heterogenous_futures(self):
- fut1 = futures.Future(loop=self.one_loop)
- fut2 = futures.Future(loop=self.other_loop)
+ fut1 = asyncio.Future(loop=self.one_loop)
+ fut2 = asyncio.Future(loop=self.other_loop)
with self.assertRaises(ValueError):
- tasks.gather(fut1, fut2)
+ asyncio.gather(fut1, fut2)
with self.assertRaises(ValueError):
- tasks.gather(fut1, loop=self.other_loop)
+ asyncio.gather(fut1, loop=self.other_loop)
def test_constructor_homogenous_futures(self):
- children = [futures.Future(loop=self.other_loop) for i in range(3)]
- fut = tasks.gather(*children)
+ children = [asyncio.Future(loop=self.other_loop) for i in range(3)]
+ fut = asyncio.gather(*children)
self.assertIs(fut._loop, self.other_loop)
self._run_loop(self.other_loop)
self.assertFalse(fut.done())
- fut = tasks.gather(*children, loop=self.other_loop)
+ fut = asyncio.gather(*children, loop=self.other_loop)
self.assertIs(fut._loop, self.other_loop)
self._run_loop(self.other_loop)
self.assertFalse(fut.done())
def test_one_cancellation(self):
- a, b, c, d, e = [futures.Future(loop=self.one_loop) for i in range(5)]
- fut = tasks.gather(a, b, c, d, e)
+ a, b, c, d, e = [asyncio.Future(loop=self.one_loop) for i in range(5)]
+ fut = asyncio.gather(a, b, c, d, e)
cb = Mock()
fut.add_done_callback(cb)
a.set_result(1)
@@ -1429,7 +1426,7 @@ class FutureGatherTests(GatherTestsBase, unittest.TestCase):
self.assertTrue(fut.done())
cb.assert_called_once_with(fut)
self.assertFalse(fut.cancelled())
- self.assertIsInstance(fut.exception(), futures.CancelledError)
+ self.assertIsInstance(fut.exception(), asyncio.CancelledError)
# Does nothing
c.set_result(3)
d.cancel()
@@ -1437,9 +1434,9 @@ class FutureGatherTests(GatherTestsBase, unittest.TestCase):
e.exception()
def test_result_exception_one_cancellation(self):
- a, b, c, d, e, f = [futures.Future(loop=self.one_loop)
+ a, b, c, d, e, f = [asyncio.Future(loop=self.one_loop)
for i in range(6)]
- fut = tasks.gather(a, b, c, d, e, f, return_exceptions=True)
+ fut = asyncio.gather(a, b, c, d, e, f, return_exceptions=True)
cb = Mock()
fut.add_done_callback(cb)
a.set_result(1)
@@ -1453,8 +1450,8 @@ class FutureGatherTests(GatherTestsBase, unittest.TestCase):
rte = RuntimeError()
f.set_exception(rte)
res = self.one_loop.run_until_complete(fut)
- self.assertIsInstance(res[2], futures.CancelledError)
- self.assertIsInstance(res[4], futures.CancelledError)
+ self.assertIsInstance(res[2], asyncio.CancelledError)
+ self.assertIsInstance(res[4], asyncio.CancelledError)
res[2] = res[4] = None
self.assertEqual(res, [1, zde, None, 3, None, rte])
cb.assert_called_once_with(fut)
@@ -1464,34 +1461,34 @@ class CoroutineGatherTests(GatherTestsBase, unittest.TestCase):
def setUp(self):
super().setUp()
- events.set_event_loop(self.one_loop)
+ asyncio.set_event_loop(self.one_loop)
def tearDown(self):
- events.set_event_loop(None)
+ asyncio.set_event_loop(None)
super().tearDown()
def wrap_futures(self, *futures):
coros = []
for fut in futures:
- @tasks.coroutine
+ @asyncio.coroutine
def coro(fut=fut):
return (yield from fut)
coros.append(coro())
return coros
def test_constructor_loop_selection(self):
- @tasks.coroutine
+ @asyncio.coroutine
def coro():
return 'abc'
gen1 = coro()
gen2 = coro()
- fut = tasks.gather(gen1, gen2)
+ fut = asyncio.gather(gen1, gen2)
self.assertIs(fut._loop, self.one_loop)
gen1.close()
gen2.close()
gen3 = coro()
gen4 = coro()
- fut = tasks.gather(gen3, gen4, loop=self.other_loop)
+ fut = asyncio.gather(gen3, gen4, loop=self.other_loop)
self.assertIs(fut._loop, self.other_loop)
gen3.close()
gen4.close()
@@ -1499,29 +1496,29 @@ class CoroutineGatherTests(GatherTestsBase, unittest.TestCase):
def test_cancellation_broadcast(self):
# Cancelling outer() cancels all children.
proof = 0
- waiter = futures.Future(loop=self.one_loop)
+ waiter = asyncio.Future(loop=self.one_loop)
- @tasks.coroutine
+ @asyncio.coroutine
def inner():
nonlocal proof
yield from waiter
proof += 1
- child1 = tasks.async(inner(), loop=self.one_loop)
- child2 = tasks.async(inner(), loop=self.one_loop)
+ child1 = asyncio.async(inner(), loop=self.one_loop)
+ child2 = asyncio.async(inner(), loop=self.one_loop)
gatherer = None
- @tasks.coroutine
+ @asyncio.coroutine
def outer():
nonlocal proof, gatherer
- gatherer = tasks.gather(child1, child2, loop=self.one_loop)
+ gatherer = asyncio.gather(child1, child2, loop=self.one_loop)
yield from gatherer
proof += 100
- f = tasks.async(outer(), loop=self.one_loop)
+ f = asyncio.async(outer(), loop=self.one_loop)
test_utils.run_briefly(self.one_loop)
self.assertTrue(f.cancel())
- with self.assertRaises(futures.CancelledError):
+ with self.assertRaises(asyncio.CancelledError):
self.one_loop.run_until_complete(f)
self.assertFalse(gatherer.cancel())
self.assertTrue(waiter.cancelled())
@@ -1533,19 +1530,19 @@ class CoroutineGatherTests(GatherTestsBase, unittest.TestCase):
def test_exception_marking(self):
# Test for the first line marked "Mark exception retrieved."
- @tasks.coroutine
+ @asyncio.coroutine
def inner(f):
yield from f
raise RuntimeError('should not be ignored')
- a = futures.Future(loop=self.one_loop)
- b = futures.Future(loop=self.one_loop)
+ a = asyncio.Future(loop=self.one_loop)
+ b = asyncio.Future(loop=self.one_loop)
- @tasks.coroutine
+ @asyncio.coroutine
def outer():
- yield from tasks.gather(inner(a), inner(b), loop=self.one_loop)
+ yield from asyncio.gather(inner(a), inner(b), loop=self.one_loop)
- f = tasks.async(outer(), loop=self.one_loop)
+ f = asyncio.async(outer(), loop=self.one_loop)
test_utils.run_briefly(self.one_loop)
a.set_result(None)
test_utils.run_briefly(self.one_loop)
diff --git a/Lib/test/test_asyncio/test_transports.py b/Lib/test/test_asyncio/test_transports.py
index 29393b527d..d16db8074b 100644
--- a/Lib/test/test_asyncio/test_transports.py
+++ b/Lib/test/test_asyncio/test_transports.py
@@ -3,17 +3,17 @@
import unittest
import unittest.mock
-from asyncio import transports
+import asyncio
class TransportTests(unittest.TestCase):
def test_ctor_extra_is_none(self):
- transport = transports.Transport()
+ transport = asyncio.Transport()
self.assertEqual(transport._extra, {})
def test_get_extra_info(self):
- transport = transports.Transport({'extra': 'info'})
+ transport = asyncio.Transport({'extra': 'info'})
self.assertEqual('info', transport.get_extra_info('extra'))
self.assertIsNone(transport.get_extra_info('unknown'))
@@ -21,7 +21,7 @@ class TransportTests(unittest.TestCase):
self.assertIs(default, transport.get_extra_info('unknown', default))
def test_writelines(self):
- transport = transports.Transport()
+ transport = asyncio.Transport()
transport.write = unittest.mock.Mock()
transport.writelines([b'line1',
@@ -31,7 +31,7 @@ class TransportTests(unittest.TestCase):
transport.write.assert_called_with(b'line1line2line3')
def test_not_implemented(self):
- transport = transports.Transport()
+ transport = asyncio.Transport()
self.assertRaises(NotImplementedError,
transport.set_write_buffer_limits)
@@ -45,13 +45,13 @@ class TransportTests(unittest.TestCase):
self.assertRaises(NotImplementedError, transport.abort)
def test_dgram_not_implemented(self):
- transport = transports.DatagramTransport()
+ transport = asyncio.DatagramTransport()
self.assertRaises(NotImplementedError, transport.sendto, 'data')
self.assertRaises(NotImplementedError, transport.abort)
def test_subprocess_transport_not_implemented(self):
- transport = transports.SubprocessTransport()
+ transport = asyncio.SubprocessTransport()
self.assertRaises(NotImplementedError, transport.get_pid)
self.assertRaises(NotImplementedError, transport.get_returncode)
diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py
index 98cf407959..9461ec8b87 100644
--- a/Lib/test/test_asyncio/test_unix_events.py
+++ b/Lib/test/test_asyncio/test_unix_events.py
@@ -17,9 +17,8 @@ if sys.platform == 'win32':
raise unittest.SkipTest('UNIX only')
-from asyncio import events
-from asyncio import futures
-from asyncio import protocols
+import asyncio
+from asyncio import log
from asyncio import test_utils
from asyncio import unix_events
@@ -28,8 +27,8 @@ from asyncio import unix_events
class SelectorEventLoopTests(unittest.TestCase):
def setUp(self):
- self.loop = unix_events.SelectorEventLoop()
- events.set_event_loop(None)
+ self.loop = asyncio.SelectorEventLoop()
+ asyncio.set_event_loop(None)
def tearDown(self):
self.loop.close()
@@ -44,7 +43,7 @@ class SelectorEventLoopTests(unittest.TestCase):
self.loop._handle_signal(signal.NSIG + 1, ())
def test_handle_signal_cancelled_handler(self):
- h = events.Handle(unittest.mock.Mock(), ())
+ h = asyncio.Handle(unittest.mock.Mock(), ())
h.cancel()
self.loop._signal_handlers[signal.NSIG + 1] = h
self.loop.remove_signal_handler = unittest.mock.Mock()
@@ -68,7 +67,7 @@ class SelectorEventLoopTests(unittest.TestCase):
cb = lambda: True
self.loop.add_signal_handler(signal.SIGHUP, cb)
h = self.loop._signal_handlers.get(signal.SIGHUP)
- self.assertIsInstance(h, events.Handle)
+ self.assertIsInstance(h, asyncio.Handle)
self.assertEqual(h._callback, cb)
@unittest.mock.patch('asyncio.unix_events.signal')
@@ -205,7 +204,7 @@ class UnixReadPipeTransportTests(unittest.TestCase):
def setUp(self):
self.loop = test_utils.TestLoop()
- self.protocol = test_utils.make_test_protocol(protocols.Protocol)
+ self.protocol = test_utils.make_test_protocol(asyncio.Protocol)
self.pipe = unittest.mock.Mock(spec_set=io.RawIOBase)
self.pipe.fileno.return_value = 5
@@ -228,7 +227,7 @@ class UnixReadPipeTransportTests(unittest.TestCase):
self.protocol.connection_made.assert_called_with(tr)
def test_ctor_with_waiter(self):
- fut = futures.Future(loop=self.loop)
+ fut = asyncio.Future(loop=self.loop)
unix_events._UnixReadPipeTransport(
self.loop, self.pipe, self.protocol, fut)
test_utils.run_briefly(self.loop)
@@ -368,7 +367,7 @@ class UnixWritePipeTransportTests(unittest.TestCase):
def setUp(self):
self.loop = test_utils.TestLoop()
- self.protocol = test_utils.make_test_protocol(protocols.BaseProtocol)
+ self.protocol = test_utils.make_test_protocol(asyncio.BaseProtocol)
self.pipe = unittest.mock.Mock(spec_set=io.RawIOBase)
self.pipe.fileno.return_value = 5
@@ -391,7 +390,7 @@ class UnixWritePipeTransportTests(unittest.TestCase):
self.protocol.connection_made.assert_called_with(tr)
def test_ctor_with_waiter(self):
- fut = futures.Future(loop=self.loop)
+ fut = asyncio.Future(loop=self.loop)
tr = unix_events._UnixWritePipeTransport(
self.loop, self.pipe, self.protocol, fut)
self.loop.assert_reader(5, tr._read_ready)
@@ -682,7 +681,7 @@ class AbstractChildWatcherTests(unittest.TestCase):
def test_not_implemented(self):
f = unittest.mock.Mock()
- watcher = unix_events.AbstractChildWatcher()
+ watcher = asyncio.AbstractChildWatcher()
self.assertRaises(
NotImplementedError, watcher.add_child_handler, f, f)
self.assertRaises(
@@ -717,7 +716,7 @@ WaitPidMocks = collections.namedtuple("WaitPidMocks",
class ChildWatcherTestsMixin:
- ignore_warnings = unittest.mock.patch.object(unix_events.logger, "warning")
+ ignore_warnings = unittest.mock.patch.object(log.logger, "warning")
def setUp(self):
self.loop = test_utils.TestLoop()
@@ -730,7 +729,7 @@ class ChildWatcherTestsMixin:
self.watcher.attach_loop(self.loop)
def waitpid(self, pid, flags):
- if isinstance(self.watcher, unix_events.SafeChildWatcher) or pid != -1:
+ if isinstance(self.watcher, asyncio.SafeChildWatcher) or pid != -1:
self.assertGreater(pid, 0)
try:
if pid < 0:
@@ -1205,7 +1204,7 @@ class ChildWatcherTestsMixin:
# raise an exception
m.waitpid.side_effect = ValueError
- with unittest.mock.patch.object(unix_events.logger,
+ with unittest.mock.patch.object(log.logger,
"exception") as m_exception:
self.assertEqual(self.watcher._sig_chld(), None)
@@ -1240,7 +1239,7 @@ class ChildWatcherTestsMixin:
self.watcher._sig_chld()
callback.assert_called(m.waitpid)
- if isinstance(self.watcher, unix_events.FastChildWatcher):
+ if isinstance(self.watcher, asyncio.FastChildWatcher):
# here the FastChildWatche enters a deadlock
# (there is no way to prevent it)
self.assertFalse(callback.called)
@@ -1380,7 +1379,7 @@ class ChildWatcherTestsMixin:
self.watcher.add_child_handler(64, callback1)
self.assertEqual(len(self.watcher._callbacks), 1)
- if isinstance(self.watcher, unix_events.FastChildWatcher):
+ if isinstance(self.watcher, asyncio.FastChildWatcher):
self.assertEqual(len(self.watcher._zombies), 1)
with unittest.mock.patch.object(
@@ -1392,31 +1391,31 @@ class ChildWatcherTestsMixin:
m_remove_signal_handler.assert_called_once_with(
signal.SIGCHLD)
self.assertFalse(self.watcher._callbacks)
- if isinstance(self.watcher, unix_events.FastChildWatcher):
+ if isinstance(self.watcher, asyncio.FastChildWatcher):
self.assertFalse(self.watcher._zombies)
class SafeChildWatcherTests (ChildWatcherTestsMixin, unittest.TestCase):
def create_watcher(self):
- return unix_events.SafeChildWatcher()
+ return asyncio.SafeChildWatcher()
class FastChildWatcherTests (ChildWatcherTestsMixin, unittest.TestCase):
def create_watcher(self):
- return unix_events.FastChildWatcher()
+ return asyncio.FastChildWatcher()
class PolicyTests(unittest.TestCase):
def create_policy(self):
- return unix_events.DefaultEventLoopPolicy()
+ return asyncio.DefaultEventLoopPolicy()
def test_get_child_watcher(self):
policy = self.create_policy()
self.assertIsNone(policy._watcher)
watcher = policy.get_child_watcher()
- self.assertIsInstance(watcher, unix_events.SafeChildWatcher)
+ self.assertIsInstance(watcher, asyncio.SafeChildWatcher)
self.assertIs(policy._watcher, watcher)
@@ -1425,7 +1424,7 @@ class PolicyTests(unittest.TestCase):
def test_get_child_watcher_after_set(self):
policy = self.create_policy()
- watcher = unix_events.FastChildWatcher()
+ watcher = asyncio.FastChildWatcher()
policy.set_child_watcher(watcher)
self.assertIs(policy._watcher, watcher)
@@ -1438,7 +1437,7 @@ class PolicyTests(unittest.TestCase):
self.assertIsNone(policy._watcher)
watcher = policy.get_child_watcher()
- self.assertIsInstance(watcher, unix_events.SafeChildWatcher)
+ self.assertIsInstance(watcher, asyncio.SafeChildWatcher)
self.assertIs(watcher._loop, loop)
loop.close()
@@ -1449,10 +1448,10 @@ class PolicyTests(unittest.TestCase):
policy.set_event_loop(policy.new_event_loop())
self.assertIsInstance(policy.get_event_loop(),
- events.AbstractEventLoop)
+ asyncio.AbstractEventLoop)
watcher = policy.get_child_watcher()
- self.assertIsInstance(watcher, unix_events.SafeChildWatcher)
+ self.assertIsInstance(watcher, asyncio.SafeChildWatcher)
self.assertIsNone(watcher._loop)
policy.get_event_loop().close()
diff --git a/Lib/test/test_asyncio/test_windows_events.py b/Lib/test/test_asyncio/test_windows_events.py
index 17c204a756..3c271ebeec 100644
--- a/Lib/test/test_asyncio/test_windows_events.py
+++ b/Lib/test/test_asyncio/test_windows_events.py
@@ -8,17 +8,12 @@ if sys.platform != 'win32':
import _winapi
import asyncio
-
-from asyncio import windows_events
-from asyncio import futures
-from asyncio import protocols
-from asyncio import streams
-from asyncio import transports
from asyncio import test_utils
from asyncio import _overlapped
+from asyncio import windows_events
-class UpperProto(protocols.Protocol):
+class UpperProto(asyncio.Protocol):
def __init__(self):
self.buf = []
@@ -35,7 +30,7 @@ class UpperProto(protocols.Protocol):
class ProactorTests(unittest.TestCase):
def setUp(self):
- self.loop = windows_events.ProactorEventLoop()
+ self.loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(None)
def tearDown(self):
@@ -44,7 +39,7 @@ class ProactorTests(unittest.TestCase):
def test_close(self):
a, b = self.loop._socketpair()
- trans = self.loop._make_socket_transport(a, protocols.Protocol())
+ trans = self.loop._make_socket_transport(a, asyncio.Protocol())
f = asyncio.async(self.loop.sock_recv(b, 100))
trans.close()
self.loop.run_until_complete(f)
@@ -67,7 +62,7 @@ class ProactorTests(unittest.TestCase):
with self.assertRaises(FileNotFoundError):
yield from self.loop.create_pipe_connection(
- protocols.Protocol, ADDRESS)
+ asyncio.Protocol, ADDRESS)
[server] = yield from self.loop.start_serving_pipe(
UpperProto, ADDRESS)
@@ -75,11 +70,11 @@ class ProactorTests(unittest.TestCase):
clients = []
for i in range(5):
- stream_reader = streams.StreamReader(loop=self.loop)
- protocol = streams.StreamReaderProtocol(stream_reader)
+ stream_reader = asyncio.StreamReader(loop=self.loop)
+ protocol = asyncio.StreamReaderProtocol(stream_reader)
trans, proto = yield from self.loop.create_pipe_connection(
lambda: protocol, ADDRESS)
- self.assertIsInstance(trans, transports.Transport)
+ self.assertIsInstance(trans, asyncio.Transport)
self.assertEqual(protocol, proto)
clients.append((stream_reader, trans))
@@ -95,7 +90,7 @@ class ProactorTests(unittest.TestCase):
with self.assertRaises(FileNotFoundError):
yield from self.loop.create_pipe_connection(
- protocols.Protocol, ADDRESS)
+ asyncio.Protocol, ADDRESS)
return 'done'
@@ -130,7 +125,7 @@ class ProactorTests(unittest.TestCase):
f = self.loop._proactor.wait_for_handle(event, 10)
f.cancel()
start = self.loop.time()
- with self.assertRaises(futures.CancelledError):
+ with self.assertRaises(asyncio.CancelledError):
self.loop.run_until_complete(f)
elapsed = self.loop.time() - start
self.assertTrue(0 <= elapsed < 0.1, elapsed)
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
index 22c8eb0709..444feb6314 100644
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -125,7 +125,7 @@ class CAPITest(unittest.TestCase):
self.assertEqual(_testcapi.docstring_no_signature.__text_signature__, None)
self.assertEqual(_testcapi.docstring_with_invalid_signature.__doc__,
- "docstring_with_invalid_signature (boo)\n"
+ "docstring_with_invalid_signature (module, boo)\n"
"\n"
"This docstring has an invalid signature."
)
@@ -133,12 +133,12 @@ class CAPITest(unittest.TestCase):
self.assertEqual(_testcapi.docstring_with_signature.__doc__,
"This docstring has a valid signature.")
- self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "(sig)")
+ self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "(module, sig)")
self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__,
"This docstring has a valid signature and some extra newlines.")
self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__,
- "(parameter)")
+ "(module, parameter)")
@unittest.skipUnless(threading, 'Threading required for this test.')
diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py
index f9c9e69f23..3950c3bc20 100644
--- a/Lib/test/test_codecs.py
+++ b/Lib/test/test_codecs.py
@@ -175,6 +175,40 @@ class ReadTest(MixInCheckStateHandling):
size*"a",
)
+ def test_mixed_readline_and_read(self):
+ lines = ["Humpty Dumpty sat on a wall,\n",
+ "Humpty Dumpty had a great fall.\r\n",
+ "All the king's horses and all the king's men\r",
+ "Couldn't put Humpty together again."]
+ data = ''.join(lines)
+ def getreader():
+ stream = io.BytesIO(data.encode(self.encoding))
+ return codecs.getreader(self.encoding)(stream)
+
+ # Issue #8260: Test readline() followed by read()
+ f = getreader()
+ self.assertEqual(f.readline(), lines[0])
+ self.assertEqual(f.read(), ''.join(lines[1:]))
+ self.assertEqual(f.read(), '')
+
+ # Issue #16636: Test readline() followed by readlines()
+ f = getreader()
+ self.assertEqual(f.readline(), lines[0])
+ self.assertEqual(f.readlines(), lines[1:])
+ self.assertEqual(f.read(), '')
+
+ # Test read() followed by read()
+ f = getreader()
+ self.assertEqual(f.read(size=40, chars=5), data[:5])
+ self.assertEqual(f.read(), data[5:])
+ self.assertEqual(f.read(), '')
+
+ # Issue #12446: Test read() followed by readlines()
+ f = getreader()
+ self.assertEqual(f.read(size=40, chars=5), data[:5])
+ self.assertEqual(f.readlines(), [lines[0][5:]] + lines[1:])
+ self.assertEqual(f.read(), '')
+
def test_bug1175396(self):
s = [
'<%!--===================================================\r\n',
@@ -2370,8 +2404,6 @@ class TransformCodecTest(unittest.TestCase):
def test_readline(self):
for encoding in bytes_transform_encodings:
- if encoding in ['uu_codec', 'zlib_codec']:
- continue
with self.subTest(encoding=encoding):
sin = codecs.encode(b"\x80", encoding)
reader = codecs.getreader(encoding)(io.BytesIO(sin))
@@ -2522,6 +2554,7 @@ class ExceptionChainingTest(unittest.TestCase):
with self.assertRaisesRegex(exc_type, full_msg) as caught:
yield caught
self.assertIsInstance(caught.exception.__cause__, exc_type)
+ self.assertIsNotNone(caught.exception.__cause__.__traceback__)
def raise_obj(self, *args, **kwds):
# Helper to dynamically change the object raised by a test codec
diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py
index a7e945cb5e..c74b2ca6ed 100644
--- a/Lib/test/test_concurrent_futures.py
+++ b/Lib/test/test_concurrent_futures.py
@@ -350,6 +350,13 @@ class AsCompletedTests:
SUCCESSFUL_FUTURE]),
completed_futures)
+ def test_duplicate_futures(self):
+ # Issue 20367. Duplicate futures should not raise exceptions or give
+ # duplicate responses.
+ future1 = self.executor.submit(time.sleep, 2)
+ completed = [f for f in futures.as_completed([future1,future1])]
+ self.assertEqual(len(completed), 1)
+
class ThreadPoolAsCompletedTests(ThreadPoolMixin, AsCompletedTests, unittest.TestCase):
pass
diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py
index f947232176..39cc776dbc 100644
--- a/Lib/test/test_contextlib.py
+++ b/Lib/test/test_contextlib.py
@@ -629,24 +629,62 @@ class TestExitStack(unittest.TestCase):
def test_exit_exception_with_correct_context(self):
# http://bugs.python.org/issue20317
@contextmanager
- def gets_the_context_right():
+ def gets_the_context_right(exc):
try:
- yield 6
+ yield
finally:
- 1 / 0
+ raise exc
+
+ exc1 = Exception(1)
+ exc2 = Exception(2)
+ exc3 = Exception(3)
+ exc4 = Exception(4)
# The contextmanager already fixes the context, so prior to the
# fix, ExitStack would try to fix it *again* and get into an
# infinite self-referential loop
try:
with ExitStack() as stack:
- stack.enter_context(gets_the_context_right())
- stack.enter_context(gets_the_context_right())
- stack.enter_context(gets_the_context_right())
- except ZeroDivisionError as exc:
- self.assertIsInstance(exc.__context__, ZeroDivisionError)
- self.assertIsInstance(exc.__context__.__context__, ZeroDivisionError)
- self.assertIsNone(exc.__context__.__context__.__context__)
+ stack.enter_context(gets_the_context_right(exc4))
+ stack.enter_context(gets_the_context_right(exc3))
+ stack.enter_context(gets_the_context_right(exc2))
+ raise exc1
+ except Exception as exc:
+ self.assertIs(exc, exc4)
+ self.assertIs(exc.__context__, exc3)
+ self.assertIs(exc.__context__.__context__, exc2)
+ self.assertIs(exc.__context__.__context__.__context__, exc1)
+ self.assertIsNone(
+ exc.__context__.__context__.__context__.__context__)
+
+ def test_exit_exception_with_existing_context(self):
+ # Addresses a lack of test coverage discovered after checking in a
+ # fix for issue 20317 that still contained debugging code.
+ def raise_nested(inner_exc, outer_exc):
+ try:
+ raise inner_exc
+ finally:
+ raise outer_exc
+ exc1 = Exception(1)
+ exc2 = Exception(2)
+ exc3 = Exception(3)
+ exc4 = Exception(4)
+ exc5 = Exception(5)
+ try:
+ with ExitStack() as stack:
+ stack.callback(raise_nested, exc4, exc5)
+ stack.callback(raise_nested, exc2, exc3)
+ raise exc1
+ except Exception as exc:
+ self.assertIs(exc, exc5)
+ self.assertIs(exc.__context__, exc4)
+ self.assertIs(exc.__context__.__context__, exc3)
+ self.assertIs(exc.__context__.__context__.__context__, exc2)
+ self.assertIs(
+ exc.__context__.__context__.__context__.__context__, exc1)
+ self.assertIsNone(
+ exc.__context__.__context__.__context__.__context__.__context__)
+
def test_body_exception_suppress(self):
diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py
index 7310afc995..ce8f254bbb 100644
--- a/Lib/test/test_curses.py
+++ b/Lib/test/test_curses.py
@@ -115,8 +115,8 @@ def window_funcs(stdscr):
stdscr.notimeout(1)
win2.overlay(win)
win2.overwrite(win)
- win2.overlay(win, 1, 2, 3, 3, 2, 1)
- win2.overwrite(win, 1, 2, 3, 3, 2, 1)
+ 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)
diff --git a/Lib/test/test_epoll.py b/Lib/test/test_epoll.py
index 58dd92f7e1..0c88cc424c 100644
--- a/Lib/test/test_epoll.py
+++ b/Lib/test/test_epoll.py
@@ -254,17 +254,6 @@ class TestEPoll(unittest.TestCase):
self.addCleanup(epoll.close)
self.assertEqual(os.get_inheritable(epoll.fileno()), False)
- def test_timeout_rounding(self):
- # epoll_wait() has a resolution of 1 millisecond, check if the timeout
- # is correctly rounded to the upper bound
- epoll = select.epoll()
- self.addCleanup(epoll.close)
- for timeout in (1e-2, 1e-3, 1e-4):
- t0 = time.monotonic()
- epoll.poll(timeout)
- dt = time.monotonic() - t0
- self.assertGreaterEqual(dt, timeout)
-
def test_main():
support.run_unittest(TestEPoll)
diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py
index 4e921177a5..5b7424bcf8 100644
--- a/Lib/test/test_generators.py
+++ b/Lib/test/test_generators.py
@@ -436,8 +436,8 @@ From the Iterators list, about the types of these things.
>>> [s for s in dir(i) if not s.startswith('_')]
['close', 'gi_code', 'gi_frame', 'gi_running', 'send', 'throw']
>>> from test.support import HAVE_DOCSTRINGS
->>> print(i.__next__.__doc__ if HAVE_DOCSTRINGS else 'x.__next__() <==> next(x)')
-x.__next__() <==> next(x)
+>>> print(i.__next__.__doc__ if HAVE_DOCSTRINGS else 'Implements next(self).')
+Implements next(self).
>>> iter(i) is i
True
>>> import types
diff --git a/Lib/test/test_genexps.py b/Lib/test/test_genexps.py
index 203b336fde..74957cb8f4 100644
--- a/Lib/test/test_genexps.py
+++ b/Lib/test/test_genexps.py
@@ -222,8 +222,8 @@ Check that generator attributes are present
True
>>> from test.support import HAVE_DOCSTRINGS
- >>> print(g.__next__.__doc__ if HAVE_DOCSTRINGS else 'x.__next__() <==> next(x)')
- x.__next__() <==> next(x)
+ >>> print(g.__next__.__doc__ if HAVE_DOCSTRINGS else 'Implements next(self).')
+ Implements next(self).
>>> import types
>>> isinstance(g, types.GeneratorType)
True
diff --git a/Lib/test/test_imghdr.py b/Lib/test/test_imghdr.py
new file mode 100644
index 0000000000..0ad4343f52
--- /dev/null
+++ b/Lib/test/test_imghdr.py
@@ -0,0 +1,131 @@
+import imghdr
+import io
+import os
+import unittest
+import warnings
+from test.support import findfile, TESTFN, unlink
+
+TEST_FILES = (
+ ('python.png', 'png'),
+ ('python.gif', 'gif'),
+ ('python.bmp', 'bmp'),
+ ('python.ppm', 'ppm'),
+ ('python.pgm', 'pgm'),
+ ('python.pbm', 'pbm'),
+ ('python.jpg', 'jpeg'),
+ ('python.ras', 'rast'),
+ ('python.sgi', 'rgb'),
+ ('python.tiff', 'tiff'),
+ ('python.xbm', 'xbm')
+)
+
+class UnseekableIO(io.FileIO):
+ def tell(self):
+ raise io.UnsupportedOperation
+
+ def seek(self, *args, **kwargs):
+ raise io.UnsupportedOperation
+
+class TestImghdr(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ cls.testfile = findfile('python.png', subdir='imghdrdata')
+ with open(cls.testfile, 'rb') as stream:
+ cls.testdata = stream.read()
+
+ def tearDown(self):
+ unlink(TESTFN)
+
+ def test_data(self):
+ for filename, expected in TEST_FILES:
+ filename = findfile(filename, subdir='imghdrdata')
+ self.assertEqual(imghdr.what(filename), expected)
+ with open(filename, 'rb') as stream:
+ self.assertEqual(imghdr.what(stream), expected)
+ with open(filename, 'rb') as stream:
+ data = stream.read()
+ self.assertEqual(imghdr.what(None, data), expected)
+ self.assertEqual(imghdr.what(None, bytearray(data)), expected)
+
+ def test_register_test(self):
+ def test_jumbo(h, file):
+ if h.startswith(b'eggs'):
+ return 'ham'
+ imghdr.tests.append(test_jumbo)
+ self.addCleanup(imghdr.tests.pop)
+ self.assertEqual(imghdr.what(None, b'eggs'), 'ham')
+
+ def test_file_pos(self):
+ with open(TESTFN, 'wb') as stream:
+ stream.write(b'ababagalamaga')
+ pos = stream.tell()
+ stream.write(self.testdata)
+ with open(TESTFN, 'rb') as stream:
+ stream.seek(pos)
+ self.assertEqual(imghdr.what(stream), 'png')
+ self.assertEqual(stream.tell(), pos)
+
+ def test_bad_args(self):
+ with self.assertRaises(TypeError):
+ imghdr.what()
+ with self.assertRaises(AttributeError):
+ imghdr.what(None)
+ with self.assertRaises(TypeError):
+ imghdr.what(self.testfile, 1)
+ with self.assertRaises(AttributeError):
+ imghdr.what(os.fsencode(self.testfile))
+ with open(self.testfile, 'rb') as f:
+ with self.assertRaises(AttributeError):
+ imghdr.what(f.fileno())
+
+ def test_invalid_headers(self):
+ for header in (b'\211PN\r\n',
+ b'\001\331',
+ b'\x59\xA6',
+ b'cutecat',
+ b'000000JFI',
+ b'GIF80'):
+ self.assertIsNone(imghdr.what(None, header))
+
+ def test_string_data(self):
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", BytesWarning)
+ for filename, _ in TEST_FILES:
+ filename = findfile(filename, subdir='imghdrdata')
+ with open(filename, 'rb') as stream:
+ data = stream.read().decode('latin1')
+ with self.assertRaises(TypeError):
+ imghdr.what(io.StringIO(data))
+ with self.assertRaises(TypeError):
+ imghdr.what(None, data)
+
+ def test_missing_file(self):
+ with self.assertRaises(FileNotFoundError):
+ imghdr.what('missing')
+
+ def test_closed_file(self):
+ stream = open(self.testfile, 'rb')
+ stream.close()
+ with self.assertRaises(ValueError) as cm:
+ imghdr.what(stream)
+ stream = io.BytesIO(self.testdata)
+ stream.close()
+ with self.assertRaises(ValueError) as cm:
+ imghdr.what(stream)
+
+ def test_unseekable(self):
+ with open(TESTFN, 'wb') as stream:
+ stream.write(self.testdata)
+ with UnseekableIO(TESTFN, 'rb') as stream:
+ with self.assertRaises(io.UnsupportedOperation):
+ imghdr.what(stream)
+
+ def test_output_stream(self):
+ with open(TESTFN, 'wb') as stream:
+ stream.write(self.testdata)
+ stream.seek(0)
+ with self.assertRaises(OSError) as cm:
+ imghdr.what(stream)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Lib/test/test_importlib/test_api.py b/Lib/test/test_importlib/test_api.py
index c3c19f4c13..744001b4c0 100644
--- a/Lib/test/test_importlib/test_api.py
+++ b/Lib/test/test_importlib/test_api.py
@@ -4,7 +4,6 @@ frozen_init, source_init = util.import_importlib('importlib')
frozen_util, source_util = util.import_importlib('importlib.util')
frozen_machinery, source_machinery = util.import_importlib('importlib.machinery')
-from contextlib import contextmanager
import os.path
import sys
from test import support
@@ -13,37 +12,6 @@ import unittest
import warnings
-@contextmanager
-def temp_module(name, content='', *, pkg=False):
- conflicts = [n for n in sys.modules if n.partition('.')[0] == name]
- with support.temp_cwd(None) as cwd:
- with util.uncache(name, *conflicts):
- with support.DirsOnSysPath(cwd):
- frozen_init.invalidate_caches()
-
- location = os.path.join(cwd, name)
- if pkg:
- modpath = os.path.join(location, '__init__.py')
- os.mkdir(name)
- else:
- modpath = location + '.py'
- if content is None:
- # Make sure the module file gets created.
- content = ''
- if content is not None:
- # not a namespace package
- with open(modpath, 'w') as modfile:
- modfile.write(content)
- yield location
-
-
-def submodule(parent, name, pkg_dir, content=''):
- path = os.path.join(pkg_dir, name + '.py')
- with open(path, 'w') as subfile:
- subfile.write(content)
- return '{}.{}'.format(parent, name), path
-
-
class ImportModuleTests:
"""Test importlib.import_module."""
@@ -210,121 +178,6 @@ class Source_FindLoaderTests(FindLoaderTests, unittest.TestCase):
init = source_init
-class FindSpecTests:
-
- class FakeMetaFinder:
- @staticmethod
- def find_spec(name, path=None, target=None): return name, path, target
-
- def test_sys_modules(self):
- name = 'some_mod'
- with util.uncache(name):
- module = types.ModuleType(name)
- loader = 'a loader!'
- spec = self.machinery.ModuleSpec(name, loader)
- module.__loader__ = loader
- module.__spec__ = spec
- sys.modules[name] = module
- found = self.init.find_spec(name)
- self.assertEqual(found, spec)
-
- def test_sys_modules_without___loader__(self):
- name = 'some_mod'
- with util.uncache(name):
- module = types.ModuleType(name)
- del module.__loader__
- loader = 'a loader!'
- spec = self.machinery.ModuleSpec(name, loader)
- module.__spec__ = spec
- sys.modules[name] = module
- found = self.init.find_spec(name)
- self.assertEqual(found, spec)
-
- def test_sys_modules_spec_is_None(self):
- name = 'some_mod'
- with util.uncache(name):
- module = types.ModuleType(name)
- module.__spec__ = None
- sys.modules[name] = module
- with self.assertRaises(ValueError):
- self.init.find_spec(name)
-
- def test_sys_modules_loader_is_None(self):
- name = 'some_mod'
- with util.uncache(name):
- module = types.ModuleType(name)
- spec = self.machinery.ModuleSpec(name, None)
- module.__spec__ = spec
- sys.modules[name] = module
- found = self.init.find_spec(name)
- self.assertEqual(found, spec)
-
- def test_sys_modules_spec_is_not_set(self):
- name = 'some_mod'
- with util.uncache(name):
- module = types.ModuleType(name)
- try:
- del module.__spec__
- except AttributeError:
- pass
- sys.modules[name] = module
- with self.assertRaises(ValueError):
- self.init.find_spec(name)
-
- def test_success(self):
- name = 'some_mod'
- with util.uncache(name):
- with util.import_state(meta_path=[self.FakeMetaFinder]):
- self.assertEqual((name, None, None),
- self.init.find_spec(name))
-
- def test_success_path(self):
- # Searching on a path should work.
- name = 'some_mod'
- path = 'path to some place'
- with util.uncache(name):
- with util.import_state(meta_path=[self.FakeMetaFinder]):
- self.assertEqual((name, path, None),
- self.init.find_spec(name, path))
-
- def test_nothing(self):
- # None is returned upon failure to find a loader.
- self.assertIsNone(self.init.find_spec('nevergoingtofindthismodule'))
-
- def test_find_submodule(self):
- name = 'spam'
- subname = 'ham'
- with temp_module(name, pkg=True) as pkg_dir:
- fullname, _ = submodule(name, subname, pkg_dir)
- spec = self.init.find_spec(fullname, [pkg_dir])
- self.assertIsNot(spec, None)
- self.assertNotIn(name, sorted(sys.modules))
- # Ensure successive calls behave the same.
- spec_again = self.init.find_spec(fullname, [pkg_dir])
- self.assertEqual(spec_again, spec)
-
- def test_find_submodule_missing_path(self):
- name = 'spam'
- subname = 'ham'
- with temp_module(name, pkg=True) as pkg_dir:
- fullname, _ = submodule(name, subname, pkg_dir)
- spec = self.init.find_spec(fullname)
- self.assertIs(spec, None)
- self.assertNotIn(name, sorted(sys.modules))
- # Ensure successive calls behave the same.
- spec = self.init.find_spec(fullname)
- self.assertIs(spec, None)
-
-
-class Frozen_FindSpecTests(FindSpecTests, unittest.TestCase):
- init = frozen_init
- machinery = frozen_machinery
-
-class Source_FindSpecTests(FindSpecTests, unittest.TestCase):
- init = source_init
- machinery = source_machinery
-
-
class ReloadTests:
"""Test module reloading for builtin and extension modules."""
@@ -484,8 +337,8 @@ class ReloadTests:
# See #19851.
name = 'spam'
subname = 'ham'
- with temp_module(name, pkg=True) as pkg_dir:
- fullname, _ = submodule(name, subname, pkg_dir)
+ with util.temp_module(name, pkg=True) as pkg_dir:
+ fullname, _ = util.submodule(name, subname, pkg_dir)
ham = self.init.import_module(fullname)
reloaded = self.init.reload(ham)
self.assertIs(reloaded, ham)
diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py
index b6fe86435b..b2823c6a78 100644
--- a/Lib/test/test_importlib/test_util.py
+++ b/Lib/test/test_importlib/test_util.py
@@ -1,5 +1,7 @@
from importlib import util
from . import util as test_util
+frozen_init, source_init = test_util.import_importlib('importlib')
+frozen_machinery, source_machinery = test_util.import_importlib('importlib.machinery')
frozen_util, source_util = test_util.import_importlib('importlib.util')
import os
@@ -310,6 +312,151 @@ Frozen_ResolveNameTests, Source_ResolveNameTests = test_util.test_both(
util=[frozen_util, source_util])
+class FindSpecTests:
+
+ class FakeMetaFinder:
+ @staticmethod
+ def find_spec(name, path=None, target=None): return name, path, target
+
+ def test_sys_modules(self):
+ name = 'some_mod'
+ with test_util.uncache(name):
+ module = types.ModuleType(name)
+ loader = 'a loader!'
+ spec = self.machinery.ModuleSpec(name, loader)
+ module.__loader__ = loader
+ module.__spec__ = spec
+ sys.modules[name] = module
+ found = self.util.find_spec(name)
+ self.assertEqual(found, spec)
+
+ def test_sys_modules_without___loader__(self):
+ name = 'some_mod'
+ with test_util.uncache(name):
+ module = types.ModuleType(name)
+ del module.__loader__
+ loader = 'a loader!'
+ spec = self.machinery.ModuleSpec(name, loader)
+ module.__spec__ = spec
+ sys.modules[name] = module
+ found = self.util.find_spec(name)
+ self.assertEqual(found, spec)
+
+ def test_sys_modules_spec_is_None(self):
+ name = 'some_mod'
+ with test_util.uncache(name):
+ module = types.ModuleType(name)
+ module.__spec__ = None
+ sys.modules[name] = module
+ with self.assertRaises(ValueError):
+ self.util.find_spec(name)
+
+ def test_sys_modules_loader_is_None(self):
+ name = 'some_mod'
+ with test_util.uncache(name):
+ module = types.ModuleType(name)
+ spec = self.machinery.ModuleSpec(name, None)
+ module.__spec__ = spec
+ sys.modules[name] = module
+ found = self.util.find_spec(name)
+ self.assertEqual(found, spec)
+
+ def test_sys_modules_spec_is_not_set(self):
+ name = 'some_mod'
+ with test_util.uncache(name):
+ module = types.ModuleType(name)
+ try:
+ del module.__spec__
+ except AttributeError:
+ pass
+ sys.modules[name] = module
+ with self.assertRaises(ValueError):
+ self.util.find_spec(name)
+
+ def test_success(self):
+ name = 'some_mod'
+ with test_util.uncache(name):
+ with test_util.import_state(meta_path=[self.FakeMetaFinder]):
+ self.assertEqual((name, None, None),
+ self.util.find_spec(name))
+
+# def test_success_path(self):
+# # Searching on a path should work.
+# name = 'some_mod'
+# path = 'path to some place'
+# with test_util.uncache(name):
+# with test_util.import_state(meta_path=[self.FakeMetaFinder]):
+# self.assertEqual((name, path, None),
+# self.util.find_spec(name, path))
+
+ def test_nothing(self):
+ # None is returned upon failure to find a loader.
+ self.assertIsNone(self.util.find_spec('nevergoingtofindthismodule'))
+
+ def test_find_submodule(self):
+ name = 'spam'
+ subname = 'ham'
+ with test_util.temp_module(name, pkg=True) as pkg_dir:
+ fullname, _ = test_util.submodule(name, subname, pkg_dir)
+ spec = self.util.find_spec(fullname)
+ self.assertIsNot(spec, None)
+ self.assertIn(name, sorted(sys.modules))
+ self.assertNotIn(fullname, sorted(sys.modules))
+ # Ensure successive calls behave the same.
+ spec_again = self.util.find_spec(fullname)
+ self.assertEqual(spec_again, spec)
+
+ def test_find_submodule_parent_already_imported(self):
+ name = 'spam'
+ subname = 'ham'
+ with test_util.temp_module(name, pkg=True) as pkg_dir:
+ self.init.import_module(name)
+ fullname, _ = test_util.submodule(name, subname, pkg_dir)
+ spec = self.util.find_spec(fullname)
+ self.assertIsNot(spec, None)
+ self.assertIn(name, sorted(sys.modules))
+ self.assertNotIn(fullname, sorted(sys.modules))
+ # Ensure successive calls behave the same.
+ spec_again = self.util.find_spec(fullname)
+ self.assertEqual(spec_again, spec)
+
+ def test_find_relative_module(self):
+ name = 'spam'
+ subname = 'ham'
+ with test_util.temp_module(name, pkg=True) as pkg_dir:
+ fullname, _ = test_util.submodule(name, subname, pkg_dir)
+ relname = '.' + subname
+ spec = self.util.find_spec(relname, name)
+ self.assertIsNot(spec, None)
+ self.assertIn(name, sorted(sys.modules))
+ self.assertNotIn(fullname, sorted(sys.modules))
+ # Ensure successive calls behave the same.
+ spec_again = self.util.find_spec(fullname)
+ self.assertEqual(spec_again, spec)
+
+ def test_find_relative_module_missing_package(self):
+ name = 'spam'
+ subname = 'ham'
+ with test_util.temp_module(name, pkg=True) as pkg_dir:
+ fullname, _ = test_util.submodule(name, subname, pkg_dir)
+ relname = '.' + subname
+ with self.assertRaises(ValueError):
+ self.util.find_spec(relname)
+ self.assertNotIn(name, sorted(sys.modules))
+ self.assertNotIn(fullname, sorted(sys.modules))
+
+
+class Frozen_FindSpecTests(FindSpecTests, unittest.TestCase):
+ init = frozen_init
+ machinery = frozen_machinery
+ util = frozen_util
+
+class Source_FindSpecTests(FindSpecTests, unittest.TestCase):
+ init = source_init
+ machinery = source_machinery
+ util = source_util
+
+
class MagicNumberTests:
def test_length(self):
diff --git a/Lib/test/test_importlib/util.py b/Lib/test/test_importlib/util.py
index a0dee6ebbc..885cec3b29 100644
--- a/Lib/test/test_importlib/util.py
+++ b/Lib/test/test_importlib/util.py
@@ -1,5 +1,5 @@
from contextlib import contextmanager
-from importlib import util
+from importlib import util, invalidate_caches
import os.path
from test import support
import unittest
@@ -46,6 +46,13 @@ def case_insensitive_tests(test):
"requires a case-insensitive filesystem")(test)
+def submodule(parent, name, pkg_dir, content=''):
+ path = os.path.join(pkg_dir, name + '.py')
+ with open(path, 'w') as subfile:
+ subfile.write(content)
+ return '{}.{}'.format(parent, name), path
+
+
@contextmanager
def uncache(*names):
"""Uncache a module from sys.modules.
@@ -71,6 +78,31 @@ def uncache(*names):
except KeyError:
pass
+
+@contextmanager
+def temp_module(name, content='', *, pkg=False):
+ conflicts = [n for n in sys.modules if n.partition('.')[0] == name]
+ with support.temp_cwd(None) as cwd:
+ with uncache(name, *conflicts):
+ with support.DirsOnSysPath(cwd):
+ invalidate_caches()
+
+ location = os.path.join(cwd, name)
+ if pkg:
+ modpath = os.path.join(location, '__init__.py')
+ os.mkdir(name)
+ else:
+ modpath = location + '.py'
+ if content is None:
+ # Make sure the module file gets created.
+ content = ''
+ if content is not None:
+ # not a namespace package
+ with open(modpath, 'w') as modfile:
+ modfile.write(content)
+ yield location
+
+
@contextmanager
def import_state(**kwargs):
"""Context manager to manage the various importers and stored state in the
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
index 1bfe7246f7..028eeb9caa 100644
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -1,21 +1,25 @@
-import re
-import sys
-import types
-import unittest
-import inspect
-import linecache
-import datetime
+import _testcapi
import collections
-import os
-import shutil
+import datetime
import functools
import importlib
+import inspect
+import io
+import linecache
+import os
from os.path import normcase
+import _pickle
+import re
+import shutil
+import sys
+import types
+import unicodedata
+import unittest
+
try:
from concurrent.futures import ThreadPoolExecutor
except ImportError:
ThreadPoolExecutor = None
-import _testcapi
from test.support import run_unittest, TESTFN, DirsOnSysPath
from test.support import MISSING_C_DOCSTRINGS
@@ -23,8 +27,6 @@ from test.script_helper import assert_python_ok, assert_python_failure
from test import inspect_fodder as mod
from test import inspect_fodder2 as mod2
-# C module for test_findsource_binary
-import unicodedata
# Functions tested in this suite:
# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
@@ -1582,23 +1584,30 @@ class TestSignatureObject(unittest.TestCase):
...))
def test_signature_on_unsupported_builtins(self):
- with self.assertRaisesRegex(ValueError, 'not supported by signature'):
- inspect.signature(type)
- with self.assertRaisesRegex(ValueError, 'not supported by signature'):
- # support for 'wrapper_descriptor'
- inspect.signature(type.__call__)
- with self.assertRaisesRegex(ValueError, 'not supported by signature'):
- # support for 'method-wrapper'
- inspect.signature(min.__call__)
+ with self.assertRaisesRegex(ValueError, 'no signature found'):
+ # min simply doesn't have a signature (yet)
+ inspect.signature(min)
@unittest.skipIf(MISSING_C_DOCSTRINGS,
"Signature information for builtins requires docstrings")
def test_signature_on_builtins(self):
- # min doesn't have a signature (yet)
- self.assertEqual(inspect.signature(min), None)
- signature = inspect.signature(_testcapi.docstring_with_signature_with_defaults)
- self.assertTrue(isinstance(signature, inspect.Signature))
+ def test_unbound_method(o):
+ """Use this to test unbound methods (things that should have a self)"""
+ signature = inspect.signature(o)
+ self.assertTrue(isinstance(signature, inspect.Signature))
+ self.assertEqual(list(signature.parameters.values())[0].name, 'self')
+ return signature
+
+ def test_callable(o):
+ """Use this to test bound methods or normal callables (things that don't expect self)"""
+ signature = inspect.signature(o)
+ self.assertTrue(isinstance(signature, inspect.Signature))
+ if signature.parameters:
+ self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
+ return signature
+
+ signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
def p(name): return signature.parameters[name].default
self.assertEqual(p('s'), 'avocado')
self.assertEqual(p('b'), b'bytes')
@@ -1611,6 +1620,41 @@ class TestSignatureObject(unittest.TestCase):
self.assertEqual(p('sys'), sys.maxsize)
self.assertEqual(p('exp'), sys.maxsize - 1)
+ test_callable(type)
+ test_callable(object)
+
+ # normal method
+ # (PyMethodDescr_Type, "method_descriptor")
+ test_unbound_method(_pickle.Pickler.dump)
+ d = _pickle.Pickler(io.StringIO())
+ test_callable(d.dump)
+
+ # static method
+ test_callable(str.maketrans)
+ test_callable('abc'.maketrans)
+
+ # class method
+ test_callable(dict.fromkeys)
+ test_callable({}.fromkeys)
+
+ # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
+ test_unbound_method(type.__call__)
+ test_unbound_method(int.__add__)
+ test_callable((3).__add__)
+
+ # _PyMethodWrapper_Type
+ # support for 'method-wrapper'
+ test_callable(min.__call__)
+
+ class ThisWorksNow:
+ __call__ = type
+ test_callable(ThisWorksNow())
+
+
+ def test_signature_on_builtins_no_signature(self):
+ with self.assertRaisesRegex(ValueError, 'no signature found for builtin'):
+ inspect.signature(_testcapi.docstring_no_signature)
+
def test_signature_on_non_function(self):
with self.assertRaisesRegex(TypeError, 'is not a callable object'):
inspect.signature(42)
@@ -1985,12 +2029,6 @@ class TestSignatureObject(unittest.TestCase):
((('a', ..., ..., "positional_or_keyword"),),
...))
- class ToFail:
- __call__ = type
- with self.assertRaisesRegex(ValueError, "not supported by signature"):
- inspect.signature(ToFail())
-
-
class Wrapped:
pass
Wrapped.__wrapped__ = lambda a: None
diff --git a/Lib/test/test_selectors.py b/Lib/test/test_selectors.py
index d306aef773..5e55eee069 100644
--- a/Lib/test/test_selectors.py
+++ b/Lib/test/test_selectors.py
@@ -5,7 +5,7 @@ import selectors
import signal
import socket
from test import support
-from time import sleep, perf_counter
+from time import sleep
import unittest
import unittest.mock
try:
@@ -363,21 +363,10 @@ class BaseSelectorTestCase(unittest.TestCase):
self.assertFalse(s.select(2))
self.assertLess(time() - t, 2.5)
- def test_timeout_rounding(self):
- # Issue #20311: Timeout must be rounded away from zero to wait *at
- # least* timeout seconds. For example, epoll_wait() has a resolution of
- # 1 ms (10^-3), epoll.select(0.0001) must wait 1 ms, not 0 ms.
+ def test_resolution(self):
s = self.SELECTOR()
- self.addCleanup(s.close)
-
- rd, wr = self.make_socketpair()
- s.register(rd, selectors.EVENT_READ)
-
- for timeout in (1e-2, 1e-3, 1e-4):
- t0 = perf_counter()
- s.select(timeout)
- dt = perf_counter() - t0
- self.assertGreaterEqual(dt, timeout)
+ self.assertIsInstance(s.resolution, (int, float))
+ self.assertGreater(s.resolution, 0.0)
class ScalableSelectorMixIn:
diff --git a/Lib/test/test_sundry.py b/Lib/test/test_sundry.py
index 2da3ac05dc..e99ca9ed37 100644
--- a/Lib/test/test_sundry.py
+++ b/Lib/test/test_sundry.py
@@ -6,7 +6,7 @@ import unittest
class TestUntestedModules(unittest.TestCase):
def test_untested_modules_can_be_imported(self):
- untested = ('bdb', 'encodings', 'formatter', 'imghdr',
+ untested = ('bdb', 'encodings', 'formatter',
'nturl2path', 'tabnanny')
with support.check_warnings(quiet=True):
for name in untested:
diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py
index 2d304d1cdd..d804f0f382 100644
--- a/Lib/test/test_tcl.py
+++ b/Lib/test/test_tcl.py
@@ -192,6 +192,45 @@ class TclTest(unittest.TestCase):
self.assertEqual(passValue((1, '2', (3.4,))),
(1, '2', (3.4,)) if self.wantobjects else '1 2 3.4')
+ def test_user_command(self):
+ result = None
+ def testfunc(arg):
+ nonlocal result
+ result = arg
+ return arg
+ self.interp.createcommand('testfunc', testfunc)
+ def check(value, expected, eq=self.assertEqual):
+ r = self.interp.call('testfunc', value)
+ self.assertIsInstance(result, str)
+ eq(result, expected)
+ self.assertIsInstance(r, str)
+ eq(r, expected)
+ def float_eq(actual, expected):
+ expected = float(expected)
+ self.assertAlmostEqual(float(actual), expected,
+ delta=abs(expected) * 1e-10)
+ def nan_eq(actual, expected):
+ actual = float(actual)
+ self.assertNotEqual(actual, actual)
+
+ check(True, '1')
+ check(False, '0')
+ check('string', 'string')
+ check('string\xbd', 'string\xbd')
+ check('string\u20ac', 'string\u20ac')
+ for i in (0, 1, -1, 2**31-1, -2**31):
+ check(i, str(i))
+ for f in (0.0, 1.0, -1.0):
+ check(f, repr(f))
+ for f in (1/3.0, sys.float_info.min, sys.float_info.max,
+ -sys.float_info.min, -sys.float_info.max):
+ check(f, f, eq=float_eq)
+ check(float('inf'), 'Inf', eq=float_eq)
+ check(-float('inf'), '-Inf', eq=float_eq)
+ check(float('nan'), 'NaN', eq=nan_eq)
+ check((), '')
+ check((1, (2,), (3, 4), '5 6', ()), '1 2 {3 4} {5 6} {}')
+
def test_splitlist(self):
splitlist = self.interp.tk.splitlist
call = self.interp.tk.call
diff --git a/Lib/test/test_telnetlib.py b/Lib/test/test_telnetlib.py
index 4f61e44d2c..ee1c35705b 100644
--- a/Lib/test/test_telnetlib.py
+++ b/Lib/test/test_telnetlib.py
@@ -116,6 +116,10 @@ class MockSelector(selectors.BaseSelector):
def __init__(self):
self.keys = {}
+ @property
+ def resolution(self):
+ return 1e-3
+
def register(self, fileobj, events, data=None):
key = selectors.SelectorKey(fileobj, 0, events, data)
self.keys[fileobj] = key
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index dc5c033739..8b76503429 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -112,11 +112,24 @@ def _check_signature(func, mock, skipfirst, instance=False):
def _copy_func_details(func, funcopy):
funcopy.__name__ = func.__name__
funcopy.__doc__ = func.__doc__
+ try:
+ funcopy.__text_signature__ = func.__text_signature__
+ except AttributeError:
+ pass
# we explicitly don't copy func.__dict__ into this copy as it would
# expose original attributes that should be mocked
- funcopy.__module__ = func.__module__
- funcopy.__defaults__ = func.__defaults__
- funcopy.__kwdefaults__ = func.__kwdefaults__
+ try:
+ funcopy.__module__ = func.__module__
+ except AttributeError:
+ pass
+ try:
+ funcopy.__defaults__ = func.__defaults__
+ except AttributeError:
+ pass
+ try:
+ funcopy.__kwdefaults__ = func.__kwdefaults__
+ except AttributeError:
+ pass
def _callable(obj):
diff --git a/Lib/wsgiref/__init__.py b/Lib/wsgiref/__init__.py
index 46c579f8ec..1efbba01a3 100644
--- a/Lib/wsgiref/__init__.py
+++ b/Lib/wsgiref/__init__.py
@@ -1,4 +1,4 @@
-"""wsgiref -- a WSGI (PEP 333) Reference Library
+"""wsgiref -- a WSGI (PEP 3333) Reference Library
Current Contents:
diff --git a/Lib/xml/etree/ElementInclude.py b/Lib/xml/etree/ElementInclude.py
index 73e491e5d9..963470e3b1 100644
--- a/Lib/xml/etree/ElementInclude.py
+++ b/Lib/xml/etree/ElementInclude.py
@@ -76,14 +76,13 @@ class FatalIncludeError(SyntaxError):
def default_loader(href, parse, encoding=None):
if parse == "xml":
- file = open(href, 'rb')
- data = ElementTree.parse(file).getroot()
+ with open(href, 'rb') as file:
+ data = ElementTree.parse(file).getroot()
else:
if not encoding:
encoding = 'UTF-8'
- file = open(href, 'r', encoding=encoding)
- data = file.read()
- file.close()
+ with open(href, 'r', encoding=encoding) as file:
+ data = file.read()
return data
##
diff --git a/Misc/ACKS b/Misc/ACKS
index b10fcc2b6b..12b5ab582f 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -725,6 +725,7 @@ Ronan Lamy
Torsten Landschoff
Åukasz Langa
Tino Lange
+Glenn Langford
Andrew Langmead
Detlef Lannert
Soren Larsen
diff --git a/Misc/NEWS b/Misc/NEWS
index 6d193d1426..31f206315c 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -2,14 +2,18 @@
Python News
+++++++++++
-What's New in Python 3.4.0 Release Candidate 1?
-===============================================
+What's New in Python 3.4.0 Beta 3?
+==================================
-Release date: 2014-01-19
+Release date: 2014-01-25
Core and Builtins
-----------------
+- Issue #20189: Four additional builtin types (PyTypeObject,
+ PyMethodDescr_Type, _PyMethodWrapper_Type, and PyWrapperDescr_Type)
+ have been modified to provide introspection information for builtins.
+
- Issue #17825: Cursor "^" is correctly positioned for SyntaxError and
IndentationError.
@@ -32,10 +36,33 @@ Core and Builtins
Library
-------
-- Issue #20311: selector.PollSelector.select() now rounds the timeout away from
- zero, instead of rounding towards zero. For example, a timeout of one
- microsecond is now rounded to one millisecond, instead of being rounded to
- zero.
+- Issue #20367: Fix behavior of concurrent.futures.as_completed() for
+ duplicate arguments. Patch by Glenn Langford.
+
+- Issue #8260: The read(), readline() and readlines() methods of
+ codecs.StreamReader returned incomplete data when were called after
+ readline() or read(size). Based on patch by Amaury Forgeot d'Arc.
+
+- Issue #20105: the codec exception chaining now correctly sets the
+ traceback of the original exception as its __traceback__ attribute.
+
+- asyncio: Various improvements and small changes not all covered by
+ issues listed below. E.g. wait_for() now cancels the inner task if
+ the timeout occcurs; tweaked the set of exported symbols; renamed
+ Empty/Full to QueueEmpty/QueueFull; "with (yield from lock)" now
+ uses a separate context manager; readexactly() raises if not enough
+ data was read; PTY support tweaks.
+
+- Issue #20311: asyncio: Add a granularity attribute to BaseEventLoop: maximum
+ between the resolution of the BaseEventLoop.time() method and the resolution
+ of the selector. The granuarility is used in the scheduler to round time and
+ deadline.
+
+- Issue #20311: selectors: Add a resolution attribute to BaseSelector.
+
+- Issue #20189: unittest.mock now no longer assumes that any object for
+ which it could get an inspect.Signature is a callable written in Python.
+ Fix courtesy of Michael Foord.
- Issue #20317: ExitStack.__exit__ could create a self-referential loop if an
exception raised by a cleanup operation already had its context set
@@ -43,9 +70,7 @@ Library
loop this caused is now avoided by checking if the expected context is
already set before trying to fix it.
-- Issue #20311: select.epoll.poll() now rounds the timeout away from zero,
- instead of rounding towards zero. For example, a timeout of one microsecond
- is now rounded to one millisecond, instead of being rounded to zero.
+- Issue #20374: Fix build with GNU readline >= 6.3.
- Issue #20262: Warnings are raised now when duplicate names are added in the
ZIP file or too long ZIP file comment is truncated.
@@ -118,20 +143,63 @@ Library
IDLE
----
---Issue #17390: Add Python version to Idle editor window title bar.
+- Issue #17390: Add Python version to Idle editor window title bar.
Original patches by Edmond Burnett and Kent Johnson.
-
+
- Issue #18960: IDLE now ignores the source encoding declaration on the second
line if the first line contains anything except a comment.
Tests
-----
+- Issue #19990: Added tests for the imghdr module. Based on patch by
+ Claudiu Popa.
+
+- Issue #20358: Tests for curses.window.overlay and curses.window.overwrite
+ no longer specify min{row,col} > max{row,col}.
+
+- Issue #19804: The test_find_mac test in test_uuid is now skipped if the
+ ifconfig executable is not available.
+
- Issue #19886: Use better estimated memory requirements for bigmem tests.
Tools/Demos
-----------
+- Issue #20390: Argument Clinic's "file" output preset now defaults to
+ "{dirname}/clinic/{basename}.h".
+
+- Issue #20390: Argument Clinic's "class" directive syntax has been extended
+ with two new required arguments: "typedef" and "type_object".
+
+- Issue #20390: Argument Clinic: If __new__ or __init__ functions didn't use
+ kwargs (or args), the PyArg_NoKeywords (or PyArg_NoPositional) calls
+ generated are only run when the type object is an exact match.
+
+- Issue #20390: Argument Clinic now fails if you have required parameters after
+ optional parameters.
+
+- Issue #20390: Argument Clinic converters now have a new template they can
+ inject code into: "modifiers". Code put there is run in the parsing
+ function after argument parsing but before the call to the impl.
+
+- Issue #20376: Argument Clinic now escapes backslashes in docstrings.
+
+- Issue #20381: Argument Clinic now sanity checks the default argument when
+ c_default is also specified, providing a nice failure message for
+ disallowed values.
+
+- Issue #20189: Argument Clinic now ensures that parser functions for
+ __new__ are always of type newfunc, the type of the tp_new slot.
+ Similarly, parser functions for __init__ are now always of type initproc,
+ the type of tp_init.
+
+- Issue #20189: Argument Clinic now suppresses the docstring for __new__
+ and __init__ functions if no docstring is provided in the input.
+
+- Issue #20189: Argument Clinic now suppresses the "self" parameter in the
+ impl for @staticmethod functions.
+
- Issue #20294: Argument Clinic now supports argument parsing for __new__ and
__init__ functions.
@@ -357,6 +425,9 @@ Library
- Issue #15475: Add __sizeof__ implementations for itertools objects.
+- Issue #19944: Fix importlib.find_spec() so it imports parents as needed
+ and move the function to importlib.util.
+
- Issue #19880: Fix a reference leak in unittest.TestCase. Explicitly break
reference cycles between frames and the _Outcome instance.
@@ -486,9 +557,6 @@ IDLE
Tests
-----
-- Issue #19804: The test_find_mac test in test_uuid is now skipped if the
- ifconfig executable is not available.
-
- Issue #20055: Fix test_shutil under Windows with symlink privileges held.
Patch by Vajrasky Kok.
diff --git a/Modules/_bz2module.c b/Modules/_bz2module.c
index fd05de0a27..2a0abe1b57 100644
--- a/Modules/_bz2module.c
+++ b/Modules/_bz2module.c
@@ -56,6 +56,8 @@ typedef struct {
#endif
} BZ2Decompressor;
+static PyTypeObject BZ2Compressor_Type;
+static PyTypeObject BZ2Decompressor_Type;
/* Helper functions. */
@@ -196,44 +198,58 @@ error:
return NULL;
}
-PyDoc_STRVAR(BZ2Compressor_compress__doc__,
-"compress(data) -> bytes\n"
-"\n"
-"Provide data to the compressor object. Returns a chunk of\n"
-"compressed data if possible, or b'' otherwise.\n"
-"\n"
-"When you have finished providing data to the compressor, call the\n"
-"flush() method to finish the compression process.\n");
+/*[clinic input]
+output preset file
+module _bz2
+class _bz2.BZ2Compressor "BZ2Compressor *" "&BZ2Compressor_Type"
+class _bz2.BZ2Decompressor "BZ2Decompressor *" "&BZ2Decompressor_Type"
+[clinic start generated code]*/
+/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
+
+#include "clinic/_bz2module.c.h"
+
+/*[clinic input]
+_bz2.BZ2Compressor.compress
+
+ data: Py_buffer
+ /
+
+Provide data to the compressor object.
+
+Returns a chunk of compressed data if possible, or b'' otherwise.
+
+When you have finished providing data to the compressor, call the
+flush() method to finish the compression process.
+[clinic start generated code]*/
static PyObject *
-BZ2Compressor_compress(BZ2Compressor *self, PyObject *args)
+_bz2_BZ2Compressor_compress_impl(BZ2Compressor *self, Py_buffer *data)
+/*[clinic end generated code: checksum=59365426e941fbcc4c7a4d0eef85ca7e19196eaa]*/
{
- Py_buffer buffer;
PyObject *result = NULL;
- if (!PyArg_ParseTuple(args, "y*:compress", &buffer))
- return NULL;
-
ACQUIRE_LOCK(self);
if (self->flushed)
PyErr_SetString(PyExc_ValueError, "Compressor has been flushed");
else
- result = compress(self, buffer.buf, buffer.len, BZ_RUN);
+ result = compress(self, data->buf, data->len, BZ_RUN);
RELEASE_LOCK(self);
- PyBuffer_Release(&buffer);
return result;
}
-PyDoc_STRVAR(BZ2Compressor_flush__doc__,
-"flush() -> bytes\n"
-"\n"
-"Finish the compression process. Returns the compressed data left\n"
-"in internal buffers.\n"
-"\n"
-"The compressor object may not be used after this method is called.\n");
+/*[clinic input]
+_bz2.BZ2Compressor.flush
+
+Finish the compression process.
+
+Returns the compressed data left in internal buffers.
+
+The compressor object may not be used after this method is called.
+[clinic start generated code]*/
static PyObject *
-BZ2Compressor_flush(BZ2Compressor *self, PyObject *noargs)
+_bz2_BZ2Compressor_flush_impl(BZ2Compressor *self)
+/*[clinic end generated code: checksum=3ef03fc1b092a701b382b97096c7fd50db87190b]*/
{
PyObject *result = NULL;
@@ -274,14 +290,24 @@ BZ2_Free(void* ctx, void *ptr)
PyMem_RawFree(ptr);
}
+/*[clinic input]
+_bz2.BZ2Compressor.__init__
+
+ compresslevel: int = 9
+ Compression level, as a number between 1 and 9.
+ /
+
+Create a compressor object for compressing data incrementally.
+
+For one-shot compression, use the compress() function instead.
+[clinic start generated code]*/
+
static int
-BZ2Compressor_init(BZ2Compressor *self, PyObject *args, PyObject *kwargs)
+_bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel)
+/*[clinic end generated code: checksum=c4e6adfd02963827075a1cc9309dc6df184b1246]*/
{
- int compresslevel = 9;
int bzerror;
- if (!PyArg_ParseTuple(args, "|i:BZ2Compressor", &compresslevel))
- return -1;
if (!(1 <= compresslevel && compresslevel <= 9)) {
PyErr_SetString(PyExc_ValueError,
"compresslevel must be between 1 and 9");
@@ -325,22 +351,12 @@ BZ2Compressor_dealloc(BZ2Compressor *self)
}
static PyMethodDef BZ2Compressor_methods[] = {
- {"compress", (PyCFunction)BZ2Compressor_compress, METH_VARARGS,
- BZ2Compressor_compress__doc__},
- {"flush", (PyCFunction)BZ2Compressor_flush, METH_NOARGS,
- BZ2Compressor_flush__doc__},
+ _BZ2_BZ2COMPRESSOR_COMPRESS_METHODDEF
+ _BZ2_BZ2COMPRESSOR_FLUSH_METHODDEF
{"__getstate__", (PyCFunction)BZ2Compressor_getstate, METH_NOARGS},
{NULL}
};
-PyDoc_STRVAR(BZ2Compressor__doc__,
-"BZ2Compressor(compresslevel=9)\n"
-"\n"
-"Create a compressor object for compressing data incrementally.\n"
-"\n"
-"compresslevel, if given, must be a number between 1 and 9.\n"
-"\n"
-"For one-shot compression, use the compress() function instead.\n");
static PyTypeObject BZ2Compressor_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
@@ -363,7 +379,7 @@ static PyTypeObject BZ2Compressor_Type = {
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
- BZ2Compressor__doc__, /* tp_doc */
+ _bz2_BZ2Compressor___init____doc__, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
@@ -378,7 +394,7 @@ static PyTypeObject BZ2Compressor_Type = {
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
- (initproc)BZ2Compressor_init, /* tp_init */
+ _bz2_BZ2Compressor___init__, /* tp_init */
0, /* tp_alloc */
PyType_GenericNew, /* tp_new */
};
@@ -451,32 +467,33 @@ error:
return NULL;
}
-PyDoc_STRVAR(BZ2Decompressor_decompress__doc__,
-"decompress(data) -> bytes\n"
-"\n"
-"Provide data to the decompressor object. Returns a chunk of\n"
-"decompressed data if possible, or b'' otherwise.\n"
-"\n"
-"Attempting to decompress data after the end of stream is reached\n"
-"raises an EOFError. Any data found after the end of the stream\n"
-"is ignored and saved in the unused_data attribute.\n");
+/*[clinic input]
+_bz2.BZ2Decompressor.decompress
+
+ data: Py_buffer
+ /
+
+Provide data to the decompressor object.
+
+Returns a chunk of decompressed data if possible, or b'' otherwise.
+
+Attempting to decompress data after the end of stream is reached
+raises an EOFError. Any data found after the end of the stream
+is ignored and saved in the unused_data attribute.
+[clinic start generated code]*/
static PyObject *
-BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *args)
+_bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data)
+/*[clinic end generated code: checksum=086e4b99e60cb3f67c0481959591eae0735320bc]*/
{
- Py_buffer buffer;
PyObject *result = NULL;
- if (!PyArg_ParseTuple(args, "y*:decompress", &buffer))
- return NULL;
-
ACQUIRE_LOCK(self);
if (self->eof)
PyErr_SetString(PyExc_EOFError, "End of stream already reached");
else
- result = decompress(self, buffer.buf, buffer.len);
+ result = decompress(self, data->buf, data->len);
RELEASE_LOCK(self);
- PyBuffer_Release(&buffer);
return result;
}
@@ -488,14 +505,20 @@ BZ2Decompressor_getstate(BZ2Decompressor *self, PyObject *noargs)
return NULL;
}
+/*[clinic input]
+_bz2.BZ2Decompressor.__init__
+
+Create a decompressor object for decompressing data incrementally.
+
+For one-shot decompression, use the decompress() function instead.
+[clinic start generated code]*/
+
static int
-BZ2Decompressor_init(BZ2Decompressor *self, PyObject *args, PyObject *kwargs)
+_bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self)
+/*[clinic end generated code: checksum=e4d2b9bb866ab8f1f4a8bb786ddb5b614ce323c0]*/
{
int bzerror;
- if (!PyArg_ParseTuple(args, ":BZ2Decompressor"))
- return -1;
-
#ifdef WITH_THREAD
self->lock = PyThread_allocate_lock();
if (self->lock == NULL) {
@@ -536,8 +559,7 @@ BZ2Decompressor_dealloc(BZ2Decompressor *self)
}
static PyMethodDef BZ2Decompressor_methods[] = {
- {"decompress", (PyCFunction)BZ2Decompressor_decompress, METH_VARARGS,
- BZ2Decompressor_decompress__doc__},
+ _BZ2_BZ2DECOMPRESSOR_DECOMPRESS_METHODDEF
{"__getstate__", (PyCFunction)BZ2Decompressor_getstate, METH_NOARGS},
{NULL}
};
@@ -556,13 +578,6 @@ static PyMemberDef BZ2Decompressor_members[] = {
{NULL}
};
-PyDoc_STRVAR(BZ2Decompressor__doc__,
-"BZ2Decompressor()\n"
-"\n"
-"Create a decompressor object for decompressing data incrementally.\n"
-"\n"
-"For one-shot decompression, use the decompress() function instead.\n");
-
static PyTypeObject BZ2Decompressor_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"_bz2.BZ2Decompressor", /* tp_name */
@@ -584,7 +599,7 @@ static PyTypeObject BZ2Decompressor_Type = {
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
- BZ2Decompressor__doc__, /* tp_doc */
+ _bz2_BZ2Decompressor___init____doc__, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
@@ -599,7 +614,7 @@ static PyTypeObject BZ2Decompressor_Type = {
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
- (initproc)BZ2Decompressor_init, /* tp_init */
+ _bz2_BZ2Decompressor___init__, /* tp_init */
0, /* tp_alloc */
PyType_GenericNew, /* tp_new */
};
diff --git a/Modules/_cryptmodule.c b/Modules/_cryptmodule.c
index af502cf5ec..9154babf5e 100644
--- a/Modules/_cryptmodule.c
+++ b/Modules/_cryptmodule.c
@@ -30,7 +30,7 @@ results for a given *word*.
[clinic start generated code]*/
PyDoc_STRVAR(crypt_crypt__doc__,
-"crypt(word, salt)\n"
+"crypt(module, word, salt)\n"
"Hash a *word* with the given *salt* and return the hashed password.\n"
"\n"
"*word* will usually be a user\'s password. *salt* (either a random 2 or 16\n"
@@ -63,7 +63,7 @@ exit:
static PyObject *
crypt_crypt_impl(PyModuleDef *module, const char *word, const char *salt)
-/*[clinic end generated code: checksum=a137540bf6862f9935fc112b8bb1d62d6dd1ad02]*/
+/*[clinic end generated code: checksum=dbfe26a21eb335abefe6a0bbd0a682ea22b9adc0]*/
{
/* On some platforms (AtheOS) crypt returns NULL for an invalid
salt. Return None in that case. XXX Maybe raise an exception? */
diff --git a/Modules/_ctypes/libffi/build-ios.sh b/Modules/_ctypes/libffi/build-ios.sh
index 3dea242255..3dea242255 100644..100755
--- a/Modules/_ctypes/libffi/build-ios.sh
+++ b/Modules/_ctypes/libffi/build-ios.sh
diff --git a/Modules/_ctypes/libffi/libtool-ldflags b/Modules/_ctypes/libffi/libtool-ldflags
index e32e37bf10..e32e37bf10 100644..100755
--- a/Modules/_ctypes/libffi/libtool-ldflags
+++ b/Modules/_ctypes/libffi/libtool-ldflags
diff --git a/Modules/_ctypes/libffi/msvcc.sh b/Modules/_ctypes/libffi/msvcc.sh
index dcdbeab16a..dcdbeab16a 100644..100755
--- a/Modules/_ctypes/libffi/msvcc.sh
+++ b/Modules/_ctypes/libffi/msvcc.sh
diff --git a/Modules/_ctypes/libffi/src/arm/gentramp.sh b/Modules/_ctypes/libffi/src/arm/gentramp.sh
index 74f0b867da..74f0b867da 100644..100755
--- a/Modules/_ctypes/libffi/src/arm/gentramp.sh
+++ b/Modules/_ctypes/libffi/src/arm/gentramp.sh
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index f81fabb09f..534dcff681 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -136,7 +136,7 @@ typedef chtype attr_t; /* No attr_t type is available */
/*[clinic input]
module curses
-class curses.window
+class curses.window "PyCursesWindowObject *" "&PyCursesWindow_Type"
[clinic start generated code]*/
/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
@@ -584,7 +584,7 @@ current settings for the window object.
[clinic start generated code]*/
PyDoc_STRVAR(curses_window_addch__doc__,
-"addch([x, y,] ch, [attr])\n"
+"addch(self, [x, y,] ch, [attr])\n"
"Paint character ch at (y, x) with attributes attr.\n"
"\n"
" x\n"
@@ -605,10 +605,10 @@ PyDoc_STRVAR(curses_window_addch__doc__,
{"addch", (PyCFunction)curses_window_addch, METH_VARARGS, curses_window_addch__doc__},
static PyObject *
-curses_window_addch_impl(PyObject *self, int group_left_1, int x, int y, PyObject *ch, int group_right_1, long attr);
+curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int x, int y, PyObject *ch, int group_right_1, long attr);
static PyObject *
-curses_window_addch(PyObject *self, PyObject *args)
+curses_window_addch(PyCursesWindowObject *self, PyObject *args)
{
PyObject *return_value = NULL;
int group_left_1 = 0;
@@ -650,8 +650,8 @@ exit:
}
static PyObject *
-curses_window_addch_impl(PyObject *self, int group_left_1, int x, int y, PyObject *ch, int group_right_1, long attr)
-/*[clinic end generated code: checksum=53d44d79791b30950972b3256bdd464f7426bf82]*/
+curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int x, int y, PyObject *ch, int group_right_1, long attr)
+/*[clinic end generated code: checksum=e1cdbd4f4e42fc6b36fd4755d7e4bd5b58751ea1]*/
{
PyCursesWindowObject *cwself = (PyCursesWindowObject *)self;
int coordinates_group = group_left_1;
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index 0ea225664f..b78725e3bb 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -18,7 +18,7 @@
/*[clinic input]
module datetime
-class datetime.datetime
+class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType"
[clinic start generated code]*/
/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
@@ -4159,7 +4159,7 @@ If no tz is specified, uses local timezone.
[clinic start generated code]*/
PyDoc_STRVAR(datetime_datetime_now__doc__,
-"now(tz=None)\n"
+"now(type, tz=None)\n"
"Returns new datetime object representing current time local to tz.\n"
"\n"
" tz\n"
@@ -4171,10 +4171,10 @@ PyDoc_STRVAR(datetime_datetime_now__doc__,
{"now", (PyCFunction)datetime_datetime_now, METH_VARARGS|METH_KEYWORDS|METH_CLASS, datetime_datetime_now__doc__},
static PyObject *
-datetime_datetime_now_impl(PyTypeObject *cls, PyObject *tz);
+datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz);
static PyObject *
-datetime_datetime_now(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
+datetime_datetime_now(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
PyObject *return_value = NULL;
static char *_keywords[] = {"tz", NULL};
@@ -4184,15 +4184,15 @@ datetime_datetime_now(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
"|O:now", _keywords,
&tz))
goto exit;
- return_value = datetime_datetime_now_impl(cls, tz);
+ return_value = datetime_datetime_now_impl(type, tz);
exit:
return return_value;
}
static PyObject *
-datetime_datetime_now_impl(PyTypeObject *cls, PyObject *tz)
-/*[clinic end generated code: checksum=ca3d26a423b3f633b260c7622e303f0915a96f7c]*/
+datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
+/*[clinic end generated code: checksum=a6d3ad2c0ab6389075289af3467f7b8eb13f5f5c]*/
{
PyObject *self;
@@ -4202,7 +4202,7 @@ datetime_datetime_now_impl(PyTypeObject *cls, PyObject *tz)
if (check_tzinfo_subclass(tz) < 0)
return NULL;
- self = datetime_best_possible((PyObject *)cls,
+ self = datetime_best_possible((PyObject *)type,
tz == Py_None ? localtime : gmtime,
tz);
if (self != NULL && tz != Py_None) {
diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c
index 24323aa0e3..88dae16560 100644
--- a/Modules/_dbmmodule.c
+++ b/Modules/_dbmmodule.c
@@ -30,7 +30,7 @@ static char *which_dbm = "Berkeley DB";
/*[clinic input]
module dbm
-class dbm.dbm
+class dbm.dbm "dbmobject *" "&Dbmtype"
[clinic start generated code]*/
/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
@@ -279,7 +279,7 @@ Return the value for key if present, otherwise default.
[clinic start generated code]*/
PyDoc_STRVAR(dbm_dbm_get__doc__,
-"get(key, [default])\n"
+"get(self, key, [default])\n"
"Return the value for key if present, otherwise default.");
#define DBM_DBM_GET_METHODDEF \
@@ -289,7 +289,7 @@ static PyObject *
dbm_dbm_get_impl(dbmobject *dp, const char *key, Py_ssize_clean_t key_length, int group_right_1, PyObject *default_value);
static PyObject *
-dbm_dbm_get(PyObject *self, PyObject *args)
+dbm_dbm_get(dbmobject *dp, PyObject *args)
{
PyObject *return_value = NULL;
const char *key;
@@ -311,7 +311,7 @@ dbm_dbm_get(PyObject *self, PyObject *args)
PyErr_SetString(PyExc_TypeError, "dbm.dbm.get requires 1 to 2 arguments");
goto exit;
}
- return_value = dbm_dbm_get_impl((dbmobject *)self, key, key_length, group_right_1, default_value);
+ return_value = dbm_dbm_get_impl(dp, key, key_length, group_right_1, default_value);
exit:
return return_value;
@@ -319,7 +319,7 @@ exit:
static PyObject *
dbm_dbm_get_impl(dbmobject *dp, const char *key, Py_ssize_clean_t key_length, int group_right_1, PyObject *default_value)
-/*[clinic end generated code: checksum=ca8bf63ec226e71d3cf390749777f7d5b7361478]*/
+/*[clinic end generated code: checksum=31d5180d6b36f1eafea78ec4391adf3559916379]*/
{
datum dbm_key, val;
@@ -462,7 +462,7 @@ Return a database object.
[clinic start generated code]*/
PyDoc_STRVAR(dbmopen__doc__,
-"open(filename, flags=\'r\', mode=0o666)\n"
+"open(module, filename, flags=\'r\', mode=0o666)\n"
"Return a database object.\n"
"\n"
" filename\n"
@@ -499,7 +499,7 @@ exit:
static PyObject *
dbmopen_impl(PyModuleDef *module, const char *filename, const char *flags, int mode)
-/*[clinic end generated code: checksum=fb265f75641553ccd963f84c143b35c11f9121fc]*/
+/*[clinic end generated code: checksum=9efae7d3c3b67a365011bf4e463e918901ba6c79]*/
{
int iflags;
diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c
index 1217ed4d1c..56a3942c76 100644
--- a/Modules/_lzmamodule.c
+++ b/Modules/_lzmamodule.c
@@ -298,36 +298,37 @@ parse_filter_spec_bcj(PyObject *spec)
return options;
}
-static void *
-parse_filter_spec(lzma_filter *f, PyObject *spec)
+static int
+lzma_filter_converter(PyObject *spec, void *ptr)
{
+ lzma_filter *f = (lzma_filter *)ptr;
PyObject *id_obj;
if (!PyMapping_Check(spec)) {
PyErr_SetString(PyExc_TypeError,
"Filter specifier must be a dict or dict-like object");
- return NULL;
+ return 0;
}
id_obj = PyMapping_GetItemString(spec, "id");
if (id_obj == NULL) {
if (PyErr_ExceptionMatches(PyExc_KeyError))
PyErr_SetString(PyExc_ValueError,
"Filter specifier must have an \"id\" entry");
- return NULL;
+ return 0;
}
f->id = PyLong_AsUnsignedLongLong(id_obj);
Py_DECREF(id_obj);
if (PyErr_Occurred())
- return NULL;
+ return 0;
switch (f->id) {
case LZMA_FILTER_LZMA1:
case LZMA_FILTER_LZMA2:
f->options = parse_filter_spec_lzma(spec);
- return f->options;
+ return f->options != NULL;
case LZMA_FILTER_DELTA:
f->options = parse_filter_spec_delta(spec);
- return f->options;
+ return f->options != NULL;
case LZMA_FILTER_X86:
case LZMA_FILTER_POWERPC:
case LZMA_FILTER_IA64:
@@ -335,10 +336,10 @@ parse_filter_spec(lzma_filter *f, PyObject *spec)
case LZMA_FILTER_ARMTHUMB:
case LZMA_FILTER_SPARC:
f->options = parse_filter_spec_bcj(spec);
- return f->options;
+ return f->options != NULL;
default:
PyErr_Format(PyExc_ValueError, "Invalid filter ID: %llu", f->id);
- return NULL;
+ return 0;
}
}
@@ -369,7 +370,7 @@ parse_filter_chain_spec(lzma_filter filters[], PyObject *filterspecs)
for (i = 0; i < num_filters; i++) {
int ok = 1;
PyObject *spec = PySequence_GetItem(filterspecs, i);
- if (spec == NULL || parse_filter_spec(&filters[i], spec) == NULL)
+ if (spec == NULL || !lzma_filter_converter(spec, &filters[i]))
ok = 0;
Py_XDECREF(spec);
if (!ok) {
@@ -468,6 +469,36 @@ error:
}
+/*[clinic input]
+output preset file
+module _lzma
+class _lzma.LZMACompressor "Compressor *" "&Compressor_type"
+class _lzma.LZMADecompressor "Decompressor *" "&Decompressor_type"
+[clinic start generated code]*/
+/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
+
+#include "clinic/_lzmamodule.c.h"
+
+/*[python input]
+
+class lzma_vli_converter(CConverter):
+ type = 'lzma_vli'
+ converter = 'lzma_vli_converter'
+
+class lzma_filter_converter(CConverter):
+ type = 'lzma_filter'
+ converter = 'lzma_filter_converter'
+ c_default = c_ignored_default = "{LZMA_VLI_UNKNOWN, NULL}"
+
+ def cleanup(self):
+ name = ensure_legal_c_identifier(self.name)
+ return ('if (%(name)s.id != LZMA_VLI_UNKNOWN)\n'
+ ' PyMem_Free(%(name)s.options);\n') % {'name': name}
+
+[python start generated code]*/
+/*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
+
+
/* LZMACompressor class. */
static PyObject *
@@ -512,44 +543,51 @@ error:
return NULL;
}
-PyDoc_STRVAR(Compressor_compress_doc,
-"compress(data) -> bytes\n"
-"\n"
-"Provide data to the compressor object. Returns a chunk of\n"
-"compressed data if possible, or b\"\" otherwise.\n"
-"\n"
-"When you have finished providing data to the compressor, call the\n"
-"flush() method to finish the conversion process.\n");
+/*[clinic input]
+_lzma.LZMACompressor.compress
+
+ self: self(type="Compressor *")
+ data: Py_buffer
+ /
+
+Provide data to the compressor object.
+
+Returns a chunk of compressed data if possible, or b'' otherwise.
+
+When you have finished providing data to the compressor, call the
+flush() method to finish the compression process.
+[clinic start generated code]*/
static PyObject *
-Compressor_compress(Compressor *self, PyObject *args)
+_lzma_LZMACompressor_compress_impl(Compressor *self, Py_buffer *data)
+/*[clinic end generated code: checksum=31f615136963e00f26f8be33440ec1e3604565ba]*/
{
- Py_buffer buffer;
PyObject *result = NULL;
- if (!PyArg_ParseTuple(args, "y*:compress", &buffer))
- return NULL;
-
ACQUIRE_LOCK(self);
if (self->flushed)
PyErr_SetString(PyExc_ValueError, "Compressor has been flushed");
else
- result = compress(self, buffer.buf, buffer.len, LZMA_RUN);
+ result = compress(self, data->buf, data->len, LZMA_RUN);
RELEASE_LOCK(self);
- PyBuffer_Release(&buffer);
return result;
}
-PyDoc_STRVAR(Compressor_flush_doc,
-"flush() -> bytes\n"
-"\n"
-"Finish the compression process. Returns the compressed data left\n"
-"in internal buffers.\n"
-"\n"
-"The compressor object cannot be used after this method is called.\n");
+/*[clinic input]
+_lzma.LZMACompressor.flush
+
+ self: self(type="Compressor *")
+
+Finish the compression process.
+
+Returns the compressed data left in internal buffers.
+
+The compressor object may not be used after this method is called.
+[clinic start generated code]*/
static PyObject *
-Compressor_flush(Compressor *self, PyObject *noargs)
+_lzma_LZMACompressor_flush_impl(Compressor *self)
+/*[clinic end generated code: checksum=fec21f3e22504f500606ba60e1ba70d79eb22188]*/
{
PyObject *result = NULL;
@@ -650,6 +688,39 @@ Compressor_init_raw(lzma_stream *lzs, PyObject *filterspecs)
return 0;
}
+/*[-clinic input]
+_lzma.LZMACompressor.__init__
+
+ self: self(type="Compressor *")
+ format: int(c_default="FORMAT_XZ") = FORMAT_XZ
+ The container format to use for the output. This can
+ be FORMAT_XZ (default), FORMAT_ALONE, or FORMAT_RAW.
+
+ check: int(c_default="-1") = unspecified
+ The integrity check to use. For FORMAT_XZ, the default
+ is CHECK_CRC64. FORMAT_ALONE and FORMAT_RAW do not suport integrity
+ checks; for these formats, check must be omitted, or be CHECK_NONE.
+
+ preset: object = None
+ If provided should be an integer in the range 0-9, optionally
+ OR-ed with the constant PRESET_EXTREME.
+
+ filters: object = None
+ If provided should be a sequence of dicts. Each dict should
+ have an entry for "id" indicating the ID of the filter, plus
+ additional entries for options to the filter.
+
+Create a compressor object for compressing data incrementally.
+
+The settings used by the compressor can be specified either as a
+preset compression level (with the 'preset' argument), or in detail
+as a custom filter chain (with the 'filters' argument). For FORMAT_XZ
+and FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset
+level. For FORMAT_RAW, the caller must always specify a filter chain;
+the raw compressor does not support preset compression levels.
+
+For one-shot compression, use the compress() function instead.
+[-clinic start generated code]*/
static int
Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs)
{
@@ -739,10 +810,8 @@ Compressor_dealloc(Compressor *self)
}
static PyMethodDef Compressor_methods[] = {
- {"compress", (PyCFunction)Compressor_compress, METH_VARARGS,
- Compressor_compress_doc},
- {"flush", (PyCFunction)Compressor_flush, METH_NOARGS,
- Compressor_flush_doc},
+ _LZMA_LZMACOMPRESSOR_COMPRESS_METHODDEF
+ _LZMA_LZMACOMPRESSOR_FLUSH_METHODDEF
{"__getstate__", (PyCFunction)Compressor_getstate, METH_NOARGS},
{NULL}
};
@@ -872,32 +941,34 @@ error:
return NULL;
}
-PyDoc_STRVAR(Decompressor_decompress_doc,
-"decompress(data) -> bytes\n"
-"\n"
-"Provide data to the decompressor object. Returns a chunk of\n"
-"decompressed data if possible, or b\"\" otherwise.\n"
-"\n"
-"Attempting to decompress data after the end of the stream is\n"
-"reached raises an EOFError. Any data found after the end of the\n"
-"stream is ignored, and saved in the unused_data attribute.\n");
+/*[clinic input]
+_lzma.LZMADecompressor.decompress
+
+ self: self(type="Decompressor *")
+ data: Py_buffer
+ /
+
+Provide data to the decompressor object.
+
+Returns a chunk of decompressed data if possible, or b'' otherwise.
+
+Attempting to decompress data after the end of stream is reached
+raises an EOFError. Any data found after the end of the stream
+is ignored and saved in the unused_data attribute.
+[clinic start generated code]*/
static PyObject *
-Decompressor_decompress(Decompressor *self, PyObject *args)
+_lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data)
+/*[clinic end generated code: checksum=d86e78da7ff0ff219d511275b16b79476da8922e]*/
{
- Py_buffer buffer;
PyObject *result = NULL;
- if (!PyArg_ParseTuple(args, "y*:decompress", &buffer))
- return NULL;
-
ACQUIRE_LOCK(self);
if (self->eof)
PyErr_SetString(PyExc_EOFError, "Already at end of stream");
else
- result = decompress(self, buffer.buf, buffer.len);
+ result = decompress(self, data->buf, data->len);
RELEASE_LOCK(self);
- PyBuffer_Release(&buffer);
return result;
}
@@ -925,38 +996,56 @@ Decompressor_init_raw(lzma_stream *lzs, PyObject *filterspecs)
return 0;
}
+/*[clinic input]
+_lzma.LZMADecompressor.__init__
+
+ self: self(type="Decompressor *")
+ format: int(c_default="FORMAT_AUTO") = FORMAT_AUTO
+ Specifies the container format of the input stream. If this is
+ FORMAT_AUTO (the default), the decompressor will automatically detect
+ whether the input is FORMAT_XZ or FORMAT_ALONE. Streams created with
+ FORMAT_RAW cannot be autodetected.
+
+ memlimit: object = None
+ Limit the amount of memory used by the decompressor. This will cause
+ decompression to fail if the input cannot be decompressed within the
+ given limit.
+
+ filters: object = None
+ A custom filter chain. This argument is required for FORMAT_RAW, and
+ not accepted with any other format. When provided, this should be a
+ sequence of dicts, each indicating the ID and options for a single
+ filter.
+
+Create a decompressor object for decompressing data incrementally.
+
+For one-shot decompression, use the decompress() function instead.
+[clinic start generated code]*/
+
static int
-Decompressor_init(Decompressor *self, PyObject *args, PyObject *kwargs)
+_lzma_LZMADecompressor___init___impl(Decompressor *self, int format, PyObject *memlimit, PyObject *filters)
+/*[clinic end generated code: checksum=9b119f6f2cc2d7a8e5be41c164a6c080ee82d0c2]*/
{
- static char *arg_names[] = {"format", "memlimit", "filters", NULL};
const uint32_t decoder_flags = LZMA_TELL_ANY_CHECK | LZMA_TELL_NO_CHECK;
- int format = FORMAT_AUTO;
- uint64_t memlimit = UINT64_MAX;
- PyObject *memlimit_obj = Py_None;
- PyObject *filterspecs = Py_None;
+ uint64_t memlimit_ = UINT64_MAX;
lzma_ret lzret;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs,
- "|iOO:LZMADecompressor", arg_names,
- &format, &memlimit_obj, &filterspecs))
- return -1;
-
- if (memlimit_obj != Py_None) {
+ if (memlimit != Py_None) {
if (format == FORMAT_RAW) {
PyErr_SetString(PyExc_ValueError,
"Cannot specify memory limit with FORMAT_RAW");
return -1;
}
- memlimit = PyLong_AsUnsignedLongLong(memlimit_obj);
+ memlimit_ = PyLong_AsUnsignedLongLong(memlimit);
if (PyErr_Occurred())
return -1;
}
- if (format == FORMAT_RAW && filterspecs == Py_None) {
+ if (format == FORMAT_RAW && filters == Py_None) {
PyErr_SetString(PyExc_ValueError,
"Must specify filters for FORMAT_RAW");
return -1;
- } else if (format != FORMAT_RAW && filterspecs != Py_None) {
+ } else if (format != FORMAT_RAW && filters != Py_None) {
PyErr_SetString(PyExc_ValueError,
"Cannot specify filters except with FORMAT_RAW");
return -1;
@@ -982,27 +1071,27 @@ Decompressor_init(Decompressor *self, PyObject *args, PyObject *kwargs)
switch (format) {
case FORMAT_AUTO:
- lzret = lzma_auto_decoder(&self->lzs, memlimit, decoder_flags);
+ lzret = lzma_auto_decoder(&self->lzs, memlimit_, decoder_flags);
if (catch_lzma_error(lzret))
break;
return 0;
case FORMAT_XZ:
- lzret = lzma_stream_decoder(&self->lzs, memlimit, decoder_flags);
+ lzret = lzma_stream_decoder(&self->lzs, memlimit_, decoder_flags);
if (catch_lzma_error(lzret))
break;
return 0;
case FORMAT_ALONE:
self->check = LZMA_CHECK_NONE;
- lzret = lzma_alone_decoder(&self->lzs, memlimit);
+ lzret = lzma_alone_decoder(&self->lzs, memlimit_);
if (catch_lzma_error(lzret))
break;
return 0;
case FORMAT_RAW:
self->check = LZMA_CHECK_NONE;
- if (Decompressor_init_raw(&self->lzs, filterspecs) == -1)
+ if (Decompressor_init_raw(&self->lzs, filters) == -1)
break;
return 0;
@@ -1034,8 +1123,7 @@ Decompressor_dealloc(Decompressor *self)
}
static PyMethodDef Decompressor_methods[] = {
- {"decompress", (PyCFunction)Decompressor_decompress, METH_VARARGS,
- Decompressor_decompress_doc},
+ _LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF
{"__getstate__", (PyCFunction)Decompressor_getstate, METH_NOARGS},
{NULL}
};
@@ -1059,27 +1147,6 @@ static PyMemberDef Decompressor_members[] = {
{NULL}
};
-PyDoc_STRVAR(Decompressor_doc,
-"LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None)\n"
-"\n"
-"Create a decompressor object for decompressing data incrementally.\n"
-"\n"
-"format specifies the container format of the input stream. If this is\n"
-"FORMAT_AUTO (the default), the decompressor will automatically detect\n"
-"whether the input is FORMAT_XZ or FORMAT_ALONE. Streams created with\n"
-"FORMAT_RAW cannot be autodetected.\n"
-"\n"
-"memlimit can be specified to limit the amount of memory used by the\n"
-"decompressor. This will cause decompression to fail if the input\n"
-"cannot be decompressed within the given limit.\n"
-"\n"
-"filters specifies a custom filter chain. This argument is required for\n"
-"FORMAT_RAW, and not accepted with any other format. When provided,\n"
-"this should be a sequence of dicts, each indicating the ID and options\n"
-"for a single filter.\n"
-"\n"
-"For one-shot decompression, use the decompress() function instead.\n");
-
static PyTypeObject Decompressor_type = {
PyVarObject_HEAD_INIT(NULL, 0)
"_lzma.LZMADecompressor", /* tp_name */
@@ -1101,7 +1168,7 @@ static PyTypeObject Decompressor_type = {
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
- Decompressor_doc, /* tp_doc */
+ _lzma_LZMADecompressor___init____doc__, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
@@ -1116,7 +1183,7 @@ static PyTypeObject Decompressor_type = {
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
- (initproc)Decompressor_init, /* tp_init */
+ _lzma_LZMADecompressor___init__, /* tp_init */
0, /* tp_alloc */
PyType_GenericNew, /* tp_new */
};
@@ -1124,48 +1191,42 @@ static PyTypeObject Decompressor_type = {
/* Module-level functions. */
-PyDoc_STRVAR(is_check_supported_doc,
-"is_check_supported(check_id) -> bool\n"
-"\n"
-"Test whether the given integrity check is supported.\n"
-"\n"
-"Always returns True for CHECK_NONE and CHECK_CRC32.\n");
+/*[clinic input]
+_lzma.is_check_supported
+ check_id: int
+ /
-static PyObject *
-is_check_supported(PyObject *self, PyObject *args)
-{
- int check_id;
+Test whether the given integrity check is supported.
- if (!PyArg_ParseTuple(args, "i:is_check_supported", &check_id))
- return NULL;
+Always returns True for CHECK_NONE and CHECK_CRC32.
+[clinic start generated code]*/
+static PyObject *
+_lzma_is_check_supported_impl(PyModuleDef *module, int check_id)
+/*[clinic end generated code: checksum=bb828e90e00ad96ed61f66719c2fca7fde637418]*/
+{
return PyBool_FromLong(lzma_check_is_supported(check_id));
}
-PyDoc_STRVAR(_encode_filter_properties_doc,
-"_encode_filter_properties(filter) -> bytes\n"
-"\n"
-"Return a bytes object encoding the options (properties) of the filter\n"
-"specified by *filter* (a dict).\n"
-"\n"
-"The result does not include the filter ID itself, only the options.\n");
+/*[clinic input]
+_lzma._encode_filter_properties
+ filter: lzma_filter(c_default="{LZMA_VLI_UNKNOWN, NULL}")
+ /
+
+Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).
+
+The result does not include the filter ID itself, only the options.
+[clinic start generated code]*/
static PyObject *
-_encode_filter_properties(PyObject *self, PyObject *args)
+_lzma__encode_filter_properties_impl(PyModuleDef *module, lzma_filter filter)
+/*[clinic end generated code: checksum=b5fe690acd6b61d1abfc32f522ada5bdcf9b13da]*/
{
- PyObject *filterspec;
- lzma_filter filter;
lzma_ret lzret;
uint32_t encoded_size;
PyObject *result = NULL;
- if (!PyArg_ParseTuple(args, "O:_encode_filter_properties", &filterspec))
- return NULL;
-
- if (parse_filter_spec(&filter, filterspec) == NULL)
- return NULL;
-
lzret = lzma_properties_size(&encoded_size, &filter);
if (catch_lzma_error(lzret))
goto error;
@@ -1179,37 +1240,36 @@ _encode_filter_properties(PyObject *self, PyObject *args)
if (catch_lzma_error(lzret))
goto error;
- PyMem_Free(filter.options);
return result;
error:
Py_XDECREF(result);
- PyMem_Free(filter.options);
return NULL;
}
-PyDoc_STRVAR(_decode_filter_properties_doc,
-"_decode_filter_properties(filter_id, encoded_props) -> dict\n"
-"\n"
-"Return a dict describing a filter with ID *filter_id*, and options\n"
-"(properties) decoded from the bytes object *encoded_props*.\n");
+/*[clinic input]
+_lzma._decode_filter_properties
+ filter_id: lzma_vli
+ encoded_props: Py_buffer
+ /
+
+Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).
+
+The result does not include the filter ID itself, only the options.
+[clinic start generated code]*/
static PyObject *
-_decode_filter_properties(PyObject *self, PyObject *args)
+_lzma__decode_filter_properties_impl(PyModuleDef *module, lzma_vli filter_id, Py_buffer *encoded_props)
+/*[clinic end generated code: checksum=235f7f5345d48744dcd21f781dafbbf05a717538]*/
{
- Py_buffer encoded_props;
lzma_filter filter;
lzma_ret lzret;
PyObject *result = NULL;
-
- if (!PyArg_ParseTuple(args, "O&y*:_decode_filter_properties",
- lzma_vli_converter, &filter.id, &encoded_props))
- return NULL;
+ filter.id = filter_id;
lzret = lzma_properties_decode(
- &filter, NULL, encoded_props.buf, encoded_props.len);
- PyBuffer_Release(&encoded_props);
+ &filter, NULL, encoded_props->buf, encoded_props->len);
if (catch_lzma_error(lzret))
return NULL;
@@ -1225,12 +1285,9 @@ _decode_filter_properties(PyObject *self, PyObject *args)
/* Module initialization. */
static PyMethodDef module_methods[] = {
- {"is_check_supported", (PyCFunction)is_check_supported,
- METH_VARARGS, is_check_supported_doc},
- {"_encode_filter_properties", (PyCFunction)_encode_filter_properties,
- METH_VARARGS, _encode_filter_properties_doc},
- {"_decode_filter_properties", (PyCFunction)_decode_filter_properties,
- METH_VARARGS, _decode_filter_properties_doc},
+ _LZMA_IS_CHECK_SUPPORTED_METHODDEF
+ _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF
+ _LZMA__DECODE_FILTER_PROPERTIES_METHODDEF
{NULL}
};
diff --git a/Modules/_lzmamodule.clinic.c b/Modules/_lzmamodule.clinic.c
new file mode 100644
index 0000000000..171354b91e
--- /dev/null
+++ b/Modules/_lzmamodule.clinic.c
@@ -0,0 +1,231 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(_lzma_LZMACompressor_compress__doc__,
+"compress(self, data)\n"
+"Provide data to the compressor object.\n"
+"\n"
+"Returns a chunk of compressed data if possible, or b\'\' otherwise.\n"
+"\n"
+"When you have finished providing data to the compressor, call the\n"
+"flush() method to finish the compression process.");
+
+#define _LZMA_LZMACOMPRESSOR_COMPRESS_METHODDEF \
+ {"compress", (PyCFunction)_lzma_LZMACompressor_compress, METH_VARARGS, _lzma_LZMACompressor_compress__doc__},
+
+static PyObject *
+_lzma_LZMACompressor_compress_impl(Compressor *self, Py_buffer *data);
+
+static PyObject *
+_lzma_LZMACompressor_compress(Compressor *self, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "y*:compress",
+ &data))
+ goto exit;
+ return_value = _lzma_LZMACompressor_compress_impl(self, &data);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(_lzma_LZMACompressor_flush__doc__,
+"flush(self)\n"
+"Finish the compression process.\n"
+"\n"
+"Returns the compressed data left in internal buffers.\n"
+"\n"
+"The compressor object may not be used after this method is called.");
+
+#define _LZMA_LZMACOMPRESSOR_FLUSH_METHODDEF \
+ {"flush", (PyCFunction)_lzma_LZMACompressor_flush, METH_NOARGS, _lzma_LZMACompressor_flush__doc__},
+
+static PyObject *
+_lzma_LZMACompressor_flush_impl(Compressor *self);
+
+static PyObject *
+_lzma_LZMACompressor_flush(Compressor *self, PyObject *Py_UNUSED(ignored))
+{
+ return _lzma_LZMACompressor_flush_impl(self);
+}
+
+PyDoc_STRVAR(_lzma_LZMADecompressor_decompress__doc__,
+"decompress(self, data)\n"
+"Provide data to the decompressor object.\n"
+"\n"
+"Returns a chunk of decompressed data if possible, or b\'\' otherwise.\n"
+"\n"
+"Attempting to decompress data after the end of stream is reached\n"
+"raises an EOFError. Any data found after the end of the stream\n"
+"is ignored and saved in the unused_data attribute.");
+
+#define _LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF \
+ {"decompress", (PyCFunction)_lzma_LZMADecompressor_decompress, METH_VARARGS, _lzma_LZMADecompressor_decompress__doc__},
+
+static PyObject *
+_lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data);
+
+static PyObject *
+_lzma_LZMADecompressor_decompress(Decompressor *self, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "y*:decompress",
+ &data))
+ goto exit;
+ return_value = _lzma_LZMADecompressor_decompress_impl(self, &data);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(_lzma_LZMADecompressor___init____doc__,
+"LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None)\n"
+"Create a decompressor object for decompressing data incrementally.\n"
+"\n"
+" format\n"
+" Specifies the container format of the input stream. If this is\n"
+" FORMAT_AUTO (the default), the decompressor will automatically detect\n"
+" whether the input is FORMAT_XZ or FORMAT_ALONE. Streams created with\n"
+" FORMAT_RAW cannot be autodetected.\n"
+" memlimit\n"
+" Limit the amount of memory used by the decompressor. This will cause\n"
+" decompression to fail if the input cannot be decompressed within the\n"
+" given limit.\n"
+" filters\n"
+" A custom filter chain. This argument is required for FORMAT_RAW, and\n"
+" not accepted with any other format. When provided, this should be a\n"
+" sequence of dicts, each indicating the ID and options for a single\n"
+" filter.\n"
+"\n"
+"For one-shot decompression, use the decompress() function instead.");
+
+static int
+_lzma_LZMADecompressor___init___impl(Decompressor *self, int format, PyObject *memlimit, PyObject *filters);
+
+static int
+_lzma_LZMADecompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ int return_value = -1;
+ static char *_keywords[] = {"format", "memlimit", "filters", NULL};
+ int format = FORMAT_AUTO;
+ PyObject *memlimit = Py_None;
+ PyObject *filters = Py_None;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "|iOO:LZMADecompressor", _keywords,
+ &format, &memlimit, &filters))
+ goto exit;
+ return_value = _lzma_LZMADecompressor___init___impl((Decompressor *)self, format, memlimit, filters);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_lzma_is_check_supported__doc__,
+"is_check_supported(module, check_id)\n"
+"Test whether the given integrity check is supported.\n"
+"\n"
+"Always returns True for CHECK_NONE and CHECK_CRC32.");
+
+#define _LZMA_IS_CHECK_SUPPORTED_METHODDEF \
+ {"is_check_supported", (PyCFunction)_lzma_is_check_supported, METH_VARARGS, _lzma_is_check_supported__doc__},
+
+static PyObject *
+_lzma_is_check_supported_impl(PyModuleDef *module, int check_id);
+
+static PyObject *
+_lzma_is_check_supported(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ int check_id;
+
+ if (!PyArg_ParseTuple(args,
+ "i:is_check_supported",
+ &check_id))
+ goto exit;
+ return_value = _lzma_is_check_supported_impl(module, check_id);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_lzma__encode_filter_properties__doc__,
+"_encode_filter_properties(module, filter)\n"
+"Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).\n"
+"\n"
+"The result does not include the filter ID itself, only the options.");
+
+#define _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF \
+ {"_encode_filter_properties", (PyCFunction)_lzma__encode_filter_properties, METH_VARARGS, _lzma__encode_filter_properties__doc__},
+
+static PyObject *
+_lzma__encode_filter_properties_impl(PyModuleDef *module, lzma_filter filter);
+
+static PyObject *
+_lzma__encode_filter_properties(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ lzma_filter filter = {LZMA_VLI_UNKNOWN, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "O&:_encode_filter_properties",
+ lzma_filter_converter, &filter))
+ goto exit;
+ return_value = _lzma__encode_filter_properties_impl(module, filter);
+
+exit:
+ /* Cleanup for filter */
+ if (filter.id != LZMA_VLI_UNKNOWN)
+ PyMem_Free(filter.options);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(_lzma__decode_filter_properties__doc__,
+"_decode_filter_properties(module, filter_id, encoded_props)\n"
+"Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).\n"
+"\n"
+"The result does not include the filter ID itself, only the options.");
+
+#define _LZMA__DECODE_FILTER_PROPERTIES_METHODDEF \
+ {"_decode_filter_properties", (PyCFunction)_lzma__decode_filter_properties, METH_VARARGS, _lzma__decode_filter_properties__doc__},
+
+static PyObject *
+_lzma__decode_filter_properties_impl(PyModuleDef *module, lzma_vli filter_id, Py_buffer *encoded_props);
+
+static PyObject *
+_lzma__decode_filter_properties(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ lzma_vli filter_id;
+ Py_buffer encoded_props = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "O&y*:_decode_filter_properties",
+ lzma_vli_converter, &filter_id, &encoded_props))
+ goto exit;
+ return_value = _lzma__decode_filter_properties_impl(module, filter_id, &encoded_props);
+
+exit:
+ /* Cleanup for encoded_props */
+ if (encoded_props.obj)
+ PyBuffer_Release(&encoded_props);
+
+ return return_value;
+}
+/*[clinic end generated code: checksum=b4b90dcbd0c9c349c3a94e26a7eecf71aab179a0]*/
diff --git a/Modules/_opcode.c b/Modules/_opcode.c
index 633c4f806c..a5c546e064 100644
--- a/Modules/_opcode.c
+++ b/Modules/_opcode.c
@@ -21,7 +21,7 @@ Compute the stack effect of the opcode.
[clinic start generated code]*/
PyDoc_STRVAR(_opcode_stack_effect__doc__,
-"stack_effect(opcode, [oparg])\n"
+"stack_effect(module, opcode, [oparg])\n"
"Compute the stack effect of the opcode.");
#define _OPCODE_STACK_EFFECT_METHODDEF \
@@ -64,7 +64,7 @@ exit:
static int
_opcode_stack_effect_impl(PyModuleDef *module, int opcode, int group_right_1, int oparg)
-/*[clinic end generated code: checksum=58fb4f1b174fc92f783dc945ca712fb752a6c283]*/
+/*[clinic end generated code: checksum=4689140ffda2494a123ea2593fb63445fb039774]*/
{
int effect;
if (HAS_ARG(opcode)) {
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
index 35e372c45a..54a5ec544d 100644
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -6,28 +6,13 @@ PyDoc_STRVAR(pickle_module_doc,
/*[clinic input]
module _pickle
-class _pickle.Pickler
-class _pickle.PicklerMemoProxy
-class _pickle.Unpickler
-class _pickle.UnpicklerMemoProxy
+class _pickle.Pickler "PicklerObject *" "&Pickler_Type"
+class _pickle.PicklerMemoProxy "PicklerMemoProxyObject *" "&PicklerMemoProxyType"
+class _pickle.Unpickler "UnpicklerObject *" "&Unpickler_Type"
+class _pickle.UnpicklerMemoProxy "UnpicklerMemoProxyObject *" "&UnpicklerMemoProxyType"
[clinic start generated code]*/
/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
-/*[python input]
-class PicklerObject_converter(self_converter):
- type = "PicklerObject *"
-
-class PicklerMemoProxyObject_converter(self_converter):
- type = "PicklerMemoProxyObject *"
-
-class UnpicklerObject_converter(self_converter):
- type = "UnpicklerObject *"
-
-class UnpicklerMemoProxyObject_converter(self_converter):
- type = "UnpicklerMemoProxyObject *"
-[python start generated code]*/
-/*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
-
/* Bump this when new opcodes are added to the pickle protocol. */
enum {
HIGHEST_PROTOCOL = 4,
@@ -3878,8 +3863,6 @@ dump(PicklerObject *self, PyObject *obj)
_pickle.Pickler.clear_memo
- self: PicklerObject
-
Clears the pickler's "memo".
The memo is the data structure that remembers which objects the
@@ -3889,7 +3872,7 @@ re-using picklers.
[clinic start generated code]*/
PyDoc_STRVAR(_pickle_Pickler_clear_memo__doc__,
-"clear_memo()\n"
+"clear_memo(self)\n"
"Clears the pickler\'s \"memo\".\n"
"\n"
"The memo is the data structure that remembers which objects the\n"
@@ -3904,14 +3887,14 @@ static PyObject *
_pickle_Pickler_clear_memo_impl(PicklerObject *self);
static PyObject *
-_pickle_Pickler_clear_memo(PyObject *self, PyObject *Py_UNUSED(ignored))
+_pickle_Pickler_clear_memo(PicklerObject *self, PyObject *Py_UNUSED(ignored))
{
- return _pickle_Pickler_clear_memo_impl((PicklerObject *)self);
+ return _pickle_Pickler_clear_memo_impl(self);
}
static PyObject *
_pickle_Pickler_clear_memo_impl(PicklerObject *self)
-/*[clinic end generated code: checksum=015cc3c5befea86cb08b9396938477bebbea4157]*/
+/*[clinic end generated code: checksum=17b1165d8dcae5a2e90b1703bf5cbbfc26114c5a]*/
{
if (self->memo)
PyMemoTable_Clear(self->memo);
@@ -3923,7 +3906,6 @@ _pickle_Pickler_clear_memo_impl(PicklerObject *self)
_pickle.Pickler.dump
- self: PicklerObject
obj: object
/
@@ -3931,7 +3913,7 @@ Write a pickled representation of the given object to the open file.
[clinic start generated code]*/
PyDoc_STRVAR(_pickle_Pickler_dump__doc__,
-"dump(obj)\n"
+"dump(self, obj)\n"
"Write a pickled representation of the given object to the open file.");
#define _PICKLE_PICKLER_DUMP_METHODDEF \
@@ -3939,7 +3921,7 @@ PyDoc_STRVAR(_pickle_Pickler_dump__doc__,
static PyObject *
_pickle_Pickler_dump(PicklerObject *self, PyObject *obj)
-/*[clinic end generated code: checksum=b72a69ec98737fabf66dae7c5a3210178bdbd3e6]*/
+/*[clinic end generated code: checksum=36db7f67c8bc05ca6f17b8ab57c54d64bfd0539e]*/
{
/* Check whether the Pickler was initialized correctly (issue3664).
Developers often forget to call __init__() in their subclasses, which
@@ -4018,7 +4000,6 @@ Pickler_clear(PicklerObject *self)
_pickle.Pickler.__init__
- self: PicklerObject
file: object
protocol: object = NULL
fix_imports: bool = True
@@ -4077,7 +4058,7 @@ _pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs)
int fix_imports = 1;
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
- "O|Op:__init__", _keywords,
+ "O|Op:Pickler", _keywords,
&file, &protocol, &fix_imports))
goto exit;
return_value = _pickle_Pickler___init___impl((PicklerObject *)self, file, protocol, fix_imports);
@@ -4088,7 +4069,7 @@ exit:
static int
_pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *protocol, int fix_imports)
-/*[clinic end generated code: checksum=d10dfb463511430b4faad9fca07627041a35b96e]*/
+/*[clinic end generated code: checksum=b055bf46cfb5b92c1863302d075246a68bd89153]*/
{
_Py_IDENTIFIER(persistent_id);
_Py_IDENTIFIER(dispatch_table);
@@ -4158,13 +4139,11 @@ typedef struct {
/*[clinic input]
_pickle.PicklerMemoProxy.clear
- self: PicklerMemoProxyObject
-
Remove all items from memo.
[clinic start generated code]*/
PyDoc_STRVAR(_pickle_PicklerMemoProxy_clear__doc__,
-"clear()\n"
+"clear(self)\n"
"Remove all items from memo.");
#define _PICKLE_PICKLERMEMOPROXY_CLEAR_METHODDEF \
@@ -4174,14 +4153,14 @@ static PyObject *
_pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self);
static PyObject *
-_pickle_PicklerMemoProxy_clear(PyObject *self, PyObject *Py_UNUSED(ignored))
+_pickle_PicklerMemoProxy_clear(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
{
- return _pickle_PicklerMemoProxy_clear_impl((PicklerMemoProxyObject *)self);
+ return _pickle_PicklerMemoProxy_clear_impl(self);
}
static PyObject *
_pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self)
-/*[clinic end generated code: checksum=bf8dd8c8688d0c0f7a2e59a804c47375b740f2f0]*/
+/*[clinic end generated code: checksum=fb4a5ba40918b3eccc9bc1e9d6875cb2737127a9]*/
{
if (self->pickler->memo)
PyMemoTable_Clear(self->pickler->memo);
@@ -4191,13 +4170,11 @@ _pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self)
/*[clinic input]
_pickle.PicklerMemoProxy.copy
- self: PicklerMemoProxyObject
-
Copy the memo to a new object.
[clinic start generated code]*/
PyDoc_STRVAR(_pickle_PicklerMemoProxy_copy__doc__,
-"copy()\n"
+"copy(self)\n"
"Copy the memo to a new object.");
#define _PICKLE_PICKLERMEMOPROXY_COPY_METHODDEF \
@@ -4207,14 +4184,14 @@ static PyObject *
_pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self);
static PyObject *
-_pickle_PicklerMemoProxy_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
+_pickle_PicklerMemoProxy_copy(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
{
- return _pickle_PicklerMemoProxy_copy_impl((PicklerMemoProxyObject *)self);
+ return _pickle_PicklerMemoProxy_copy_impl(self);
}
static PyObject *
_pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self)
-/*[clinic end generated code: checksum=72d46879dc658adbd3d28b5c82dd8dcfa6b9b124]*/
+/*[clinic end generated code: checksum=3d27d3005725f1828c9a92a38197811c54c64abb]*/
{
Py_ssize_t i;
PyMemoTable *memo;
@@ -4254,13 +4231,11 @@ _pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self)
/*[clinic input]
_pickle.PicklerMemoProxy.__reduce__
- self: PicklerMemoProxyObject
-
Implement pickle support.
[clinic start generated code]*/
PyDoc_STRVAR(_pickle_PicklerMemoProxy___reduce____doc__,
-"__reduce__()\n"
+"__reduce__(self)\n"
"Implement pickle support.");
#define _PICKLE_PICKLERMEMOPROXY___REDUCE___METHODDEF \
@@ -4270,14 +4245,14 @@ static PyObject *
_pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self);
static PyObject *
-_pickle_PicklerMemoProxy___reduce__(PyObject *self, PyObject *Py_UNUSED(ignored))
+_pickle_PicklerMemoProxy___reduce__(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
{
- return _pickle_PicklerMemoProxy___reduce___impl((PicklerMemoProxyObject *)self);
+ return _pickle_PicklerMemoProxy___reduce___impl(self);
}
static PyObject *
_pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self)
-/*[clinic end generated code: checksum=aad71c4d81d1ed8bf0d32362dd80a29b9f3b0d03]*/
+/*[clinic end generated code: checksum=2682cf8a3a5027def6328419001b086b047d47c8]*/
{
PyObject *reduce_value, *dict_args;
PyObject *contents = _pickle_PicklerMemoProxy_copy_impl(self);
@@ -6174,7 +6149,7 @@ static PyObject *
load(UnpicklerObject *self)
{
PyObject *value = NULL;
- char *s;
+ char *s = NULL;
self->num_marks = 0;
self->proto = 0;
@@ -6299,7 +6274,7 @@ specified therein.
[clinic start generated code]*/
PyDoc_STRVAR(_pickle_Unpickler_load__doc__,
-"load()\n"
+"load(self)\n"
"Load a pickle.\n"
"\n"
"Read a pickled object representation from the open file object given\n"
@@ -6310,17 +6285,17 @@ PyDoc_STRVAR(_pickle_Unpickler_load__doc__,
{"load", (PyCFunction)_pickle_Unpickler_load, METH_NOARGS, _pickle_Unpickler_load__doc__},
static PyObject *
-_pickle_Unpickler_load_impl(PyObject *self);
+_pickle_Unpickler_load_impl(UnpicklerObject *self);
static PyObject *
-_pickle_Unpickler_load(PyObject *self, PyObject *Py_UNUSED(ignored))
+_pickle_Unpickler_load(UnpicklerObject *self, PyObject *Py_UNUSED(ignored))
{
return _pickle_Unpickler_load_impl(self);
}
static PyObject *
-_pickle_Unpickler_load_impl(PyObject *self)
-/*[clinic end generated code: checksum=9477099fe6a90748c13ff1a6dd92ba7ab7a89602]*/
+_pickle_Unpickler_load_impl(UnpicklerObject *self)
+/*[clinic end generated code: checksum=5ccece694e9898856d916e0a87f0133d4537ebb9]*/
{
UnpicklerObject *unpickler = (UnpicklerObject*)self;
@@ -6347,7 +6322,6 @@ _pickle_Unpickler_load_impl(PyObject *self)
_pickle.Unpickler.find_class
- self: UnpicklerObject
module_name: object
global_name: object
/
@@ -6363,7 +6337,7 @@ needed. Both arguments passed are str objects.
[clinic start generated code]*/
PyDoc_STRVAR(_pickle_Unpickler_find_class__doc__,
-"find_class(module_name, global_name)\n"
+"find_class(self, module_name, global_name)\n"
"Return an object from a specified module.\n"
"\n"
"If necessary, the module will be imported. Subclasses may override\n"
@@ -6380,7 +6354,7 @@ static PyObject *
_pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyObject *module_name, PyObject *global_name);
static PyObject *
-_pickle_Unpickler_find_class(PyObject *self, PyObject *args)
+_pickle_Unpickler_find_class(UnpicklerObject *self, PyObject *args)
{
PyObject *return_value = NULL;
PyObject *module_name;
@@ -6390,7 +6364,7 @@ _pickle_Unpickler_find_class(PyObject *self, PyObject *args)
2, 2,
&module_name, &global_name))
goto exit;
- return_value = _pickle_Unpickler_find_class_impl((UnpicklerObject *)self, module_name, global_name);
+ return_value = _pickle_Unpickler_find_class_impl(self, module_name, global_name);
exit:
return return_value;
@@ -6398,7 +6372,7 @@ exit:
static PyObject *
_pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyObject *module_name, PyObject *global_name)
-/*[clinic end generated code: checksum=15ed4836fd5860425fff9ea7855d4f1f4413c170]*/
+/*[clinic end generated code: checksum=2b8d5398787c8ac7ea5d45f644433169e441003b]*/
{
PyObject *global;
PyObject *modules_dict;
@@ -6551,7 +6525,6 @@ Unpickler_clear(UnpicklerObject *self)
_pickle.Unpickler.__init__
- self: UnpicklerObject
file: object
*
fix_imports: bool = True
@@ -6617,7 +6590,7 @@ _pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs)
const char *errors = "strict";
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
- "O|$pss:__init__", _keywords,
+ "O|$pss:Unpickler", _keywords,
&file, &fix_imports, &encoding, &errors))
goto exit;
return_value = _pickle_Unpickler___init___impl((UnpicklerObject *)self, file, fix_imports, encoding, errors);
@@ -6628,7 +6601,7 @@ exit:
static int
_pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_imports, const char *encoding, const char *errors)
-/*[clinic end generated code: checksum=eb1a2cfc7b6f97c33980cff3d3b97d184a382f02]*/
+/*[clinic end generated code: checksum=a8a9dde29eb4ddd538b45099408ea77e01940692]*/
{
_Py_IDENTIFIER(persistent_load);
@@ -6692,13 +6665,11 @@ typedef struct {
/*[clinic input]
_pickle.UnpicklerMemoProxy.clear
- self: UnpicklerMemoProxyObject
-
Remove all items from memo.
[clinic start generated code]*/
PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_clear__doc__,
-"clear()\n"
+"clear(self)\n"
"Remove all items from memo.");
#define _PICKLE_UNPICKLERMEMOPROXY_CLEAR_METHODDEF \
@@ -6708,14 +6679,14 @@ static PyObject *
_pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self);
static PyObject *
-_pickle_UnpicklerMemoProxy_clear(PyObject *self, PyObject *Py_UNUSED(ignored))
+_pickle_UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
{
- return _pickle_UnpicklerMemoProxy_clear_impl((UnpicklerMemoProxyObject *)self);
+ return _pickle_UnpicklerMemoProxy_clear_impl(self);
}
static PyObject *
_pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self)
-/*[clinic end generated code: checksum=07adecee2181e5e268b2ff184360b1d88ad947f2]*/
+/*[clinic end generated code: checksum=32f6ee47e44405dd587f768f3690d47947bb5a8e]*/
{
_Unpickler_MemoCleanup(self->unpickler);
self->unpickler->memo = _Unpickler_NewMemo(self->unpickler->memo_size);
@@ -6727,13 +6698,11 @@ _pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self)
/*[clinic input]
_pickle.UnpicklerMemoProxy.copy
- self: UnpicklerMemoProxyObject
-
Copy the memo to a new object.
[clinic start generated code]*/
PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_copy__doc__,
-"copy()\n"
+"copy(self)\n"
"Copy the memo to a new object.");
#define _PICKLE_UNPICKLERMEMOPROXY_COPY_METHODDEF \
@@ -6743,14 +6712,14 @@ static PyObject *
_pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self);
static PyObject *
-_pickle_UnpicklerMemoProxy_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
+_pickle_UnpicklerMemoProxy_copy(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
{
- return _pickle_UnpicklerMemoProxy_copy_impl((UnpicklerMemoProxyObject *)self);
+ return _pickle_UnpicklerMemoProxy_copy_impl(self);
}
static PyObject *
_pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self)
-/*[clinic end generated code: checksum=47b9f0cc12c5a54004252e1b4916822cdfa8a881]*/
+/*[clinic end generated code: checksum=ac3da80efc3b2548aa8b5c5358d0e82e615fce1d]*/
{
Py_ssize_t i;
PyObject *new_memo = PyDict_New();
@@ -6783,13 +6752,11 @@ error:
/*[clinic input]
_pickle.UnpicklerMemoProxy.__reduce__
- self: UnpicklerMemoProxyObject
-
Implement pickling support.
[clinic start generated code]*/
PyDoc_STRVAR(_pickle_UnpicklerMemoProxy___reduce____doc__,
-"__reduce__()\n"
+"__reduce__(self)\n"
"Implement pickling support.");
#define _PICKLE_UNPICKLERMEMOPROXY___REDUCE___METHODDEF \
@@ -6799,14 +6766,14 @@ static PyObject *
_pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self);
static PyObject *
-_pickle_UnpicklerMemoProxy___reduce__(PyObject *self, PyObject *Py_UNUSED(ignored))
+_pickle_UnpicklerMemoProxy___reduce__(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
{
- return _pickle_UnpicklerMemoProxy___reduce___impl((UnpicklerMemoProxyObject *)self);
+ return _pickle_UnpicklerMemoProxy___reduce___impl(self);
}
static PyObject *
_pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self)
-/*[clinic end generated code: checksum=2f061bb9ecd9ee8500184c135148a131c46a3b88]*/
+/*[clinic end generated code: checksum=2373102b7c87d99ba4c4a56b6813d2c84dd61865]*/
{
PyObject *reduce_value;
PyObject *constructor_args;
@@ -7115,7 +7082,7 @@ to map the new Python 3 names to the old module names used in Python
[clinic start generated code]*/
PyDoc_STRVAR(_pickle_dump__doc__,
-"dump(obj, file, protocol=None, *, fix_imports=True)\n"
+"dump(module, obj, file, protocol=None, *, fix_imports=True)\n"
"Write a pickled representation of obj to the open file object file.\n"
"\n"
"This is equivalent to ``Pickler(file, protocol).dump(obj)``, but may\n"
@@ -7166,7 +7133,7 @@ exit:
static PyObject *
_pickle_dump_impl(PyModuleDef *module, PyObject *obj, PyObject *file, PyObject *protocol, int fix_imports)
-/*[clinic end generated code: checksum=eb5c23e64da34477178230b704d2cc9c6b6650ea]*/
+/*[clinic end generated code: checksum=1d4ff873e13eb840ff275d716d8d4c5554af087c]*/
{
PicklerObject *pickler = _Pickler_New();
@@ -7218,7 +7185,7 @@ Python 2, so that the pickle data stream is readable with Python 2.
[clinic start generated code]*/
PyDoc_STRVAR(_pickle_dumps__doc__,
-"dumps(obj, protocol=None, *, fix_imports=True)\n"
+"dumps(module, obj, protocol=None, *, fix_imports=True)\n"
"Return the pickled representation of the object as a bytes object.\n"
"\n"
"The optional *protocol* argument tells the pickler to use the given\n"
@@ -7260,7 +7227,7 @@ exit:
static PyObject *
_pickle_dumps_impl(PyModuleDef *module, PyObject *obj, PyObject *protocol, int fix_imports)
-/*[clinic end generated code: checksum=e9b915d61202a9692cb6c6718db74fe54fc9c4d1]*/
+/*[clinic end generated code: checksum=9c6c0291ef2d2b0856b7d4caecdcb7bad13a23b3]*/
{
PyObject *result;
PicklerObject *pickler = _Pickler_New();
@@ -7319,7 +7286,7 @@ string instances as bytes objects.
[clinic start generated code]*/
PyDoc_STRVAR(_pickle_load__doc__,
-"load(file, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n"
+"load(module, file, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n"
"Read and return an object from the pickle data stored in a file.\n"
"\n"
"This is equivalent to ``Unpickler(file).load()``, but may be more\n"
@@ -7372,7 +7339,7 @@ exit:
static PyObject *
_pickle_load_impl(PyModuleDef *module, PyObject *file, int fix_imports, const char *encoding, const char *errors)
-/*[clinic end generated code: checksum=b41f06970e57acf2fd602e4b7f88e3f3e1e53087]*/
+/*[clinic end generated code: checksum=2b5b7e5e3a836cf1c53377ce9274a84a8bceef67]*/
{
PyObject *result;
UnpicklerObject *unpickler = _Unpickler_New();
@@ -7424,7 +7391,7 @@ string instances as bytes objects.
[clinic start generated code]*/
PyDoc_STRVAR(_pickle_loads__doc__,
-"loads(data, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n"
+"loads(module, data, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n"
"Read and return an object from the given pickle data.\n"
"\n"
"The protocol version of the pickle is detected automatically, so no\n"
@@ -7468,7 +7435,7 @@ exit:
static PyObject *
_pickle_loads_impl(PyModuleDef *module, PyObject *data, int fix_imports, const char *encoding, const char *errors)
-/*[clinic end generated code: checksum=0663de43aca6c21508a777e29d98c9c3a6e7f72d]*/
+/*[clinic end generated code: checksum=7b21a75997c8f6636e4bf48c663b28f2bfd4eb6a]*/
{
PyObject *result;
UnpicklerObject *unpickler = _Unpickler_New();
diff --git a/Modules/_sre.c b/Modules/_sre.c
index 5a8f839c75..41dca7d97d 100644
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -528,11 +528,10 @@ sre_search(SRE_STATE* state, SRE_CODE* pattern)
/*[clinic input]
module _sre
-class _sre.SRE_Pattern
+class _sre.SRE_Pattern "PatternObject *" "&Pattern_Type"
_sre.SRE_Pattern.match as pattern_match
- self: self(type="PatternObject *")
pattern: object
pos: Py_ssize_t = 0
endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize
@@ -541,7 +540,7 @@ Matches zero or more characters at the beginning of the string.
[clinic start generated code]*/
PyDoc_STRVAR(pattern_match__doc__,
-"match(pattern, pos=0, endpos=sys.maxsize)\n"
+"match(self, pattern, pos=0, endpos=sys.maxsize)\n"
"Matches zero or more characters at the beginning of the string.");
#define PATTERN_MATCH_METHODDEF \
@@ -551,7 +550,7 @@ static PyObject *
pattern_match_impl(PatternObject *self, PyObject *pattern, Py_ssize_t pos, Py_ssize_t endpos);
static PyObject *
-pattern_match(PyObject *self, PyObject *args, PyObject *kwargs)
+pattern_match(PatternObject *self, PyObject *args, PyObject *kwargs)
{
PyObject *return_value = NULL;
static char *_keywords[] = {"pattern", "pos", "endpos", NULL};
@@ -563,7 +562,7 @@ pattern_match(PyObject *self, PyObject *args, PyObject *kwargs)
"O|nn:match", _keywords,
&pattern, &pos, &endpos))
goto exit;
- return_value = pattern_match_impl((PatternObject *)self, pattern, pos, endpos);
+ return_value = pattern_match_impl(self, pattern, pos, endpos);
exit:
return return_value;
@@ -571,7 +570,7 @@ exit:
static PyObject *
pattern_match_impl(PatternObject *self, PyObject *pattern, Py_ssize_t pos, Py_ssize_t endpos)
-/*[clinic end generated code: checksum=63e59c5f3019efe6c1f3acdec42b2d3595e14a09]*/
+/*[clinic end generated code: checksum=4a3865d13638cb7c13dcae1fe58c1a9c35071998]*/
{
SRE_STATE state;
Py_ssize_t status;
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 4f4c69ee52..35eb21dc98 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -2851,18 +2851,18 @@ PyDoc_STRVAR(docstring_no_signature,
);
PyDoc_STRVAR(docstring_with_invalid_signature,
-"docstring_with_invalid_signature (boo)\n"
+"docstring_with_invalid_signature (module, boo)\n"
"\n"
"This docstring has an invalid signature."
);
PyDoc_STRVAR(docstring_with_signature,
-"docstring_with_signature(sig)\n"
+"docstring_with_signature(module, sig)\n"
"This docstring has a valid signature."
);
PyDoc_STRVAR(docstring_with_signature_and_extra_newlines,
-"docstring_with_signature_and_extra_newlines(parameter)\n"
+"docstring_with_signature_and_extra_newlines(module, parameter)\n"
"\n"
"\n"
"\n"
@@ -2870,7 +2870,7 @@ PyDoc_STRVAR(docstring_with_signature_and_extra_newlines,
);
PyDoc_STRVAR(docstring_with_signature_with_defaults,
-"docstring_with_signature_with_defaults(s='avocado', b=b'bytes', d=3.14, i=35, n=None, t=True, f=False, local=the_number_three, sys=sys.maxsize, exp=sys.maxsize - 1)\n"
+"docstring_with_signature_with_defaults(module, s='avocado', b=b'bytes', d=3.14, i=35, n=None, t=True, f=False, local=the_number_three, sys=sys.maxsize, exp=sys.maxsize - 1)\n"
"\n"
"\n"
"\n"
diff --git a/Modules/_weakref.c b/Modules/_weakref.c
index e5d6519b71..1cc6246b2f 100644
--- a/Modules/_weakref.c
+++ b/Modules/_weakref.c
@@ -20,7 +20,7 @@ Return the number of weak references to 'object'.
[clinic start generated code]*/
PyDoc_STRVAR(_weakref_getweakrefcount__doc__,
-"getweakrefcount(object)\n"
+"getweakrefcount(module, object)\n"
"Return the number of weak references to \'object\'.");
#define _WEAKREF_GETWEAKREFCOUNT_METHODDEF \
@@ -46,7 +46,7 @@ exit:
static Py_ssize_t
_weakref_getweakrefcount_impl(PyModuleDef *module, PyObject *object)
-/*[clinic end generated code: checksum=744fa73ba68c0ee89567e9cb9bea11863270d516]*/
+/*[clinic end generated code: checksum=dd8ba0730babf263d3db78d260ea7eacf6eb3735]*/
{
PyWeakReference **list;
diff --git a/Modules/audioop.c b/Modules/audioop.c
index f8bb18acf9..159b2fbdc8 100644
--- a/Modules/audioop.c
+++ b/Modules/audioop.c
@@ -390,128 +390,153 @@ audioop_check_parameters(Py_ssize_t len, int size)
return 1;
}
+/*[clinic input]
+output preset file
+module audioop
+[clinic start generated code]*/
+/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
+
+/*[clinic input]
+audioop.getsample
+
+ fragment: Py_buffer
+ width: int
+ index: Py_ssize_t
+ /
+
+Return the value of sample index from the fragment.
+[clinic start generated code]*/
+
static PyObject *
-audioop_getsample(PyObject *self, PyObject *args)
+audioop_getsample_impl(PyModuleDef *module, Py_buffer *fragment, int width, Py_ssize_t index)
+/*[clinic end generated code: checksum=f4482497e6f6e78fe88451c19a288837099d6eef]*/
{
- Py_buffer view;
- Py_ssize_t i;
- int size;
int val;
- if (!PyArg_ParseTuple(args, "y*in:getsample", &view, &size, &i))
+ if (!audioop_check_parameters(fragment->len, width))
return NULL;
- if (!audioop_check_parameters(view.len, size))
- goto error;
- if (i < 0 || i >= view.len/size) {
+ if (index < 0 || index >= fragment->len/width) {
PyErr_SetString(AudioopError, "Index out of range");
- goto error;
+ return NULL;
}
- val = GETRAWSAMPLE(size, view.buf, i*size);
- PyBuffer_Release(&view);
+ val = GETRAWSAMPLE(width, fragment->buf, index*width);
return PyLong_FromLong(val);
-
- error:
- PyBuffer_Release(&view);
- return NULL;
}
+/*[clinic input]
+audioop.max
+
+ fragment: Py_buffer
+ width: int
+ /
+
+Return the maximum of the absolute value of all samples in a fragment.
+[clinic start generated code]*/
+
static PyObject *
-audioop_max(PyObject *self, PyObject *args)
+audioop_max_impl(PyModuleDef *module, Py_buffer *fragment, int width)
+/*[clinic end generated code: checksum=85047ee1001f230518386b16148955ba9be4874f]*/
{
- Py_buffer view;
Py_ssize_t i;
- int size;
unsigned int absval, max = 0;
- if (!PyArg_ParseTuple(args, "y*i:max", &view, &size))
- return NULL;
- if (!audioop_check_parameters(view.len, size)) {
- PyBuffer_Release(&view);
+ if (!audioop_check_parameters(fragment->len, width))
return NULL;
- }
- for (i = 0; i < view.len; i += size) {
- int val = GETRAWSAMPLE(size, view.buf, i);
+ for (i = 0; i < fragment->len; i += width) {
+ int val = GETRAWSAMPLE(width, fragment->buf, i);
if (val < 0) absval = (-val);
else absval = val;
if (absval > max) max = absval;
}
- PyBuffer_Release(&view);
return PyLong_FromUnsignedLong(max);
}
+/*[clinic input]
+audioop.minmax
+
+ fragment: Py_buffer
+ width: int
+ /
+
+Return the minimum and maximum values of all samples in the sound fragment.
+[clinic start generated code]*/
+
static PyObject *
-audioop_minmax(PyObject *self, PyObject *args)
+audioop_minmax_impl(PyModuleDef *module, Py_buffer *fragment, int width)
+/*[clinic end generated code: checksum=ae8f5513c64fd569849adbbcc5fcd4d8f399da1b]*/
{
- Py_buffer view;
Py_ssize_t i;
- int size;
/* -1 trick below is needed on Windows to support -0x80000000 without
a warning */
int min = 0x7fffffff, max = -0x7FFFFFFF-1;
- if (!PyArg_ParseTuple(args, "y*i:minmax", &view, &size))
- return NULL;
- if (!audioop_check_parameters(view.len, size)) {
- PyBuffer_Release(&view);
+ if (!audioop_check_parameters(fragment->len, width))
return NULL;
- }
- for (i = 0; i < view.len; i += size) {
- int val = GETRAWSAMPLE(size, view.buf, i);
+ for (i = 0; i < fragment->len; i += width) {
+ int val = GETRAWSAMPLE(width, fragment->buf, i);
if (val > max) max = val;
if (val < min) min = val;
}
- PyBuffer_Release(&view);
return Py_BuildValue("(ii)", min, max);
}
+/*[clinic input]
+audioop.avg
+
+ fragment: Py_buffer
+ width: int
+ /
+
+Return the average over all samples in the fragment.
+[clinic start generated code]*/
+
static PyObject *
-audioop_avg(PyObject *self, PyObject *args)
+audioop_avg_impl(PyModuleDef *module, Py_buffer *fragment, int width)
+/*[clinic end generated code: checksum=7fccd645c95f4860899f6b3aaab269e3e58806e1]*/
{
- Py_buffer view;
Py_ssize_t i;
- int size, avg;
+ int avg;
double sum = 0.0;
- if (!PyArg_ParseTuple(args, "y*i:avg", &view, &size))
- return NULL;
- if (!audioop_check_parameters(view.len, size)) {
- PyBuffer_Release(&view);
+ if (!audioop_check_parameters(fragment->len, width))
return NULL;
- }
- for (i = 0; i < view.len; i += size)
- sum += GETRAWSAMPLE(size, view.buf, i);
- if (view.len == 0)
+ for (i = 0; i < fragment->len; i += width)
+ sum += GETRAWSAMPLE(width, fragment->buf, i);
+ if (fragment->len == 0)
avg = 0;
else
- avg = (int)floor(sum / (double)(view.len/size));
- PyBuffer_Release(&view);
+ avg = (int)floor(sum / (double)(fragment->len/width));
return PyLong_FromLong(avg);
}
+/*[clinic input]
+audioop.rms
+
+ fragment: Py_buffer
+ width: int
+ /
+
+Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n).
+[clinic start generated code]*/
+
static PyObject *
-audioop_rms(PyObject *self, PyObject *args)
+audioop_rms_impl(PyModuleDef *module, Py_buffer *fragment, int width)
+/*[clinic end generated code: checksum=7b398702c81b709d87aba3f0635eeb3fc1b0a1a4]*/
{
- Py_buffer view;
Py_ssize_t i;
- int size;
unsigned int res;
double sum_squares = 0.0;
- if (!PyArg_ParseTuple(args, "y*i:rms", &view, &size))
- return NULL;
- if (!audioop_check_parameters(view.len, size)) {
- PyBuffer_Release(&view);
+ if (!audioop_check_parameters(fragment->len, width))
return NULL;
- }
- for (i = 0; i < view.len; i += size) {
- double val = GETRAWSAMPLE(size, view.buf, i);
+ for (i = 0; i < fragment->len; i += width) {
+ double val = GETRAWSAMPLE(width, fragment->buf, i);
sum_squares += val*val;
}
- if (view.len == 0)
+ if (fragment->len == 0)
res = 0;
else
- res = (unsigned int)sqrt(sum_squares / (double)(view.len/size));
- PyBuffer_Release(&view);
+ res = (unsigned int)sqrt(sum_squares / (double)(fragment->len/width));
return PyLong_FromUnsignedLong(res);
}
@@ -558,31 +583,38 @@ static double _sum2(const short *a, const short *b, Py_ssize_t len)
** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
** is completely recalculated each step.
*/
+/*[clinic input]
+audioop.findfit
+
+ fragment: Py_buffer
+ reference: Py_buffer
+ /
+
+Try to match reference as well as possible to a portion of fragment.
+[clinic start generated code]*/
+
static PyObject *
-audioop_findfit(PyObject *self, PyObject *args)
+audioop_findfit_impl(PyModuleDef *module, Py_buffer *fragment, Py_buffer *reference)
+/*[clinic end generated code: checksum=505fd04d4244db31044abb5c114a5e8f9c45b171]*/
{
- Py_buffer view1;
- Py_buffer view2;
const short *cp1, *cp2;
Py_ssize_t len1, len2;
Py_ssize_t j, best_j;
double aj_m1, aj_lm1;
double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
- if (!PyArg_ParseTuple(args, "y*y*:findfit", &view1, &view2))
- return NULL;
- if (view1.len & 1 || view2.len & 1) {
+ if (fragment->len & 1 || reference->len & 1) {
PyErr_SetString(AudioopError, "Strings should be even-sized");
- goto error;
+ return NULL;
}
- cp1 = (const short *)view1.buf;
- len1 = view1.len >> 1;
- cp2 = (const short *)view2.buf;
- len2 = view2.len >> 1;
+ cp1 = (const short *)fragment->buf;
+ len1 = fragment->len >> 1;
+ cp2 = (const short *)reference->buf;
+ len2 = reference->len >> 1;
if (len1 < len2) {
PyErr_SetString(AudioopError, "First sample should be longer");
- goto error;
+ return NULL;
}
sum_ri_2 = _sum2(cp2, cp2, len2);
sum_aij_2 = _sum2(cp1, cp1, len2);
@@ -612,93 +644,94 @@ audioop_findfit(PyObject *self, PyObject *args)
factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
- PyBuffer_Release(&view1);
- PyBuffer_Release(&view2);
return Py_BuildValue("(nf)", best_j, factor);
-
- error:
- PyBuffer_Release(&view1);
- PyBuffer_Release(&view2);
- return NULL;
}
/*
** findfactor finds a factor f so that the energy in A-fB is minimal.
** See the comment for findfit for details.
*/
+/*[clinic input]
+audioop.findfactor
+
+ fragment: Py_buffer
+ reference: Py_buffer
+ /
+
+Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal.
+[clinic start generated code]*/
+
static PyObject *
-audioop_findfactor(PyObject *self, PyObject *args)
+audioop_findfactor_impl(PyModuleDef *module, Py_buffer *fragment, Py_buffer *reference)
+/*[clinic end generated code: checksum=ddf35a1e57575ce4acbc000104810d9fdde8eba5]*/
{
- Py_buffer view1;
- Py_buffer view2;
const short *cp1, *cp2;
Py_ssize_t len;
double sum_ri_2, sum_aij_ri, result;
- if (!PyArg_ParseTuple(args, "y*y*:findfactor", &view1, &view2))
- return NULL;
- if (view1.len & 1 || view2.len & 1) {
+ if (fragment->len & 1 || reference->len & 1) {
PyErr_SetString(AudioopError, "Strings should be even-sized");
- goto error;
+ return NULL;
}
- if (view1.len != view2.len) {
+ if (fragment->len != reference->len) {
PyErr_SetString(AudioopError, "Samples should be same size");
- goto error;
+ return NULL;
}
- cp1 = (const short *)view1.buf;
- cp2 = (const short *)view2.buf;
- len = view1.len >> 1;
+ cp1 = (const short *)fragment->buf;
+ cp2 = (const short *)reference->buf;
+ len = fragment->len >> 1;
sum_ri_2 = _sum2(cp2, cp2, len);
sum_aij_ri = _sum2(cp1, cp2, len);
result = sum_aij_ri / sum_ri_2;
- PyBuffer_Release(&view1);
- PyBuffer_Release(&view2);
return PyFloat_FromDouble(result);
-
- error:
- PyBuffer_Release(&view1);
- PyBuffer_Release(&view2);
- return NULL;
}
/*
** findmax returns the index of the n-sized segment of the input sample
** that contains the most energy.
*/
+/*[clinic input]
+audioop.findmax
+
+ fragment: Py_buffer
+ length: Py_ssize_t
+ /
+
+Search fragment for a slice of specified number of samples with maximum energy.
+[clinic start generated code]*/
+
static PyObject *
-audioop_findmax(PyObject *self, PyObject *args)
+audioop_findmax_impl(PyModuleDef *module, Py_buffer *fragment, Py_ssize_t length)
+/*[clinic end generated code: checksum=21d0c2a1e5655134f7460b7fd49ee4ba1e5fdb13]*/
{
- Py_buffer view;
const short *cp1;
- Py_ssize_t len1, len2;
+ Py_ssize_t len1;
Py_ssize_t j, best_j;
double aj_m1, aj_lm1;
double result, best_result;
- if (!PyArg_ParseTuple(args, "y*n:findmax", &view, &len2))
- return NULL;
- if (view.len & 1) {
+ if (fragment->len & 1) {
PyErr_SetString(AudioopError, "Strings should be even-sized");
- goto error;
+ return NULL;
}
- cp1 = (const short *)view.buf;
- len1 = view.len >> 1;
+ cp1 = (const short *)fragment->buf;
+ len1 = fragment->len >> 1;
- if (len2 < 0 || len1 < len2) {
+ if (length < 0 || len1 < length) {
PyErr_SetString(AudioopError, "Input sample should be longer");
- goto error;
+ return NULL;
}
- result = _sum2(cp1, cp1, len2);
+ result = _sum2(cp1, cp1, length);
best_result = result;
best_j = 0;
- for ( j=1; j<=len1-len2; j++) {
+ for ( j=1; j<=len1-length; j++) {
aj_m1 = (double)cp1[j-1];
- aj_lm1 = (double)cp1[j+len2-1];
+ aj_lm1 = (double)cp1[j+length-1];
result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
@@ -709,39 +742,37 @@ audioop_findmax(PyObject *self, PyObject *args)
}
- PyBuffer_Release(&view);
return PyLong_FromSsize_t(best_j);
-
- error:
- PyBuffer_Release(&view);
- return NULL;
}
+/*[clinic input]
+audioop.avgpp
+
+ fragment: Py_buffer
+ width: int
+ /
+
+Return the average peak-peak value over all samples in the fragment.
+[clinic start generated code]*/
+
static PyObject *
-audioop_avgpp(PyObject *self, PyObject *args)
+audioop_avgpp_impl(PyModuleDef *module, Py_buffer *fragment, int width)
+/*[clinic end generated code: checksum=06c8380fd6e34207f4b58d6c3d4b5ebc7afe138d]*/
{
- Py_buffer view;
Py_ssize_t i;
- int size, prevval, prevextremevalid = 0,
- prevextreme = 0;
+ int prevval, prevextremevalid = 0, prevextreme = 0;
double sum = 0.0;
unsigned int avg;
int diff, prevdiff, nextreme = 0;
- if (!PyArg_ParseTuple(args, "y*i:avgpp", &view, &size))
+ if (!audioop_check_parameters(fragment->len, width))
return NULL;
- if (!audioop_check_parameters(view.len, size)) {
- PyBuffer_Release(&view);
- return NULL;
- }
- if (view.len <= size) {
- PyBuffer_Release(&view);
+ if (fragment->len <= width)
return PyLong_FromLong(0);
- }
- prevval = GETRAWSAMPLE(size, view.buf, 0);
+ prevval = GETRAWSAMPLE(width, fragment->buf, 0);
prevdiff = 17; /* Anything != 0, 1 */
- for (i = size; i < view.len; i += size) {
- int val = GETRAWSAMPLE(size, view.buf, i);
+ for (i = width; i < fragment->len; i += width) {
+ int val = GETRAWSAMPLE(width, fragment->buf, i);
if (val != prevval) {
diff = val < prevval;
if (prevdiff == !diff) {
@@ -768,34 +799,36 @@ audioop_avgpp(PyObject *self, PyObject *args)
avg = 0;
else
avg = (unsigned int)(sum / (double)nextreme);
- PyBuffer_Release(&view);
return PyLong_FromUnsignedLong(avg);
}
+/*[clinic input]
+audioop.maxpp
+
+ fragment: Py_buffer
+ width: int
+ /
+
+Return the maximum peak-peak value in the sound fragment.
+[clinic start generated code]*/
+
static PyObject *
-audioop_maxpp(PyObject *self, PyObject *args)
+audioop_maxpp_impl(PyModuleDef *module, Py_buffer *fragment, int width)
+/*[clinic end generated code: checksum=c300c0bd7e8535c07e128bbaac211c69744f750b]*/
{
- Py_buffer view;
Py_ssize_t i;
- int size, prevval, prevextremevalid = 0,
- prevextreme = 0;
+ int prevval, prevextremevalid = 0, prevextreme = 0;
unsigned int max = 0, extremediff;
int diff, prevdiff;
- if (!PyArg_ParseTuple(args, "y*i:maxpp", &view, &size))
- return NULL;
- if (!audioop_check_parameters(view.len, size)) {
- PyBuffer_Release(&view);
+ if (!audioop_check_parameters(fragment->len, width))
return NULL;
- }
- if (view.len <= size) {
- PyBuffer_Release(&view);
+ if (fragment->len <= width)
return PyLong_FromLong(0);
- }
- prevval = GETRAWSAMPLE(size, view.buf, 0);
+ prevval = GETRAWSAMPLE(width, fragment->buf, 0);
prevdiff = 17; /* Anything != 0, 1 */
- for (i = size; i < view.len; i += size) {
- int val = GETRAWSAMPLE(size, view.buf, i);
+ for (i = width; i < fragment->len; i += width) {
+ int val = GETRAWSAMPLE(width, fragment->buf, i);
if (val != prevval) {
diff = val < prevval;
if (prevdiff == !diff) {
@@ -819,187 +852,215 @@ audioop_maxpp(PyObject *self, PyObject *args)
prevdiff = diff;
}
}
- PyBuffer_Release(&view);
return PyLong_FromUnsignedLong(max);
}
+/*[clinic input]
+audioop.cross
+
+ fragment: Py_buffer
+ width: int
+ /
+
+Return the number of zero crossings in the fragment passed as an argument.
+[clinic start generated code]*/
+
static PyObject *
-audioop_cross(PyObject *self, PyObject *args)
+audioop_cross_impl(PyModuleDef *module, Py_buffer *fragment, int width)
+/*[clinic end generated code: checksum=99e6572d7d7cdbf1b5372090308201c62d518a43]*/
{
- Py_buffer view;
Py_ssize_t i;
- int size;
int prevval;
Py_ssize_t ncross;
- if (!PyArg_ParseTuple(args, "y*i:cross", &view, &size))
- return NULL;
- if (!audioop_check_parameters(view.len, size)) {
- PyBuffer_Release(&view);
+ if (!audioop_check_parameters(fragment->len, width))
return NULL;
- }
ncross = -1;
prevval = 17; /* Anything <> 0,1 */
- for (i = 0; i < view.len; i += size) {
- int val = GETRAWSAMPLE(size, view.buf, i) < 0;
+ for (i = 0; i < fragment->len; i += width) {
+ int val = GETRAWSAMPLE(width, fragment->buf, i) < 0;
if (val != prevval) ncross++;
prevval = val;
}
- PyBuffer_Release(&view);
return PyLong_FromSsize_t(ncross);
}
+/*[clinic input]
+audioop.mul
+
+ fragment: Py_buffer
+ width: int
+ factor: double
+ /
+
+Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor.
+[clinic start generated code]*/
+
static PyObject *
-audioop_mul(PyObject *self, PyObject *args)
+audioop_mul_impl(PyModuleDef *module, Py_buffer *fragment, int width, double factor)
+/*[clinic end generated code: checksum=a697ebbd5852d38f941d52127a5b38e4f8cd5540]*/
{
- Py_buffer view;
signed char *ncp;
Py_ssize_t i;
- int size;
- double factor, maxval, minval;
- PyObject *rv = NULL;
+ double maxval, minval;
+ PyObject *rv;
- if (!PyArg_ParseTuple(args, "y*id:mul", &view, &size, &factor))
+ if (!audioop_check_parameters(fragment->len, width))
return NULL;
- if (!audioop_check_parameters(view.len, size))
- goto exit;
- maxval = (double) maxvals[size];
- minval = (double) minvals[size];
+ maxval = (double) maxvals[width];
+ minval = (double) minvals[width];
- rv = PyBytes_FromStringAndSize(NULL, view.len);
+ rv = PyBytes_FromStringAndSize(NULL, fragment->len);
if (rv == NULL)
- goto exit;
+ return NULL;
ncp = (signed char *)PyBytes_AsString(rv);
- for (i = 0; i < view.len; i += size) {
- double val = GETRAWSAMPLE(size, view.buf, i);
+ for (i = 0; i < fragment->len; i += width) {
+ double val = GETRAWSAMPLE(width, fragment->buf, i);
val *= factor;
val = floor(fbound(val, minval, maxval));
- SETRAWSAMPLE(size, ncp, i, (int)val);
+ SETRAWSAMPLE(width, ncp, i, (int)val);
}
- exit:
- PyBuffer_Release(&view);
return rv;
}
+/*[clinic input]
+audioop.tomono
+
+ fragment: Py_buffer
+ width: int
+ lfactor: double
+ rfactor: double
+ /
+
+Convert a stereo fragment to a mono fragment.
+[clinic start generated code]*/
+
static PyObject *
-audioop_tomono(PyObject *self, PyObject *args)
+audioop_tomono_impl(PyModuleDef *module, Py_buffer *fragment, int width, double lfactor, double rfactor)
+/*[clinic end generated code: checksum=436e7710521661dd541ec177ee53e6b0ee340182]*/
{
- Py_buffer pcp;
signed char *cp, *ncp;
Py_ssize_t len, i;
- int size;
- double fac1, fac2, maxval, minval;
- PyObject *rv = NULL;
+ double maxval, minval;
+ PyObject *rv;
- if (!PyArg_ParseTuple(args, "y*idd:tomono",
- &pcp, &size, &fac1, &fac2))
+ cp = fragment->buf;
+ len = fragment->len;
+ if (!audioop_check_parameters(len, width))
return NULL;
- cp = pcp.buf;
- len = pcp.len;
- if (!audioop_check_parameters(len, size))
- goto exit;
- if (((len / size) & 1) != 0) {
+ if (((len / width) & 1) != 0) {
PyErr_SetString(AudioopError, "not a whole number of frames");
- goto exit;
+ return NULL;
}
- maxval = (double) maxvals[size];
- minval = (double) minvals[size];
+ maxval = (double) maxvals[width];
+ minval = (double) minvals[width];
rv = PyBytes_FromStringAndSize(NULL, len/2);
if (rv == NULL)
- goto exit;
+ return NULL;
ncp = (signed char *)PyBytes_AsString(rv);
- for (i = 0; i < len; i += size*2) {
- double val1 = GETRAWSAMPLE(size, cp, i);
- double val2 = GETRAWSAMPLE(size, cp, i + size);
- double val = val1*fac1 + val2*fac2;
+ for (i = 0; i < len; i += width*2) {
+ double val1 = GETRAWSAMPLE(width, cp, i);
+ double val2 = GETRAWSAMPLE(width, cp, i + width);
+ double val = val1*lfactor + val2*rfactor;
val = floor(fbound(val, minval, maxval));
- SETRAWSAMPLE(size, ncp, i/2, val);
+ SETRAWSAMPLE(width, ncp, i/2, val);
}
- exit:
- PyBuffer_Release(&pcp);
return rv;
}
+/*[clinic input]
+audioop.tostereo
+
+ fragment: Py_buffer
+ width: int
+ lfactor: double
+ rfactor: double
+ /
+
+Generate a stereo fragment from a mono fragment.
+[clinic start generated code]*/
+
static PyObject *
-audioop_tostereo(PyObject *self, PyObject *args)
+audioop_tostereo_impl(PyModuleDef *module, Py_buffer *fragment, int width, double lfactor, double rfactor)
+/*[clinic end generated code: checksum=6ff50681c87f4c1cbe4c394c4186ae8ae91b5c0d]*/
{
- Py_buffer view;
signed char *ncp;
Py_ssize_t i;
- int size;
- double fac1, fac2, maxval, minval;
- PyObject *rv = NULL;
+ double maxval, minval;
+ PyObject *rv;
- if (!PyArg_ParseTuple(args, "y*idd:tostereo",
- &view, &size, &fac1, &fac2))
+ if (!audioop_check_parameters(fragment->len, width))
return NULL;
- if (!audioop_check_parameters(view.len, size))
- goto exit;
- maxval = (double) maxvals[size];
- minval = (double) minvals[size];
+ maxval = (double) maxvals[width];
+ minval = (double) minvals[width];
- if (view.len > PY_SSIZE_T_MAX/2) {
+ if (fragment->len > PY_SSIZE_T_MAX/2) {
PyErr_SetString(PyExc_MemoryError,
"not enough memory for output buffer");
- goto exit;
+ return NULL;
}
- rv = PyBytes_FromStringAndSize(NULL, view.len*2);
+ rv = PyBytes_FromStringAndSize(NULL, fragment->len*2);
if (rv == NULL)
- goto exit;
+ return NULL;
ncp = (signed char *)PyBytes_AsString(rv);
- for (i = 0; i < view.len; i += size) {
- double val = GETRAWSAMPLE(size, view.buf, i);
- int val1 = (int)floor(fbound(val*fac1, minval, maxval));
- int val2 = (int)floor(fbound(val*fac2, minval, maxval));
- SETRAWSAMPLE(size, ncp, i*2, val1);
- SETRAWSAMPLE(size, ncp, i*2 + size, val2);
+ for (i = 0; i < fragment->len; i += width) {
+ double val = GETRAWSAMPLE(width, fragment->buf, i);
+ int val1 = (int)floor(fbound(val*lfactor, minval, maxval));
+ int val2 = (int)floor(fbound(val*rfactor, minval, maxval));
+ SETRAWSAMPLE(width, ncp, i*2, val1);
+ SETRAWSAMPLE(width, ncp, i*2 + width, val2);
}
- exit:
- PyBuffer_Release(&view);
return rv;
}
+/*[clinic input]
+audioop.add
+
+ fragment1: Py_buffer
+ fragment2: Py_buffer
+ width: int
+ /
+
+Return a fragment which is the addition of the two samples passed as parameters.
+[clinic start generated code]*/
+
static PyObject *
-audioop_add(PyObject *self, PyObject *args)
+audioop_add_impl(PyModuleDef *module, Py_buffer *fragment1, Py_buffer *fragment2, int width)
+/*[clinic end generated code: checksum=f9218bf9ea75c3f1e4b2ed5ffdfd631354e8fdfe]*/
{
- Py_buffer view1;
- Py_buffer view2;
signed char *ncp;
Py_ssize_t i;
- int size, minval, maxval, newval;
- PyObject *rv = NULL;
+ int minval, maxval, newval;
+ PyObject *rv;
- if (!PyArg_ParseTuple(args, "y*y*i:add",
- &view1, &view2, &size))
+ if (!audioop_check_parameters(fragment1->len, width))
return NULL;
- if (!audioop_check_parameters(view1.len, size))
- goto exit;
- if (view1.len != view2.len) {
+ if (fragment1->len != fragment2->len) {
PyErr_SetString(AudioopError, "Lengths should be the same");
- goto exit;
+ return NULL;
}
- maxval = maxvals[size];
- minval = minvals[size];
+ maxval = maxvals[width];
+ minval = minvals[width];
- rv = PyBytes_FromStringAndSize(NULL, view1.len);
+ rv = PyBytes_FromStringAndSize(NULL, fragment1->len);
if (rv == NULL)
- goto exit;
+ return NULL;
ncp = (signed char *)PyBytes_AsString(rv);
- for (i = 0; i < view1.len; i += size) {
- int val1 = GETRAWSAMPLE(size, view1.buf, i);
- int val2 = GETRAWSAMPLE(size, view2.buf, i);
+ for (i = 0; i < fragment1->len; i += width) {
+ int val1 = GETRAWSAMPLE(width, fragment1->buf, i);
+ int val2 = GETRAWSAMPLE(width, fragment2->buf, i);
- if (size < 4) {
+ if (width < 4) {
newval = val1 + val2;
/* truncate in case of overflow */
if (newval > maxval)
@@ -1013,165 +1074,176 @@ audioop_add(PyObject *self, PyObject *args)
newval = (int)floor(fbound(fval, minval, maxval));
}
- SETRAWSAMPLE(size, ncp, i, newval);
+ SETRAWSAMPLE(width, ncp, i, newval);
}
- exit:
- PyBuffer_Release(&view1);
- PyBuffer_Release(&view2);
return rv;
}
+/*[clinic input]
+audioop.bias
+
+ fragment: Py_buffer
+ width: int
+ bias: int
+ /
+
+Return a fragment that is the original fragment with a bias added to each sample.
+[clinic start generated code]*/
+
static PyObject *
-audioop_bias(PyObject *self, PyObject *args)
+audioop_bias_impl(PyModuleDef *module, Py_buffer *fragment, int width, int bias)
+/*[clinic end generated code: checksum=8ec80b3f5d510a51a85e89e8c0a73070697f2ab4]*/
{
- Py_buffer view;
signed char *ncp;
Py_ssize_t i;
- int size, bias;
unsigned int val = 0, mask;
- PyObject *rv = NULL;
+ PyObject *rv;
- if (!PyArg_ParseTuple(args, "y*ii:bias",
- &view, &size, &bias))
+ if (!audioop_check_parameters(fragment->len, width))
return NULL;
- if (!audioop_check_parameters(view.len, size))
- goto exit;
-
- rv = PyBytes_FromStringAndSize(NULL, view.len);
+ rv = PyBytes_FromStringAndSize(NULL, fragment->len);
if (rv == NULL)
- goto exit;
+ return NULL;
ncp = (signed char *)PyBytes_AsString(rv);
- mask = masks[size];
+ mask = masks[width];
- for (i = 0; i < view.len; i += size) {
- if (size == 1)
- val = GETINTX(unsigned char, view.buf, i);
- else if (size == 2)
- val = GETINTX(unsigned short, view.buf, i);
- else if (size == 3)
- val = ((unsigned int)GETINT24(view.buf, i)) & 0xffffffu;
+ for (i = 0; i < fragment->len; i += width) {
+ if (width == 1)
+ val = GETINTX(unsigned char, fragment->buf, i);
+ else if (width == 2)
+ val = GETINTX(unsigned short, fragment->buf, i);
+ else if (width == 3)
+ val = ((unsigned int)GETINT24(fragment->buf, i)) & 0xffffffu;
else {
- assert(size == 4);
- val = GETINTX(PY_UINT32_T, view.buf, i);
+ assert(width == 4);
+ val = GETINTX(PY_UINT32_T, fragment->buf, i);
}
val += (unsigned int)bias;
/* wrap around in case of overflow */
val &= mask;
- if (size == 1)
+ if (width == 1)
SETINTX(unsigned char, ncp, i, val);
- else if (size == 2)
+ else if (width == 2)
SETINTX(unsigned short, ncp, i, val);
- else if (size == 3)
+ else if (width == 3)
SETINT24(ncp, i, (int)val);
else {
- assert(size == 4);
+ assert(width == 4);
SETINTX(PY_UINT32_T, ncp, i, val);
}
}
- exit:
- PyBuffer_Release(&view);
return rv;
}
+/*[clinic input]
+audioop.reverse
+
+ fragment: Py_buffer
+ width: int
+ /
+
+Reverse the samples in a fragment and returns the modified fragment.
+[clinic start generated code]*/
+
static PyObject *
-audioop_reverse(PyObject *self, PyObject *args)
+audioop_reverse_impl(PyModuleDef *module, Py_buffer *fragment, int width)
+/*[clinic end generated code: checksum=6ec3c91337f5925eaf17a7b8b907120102b6fb72]*/
{
- Py_buffer view;
unsigned char *ncp;
Py_ssize_t i;
- int size;
- PyObject *rv = NULL;
+ PyObject *rv;
- if (!PyArg_ParseTuple(args, "y*i:reverse",
- &view, &size))
+ if (!audioop_check_parameters(fragment->len, width))
return NULL;
- if (!audioop_check_parameters(view.len, size))
- goto exit;
-
- rv = PyBytes_FromStringAndSize(NULL, view.len);
+ rv = PyBytes_FromStringAndSize(NULL, fragment->len);
if (rv == NULL)
- goto exit;
+ return NULL;
ncp = (unsigned char *)PyBytes_AsString(rv);
- for (i = 0; i < view.len; i += size) {
- int val = GETRAWSAMPLE(size, view.buf, i);
- SETRAWSAMPLE(size, ncp, view.len - i - size, val);
+ for (i = 0; i < fragment->len; i += width) {
+ int val = GETRAWSAMPLE(width, fragment->buf, i);
+ SETRAWSAMPLE(width, ncp, fragment->len - i - width, val);
}
- exit:
- PyBuffer_Release(&view);
return rv;
}
+/*[clinic input]
+audioop.byteswap
+
+ fragment: Py_buffer
+ width: int
+ /
+
+Convert big-endian samples to little-endian and vice versa.
+[clinic start generated code]*/
+
static PyObject *
-audioop_byteswap(PyObject *self, PyObject *args)
+audioop_byteswap_impl(PyModuleDef *module, Py_buffer *fragment, int width)
+/*[clinic end generated code: checksum=bfe4aa584b7a3f5bd818cf79f83fa73e612cc9b8]*/
{
- Py_buffer view;
unsigned char *ncp;
Py_ssize_t i;
- int size;
- PyObject *rv = NULL;
+ PyObject *rv;
- if (!PyArg_ParseTuple(args, "y*i:swapbytes",
- &view, &size))
+ if (!audioop_check_parameters(fragment->len, width))
return NULL;
- if (!audioop_check_parameters(view.len, size))
- goto exit;
-
- rv = PyBytes_FromStringAndSize(NULL, view.len);
+ rv = PyBytes_FromStringAndSize(NULL, fragment->len);
if (rv == NULL)
- goto exit;
+ return NULL;
ncp = (unsigned char *)PyBytes_AsString(rv);
- for (i = 0; i < view.len; i += size) {
+ for (i = 0; i < fragment->len; i += width) {
int j;
- for (j = 0; j < size; j++)
- ncp[i + size - 1 - j] = ((unsigned char *)view.buf)[i + j];
+ for (j = 0; j < width; j++)
+ ncp[i + width - 1 - j] = ((unsigned char *)fragment->buf)[i + j];
}
- exit:
- PyBuffer_Release(&view);
return rv;
}
+/*[clinic input]
+audioop.lin2lin
+
+ fragment: Py_buffer
+ width: int
+ newwidth: int
+ /
+
+Convert samples between 1-, 2-, 3- and 4-byte formats.
+[clinic start generated code]*/
+
static PyObject *
-audioop_lin2lin(PyObject *self, PyObject *args)
+audioop_lin2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width, int newwidth)
+/*[clinic end generated code: checksum=3f9468a74472a93e2054a9da0ea1bbc39fe23e84]*/
{
- Py_buffer view;
unsigned char *ncp;
Py_ssize_t i, j;
- int size, size2;
- PyObject *rv = NULL;
+ PyObject *rv;
- if (!PyArg_ParseTuple(args, "y*ii:lin2lin",
- &view, &size, &size2))
+ if (!audioop_check_parameters(fragment->len, width))
+ return NULL;
+ if (!audioop_check_size(newwidth))
return NULL;
- if (!audioop_check_parameters(view.len, size))
- goto exit;
- if (!audioop_check_size(size2))
- goto exit;
-
- if (view.len/size > PY_SSIZE_T_MAX/size2) {
+ if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) {
PyErr_SetString(PyExc_MemoryError,
"not enough memory for output buffer");
- goto exit;
+ return NULL;
}
- rv = PyBytes_FromStringAndSize(NULL, (view.len/size)*size2);
+ rv = PyBytes_FromStringAndSize(NULL, (fragment->len/width)*newwidth);
if (rv == NULL)
- goto exit;
+ return NULL;
ncp = (unsigned char *)PyBytes_AsString(rv);
- for (i = j = 0; i < view.len; i += size, j += size2) {
- int val = GETSAMPLE32(size, view.buf, i);
- SETSAMPLE32(size2, ncp, j, val);
+ for (i = j = 0; i < fragment->len; i += width, j += newwidth) {
+ int val = GETSAMPLE32(width, fragment->buf, i);
+ SETSAMPLE32(newwidth, ncp, j, val);
}
- exit:
- PyBuffer_Release(&view);
return rv;
}
@@ -1186,50 +1258,60 @@ gcd(int a, int b)
return a;
}
+/*[clinic input]
+audioop.ratecv
+
+ fragment: Py_buffer
+ width: int
+ nchannels: int
+ inrate: int
+ outrate: int
+ state: object
+ weightA: int = 1
+ weightB: int = 0
+ /
+
+Convert the frame rate of the input fragment.
+[clinic start generated code]*/
+
static PyObject *
-audioop_ratecv(PyObject *self, PyObject *args)
+audioop_ratecv_impl(PyModuleDef *module, Py_buffer *fragment, int width, int nchannels, int inrate, int outrate, PyObject *state, int weightA, int weightB)
+/*[clinic end generated code: checksum=5585dddc4b5ff2363877076f4c6616df8d3e6f14]*/
{
- Py_buffer view;
char *cp, *ncp;
Py_ssize_t len;
- int size, nchannels, inrate, outrate, weightA, weightB;
int chan, d, *prev_i, *cur_i, cur_o;
- PyObject *state, *samps, *str, *rv = NULL;
+ PyObject *samps, *str, *rv = NULL;
int bytes_per_frame;
- weightA = 1;
- weightB = 0;
- if (!PyArg_ParseTuple(args, "y*iiiiO|ii:ratecv", &view, &size,
- &nchannels, &inrate, &outrate, &state,
- &weightA, &weightB))
+ if (!audioop_check_size(width))
return NULL;
- if (!audioop_check_size(size))
- goto exit2;
if (nchannels < 1) {
PyErr_SetString(AudioopError, "# of channels should be >= 1");
- goto exit2;
+ return NULL;
}
- if (size > INT_MAX / nchannels) {
+ if (width > INT_MAX / nchannels) {
/* This overflow test is rigorously correct because
both multiplicands are >= 1. Use the argument names
from the docs for the error msg. */
PyErr_SetString(PyExc_OverflowError,
"width * nchannels too big for a C int");
- goto exit2;
+ return NULL;
}
- bytes_per_frame = size * nchannels;
+ bytes_per_frame = width * nchannels;
if (weightA < 1 || weightB < 0) {
PyErr_SetString(AudioopError,
"weightA should be >= 1, weightB should be >= 0");
- goto exit2;
+ return NULL;
}
- if (view.len % bytes_per_frame != 0) {
+ assert(fragment->len >= 0);
+ if (fragment->len % bytes_per_frame != 0) {
PyErr_SetString(AudioopError, "not a whole number of frames");
- goto exit2;
+ return NULL;
}
if (inrate <= 0 || outrate <= 0) {
PyErr_SetString(AudioopError, "sampling rate not > 0");
- goto exit2;
+ return NULL;
}
/* divide inrate and outrate by their greatest common divisor */
d = gcd(inrate, outrate);
@@ -1243,7 +1325,7 @@ audioop_ratecv(PyObject *self, PyObject *args)
if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
PyErr_SetString(PyExc_MemoryError,
"not enough memory for output buffer");
- goto exit2;
+ return NULL;
}
prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
@@ -1252,7 +1334,7 @@ audioop_ratecv(PyObject *self, PyObject *args)
goto exit;
}
- len = view.len / bytes_per_frame; /* # of frames */
+ len = fragment->len / bytes_per_frame; /* # of frames */
if (state == Py_None) {
d = -outrate;
@@ -1289,7 +1371,7 @@ audioop_ratecv(PyObject *self, PyObject *args)
case ceiling(len/inrate) * outrate. */
/* compute ceiling(len/inrate) without overflow */
- Py_ssize_t q = len > 0 ? 1 + (len - 1) / inrate : 0;
+ Py_ssize_t q = 1 + (len - 1) / inrate;
if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
str = NULL;
else
@@ -1302,7 +1384,7 @@ audioop_ratecv(PyObject *self, PyObject *args)
goto exit;
}
ncp = PyBytes_AsString(str);
- cp = view.buf;
+ cp = fragment->buf;
for (;;) {
while (d < 0) {
@@ -1333,8 +1415,8 @@ audioop_ratecv(PyObject *self, PyObject *args)
}
for (chan = 0; chan < nchannels; chan++) {
prev_i[chan] = cur_i[chan];
- cur_i[chan] = GETSAMPLE32(size, cp, 0);
- cp += size;
+ cur_i[chan] = GETSAMPLE32(width, cp, 0);
+ cp += width;
/* implements a simple digital filter */
cur_i[chan] = (int)(
((double)weightA * (double)cur_i[chan] +
@@ -1349,8 +1431,8 @@ audioop_ratecv(PyObject *self, PyObject *args)
cur_o = (int)(((double)prev_i[chan] * (double)d +
(double)cur_i[chan] * (double)(outrate - d)) /
(double)outrate);
- SETSAMPLE32(size, ncp, 0, cur_o);
- ncp += size;
+ SETSAMPLE32(width, ncp, 0, cur_o);
+ ncp += width;
}
d -= inrate;
}
@@ -1358,166 +1440,184 @@ audioop_ratecv(PyObject *self, PyObject *args)
exit:
PyMem_Free(prev_i);
PyMem_Free(cur_i);
- exit2:
- PyBuffer_Release(&view);
return rv;
}
+/*[clinic input]
+audioop.lin2ulaw
+
+ fragment: Py_buffer
+ width: int
+ /
+
+Convert samples in the audio fragment to u-LAW encoding.
+[clinic start generated code]*/
+
static PyObject *
-audioop_lin2ulaw(PyObject *self, PyObject *args)
+audioop_lin2ulaw_impl(PyModuleDef *module, Py_buffer *fragment, int width)
+/*[clinic end generated code: checksum=26263cc877c5e1bc84fede972fb59499a82d949c]*/
{
- Py_buffer view;
unsigned char *ncp;
Py_ssize_t i;
- int size;
- PyObject *rv = NULL;
+ PyObject *rv;
- if (!PyArg_ParseTuple(args, "y*i:lin2ulaw",
- &view, &size))
+ if (!audioop_check_parameters(fragment->len, width))
return NULL;
- if (!audioop_check_parameters(view.len, size))
- goto exit;
-
- rv = PyBytes_FromStringAndSize(NULL, view.len/size);
+ rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
if (rv == NULL)
- goto exit;
+ return NULL;
ncp = (unsigned char *)PyBytes_AsString(rv);
- for (i = 0; i < view.len; i += size) {
- int val = GETSAMPLE32(size, view.buf, i);
+ for (i = 0; i < fragment->len; i += width) {
+ int val = GETSAMPLE32(width, fragment->buf, i);
*ncp++ = st_14linear2ulaw(val >> 18);
}
- exit:
- PyBuffer_Release(&view);
return rv;
}
+/*[clinic input]
+audioop.ulaw2lin
+
+ fragment: Py_buffer
+ width: int
+ /
+
+Convert sound fragments in u-LAW encoding to linearly encoded sound fragments.
+[clinic start generated code]*/
+
static PyObject *
-audioop_ulaw2lin(PyObject *self, PyObject *args)
+audioop_ulaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width)
+/*[clinic end generated code: checksum=9864cb34e3a1d87689f830d4c95cdcaae9a44561]*/
{
- Py_buffer view;
unsigned char *cp;
signed char *ncp;
Py_ssize_t i;
- int size;
- PyObject *rv = NULL;
+ PyObject *rv;
- if (!PyArg_ParseTuple(args, "y*i:ulaw2lin",
- &view, &size))
+ if (!audioop_check_size(width))
return NULL;
- if (!audioop_check_size(size))
- goto exit;
-
- if (view.len > PY_SSIZE_T_MAX/size) {
+ if (fragment->len > PY_SSIZE_T_MAX/width) {
PyErr_SetString(PyExc_MemoryError,
"not enough memory for output buffer");
- goto exit;
+ return NULL;
}
- rv = PyBytes_FromStringAndSize(NULL, view.len*size);
+ rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
if (rv == NULL)
- goto exit;
+ return NULL;
ncp = (signed char *)PyBytes_AsString(rv);
- cp = view.buf;
- for (i = 0; i < view.len*size; i += size) {
+ cp = fragment->buf;
+ for (i = 0; i < fragment->len*width; i += width) {
int val = st_ulaw2linear16(*cp++) << 16;
- SETSAMPLE32(size, ncp, i, val);
+ SETSAMPLE32(width, ncp, i, val);
}
- exit:
- PyBuffer_Release(&view);
return rv;
}
+/*[clinic input]
+audioop.lin2alaw
+
+ fragment: Py_buffer
+ width: int
+ /
+
+Convert samples in the audio fragment to a-LAW encoding.
+[clinic start generated code]*/
+
static PyObject *
-audioop_lin2alaw(PyObject *self, PyObject *args)
+audioop_lin2alaw_impl(PyModuleDef *module, Py_buffer *fragment, int width)
+/*[clinic end generated code: checksum=d5bf14bd0fe6fdcd4b0d604ccdf257097eb2419e]*/
{
- Py_buffer view;
unsigned char *ncp;
Py_ssize_t i;
- int size;
- PyObject *rv = NULL;
+ PyObject *rv;
- if (!PyArg_ParseTuple(args, "y*i:lin2alaw",
- &view, &size))
+ if (!audioop_check_parameters(fragment->len, width))
return NULL;
- if (!audioop_check_parameters(view.len, size))
- goto exit;
-
- rv = PyBytes_FromStringAndSize(NULL, view.len/size);
+ rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
if (rv == NULL)
- goto exit;
+ return NULL;
ncp = (unsigned char *)PyBytes_AsString(rv);
- for (i = 0; i < view.len; i += size) {
- int val = GETSAMPLE32(size, view.buf, i);
+ for (i = 0; i < fragment->len; i += width) {
+ int val = GETSAMPLE32(width, fragment->buf, i);
*ncp++ = st_linear2alaw(val >> 19);
}
- exit:
- PyBuffer_Release(&view);
return rv;
}
+/*[clinic input]
+audioop.alaw2lin
+
+ fragment: Py_buffer
+ width: int
+ /
+
+Convert sound fragments in a-LAW encoding to linearly encoded sound fragments.
+[clinic start generated code]*/
+
static PyObject *
-audioop_alaw2lin(PyObject *self, PyObject *args)
+audioop_alaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width)
+/*[clinic end generated code: checksum=d2b604ddd036e1cd4bb95b5553626b44302db48a]*/
{
- Py_buffer view;
unsigned char *cp;
signed char *ncp;
Py_ssize_t i;
- int size, val;
- PyObject *rv = NULL;
+ int val;
+ PyObject *rv;
- if (!PyArg_ParseTuple(args, "y*i:alaw2lin",
- &view, &size))
+ if (!audioop_check_size(width))
return NULL;
- if (!audioop_check_size(size))
- goto exit;
-
- if (view.len > PY_SSIZE_T_MAX/size) {
+ if (fragment->len > PY_SSIZE_T_MAX/width) {
PyErr_SetString(PyExc_MemoryError,
"not enough memory for output buffer");
- goto exit;
+ return NULL;
}
- rv = PyBytes_FromStringAndSize(NULL, view.len*size);
+ rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
if (rv == NULL)
- goto exit;
+ return NULL;
ncp = (signed char *)PyBytes_AsString(rv);
- cp = view.buf;
+ cp = fragment->buf;
- for (i = 0; i < view.len*size; i += size) {
+ for (i = 0; i < fragment->len*width; i += width) {
val = st_alaw2linear16(*cp++) << 16;
- SETSAMPLE32(size, ncp, i, val);
+ SETSAMPLE32(width, ncp, i, val);
}
- exit:
- PyBuffer_Release(&view);
return rv;
}
+/*[clinic input]
+audioop.lin2adpcm
+
+ fragment: Py_buffer
+ width: int
+ state: object
+ /
+
+Convert samples to 4 bit Intel/DVI ADPCM encoding.
+[clinic start generated code]*/
+
static PyObject *
-audioop_lin2adpcm(PyObject *self, PyObject *args)
+audioop_lin2adpcm_impl(PyModuleDef *module, Py_buffer *fragment, int width, PyObject *state)
+/*[clinic end generated code: checksum=4654c29d2731fafe35e7aa1e3d261361dbbbcc3b]*/
{
- Py_buffer view;
signed char *ncp;
Py_ssize_t i;
- int size, step, valpred, delta,
+ int step, valpred, delta,
index, sign, vpdiff, diff;
- PyObject *rv = NULL, *state, *str = NULL;
+ PyObject *rv = NULL, *str;
int outputbuffer = 0, bufferstep;
- if (!PyArg_ParseTuple(args, "y*iO:lin2adpcm",
- &view, &size, &state))
+ if (!audioop_check_parameters(fragment->len, width))
return NULL;
- if (!audioop_check_parameters(view.len, size))
- goto exit;
-
- str = PyBytes_FromStringAndSize(NULL, view.len/(size*2));
+ str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2));
if (str == NULL)
- goto exit;
+ return NULL;
ncp = (signed char *)PyBytes_AsString(str);
/* Decode state, should have (value, step) */
@@ -1528,14 +1628,15 @@ audioop_lin2adpcm(PyObject *self, PyObject *args)
} else if (!PyTuple_Check(state)) {
PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
goto exit;
- } else if (!PyArg_ParseTuple(state, "ii", &valpred, &index))
+ } else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
goto exit;
+ }
step = stepsizeTable[index];
bufferstep = 1;
- for (i = 0; i < view.len; i += size) {
- int val = GETSAMPLE32(size, view.buf, i) >> 16;
+ for (i = 0; i < fragment->len; i += width) {
+ int val = GETSAMPLE32(width, fragment->buf, i) >> 16;
/* Step 1 - compute difference with previous value */
if (val < valpred) {
@@ -1605,30 +1706,37 @@ audioop_lin2adpcm(PyObject *self, PyObject *args)
bufferstep = !bufferstep;
}
rv = Py_BuildValue("(O(ii))", str, valpred, index);
+
exit:
- Py_XDECREF(str);
- PyBuffer_Release(&view);
+ Py_DECREF(str);
return rv;
}
+/*[clinic input]
+audioop.adpcm2lin
+
+ fragment: Py_buffer
+ width: int
+ state: object
+ /
+
+Decode an Intel/DVI ADPCM coded fragment to a linear fragment.
+[clinic start generated code]*/
+
static PyObject *
-audioop_adpcm2lin(PyObject *self, PyObject *args)
+audioop_adpcm2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width, PyObject *state)
+/*[clinic end generated code: checksum=371965cdcc0aa69ba970e8bc5662b30d45bcc38d]*/
{
- Py_buffer view;
signed char *cp;
signed char *ncp;
Py_ssize_t i, outlen;
- int size, valpred, step, delta, index, sign, vpdiff;
- PyObject *rv = NULL, *str, *state;
+ int valpred, step, delta, index, sign, vpdiff;
+ PyObject *rv, *str;
int inputbuffer = 0, bufferstep;
- if (!PyArg_ParseTuple(args, "y*iO:adpcm2lin",
- &view, &size, &state))
+ if (!audioop_check_size(width))
return NULL;
- if (!audioop_check_size(size))
- goto exit;
-
/* Decode state, should have (value, step) */
if ( state == Py_None ) {
/* First time, it seems. Set defaults */
@@ -1636,26 +1744,26 @@ audioop_adpcm2lin(PyObject *self, PyObject *args)
index = 0;
} else if (!PyTuple_Check(state)) {
PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
- goto exit;
+ return NULL;
} else if (!PyArg_ParseTuple(state, "ii", &valpred, &index))
- goto exit;
+ return NULL;
- if (view.len > (PY_SSIZE_T_MAX/2)/size) {
+ if (fragment->len > (PY_SSIZE_T_MAX/2)/width) {
PyErr_SetString(PyExc_MemoryError,
"not enough memory for output buffer");
- goto exit;
+ return NULL;
}
- outlen = view.len*size*2;
+ outlen = fragment->len*width*2;
str = PyBytes_FromStringAndSize(NULL, outlen);
if (str == NULL)
- goto exit;
+ return NULL;
ncp = (signed char *)PyBytes_AsString(str);
- cp = view.buf;
+ cp = fragment->buf;
step = stepsizeTable[index];
bufferstep = 0;
- for (i = 0; i < outlen; i += size) {
+ for (i = 0; i < outlen; i += width) {
/* Step 1 - get the delta value and compute next index */
if ( bufferstep ) {
delta = inputbuffer & 0xf;
@@ -1700,43 +1808,43 @@ audioop_adpcm2lin(PyObject *self, PyObject *args)
step = stepsizeTable[index];
/* Step 6 - Output value */
- SETSAMPLE32(size, ncp, i, valpred << 16);
+ SETSAMPLE32(width, ncp, i, valpred << 16);
}
rv = Py_BuildValue("(O(ii))", str, valpred, index);
Py_DECREF(str);
- exit:
- PyBuffer_Release(&view);
return rv;
}
+#include "clinic/audioop.c.h"
+
static PyMethodDef audioop_methods[] = {
- { "max", audioop_max, METH_VARARGS },
- { "minmax", audioop_minmax, METH_VARARGS },
- { "avg", audioop_avg, METH_VARARGS },
- { "maxpp", audioop_maxpp, METH_VARARGS },
- { "avgpp", audioop_avgpp, METH_VARARGS },
- { "rms", audioop_rms, METH_VARARGS },
- { "findfit", audioop_findfit, METH_VARARGS },
- { "findmax", audioop_findmax, METH_VARARGS },
- { "findfactor", audioop_findfactor, METH_VARARGS },
- { "cross", audioop_cross, METH_VARARGS },
- { "mul", audioop_mul, METH_VARARGS },
- { "add", audioop_add, METH_VARARGS },
- { "bias", audioop_bias, METH_VARARGS },
- { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
- { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
- { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
- { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
- { "lin2lin", audioop_lin2lin, METH_VARARGS },
- { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
- { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
- { "tomono", audioop_tomono, METH_VARARGS },
- { "tostereo", audioop_tostereo, METH_VARARGS },
- { "getsample", audioop_getsample, METH_VARARGS },
- { "reverse", audioop_reverse, METH_VARARGS },
- { "byteswap", audioop_byteswap, METH_VARARGS },
- { "ratecv", audioop_ratecv, METH_VARARGS },
+ AUDIOOP_MAX_METHODDEF
+ AUDIOOP_MINMAX_METHODDEF
+ AUDIOOP_AVG_METHODDEF
+ AUDIOOP_MAXPP_METHODDEF
+ AUDIOOP_AVGPP_METHODDEF
+ AUDIOOP_RMS_METHODDEF
+ AUDIOOP_FINDFIT_METHODDEF
+ AUDIOOP_FINDMAX_METHODDEF
+ AUDIOOP_FINDFACTOR_METHODDEF
+ AUDIOOP_CROSS_METHODDEF
+ AUDIOOP_MUL_METHODDEF
+ AUDIOOP_ADD_METHODDEF
+ AUDIOOP_BIAS_METHODDEF
+ AUDIOOP_ULAW2LIN_METHODDEF
+ AUDIOOP_LIN2ULAW_METHODDEF
+ AUDIOOP_ALAW2LIN_METHODDEF
+ AUDIOOP_LIN2ALAW_METHODDEF
+ AUDIOOP_LIN2LIN_METHODDEF
+ AUDIOOP_ADPCM2LIN_METHODDEF
+ AUDIOOP_LIN2ADPCM_METHODDEF
+ AUDIOOP_TOMONO_METHODDEF
+ AUDIOOP_TOSTEREO_METHODDEF
+ AUDIOOP_GETSAMPLE_METHODDEF
+ AUDIOOP_REVERSE_METHODDEF
+ AUDIOOP_BYTESWAP_METHODDEF
+ AUDIOOP_RATECV_METHODDEF
{ 0, 0 }
};
diff --git a/Modules/binascii.c b/Modules/binascii.c
index 0f4970141d..d38182e432 100644
--- a/Modules/binascii.c
+++ b/Modules/binascii.c
@@ -183,6 +183,27 @@ static unsigned short crctab_hqx[256] = {
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
};
+/*[clinic input]
+output preset file
+module binascii
+[clinic start generated code]*/
+/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
+
+/*[python input]
+
+class ascii_buffer_converter(CConverter):
+ type = 'Py_buffer'
+ converter = 'ascii_buffer_converter'
+ impl_by_reference = True
+ c_default = "{NULL, NULL}"
+
+ def cleanup(self):
+ name = self.name
+ return "".join(["if (", name, ".obj)\n PyBuffer_Release(&", name, ");\n"])
+
+[python start generated code]*/
+/*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
+
static int
ascii_buffer_converter(PyObject *arg, Py_buffer *buf)
{
@@ -220,13 +241,21 @@ ascii_buffer_converter(PyObject *arg, Py_buffer *buf)
return Py_CLEANUP_SUPPORTED;
}
+#include "clinic/binascii.c.h"
+
+/*[clinic input]
+binascii.a2b_uu
+
+ data: ascii_buffer
+ /
-PyDoc_STRVAR(doc_a2b_uu, "(ascii) -> bin. Decode a line of uuencoded data");
+Decode a line of uuencoded data.
+[clinic start generated code]*/
static PyObject *
-binascii_a2b_uu(PyObject *self, PyObject *args)
+binascii_a2b_uu_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: checksum=5779f39b0b48459ff0f7a365d7e69b57422e2a4a]*/
{
- Py_buffer pascii;
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
@@ -234,10 +263,8 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
PyObject *rv;
Py_ssize_t ascii_len, bin_len;
- if ( !PyArg_ParseTuple(args, "O&:a2b_uu", ascii_buffer_converter, &pascii) )
- return NULL;
- ascii_data = pascii.buf;
- ascii_len = pascii.len;
+ ascii_data = data->buf;
+ ascii_len = data->len;
assert(ascii_len >= 0);
@@ -246,10 +273,8 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
ascii_len--;
/* Allocate the buffer */
- if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) {
- PyBuffer_Release(&pascii);
+ if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL )
return NULL;
- }
bin_data = (unsigned char *)PyBytes_AS_STRING(rv);
for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) {
@@ -269,7 +294,6 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
*/
if ( this_ch < ' ' || this_ch > (' ' + 64)) {
PyErr_SetString(Error, "Illegal char");
- PyBuffer_Release(&pascii);
Py_DECREF(rv);
return NULL;
}
@@ -298,21 +322,26 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
if ( this_ch != ' ' && this_ch != ' '+64 &&
this_ch != '\n' && this_ch != '\r' ) {
PyErr_SetString(Error, "Trailing garbage");
- PyBuffer_Release(&pascii);
Py_DECREF(rv);
return NULL;
}
}
- PyBuffer_Release(&pascii);
return rv;
}
-PyDoc_STRVAR(doc_b2a_uu, "(bin) -> ascii. Uuencode line of data");
+/*[clinic input]
+binascii.b2a_uu
+
+ data: Py_buffer
+ /
+
+Uuencode line of data.
+[clinic start generated code]*/
static PyObject *
-binascii_b2a_uu(PyObject *self, PyObject *args)
+binascii_b2a_uu_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: checksum=181021b69bb9a4149fffa98aa3ed57b59ffa38cb]*/
{
- Py_buffer pbin;
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
@@ -320,22 +349,17 @@ binascii_b2a_uu(PyObject *self, PyObject *args)
PyObject *rv;
Py_ssize_t bin_len;
- if ( !PyArg_ParseTuple(args, "y*:b2a_uu", &pbin) )
- return NULL;
- bin_data = pbin.buf;
- bin_len = pbin.len;
+ bin_data = data->buf;
+ bin_len = data->len;
if ( bin_len > 45 ) {
/* The 45 is a limit that appears in all uuencode's */
PyErr_SetString(Error, "At most 45 bytes at once");
- PyBuffer_Release(&pbin);
return NULL;
}
/* We're lazy and allocate to much (fixed up later) */
- if ( (rv=PyBytes_FromStringAndSize(NULL, 2 + (bin_len+2)/3*4)) == NULL ) {
- PyBuffer_Release(&pbin);
+ if ( (rv=PyBytes_FromStringAndSize(NULL, 2 + (bin_len+2)/3*4)) == NULL )
return NULL;
- }
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);
/* Store the length */
@@ -363,7 +387,6 @@ binascii_b2a_uu(PyObject *self, PyObject *args)
(unsigned char *)PyBytes_AS_STRING(rv))) < 0) {
Py_CLEAR(rv);
}
- PyBuffer_Release(&pbin);
return rv;
}
@@ -393,12 +416,19 @@ binascii_find_valid(unsigned char *s, Py_ssize_t slen, int num)
return ret;
}
-PyDoc_STRVAR(doc_a2b_base64, "(ascii) -> bin. Decode a line of base64 data");
+/*[clinic input]
+binascii.a2b_base64
+
+ data: ascii_buffer
+ /
+
+Decode a line of base64 data.
+[clinic start generated code]*/
static PyObject *
-binascii_a2b_base64(PyObject *self, PyObject *args)
+binascii_a2b_base64_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: checksum=3e351b702bed56d249caa4aa0f1bb3fae7546025]*/
{
- Py_buffer pascii;
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
@@ -407,25 +437,19 @@ binascii_a2b_base64(PyObject *self, PyObject *args)
Py_ssize_t ascii_len, bin_len;
int quad_pos = 0;
- if ( !PyArg_ParseTuple(args, "O&:a2b_base64", ascii_buffer_converter, &pascii) )
- return NULL;
- ascii_data = pascii.buf;
- ascii_len = pascii.len;
+ ascii_data = data->buf;
+ ascii_len = data->len;
assert(ascii_len >= 0);
- if (ascii_len > PY_SSIZE_T_MAX - 3) {
- PyBuffer_Release(&pascii);
+ if (ascii_len > PY_SSIZE_T_MAX - 3)
return PyErr_NoMemory();
- }
bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */
/* Allocate the buffer */
- if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) {
- PyBuffer_Release(&pascii);
+ if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL )
return NULL;
- }
bin_data = (unsigned char *)PyBytes_AS_STRING(rv);
bin_len = 0;
@@ -478,7 +502,6 @@ binascii_a2b_base64(PyObject *self, PyObject *args)
}
if (leftbits != 0) {
- PyBuffer_Release(&pascii);
PyErr_SetString(Error, "Incorrect padding");
Py_DECREF(rv);
return NULL;
@@ -497,16 +520,23 @@ binascii_a2b_base64(PyObject *self, PyObject *args)
Py_DECREF(rv);
rv = PyBytes_FromStringAndSize("", 0);
}
- PyBuffer_Release(&pascii);
return rv;
}
-PyDoc_STRVAR(doc_b2a_base64, "(bin) -> ascii. Base64-code line of data");
+
+/*[clinic input]
+binascii.b2a_base64
+
+ data: Py_buffer
+ /
+
+Base64-code line of data.
+[clinic start generated code]*/
static PyObject *
-binascii_b2a_base64(PyObject *self, PyObject *args)
+binascii_b2a_base64_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: checksum=3cd61fbee2913285e253bc5415c9d052b0c5dd96]*/
{
- Py_buffer pbuf;
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
@@ -514,26 +544,21 @@ binascii_b2a_base64(PyObject *self, PyObject *args)
PyObject *rv;
Py_ssize_t bin_len;
- if ( !PyArg_ParseTuple(args, "y*:b2a_base64", &pbuf) )
- return NULL;
- bin_data = pbuf.buf;
- bin_len = pbuf.len;
+ bin_data = data->buf;
+ bin_len = data->len;
assert(bin_len >= 0);
if ( bin_len > BASE64_MAXBIN ) {
PyErr_SetString(Error, "Too much data for base64 line");
- PyBuffer_Release(&pbuf);
return NULL;
}
/* We're lazy and allocate too much (fixed up later).
"+3" leaves room for up to two pad characters and a trailing
newline. Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */
- if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL ) {
- PyBuffer_Release(&pbuf);
+ if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL )
return NULL;
- }
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);
for( ; bin_len > 0 ; bin_len--, bin_data++ ) {
@@ -563,16 +588,22 @@ binascii_b2a_base64(PyObject *self, PyObject *args)
(unsigned char *)PyBytes_AS_STRING(rv))) < 0) {
Py_CLEAR(rv);
}
- PyBuffer_Release(&pbuf);
return rv;
}
-PyDoc_STRVAR(doc_a2b_hqx, "ascii -> bin, done. Decode .hqx coding");
+/*[clinic input]
+binascii.a2b_hqx
+
+ data: ascii_buffer
+ /
+
+Decode .hqx coding.
+[clinic start generated code]*/
static PyObject *
-binascii_a2b_hqx(PyObject *self, PyObject *args)
+binascii_a2b_hqx_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: checksum=60bcdbbd28b105cd7091d98e70a6e458f8039e9e]*/
{
- Py_buffer pascii;
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
@@ -581,25 +612,19 @@ binascii_a2b_hqx(PyObject *self, PyObject *args)
Py_ssize_t len;
int done = 0;
- if ( !PyArg_ParseTuple(args, "O&:a2b_hqx", ascii_buffer_converter, &pascii) )
- return NULL;
- ascii_data = pascii.buf;
- len = pascii.len;
+ ascii_data = data->buf;
+ len = data->len;
assert(len >= 0);
- if (len > PY_SSIZE_T_MAX - 2) {
- PyBuffer_Release(&pascii);
+ if (len > PY_SSIZE_T_MAX - 2)
return PyErr_NoMemory();
- }
/* Allocate a string that is too big (fixed later)
Add two to the initial length to prevent interning which
would preclude subsequent resizing. */
- if ( (rv=PyBytes_FromStringAndSize(NULL, len+2)) == NULL ) {
- PyBuffer_Release(&pascii);
+ if ( (rv=PyBytes_FromStringAndSize(NULL, len+2)) == NULL )
return NULL;
- }
bin_data = (unsigned char *)PyBytes_AS_STRING(rv);
for( ; len > 0 ; len--, ascii_data++ ) {
@@ -609,7 +634,6 @@ binascii_a2b_hqx(PyObject *self, PyObject *args)
continue;
if ( this_ch == FAIL ) {
PyErr_SetString(Error, "Illegal char");
- PyBuffer_Release(&pascii);
Py_DECREF(rv);
return NULL;
}
@@ -632,7 +656,6 @@ binascii_a2b_hqx(PyObject *self, PyObject *args)
if ( leftbits && !done ) {
PyErr_SetString(Incomplete,
"String has incomplete number of bytes");
- PyBuffer_Release(&pascii);
Py_DECREF(rv);
return NULL;
}
@@ -643,43 +666,43 @@ binascii_a2b_hqx(PyObject *self, PyObject *args)
}
if (rv) {
PyObject *rrv = Py_BuildValue("Oi", rv, done);
- PyBuffer_Release(&pascii);
Py_DECREF(rv);
return rrv;
}
- PyBuffer_Release(&pascii);
return NULL;
}
-PyDoc_STRVAR(doc_rlecode_hqx, "Binhex RLE-code binary data");
+
+/*[clinic input]
+binascii.rlecode_hqx
+
+ data: Py_buffer
+ /
+
+Binhex RLE-code binary data.
+[clinic start generated code]*/
static PyObject *
-binascii_rlecode_hqx(PyObject *self, PyObject *args)
+binascii_rlecode_hqx_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: checksum=0905da344dbf064855925c3a0fb83ec11ca33e8b]*/
{
- Py_buffer pbuf;
unsigned char *in_data, *out_data;
PyObject *rv;
unsigned char ch;
Py_ssize_t in, inend, len;
- if ( !PyArg_ParseTuple(args, "y*:rlecode_hqx", &pbuf) )
- return NULL;
- in_data = pbuf.buf;
- len = pbuf.len;
+ in_data = data->buf;
+ len = data->len;
assert(len >= 0);
- if (len > PY_SSIZE_T_MAX / 2 - 2) {
- PyBuffer_Release(&pbuf);
+ if (len > PY_SSIZE_T_MAX / 2 - 2)
return PyErr_NoMemory();
- }
/* Worst case: output is twice as big as input (fixed later) */
- if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) {
- PyBuffer_Release(&pbuf);
+ if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL )
return NULL;
- }
out_data = (unsigned char *)PyBytes_AS_STRING(rv);
for( in=0; in<len; in++) {
@@ -711,16 +734,23 @@ binascii_rlecode_hqx(PyObject *self, PyObject *args)
(unsigned char *)PyBytes_AS_STRING(rv))) < 0) {
Py_CLEAR(rv);
}
- PyBuffer_Release(&pbuf);
return rv;
}
-PyDoc_STRVAR(doc_b2a_hqx, "Encode .hqx data");
+
+/*[clinic input]
+binascii.b2a_hqx
+
+ data: Py_buffer
+ /
+
+Encode .hqx data.
+[clinic start generated code]*/
static PyObject *
-binascii_b2a_hqx(PyObject *self, PyObject *args)
+binascii_b2a_hqx_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: checksum=5a987810d5e3cdbb0eb415eba8907c022342fe15]*/
{
- Py_buffer pbin;
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
@@ -728,23 +758,17 @@ binascii_b2a_hqx(PyObject *self, PyObject *args)
PyObject *rv;
Py_ssize_t len;
- if ( !PyArg_ParseTuple(args, "y*:b2a_hqx", &pbin) )
- return NULL;
- bin_data = pbin.buf;
- len = pbin.len;
+ bin_data = data->buf;
+ len = data->len;
assert(len >= 0);
- if (len > PY_SSIZE_T_MAX / 2 - 2) {
- PyBuffer_Release(&pbin);
+ if (len > PY_SSIZE_T_MAX / 2 - 2)
return PyErr_NoMemory();
- }
/* Allocate a buffer that is at least large enough */
- if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) {
- PyBuffer_Release(&pbin);
+ if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL )
return NULL;
- }
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);
for( ; len > 0 ; len--, bin_data++ ) {
@@ -767,44 +791,43 @@ binascii_b2a_hqx(PyObject *self, PyObject *args)
(unsigned char *)PyBytes_AS_STRING(rv))) < 0) {
Py_CLEAR(rv);
}
- PyBuffer_Release(&pbin);
return rv;
}
-PyDoc_STRVAR(doc_rledecode_hqx, "Decode hexbin RLE-coded string");
+
+/*[clinic input]
+binascii.rledecode_hqx
+
+ data: Py_buffer
+ /
+
+Decode hexbin RLE-coded string.
+[clinic start generated code]*/
static PyObject *
-binascii_rledecode_hqx(PyObject *self, PyObject *args)
+binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: checksum=f7afd89b789946ab50e31d595c695d5cad7e27e3]*/
{
- Py_buffer pin;
unsigned char *in_data, *out_data;
unsigned char in_byte, in_repeat;
PyObject *rv;
Py_ssize_t in_len, out_len, out_len_left;
- if ( !PyArg_ParseTuple(args, "y*:rledecode_hqx", &pin) )
- return NULL;
- in_data = pin.buf;
- in_len = pin.len;
+ in_data = data->buf;
+ in_len = data->len;
assert(in_len >= 0);
/* Empty string is a special case */
- if ( in_len == 0 ) {
- PyBuffer_Release(&pin);
+ if ( in_len == 0 )
return PyBytes_FromStringAndSize("", 0);
- }
- else if (in_len > PY_SSIZE_T_MAX / 2) {
- PyBuffer_Release(&pin);
+ else if (in_len > PY_SSIZE_T_MAX / 2)
return PyErr_NoMemory();
- }
/* Allocate a buffer of reasonable size. Resized when needed */
out_len = in_len*2;
- if ( (rv=PyBytes_FromStringAndSize(NULL, out_len)) == NULL ) {
- PyBuffer_Release(&pin);
+ if ( (rv=PyBytes_FromStringAndSize(NULL, out_len)) == NULL )
return NULL;
- }
out_len_left = out_len;
out_data = (unsigned char *)PyBytes_AS_STRING(rv);
@@ -817,7 +840,6 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
if ( --in_len < 0 ) { \
PyErr_SetString(Incomplete, ""); \
Py_DECREF(rv); \
- PyBuffer_Release(&pin); \
return NULL; \
} \
b = *in_data++; \
@@ -828,7 +850,7 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
if ( --out_len_left < 0 ) { \
if ( out_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); \
if (_PyBytes_Resize(&rv, 2*out_len) < 0) \
- { Py_XDECREF(rv); PyBuffer_Release(&pin); return NULL; } \
+ { Py_XDECREF(rv); return NULL; } \
out_data = (unsigned char *)PyBytes_AS_STRING(rv) \
+ out_len; \
out_len_left = out_len-1; \
@@ -850,7 +872,6 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
** of the string only). This is a programmer error.
*/
PyErr_SetString(Error, "Orphaned RLE code at start");
- PyBuffer_Release(&pin);
Py_DECREF(rv);
return NULL;
}
@@ -883,57 +904,39 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
(unsigned char *)PyBytes_AS_STRING(rv))) < 0) {
Py_CLEAR(rv);
}
- PyBuffer_Release(&pin);
return rv;
}
-PyDoc_STRVAR(doc_crc_hqx,
-"(data, oldcrc) -> newcrc. Compute hqx CRC incrementally");
-static PyObject *
-binascii_crc_hqx(PyObject *self, PyObject *args)
+/*[clinic input]
+binascii.crc_hqx -> int
+
+ data: Py_buffer
+ crc: int
+ /
+
+Compute hqx CRC incrementally.
+[clinic start generated code]*/
+
+static int
+binascii_crc_hqx_impl(PyModuleDef *module, Py_buffer *data, int crc)
+/*[clinic end generated code: checksum=634dac18dfa863d738833b5a0886eca93c034c0c]*/
{
- Py_buffer pin;
unsigned char *bin_data;
- unsigned int crc;
+ unsigned int ucrc = (unsigned int)crc;
Py_ssize_t len;
- if ( !PyArg_ParseTuple(args, "y*i:crc_hqx", &pin, &crc) )
- return NULL;
- bin_data = pin.buf;
- len = pin.len;
+ bin_data = data->buf;
+ len = data->len;
while(len-- > 0) {
- crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++];
+ ucrc=((ucrc<<8)&0xff00)^crctab_hqx[((ucrc>>8)&0xff)^*bin_data++];
}
- PyBuffer_Release(&pin);
- return Py_BuildValue("i", crc);
+ return (int)ucrc;
}
-PyDoc_STRVAR(doc_crc32,
-"(data, oldcrc = 0) -> newcrc. Compute CRC-32 incrementally");
-
-#ifdef USE_ZLIB_CRC32
-/* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */
-static PyObject *
-binascii_crc32(PyObject *self, PyObject *args)
-{
- unsigned int crc32val = 0; /* crc32(0L, Z_NULL, 0) */
- Py_buffer pbuf;
- Byte *buf;
- Py_ssize_t len;
- int signed_val;
-
- if (!PyArg_ParseTuple(args, "y*|I:crc32", &pbuf, &crc32val))
- return NULL;
- buf = (Byte*)pbuf.buf;
- len = pbuf.len;
- signed_val = crc32(crc32val, buf, len);
- PyBuffer_Release(&pbuf);
- return PyLong_FromUnsignedLong(signed_val & 0xffffffffU);
-}
-#else /* USE_ZLIB_CRC32 */
+#ifndef USE_ZLIB_CRC32
/* Crc - 32 BIT ANSI X3.66 CRC checksum files
Also known as: ISO 3307
**********************************************************************|
@@ -1051,20 +1054,42 @@ static unsigned int crc_32_tab[256] = {
0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU,
0x2d02ef8dU
};
+#endif /* USE_ZLIB_CRC32 */
-static PyObject *
-binascii_crc32(PyObject *self, PyObject *args)
+/*[clinic input]
+binascii.crc32 -> unsigned_int
+
+ data: Py_buffer
+ crc: unsigned_int(bitwise=True) = 0
+ /
+
+Compute CRC-32 incrementally.
+[clinic start generated code]*/
+
+static unsigned int
+binascii_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc)
+/*[clinic end generated code: checksum=620a961643393c4f2a1fb273fda2acb43970c3f5]*/
+
+#ifdef USE_ZLIB_CRC32
+/* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */
+{
+ Byte *buf;
+ Py_ssize_t len;
+ int signed_val;
+
+ buf = (Byte*)data->buf;
+ len = data->len;
+ signed_val = crc32(crc, buf, len);
+ return (unsigned int)signed_val & 0xffffffffU;
+}
+#else /* USE_ZLIB_CRC32 */
{ /* By Jim Ahlstrom; All rights transferred to CNRI */
- Py_buffer pbin;
unsigned char *bin_data;
- unsigned int crc = 0; /* initial value of CRC */
Py_ssize_t len;
unsigned int result;
- if ( !PyArg_ParseTuple(args, "y*|I:crc32", &pbin, &crc) )
- return NULL;
- bin_data = pbin.buf;
- len = pbin.len;
+ bin_data = data->buf;
+ len = data->len;
crc = ~ crc;
while (len-- > 0) {
@@ -1073,38 +1098,42 @@ binascii_crc32(PyObject *self, PyObject *args)
}
result = (crc ^ 0xFFFFFFFF);
- PyBuffer_Release(&pbin);
- return PyLong_FromUnsignedLong(result & 0xffffffff);
+ return result & 0xffffffff;
}
#endif /* USE_ZLIB_CRC32 */
+/*[clinic input]
+binascii.b2a_hex
+
+ data: Py_buffer
+ /
+
+Hexadecimal representation of binary data.
+
+The return value is a bytes object. This function is also
+available as "hexlify()".
+[clinic start generated code]*/
static PyObject *
-binascii_hexlify(PyObject *self, PyObject *args)
+binascii_b2a_hex_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: checksum=179318922c2f8fdaee0d4d3283758aec8e8741a5]*/
{
- Py_buffer parg;
char* argbuf;
Py_ssize_t arglen;
PyObject *retval;
char* retbuf;
Py_ssize_t i, j;
- if (!PyArg_ParseTuple(args, "y*:b2a_hex", &parg))
- return NULL;
- argbuf = parg.buf;
- arglen = parg.len;
+ argbuf = data->buf;
+ arglen = data->len;
assert(arglen >= 0);
- if (arglen > PY_SSIZE_T_MAX / 2) {
- PyBuffer_Release(&parg);
+ if (arglen > PY_SSIZE_T_MAX / 2)
return PyErr_NoMemory();
- }
retval = PyBytes_FromStringAndSize(NULL, arglen*2);
- if (!retval) {
- PyBuffer_Release(&parg);
+ if (!retval)
return NULL;
- }
retbuf = PyBytes_AS_STRING(retval);
/* make hex version of string, taken from shamodule.c */
@@ -1115,16 +1144,9 @@ binascii_hexlify(PyObject *self, PyObject *args)
c = argbuf[i] & 0xf;
retbuf[j++] = Py_hexdigits[c];
}
- PyBuffer_Release(&parg);
return retval;
}
-PyDoc_STRVAR(doc_hexlify,
-"b2a_hex(data) -> s; Hexadecimal representation of binary data.\n\
-\n\
-The return value is a bytes object. This function is also\n\
-available as \"hexlify()\".");
-
static int
to_int(int c)
@@ -1141,20 +1163,30 @@ to_int(int c)
}
+/*[clinic input]
+binascii.a2b_hex
+
+ hexstr: ascii_buffer
+ /
+
+Binary data of hexadecimal representation.
+
+hexstr must contain an even number of hex digits (upper or lower case).
+This function is also available as "unhexlify()".
+[clinic start generated code]*/
+
static PyObject *
-binascii_unhexlify(PyObject *self, PyObject *args)
+binascii_a2b_hex_impl(PyModuleDef *module, Py_buffer *hexstr)
+/*[clinic end generated code: checksum=d61da452b5c6d2903c32c3e90e6a97221b25989b]*/
{
- Py_buffer parg;
char* argbuf;
Py_ssize_t arglen;
PyObject *retval;
char* retbuf;
Py_ssize_t i, j;
- if (!PyArg_ParseTuple(args, "O&:a2b_hex", ascii_buffer_converter, &parg))
- return NULL;
- argbuf = parg.buf;
- arglen = parg.len;
+ argbuf = hexstr->buf;
+ arglen = hexstr->len;
assert(arglen >= 0);
@@ -1163,16 +1195,13 @@ binascii_unhexlify(PyObject *self, PyObject *args)
* raise an exception.
*/
if (arglen % 2) {
- PyBuffer_Release(&parg);
PyErr_SetString(Error, "Odd-length string");
return NULL;
}
retval = PyBytes_FromStringAndSize(NULL, (arglen/2));
- if (!retval) {
- PyBuffer_Release(&parg);
+ if (!retval)
return NULL;
- }
retbuf = PyBytes_AS_STRING(retval);
for (i=j=0; i < arglen; i += 2) {
@@ -1185,21 +1214,13 @@ binascii_unhexlify(PyObject *self, PyObject *args)
}
retbuf[j++] = (top << 4) + bot;
}
- PyBuffer_Release(&parg);
return retval;
finally:
- PyBuffer_Release(&parg);
Py_DECREF(retval);
return NULL;
}
-PyDoc_STRVAR(doc_unhexlify,
-"a2b_hex(hexstr) -> s; Binary data of hexadecimal representation.\n\
-\n\
-hexstr must contain an even number of hex digits (upper or lower case).\n\
-This function is also available as \"unhexlify()\"");
-
static int table_hex[128] = {
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
@@ -1215,25 +1236,28 @@ static int table_hex[128] = {
#define MAXLINESIZE 76
-PyDoc_STRVAR(doc_a2b_qp, "Decode a string of qp-encoded data");
-static PyObject*
-binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs)
+/*[clinic input]
+binascii.a2b_qp
+
+ data: ascii_buffer
+ header: int(c_default="0") = False
+
+Decode a string of qp-encoded data.
+[clinic start generated code]*/
+
+static PyObject *
+binascii_a2b_qp_impl(PyModuleDef *module, Py_buffer *data, int header)
+/*[clinic end generated code: checksum=a44ef8827035211431d0906a76dbfe97e59a5079]*/
{
Py_ssize_t in, out;
char ch;
- Py_buffer pdata;
- unsigned char *data, *odata;
+ unsigned char *ascii_data, *odata;
Py_ssize_t datalen = 0;
PyObject *rv;
- static char *kwlist[] = {"data", "header", NULL};
- int header = 0;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i:a2b_qp", kwlist,
- ascii_buffer_converter, &pdata, &header))
- return NULL;
- data = pdata.buf;
- datalen = pdata.len;
+ ascii_data = data->buf;
+ datalen = data->len;
/* We allocate the output same size as input, this is overkill.
* The previous implementation used calloc() so we'll zero out the
@@ -1241,7 +1265,6 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs)
*/
odata = (unsigned char *) PyMem_Malloc(datalen);
if (odata == NULL) {
- PyBuffer_Release(&pdata);
PyErr_NoMemory();
return NULL;
}
@@ -1249,31 +1272,31 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs)
in = out = 0;
while (in < datalen) {
- if (data[in] == '=') {
+ if (ascii_data[in] == '=') {
in++;
if (in >= datalen) break;
/* Soft line breaks */
- if ((data[in] == '\n') || (data[in] == '\r')) {
- if (data[in] != '\n') {
- while (in < datalen && data[in] != '\n') in++;
+ if ((ascii_data[in] == '\n') || (ascii_data[in] == '\r')) {
+ if (ascii_data[in] != '\n') {
+ while (in < datalen && ascii_data[in] != '\n') in++;
}
if (in < datalen) in++;
}
- else if (data[in] == '=') {
+ else if (ascii_data[in] == '=') {
/* broken case from broken python qp */
odata[out++] = '=';
in++;
}
- else if (((data[in] >= 'A' && data[in] <= 'F') ||
- (data[in] >= 'a' && data[in] <= 'f') ||
- (data[in] >= '0' && data[in] <= '9')) &&
- ((data[in+1] >= 'A' && data[in+1] <= 'F') ||
- (data[in+1] >= 'a' && data[in+1] <= 'f') ||
- (data[in+1] >= '0' && data[in+1] <= '9'))) {
+ else if (((ascii_data[in] >= 'A' && ascii_data[in] <= 'F') ||
+ (ascii_data[in] >= 'a' && ascii_data[in] <= 'f') ||
+ (ascii_data[in] >= '0' && ascii_data[in] <= '9')) &&
+ ((ascii_data[in+1] >= 'A' && ascii_data[in+1] <= 'F') ||
+ (ascii_data[in+1] >= 'a' && ascii_data[in+1] <= 'f') ||
+ (ascii_data[in+1] >= '0' && ascii_data[in+1] <= '9'))) {
/* hexval */
- ch = hexval(data[in]) << 4;
+ ch = hexval(ascii_data[in]) << 4;
in++;
- ch |= hexval(data[in]);
+ ch |= hexval(ascii_data[in]);
in++;
odata[out++] = ch;
}
@@ -1281,22 +1304,20 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs)
odata[out++] = '=';
}
}
- else if (header && data[in] == '_') {
+ else if (header && ascii_data[in] == '_') {
odata[out++] = ' ';
in++;
}
else {
- odata[out] = data[in];
+ odata[out] = ascii_data[in];
in++;
out++;
}
}
if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) {
- PyBuffer_Release(&pdata);
PyMem_Free(odata);
return NULL;
}
- PyBuffer_Release(&pdata);
PyMem_Free(odata);
return rv;
}
@@ -1312,62 +1333,62 @@ to_hex (unsigned char ch, unsigned char *s)
return 0;
}
-PyDoc_STRVAR(doc_b2a_qp,
-"b2a_qp(data, quotetabs=0, istext=1, header=0) -> s; \n\
- Encode a string using quoted-printable encoding. \n\
-\n\
-On encoding, when istext is set, newlines are not encoded, and white \n\
-space at end of lines is. When istext is not set, \\r and \\n (CR/LF) are \n\
-both encoded. When quotetabs is set, space and tabs are encoded.");
-
/* XXX: This is ridiculously complicated to be backward compatible
* (mostly) with the quopri module. It doesn't re-create the quopri
* module bug where text ending in CRLF has the CR encoded */
-static PyObject*
-binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
+
+/*[clinic input]
+binascii.b2a_qp
+
+ data: Py_buffer
+ quotetabs: int(c_default="0") = False
+ istext: int(c_default="1") = True
+ header: int(c_default="0") = False
+
+Encode a string using quoted-printable encoding.
+
+On encoding, when istext is set, newlines are not encoded, and white
+space at end of lines is. When istext is not set, \r and \n (CR/LF)
+are both encoded. When quotetabs is set, space and tabs are encoded.
+[clinic start generated code]*/
+
+static PyObject *
+binascii_b2a_qp_impl(PyModuleDef *module, Py_buffer *data, int quotetabs, int istext, int header)
+/*[clinic end generated code: checksum=ff2991ba640fff3e67ac63205801c7173a0366cd]*/
{
Py_ssize_t in, out;
- Py_buffer pdata;
- unsigned char *data, *odata;
+ unsigned char *databuf, *odata;
Py_ssize_t datalen = 0, odatalen = 0;
PyObject *rv;
unsigned int linelen = 0;
- static char *kwlist[] = {"data", "quotetabs", "istext",
- "header", NULL};
- int istext = 1;
- int quotetabs = 0;
- int header = 0;
unsigned char ch;
int crlf = 0;
unsigned char *p;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|iii", kwlist, &pdata,
- &quotetabs, &istext, &header))
- return NULL;
- data = pdata.buf;
- datalen = pdata.len;
+ databuf = data->buf;
+ datalen = data->len;
/* See if this string is using CRLF line ends */
/* XXX: this function has the side effect of converting all of
* the end of lines to be the same depending on this detection
* here */
- p = (unsigned char *) memchr(data, '\n', datalen);
- if ((p != NULL) && (p > data) && (*(p-1) == '\r'))
+ p = (unsigned char *) memchr(databuf, '\n', datalen);
+ if ((p != NULL) && (p > databuf) && (*(p-1) == '\r'))
crlf = 1;
/* First, scan to see how many characters need to be encoded */
in = 0;
while (in < datalen) {
- if ((data[in] > 126) ||
- (data[in] == '=') ||
- (header && data[in] == '_') ||
- ((data[in] == '.') && (linelen == 0) &&
- (data[in+1] == '\n' || data[in+1] == '\r' || data[in+1] == 0)) ||
- (!istext && ((data[in] == '\r') || (data[in] == '\n'))) ||
- ((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) ||
- ((data[in] < 33) &&
- (data[in] != '\r') && (data[in] != '\n') &&
- (quotetabs || ((data[in] != '\t') && (data[in] != ' ')))))
+ if ((databuf[in] > 126) ||
+ (databuf[in] == '=') ||
+ (header && databuf[in] == '_') ||
+ ((databuf[in] == '.') && (linelen == 0) &&
+ (databuf[in+1] == '\n' || databuf[in+1] == '\r' || databuf[in+1] == 0)) ||
+ (!istext && ((databuf[in] == '\r') || (databuf[in] == '\n'))) ||
+ ((databuf[in] == '\t' || databuf[in] == ' ') && (in + 1 == datalen)) ||
+ ((databuf[in] < 33) &&
+ (databuf[in] != '\r') && (databuf[in] != '\n') &&
+ (quotetabs || ((databuf[in] != '\t') && (databuf[in] != ' ')))))
{
if ((linelen + 3) >= MAXLINESIZE) {
linelen = 0;
@@ -1382,26 +1403,26 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
}
else {
if (istext &&
- ((data[in] == '\n') ||
- ((in+1 < datalen) && (data[in] == '\r') &&
- (data[in+1] == '\n'))))
+ ((databuf[in] == '\n') ||
+ ((in+1 < datalen) && (databuf[in] == '\r') &&
+ (databuf[in+1] == '\n'))))
{
linelen = 0;
/* Protect against whitespace on end of line */
- if (in && ((data[in-1] == ' ') || (data[in-1] == '\t')))
+ if (in && ((databuf[in-1] == ' ') || (databuf[in-1] == '\t')))
odatalen += 2;
if (crlf)
odatalen += 2;
else
odatalen += 1;
- if (data[in] == '\r')
+ if (databuf[in] == '\r')
in += 2;
else
in++;
}
else {
if ((in + 1 != datalen) &&
- (data[in+1] != '\n') &&
+ (databuf[in+1] != '\n') &&
(linelen + 1) >= MAXLINESIZE) {
linelen = 0;
if (crlf)
@@ -1422,7 +1443,6 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
*/
odata = (unsigned char *) PyMem_Malloc(odatalen);
if (odata == NULL) {
- PyBuffer_Release(&pdata);
PyErr_NoMemory();
return NULL;
}
@@ -1430,17 +1450,17 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
in = out = linelen = 0;
while (in < datalen) {
- if ((data[in] > 126) ||
- (data[in] == '=') ||
- (header && data[in] == '_') ||
- ((data[in] == '.') && (linelen == 0) &&
- (data[in+1] == '\n' || data[in+1] == '\r' || data[in+1] == 0)) ||
- (!istext && ((data[in] == '\r') || (data[in] == '\n'))) ||
- ((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) ||
- ((data[in] < 33) &&
- (data[in] != '\r') && (data[in] != '\n') &&
+ if ((databuf[in] > 126) ||
+ (databuf[in] == '=') ||
+ (header && databuf[in] == '_') ||
+ ((databuf[in] == '.') && (linelen == 0) &&
+ (databuf[in+1] == '\n' || databuf[in+1] == '\r' || databuf[in+1] == 0)) ||
+ (!istext && ((databuf[in] == '\r') || (databuf[in] == '\n'))) ||
+ ((databuf[in] == '\t' || databuf[in] == ' ') && (in + 1 == datalen)) ||
+ ((databuf[in] < 33) &&
+ (databuf[in] != '\r') && (databuf[in] != '\n') &&
(quotetabs ||
- (!quotetabs && ((data[in] != '\t') && (data[in] != ' '))))))
+ (!quotetabs && ((databuf[in] != '\t') && (databuf[in] != ' '))))))
{
if ((linelen + 3 )>= MAXLINESIZE) {
odata[out++] = '=';
@@ -1449,16 +1469,16 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
linelen = 0;
}
odata[out++] = '=';
- to_hex(data[in], &odata[out]);
+ to_hex(databuf[in], &odata[out]);
out += 2;
in++;
linelen += 3;
}
else {
if (istext &&
- ((data[in] == '\n') ||
- ((in+1 < datalen) && (data[in] == '\r') &&
- (data[in+1] == '\n'))))
+ ((databuf[in] == '\n') ||
+ ((in+1 < datalen) && (databuf[in] == '\r') &&
+ (databuf[in+1] == '\n'))))
{
linelen = 0;
/* Protect against whitespace on end of line */
@@ -1471,14 +1491,14 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
if (crlf) odata[out++] = '\r';
odata[out++] = '\n';
- if (data[in] == '\r')
+ if (databuf[in] == '\r')
in += 2;
else
in++;
}
else {
if ((in + 1 != datalen) &&
- (data[in+1] != '\n') &&
+ (databuf[in+1] != '\n') &&
(linelen + 1) >= MAXLINESIZE) {
odata[out++] = '=';
if (crlf) odata[out++] = '\r';
@@ -1486,22 +1506,20 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
linelen = 0;
}
linelen++;
- if (header && data[in] == ' ') {
+ if (header && databuf[in] == ' ') {
odata[out++] = '_';
in++;
}
else {
- odata[out++] = data[in++];
+ odata[out++] = databuf[in++];
}
}
}
}
if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) {
- PyBuffer_Release(&pdata);
PyMem_Free(odata);
return NULL;
}
- PyBuffer_Release(&pdata);
PyMem_Free(odata);
return rv;
}
@@ -1509,25 +1527,24 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
/* List of functions defined in the module */
static struct PyMethodDef binascii_module_methods[] = {
- {"a2b_uu", binascii_a2b_uu, METH_VARARGS, doc_a2b_uu},
- {"b2a_uu", binascii_b2a_uu, METH_VARARGS, doc_b2a_uu},
- {"a2b_base64", binascii_a2b_base64, METH_VARARGS, doc_a2b_base64},
- {"b2a_base64", binascii_b2a_base64, METH_VARARGS, doc_b2a_base64},
- {"a2b_hqx", binascii_a2b_hqx, METH_VARARGS, doc_a2b_hqx},
- {"b2a_hqx", binascii_b2a_hqx, METH_VARARGS, doc_b2a_hqx},
- {"b2a_hex", binascii_hexlify, METH_VARARGS, doc_hexlify},
- {"a2b_hex", binascii_unhexlify, METH_VARARGS, doc_unhexlify},
- {"hexlify", binascii_hexlify, METH_VARARGS, doc_hexlify},
- {"unhexlify", binascii_unhexlify, METH_VARARGS, doc_unhexlify},
- {"rlecode_hqx", binascii_rlecode_hqx, METH_VARARGS, doc_rlecode_hqx},
- {"rledecode_hqx", binascii_rledecode_hqx, METH_VARARGS,
- doc_rledecode_hqx},
- {"crc_hqx", binascii_crc_hqx, METH_VARARGS, doc_crc_hqx},
- {"crc32", binascii_crc32, METH_VARARGS, doc_crc32},
- {"a2b_qp", (PyCFunction)binascii_a2b_qp, METH_VARARGS | METH_KEYWORDS,
- doc_a2b_qp},
- {"b2a_qp", (PyCFunction)binascii_b2a_qp, METH_VARARGS | METH_KEYWORDS,
- doc_b2a_qp},
+ BINASCII_A2B_UU_METHODDEF
+ BINASCII_B2A_UU_METHODDEF
+ BINASCII_A2B_BASE64_METHODDEF
+ BINASCII_B2A_BASE64_METHODDEF
+ BINASCII_A2B_HQX_METHODDEF
+ BINASCII_B2A_HQX_METHODDEF
+ BINASCII_A2B_HEX_METHODDEF
+ BINASCII_B2A_HEX_METHODDEF
+ {"unhexlify", (PyCFunction)binascii_a2b_hex, METH_VARARGS,
+ binascii_a2b_hex__doc__},
+ {"hexlify", (PyCFunction)binascii_b2a_hex, METH_VARARGS,
+ binascii_b2a_hex__doc__},
+ BINASCII_RLECODE_HQX_METHODDEF
+ BINASCII_RLEDECODE_HQX_METHODDEF
+ BINASCII_CRC_HQX_METHODDEF
+ BINASCII_CRC32_METHODDEF
+ BINASCII_A2B_QP_METHODDEF
+ BINASCII_B2A_QP_METHODDEF
{NULL, NULL} /* sentinel */
};
diff --git a/Modules/clinic/_bz2module.c.h b/Modules/clinic/_bz2module.c.h
new file mode 100644
index 0000000000..161100234c
--- /dev/null
+++ b/Modules/clinic/_bz2module.c.h
@@ -0,0 +1,152 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(_bz2_BZ2Compressor_compress__doc__,
+"compress(self, data)\n"
+"Provide data to the compressor object.\n"
+"\n"
+"Returns a chunk of compressed data if possible, or b\'\' otherwise.\n"
+"\n"
+"When you have finished providing data to the compressor, call the\n"
+"flush() method to finish the compression process.");
+
+#define _BZ2_BZ2COMPRESSOR_COMPRESS_METHODDEF \
+ {"compress", (PyCFunction)_bz2_BZ2Compressor_compress, METH_VARARGS, _bz2_BZ2Compressor_compress__doc__},
+
+static PyObject *
+_bz2_BZ2Compressor_compress_impl(BZ2Compressor *self, Py_buffer *data);
+
+static PyObject *
+_bz2_BZ2Compressor_compress(BZ2Compressor *self, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "y*:compress",
+ &data))
+ goto exit;
+ return_value = _bz2_BZ2Compressor_compress_impl(self, &data);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(_bz2_BZ2Compressor_flush__doc__,
+"flush(self)\n"
+"Finish the compression process.\n"
+"\n"
+"Returns the compressed data left in internal buffers.\n"
+"\n"
+"The compressor object may not be used after this method is called.");
+
+#define _BZ2_BZ2COMPRESSOR_FLUSH_METHODDEF \
+ {"flush", (PyCFunction)_bz2_BZ2Compressor_flush, METH_NOARGS, _bz2_BZ2Compressor_flush__doc__},
+
+static PyObject *
+_bz2_BZ2Compressor_flush_impl(BZ2Compressor *self);
+
+static PyObject *
+_bz2_BZ2Compressor_flush(BZ2Compressor *self, PyObject *Py_UNUSED(ignored))
+{
+ return _bz2_BZ2Compressor_flush_impl(self);
+}
+
+PyDoc_STRVAR(_bz2_BZ2Compressor___init____doc__,
+"BZ2Compressor(compresslevel=9)\n"
+"Create a compressor object for compressing data incrementally.\n"
+"\n"
+" compresslevel\n"
+" Compression level, as a number between 1 and 9.\n"
+"\n"
+"For one-shot compression, use the compress() function instead.");
+
+static int
+_bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel);
+
+static int
+_bz2_BZ2Compressor___init__(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ int return_value = -1;
+ int compresslevel = 9;
+
+ if ((Py_TYPE(self) == &BZ2Compressor_Type) &&
+ !_PyArg_NoKeywords("BZ2Compressor", kwargs))
+ goto exit;
+ if (!PyArg_ParseTuple(args,
+ "|i:BZ2Compressor",
+ &compresslevel))
+ goto exit;
+ return_value = _bz2_BZ2Compressor___init___impl((BZ2Compressor *)self, compresslevel);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_bz2_BZ2Decompressor_decompress__doc__,
+"decompress(self, data)\n"
+"Provide data to the decompressor object.\n"
+"\n"
+"Returns a chunk of decompressed data if possible, or b\'\' otherwise.\n"
+"\n"
+"Attempting to decompress data after the end of stream is reached\n"
+"raises an EOFError. Any data found after the end of the stream\n"
+"is ignored and saved in the unused_data attribute.");
+
+#define _BZ2_BZ2DECOMPRESSOR_DECOMPRESS_METHODDEF \
+ {"decompress", (PyCFunction)_bz2_BZ2Decompressor_decompress, METH_VARARGS, _bz2_BZ2Decompressor_decompress__doc__},
+
+static PyObject *
+_bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data);
+
+static PyObject *
+_bz2_BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "y*:decompress",
+ &data))
+ goto exit;
+ return_value = _bz2_BZ2Decompressor_decompress_impl(self, &data);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(_bz2_BZ2Decompressor___init____doc__,
+"BZ2Decompressor()\n"
+"Create a decompressor object for decompressing data incrementally.\n"
+"\n"
+"For one-shot decompression, use the decompress() function instead.");
+
+static int
+_bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self);
+
+static int
+_bz2_BZ2Decompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ int return_value = -1;
+
+ if ((Py_TYPE(self) == &BZ2Decompressor_Type) &&
+ !_PyArg_NoPositional("BZ2Decompressor", args))
+ goto exit;
+ if ((Py_TYPE(self) == &BZ2Decompressor_Type) &&
+ !_PyArg_NoKeywords("BZ2Decompressor", kwargs))
+ goto exit;
+ return_value = _bz2_BZ2Decompressor___init___impl((BZ2Decompressor *)self);
+
+exit:
+ return return_value;
+}
+/*[clinic end generated code: checksum=4ade1dba3921a8bd8a614e5417f7654d8fb10be5]*/
diff --git a/Modules/clinic/_lzmamodule.c.h b/Modules/clinic/_lzmamodule.c.h
new file mode 100644
index 0000000000..171354b91e
--- /dev/null
+++ b/Modules/clinic/_lzmamodule.c.h
@@ -0,0 +1,231 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(_lzma_LZMACompressor_compress__doc__,
+"compress(self, data)\n"
+"Provide data to the compressor object.\n"
+"\n"
+"Returns a chunk of compressed data if possible, or b\'\' otherwise.\n"
+"\n"
+"When you have finished providing data to the compressor, call the\n"
+"flush() method to finish the compression process.");
+
+#define _LZMA_LZMACOMPRESSOR_COMPRESS_METHODDEF \
+ {"compress", (PyCFunction)_lzma_LZMACompressor_compress, METH_VARARGS, _lzma_LZMACompressor_compress__doc__},
+
+static PyObject *
+_lzma_LZMACompressor_compress_impl(Compressor *self, Py_buffer *data);
+
+static PyObject *
+_lzma_LZMACompressor_compress(Compressor *self, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "y*:compress",
+ &data))
+ goto exit;
+ return_value = _lzma_LZMACompressor_compress_impl(self, &data);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(_lzma_LZMACompressor_flush__doc__,
+"flush(self)\n"
+"Finish the compression process.\n"
+"\n"
+"Returns the compressed data left in internal buffers.\n"
+"\n"
+"The compressor object may not be used after this method is called.");
+
+#define _LZMA_LZMACOMPRESSOR_FLUSH_METHODDEF \
+ {"flush", (PyCFunction)_lzma_LZMACompressor_flush, METH_NOARGS, _lzma_LZMACompressor_flush__doc__},
+
+static PyObject *
+_lzma_LZMACompressor_flush_impl(Compressor *self);
+
+static PyObject *
+_lzma_LZMACompressor_flush(Compressor *self, PyObject *Py_UNUSED(ignored))
+{
+ return _lzma_LZMACompressor_flush_impl(self);
+}
+
+PyDoc_STRVAR(_lzma_LZMADecompressor_decompress__doc__,
+"decompress(self, data)\n"
+"Provide data to the decompressor object.\n"
+"\n"
+"Returns a chunk of decompressed data if possible, or b\'\' otherwise.\n"
+"\n"
+"Attempting to decompress data after the end of stream is reached\n"
+"raises an EOFError. Any data found after the end of the stream\n"
+"is ignored and saved in the unused_data attribute.");
+
+#define _LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF \
+ {"decompress", (PyCFunction)_lzma_LZMADecompressor_decompress, METH_VARARGS, _lzma_LZMADecompressor_decompress__doc__},
+
+static PyObject *
+_lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data);
+
+static PyObject *
+_lzma_LZMADecompressor_decompress(Decompressor *self, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "y*:decompress",
+ &data))
+ goto exit;
+ return_value = _lzma_LZMADecompressor_decompress_impl(self, &data);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(_lzma_LZMADecompressor___init____doc__,
+"LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None)\n"
+"Create a decompressor object for decompressing data incrementally.\n"
+"\n"
+" format\n"
+" Specifies the container format of the input stream. If this is\n"
+" FORMAT_AUTO (the default), the decompressor will automatically detect\n"
+" whether the input is FORMAT_XZ or FORMAT_ALONE. Streams created with\n"
+" FORMAT_RAW cannot be autodetected.\n"
+" memlimit\n"
+" Limit the amount of memory used by the decompressor. This will cause\n"
+" decompression to fail if the input cannot be decompressed within the\n"
+" given limit.\n"
+" filters\n"
+" A custom filter chain. This argument is required for FORMAT_RAW, and\n"
+" not accepted with any other format. When provided, this should be a\n"
+" sequence of dicts, each indicating the ID and options for a single\n"
+" filter.\n"
+"\n"
+"For one-shot decompression, use the decompress() function instead.");
+
+static int
+_lzma_LZMADecompressor___init___impl(Decompressor *self, int format, PyObject *memlimit, PyObject *filters);
+
+static int
+_lzma_LZMADecompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ int return_value = -1;
+ static char *_keywords[] = {"format", "memlimit", "filters", NULL};
+ int format = FORMAT_AUTO;
+ PyObject *memlimit = Py_None;
+ PyObject *filters = Py_None;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "|iOO:LZMADecompressor", _keywords,
+ &format, &memlimit, &filters))
+ goto exit;
+ return_value = _lzma_LZMADecompressor___init___impl((Decompressor *)self, format, memlimit, filters);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_lzma_is_check_supported__doc__,
+"is_check_supported(module, check_id)\n"
+"Test whether the given integrity check is supported.\n"
+"\n"
+"Always returns True for CHECK_NONE and CHECK_CRC32.");
+
+#define _LZMA_IS_CHECK_SUPPORTED_METHODDEF \
+ {"is_check_supported", (PyCFunction)_lzma_is_check_supported, METH_VARARGS, _lzma_is_check_supported__doc__},
+
+static PyObject *
+_lzma_is_check_supported_impl(PyModuleDef *module, int check_id);
+
+static PyObject *
+_lzma_is_check_supported(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ int check_id;
+
+ if (!PyArg_ParseTuple(args,
+ "i:is_check_supported",
+ &check_id))
+ goto exit;
+ return_value = _lzma_is_check_supported_impl(module, check_id);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_lzma__encode_filter_properties__doc__,
+"_encode_filter_properties(module, filter)\n"
+"Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).\n"
+"\n"
+"The result does not include the filter ID itself, only the options.");
+
+#define _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF \
+ {"_encode_filter_properties", (PyCFunction)_lzma__encode_filter_properties, METH_VARARGS, _lzma__encode_filter_properties__doc__},
+
+static PyObject *
+_lzma__encode_filter_properties_impl(PyModuleDef *module, lzma_filter filter);
+
+static PyObject *
+_lzma__encode_filter_properties(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ lzma_filter filter = {LZMA_VLI_UNKNOWN, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "O&:_encode_filter_properties",
+ lzma_filter_converter, &filter))
+ goto exit;
+ return_value = _lzma__encode_filter_properties_impl(module, filter);
+
+exit:
+ /* Cleanup for filter */
+ if (filter.id != LZMA_VLI_UNKNOWN)
+ PyMem_Free(filter.options);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(_lzma__decode_filter_properties__doc__,
+"_decode_filter_properties(module, filter_id, encoded_props)\n"
+"Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).\n"
+"\n"
+"The result does not include the filter ID itself, only the options.");
+
+#define _LZMA__DECODE_FILTER_PROPERTIES_METHODDEF \
+ {"_decode_filter_properties", (PyCFunction)_lzma__decode_filter_properties, METH_VARARGS, _lzma__decode_filter_properties__doc__},
+
+static PyObject *
+_lzma__decode_filter_properties_impl(PyModuleDef *module, lzma_vli filter_id, Py_buffer *encoded_props);
+
+static PyObject *
+_lzma__decode_filter_properties(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ lzma_vli filter_id;
+ Py_buffer encoded_props = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "O&y*:_decode_filter_properties",
+ lzma_vli_converter, &filter_id, &encoded_props))
+ goto exit;
+ return_value = _lzma__decode_filter_properties_impl(module, filter_id, &encoded_props);
+
+exit:
+ /* Cleanup for encoded_props */
+ if (encoded_props.obj)
+ PyBuffer_Release(&encoded_props);
+
+ return return_value;
+}
+/*[clinic end generated code: checksum=b4b90dcbd0c9c349c3a94e26a7eecf71aab179a0]*/
diff --git a/Modules/clinic/audioop.c.h b/Modules/clinic/audioop.c.h
new file mode 100644
index 0000000000..974fdb1df5
--- /dev/null
+++ b/Modules/clinic/audioop.c.h
@@ -0,0 +1,836 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(audioop_getsample__doc__,
+"getsample(module, fragment, width, index)\n"
+"Return the value of sample index from the fragment.");
+
+#define AUDIOOP_GETSAMPLE_METHODDEF \
+ {"getsample", (PyCFunction)audioop_getsample, METH_VARARGS, audioop_getsample__doc__},
+
+static PyObject *
+audioop_getsample_impl(PyModuleDef *module, Py_buffer *fragment, int width, Py_ssize_t index);
+
+static PyObject *
+audioop_getsample(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+ Py_ssize_t index;
+
+ if (!PyArg_ParseTuple(args,
+ "y*in:getsample",
+ &fragment, &width, &index))
+ goto exit;
+ return_value = audioop_getsample_impl(module, &fragment, width, index);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_max__doc__,
+"max(module, fragment, width)\n"
+"Return the maximum of the absolute value of all samples in a fragment.");
+
+#define AUDIOOP_MAX_METHODDEF \
+ {"max", (PyCFunction)audioop_max, METH_VARARGS, audioop_max__doc__},
+
+static PyObject *
+audioop_max_impl(PyModuleDef *module, Py_buffer *fragment, int width);
+
+static PyObject *
+audioop_max(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+
+ if (!PyArg_ParseTuple(args,
+ "y*i:max",
+ &fragment, &width))
+ goto exit;
+ return_value = audioop_max_impl(module, &fragment, width);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_minmax__doc__,
+"minmax(module, fragment, width)\n"
+"Return the minimum and maximum values of all samples in the sound fragment.");
+
+#define AUDIOOP_MINMAX_METHODDEF \
+ {"minmax", (PyCFunction)audioop_minmax, METH_VARARGS, audioop_minmax__doc__},
+
+static PyObject *
+audioop_minmax_impl(PyModuleDef *module, Py_buffer *fragment, int width);
+
+static PyObject *
+audioop_minmax(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+
+ if (!PyArg_ParseTuple(args,
+ "y*i:minmax",
+ &fragment, &width))
+ goto exit;
+ return_value = audioop_minmax_impl(module, &fragment, width);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_avg__doc__,
+"avg(module, fragment, width)\n"
+"Return the average over all samples in the fragment.");
+
+#define AUDIOOP_AVG_METHODDEF \
+ {"avg", (PyCFunction)audioop_avg, METH_VARARGS, audioop_avg__doc__},
+
+static PyObject *
+audioop_avg_impl(PyModuleDef *module, Py_buffer *fragment, int width);
+
+static PyObject *
+audioop_avg(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+
+ if (!PyArg_ParseTuple(args,
+ "y*i:avg",
+ &fragment, &width))
+ goto exit;
+ return_value = audioop_avg_impl(module, &fragment, width);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_rms__doc__,
+"rms(module, fragment, width)\n"
+"Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n).");
+
+#define AUDIOOP_RMS_METHODDEF \
+ {"rms", (PyCFunction)audioop_rms, METH_VARARGS, audioop_rms__doc__},
+
+static PyObject *
+audioop_rms_impl(PyModuleDef *module, Py_buffer *fragment, int width);
+
+static PyObject *
+audioop_rms(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+
+ if (!PyArg_ParseTuple(args,
+ "y*i:rms",
+ &fragment, &width))
+ goto exit;
+ return_value = audioop_rms_impl(module, &fragment, width);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_findfit__doc__,
+"findfit(module, fragment, reference)\n"
+"Try to match reference as well as possible to a portion of fragment.");
+
+#define AUDIOOP_FINDFIT_METHODDEF \
+ {"findfit", (PyCFunction)audioop_findfit, METH_VARARGS, audioop_findfit__doc__},
+
+static PyObject *
+audioop_findfit_impl(PyModuleDef *module, Py_buffer *fragment, Py_buffer *reference);
+
+static PyObject *
+audioop_findfit(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ Py_buffer reference = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "y*y*:findfit",
+ &fragment, &reference))
+ goto exit;
+ return_value = audioop_findfit_impl(module, &fragment, &reference);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+ /* Cleanup for reference */
+ if (reference.obj)
+ PyBuffer_Release(&reference);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_findfactor__doc__,
+"findfactor(module, fragment, reference)\n"
+"Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal.");
+
+#define AUDIOOP_FINDFACTOR_METHODDEF \
+ {"findfactor", (PyCFunction)audioop_findfactor, METH_VARARGS, audioop_findfactor__doc__},
+
+static PyObject *
+audioop_findfactor_impl(PyModuleDef *module, Py_buffer *fragment, Py_buffer *reference);
+
+static PyObject *
+audioop_findfactor(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ Py_buffer reference = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "y*y*:findfactor",
+ &fragment, &reference))
+ goto exit;
+ return_value = audioop_findfactor_impl(module, &fragment, &reference);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+ /* Cleanup for reference */
+ if (reference.obj)
+ PyBuffer_Release(&reference);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_findmax__doc__,
+"findmax(module, fragment, length)\n"
+"Search fragment for a slice of specified number of samples with maximum energy.");
+
+#define AUDIOOP_FINDMAX_METHODDEF \
+ {"findmax", (PyCFunction)audioop_findmax, METH_VARARGS, audioop_findmax__doc__},
+
+static PyObject *
+audioop_findmax_impl(PyModuleDef *module, Py_buffer *fragment, Py_ssize_t length);
+
+static PyObject *
+audioop_findmax(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ Py_ssize_t length;
+
+ if (!PyArg_ParseTuple(args,
+ "y*n:findmax",
+ &fragment, &length))
+ goto exit;
+ return_value = audioop_findmax_impl(module, &fragment, length);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_avgpp__doc__,
+"avgpp(module, fragment, width)\n"
+"Return the average peak-peak value over all samples in the fragment.");
+
+#define AUDIOOP_AVGPP_METHODDEF \
+ {"avgpp", (PyCFunction)audioop_avgpp, METH_VARARGS, audioop_avgpp__doc__},
+
+static PyObject *
+audioop_avgpp_impl(PyModuleDef *module, Py_buffer *fragment, int width);
+
+static PyObject *
+audioop_avgpp(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+
+ if (!PyArg_ParseTuple(args,
+ "y*i:avgpp",
+ &fragment, &width))
+ goto exit;
+ return_value = audioop_avgpp_impl(module, &fragment, width);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_maxpp__doc__,
+"maxpp(module, fragment, width)\n"
+"Return the maximum peak-peak value in the sound fragment.");
+
+#define AUDIOOP_MAXPP_METHODDEF \
+ {"maxpp", (PyCFunction)audioop_maxpp, METH_VARARGS, audioop_maxpp__doc__},
+
+static PyObject *
+audioop_maxpp_impl(PyModuleDef *module, Py_buffer *fragment, int width);
+
+static PyObject *
+audioop_maxpp(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+
+ if (!PyArg_ParseTuple(args,
+ "y*i:maxpp",
+ &fragment, &width))
+ goto exit;
+ return_value = audioop_maxpp_impl(module, &fragment, width);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_cross__doc__,
+"cross(module, fragment, width)\n"
+"Return the number of zero crossings in the fragment passed as an argument.");
+
+#define AUDIOOP_CROSS_METHODDEF \
+ {"cross", (PyCFunction)audioop_cross, METH_VARARGS, audioop_cross__doc__},
+
+static PyObject *
+audioop_cross_impl(PyModuleDef *module, Py_buffer *fragment, int width);
+
+static PyObject *
+audioop_cross(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+
+ if (!PyArg_ParseTuple(args,
+ "y*i:cross",
+ &fragment, &width))
+ goto exit;
+ return_value = audioop_cross_impl(module, &fragment, width);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_mul__doc__,
+"mul(module, fragment, width, factor)\n"
+"Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor.");
+
+#define AUDIOOP_MUL_METHODDEF \
+ {"mul", (PyCFunction)audioop_mul, METH_VARARGS, audioop_mul__doc__},
+
+static PyObject *
+audioop_mul_impl(PyModuleDef *module, Py_buffer *fragment, int width, double factor);
+
+static PyObject *
+audioop_mul(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+ double factor;
+
+ if (!PyArg_ParseTuple(args,
+ "y*id:mul",
+ &fragment, &width, &factor))
+ goto exit;
+ return_value = audioop_mul_impl(module, &fragment, width, factor);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_tomono__doc__,
+"tomono(module, fragment, width, lfactor, rfactor)\n"
+"Convert a stereo fragment to a mono fragment.");
+
+#define AUDIOOP_TOMONO_METHODDEF \
+ {"tomono", (PyCFunction)audioop_tomono, METH_VARARGS, audioop_tomono__doc__},
+
+static PyObject *
+audioop_tomono_impl(PyModuleDef *module, Py_buffer *fragment, int width, double lfactor, double rfactor);
+
+static PyObject *
+audioop_tomono(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+ double lfactor;
+ double rfactor;
+
+ if (!PyArg_ParseTuple(args,
+ "y*idd:tomono",
+ &fragment, &width, &lfactor, &rfactor))
+ goto exit;
+ return_value = audioop_tomono_impl(module, &fragment, width, lfactor, rfactor);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_tostereo__doc__,
+"tostereo(module, fragment, width, lfactor, rfactor)\n"
+"Generate a stereo fragment from a mono fragment.");
+
+#define AUDIOOP_TOSTEREO_METHODDEF \
+ {"tostereo", (PyCFunction)audioop_tostereo, METH_VARARGS, audioop_tostereo__doc__},
+
+static PyObject *
+audioop_tostereo_impl(PyModuleDef *module, Py_buffer *fragment, int width, double lfactor, double rfactor);
+
+static PyObject *
+audioop_tostereo(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+ double lfactor;
+ double rfactor;
+
+ if (!PyArg_ParseTuple(args,
+ "y*idd:tostereo",
+ &fragment, &width, &lfactor, &rfactor))
+ goto exit;
+ return_value = audioop_tostereo_impl(module, &fragment, width, lfactor, rfactor);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_add__doc__,
+"add(module, fragment1, fragment2, width)\n"
+"Return a fragment which is the addition of the two samples passed as parameters.");
+
+#define AUDIOOP_ADD_METHODDEF \
+ {"add", (PyCFunction)audioop_add, METH_VARARGS, audioop_add__doc__},
+
+static PyObject *
+audioop_add_impl(PyModuleDef *module, Py_buffer *fragment1, Py_buffer *fragment2, int width);
+
+static PyObject *
+audioop_add(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment1 = {NULL, NULL};
+ Py_buffer fragment2 = {NULL, NULL};
+ int width;
+
+ if (!PyArg_ParseTuple(args,
+ "y*y*i:add",
+ &fragment1, &fragment2, &width))
+ goto exit;
+ return_value = audioop_add_impl(module, &fragment1, &fragment2, width);
+
+exit:
+ /* Cleanup for fragment1 */
+ if (fragment1.obj)
+ PyBuffer_Release(&fragment1);
+ /* Cleanup for fragment2 */
+ if (fragment2.obj)
+ PyBuffer_Release(&fragment2);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_bias__doc__,
+"bias(module, fragment, width, bias)\n"
+"Return a fragment that is the original fragment with a bias added to each sample.");
+
+#define AUDIOOP_BIAS_METHODDEF \
+ {"bias", (PyCFunction)audioop_bias, METH_VARARGS, audioop_bias__doc__},
+
+static PyObject *
+audioop_bias_impl(PyModuleDef *module, Py_buffer *fragment, int width, int bias);
+
+static PyObject *
+audioop_bias(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+ int bias;
+
+ if (!PyArg_ParseTuple(args,
+ "y*ii:bias",
+ &fragment, &width, &bias))
+ goto exit;
+ return_value = audioop_bias_impl(module, &fragment, width, bias);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_reverse__doc__,
+"reverse(module, fragment, width)\n"
+"Reverse the samples in a fragment and returns the modified fragment.");
+
+#define AUDIOOP_REVERSE_METHODDEF \
+ {"reverse", (PyCFunction)audioop_reverse, METH_VARARGS, audioop_reverse__doc__},
+
+static PyObject *
+audioop_reverse_impl(PyModuleDef *module, Py_buffer *fragment, int width);
+
+static PyObject *
+audioop_reverse(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+
+ if (!PyArg_ParseTuple(args,
+ "y*i:reverse",
+ &fragment, &width))
+ goto exit;
+ return_value = audioop_reverse_impl(module, &fragment, width);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_byteswap__doc__,
+"byteswap(module, fragment, width)\n"
+"Convert big-endian samples to little-endian and vice versa.");
+
+#define AUDIOOP_BYTESWAP_METHODDEF \
+ {"byteswap", (PyCFunction)audioop_byteswap, METH_VARARGS, audioop_byteswap__doc__},
+
+static PyObject *
+audioop_byteswap_impl(PyModuleDef *module, Py_buffer *fragment, int width);
+
+static PyObject *
+audioop_byteswap(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+
+ if (!PyArg_ParseTuple(args,
+ "y*i:byteswap",
+ &fragment, &width))
+ goto exit;
+ return_value = audioop_byteswap_impl(module, &fragment, width);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_lin2lin__doc__,
+"lin2lin(module, fragment, width, newwidth)\n"
+"Convert samples between 1-, 2-, 3- and 4-byte formats.");
+
+#define AUDIOOP_LIN2LIN_METHODDEF \
+ {"lin2lin", (PyCFunction)audioop_lin2lin, METH_VARARGS, audioop_lin2lin__doc__},
+
+static PyObject *
+audioop_lin2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width, int newwidth);
+
+static PyObject *
+audioop_lin2lin(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+ int newwidth;
+
+ if (!PyArg_ParseTuple(args,
+ "y*ii:lin2lin",
+ &fragment, &width, &newwidth))
+ goto exit;
+ return_value = audioop_lin2lin_impl(module, &fragment, width, newwidth);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_ratecv__doc__,
+"ratecv(module, fragment, width, nchannels, inrate, outrate, state, weightA=1, weightB=0)\n"
+"Convert the frame rate of the input fragment.");
+
+#define AUDIOOP_RATECV_METHODDEF \
+ {"ratecv", (PyCFunction)audioop_ratecv, METH_VARARGS, audioop_ratecv__doc__},
+
+static PyObject *
+audioop_ratecv_impl(PyModuleDef *module, Py_buffer *fragment, int width, int nchannels, int inrate, int outrate, PyObject *state, int weightA, int weightB);
+
+static PyObject *
+audioop_ratecv(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+ int nchannels;
+ int inrate;
+ int outrate;
+ PyObject *state;
+ int weightA = 1;
+ int weightB = 0;
+
+ if (!PyArg_ParseTuple(args,
+ "y*iiiiO|ii:ratecv",
+ &fragment, &width, &nchannels, &inrate, &outrate, &state, &weightA, &weightB))
+ goto exit;
+ return_value = audioop_ratecv_impl(module, &fragment, width, nchannels, inrate, outrate, state, weightA, weightB);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_lin2ulaw__doc__,
+"lin2ulaw(module, fragment, width)\n"
+"Convert samples in the audio fragment to u-LAW encoding.");
+
+#define AUDIOOP_LIN2ULAW_METHODDEF \
+ {"lin2ulaw", (PyCFunction)audioop_lin2ulaw, METH_VARARGS, audioop_lin2ulaw__doc__},
+
+static PyObject *
+audioop_lin2ulaw_impl(PyModuleDef *module, Py_buffer *fragment, int width);
+
+static PyObject *
+audioop_lin2ulaw(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+
+ if (!PyArg_ParseTuple(args,
+ "y*i:lin2ulaw",
+ &fragment, &width))
+ goto exit;
+ return_value = audioop_lin2ulaw_impl(module, &fragment, width);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_ulaw2lin__doc__,
+"ulaw2lin(module, fragment, width)\n"
+"Convert sound fragments in u-LAW encoding to linearly encoded sound fragments.");
+
+#define AUDIOOP_ULAW2LIN_METHODDEF \
+ {"ulaw2lin", (PyCFunction)audioop_ulaw2lin, METH_VARARGS, audioop_ulaw2lin__doc__},
+
+static PyObject *
+audioop_ulaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width);
+
+static PyObject *
+audioop_ulaw2lin(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+
+ if (!PyArg_ParseTuple(args,
+ "y*i:ulaw2lin",
+ &fragment, &width))
+ goto exit;
+ return_value = audioop_ulaw2lin_impl(module, &fragment, width);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_lin2alaw__doc__,
+"lin2alaw(module, fragment, width)\n"
+"Convert samples in the audio fragment to a-LAW encoding.");
+
+#define AUDIOOP_LIN2ALAW_METHODDEF \
+ {"lin2alaw", (PyCFunction)audioop_lin2alaw, METH_VARARGS, audioop_lin2alaw__doc__},
+
+static PyObject *
+audioop_lin2alaw_impl(PyModuleDef *module, Py_buffer *fragment, int width);
+
+static PyObject *
+audioop_lin2alaw(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+
+ if (!PyArg_ParseTuple(args,
+ "y*i:lin2alaw",
+ &fragment, &width))
+ goto exit;
+ return_value = audioop_lin2alaw_impl(module, &fragment, width);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_alaw2lin__doc__,
+"alaw2lin(module, fragment, width)\n"
+"Convert sound fragments in a-LAW encoding to linearly encoded sound fragments.");
+
+#define AUDIOOP_ALAW2LIN_METHODDEF \
+ {"alaw2lin", (PyCFunction)audioop_alaw2lin, METH_VARARGS, audioop_alaw2lin__doc__},
+
+static PyObject *
+audioop_alaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width);
+
+static PyObject *
+audioop_alaw2lin(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+
+ if (!PyArg_ParseTuple(args,
+ "y*i:alaw2lin",
+ &fragment, &width))
+ goto exit;
+ return_value = audioop_alaw2lin_impl(module, &fragment, width);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_lin2adpcm__doc__,
+"lin2adpcm(module, fragment, width, state)\n"
+"Convert samples to 4 bit Intel/DVI ADPCM encoding.");
+
+#define AUDIOOP_LIN2ADPCM_METHODDEF \
+ {"lin2adpcm", (PyCFunction)audioop_lin2adpcm, METH_VARARGS, audioop_lin2adpcm__doc__},
+
+static PyObject *
+audioop_lin2adpcm_impl(PyModuleDef *module, Py_buffer *fragment, int width, PyObject *state);
+
+static PyObject *
+audioop_lin2adpcm(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+ PyObject *state;
+
+ if (!PyArg_ParseTuple(args,
+ "y*iO:lin2adpcm",
+ &fragment, &width, &state))
+ goto exit;
+ return_value = audioop_lin2adpcm_impl(module, &fragment, width, state);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(audioop_adpcm2lin__doc__,
+"adpcm2lin(module, fragment, width, state)\n"
+"Decode an Intel/DVI ADPCM coded fragment to a linear fragment.");
+
+#define AUDIOOP_ADPCM2LIN_METHODDEF \
+ {"adpcm2lin", (PyCFunction)audioop_adpcm2lin, METH_VARARGS, audioop_adpcm2lin__doc__},
+
+static PyObject *
+audioop_adpcm2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width, PyObject *state);
+
+static PyObject *
+audioop_adpcm2lin(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer fragment = {NULL, NULL};
+ int width;
+ PyObject *state;
+
+ if (!PyArg_ParseTuple(args,
+ "y*iO:adpcm2lin",
+ &fragment, &width, &state))
+ goto exit;
+ return_value = audioop_adpcm2lin_impl(module, &fragment, width, state);
+
+exit:
+ /* Cleanup for fragment */
+ if (fragment.obj)
+ PyBuffer_Release(&fragment);
+
+ return return_value;
+}
+/*[clinic end generated code: checksum=0d9fa2c5719e996b169f808350016cd622799562]*/
diff --git a/Modules/clinic/binascii.c.h b/Modules/clinic/binascii.c.h
new file mode 100644
index 0000000000..cbafc68efa
--- /dev/null
+++ b/Modules/clinic/binascii.c.h
@@ -0,0 +1,450 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(binascii_a2b_uu__doc__,
+"a2b_uu(module, data)\n"
+"Decode a line of uuencoded data.");
+
+#define BINASCII_A2B_UU_METHODDEF \
+ {"a2b_uu", (PyCFunction)binascii_a2b_uu, METH_VARARGS, binascii_a2b_uu__doc__},
+
+static PyObject *
+binascii_a2b_uu_impl(PyModuleDef *module, Py_buffer *data);
+
+static PyObject *
+binascii_a2b_uu(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "O&:a2b_uu",
+ ascii_buffer_converter, &data))
+ goto exit;
+ return_value = binascii_a2b_uu_impl(module, &data);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(binascii_b2a_uu__doc__,
+"b2a_uu(module, data)\n"
+"Uuencode line of data.");
+
+#define BINASCII_B2A_UU_METHODDEF \
+ {"b2a_uu", (PyCFunction)binascii_b2a_uu, METH_VARARGS, binascii_b2a_uu__doc__},
+
+static PyObject *
+binascii_b2a_uu_impl(PyModuleDef *module, Py_buffer *data);
+
+static PyObject *
+binascii_b2a_uu(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "y*:b2a_uu",
+ &data))
+ goto exit;
+ return_value = binascii_b2a_uu_impl(module, &data);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(binascii_a2b_base64__doc__,
+"a2b_base64(module, data)\n"
+"Decode a line of base64 data.");
+
+#define BINASCII_A2B_BASE64_METHODDEF \
+ {"a2b_base64", (PyCFunction)binascii_a2b_base64, METH_VARARGS, binascii_a2b_base64__doc__},
+
+static PyObject *
+binascii_a2b_base64_impl(PyModuleDef *module, Py_buffer *data);
+
+static PyObject *
+binascii_a2b_base64(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "O&:a2b_base64",
+ ascii_buffer_converter, &data))
+ goto exit;
+ return_value = binascii_a2b_base64_impl(module, &data);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(binascii_b2a_base64__doc__,
+"b2a_base64(module, data)\n"
+"Base64-code line of data.");
+
+#define BINASCII_B2A_BASE64_METHODDEF \
+ {"b2a_base64", (PyCFunction)binascii_b2a_base64, METH_VARARGS, binascii_b2a_base64__doc__},
+
+static PyObject *
+binascii_b2a_base64_impl(PyModuleDef *module, Py_buffer *data);
+
+static PyObject *
+binascii_b2a_base64(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "y*:b2a_base64",
+ &data))
+ goto exit;
+ return_value = binascii_b2a_base64_impl(module, &data);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(binascii_a2b_hqx__doc__,
+"a2b_hqx(module, data)\n"
+"Decode .hqx coding.");
+
+#define BINASCII_A2B_HQX_METHODDEF \
+ {"a2b_hqx", (PyCFunction)binascii_a2b_hqx, METH_VARARGS, binascii_a2b_hqx__doc__},
+
+static PyObject *
+binascii_a2b_hqx_impl(PyModuleDef *module, Py_buffer *data);
+
+static PyObject *
+binascii_a2b_hqx(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "O&:a2b_hqx",
+ ascii_buffer_converter, &data))
+ goto exit;
+ return_value = binascii_a2b_hqx_impl(module, &data);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(binascii_rlecode_hqx__doc__,
+"rlecode_hqx(module, data)\n"
+"Binhex RLE-code binary data.");
+
+#define BINASCII_RLECODE_HQX_METHODDEF \
+ {"rlecode_hqx", (PyCFunction)binascii_rlecode_hqx, METH_VARARGS, binascii_rlecode_hqx__doc__},
+
+static PyObject *
+binascii_rlecode_hqx_impl(PyModuleDef *module, Py_buffer *data);
+
+static PyObject *
+binascii_rlecode_hqx(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "y*:rlecode_hqx",
+ &data))
+ goto exit;
+ return_value = binascii_rlecode_hqx_impl(module, &data);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(binascii_b2a_hqx__doc__,
+"b2a_hqx(module, data)\n"
+"Encode .hqx data.");
+
+#define BINASCII_B2A_HQX_METHODDEF \
+ {"b2a_hqx", (PyCFunction)binascii_b2a_hqx, METH_VARARGS, binascii_b2a_hqx__doc__},
+
+static PyObject *
+binascii_b2a_hqx_impl(PyModuleDef *module, Py_buffer *data);
+
+static PyObject *
+binascii_b2a_hqx(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "y*:b2a_hqx",
+ &data))
+ goto exit;
+ return_value = binascii_b2a_hqx_impl(module, &data);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(binascii_rledecode_hqx__doc__,
+"rledecode_hqx(module, data)\n"
+"Decode hexbin RLE-coded string.");
+
+#define BINASCII_RLEDECODE_HQX_METHODDEF \
+ {"rledecode_hqx", (PyCFunction)binascii_rledecode_hqx, METH_VARARGS, binascii_rledecode_hqx__doc__},
+
+static PyObject *
+binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data);
+
+static PyObject *
+binascii_rledecode_hqx(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "y*:rledecode_hqx",
+ &data))
+ goto exit;
+ return_value = binascii_rledecode_hqx_impl(module, &data);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(binascii_crc_hqx__doc__,
+"crc_hqx(module, data, crc)\n"
+"Compute hqx CRC incrementally.");
+
+#define BINASCII_CRC_HQX_METHODDEF \
+ {"crc_hqx", (PyCFunction)binascii_crc_hqx, METH_VARARGS, binascii_crc_hqx__doc__},
+
+static int
+binascii_crc_hqx_impl(PyModuleDef *module, Py_buffer *data, int crc);
+
+static PyObject *
+binascii_crc_hqx(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+ int crc;
+ int _return_value;
+
+ if (!PyArg_ParseTuple(args,
+ "y*i:crc_hqx",
+ &data, &crc))
+ goto exit;
+ _return_value = binascii_crc_hqx_impl(module, &data, crc);
+ if ((_return_value == -1) && PyErr_Occurred())
+ goto exit;
+ return_value = PyLong_FromLong((long)_return_value);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(binascii_crc32__doc__,
+"crc32(module, data, crc=0)\n"
+"Compute CRC-32 incrementally.");
+
+#define BINASCII_CRC32_METHODDEF \
+ {"crc32", (PyCFunction)binascii_crc32, METH_VARARGS, binascii_crc32__doc__},
+
+static unsigned int
+binascii_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc);
+
+static PyObject *
+binascii_crc32(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+ unsigned int crc = 0;
+ unsigned int _return_value;
+
+ if (!PyArg_ParseTuple(args,
+ "y*|I:crc32",
+ &data, &crc))
+ goto exit;
+ _return_value = binascii_crc32_impl(module, &data, crc);
+ if ((_return_value == -1) && PyErr_Occurred())
+ goto exit;
+ return_value = PyLong_FromUnsignedLong((unsigned long)_return_value);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(binascii_b2a_hex__doc__,
+"b2a_hex(module, data)\n"
+"Hexadecimal representation of binary data.\n"
+"\n"
+"The return value is a bytes object. This function is also\n"
+"available as \"hexlify()\".");
+
+#define BINASCII_B2A_HEX_METHODDEF \
+ {"b2a_hex", (PyCFunction)binascii_b2a_hex, METH_VARARGS, binascii_b2a_hex__doc__},
+
+static PyObject *
+binascii_b2a_hex_impl(PyModuleDef *module, Py_buffer *data);
+
+static PyObject *
+binascii_b2a_hex(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "y*:b2a_hex",
+ &data))
+ goto exit;
+ return_value = binascii_b2a_hex_impl(module, &data);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(binascii_a2b_hex__doc__,
+"a2b_hex(module, hexstr)\n"
+"Binary data of hexadecimal representation.\n"
+"\n"
+"hexstr must contain an even number of hex digits (upper or lower case).\n"
+"This function is also available as \"unhexlify()\".");
+
+#define BINASCII_A2B_HEX_METHODDEF \
+ {"a2b_hex", (PyCFunction)binascii_a2b_hex, METH_VARARGS, binascii_a2b_hex__doc__},
+
+static PyObject *
+binascii_a2b_hex_impl(PyModuleDef *module, Py_buffer *hexstr);
+
+static PyObject *
+binascii_a2b_hex(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer hexstr = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "O&:a2b_hex",
+ ascii_buffer_converter, &hexstr))
+ goto exit;
+ return_value = binascii_a2b_hex_impl(module, &hexstr);
+
+exit:
+ /* Cleanup for hexstr */
+ if (hexstr.obj)
+ PyBuffer_Release(&hexstr);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(binascii_a2b_qp__doc__,
+"a2b_qp(module, data, header=False)\n"
+"Decode a string of qp-encoded data.");
+
+#define BINASCII_A2B_QP_METHODDEF \
+ {"a2b_qp", (PyCFunction)binascii_a2b_qp, METH_VARARGS|METH_KEYWORDS, binascii_a2b_qp__doc__},
+
+static PyObject *
+binascii_a2b_qp_impl(PyModuleDef *module, Py_buffer *data, int header);
+
+static PyObject *
+binascii_a2b_qp(PyModuleDef *module, PyObject *args, PyObject *kwargs)
+{
+ PyObject *return_value = NULL;
+ static char *_keywords[] = {"data", "header", NULL};
+ Py_buffer data = {NULL, NULL};
+ int header = 0;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "O&|i:a2b_qp", _keywords,
+ ascii_buffer_converter, &data, &header))
+ goto exit;
+ return_value = binascii_a2b_qp_impl(module, &data, header);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(binascii_b2a_qp__doc__,
+"b2a_qp(module, data, quotetabs=False, istext=True, header=False)\n"
+"Encode a string using quoted-printable encoding.\n"
+"\n"
+"On encoding, when istext is set, newlines are not encoded, and white\n"
+"space at end of lines is. When istext is not set, \\r and \\n (CR/LF)\n"
+"are both encoded. When quotetabs is set, space and tabs are encoded.");
+
+#define BINASCII_B2A_QP_METHODDEF \
+ {"b2a_qp", (PyCFunction)binascii_b2a_qp, METH_VARARGS|METH_KEYWORDS, binascii_b2a_qp__doc__},
+
+static PyObject *
+binascii_b2a_qp_impl(PyModuleDef *module, Py_buffer *data, int quotetabs, int istext, int header);
+
+static PyObject *
+binascii_b2a_qp(PyModuleDef *module, PyObject *args, PyObject *kwargs)
+{
+ PyObject *return_value = NULL;
+ static char *_keywords[] = {"data", "quotetabs", "istext", "header", NULL};
+ Py_buffer data = {NULL, NULL};
+ int quotetabs = 0;
+ int istext = 1;
+ int header = 0;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "y*|iii:b2a_qp", _keywords,
+ &data, &quotetabs, &istext, &header))
+ goto exit;
+ return_value = binascii_b2a_qp_impl(module, &data, quotetabs, istext, header);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+/*[clinic end generated code: checksum=8180e5be47a110ae8c89263a7c12a91d80754f60]*/
diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h
new file mode 100644
index 0000000000..0adeb0164d
--- /dev/null
+++ b/Modules/clinic/zlibmodule.c.h
@@ -0,0 +1,411 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(zlib_compress__doc__,
+"compress(module, bytes, level=Z_DEFAULT_COMPRESSION)\n"
+"Returns a bytes object containing compressed data.\n"
+"\n"
+" bytes\n"
+" Binary data to be compressed.\n"
+" level\n"
+" Compression level, in 0-9.");
+
+#define ZLIB_COMPRESS_METHODDEF \
+ {"compress", (PyCFunction)zlib_compress, METH_VARARGS, zlib_compress__doc__},
+
+static PyObject *
+zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int level);
+
+static PyObject *
+zlib_compress(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer bytes = {NULL, NULL};
+ int level = Z_DEFAULT_COMPRESSION;
+
+ if (!PyArg_ParseTuple(args,
+ "y*|i:compress",
+ &bytes, &level))
+ goto exit;
+ return_value = zlib_compress_impl(module, &bytes, level);
+
+exit:
+ /* Cleanup for bytes */
+ if (bytes.obj)
+ PyBuffer_Release(&bytes);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(zlib_decompress__doc__,
+"decompress(module, data, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE)\n"
+"Returns a bytes object containing the uncompressed data.\n"
+"\n"
+" data\n"
+" Compressed data.\n"
+" wbits\n"
+" The window buffer size.\n"
+" bufsize\n"
+" The initial output buffer size.");
+
+#define ZLIB_DECOMPRESS_METHODDEF \
+ {"decompress", (PyCFunction)zlib_decompress, METH_VARARGS, zlib_decompress__doc__},
+
+static PyObject *
+zlib_decompress_impl(PyModuleDef *module, Py_buffer *data, int wbits, unsigned int bufsize);
+
+static PyObject *
+zlib_decompress(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+ int wbits = MAX_WBITS;
+ unsigned int bufsize = DEF_BUF_SIZE;
+
+ if (!PyArg_ParseTuple(args,
+ "y*|iO&:decompress",
+ &data, &wbits, uint_converter, &bufsize))
+ goto exit;
+ return_value = zlib_decompress_impl(module, &data, wbits, bufsize);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(zlib_compressobj__doc__,
+"compressobj(module, level=Z_DEFAULT_COMPRESSION, method=DEFLATED, wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL, strategy=Z_DEFAULT_STRATEGY, zdict=None)\n"
+"Return a compressor object.\n"
+"\n"
+" level\n"
+" The compression level (an integer in the range 0-9; default is 6).\n"
+" Higher compression levels are slower, but produce smaller results.\n"
+" method\n"
+" The compression algorithm. If given, this must be DEFLATED.\n"
+" wbits\n"
+" The base two logarithm of the window size (range: 8..15).\n"
+" memLevel\n"
+" Controls the amount of memory used for internal compression state.\n"
+" Valid values range from 1 to 9. Higher values result in higher memory\n"
+" usage, faster compression, and smaller output.\n"
+" strategy\n"
+" Used to tune the compression algorithm. Possible values are\n"
+" Z_DEFAULT_STRATEGY, Z_FILTERED, and Z_HUFFMAN_ONLY.\n"
+" zdict\n"
+" The predefined compression dictionary - a sequence of bytes\n"
+" containing subsequences that are likely to occur in the input data.");
+
+#define ZLIB_COMPRESSOBJ_METHODDEF \
+ {"compressobj", (PyCFunction)zlib_compressobj, METH_VARARGS|METH_KEYWORDS, zlib_compressobj__doc__},
+
+static PyObject *
+zlib_compressobj_impl(PyModuleDef *module, int level, int method, int wbits, int memLevel, int strategy, Py_buffer *zdict);
+
+static PyObject *
+zlib_compressobj(PyModuleDef *module, PyObject *args, PyObject *kwargs)
+{
+ PyObject *return_value = NULL;
+ static char *_keywords[] = {"level", "method", "wbits", "memLevel", "strategy", "zdict", NULL};
+ int level = Z_DEFAULT_COMPRESSION;
+ int method = DEFLATED;
+ int wbits = MAX_WBITS;
+ int memLevel = DEF_MEM_LEVEL;
+ int strategy = Z_DEFAULT_STRATEGY;
+ Py_buffer zdict = {NULL, NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "|iiiiiy*:compressobj", _keywords,
+ &level, &method, &wbits, &memLevel, &strategy, &zdict))
+ goto exit;
+ return_value = zlib_compressobj_impl(module, level, method, wbits, memLevel, strategy, &zdict);
+
+exit:
+ /* Cleanup for zdict */
+ if (zdict.obj)
+ PyBuffer_Release(&zdict);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(zlib_decompressobj__doc__,
+"decompressobj(module, wbits=MAX_WBITS, zdict=b\'\')\n"
+"Return a decompressor object.\n"
+"\n"
+" wbits\n"
+" The window buffer size.\n"
+" zdict\n"
+" The predefined compression dictionary. This must be the same\n"
+" dictionary as used by the compressor that produced the input data.");
+
+#define ZLIB_DECOMPRESSOBJ_METHODDEF \
+ {"decompressobj", (PyCFunction)zlib_decompressobj, METH_VARARGS|METH_KEYWORDS, zlib_decompressobj__doc__},
+
+static PyObject *
+zlib_decompressobj_impl(PyModuleDef *module, int wbits, PyObject *zdict);
+
+static PyObject *
+zlib_decompressobj(PyModuleDef *module, PyObject *args, PyObject *kwargs)
+{
+ PyObject *return_value = NULL;
+ static char *_keywords[] = {"wbits", "zdict", NULL};
+ int wbits = MAX_WBITS;
+ PyObject *zdict = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "|iO:decompressobj", _keywords,
+ &wbits, &zdict))
+ goto exit;
+ return_value = zlib_decompressobj_impl(module, wbits, zdict);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(zlib_Compress_compress__doc__,
+"compress(self, data)\n"
+"Returns a bytes object containing compressed data.\n"
+"\n"
+" data\n"
+" Binary data to be compressed.\n"
+"\n"
+"After calling this function, some of the input data may still\n"
+"be stored in internal buffers for later processing.\n"
+"Call the flush() method to clear these buffers.");
+
+#define ZLIB_COMPRESS_COMPRESS_METHODDEF \
+ {"compress", (PyCFunction)zlib_Compress_compress, METH_VARARGS, zlib_Compress_compress__doc__},
+
+static PyObject *
+zlib_Compress_compress_impl(compobject *self, Py_buffer *data);
+
+static PyObject *
+zlib_Compress_compress(compobject *self, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+
+ if (!PyArg_ParseTuple(args,
+ "y*:compress",
+ &data))
+ goto exit;
+ return_value = zlib_Compress_compress_impl(self, &data);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(zlib_Decompress_decompress__doc__,
+"decompress(self, data, max_length=0)\n"
+"Return a bytes object containing the decompressed version of the data.\n"
+"\n"
+" data\n"
+" The binary data to decompress.\n"
+" max_length\n"
+" The maximum allowable length of the decompressed data.\n"
+" Unconsumed input data will be stored in\n"
+" the unconsumed_tail attribute.\n"
+"\n"
+"After calling this function, some of the input data may still be stored in\n"
+"internal buffers for later processing.\n"
+"Call the flush() method to clear these buffers.");
+
+#define ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF \
+ {"decompress", (PyCFunction)zlib_Decompress_decompress, METH_VARARGS, zlib_Decompress_decompress__doc__},
+
+static PyObject *
+zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length);
+
+static PyObject *
+zlib_Decompress_decompress(compobject *self, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+ unsigned int max_length = 0;
+
+ if (!PyArg_ParseTuple(args,
+ "y*|O&:decompress",
+ &data, uint_converter, &max_length))
+ goto exit;
+ return_value = zlib_Decompress_decompress_impl(self, &data, max_length);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(zlib_Compress_flush__doc__,
+"flush(self, mode=Z_FINISH)\n"
+"Return a bytes object containing any remaining compressed data.\n"
+"\n"
+" mode\n"
+" One of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH.\n"
+" If mode == Z_FINISH, the compressor object can no longer be\n"
+" used after calling the flush() method. Otherwise, more data\n"
+" can still be compressed.");
+
+#define ZLIB_COMPRESS_FLUSH_METHODDEF \
+ {"flush", (PyCFunction)zlib_Compress_flush, METH_VARARGS, zlib_Compress_flush__doc__},
+
+static PyObject *
+zlib_Compress_flush_impl(compobject *self, int mode);
+
+static PyObject *
+zlib_Compress_flush(compobject *self, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ int mode = Z_FINISH;
+
+ if (!PyArg_ParseTuple(args,
+ "|i:flush",
+ &mode))
+ goto exit;
+ return_value = zlib_Compress_flush_impl(self, mode);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(zlib_Compress_copy__doc__,
+"copy(self)\n"
+"Return a copy of the compression object.");
+
+#define ZLIB_COMPRESS_COPY_METHODDEF \
+ {"copy", (PyCFunction)zlib_Compress_copy, METH_NOARGS, zlib_Compress_copy__doc__},
+
+static PyObject *
+zlib_Compress_copy_impl(compobject *self);
+
+static PyObject *
+zlib_Compress_copy(compobject *self, PyObject *Py_UNUSED(ignored))
+{
+ return zlib_Compress_copy_impl(self);
+}
+
+PyDoc_STRVAR(zlib_Decompress_copy__doc__,
+"copy(self)\n"
+"Return a copy of the decompression object.");
+
+#define ZLIB_DECOMPRESS_COPY_METHODDEF \
+ {"copy", (PyCFunction)zlib_Decompress_copy, METH_NOARGS, zlib_Decompress_copy__doc__},
+
+static PyObject *
+zlib_Decompress_copy_impl(compobject *self);
+
+static PyObject *
+zlib_Decompress_copy(compobject *self, PyObject *Py_UNUSED(ignored))
+{
+ return zlib_Decompress_copy_impl(self);
+}
+
+PyDoc_STRVAR(zlib_Decompress_flush__doc__,
+"flush(self, length=DEF_BUF_SIZE)\n"
+"Return a bytes object containing any remaining decompressed data.\n"
+"\n"
+" length\n"
+" the initial size of the output buffer.");
+
+#define ZLIB_DECOMPRESS_FLUSH_METHODDEF \
+ {"flush", (PyCFunction)zlib_Decompress_flush, METH_VARARGS, zlib_Decompress_flush__doc__},
+
+static PyObject *
+zlib_Decompress_flush_impl(compobject *self, unsigned int length);
+
+static PyObject *
+zlib_Decompress_flush(compobject *self, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ unsigned int length = DEF_BUF_SIZE;
+
+ if (!PyArg_ParseTuple(args,
+ "|O&:flush",
+ uint_converter, &length))
+ goto exit;
+ return_value = zlib_Decompress_flush_impl(self, length);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(zlib_adler32__doc__,
+"adler32(module, data, value=1)\n"
+"Compute an Adler-32 checksum of data.\n"
+"\n"
+" value\n"
+" Starting value of the checksum.\n"
+"\n"
+"The returned checksum is an integer.");
+
+#define ZLIB_ADLER32_METHODDEF \
+ {"adler32", (PyCFunction)zlib_adler32, METH_VARARGS, zlib_adler32__doc__},
+
+static PyObject *
+zlib_adler32_impl(PyModuleDef *module, Py_buffer *data, unsigned int value);
+
+static PyObject *
+zlib_adler32(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+ unsigned int value = 1;
+
+ if (!PyArg_ParseTuple(args,
+ "y*|I:adler32",
+ &data, &value))
+ goto exit;
+ return_value = zlib_adler32_impl(module, &data, value);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+
+PyDoc_STRVAR(zlib_crc32__doc__,
+"crc32(module, data, value=0)\n"
+"Compute a CRC-32 checksum of data.\n"
+"\n"
+" value\n"
+" Starting value of the checksum.\n"
+"\n"
+"The returned checksum is an integer.");
+
+#define ZLIB_CRC32_METHODDEF \
+ {"crc32", (PyCFunction)zlib_crc32, METH_VARARGS, zlib_crc32__doc__},
+
+static PyObject *
+zlib_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int value);
+
+static PyObject *
+zlib_crc32(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+ unsigned int value = 0;
+
+ if (!PyArg_ParseTuple(args,
+ "y*|I:crc32",
+ &data, &value))
+ goto exit;
+ return_value = zlib_crc32_impl(module, &data, value);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj)
+ PyBuffer_Release(&data);
+
+ return return_value;
+}
+/*[clinic end generated code: checksum=04f94bbaf2652717753e237e4021bf6c92ddffdd]*/
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 35b9ff47ee..98897895b7 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -2430,7 +2430,7 @@ It's an error to use dir_fd or follow_symlinks when specifying path as
[clinic start generated code]*/
PyDoc_STRVAR(os_stat__doc__,
-"stat(path, *, dir_fd=None, follow_symlinks=True)\n"
+"stat(module, path, *, dir_fd=None, follow_symlinks=True)\n"
"Perform a stat system call on the given path.\n"
"\n"
" path\n"
@@ -2481,7 +2481,7 @@ exit:
static PyObject *
os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks)
-/*[clinic end generated code: checksum=85a71ad602e89f8e280118da976f70cd2f9abdf1]*/
+/*[clinic end generated code: checksum=09cc91b4947f9e3b9335c8be998bb7c56f7f8b40]*/
{
return posix_do_stat("stat", path, dir_fd, follow_symlinks);
}
@@ -2562,7 +2562,7 @@ Note that most operations will use the effective uid/gid, therefore this
[clinic start generated code]*/
PyDoc_STRVAR(os_access__doc__,
-"access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True)\n"
+"access(module, path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True)\n"
"Use the real uid/gid to test for access to a path.\n"
"\n"
" path\n"
@@ -2622,7 +2622,7 @@ exit:
static PyObject *
os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks)
-/*[clinic end generated code: checksum=636e835c36562a2fc11acab75314634127fdf769]*/
+/*[clinic end generated code: checksum=6483a51e1fee83da4f8e41cbc8054a701cfed1c5]*/
{
PyObject *return_value = NULL;
@@ -2718,7 +2718,7 @@ Return the name of the terminal device connected to 'fd'.
[clinic start generated code]*/
PyDoc_STRVAR(os_ttyname__doc__,
-"ttyname(fd)\n"
+"ttyname(module, fd)\n"
"Return the name of the terminal device connected to \'fd\'.\n"
"\n"
" fd\n"
@@ -2752,7 +2752,7 @@ exit:
static char *
os_ttyname_impl(PyModuleDef *module, int fd)
-/*[clinic end generated code: checksum=0f368134dc0a7f21f25185e2e6bacf7675fb473a]*/
+/*[clinic end generated code: checksum=11bbb8b7969155f54bb8a1ec35ac1ebdfd4b0fec]*/
{
char *ret;
diff --git a/Modules/readline.c b/Modules/readline.c
index 43e25bc078..02521aaca4 100644
--- a/Modules/readline.c
+++ b/Modules/readline.c
@@ -935,7 +935,7 @@ on_completion(const char *text, int state)
* before calling the normal completer */
static char **
-flex_complete(char *text, int start, int end)
+flex_complete(const char *text, int start, int end)
{
char **result;
#ifdef WITH_THREAD
@@ -998,12 +998,12 @@ setup_readline(readlinestate *mod_state)
rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap);
rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap);
/* Set our hook functions */
- rl_startup_hook = (Function *)on_startup_hook;
+ rl_startup_hook = on_startup_hook;
#ifdef HAVE_RL_PRE_INPUT_HOOK
- rl_pre_input_hook = (Function *)on_pre_input_hook;
+ rl_pre_input_hook = on_pre_input_hook;
#endif
/* Set our completion function */
- rl_attempted_completion_function = (CPPFunction *)flex_complete;
+ rl_attempted_completion_function = flex_complete;
/* Set Python word break characters */
completer_word_break_characters =
rl_completer_word_break_characters =
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c
index 0c9b9d9f8c..d44e8de929 100644
--- a/Modules/selectmodule.c
+++ b/Modules/selectmodule.c
@@ -1458,9 +1458,7 @@ pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
return NULL;
}
else {
- /* epoll_wait() has a resolution of 1 millisecond, round away from zero
- to wait *at least* dtimeout seconds. */
- timeout = (int)ceil(dtimeout * 1000.0);
+ timeout = (int)(dtimeout * 1000.0);
}
if (maxevents == -1) {
diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c
index d12e4382f2..ca1620feab 100644
--- a/Modules/unicodedata.c
+++ b/Modules/unicodedata.c
@@ -19,7 +19,7 @@
/*[clinic input]
module unicodedata
-class unicodedata.UCD
+class unicodedata.UCD 'PreviousDBVersion *' '&UCD_Type'
[clinic start generated code]*/
/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
@@ -129,7 +129,7 @@ not given, ValueError is raised.
[clinic start generated code]*/
PyDoc_STRVAR(unicodedata_UCD_decimal__doc__,
-"decimal(unichr, default=None)\n"
+"decimal(self, unichr, default=None)\n"
"Converts a Unicode character into its equivalent decimal value.\n"
"\n"
"Returns the decimal value assigned to the Unicode character unichr\n"
@@ -140,10 +140,10 @@ PyDoc_STRVAR(unicodedata_UCD_decimal__doc__,
{"decimal", (PyCFunction)unicodedata_UCD_decimal, METH_VARARGS, unicodedata_UCD_decimal__doc__},
static PyObject *
-unicodedata_UCD_decimal_impl(PyObject *self, PyUnicodeObject *unichr, PyObject *default_value);
+unicodedata_UCD_decimal_impl(PreviousDBVersion *self, PyUnicodeObject *unichr, PyObject *default_value);
static PyObject *
-unicodedata_UCD_decimal(PyObject *self, PyObject *args)
+unicodedata_UCD_decimal(PreviousDBVersion *self, PyObject *args)
{
PyObject *return_value = NULL;
PyUnicodeObject *unichr;
@@ -160,15 +160,14 @@ exit:
}
static PyObject *
-unicodedata_UCD_decimal_impl(PyObject *self, PyUnicodeObject *unichr, PyObject *default_value)
-/*[clinic end generated code: checksum=73edde0e9cd5913ea174c4fa81504369761b7426]*/
+unicodedata_UCD_decimal_impl(PreviousDBVersion *self, PyUnicodeObject *unichr, PyObject *default_value)
+/*[clinic end generated code: checksum=e1371a1a016e19fdd3cd2c1af1d1832df095f50b]*/
{
- PyUnicodeObject *v = (PyUnicodeObject *)unichr;
int have_old = 0;
long rc;
Py_UCS4 c;
- c = getuchar(v);
+ c = getuchar(unichr);
if (c == (Py_UCS4)-1)
return NULL;
diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c
index 3894296b1f..a6b72bd4a8 100644
--- a/Modules/zlibmodule.c
+++ b/Modules/zlibmodule.c
@@ -28,10 +28,9 @@
#else
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
#endif
-#define DEF_WBITS MAX_WBITS
-/* The output buffer will be increased in chunks of DEFAULTALLOC bytes. */
-#define DEFAULTALLOC (16*1024)
+/* Initial buffer size. */
+#define DEF_BUF_SIZE (16*1024)
static PyTypeObject Comptype;
static PyTypeObject Decomptype;
@@ -82,42 +81,13 @@ zlib_error(z_stream zst, int err, char *msg)
}
/*[clinic input]
+output preset file
module zlib
-class zlib.Compress
-class zlib.Decompress
+class zlib.Compress "compobject *" "&Comptype"
+class zlib.Decompress "compobject *" "&Decomptype"
[clinic start generated code]*/
/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
-PyDoc_STRVAR(compressobj__doc__,
-"compressobj(level=-1, method=DEFLATED, wbits=15, memlevel=8,\n"
-" strategy=Z_DEFAULT_STRATEGY[, zdict])\n"
-" -- Return a compressor object.\n"
-"\n"
-"level is the compression level (an integer in the range 0-9; default is 6).\n"
-"Higher compression levels are slower, but produce smaller results.\n"
-"\n"
-"method is the compression algorithm. If given, this must be DEFLATED.\n"
-"\n"
-"wbits is the base two logarithm of the window size (range: 8..15).\n"
-"\n"
-"memlevel controls the amount of memory used for internal compression state.\n"
-"Valid values range from 1 to 9. Higher values result in higher memory usage,\n"
-"faster compression, and smaller output.\n"
-"\n"
-"strategy is used to tune the compression algorithm. Possible values are\n"
-"Z_DEFAULT_STRATEGY, Z_FILTERED, and Z_HUFFMAN_ONLY.\n"
-"\n"
-"zdict is the predefined compression dictionary - a sequence of bytes\n"
-"containing subsequences that are likely to occur in the input data.");
-
-PyDoc_STRVAR(decompressobj__doc__,
-"decompressobj([wbits[, zdict]]) -- Return a decompressor object.\n"
-"\n"
-"Optional arg wbits is the window buffer size.\n"
-"\n"
-"Optional arg zdict is the predefined compression dictionary. This must be\n"
-"the same dictionary as used by the compressor that produced the input data.");
-
static compobject *
newcompobject(PyTypeObject *type)
{
@@ -165,70 +135,20 @@ PyZlib_Free(voidpf ctx, void *ptr)
}
/*[clinic input]
-
zlib.compress
+
bytes: Py_buffer
Binary data to be compressed.
- [
- level: int
+ level: int(c_default="Z_DEFAULT_COMPRESSION") = Z_DEFAULT_COMPRESSION
Compression level, in 0-9.
- ]
/
-Returns compressed string.
-
+Returns a bytes object containing compressed data.
[clinic start generated code]*/
-PyDoc_STRVAR(zlib_compress__doc__,
-"compress(bytes, [level])\n"
-"Returns compressed string.\n"
-"\n"
-" bytes\n"
-" Binary data to be compressed.\n"
-" level\n"
-" Compression level, in 0-9.");
-
-#define ZLIB_COMPRESS_METHODDEF \
- {"compress", (PyCFunction)zlib_compress, METH_VARARGS, zlib_compress__doc__},
-
static PyObject *
-zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int group_right_1, int level);
-
-static PyObject *
-zlib_compress(PyModuleDef *module, PyObject *args)
-{
- PyObject *return_value = NULL;
- Py_buffer bytes = {NULL, NULL};
- int group_right_1 = 0;
- int level = 0;
-
- switch (PyTuple_GET_SIZE(args)) {
- case 1:
- if (!PyArg_ParseTuple(args, "y*:compress", &bytes))
- goto exit;
- break;
- case 2:
- if (!PyArg_ParseTuple(args, "y*i:compress", &bytes, &level))
- goto exit;
- group_right_1 = 1;
- break;
- default:
- PyErr_SetString(PyExc_TypeError, "zlib.compress requires 1 to 2 arguments");
- goto exit;
- }
- return_value = zlib_compress_impl(module, &bytes, group_right_1, level);
-
-exit:
- /* Cleanup for bytes */
- if (bytes.obj)
- PyBuffer_Release(&bytes);
-
- return return_value;
-}
-
-static PyObject *
-zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int group_right_1, int level)
-/*[clinic end generated code: checksum=74648f97e6b9d3cc9cd568d47262d462bded7ed0]*/
+zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int level)
+/*[clinic end generated code: checksum=5d7dd4588788efd3516e5f4225050d6413632601]*/
{
PyObject *ReturnVal = NULL;
Byte *input, *output = NULL;
@@ -236,9 +156,6 @@ zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int group_right_1, int
int err;
z_stream zst;
- if (!group_right_1)
- level = Z_DEFAULT_COMPRESSION;
-
if ((size_t)bytes->len > UINT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"Size does not fit in an unsigned int");
@@ -312,6 +229,7 @@ zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int group_right_1, int
class uint_converter(CConverter):
type = 'unsigned int'
converter = 'uint_converter'
+ c_ignored_default = "0"
[python start generated code]*/
/*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
@@ -347,35 +265,38 @@ uint_converter(PyObject *obj, void *ptr)
return 1;
}
-PyDoc_STRVAR(decompress__doc__,
-"decompress(string[, wbits[, bufsize]]) -- Return decompressed string.\n"
-"\n"
-"Optional arg wbits is the window buffer size. Optional arg bufsize is\n"
-"the initial output buffer size.");
+/*[clinic input]
+zlib.decompress
+
+ data: Py_buffer
+ Compressed data.
+ wbits: int(c_default="MAX_WBITS") = MAX_WBITS
+ The window buffer size.
+ bufsize: uint(c_default="DEF_BUF_SIZE") = DEF_BUF_SIZE
+ The initial output buffer size.
+ /
+
+Returns a bytes object containing the uncompressed data.
+[clinic start generated code]*/
static PyObject *
-PyZlib_decompress(PyObject *self, PyObject *args)
+zlib_decompress_impl(PyModuleDef *module, Py_buffer *data, int wbits, unsigned int bufsize)
+/*[clinic end generated code: checksum=9e5464e72df9cb5fee73df662dbcaed867e01d32]*/
{
PyObject *result_str = NULL;
- Py_buffer pinput;
Byte *input;
unsigned int length;
int err;
- int wsize=DEF_WBITS;
- unsigned int bufsize = DEFAULTALLOC, new_bufsize;
+ unsigned int new_bufsize;
z_stream zst;
- if (!PyArg_ParseTuple(args, "y*|iO&:decompress",
- &pinput, &wsize, uint_converter, &bufsize))
- return NULL;
-
- if ((size_t)pinput.len > UINT_MAX) {
+ if ((size_t)data->len > UINT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"Size does not fit in an unsigned int");
goto error;
}
- input = pinput.buf;
- length = (unsigned int)pinput.len;
+ input = data->buf;
+ length = (unsigned int)data->len;
if (bufsize == 0)
bufsize = 1;
@@ -391,7 +312,7 @@ PyZlib_decompress(PyObject *self, PyObject *args)
zst.zfree = PyZlib_Free;
zst.next_out = (Byte *)PyBytes_AS_STRING(result_str);
zst.next_in = (Byte *)input;
- err = inflateInit2(&zst, wsize);
+ err = inflateInit2(&zst, wbits);
switch(err) {
case(Z_OK):
@@ -457,32 +378,45 @@ PyZlib_decompress(PyObject *self, PyObject *args)
if (_PyBytes_Resize(&result_str, zst.total_out) < 0)
goto error;
- PyBuffer_Release(&pinput);
return result_str;
error:
- PyBuffer_Release(&pinput);
Py_XDECREF(result_str);
return NULL;
}
+/*[clinic input]
+zlib.compressobj
+
+ level: int(c_default="Z_DEFAULT_COMPRESSION") = Z_DEFAULT_COMPRESSION
+ The compression level (an integer in the range 0-9; default is 6).
+ Higher compression levels are slower, but produce smaller results.
+ method: int(c_default="DEFLATED") = DEFLATED
+ The compression algorithm. If given, this must be DEFLATED.
+ wbits: int(c_default="MAX_WBITS") = MAX_WBITS
+ The base two logarithm of the window size (range: 8..15).
+ memLevel: int(c_default="DEF_MEM_LEVEL") = DEF_MEM_LEVEL
+ Controls the amount of memory used for internal compression state.
+ Valid values range from 1 to 9. Higher values result in higher memory
+ usage, faster compression, and smaller output.
+ strategy: int(c_default="Z_DEFAULT_STRATEGY") = Z_DEFAULT_STRATEGY
+ Used to tune the compression algorithm. Possible values are
+ Z_DEFAULT_STRATEGY, Z_FILTERED, and Z_HUFFMAN_ONLY.
+ zdict: Py_buffer = None
+ The predefined compression dictionary - a sequence of bytes
+ containing subsequences that are likely to occur in the input data.
+
+Return a compressor object.
+[clinic start generated code]*/
+
static PyObject *
-PyZlib_compressobj(PyObject *selfptr, PyObject *args, PyObject *kwargs)
+zlib_compressobj_impl(PyModuleDef *module, int level, int method, int wbits, int memLevel, int strategy, Py_buffer *zdict)
+/*[clinic end generated code: checksum=89e5a6c1449caa9ed76f1baad066600e985151a9]*/
{
compobject *self = NULL;
- int level=Z_DEFAULT_COMPRESSION, method=DEFLATED;
- int wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL, strategy=0, err;
- Py_buffer zdict;
- static char *kwlist[] = {"level", "method", "wbits",
- "memLevel", "strategy", "zdict", NULL};
-
- zdict.buf = NULL; /* Sentinel, so we can tell whether zdict was supplied. */
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iiiiiy*:compressobj",
- kwlist, &level, &method, &wbits,
- &memLevel, &strategy, &zdict))
- return NULL;
+ int err;
- if (zdict.buf != NULL && (size_t)zdict.len > UINT_MAX) {
+ if (zdict->buf != NULL && (size_t)zdict->len > UINT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"zdict length does not fit in an unsigned int");
goto error;
@@ -500,11 +434,11 @@ PyZlib_compressobj(PyObject *selfptr, PyObject *args, PyObject *kwargs)
switch(err) {
case (Z_OK):
self->is_initialised = 1;
- if (zdict.buf == NULL) {
+ if (zdict->buf == NULL) {
goto success;
} else {
err = deflateSetDictionary(&self->zst,
- zdict.buf, (unsigned int)zdict.len);
+ zdict->buf, (unsigned int)zdict->len);
switch (err) {
case (Z_OK):
goto success;
@@ -532,22 +466,28 @@ PyZlib_compressobj(PyObject *selfptr, PyObject *args, PyObject *kwargs)
Py_XDECREF(self);
self = NULL;
success:
- if (zdict.buf != NULL)
- PyBuffer_Release(&zdict);
return (PyObject*)self;
}
+/*[clinic input]
+zlib.decompressobj
+
+ wbits: int(c_default="MAX_WBITS") = MAX_WBITS
+ The window buffer size.
+ zdict: object(c_default="NULL") = b''
+ The predefined compression dictionary. This must be the same
+ dictionary as used by the compressor that produced the input data.
+
+Return a decompressor object.
+[clinic start generated code]*/
+
static PyObject *
-PyZlib_decompressobj(PyObject *selfptr, PyObject *args, PyObject *kwargs)
+zlib_decompressobj_impl(PyModuleDef *module, int wbits, PyObject *zdict)
+/*[clinic end generated code: checksum=8ccd583fbd631798566d415933cd44440c8a74b5]*/
{
- static char *kwlist[] = {"wbits", "zdict", NULL};
- int wbits=DEF_WBITS, err;
+ int err;
compobject *self;
- PyObject *zdict=NULL;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:decompressobj",
- kwlist, &wbits, &zdict))
- return NULL;
if (zdict != NULL && !PyObject_CheckBuffer(zdict)) {
PyErr_SetString(PyExc_TypeError,
"zdict argument must support the buffer protocol");
@@ -615,37 +555,41 @@ Decomp_dealloc(compobject *self)
Dealloc(self);
}
-PyDoc_STRVAR(comp_compress__doc__,
-"compress(data) -- Return a string containing data compressed.\n"
-"\n"
-"After calling this function, some of the input data may still\n"
-"be stored in internal buffers for later processing.\n"
-"Call the flush() method to clear these buffers.");
+/*[clinic input]
+zlib.Compress.compress
+
+ data: Py_buffer
+ Binary data to be compressed.
+ /
+
+Returns a bytes object containing compressed data.
+After calling this function, some of the input data may still
+be stored in internal buffers for later processing.
+Call the flush() method to clear these buffers.
+[clinic start generated code]*/
static PyObject *
-PyZlib_objcompress(compobject *self, PyObject *args)
+zlib_Compress_compress_impl(compobject *self, Py_buffer *data)
+/*[clinic end generated code: checksum=5d5cd791cbc6a7f4b6de4ec12c085c88d4d3e31c]*/
{
int err;
unsigned int inplen;
- unsigned int length = DEFAULTALLOC, new_length;
- PyObject *RetVal = NULL;
- Py_buffer pinput;
+ unsigned int length = DEF_BUF_SIZE, new_length;
+ PyObject *RetVal;
Byte *input;
unsigned long start_total_out;
- if (!PyArg_ParseTuple(args, "y*:compress", &pinput))
- return NULL;
- if ((size_t)pinput.len > UINT_MAX) {
+ if ((size_t)data->len > UINT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"Size does not fit in an unsigned int");
- goto error_outer;
+ return NULL;
}
- input = pinput.buf;
- inplen = (unsigned int)pinput.len;
+ input = data->buf;
+ inplen = (unsigned int)data->len;
if (!(RetVal = PyBytes_FromStringAndSize(NULL, length)))
- goto error_outer;
+ return NULL;
ENTER_ZLIB(self);
@@ -668,7 +612,7 @@ PyZlib_objcompress(compobject *self, PyObject *args)
new_length = UINT_MAX;
if (_PyBytes_Resize(&RetVal, new_length) < 0) {
Py_CLEAR(RetVal);
- goto error;
+ goto done;
}
self->zst.next_out =
(unsigned char *)PyBytes_AS_STRING(RetVal) + length;
@@ -686,18 +630,15 @@ PyZlib_objcompress(compobject *self, PyObject *args)
if (err != Z_OK && err != Z_BUF_ERROR) {
zlib_error(self->zst, err, "while compressing data");
- Py_DECREF(RetVal);
- RetVal = NULL;
- goto error;
+ Py_CLEAR(RetVal);
+ goto done;
}
if (_PyBytes_Resize(&RetVal, self->zst.total_out - start_total_out) < 0) {
Py_CLEAR(RetVal);
}
- error:
+ done:
LEAVE_ZLIB(self);
- error_outer:
- PyBuffer_Release(&pinput);
return RetVal;
}
@@ -745,11 +686,8 @@ save_unconsumed_input(compobject *self, int err)
}
/*[clinic input]
-
zlib.Decompress.decompress
- self: self(type="compobject *")
-
data: Py_buffer
The binary data to decompress.
max_length: uint = 0
@@ -758,61 +696,19 @@ zlib.Decompress.decompress
the unconsumed_tail attribute.
/
-Return a string containing the decompressed version of the data.
+Return a bytes object containing the decompressed version of the data.
After calling this function, some of the input data may still be stored in
internal buffers for later processing.
Call the flush() method to clear these buffers.
[clinic start generated code]*/
-PyDoc_STRVAR(zlib_Decompress_decompress__doc__,
-"decompress(data, max_length=0)\n"
-"Return a string containing the decompressed version of the data.\n"
-"\n"
-" data\n"
-" The binary data to decompress.\n"
-" max_length\n"
-" The maximum allowable length of the decompressed data.\n"
-" Unconsumed input data will be stored in\n"
-" the unconsumed_tail attribute.\n"
-"\n"
-"After calling this function, some of the input data may still be stored in\n"
-"internal buffers for later processing.\n"
-"Call the flush() method to clear these buffers.");
-
-#define ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF \
- {"decompress", (PyCFunction)zlib_Decompress_decompress, METH_VARARGS, zlib_Decompress_decompress__doc__},
-
-static PyObject *
-zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length);
-
-static PyObject *
-zlib_Decompress_decompress(PyObject *self, PyObject *args)
-{
- PyObject *return_value = NULL;
- Py_buffer data = {NULL, NULL};
- unsigned int max_length = 0;
-
- if (!PyArg_ParseTuple(args,
- "y*|O&:decompress",
- &data, uint_converter, &max_length))
- goto exit;
- return_value = zlib_Decompress_decompress_impl((compobject *)self, &data, max_length);
-
-exit:
- /* Cleanup for data */
- if (data.obj)
- PyBuffer_Release(&data);
-
- return return_value;
-}
-
static PyObject *
zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length)
-/*[clinic end generated code: checksum=e0058024c4a97b411d2e2197791b89fde175f76f]*/
+/*[clinic end generated code: checksum=755cccc9087bfe55486b7e15fa7e2ab60b4c86d6]*/
{
int err;
- unsigned int old_length, length = DEFAULTALLOC;
+ unsigned int old_length, length = DEF_BUF_SIZE;
PyObject *RetVal = NULL;
unsigned long start_total_out;
@@ -929,29 +825,31 @@ zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int
return RetVal;
}
-PyDoc_STRVAR(comp_flush__doc__,
-"flush( [mode] ) -- Return a string containing any remaining compressed data.\n"
-"\n"
-"mode can be one of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH; the\n"
-"default value used when mode is not specified is Z_FINISH.\n"
-"If mode == Z_FINISH, the compressor object can no longer be used after\n"
-"calling the flush() method. Otherwise, more data can still be compressed.");
+/*[clinic input]
+zlib.Compress.flush
+
+ mode: int(c_default="Z_FINISH") = Z_FINISH
+ One of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH.
+ If mode == Z_FINISH, the compressor object can no longer be
+ used after calling the flush() method. Otherwise, more data
+ can still be compressed.
+ /
+
+Return a bytes object containing any remaining compressed data.
+[clinic start generated code]*/
static PyObject *
-PyZlib_flush(compobject *self, PyObject *args)
+zlib_Compress_flush_impl(compobject *self, int mode)
+/*[clinic end generated code: checksum=a203f4cefc9de727aa1d2ea39d11c0a16c32041a]*/
{
int err;
- unsigned int length = DEFAULTALLOC, new_length;
+ unsigned int length = DEF_BUF_SIZE, new_length;
PyObject *RetVal;
- int flushmode = Z_FINISH;
unsigned long start_total_out;
- if (!PyArg_ParseTuple(args, "|i:flush", &flushmode))
- return NULL;
-
/* Flushing with Z_NO_FLUSH is a no-op, so there's no point in
doing any work at all; just return an empty string. */
- if (flushmode == Z_NO_FLUSH) {
+ if (mode == Z_NO_FLUSH) {
return PyBytes_FromStringAndSize(NULL, 0);
}
@@ -966,7 +864,7 @@ PyZlib_flush(compobject *self, PyObject *args)
self->zst.next_out = (unsigned char *)PyBytes_AS_STRING(RetVal);
Py_BEGIN_ALLOW_THREADS
- err = deflate(&(self->zst), flushmode);
+ err = deflate(&(self->zst), mode);
Py_END_ALLOW_THREADS
/* while Z_OK and the output buffer is full, there might be more output,
@@ -986,14 +884,14 @@ PyZlib_flush(compobject *self, PyObject *args)
length = new_length;
Py_BEGIN_ALLOW_THREADS
- err = deflate(&(self->zst), flushmode);
+ err = deflate(&(self->zst), mode);
Py_END_ALLOW_THREADS
}
- /* If flushmode is Z_FINISH, we also have to call deflateEnd() to free
+ /* If mode is Z_FINISH, we also have to call deflateEnd() to free
various data structures. Note we should only get Z_STREAM_END when
- flushmode is Z_FINISH, but checking both for safety*/
- if (err == Z_STREAM_END && flushmode == Z_FINISH) {
+ mode is Z_FINISH, but checking both for safety*/
+ if (err == Z_STREAM_END && mode == Z_FINISH) {
err = deflateEnd(&(self->zst));
if (err != Z_OK) {
zlib_error(self->zst, err, "while finishing compression");
@@ -1030,30 +928,12 @@ PyZlib_flush(compobject *self, PyObject *args)
/*[clinic input]
zlib.Compress.copy
- self: self(type="compobject *")
-
Return a copy of the compression object.
[clinic start generated code]*/
-PyDoc_STRVAR(zlib_Compress_copy__doc__,
-"copy()\n"
-"Return a copy of the compression object.");
-
-#define ZLIB_COMPRESS_COPY_METHODDEF \
- {"copy", (PyCFunction)zlib_Compress_copy, METH_NOARGS, zlib_Compress_copy__doc__},
-
-static PyObject *
-zlib_Compress_copy_impl(compobject *self);
-
-static PyObject *
-zlib_Compress_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
-{
- return zlib_Compress_copy_impl((compobject *)self);
-}
-
static PyObject *
zlib_Compress_copy_impl(compobject *self)
-/*[clinic end generated code: checksum=d57a7911deb7940e85a8d7e65af20b6e2df69000]*/
+/*[clinic end generated code: checksum=5144aa153c21e805afa5c19e5b48cf8e6480b5da]*/
{
compobject *retval = NULL;
int err;
@@ -1103,11 +983,15 @@ error:
return NULL;
}
-PyDoc_STRVAR(decomp_copy__doc__,
-"copy() -- Return a copy of the decompression object.");
+/*[clinic input]
+zlib.Decompress.copy
+
+Return a copy of the decompression object.
+[clinic start generated code]*/
static PyObject *
-PyZlib_uncopy(compobject *self)
+zlib_Decompress_copy_impl(compobject *self)
+/*[clinic end generated code: checksum=02a883a2a510c8ccfeef3f89e317a275bfe8c094]*/
{
compobject *retval = NULL;
int err;
@@ -1159,24 +1043,26 @@ error:
}
#endif
-PyDoc_STRVAR(decomp_flush__doc__,
-"flush( [length] ) -- Return a string containing any remaining\n"
-"decompressed data. length, if given, is the initial size of the\n"
-"output buffer.\n"
-"\n"
-"The decompressor object can no longer be used after this call.");
+/*[clinic input]
+zlib.Decompress.flush
+
+ length: uint(c_default="DEF_BUF_SIZE") = DEF_BUF_SIZE
+ the initial size of the output buffer.
+ /
+
+Return a bytes object containing any remaining decompressed data.
+[clinic start generated code]*/
static PyObject *
-PyZlib_unflush(compobject *self, PyObject *args)
+zlib_Decompress_flush_impl(compobject *self, unsigned int length)
+/*[clinic end generated code: checksum=db6fb753ab698e22afe3957c9da9e5e77f4bfc08]*/
{
int err;
- unsigned int length = DEFAULTALLOC, new_length;
+ unsigned int new_length;
PyObject * retval = NULL;
unsigned long start_total_out;
Py_ssize_t size;
- if (!PyArg_ParseTuple(args, "|O&:flush", uint_converter, &length))
- return NULL;
if (length == 0) {
PyErr_SetString(PyExc_ValueError, "length must be greater than zero");
return NULL;
@@ -1252,12 +1138,12 @@ error:
return retval;
}
+#include "clinic/zlibmodule.c.h"
+
static PyMethodDef comp_methods[] =
{
- {"compress", (binaryfunc)PyZlib_objcompress, METH_VARARGS,
- comp_compress__doc__},
- {"flush", (binaryfunc)PyZlib_flush, METH_VARARGS,
- comp_flush__doc__},
+ ZLIB_COMPRESS_COMPRESS_METHODDEF
+ ZLIB_COMPRESS_FLUSH_METHODDEF
#ifdef HAVE_ZLIB_COPY
ZLIB_COMPRESS_COPY_METHODDEF
#endif
@@ -1267,11 +1153,9 @@ static PyMethodDef comp_methods[] =
static PyMethodDef Decomp_methods[] =
{
ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF
- {"flush", (binaryfunc)PyZlib_unflush, METH_VARARGS,
- decomp_flush__doc__},
+ ZLIB_DECOMPRESS_FLUSH_METHODDEF
#ifdef HAVE_ZLIB_COPY
- {"copy", (PyCFunction)PyZlib_uncopy, METH_NOARGS,
- decomp_copy__doc__},
+ ZLIB_DECOMPRESS_COPY_METHODDEF
#endif
{NULL, NULL}
};
@@ -1284,95 +1168,95 @@ static PyMemberDef Decomp_members[] = {
{NULL},
};
-PyDoc_STRVAR(adler32__doc__,
-"adler32(string[, start]) -- Compute an Adler-32 checksum of string.\n"
-"\n"
-"An optional starting value can be specified. The returned checksum is\n"
-"an integer.");
+/*[clinic input]
+zlib.adler32
+
+ data: Py_buffer
+ value: unsigned_int(bitwise=True) = 1
+ Starting value of the checksum.
+ /
+
+Compute an Adler-32 checksum of data.
+
+The returned checksum is an integer.
+[clinic start generated code]*/
static PyObject *
-PyZlib_adler32(PyObject *self, PyObject *args)
+zlib_adler32_impl(PyModuleDef *module, Py_buffer *data, unsigned int value)
+/*[clinic end generated code: checksum=51d6d75ee655c78af8c968fdb4c11d97e62c67d5]*/
{
- unsigned int adler32val = 1; /* adler32(0L, Z_NULL, 0) */
- Py_buffer pbuf;
-
- if (!PyArg_ParseTuple(args, "y*|I:adler32", &pbuf, &adler32val))
- return NULL;
/* Releasing the GIL for very small buffers is inefficient
and may lower performance */
- if (pbuf.len > 1024*5) {
- unsigned char *buf = pbuf.buf;
- Py_ssize_t len = pbuf.len;
+ if (data->len > 1024*5) {
+ unsigned char *buf = data->buf;
+ Py_ssize_t len = data->len;
Py_BEGIN_ALLOW_THREADS
/* Avoid truncation of length for very large buffers. adler32() takes
length as an unsigned int, which may be narrower than Py_ssize_t. */
while ((size_t)len > UINT_MAX) {
- adler32val = adler32(adler32val, buf, UINT_MAX);
+ value = adler32(value, buf, UINT_MAX);
buf += (size_t) UINT_MAX;
len -= (size_t) UINT_MAX;
}
- adler32val = adler32(adler32val, buf, (unsigned int)len);
+ value = adler32(value, buf, (unsigned int)len);
Py_END_ALLOW_THREADS
} else {
- adler32val = adler32(adler32val, pbuf.buf, (unsigned int)pbuf.len);
+ value = adler32(value, data->buf, (unsigned int)data->len);
}
- PyBuffer_Release(&pbuf);
- return PyLong_FromUnsignedLong(adler32val & 0xffffffffU);
+ return PyLong_FromUnsignedLong(value & 0xffffffffU);
}
-PyDoc_STRVAR(crc32__doc__,
-"crc32(string[, start]) -- Compute a CRC-32 checksum of string.\n"
-"\n"
-"An optional starting value can be specified. The returned checksum is\n"
-"an integer.");
+/*[clinic input]
+zlib.crc32
+
+ data: Py_buffer
+ value: unsigned_int(bitwise=True) = 0
+ Starting value of the checksum.
+ /
+
+Compute a CRC-32 checksum of data.
+
+The returned checksum is an integer.
+[clinic start generated code]*/
static PyObject *
-PyZlib_crc32(PyObject *self, PyObject *args)
+zlib_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int value)
+/*[clinic end generated code: checksum=c1e986e74fe7b62369998a71a81ebeb9b73e8d4c]*/
{
- unsigned int crc32val = 0; /* crc32(0L, Z_NULL, 0) */
- Py_buffer pbuf;
int signed_val;
- if (!PyArg_ParseTuple(args, "y*|I:crc32", &pbuf, &crc32val))
- return NULL;
/* Releasing the GIL for very small buffers is inefficient
and may lower performance */
- if (pbuf.len > 1024*5) {
- unsigned char *buf = pbuf.buf;
- Py_ssize_t len = pbuf.len;
+ if (data->len > 1024*5) {
+ unsigned char *buf = data->buf;
+ Py_ssize_t len = data->len;
Py_BEGIN_ALLOW_THREADS
/* Avoid truncation of length for very large buffers. crc32() takes
length as an unsigned int, which may be narrower than Py_ssize_t. */
while ((size_t)len > UINT_MAX) {
- crc32val = crc32(crc32val, buf, UINT_MAX);
+ value = crc32(value, buf, UINT_MAX);
buf += (size_t) UINT_MAX;
len -= (size_t) UINT_MAX;
}
- signed_val = crc32(crc32val, buf, (unsigned int)len);
+ signed_val = crc32(value, buf, (unsigned int)len);
Py_END_ALLOW_THREADS
} else {
- signed_val = crc32(crc32val, pbuf.buf, (unsigned int)pbuf.len);
+ signed_val = crc32(value, data->buf, (unsigned int)data->len);
}
- PyBuffer_Release(&pbuf);
return PyLong_FromUnsignedLong(signed_val & 0xffffffffU);
}
static PyMethodDef zlib_methods[] =
{
- {"adler32", (PyCFunction)PyZlib_adler32, METH_VARARGS,
- adler32__doc__},
+ ZLIB_ADLER32_METHODDEF
ZLIB_COMPRESS_METHODDEF
- {"compressobj", (PyCFunction)PyZlib_compressobj, METH_VARARGS|METH_KEYWORDS,
- compressobj__doc__},
- {"crc32", (PyCFunction)PyZlib_crc32, METH_VARARGS,
- crc32__doc__},
- {"decompress", (PyCFunction)PyZlib_decompress, METH_VARARGS,
- decompress__doc__},
- {"decompressobj", (PyCFunction)PyZlib_decompressobj, METH_VARARGS|METH_KEYWORDS,
- decompressobj__doc__},
+ ZLIB_COMPRESSOBJ_METHODDEF
+ ZLIB_CRC32_METHODDEF
+ ZLIB_DECOMPRESS_METHODDEF
+ ZLIB_DECOMPRESSOBJ_METHODDEF
{NULL, NULL}
};
@@ -1486,6 +1370,7 @@ PyInit_zlib(void)
PyModule_AddIntMacro(m, MAX_WBITS);
PyModule_AddIntMacro(m, DEFLATED);
PyModule_AddIntMacro(m, DEF_MEM_LEVEL);
+ PyModule_AddIntMacro(m, DEF_BUF_SIZE);
PyModule_AddIntMacro(m, Z_BEST_SPEED);
PyModule_AddIntMacro(m, Z_BEST_COMPRESSION);
PyModule_AddIntMacro(m, Z_DEFAULT_COMPRESSION);
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
index 312fc402d3..ce1c71beb2 100644
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -353,11 +353,17 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
static PyObject *
method_get_doc(PyMethodDescrObject *descr, void *closure)
{
- if (descr->d_method->ml_doc == NULL) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- return PyUnicode_FromString(descr->d_method->ml_doc);
+ const char *name = descr->d_method->ml_name;
+ const char *doc = descr->d_method->ml_doc;
+ return _PyType_GetDocFromInternalDoc(name, doc);
+}
+
+static PyObject *
+method_get_text_signature(PyMethodDescrObject *descr, void *closure)
+{
+ const char *name = descr->d_method->ml_name;
+ const char *doc = descr->d_method->ml_doc;
+ return _PyType_GetTextSignatureFromInternalDoc(name, doc);
}
static PyObject *
@@ -425,6 +431,7 @@ static PyMemberDef descr_members[] = {
static PyGetSetDef method_getset[] = {
{"__doc__", (getter)method_get_doc},
{"__qualname__", (getter)descr_get_qualname},
+ {"__text_signature__", (getter)method_get_text_signature},
{0}
};
@@ -463,16 +470,23 @@ static PyGetSetDef getset_getset[] = {
static PyObject *
wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure)
{
- if (descr->d_base->doc == NULL) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- return PyUnicode_FromString(descr->d_base->doc);
+ const char *name = descr->d_base->name;
+ const char *doc = descr->d_base->doc;
+ return _PyType_GetDocFromInternalDoc(name, doc);
+}
+
+static PyObject *
+wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure)
+{
+ const char *name = descr->d_base->name;
+ const char *doc = descr->d_base->doc;
+ return _PyType_GetTextSignatureFromInternalDoc(name, doc);
}
static PyGetSetDef wrapperdescr_getset[] = {
{"__doc__", (getter)wrapperdescr_get_doc},
{"__qualname__", (getter)descr_get_qualname},
+ {"__text_signature__", (getter)wrapperdescr_get_text_signature},
{0}
};
@@ -1143,17 +1157,19 @@ wrapper_name(wrapperobject *wp)
}
static PyObject *
-wrapper_doc(wrapperobject *wp)
+wrapper_doc(wrapperobject *wp, void *closure)
{
- const char *s = wp->descr->d_base->doc;
+ const char *name = wp->descr->d_base->name;
+ const char *doc = wp->descr->d_base->doc;
+ return _PyType_GetDocFromInternalDoc(name, doc);
+}
- if (s == NULL) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- else {
- return PyUnicode_FromString(s);
- }
+static PyObject *
+wrapper_text_signature(wrapperobject *wp, void *closure)
+{
+ const char *name = wp->descr->d_base->name;
+ const char *doc = wp->descr->d_base->doc;
+ return _PyType_GetTextSignatureFromInternalDoc(name, doc);
}
static PyObject *
@@ -1167,6 +1183,7 @@ static PyGetSetDef wrapper_getsets[] = {
{"__name__", (getter)wrapper_name},
{"__qualname__", (getter)wrapper_qualname},
{"__doc__", (getter)wrapper_doc},
+ {"__text_signature__", (getter)wrapper_text_signature},
{0}
};
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index ceb45e0ae6..2332e3fcd8 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -70,7 +70,7 @@ to the combined-table form.
#include "stringlib/eq.h"
/*[clinic input]
-class dict
+class dict "PyDictObject *" "&PyDict_Type"
[clinic start generated code]*/
/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
@@ -1691,37 +1691,70 @@ dict_items(PyDictObject *mp)
return v;
}
+/*[clinic input]
+@classmethod
+dict.fromkeys
+ iterable: object
+ value: object=None
+ /
+
+Returns a new dict with keys from iterable and values equal to value.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(dict_fromkeys__doc__,
+"fromkeys(type, iterable, value=None)\n"
+"Returns a new dict with keys from iterable and values equal to value.");
+
+#define DICT_FROMKEYS_METHODDEF \
+ {"fromkeys", (PyCFunction)dict_fromkeys, METH_VARARGS|METH_CLASS, dict_fromkeys__doc__},
+
+static PyObject *
+dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value);
+
static PyObject *
-dict_fromkeys(PyObject *cls, PyObject *args)
+dict_fromkeys(PyTypeObject *type, PyObject *args)
{
- PyObject *seq;
+ PyObject *return_value = NULL;
+ PyObject *iterable;
PyObject *value = Py_None;
+
+ if (!PyArg_UnpackTuple(args, "fromkeys",
+ 1, 2,
+ &iterable, &value))
+ goto exit;
+ return_value = dict_fromkeys_impl(type, iterable, value);
+
+exit:
+ return return_value;
+}
+
+static PyObject *
+dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value)
+/*[clinic end generated code: checksum=008269e1774a379b356841548c04061fd78a9542]*/
+{
PyObject *it; /* iter(seq) */
PyObject *key;
PyObject *d;
int status;
- if (!PyArg_UnpackTuple(args, "fromkeys", 1, 2, &seq, &value))
- return NULL;
-
- d = PyObject_CallObject(cls, NULL);
+ d = PyObject_CallObject((PyObject *)type, NULL);
if (d == NULL)
return NULL;
if (PyDict_CheckExact(d) && ((PyDictObject *)d)->ma_used == 0) {
- if (PyDict_CheckExact(seq)) {
+ if (PyDict_CheckExact(iterable)) {
PyDictObject *mp = (PyDictObject *)d;
PyObject *oldvalue;
Py_ssize_t pos = 0;
PyObject *key;
Py_hash_t hash;
- if (dictresize(mp, Py_SIZE(seq))) {
+ if (dictresize(mp, Py_SIZE(iterable))) {
Py_DECREF(d);
return NULL;
}
- while (_PyDict_Next(seq, &pos, &key, &oldvalue, &hash)) {
+ while (_PyDict_Next(iterable, &pos, &key, &oldvalue, &hash)) {
if (insertdict(mp, key, hash, value)) {
Py_DECREF(d);
return NULL;
@@ -1729,18 +1762,18 @@ dict_fromkeys(PyObject *cls, PyObject *args)
}
return d;
}
- if (PyAnySet_CheckExact(seq)) {
+ if (PyAnySet_CheckExact(iterable)) {
PyDictObject *mp = (PyDictObject *)d;
Py_ssize_t pos = 0;
PyObject *key;
Py_hash_t hash;
- if (dictresize(mp, PySet_GET_SIZE(seq))) {
+ if (dictresize(mp, PySet_GET_SIZE(iterable))) {
Py_DECREF(d);
return NULL;
}
- while (_PySet_NextEntry(seq, &pos, &key, &hash)) {
+ while (_PySet_NextEntry(iterable, &pos, &key, &hash)) {
if (insertdict(mp, key, hash, value)) {
Py_DECREF(d);
return NULL;
@@ -1750,7 +1783,7 @@ dict_fromkeys(PyObject *cls, PyObject *args)
}
}
- it = PyObject_GetIter(seq);
+ it = PyObject_GetIter(iterable);
if (it == NULL){
Py_DECREF(d);
return NULL;
@@ -2176,17 +2209,17 @@ True if D has a key k, else False.
[clinic start generated code]*/
PyDoc_STRVAR(dict___contains____doc__,
-"__contains__(key)\n"
+"__contains__(self, key)\n"
"True if D has a key k, else False.");
#define DICT___CONTAINS___METHODDEF \
{"__contains__", (PyCFunction)dict___contains__, METH_O|METH_COEXIST, dict___contains____doc__},
static PyObject *
-dict___contains__(PyObject *self, PyObject *key)
-/*[clinic end generated code: checksum=402ddb624ba1e4db764bfdfbbee6c1c59d1a11fa]*/
+dict___contains__(PyDictObject *self, PyObject *key)
+/*[clinic end generated code: checksum=744ca54369dda9815a596304087f1b37fafa5960]*/
{
- register PyDictObject *mp = (PyDictObject *)self;
+ register PyDictObject *mp = self;
Py_hash_t hash;
PyDictKeyEntry *ep;
PyObject **value_addr;
@@ -2496,10 +2529,6 @@ If E is present and has a .keys() method, then does: for k in E: D[k] = E[k]\n\
If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v\n\
In either case, this is followed by: for k in F: D[k] = F[k]");
-PyDoc_STRVAR(fromkeys__doc__,
-"dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.\n\
-v defaults to None.");
-
PyDoc_STRVAR(clear__doc__,
"D.clear() -> None. Remove all items from D.");
@@ -2540,8 +2569,7 @@ static PyMethodDef mapp_methods[] = {
values__doc__},
{"update", (PyCFunction)dict_update, METH_VARARGS | METH_KEYWORDS,
update__doc__},
- {"fromkeys", (PyCFunction)dict_fromkeys, METH_VARARGS | METH_CLASS,
- fromkeys__doc__},
+ DICT_FROMKEYS_METHODDEF
{"clear", (PyCFunction)dict_clear, METH_NOARGS,
clear__doc__},
{"copy", (PyCFunction)dict_copy, METH_NOARGS,
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index bff7f0819e..2531ead50f 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -2689,8 +2689,11 @@ _PyErr_TrySetFromCause(const char *format, ...)
* types as well, but that's quite a bit trickier due to the extra
* state potentially stored on OSError instances.
*/
-
- Py_XDECREF(tb);
+ /* Ensure the traceback is set correctly on the existing exception */
+ if (tb != NULL) {
+ PyException_SetTraceback(val, tb);
+ Py_DECREF(tb);
+ }
#ifdef HAVE_STDARG_PROTOTYPES
va_start(vargs, format);
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
index 6179aeebd0..227ad57436 100644
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -179,75 +179,20 @@ static PyMethodDef meth_methods[] = {
{NULL, NULL}
};
-/*
- * finds the docstring's introspection signature.
- * if present, returns a pointer pointing to the first '('.
- * otherwise returns NULL.
- */
-static const char *find_signature(PyCFunctionObject *m)
-{
- const char *trace = m->m_ml->ml_doc;
- const char *name = m->m_ml->ml_name;
- size_t length;
- if (!trace || !name)
- return NULL;
- length = strlen(name);
- if (strncmp(trace, name, length))
- return NULL;
- trace += length;
- if (*trace != '(')
- return NULL;
- return trace;
-}
-
-/*
- * skips to the end of the docstring's instrospection signature.
- */
-static const char *skip_signature(const char *trace)
-{
- while (*trace && *trace != '\n')
- trace++;
- return trace;
-}
-
-static const char *skip_eols(const char *trace)
-{
- while (*trace == '\n')
- trace++;
- return trace;
-}
-
static PyObject *
meth_get__text_signature__(PyCFunctionObject *m, void *closure)
{
- const char *start = find_signature(m);
- const char *trace;
-
- if (!start) {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- trace = skip_signature(start);
- return PyUnicode_FromStringAndSize(start, trace - start);
+ const char *name = m->m_ml->ml_name;
+ const char *doc = m->m_ml->ml_doc;
+ return _PyType_GetTextSignatureFromInternalDoc(name, doc);
}
static PyObject *
meth_get__doc__(PyCFunctionObject *m, void *closure)
{
- const char *doc = find_signature(m);
-
- if (doc)
- doc = skip_eols(skip_signature(doc));
- else
- doc = m->m_ml->ml_doc;
-
- if (!doc) {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- return PyUnicode_FromString(doc);
+ const char *name = m->m_ml->ml_name;
+ const char *doc = m->m_ml->ml_doc;
+ return _PyType_GetDocFromInternalDoc(name, doc);
}
static PyObject *
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 530670f361..08da4de016 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -54,6 +54,83 @@ _Py_IDENTIFIER(builtins);
static PyObject *
slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+/*
+ * finds the docstring's introspection signature.
+ * if present, returns a pointer pointing to the first '('.
+ * otherwise returns NULL.
+ */
+static const char *
+find_signature(const char *name, const char *doc)
+{
+ size_t length;
+ if (!doc || !name)
+ return NULL;
+ length = strlen(name);
+ if (strncmp(doc, name, length))
+ return NULL;
+ doc += length;
+ if (*doc != '(')
+ return NULL;
+ return doc;
+}
+
+/*
+ * skips to the end of the docstring's instrospection signature.
+ */
+static const char *
+skip_signature(const char *doc)
+{
+ while (*doc && *doc != '\n')
+ doc++;
+ return doc;
+}
+
+static const char *
+skip_eols(const char *trace)
+{
+ while (*trace == '\n')
+ trace++;
+ return trace;
+}
+
+static const char *
+_PyType_DocWithoutSignature(const char *name, const char *internal_doc)
+{
+ const char *signature = find_signature(name, internal_doc);
+
+ if (signature)
+ return skip_eols(skip_signature(signature));
+ return internal_doc;
+}
+
+PyObject *
+_PyType_GetDocFromInternalDoc(const char *name, const char *internal_doc)
+{
+ const char *doc = _PyType_DocWithoutSignature(name, internal_doc);
+
+ if (!doc) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ return PyUnicode_FromString(doc);
+}
+
+PyObject *
+_PyType_GetTextSignatureFromInternalDoc(const char *name, const char *internal_doc)
+{
+ const char *signature = find_signature(name, internal_doc);
+ const char *doc;
+
+ if (!signature) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ doc = skip_signature(signature);
+ return PyUnicode_FromStringAndSize(signature, doc - signature);
+}
+
unsigned int
PyType_ClearCache(void)
{
@@ -628,8 +705,11 @@ static PyObject *
type_get_doc(PyTypeObject *type, void *context)
{
PyObject *result;
- if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL)
- return PyUnicode_FromString(type->tp_doc);
+ if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) {
+ const char *name = type->tp_name;
+ const char *doc = type->tp_doc;
+ return _PyType_GetDocFromInternalDoc(name, doc);
+ }
result = _PyDict_GetItemId(type->tp_dict, &PyId___doc__);
if (result == NULL) {
result = Py_None;
@@ -645,6 +725,14 @@ type_get_doc(PyTypeObject *type, void *context)
return result;
}
+static PyObject *
+type_get_text_signature(PyTypeObject *type, void *context)
+{
+ const char *name = type->tp_name;
+ const char *doc = type->tp_doc;
+ return _PyType_GetTextSignatureFromInternalDoc(name, doc);
+}
+
static int
type_set_doc(PyTypeObject *type, PyObject *value, void *context)
{
@@ -691,6 +779,7 @@ static PyGetSetDef type_getsets[] = {
(setter)type_set_abstractmethods, NULL},
{"__dict__", (getter)type_dict, NULL, NULL},
{"__doc__", (getter)type_get_doc, (setter)type_set_doc, NULL},
+ {"__text_signature__", (getter)type_get_text_signature, NULL, NULL},
{0}
};
@@ -2519,13 +2608,14 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
/* need to make a copy of the docstring slot, which usually
points to a static string literal */
if (slot->slot == Py_tp_doc) {
- size_t len = strlen(slot->pfunc)+1;
+ const char *old_doc = _PyType_DocWithoutSignature(spec->name, slot->pfunc);
+ size_t len = strlen(old_doc)+1;
char *tp_doc = PyObject_MALLOC(len);
if (tp_doc == NULL) {
PyErr_NoMemory();
goto fail;
}
- memcpy(tp_doc, slot->pfunc, len);
+ memcpy(tp_doc, old_doc, len);
type->tp_doc = tp_doc;
}
}
@@ -2909,6 +2999,8 @@ static PyMethodDef type_methods[] = {
};
PyDoc_STRVAR(type_doc,
+/* this text signature cannot be accurate yet. will fix. --larry */
+"type(object_or_name, bases, dict)\n"
"type(object) -> the object's type\n"
"type(name, bases, dict) -> a new type");
@@ -3480,7 +3572,7 @@ _PyObject_GetState(PyObject *obj)
{
PyObject **dict;
dict = _PyObject_GetDictPtr(obj);
- /* It is possible that the object's dict is not initialized
+ /* It is possible that the object's dict is not initialized
yet. In this case, we will return None for the state.
We also return None if the dict is empty to make the behavior
consistent regardless whether the dict was initialized or not.
@@ -3788,7 +3880,7 @@ reduce_4(PyObject *obj)
Py_DECREF(state);
Py_DECREF(listitems);
Py_DECREF(dictitems);
- return result;
+ return result;
}
static PyObject *
@@ -3813,7 +3905,7 @@ reduce_2(PyObject *obj)
}
else if (kwargs != NULL) {
if (PyDict_Size(kwargs) > 0) {
- PyErr_SetString(PyExc_ValueError,
+ PyErr_SetString(PyExc_ValueError,
"must use protocol 4 or greater to copy this "
"object; since __getnewargs_ex__ returned "
"keyword arguments.");
@@ -4103,8 +4195,8 @@ PyTypeObject PyBaseObject_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- PyDoc_STR("The most base type"), /* tp_doc */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ PyDoc_STR("object()\nThe most base type"), /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
object_richcompare, /* tp_richcompare */
@@ -4571,7 +4663,8 @@ PyType_Ready(PyTypeObject *type)
*/
if (_PyDict_GetItemId(type->tp_dict, &PyId___doc__) == NULL) {
if (type->tp_doc != NULL) {
- PyObject *doc = PyUnicode_FromString(type->tp_doc);
+ const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, type->tp_doc);
+ PyObject *doc = PyUnicode_FromString(old_doc);
if (doc == NULL)
goto error;
if (_PyDict_SetItemId(type->tp_dict, &PyId___doc__, doc) < 0) {
@@ -6005,22 +6098,22 @@ typedef struct wrapperbase slotdef;
ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC)
#define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \
- "x." NAME "() <==> " DOC)
+ NAME "(self)\n" DOC)
#define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \
- "x." NAME "(y) <==> x" DOC "y")
+ NAME "(self, value)\nReturns self" DOC "value.")
#define BINSLOT(NAME, SLOT, FUNCTION, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \
- "x." NAME "(y) <==> x" DOC "y")
+ NAME "(self, value)\nReturns self" DOC "value.")
#define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \
- "x." NAME "(y) <==> y" DOC "x")
+ NAME "(self, value)\nReturns value" DOC "self.")
#define BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \
- "x." NAME "(y) <==> " DOC)
+ NAME "(self, value)\n" DOC)
#define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \
- "x." NAME "(y) <==> " DOC)
+ NAME "(self, value)\n" DOC)
static slotdef slotdefs[] = {
TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""),
@@ -6028,80 +6121,85 @@ static slotdef slotdefs[] = {
TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""),
TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""),
TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc,
- "x.__repr__() <==> repr(x)"),
+ "__repr__(self)\nReturns repr(self)."),
TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc,
- "x.__hash__() <==> hash(x)"),
+ "__hash__(self)\nReturns hash(self)."),
FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call,
- "x.__call__(...) <==> x(...)", PyWrapperFlag_KEYWORDS),
+ "__call__(self, *args, **kwargs)\nCalls self as a function.",
+ PyWrapperFlag_KEYWORDS),
TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc,
- "x.__str__() <==> str(x)"),
+ "__str__(self)\nReturns str(self)."),
TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook,
- wrap_binaryfunc, "x.__getattribute__('name') <==> x.name"),
+ wrap_binaryfunc,
+ "__getattribute__(self, name)\nReturns getattr(self, name)."),
TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""),
TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr,
- "x.__setattr__('name', value) <==> x.name = value"),
+ "__setattr__(self, name, value)\nImplements setattr(self, name, value)."),
TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr,
- "x.__delattr__('name') <==> del x.name"),
+ "__delattr__(self, name)\nImplements delattr(self, name)."),
TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt,
- "x.__lt__(y) <==> x<y"),
+ "__lt__(self, value)\nReturns self<value."),
TPSLOT("__le__", tp_richcompare, slot_tp_richcompare, richcmp_le,
- "x.__le__(y) <==> x<=y"),
+ "__le__(self, value)\nReturns self<=value."),
TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq,
- "x.__eq__(y) <==> x==y"),
+ "__eq__(self, value)\nReturns self==value."),
TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne,
- "x.__ne__(y) <==> x!=y"),
+ "__ne__(self, value)\nReturns self!=value."),
TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt,
- "x.__gt__(y) <==> x>y"),
+ "__gt__(self, value)\nReturns self>value."),
TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge,
- "x.__ge__(y) <==> x>=y"),
+ "__ge__(self, value)\nReturns self>=value."),
TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc,
- "x.__iter__() <==> iter(x)"),
+ "__iter__(self)\nImplements iter(self)."),
TPSLOT("__next__", tp_iternext, slot_tp_iternext, wrap_next,
- "x.__next__() <==> next(x)"),
+ "__next__(self)\nImplements next(self)."),
TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get,
- "descr.__get__(obj[, type]) -> value"),
+ "__get__(self, instance, owner)\nCalled to get an attribute of instance, which is of type owner."),
TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set,
- "descr.__set__(obj, value)"),
+ "__set__(self, instance, value)\nSets an attribute of instance to value."),
TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set,
- wrap_descr_delete, "descr.__delete__(obj)"),
+ wrap_descr_delete,
+ "__delete__(instance)\nDeletes an attribute of instance."),
FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)wrap_init,
- "x.__init__(...) initializes x; "
- "see help(type(x)) for signature",
+ "__init__(self, *args, **kwargs)\n"
+ "Initializes self. See help(type(self)) for accurate signature.",
PyWrapperFlag_KEYWORDS),
- TPSLOT("__new__", tp_new, slot_tp_new, NULL, ""),
+ TPSLOT("__new__", tp_new, slot_tp_new, NULL,
+ "__new__(cls, *args, **kwargs)\n"
+ "Creates new object. See help(cls) for accurate signature."),
TPSLOT("__del__", tp_finalize, slot_tp_finalize, (wrapperfunc)wrap_del, ""),
BINSLOT("__add__", nb_add, slot_nb_add,
- "+"),
+ "+"),
RBINSLOT("__radd__", nb_add, slot_nb_add,
- "+"),
+ "+"),
BINSLOT("__sub__", nb_subtract, slot_nb_subtract,
- "-"),
+ "-"),
RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract,
- "-"),
+ "-"),
BINSLOT("__mul__", nb_multiply, slot_nb_multiply,
- "*"),
+ "*"),
RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply,
- "*"),
+ "*"),
BINSLOT("__mod__", nb_remainder, slot_nb_remainder,
- "%"),
+ "%"),
RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder,
- "%"),
+ "%"),
BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod,
- "divmod(x, y)"),
+ "__divmod__(self, value)\nReturns divmod(self, value)."),
RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod,
- "divmod(y, x)"),
+ "__rdivmod__(self, value)\nReturns divmod(value, self)."),
NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc,
- "x.__pow__(y[, z]) <==> pow(x, y[, z])"),
+ "__pow__(self, value, mod=None)\nReturns pow(self, value, mod)."),
NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r,
- "y.__rpow__(x[, z]) <==> pow(x, y[, z])"),
- UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-x"),
- UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+x"),
+ "__rpow__(self, value, mod=None)\nReturns pow(value, self, mod)."),
+ UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-self"),
+ UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+self"),
UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc,
- "abs(x)"),
+ "abs(self)"),
UNSLOT("__bool__", nb_bool, slot_nb_bool, wrap_inquirypred,
- "x != 0"),
- UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~x"),
+ "self != 0"),
+ UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~self"),
BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"),
RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"),
BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"),
@@ -6113,9 +6211,9 @@ static slotdef slotdefs[] = {
BINSLOT("__or__", nb_or, slot_nb_or, "|"),
RBINSLOT("__ror__", nb_or, slot_nb_or, "|"),
UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc,
- "int(x)"),
+ "int(self)"),
UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc,
- "float(x)"),
+ "float(self)"),
IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add,
wrap_binaryfunc, "+="),
IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract,
@@ -6145,45 +6243,48 @@ static slotdef slotdefs[] = {
IBSLOT("__itruediv__", nb_inplace_true_divide,
slot_nb_inplace_true_divide, wrap_binaryfunc, "/"),
NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc,
- "x[y:z] <==> x[y.__index__():z.__index__()]"),
-
+ "__index__(self)\n"
+ "Returns self converted to an integer, if self is suitable"
+ "for use as an index into a list."),
MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc,
- "x.__len__() <==> len(x)"),
+ "__len__(self)\nReturns len(self)."),
MPSLOT("__getitem__", mp_subscript, slot_mp_subscript,
wrap_binaryfunc,
- "x.__getitem__(y) <==> x[y]"),
+ "__getitem__(self, key)\nReturns self[key]."),
MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript,
wrap_objobjargproc,
- "x.__setitem__(i, y) <==> x[i]=y"),
+ "__setitem__(self, key, value)\nSets self[key] to value."),
MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript,
wrap_delitem,
- "x.__delitem__(y) <==> del x[y]"),
+ "__delitem__(key)\nDeletes self[key]."),
SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc,
- "x.__len__() <==> len(x)"),
+ "__len__(self)\nReturns len(self)."),
/* Heap types defining __add__/__mul__ have sq_concat/sq_repeat == NULL.
The logic in abstract.c always falls back to nb_add/nb_multiply in
this case. Defining both the nb_* and the sq_* slots to call the
user-defined methods has unexpected side-effects, as shown by
test_descr.notimplemented() */
SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc,
- "x.__add__(y) <==> x+y"),
+ "__add__(self, value)\nReturns self+value."),
SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc,
- "x.__mul__(n) <==> x*n"),
+ "__mul__(self, value)\nReturns self*value.n"),
SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc,
- "x.__rmul__(n) <==> n*x"),
+ "__rmul__(self, value)\nReturns self*value."),
SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item,
- "x.__getitem__(y) <==> x[y]"),
+ "__getitem__(self, key)\nReturns self[key]."),
SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem,
- "x.__setitem__(i, y) <==> x[i]=y"),
+ "__setitem__(self, key, value)\nSets self[key] to value."),
SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem,
- "x.__delitem__(y) <==> del x[y]"),
+ "__delitem__(self, key)\nDeletes self[key]."),
SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc,
- "x.__contains__(y) <==> y in x"),
+ "__contains__(self, key)\nReturns key in self."),
SQSLOT("__iadd__", sq_inplace_concat, NULL,
- wrap_binaryfunc, "x.__iadd__(y) <==> x+=y"),
+ wrap_binaryfunc,
+ "__iadd__(self, value)\nImplements self+=value."),
SQSLOT("__imul__", sq_inplace_repeat, NULL,
- wrap_indexargfunc, "x.__imul__(y) <==> x*=y"),
+ wrap_indexargfunc,
+ "__imul__(self, value)\nImplements self*=value."),
{NULL}
};
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 1ce10cfd90..919b7333d7 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -48,7 +48,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#endif
/*[clinic input]
-class str
+class str "PyUnicodeObject *" "&PyUnicode_Type"
[clinic start generated code]*/
/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
@@ -12900,7 +12900,7 @@ PyDoc_STRVAR(unicode_maketrans__doc__,
{"maketrans", (PyCFunction)unicode_maketrans, METH_VARARGS|METH_STATIC, unicode_maketrans__doc__},
static PyObject *
-unicode_maketrans_impl(void *null, PyObject *x, PyObject *y, PyObject *z);
+unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z);
static PyObject *
unicode_maketrans(void *null, PyObject *args)
@@ -12914,15 +12914,15 @@ unicode_maketrans(void *null, PyObject *args)
"O|UU:maketrans",
&x, &y, &z))
goto exit;
- return_value = unicode_maketrans_impl(null, x, y, z);
+ return_value = unicode_maketrans_impl(x, y, z);
exit:
return return_value;
}
static PyObject *
-unicode_maketrans_impl(void *null, PyObject *x, PyObject *y, PyObject *z)
-/*[clinic end generated code: checksum=7f76f414a0dfd0c614e0d4717872eeb520516da7]*/
+unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z)
+/*[clinic end generated code: checksum=90a3de8c494b304687e1e0d7e5fa8ba78eac6533]*/
{
PyObject *new = NULL, *key, *value;
Py_ssize_t i = 0;
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index e3157d09c2..745457fed9 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -1325,7 +1325,7 @@ builtin_len(PyObject *self, PyObject *v)
}
PyDoc_STRVAR(len_doc,
-"len(object) -> integer\n\
+"len(module, object)\n\
\n\
Return the number of items of a sequence or mapping.");
diff --git a/Python/import.c b/Python/import.c
index fb7d88c02f..ae8ff5e915 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -232,7 +232,7 @@ On platforms without threads, return False.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_lock_held__doc__,
-"lock_held()\n"
+"lock_held(module)\n"
"Return True if the import lock is currently held, else False.\n"
"\n"
"On platforms without threads, return False.");
@@ -251,7 +251,7 @@ _imp_lock_held(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
static PyObject *
_imp_lock_held_impl(PyModuleDef *module)
-/*[clinic end generated code: checksum=ede1cafb78eb22e3009602f684c8b780e2b82d62]*/
+/*[clinic end generated code: checksum=17172a9917d389dd1564e2108fec34d23aecb6c2]*/
{
#ifdef WITH_THREAD
return PyBool_FromLong(import_lock_thread != -1);
@@ -270,7 +270,7 @@ modules. On platforms without threads, this function does nothing.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_acquire_lock__doc__,
-"acquire_lock()\n"
+"acquire_lock(module)\n"
"Acquires the interpreter\'s import lock for the current thread.\n"
"\n"
"This lock should be used by import hooks to ensure thread-safety when importing\n"
@@ -290,7 +290,7 @@ _imp_acquire_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
static PyObject *
_imp_acquire_lock_impl(PyModuleDef *module)
-/*[clinic end generated code: checksum=5b520b2416c5954a7cf0ed30955d68abe20b5868]*/
+/*[clinic end generated code: checksum=20db30e18f6b8758386fe06907edb3f8e43080d7]*/
{
#ifdef WITH_THREAD
_PyImport_AcquireLock();
@@ -308,7 +308,7 @@ On platforms without threads, this function does nothing.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_release_lock__doc__,
-"release_lock()\n"
+"release_lock(module)\n"
"Release the interpreter\'s import lock.\n"
"\n"
"On platforms without threads, this function does nothing.");
@@ -327,7 +327,7 @@ _imp_release_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
static PyObject *
_imp_release_lock_impl(PyModuleDef *module)
-/*[clinic end generated code: checksum=efcd9d2923294c04371596e7f6d66a706d43fcac]*/
+/*[clinic end generated code: checksum=17749fd7752d2c392447a1f83c5d371f54d7ebd3]*/
{
#ifdef WITH_THREAD
if (_PyImport_ReleaseLock() < 0) {
@@ -927,7 +927,7 @@ Changes code.co_filename to specify the passed-in file path.
[clinic start generated code]*/
PyDoc_STRVAR(_imp__fix_co_filename__doc__,
-"_fix_co_filename(code, path)\n"
+"_fix_co_filename(module, code, path)\n"
"Changes code.co_filename to specify the passed-in file path.\n"
"\n"
" code\n"
@@ -960,7 +960,7 @@ exit:
static PyObject *
_imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, PyObject *path)
-/*[clinic end generated code: checksum=4f55bad308072b30ad1921068fc4ce85bd2b39bf]*/
+/*[clinic end generated code: checksum=d32cf2b2e0480c714f909921cc9e55d763b39dd5]*/
{
update_compiled_module(code, path);
@@ -1823,7 +1823,7 @@ Returns the list of file suffixes used to identify extension modules.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_extension_suffixes__doc__,
-"extension_suffixes()\n"
+"extension_suffixes(module)\n"
"Returns the list of file suffixes used to identify extension modules.");
#define _IMP_EXTENSION_SUFFIXES_METHODDEF \
@@ -1840,7 +1840,7 @@ _imp_extension_suffixes(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
static PyObject *
_imp_extension_suffixes_impl(PyModuleDef *module)
-/*[clinic end generated code: checksum=82fb35d8429a429a4dc80c84b45b1aad73ff1de7]*/
+/*[clinic end generated code: checksum=625c8f11a5bbd4b85373f0a54f7f3ef19c55beb4]*/
{
PyObject *list;
const char *suffix;
@@ -1878,7 +1878,7 @@ Initializes a built-in module.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_init_builtin__doc__,
-"init_builtin(name)\n"
+"init_builtin(module, name)\n"
"Initializes a built-in module.");
#define _IMP_INIT_BUILTIN_METHODDEF \
@@ -1905,7 +1905,7 @@ exit:
static PyObject *
_imp_init_builtin_impl(PyModuleDef *module, PyObject *name)
-/*[clinic end generated code: checksum=59239206e5b2fb59358066e72fd0e72e55a7baf5]*/
+/*[clinic end generated code: checksum=a4e4805a523757cd3ddfeec6e5b16740678fed6a]*/
{
int ret;
PyObject *m;
@@ -1932,7 +1932,7 @@ Initializes a frozen module.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_init_frozen__doc__,
-"init_frozen(name)\n"
+"init_frozen(module, name)\n"
"Initializes a frozen module.");
#define _IMP_INIT_FROZEN_METHODDEF \
@@ -1959,7 +1959,7 @@ exit:
static PyObject *
_imp_init_frozen_impl(PyModuleDef *module, PyObject *name)
-/*[clinic end generated code: checksum=503fcc3de9961263e4d9484259af357a7d287a0b]*/
+/*[clinic end generated code: checksum=2a58c119dd3e121cf5a9924f936cfd7b40253c12]*/
{
int ret;
PyObject *m;
@@ -1986,7 +1986,7 @@ Create a code object for a frozen module.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_get_frozen_object__doc__,
-"get_frozen_object(name)\n"
+"get_frozen_object(module, name)\n"
"Create a code object for a frozen module.");
#define _IMP_GET_FROZEN_OBJECT_METHODDEF \
@@ -2013,7 +2013,7 @@ exit:
static PyObject *
_imp_get_frozen_object_impl(PyModuleDef *module, PyObject *name)
-/*[clinic end generated code: checksum=7a6423a4daf139496b9a394ff3ac6130089d1cba]*/
+/*[clinic end generated code: checksum=94c9108b58dda80d187fef21275a009bd0f91e96]*/
{
return get_frozen_object(name);
}
@@ -2028,7 +2028,7 @@ Returns True if the module name is of a frozen package.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_is_frozen_package__doc__,
-"is_frozen_package(name)\n"
+"is_frozen_package(module, name)\n"
"Returns True if the module name is of a frozen package.");
#define _IMP_IS_FROZEN_PACKAGE_METHODDEF \
@@ -2055,7 +2055,7 @@ exit:
static PyObject *
_imp_is_frozen_package_impl(PyModuleDef *module, PyObject *name)
-/*[clinic end generated code: checksum=dc7e361ea30b6945b8bbe7266d7b9a5ea433b510]*/
+/*[clinic end generated code: checksum=17a342b94dbe859cdfc361bc8a6bc1b3cb163364]*/
{
return is_frozen_package(name);
}
@@ -2070,7 +2070,7 @@ Returns True if the module name corresponds to a built-in module.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_is_builtin__doc__,
-"is_builtin(name)\n"
+"is_builtin(module, name)\n"
"Returns True if the module name corresponds to a built-in module.");
#define _IMP_IS_BUILTIN_METHODDEF \
@@ -2097,7 +2097,7 @@ exit:
static PyObject *
_imp_is_builtin_impl(PyModuleDef *module, PyObject *name)
-/*[clinic end generated code: checksum=353938c1d55210a1e3850d3ccba7539d02165cac]*/
+/*[clinic end generated code: checksum=51c6139dcfd9bee1f40980ea68b7797f8489d69a]*/
{
return PyLong_FromLong(is_builtin(name));
}
@@ -2112,7 +2112,7 @@ Returns True if the module name corresponds to a frozen module.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_is_frozen__doc__,
-"is_frozen(name)\n"
+"is_frozen(module, name)\n"
"Returns True if the module name corresponds to a frozen module.");
#define _IMP_IS_FROZEN_METHODDEF \
@@ -2139,7 +2139,7 @@ exit:
static PyObject *
_imp_is_frozen_impl(PyModuleDef *module, PyObject *name)
-/*[clinic end generated code: checksum=978b547ddcb76fa6c4a181ad53569c9acf382c7b]*/
+/*[clinic end generated code: checksum=4b079fb45a495835056ea5604735d552d222be5c]*/
{
const struct _frozen *p;
@@ -2161,7 +2161,7 @@ Loads an extension module.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_load_dynamic__doc__,
-"load_dynamic(name, path, file=None)\n"
+"load_dynamic(module, name, path, file=None)\n"
"Loads an extension module.");
#define _IMP_LOAD_DYNAMIC_METHODDEF \
@@ -2190,7 +2190,7 @@ exit:
static PyObject *
_imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, PyObject *file)
-/*[clinic end generated code: checksum=6795f65d9ce003ccaf08e4e8eef484dc52e262d0]*/
+/*[clinic end generated code: checksum=63e051fd0d0350c785bf185be41b0892f9920622]*/
{
PyObject *mod;
FILE *fp;
diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py
index 8fc2e1e823..f3fe3c140d 100755
--- a/Tools/clinic/clinic.py
+++ b/Tools/clinic/clinic.py
@@ -120,6 +120,7 @@ def fail(*args, filename=None, line_number=None):
def quoted_for_c_string(s):
for old, new in (
+ ('\\', '\\\\'), # must be first!
('"', '\\"'),
("'", "\\'"),
):
@@ -139,9 +140,9 @@ def is_legal_py_identifier(s):
# so if they're used Argument Clinic will add "_value" to the end
# of the name in C.
c_keywords = set("""
-asm auto break case char cls const continue default do double
-else enum extern float for goto if inline int long module null
-register return self short signed sizeof static struct switch
+asm auto break case char const continue default do double
+else enum extern float for goto if inline int long
+register return short signed sizeof static struct switch
typedef typeof union unsigned void volatile while
""".strip().split())
@@ -299,6 +300,10 @@ class CRenderData:
# Should be full lines with \n eol characters.
self.initializers = []
+ # The C statements needed to dynamically modify the values
+ # parsed by the parse call, before calling the impl.
+ self.modifications = []
+
# The entries for the "keywords" array for PyArg_ParseTuple.
# Should be individual strings representing the names.
self.keywords = []
@@ -540,6 +545,7 @@ __________________________________________________
parser_definition_impl_call
+ {modifications}
{return_value} = {c_basename}_impl({impl_arguments});
__________________________________________________
@@ -574,14 +580,14 @@ __________________________________________________
parser_definition_no_positional
- if (!_PyArg_NoPositional("{name}", args))
+ if ({self_type_check}!_PyArg_NoPositional("{name}", args))
goto exit;
__________________________________________________
parser_definition_no_keywords
- if (!_PyArg_NoKeywords("{name}", kwargs))
+ if ({self_type_check}!_PyArg_NoKeywords("{name}", kwargs))
goto exit;
__________________________________________________
@@ -635,6 +641,9 @@ __________________________________________________
def output_templates(self, f):
parameters = list(f.parameters.values())
+ assert parameters
+ assert isinstance(parameters[0].converter, self_converter)
+ del parameters[0]
converters = [p.converter for p in parameters]
has_option_groups = parameters and (parameters[0].group or parameters[-1].group)
@@ -679,12 +688,15 @@ __________________________________________________
return_value_declaration = "PyObject *return_value = NULL;"
methoddef_define = templates['methoddef_define']
- docstring_prototype = templates['docstring_prototype']
- docstring_definition = templates['docstring_definition']
+ if new_or_init and not f.docstring:
+ docstring_prototype = docstring_definition = ''
+ else:
+ docstring_prototype = templates['docstring_prototype']
+ docstring_definition = templates['docstring_definition']
impl_definition = templates['impl_definition']
impl_prototype = parser_prototype = parser_definition = None
- parser_body_fields = None
+ parser_body_fields = ()
def parser_body(prototype, *fields):
nonlocal parser_body_fields
add, output = text_accumulator()
@@ -858,6 +870,8 @@ __________________________________________________
add, output = text_accumulator()
parameters = list(f.parameters.values())
+ if isinstance(parameters[0].converter, self_converter):
+ del parameters[0]
groups = []
group = None
@@ -936,14 +950,69 @@ __________________________________________________
data = CRenderData()
parameters = list(f.parameters.values())
+ assert parameters, "We should always have a 'self' at this point!"
+
converters = [p.converter for p in parameters]
+ templates = self.output_templates(f)
+
+ f_self = parameters[0]
+ selfless = parameters[1:]
+ assert isinstance(f_self.converter, self_converter), "No self parameter in " + repr(f.full_name) + "!"
+
+ last_group = 0
+ first_optional = len(selfless)
+ positional = selfless and selfless[-1].kind == inspect.Parameter.POSITIONAL_ONLY
+ new_or_init = f.kind in (METHOD_NEW, METHOD_INIT)
+ default_return_converter = (not f.return_converter or
+ f.return_converter.type == 'PyObject *')
+ has_option_groups = False
+
+ # offset i by -1 because first_optional needs to ignore self
+ for i, p in enumerate(parameters, -1):
+ c = p.converter
+
+ if (i != -1) and (p.default is not unspecified):
+ first_optional = min(first_optional, i)
+
+ # insert group variable
+ group = p.group
+ if last_group != group:
+ last_group = group
+ if group:
+ group_name = self.group_to_variable_name(group)
+ data.impl_arguments.append(group_name)
+ data.declarations.append("int " + group_name + " = 0;")
+ data.impl_parameters.append("int " + group_name)
+ has_option_groups = True
+
+ c.render(p, data)
+
+ if has_option_groups and (not positional):
+ fail("You cannot use optional groups ('[' and ']')\nunless all parameters are positional-only ('/').")
+
+ # HACK
+ # when we're METH_O, but have a custom return converter,
+ # we use "impl_parameters" for the parsing function
+ # because that works better. but that means we must
+ # supress actually declaring the impl's parameters
+ # as variables in the parsing function. but since it's
+ # METH_O, we have exactly one anyway, so we know exactly
+ # where it is.
+ if ("METH_O" in templates['methoddef_define'] and
+ not default_return_converter):
+ data.declarations.pop(0)
+
template_dict = {}
full_name = f.full_name
template_dict['full_name'] = full_name
- name = full_name.rpartition('.')[2]
+ if new_or_init:
+ name = f.cls.name
+ else:
+ name = f.name
+
template_dict['name'] = name
if f.c_basename:
@@ -953,6 +1022,7 @@ __________________________________________________
if fields[-1] == '__new__':
fields.pop()
c_basename = "_".join(fields)
+
template_dict['c_basename'] = c_basename
methoddef_name = "{}_METHODDEF".format(c_basename.upper())
@@ -960,73 +1030,15 @@ __________________________________________________
template_dict['docstring'] = self.docstring_for_c_string(f)
- positional = has_option_groups = False
-
- first_optional = len(parameters)
-
- if parameters:
- last_group = 0
-
- for i, p in enumerate(parameters):
- c = p.converter
-
- if p.default is not unspecified:
- first_optional = min(first_optional, i)
-
- # insert group variable
- group = p.group
- if last_group != group:
- last_group = group
- if group:
- group_name = self.group_to_variable_name(group)
- data.impl_arguments.append(group_name)
- data.declarations.append("int " + group_name + " = 0;")
- data.impl_parameters.append("int " + group_name)
- has_option_groups = True
- c.render(p, data)
-
- positional = parameters[-1].kind == inspect.Parameter.POSITIONAL_ONLY
- if has_option_groups and (not positional):
- fail("You cannot use optional groups ('[' and ']')\nunless all parameters are positional-only ('/').")
-
- # HACK
- # when we're METH_O, but have a custom
- # return converter, we use
- # "impl_parameters" for the parsing
- # function because that works better.
- # but that means we must supress actually
- # declaring the impl's parameters as variables
- # in the parsing function. but since it's
- # METH_O, we only have one anyway, so we don't
- # have any problem finding it.
- default_return_converter = (not f.return_converter or
- f.return_converter.type == 'PyObject *')
- if (len(parameters) == 1 and
- parameters[0].kind == inspect.Parameter.POSITIONAL_ONLY and
- not converters[0].is_optional() and
- isinstance(converters[0], object_converter) and
- converters[0].format_unit == 'O' and
- not default_return_converter):
-
- data.declarations.pop(0)
-
- # now insert our "self" (or whatever) parameters
- # (we deliberately don't call render on self converters)
- stock_self = self_converter('self', f)
- template_dict['self_name'] = stock_self.name
- template_dict['self_type'] = stock_self.type
- data.impl_parameters.insert(0, f.self_converter.type + ("" if f.self_converter.type.endswith('*') else " ") + f.self_converter.name)
- if f.self_converter.type != stock_self.type:
- self_cast = '(' + f.self_converter.type + ')'
- else:
- self_cast = ''
- data.impl_arguments.insert(0, self_cast + stock_self.name)
+ template_dict['self_name'] = template_dict['self_type'] = template_dict['self_type_check'] = ''
+ f_self.converter.set_template_dict(template_dict)
f.return_converter.render(f, data)
template_dict['impl_return_type'] = f.return_converter.type
template_dict['declarations'] = "\n".join(data.declarations)
template_dict['initializers'] = "\n\n".join(data.initializers)
+ template_dict['modifications'] = '\n\n'.join(data.modifications)
template_dict['keywords'] = '"' + '", "'.join(data.keywords) + '"'
template_dict['format_units'] = ''.join(data.format_units)
template_dict['parse_arguments'] = ', '.join(data.parse_arguments)
@@ -1036,15 +1048,16 @@ __________________________________________________
template_dict['cleanup'] = "".join(data.cleanup)
template_dict['return_value'] = data.return_value
- # used by unpack tuple
- template_dict['unpack_min'] = str(first_optional)
- template_dict['unpack_max'] = str(len(parameters))
+ # used by unpack tuple code generator
+ ignore_self = -1 if isinstance(converters[0], self_converter) else 0
+ unpack_min = first_optional
+ unpack_max = len(selfless)
+ template_dict['unpack_min'] = str(unpack_min)
+ template_dict['unpack_max'] = str(unpack_max)
if has_option_groups:
self.render_option_group_parsing(f, template_dict)
- templates = self.output_templates(f)
-
for name, destination in clinic.field_destinations.items():
template = templates[name]
if has_option_groups:
@@ -1054,6 +1067,7 @@ __________________________________________________
declarations=template_dict['declarations'],
return_conversion=template_dict['return_conversion'],
initializers=template_dict['initializers'],
+ modifications=template_dict['modifications'],
cleanup=template_dict['cleanup'],
)
@@ -1077,6 +1091,7 @@ __________________________________________________
+
@contextlib.contextmanager
def OverrideStdioWith(stdout):
saved_stdout = sys.stdout
@@ -1349,8 +1364,14 @@ class Destination:
fail("Too many arguments for destination " + name + " new " + type)
if type =='file':
d = {}
- d['filename'] = filename = clinic.filename
- d['basename'], d['extension'] = os.path.splitext(filename)
+ filename = clinic.filename
+ d['path'] = filename
+ dirname, basename = os.path.split(filename)
+ if not dirname:
+ dirname = '.'
+ d['dirname'] = dirname
+ d['basename'] = basename
+ d['basename_root'], d['basename_extension'] = os.path.splitext(filename)
self.filename = args[0].format_map(d)
if type == 'two-pass':
self.id = None
@@ -1469,7 +1490,7 @@ impl_definition block
self.add_destination("buffer", "buffer")
self.add_destination("two-pass", "two-pass")
if filename:
- self.add_destination("file", "file", "{basename}.clinic{extension}")
+ self.add_destination("file", "file", "{dirname}/clinic/{basename}.h")
d = self.destinations.get
self.field_destinations = collections.OrderedDict((
@@ -1565,6 +1586,14 @@ impl_definition block
if destination.type == 'file':
try:
+ dirname = os.path.dirname(destination.filename)
+ try:
+ os.makedirs(dirname)
+ except FileExistsError:
+ if not os.path.isdir(dirname):
+ fail("Can't write to destination {}, "
+ "can't make directory {}!".format(
+ destination.filename, dirname))
with open(destination.filename, "rt") as f:
parser_2 = BlockParser(f.read(), language=self.language)
blocks = list(parser_2)
@@ -1689,10 +1718,12 @@ class Module:
return "<clinic.Module " + repr(self.name) + " at " + str(id(self)) + ">"
class Class:
- def __init__(self, name, module=None, cls=None):
+ def __init__(self, name, module=None, cls=None, typedef=None, type_object=None):
self.name = name
self.module = module
self.cls = cls
+ self.typedef = typedef
+ self.type_object = type_object
self.parent = cls or module
self.classes = collections.OrderedDict()
@@ -1775,7 +1806,9 @@ __xor__
""".strip().split())
-INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW = range(6)
+INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW = """
+INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW
+""".replace(",", "").strip().split()
class Function:
"""
@@ -1969,6 +2002,20 @@ class CConverter(metaclass=CConverterAutoRegister):
# Only used by format units ending with '#'.
length = False
+ # Should we show this parameter in the generated
+ # __text_signature__? This is *almost* always True.
+ # (It's only False for __new__, __init__, and METH_STATIC functions.)
+ show_in_signature = True
+
+ # Overrides the name used in a text signature.
+ # The name used for a "self" parameter must be one of
+ # self, type, or module; however users can set their own.
+ # This lets the self_converter overrule the user-settable
+ # name, *just* for the text signature.
+ # Only set by self_converter.
+ signature_name = None
+
+ # keep in sync with self_converter.__init__!
def __init__(self, name, function, default=unspecified, *, c_default=None, py_default=None, annotation=unspecified, **kwargs):
self.function = function
self.name = name
@@ -1998,11 +2045,23 @@ class CConverter(metaclass=CConverterAutoRegister):
def is_optional(self):
return (self.default is not unspecified)
- def render(self, parameter, data):
- """
- parameter is a clinic.Parameter instance.
- data is a CRenderData instance.
- """
+ def _render_self(self, parameter, data):
+ self.parameter = parameter
+ original_name = self.name
+ name = ensure_legal_c_identifier(original_name)
+
+ # impl_arguments
+ s = ("&" if self.impl_by_reference else "") + name
+ data.impl_arguments.append(s)
+ if self.length:
+ data.impl_arguments.append(self.length_name())
+
+ # impl_parameters
+ data.impl_parameters.append(self.simple_declaration(by_reference=self.impl_by_reference))
+ if self.length:
+ data.impl_parameters.append("Py_ssize_clean_t " + self.length_name())
+
+ def _render_non_self(self, parameter, data):
self.parameter = parameter
original_name = self.name
name = ensure_legal_c_identifier(original_name)
@@ -2016,11 +2075,10 @@ class CConverter(metaclass=CConverterAutoRegister):
if initializers:
data.initializers.append('/* initializers for ' + name + ' */\n' + initializers.rstrip())
- # impl_arguments
- s = ("&" if self.impl_by_reference else "") + name
- data.impl_arguments.append(s)
- if self.length:
- data.impl_arguments.append(self.length_name())
+ # modifications
+ modifications = self.modify()
+ if modifications:
+ data.modifications.append('/* modifications for ' + name + ' */\n' + modifications.rstrip())
# keywords
data.keywords.append(original_name)
@@ -2035,16 +2093,19 @@ class CConverter(metaclass=CConverterAutoRegister):
# parse_arguments
self.parse_argument(data.parse_arguments)
- # impl_parameters
- data.impl_parameters.append(self.simple_declaration(by_reference=self.impl_by_reference))
- if self.length:
- data.impl_parameters.append("Py_ssize_clean_t " + self.length_name())
-
# cleanup
cleanup = self.cleanup()
if cleanup:
data.cleanup.append('/* Cleanup for ' + name + ' */\n' + cleanup.rstrip() + "\n")
+ def render(self, parameter, data):
+ """
+ parameter is a clinic.Parameter instance.
+ data is a CRenderData instance.
+ """
+ self._render_self(parameter, data)
+ self._render_non_self(parameter, data)
+
def length_name(self):
"""Computes the name of the associated "length" variable."""
if not self.length:
@@ -2121,6 +2182,14 @@ class CConverter(metaclass=CConverterAutoRegister):
"""
return ""
+ def modify(self):
+ """
+ The C statements required to modify this variable after parsing.
+ Returns a string containing this code indented at column 0.
+ If no initialization is necessary, returns an empty string.
+ """
+ return ""
+
def cleanup(self):
"""
The C statements required to clean up after this variable.
@@ -2318,7 +2387,7 @@ class str_converter(CConverter):
format_unit = 'et#'
if format_unit.endswith('#'):
- print("Warning: code using format unit ", repr(format_unit), "probably doesn't work properly.")
+ fail("Sorry: code using format unit ", repr(format_unit), "probably doesn't work properly yet.\nGive Larry your test case and he'll it.")
# TODO set pointer to NULL
# TODO add cleanup for buffer
pass
@@ -2421,35 +2490,124 @@ class Py_buffer_converter(CConverter):
return "".join(["if (", name, ".obj)\n PyBuffer_Release(&", name, ");\n"])
+def correct_name_for_self(f):
+ if f.kind in (CALLABLE, METHOD_INIT):
+ if f.cls:
+ return "PyObject *", "self"
+ return "PyModuleDef *", "module"
+ if f.kind == STATIC_METHOD:
+ return "void *", "null"
+ if f.kind in (CLASS_METHOD, METHOD_NEW):
+ return "PyTypeObject *", "type"
+ raise RuntimeError("Unhandled type of function f: " + repr(f.kind))
+
+def required_type_for_self_for_parser(f):
+ type, _ = correct_name_for_self(f)
+ if f.kind in (METHOD_INIT, METHOD_NEW, STATIC_METHOD, CLASS_METHOD):
+ return type
+ return None
+
+
class self_converter(CConverter):
"""
A special-case converter:
this is the default converter used for "self".
"""
- type = "PyObject *"
+ type = None
+ format_unit = ''
+
+
def converter_init(self, *, type=None):
f = self.function
- if f.kind in (CALLABLE, METHOD_INIT):
- if f.cls:
- self.name = "self"
- else:
- self.name = "module"
- self.type = "PyModuleDef *"
- elif f.kind == STATIC_METHOD:
- self.name = "null"
- self.type = "void *"
- elif f.kind == CLASS_METHOD:
- self.name = "cls"
- self.type = "PyTypeObject *"
- elif f.kind == METHOD_NEW:
- self.name = "type"
- self.type = "PyTypeObject *"
-
- if type:
- self.type = type
+ default_type, default_name = correct_name_for_self(f)
+ self.signature_name = default_name
+ self.type = type or self.type or default_type
+
+ kind = self.function.kind
+ new_or_init = kind in (METHOD_NEW, METHOD_INIT)
+
+ if (kind == STATIC_METHOD) or new_or_init:
+ self.show_in_signature = False
+
+ # tp_new (METHOD_NEW) functions are of type newfunc:
+ # typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *);
+ # PyTypeObject is a typedef for struct _typeobject.
+ #
+ # tp_init (METHOD_INIT) functions are of type initproc:
+ # typedef int (*initproc)(PyObject *, PyObject *, PyObject *);
+ #
+ # All other functions generated by Argument Clinic are stored in
+ # PyMethodDef structures, in the ml_meth slot, which is of type PyCFunction:
+ # typedef PyObject *(*PyCFunction)(PyObject *, PyObject *);
+ # However! We habitually cast these functions to PyCFunction,
+ # since functions that accept keyword arguments don't fit this signature
+ # but are stored there anyway. So strict type equality isn't important
+ # for these functions.
+ #
+ # So:
+ #
+ # * The name of the first parameter to the impl and the parsing function will always
+ # be self.name.
+ #
+ # * The type of the first parameter to the impl will always be of self.type.
+ #
+ # * If the function is neither tp_new (METHOD_NEW) nor tp_init (METHOD_INIT):
+ # * The type of the first parameter to the parsing function is also self.type.
+ # This means that if you step into the parsing function, your "self" parameter
+ # is of the correct type, which may make debugging more pleasant.
+ #
+ # * Else if the function is tp_new (METHOD_NEW):
+ # * The type of the first parameter to the parsing function is "PyTypeObject *",
+ # so the type signature of the function call is an exact match.
+ # * If self.type != "PyTypeObject *", we cast the first parameter to self.type
+ # in the impl call.
+ #
+ # * Else if the function is tp_init (METHOD_INIT):
+ # * The type of the first parameter to the parsing function is "PyObject *",
+ # so the type signature of the function call is an exact match.
+ # * If self.type != "PyObject *", we cast the first parameter to self.type
+ # in the impl call.
+
+ @property
+ def parser_type(self):
+ return required_type_for_self_for_parser(self.function) or self.type
def render(self, parameter, data):
- fail("render() should never be called on self_converter instances")
+ """
+ parameter is a clinic.Parameter instance.
+ data is a CRenderData instance.
+ """
+ if self.function.kind == STATIC_METHOD:
+ return
+
+ self._render_self(parameter, data)
+
+ if self.type != self.parser_type:
+ # insert cast to impl_argument[0], aka self.
+ # we know we're in the first slot in all the CRenderData lists,
+ # because we render parameters in order, and self is always first.
+ assert len(data.impl_arguments) == 1
+ assert data.impl_arguments[0] == self.name
+ data.impl_arguments[0] = '(' + self.type + ")" + data.impl_arguments[0]
+
+ def set_template_dict(self, template_dict):
+ template_dict['self_name'] = self.name
+ template_dict['self_type'] = self.parser_type
+ kind = self.function.kind
+ cls = self.function.cls
+
+ if ((kind in (METHOD_NEW, METHOD_INIT)) and cls and cls.typedef):
+ if kind == METHOD_NEW:
+ passed_in_type = self.name
+ else:
+ passed_in_type = 'Py_TYPE({})'.format(self.name)
+
+ line = '({passed_in_type} == {type_object}) &&\n '
+ d = {
+ 'type_object': self.function.cls.type_object,
+ 'passed_in_type': passed_in_type
+ }
+ template_dict['self_type_check'] = line.format_map(d)
@@ -2704,6 +2862,7 @@ class DSLParser:
self.keyword_only = False
self.group = 0
self.parameter_state = self.ps_start
+ self.seen_positional_with_default = False
self.indent = IndentStack()
self.kind = CALLABLE
self.coexist = False
@@ -2721,11 +2880,15 @@ class DSLParser:
module, cls = self.clinic._module_and_class(fields)
if cls:
fail("Can't nest a module inside a class!")
+
+ if name in module.classes:
+ fail("Already defined module " + repr(name) + "!")
+
m = Module(name, module)
module.modules[name] = m
self.block.signatures.append(m)
- def directive_class(self, name):
+ def directive_class(self, name, typedef, type_object):
fields = name.split('.')
in_classes = False
parent = self
@@ -2733,11 +2896,12 @@ class DSLParser:
so_far = []
module, cls = self.clinic._module_and_class(fields)
- c = Class(name, module, cls)
- if cls:
- cls.classes[name] = c
- else:
- module.classes[name] = c
+ parent = cls or module
+ if name in parent.classes:
+ fail("Already defined class " + repr(name) + "!")
+
+ c = Class(name, module, cls, typedef, type_object)
+ parent.classes[name] = c
self.block.signatures.append(c)
def directive_set(self, name, value):
@@ -2931,6 +3095,8 @@ class DSLParser:
else:
existing_function = None
if not existing_function:
+ print("class", cls, "module", module, "exsiting", existing)
+ print("cls. functions", cls.functions)
fail("Couldn't find existing function " + repr(existing) + "!")
fields = [x.strip() for x in full_name.split('.')]
@@ -2997,7 +3163,7 @@ class DSLParser:
if not return_converter:
return_converter = init_return_converter()
elif fields[-1] in unsupported_special_methods:
- fail(fields[-1] + " should not be converted to Argument Clinic! (Yet.)")
+ fail(fields[-1] + " is a special method and cannot be converted to Argument Clinic! (Yet.)")
if not return_converter:
return_converter = CReturnConverter()
@@ -3007,6 +3173,16 @@ class DSLParser:
self.function = Function(name=function_name, full_name=full_name, module=module, cls=cls, c_basename=c_basename,
return_converter=return_converter, kind=self.kind, coexist=self.coexist)
self.block.signatures.append(self.function)
+
+ # insert a self converter automatically
+ type, name = correct_name_for_self(self.function)
+ kwargs = {}
+ if cls and type == "PyObject *":
+ kwargs['type'] = cls.typedef
+ sc = self.function.self_converter = self_converter(name, self.function, **kwargs)
+ p_self = Parameter(sc.name, inspect.Parameter.POSITIONAL_ONLY, function=self.function, converter=sc)
+ self.function.parameters[sc.name] = p_self
+
(cls or module).functions.append(self.function)
self.next(self.state_parameters_start)
@@ -3064,18 +3240,21 @@ class DSLParser:
# "parameter_state". (Previously the code was a miasma of ifs and
# separate boolean state variables.) The states are:
#
- # [ [ a, b, ] c, ] d, e, f, [ g, h, [ i ] ] / <- line
- # 01 2 3 4 5 6 <- state transitions
+ # [ [ a, b, ] c, ] d, e, f=3, [ g, h, [ i ] ] / <- line
+ # 01 2 3 4 5 6 7 <- state transitions
#
# 0: ps_start. before we've seen anything. legal transitions are to 1 or 3.
# 1: ps_left_square_before. left square brackets before required parameters.
# 2: ps_group_before. in a group, before required parameters.
- # 3: ps_required. required parameters. (renumber left groups!)
- # 4: ps_group_after. in a group, after required parameters.
- # 5: ps_right_square_after. right square brackets after required parameters.
- # 6: ps_seen_slash. seen slash.
+ # 3: ps_required. required parameters, positional-or-keyword or positional-only
+ # (we don't know yet). (renumber left groups!)
+ # 4: ps_optional. positional-or-keyword or positional-only parameters that
+ # now must have default values.
+ # 5: ps_group_after. in a group, after required parameters.
+ # 6: ps_right_square_after. right square brackets after required parameters.
+ # 7: ps_seen_slash. seen slash.
ps_start, ps_left_square_before, ps_group_before, ps_required, \
- ps_group_after, ps_right_square_after, ps_seen_slash = range(7)
+ ps_optional, ps_group_after, ps_right_square_after, ps_seen_slash = range(8)
def state_parameters_start(self, line):
if self.ignore_line(line):
@@ -3134,21 +3313,25 @@ class DSLParser:
elif self.parameter_state == self.ps_group_before:
if not self.group:
self.to_required()
- elif self.parameter_state == self.ps_group_after:
+ elif self.parameter_state in (self.ps_group_after, self.ps_optional):
pass
else:
- fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ")")
+ fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".a)")
base, equals, default = line.rpartition('=')
if not equals:
base = default
default = None
+
module = None
try:
ast_input = "def x({}): pass".format(base)
module = ast.parse(ast_input)
except SyntaxError:
try:
+ # the last = was probably inside a function call, like
+ # i: int(nullable=True)
+ # so assume there was no actual default value.
default = None
ast_input = "def x({}): pass".format(line)
module = ast.parse(ast_input)
@@ -3164,43 +3347,65 @@ class DSLParser:
name, legacy, kwargs = self.parse_converter(parameter.annotation)
if not default:
+ if self.parameter_state == self.ps_optional:
+ fail("Can't have a parameter without a default (" + repr(parameter_name) + ")\nafter a parameter with a default!")
value = unspecified
if 'py_default' in kwargs:
fail("You can't specify py_default without specifying a default value!")
else:
+ if self.parameter_state == self.ps_required:
+ self.parameter_state = self.ps_optional
default = default.strip()
+ bad = False
ast_input = "x = {}".format(default)
+ bad = False
try:
module = ast.parse(ast_input)
- # blacklist of disallowed ast nodes
- class DetectBadNodes(ast.NodeVisitor):
- bad = False
- def bad_node(self, node):
- self.bad = True
-
- # inline function call
- visit_Call = bad_node
- # inline if statement ("x = 3 if y else z")
- visit_IfExp = bad_node
-
- # comprehensions and generator expressions
- visit_ListComp = visit_SetComp = bad_node
- visit_DictComp = visit_GeneratorExp = bad_node
-
- # literals for advanced types
- visit_Dict = visit_Set = bad_node
- visit_List = visit_Tuple = bad_node
-
- # "starred": "a = [1, 2, 3]; *a"
- visit_Starred = bad_node
-
- # allow ellipsis, for now
- # visit_Ellipsis = bad_node
-
- blacklist = DetectBadNodes()
- blacklist.visit(module)
- if blacklist.bad:
+ if 'c_default' not in kwargs:
+ # we can only represent very simple data values in C.
+ # detect whether default is okay, via a blacklist
+ # of disallowed ast nodes.
+ class DetectBadNodes(ast.NodeVisitor):
+ bad = False
+ def bad_node(self, node):
+ self.bad = True
+
+ # inline function call
+ visit_Call = bad_node
+ # inline if statement ("x = 3 if y else z")
+ visit_IfExp = bad_node
+
+ # comprehensions and generator expressions
+ visit_ListComp = visit_SetComp = bad_node
+ visit_DictComp = visit_GeneratorExp = bad_node
+
+ # literals for advanced types
+ visit_Dict = visit_Set = bad_node
+ visit_List = visit_Tuple = bad_node
+
+ # "starred": "a = [1, 2, 3]; *a"
+ visit_Starred = bad_node
+
+ # allow ellipsis, for now
+ # visit_Ellipsis = bad_node
+
+ blacklist = DetectBadNodes()
+ blacklist.visit(module)
+ bad = blacklist.bad
+ else:
+ # if they specify a c_default, we can be more lenient about the default value.
+ # but at least make an attempt at ensuring it's a valid expression.
+ try:
+ value = eval(default)
+ if value == unspecified:
+ fail("'unspecified' is not a legal default value!")
+ except NameError:
+ pass # probably a named constant
+ except Exception as e:
+ fail("Malformed expression given as default value\n"
+ "{!r} caused {!r}".format(default, e))
+ if bad:
fail("Unsupported expression as default value: " + repr(default))
expr = module.body[0].value
@@ -3263,18 +3468,22 @@ class DSLParser:
fail('{} is not a valid {}converter'.format(name, legacy_str))
converter = dict[name](parameter_name, self.function, value, **kwargs)
- # special case: if it's the self converter,
- # don't actually add it to the parameter list
+ kind = inspect.Parameter.KEYWORD_ONLY if self.keyword_only else inspect.Parameter.POSITIONAL_OR_KEYWORD
+
if isinstance(converter, self_converter):
- if self.function.parameters or (self.parameter_state != self.ps_required):
- fail("The 'self' parameter, if specified, must be the very first thing in the parameter block.")
- if self.function.self_converter:
- fail("You can't specify the 'self' parameter more than once.")
- self.function.self_converter = converter
- self.parameter_state = self.ps_start
- return
+ if len(self.function.parameters) == 1:
+ if (self.parameter_state != self.ps_required):
+ fail("A 'self' parameter cannot be marked optional.")
+ if value is not unspecified:
+ fail("A 'self' parameter cannot have a default value.")
+ if self.group:
+ fail("A 'self' parameter cannot be in an optional group.")
+ kind = inspect.Parameter.POSITIONAL_ONLY
+ self.parameter_state = self.ps_start
+ self.function.parameters.clear()
+ else:
+ fail("A 'self' parameter, if specified, must be the very first thing in the parameter block.")
- kind = inspect.Parameter.KEYWORD_ONLY if self.keyword_only else inspect.Parameter.POSITIONAL_OR_KEYWORD
p = Parameter(parameter_name, kind, function=self.function, converter=converter, default=value, group=self.group)
if parameter_name in self.function.parameters:
@@ -3309,7 +3518,7 @@ class DSLParser:
elif self.parameter_state in (self.ps_required, self.ps_group_after):
self.parameter_state = self.ps_group_after
else:
- fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ")")
+ fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".b)")
self.group += 1
elif symbol == ']':
if not self.group:
@@ -3322,18 +3531,18 @@ class DSLParser:
elif self.parameter_state in (self.ps_group_after, self.ps_right_square_after):
self.parameter_state = self.ps_right_square_after
else:
- fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ")")
+ fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".c)")
elif symbol == '/':
- # ps_required is allowed here, that allows positional-only without option groups
+ # ps_required and ps_optional are allowed here, that allows positional-only without option groups
# to work (and have default values!)
- if (self.parameter_state not in (self.ps_required, self.ps_right_square_after, self.ps_group_before)) or self.group:
- fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ")")
+ if (self.parameter_state not in (self.ps_required, self.ps_optional, self.ps_right_square_after, self.ps_group_before)) or self.group:
+ fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".d)")
if self.keyword_only:
fail("Function " + self.function.name + " mixes keyword-only and positional-only parameters, which is unsupported.")
self.parameter_state = self.ps_seen_slash
# fixup preceeding parameters
for p in self.function.parameters.values():
- if p.kind != inspect.Parameter.POSITIONAL_OR_KEYWORD:
+ if (p.kind != inspect.Parameter.POSITIONAL_OR_KEYWORD and not isinstance(p.converter, self_converter)):
fail("Function " + self.function.name + " mixes keyword-only and positional-only parameters, which is unsupported.")
p.kind = inspect.Parameter.POSITIONAL_ONLY
@@ -3394,6 +3603,11 @@ class DSLParser:
def format_docstring(self):
f = self.function
+ new_or_init = f.kind in (METHOD_NEW, METHOD_INIT)
+ if new_or_init and not f.docstring:
+ # don't render a docstring at all, no signature, nothing.
+ return f.docstring
+
add, output = text_accumulator()
parameters = list(f.parameters.values())
@@ -3401,7 +3615,7 @@ class DSLParser:
## docstring first line
##
- if f.kind in (METHOD_NEW, METHOD_INIT):
+ if new_or_init:
assert f.cls
add(f.cls.name)
else:
@@ -3409,17 +3623,24 @@ class DSLParser:
add('(')
# populate "right_bracket_count" field for every parameter
- if parameters:
+ assert parameters, "We should always have a self parameter. " + repr(f)
+ assert isinstance(parameters[0].converter, self_converter)
+ parameters[0].right_bracket_count = 0
+ parameters_after_self = parameters[1:]
+ if parameters_after_self:
# for now, the only way Clinic supports positional-only parameters
- # is if all of them are positional-only.
- positional_only_parameters = [p.kind == inspect.Parameter.POSITIONAL_ONLY for p in parameters]
- if parameters[0].kind == inspect.Parameter.POSITIONAL_ONLY:
+ # is if all of them are positional-only...
+ #
+ # ... except for self! self is always positional-only.
+
+ positional_only_parameters = [p.kind == inspect.Parameter.POSITIONAL_ONLY for p in parameters_after_self]
+ if parameters_after_self[0].kind == inspect.Parameter.POSITIONAL_ONLY:
assert all(positional_only_parameters)
for p in parameters:
p.right_bracket_count = abs(p.group)
else:
# don't put any right brackets around non-positional-only parameters, ever.
- for p in parameters:
+ for p in parameters_after_self:
p.right_bracket_count = 0
right_bracket_count = 0
@@ -3439,6 +3660,9 @@ class DSLParser:
add_comma = False
for p in parameters:
+ if not p.converter.show_in_signature:
+ continue
+
assert p.name
if p.is_keyword_only() and not added_star:
@@ -3446,8 +3670,10 @@ class DSLParser:
if add_comma:
add(', ')
add('*')
+ add_comma = True
- a = [p.name]
+ name = p.converter.signature_name or p.name
+ a = [name]
if p.converter.is_optional():
a.append('=')
value = p.converter.py_default
@@ -3560,9 +3786,6 @@ class DSLParser:
if not self.function:
return
- if not self.function.self_converter:
- self.function.self_converter = self_converter("self", self.function)
-
if self.keyword_only:
values = self.function.parameters.values()
if not values:
@@ -3582,6 +3805,8 @@ class DSLParser:
self.function.docstring = self.format_docstring()
+
+
# maps strings to callables.
# the callable should return an object
# that implements the clinic parser
@@ -3607,6 +3832,7 @@ def main(argv):
cmdline = argparse.ArgumentParser()
cmdline.add_argument("-f", "--force", action='store_true')
cmdline.add_argument("-o", "--output", type=str)
+ cmdline.add_argument("-v", "--verbose", action='store_true')
cmdline.add_argument("--converters", action='store_true')
cmdline.add_argument("--make", action='store_true')
cmdline.add_argument("filename", type=str, nargs="*")
@@ -3680,13 +3906,15 @@ def main(argv):
cmdline.print_usage()
sys.exit(-1)
for root, dirs, files in os.walk('.'):
- for rcs_dir in ('.svn', '.git', '.hg'):
+ for rcs_dir in ('.svn', '.git', '.hg', 'build'):
if rcs_dir in dirs:
dirs.remove(rcs_dir)
for filename in files:
- if not filename.endswith('.c'):
+ if not (filename.endswith('.c') or filename.endswith('.h')):
continue
path = os.path.join(root, filename)
+ if ns.verbose:
+ print(path)
parse_file(path, verify=not ns.force)
return
@@ -3701,6 +3929,8 @@ def main(argv):
sys.exit(-1)
for filename in ns.filename:
+ if ns.verbose:
+ print(filename)
parse_file(filename, output=ns.output, verify=not ns.force)