merge heads
This commit is contained in:
commit
08a95cabe3
|
@ -447,34 +447,3 @@ In Python 2.2, you can inherit from built-in classes such as :class:`int`,
|
|||
The Boost Python Library (BPL, http://www.boost.org/libs/python/doc/index.html)
|
||||
provides a way of doing this from C++ (i.e. you can inherit from an extension
|
||||
class written in C++ using the BPL).
|
||||
|
||||
|
||||
When importing module X, why do I get "undefined symbol: PyUnicodeUCS2*"?
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
You are using a version of Python that uses a 4-byte representation for Unicode
|
||||
characters, but some C extension module you are importing was compiled using a
|
||||
Python that uses a 2-byte representation for Unicode characters (the default).
|
||||
|
||||
If instead the name of the undefined symbol starts with ``PyUnicodeUCS4``, the
|
||||
problem is the reverse: Python was built using 2-byte Unicode characters, and
|
||||
the extension module was compiled using a Python with 4-byte Unicode characters.
|
||||
|
||||
This can easily occur when using pre-built extension packages. RedHat Linux
|
||||
7.x, in particular, provided a "python2" binary that is compiled with 4-byte
|
||||
Unicode. This only causes the link failure if the extension uses any of the
|
||||
``PyUnicode_*()`` functions. It is also a problem if an extension uses any of
|
||||
the Unicode-related format specifiers for :c:func:`Py_BuildValue` (or similar) or
|
||||
parameter specifications for :c:func:`PyArg_ParseTuple`.
|
||||
|
||||
You can check the size of the Unicode character a Python interpreter is using by
|
||||
checking the value of sys.maxunicode:
|
||||
|
||||
>>> import sys
|
||||
>>> if sys.maxunicode > 65535:
|
||||
... print('UCS4 build')
|
||||
... else:
|
||||
... print('UCS2 build')
|
||||
|
||||
The only way to solve this problem is to use extension modules compiled with a
|
||||
Python binary built using the same size for Unicode characters.
|
||||
|
|
|
@ -123,7 +123,9 @@ and off individually. They are described here in more detail.
|
|||
.. 2to3fixer:: callable
|
||||
|
||||
Converts ``callable(x)`` to ``isinstance(x, collections.Callable)``, adding
|
||||
an import to :mod:`collections` if needed.
|
||||
an import to :mod:`collections` if needed. Note ``callable(x)`` has returned
|
||||
in Python 3.2, so if you do not intend to support Python 3.1, you can disable
|
||||
this fixer.
|
||||
|
||||
.. 2to3fixer:: dict
|
||||
|
||||
|
|
|
@ -427,7 +427,7 @@ FTP_TLS Objects
|
|||
|
||||
.. method:: FTP_TLS.ccc()
|
||||
|
||||
Revert control channel back to plaintex. This can be useful to take
|
||||
Revert control channel back to plaintext. This can be useful to take
|
||||
advantage of firewalls that know how to handle NAT with non-secure FTP
|
||||
without opening fixed ports.
|
||||
|
||||
|
|
|
@ -353,8 +353,8 @@ The :mod:`signal` module defines the following functions:
|
|||
signals in *sigset* is already pending for the calling thread, the function
|
||||
will return immediately with information about that signal. The signal
|
||||
handler is not called for the delivered signal. The function raises an
|
||||
:exc:`OSError` with error number set to :const:`errno.EINTR` if it is
|
||||
interrupted by a signal that is not in *sigset*.
|
||||
:exc:`InterruptedError` if it is interrupted by a signal that is not in
|
||||
*sigset*.
|
||||
|
||||
The return value is an object representing the data contained in the
|
||||
:c:type:`siginfo_t` structure, namely: :attr:`si_signo`, :attr:`si_code`,
|
||||
|
|
|
@ -361,7 +361,7 @@ This is the server side::
|
|||
def handle(self):
|
||||
# self.request is the TCP socket connected to the client
|
||||
self.data = self.request.recv(1024).strip()
|
||||
print("%s wrote:" % self.client_address[0])
|
||||
print("{} wrote:".format(self.client_address[0]))
|
||||
print(self.data)
|
||||
# just send back the same data, but upper-cased
|
||||
self.request.send(self.data.upper())
|
||||
|
@ -385,7 +385,7 @@ objects that simplify communication by providing the standard file interface)::
|
|||
# self.rfile is a file-like object created by the handler;
|
||||
# we can now use e.g. readline() instead of raw recv() calls
|
||||
self.data = self.rfile.readline().strip()
|
||||
print("%s wrote:" % self.client_address[0])
|
||||
print("{} wrote:".format(self.client_address[0]))
|
||||
print(self.data)
|
||||
# Likewise, self.wfile is a file-like object used to write back
|
||||
# to the client
|
||||
|
@ -408,16 +408,18 @@ This is the client side::
|
|||
# Create a socket (SOCK_STREAM means a TCP socket)
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
||||
# Connect to server and send data
|
||||
sock.connect((HOST, PORT))
|
||||
sock.send(bytes(data + "\n","utf8"))
|
||||
try:
|
||||
# Connect to server and send data
|
||||
sock.connect((HOST, PORT))
|
||||
sock.send(bytes(data + "\n", "utf-8"))
|
||||
|
||||
# Receive data from the server and shut down
|
||||
received = sock.recv(1024)
|
||||
sock.close()
|
||||
# Receive data from the server and shut down
|
||||
received = str(sock.recv(1024), "utf-8")
|
||||
finally:
|
||||
sock.close()
|
||||
|
||||
print("Sent: %s" % data)
|
||||
print("Received: %s" % received)
|
||||
print("Sent: {}".format(data))
|
||||
print("Received: {}".format(received))
|
||||
|
||||
|
||||
The output of the example should look something like this:
|
||||
|
@ -434,10 +436,10 @@ Client::
|
|||
|
||||
$ python TCPClient.py hello world with TCP
|
||||
Sent: hello world with TCP
|
||||
Received: b'HELLO WORLD WITH TCP'
|
||||
Received: HELLO WORLD WITH TCP
|
||||
$ python TCPClient.py python is nice
|
||||
Sent: python is nice
|
||||
Received: b'PYTHON IS NICE'
|
||||
Received: PYTHON IS NICE
|
||||
|
||||
|
||||
:class:`socketserver.UDPServer` Example
|
||||
|
@ -458,7 +460,7 @@ This is the server side::
|
|||
def handle(self):
|
||||
data = self.request[0].strip()
|
||||
socket = self.request[1]
|
||||
print("%s wrote:" % self.client_address[0])
|
||||
print("{} wrote:".format(self.client_address[0]))
|
||||
print(data)
|
||||
socket.sendto(data.upper(), self.client_address)
|
||||
|
||||
|
@ -480,11 +482,11 @@ This is the client side::
|
|||
|
||||
# As you can see, there is no connect() call; UDP has no connections.
|
||||
# Instead, data is directly sent to the recipient via sendto().
|
||||
sock.sendto(bytes(data + "\n","utf8"), (HOST, PORT))
|
||||
received = sock.recv(1024)
|
||||
sock.sendto(bytes(data + "\n", "utf-8"), (HOST, PORT))
|
||||
received = str(sock.recv(1024), "utf-8")
|
||||
|
||||
print("Sent: %s" % data)
|
||||
print("Received: %s" % received)
|
||||
print("Sent: {}".format(data))
|
||||
print("Received: {}".format(received))
|
||||
|
||||
The output of the example should look exactly like for the TCP server example.
|
||||
|
||||
|
@ -504,9 +506,9 @@ An example for the :class:`ThreadingMixIn` class::
|
|||
class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
|
||||
|
||||
def handle(self):
|
||||
data = self.request.recv(1024)
|
||||
data = str(self.request.recv(1024), 'ascii')
|
||||
cur_thread = threading.current_thread()
|
||||
response = bytes("%s: %s" % (cur_thread.getName(), data),'ascii')
|
||||
response = bytes("{}: {}".format(cur_thread.name, data), 'ascii')
|
||||
self.request.send(response)
|
||||
|
||||
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
||||
|
@ -515,10 +517,12 @@ An example for the :class:`ThreadingMixIn` class::
|
|||
def client(ip, port, message):
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.connect((ip, port))
|
||||
sock.send(message)
|
||||
response = sock.recv(1024)
|
||||
print("Received: %s" % response)
|
||||
sock.close()
|
||||
try:
|
||||
sock.send(bytes(message, 'ascii'))
|
||||
response = str(sock.recv(1024), 'ascii')
|
||||
print("Received: {}".format(response))
|
||||
finally:
|
||||
sock.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Port 0 means to select an arbitrary unused port
|
||||
|
@ -531,13 +535,13 @@ An example for the :class:`ThreadingMixIn` class::
|
|||
# more thread for each request
|
||||
server_thread = threading.Thread(target=server.serve_forever)
|
||||
# Exit the server thread when the main thread terminates
|
||||
server_thread.setDaemon(True)
|
||||
server_thread.daemon = True
|
||||
server_thread.start()
|
||||
print("Server loop running in thread:", server_thread.name)
|
||||
|
||||
client(ip, port, b"Hello World 1")
|
||||
client(ip, port, b"Hello World 2")
|
||||
client(ip, port, b"Hello World 3")
|
||||
client(ip, port, "Hello World 1")
|
||||
client(ip, port, "Hello World 2")
|
||||
client(ip, port, "Hello World 3")
|
||||
|
||||
server.shutdown()
|
||||
|
||||
|
@ -546,9 +550,9 @@ The output of the example should look something like this::
|
|||
|
||||
$ python ThreadedTCPServer.py
|
||||
Server loop running in thread: Thread-1
|
||||
Received: b"Thread-2: b'Hello World 1'"
|
||||
Received: b"Thread-3: b'Hello World 2'"
|
||||
Received: b"Thread-4: b'Hello World 3'"
|
||||
Received: Thread-2: Hello World 1
|
||||
Received: Thread-3: Hello World 2
|
||||
Received: Thread-4: Hello World 3
|
||||
|
||||
|
||||
The :class:`ForkingMixIn` class is used in the same way, except that the server
|
||||
|
|
|
@ -49,28 +49,32 @@
|
|||
This article explains the new features in Python 3.3, compared to 3.2.
|
||||
|
||||
|
||||
.. _pep-393:
|
||||
|
||||
PEP 393: Flexible String Representation
|
||||
=======================================
|
||||
|
||||
[Abstract copied from the PEP: The Unicode string type is changed to support
|
||||
multiple internal representations, depending on the character with the largest
|
||||
Unicode ordinal (1, 2, or 4 bytes). This allows a space-efficient
|
||||
representation in common cases, but gives access to full UCS-4 on all systems.
|
||||
For compatibility with existing APIs, several representations may exist in
|
||||
parallel; over time, this compatibility should be phased out.]
|
||||
The Unicode string type is changed to support multiple internal
|
||||
representations, depending on the character with the largest Unicode ordinal
|
||||
(1, 2, or 4 bytes) in the represented string. This allows a space-efficient
|
||||
representation in common cases, but gives access to full UCS-4 on all
|
||||
systems. For compatibility with existing APIs, several representations may
|
||||
exist in parallel; over time, this compatibility should be phased out.
|
||||
|
||||
PEP 393 is fully backward compatible. The legacy API should remain
|
||||
available at least five years. Applications using the legacy API will not
|
||||
fully benefit of the memory reduction, or worse may use a little bit more
|
||||
memory, because Python may have to maintain two versions of each string (in
|
||||
the legacy format and in the new efficient storage).
|
||||
On the Python side, there should be no downside to this change.
|
||||
|
||||
XXX Add list of changes introduced by :pep:`393` here:
|
||||
On the C API side, PEP 393 is fully backward compatible. The legacy API
|
||||
should remain available at least five years. Applications using the legacy
|
||||
API will not fully benefit of the memory reduction, or - worse - may use
|
||||
a bit more memory, because Python may have to maintain two versions of each
|
||||
string (in the legacy format and in the new efficient storage).
|
||||
|
||||
Changes introduced by :pep:`393` are the following:
|
||||
|
||||
* Python now always supports the full range of Unicode codepoints, including
|
||||
non-BMP ones (i.e. from ``U+0000`` to ``U+10FFFF``). The distinction between
|
||||
narrow and wide builds no longer exists and Python now behaves like a wide
|
||||
build.
|
||||
build, even under Windows.
|
||||
|
||||
* The storage of Unicode strings now depends on the highest codepoint in the string:
|
||||
|
||||
|
@ -86,7 +90,8 @@ XXX Add list of changes introduced by :pep:`393` here:
|
|||
XXX The result should be moved in the PEP and a small summary about
|
||||
performances and a link to the PEP should be added here.
|
||||
|
||||
* Some of the problems visible on narrow builds have been fixed, for example:
|
||||
* With the death of narrow builds, the problems specific to narrow builds have
|
||||
also been fixed, for example:
|
||||
|
||||
* :func:`len` now always returns 1 for non-BMP characters,
|
||||
so ``len('\U0010FFFF') == 1``;
|
||||
|
@ -94,10 +99,11 @@ XXX Add list of changes introduced by :pep:`393` here:
|
|||
* surrogate pairs are not recombined in string literals,
|
||||
so ``'\uDBFF\uDFFF' != '\U0010FFFF'``;
|
||||
|
||||
* indexing or slicing a non-BMP characters doesn't return surrogates anymore,
|
||||
* indexing or slicing non-BMP characters returns the expected value,
|
||||
so ``'\U0010FFFF'[0]`` now returns ``'\U0010FFFF'`` and not ``'\uDBFF'``;
|
||||
|
||||
* several other functions in the stdlib now handle correctly non-BMP codepoints.
|
||||
* several other functions in the standard library now handle correctly
|
||||
non-BMP codepoints.
|
||||
|
||||
* The value of :data:`sys.maxunicode` is now always ``1114111`` (``0x10FFFF``
|
||||
in hexadecimal). The :c:func:`PyUnicode_GetMax` function still returns
|
||||
|
@ -113,40 +119,44 @@ PEP 3151: Reworking the OS and IO exception hierarchy
|
|||
=====================================================
|
||||
|
||||
:pep:`3151` - Reworking the OS and IO exception hierarchy
|
||||
PEP written and implemented by Antoine Pitrou.
|
||||
PEP written and implemented by Antoine Pitrou.
|
||||
|
||||
New subclasses of :exc:`OSError` exceptions:
|
||||
The hierarchy of exceptions raised by operating system errors is now both
|
||||
simplified and finer-grained.
|
||||
|
||||
* :exc:`BlockingIOError`
|
||||
* :exc:`ChildProcessError`
|
||||
* :exc:`ConnectionError`
|
||||
You don't have to worry anymore about choosing the appropriate exception
|
||||
type between :exc:`OSError`, :exc:`IOError`, :exc:`EnvironmentError`,
|
||||
:exc:`WindowsError`, :exc:`mmap.error`, :exc:`socket.error` or
|
||||
:exc:`select.error`. All these exception types are now only one:
|
||||
:exc:`OSError`. The other names are kept as aliases for compatibility
|
||||
reasons.
|
||||
|
||||
* :exc:`BrokenPipeError`
|
||||
* :exc:`ConnectionAbortedError`
|
||||
* :exc:`ConnectionRefusedError`
|
||||
* :exc:`ConnectionResetError`
|
||||
Also, it is now easier to catch a specific error condition. Instead of
|
||||
inspecting the ``errno`` attribute (or ``args[0]``) for a particular
|
||||
constant from the :mod:`errno` module, you can catch the adequate
|
||||
:exc:`OSError` subclass. The available subclasses are the following:
|
||||
|
||||
* :exc:`FileExistsError`
|
||||
* :exc:`FileNotFoundError`
|
||||
* :exc:`InterruptedError`
|
||||
* :exc:`IsADirectoryError`
|
||||
* :exc:`NotADirectoryError`
|
||||
* :exc:`PermissionError`
|
||||
* :exc:`ProcessLookupError`
|
||||
* :exc:`TimeoutError`
|
||||
* :exc:`BlockingIOError`
|
||||
* :exc:`ChildProcessError`
|
||||
* :exc:`ConnectionError`
|
||||
* :exc:`FileExistsError`
|
||||
* :exc:`FileNotFoundError`
|
||||
* :exc:`InterruptedError`
|
||||
* :exc:`IsADirectoryError`
|
||||
* :exc:`NotADirectoryError`
|
||||
* :exc:`PermissionError`
|
||||
* :exc:`ProcessLookupError`
|
||||
* :exc:`TimeoutError`
|
||||
|
||||
The following exceptions have been merged into :exc:`OSError`:
|
||||
And the :exc:`ConnectionError` itself has finer-grained subclasses:
|
||||
|
||||
* :exc:`EnvironmentError`
|
||||
* :exc:`IOError`
|
||||
* :exc:`WindowsError`
|
||||
* :exc:`VMSError`
|
||||
* :exc:`socket.error`
|
||||
* :exc:`select.error`
|
||||
* :exc:`mmap.error`
|
||||
* :exc:`BrokenPipeError`
|
||||
* :exc:`ConnectionAbortedError`
|
||||
* :exc:`ConnectionRefusedError`
|
||||
* :exc:`ConnectionResetError`
|
||||
|
||||
Thanks to the new exceptions, common usages of the :mod:`errno` can now be
|
||||
avoided. For example, the following code written for Python 3.2: ::
|
||||
avoided. For example, the following code written for Python 3.2::
|
||||
|
||||
from errno import ENOENT, EACCES, EPERM
|
||||
|
||||
|
@ -161,7 +171,8 @@ avoided. For example, the following code written for Python 3.2: ::
|
|||
else:
|
||||
raise
|
||||
|
||||
can now be written without the :mod:`errno` import: ::
|
||||
can now be written without the :mod:`errno` import and without manual
|
||||
inspection of exception attributes::
|
||||
|
||||
try:
|
||||
with open("document.txt") as f:
|
||||
|
@ -180,7 +191,7 @@ Some smaller changes made to the core Python language are:
|
|||
* Stub
|
||||
|
||||
Added support for Unicode name aliases and named sequences.
|
||||
Both :func:`unicodedata.lookup()` and '\N{...}' now resolve name aliases,
|
||||
Both :func:`unicodedata.lookup()` and ``'\N{...}'`` now resolve name aliases,
|
||||
and :func:`unicodedata.lookup()` resolves named sequences too.
|
||||
|
||||
(Contributed by Ezio Melotti in :issue:`12753`)
|
||||
|
@ -267,7 +278,7 @@ ftplib
|
|||
|
||||
The :class:`~ftplib.FTP_TLS` class now provides a new
|
||||
:func:`~ftplib.FTP_TLS.ccc` function to revert control channel back to
|
||||
plaintex. This can be useful to take advantage of firewalls that know how to
|
||||
plaintext. This can be useful to take advantage of firewalls that know how to
|
||||
handle NAT with non-secure FTP without opening fixed ports.
|
||||
|
||||
(Contributed by Giampaolo Rodolà in :issue:`12139`)
|
||||
|
@ -531,7 +542,10 @@ Porting to Python 3.3
|
|||
=====================
|
||||
|
||||
This section lists previously described changes and other bugfixes
|
||||
that may require changes to your code:
|
||||
that may require changes to your code.
|
||||
|
||||
Porting Python code
|
||||
-------------------
|
||||
|
||||
* Issue #12326: On Linux, sys.platform doesn't contain the major version
|
||||
anymore. It is now always 'linux', instead of 'linux2' or 'linux3' depending
|
||||
|
@ -539,6 +553,24 @@ that may require changes to your code:
|
|||
with sys.platform.startswith('linux'), or directly sys.platform == 'linux' if
|
||||
you don't need to support older Python versions.
|
||||
|
||||
Porting C code
|
||||
--------------
|
||||
|
||||
* Due to :ref:`PEP 393 <pep-393>`, the :c:type:`Py_UNICODE` type and all
|
||||
functions using this type are deprecated (but will stay available for
|
||||
at least five years). If you were using low-level Unicode APIs to
|
||||
construct and access unicode objects and you want to benefit of the
|
||||
memory footprint reduction provided by the PEP 393, you have to convert
|
||||
your code to the new :doc:`Unicode API <../c-api/unicode>`.
|
||||
|
||||
However, if you only have been using high-level functions such as
|
||||
:c:func:`PyUnicode_Concat()`, :c:func:`PyUnicode_Join` or
|
||||
:c:func:`PyUnicode_FromFormat()`, your code will automatically take
|
||||
advantage of the new unicode representations.
|
||||
|
||||
Other issues
|
||||
------------
|
||||
|
||||
.. Issue #11591: When :program:`python` was started with :option:`-S`,
|
||||
``import site`` will not add site-specific paths to the module search
|
||||
paths. In previous versions, it did. See changeset for doc changes in
|
||||
|
@ -548,8 +580,3 @@ that may require changes to your code:
|
|||
removed. Code checking sys.flags.division_warning will need updating.
|
||||
Contributed by Éric Araujo.
|
||||
|
||||
* :pep:`393`: The :c:type:`Py_UNICODE` type and all functions using this type
|
||||
are deprecated. To fully benefit of the memory footprint reduction provided
|
||||
by the PEP 393, you have to convert your code to the new Unicode API. Read
|
||||
the porting guide: XXX.
|
||||
|
||||
|
|
17
Lib/_pyio.py
17
Lib/_pyio.py
|
@ -14,7 +14,6 @@ except ImportError:
|
|||
|
||||
import io
|
||||
from io import (__all__, SEEK_SET, SEEK_CUR, SEEK_END)
|
||||
from errno import EINTR
|
||||
|
||||
# open() uses st_blksize whenever we can
|
||||
DEFAULT_BUFFER_SIZE = 8 * 1024 # bytes
|
||||
|
@ -948,9 +947,7 @@ class BufferedReader(_BufferedIOMixin):
|
|||
# Read until EOF or until read() would block.
|
||||
try:
|
||||
chunk = self.raw.read()
|
||||
except IOError as e:
|
||||
if e.errno != EINTR:
|
||||
raise
|
||||
except InterruptedError:
|
||||
continue
|
||||
if chunk in empty_values:
|
||||
nodata_val = chunk
|
||||
|
@ -972,9 +969,7 @@ class BufferedReader(_BufferedIOMixin):
|
|||
while avail < n:
|
||||
try:
|
||||
chunk = self.raw.read(wanted)
|
||||
except IOError as e:
|
||||
if e.errno != EINTR:
|
||||
raise
|
||||
except InterruptedError:
|
||||
continue
|
||||
if chunk in empty_values:
|
||||
nodata_val = chunk
|
||||
|
@ -1007,9 +1002,7 @@ class BufferedReader(_BufferedIOMixin):
|
|||
while True:
|
||||
try:
|
||||
current = self.raw.read(to_read)
|
||||
except IOError as e:
|
||||
if e.errno != EINTR:
|
||||
raise
|
||||
except InterruptedError:
|
||||
continue
|
||||
break
|
||||
if current:
|
||||
|
@ -1120,9 +1113,7 @@ class BufferedWriter(_BufferedIOMixin):
|
|||
while self._write_buf:
|
||||
try:
|
||||
n = self.raw.write(self._write_buf)
|
||||
except IOError as e:
|
||||
if e.errno != EINTR:
|
||||
raise
|
||||
except InterruptedError:
|
||||
continue
|
||||
if n > len(self._write_buf) or n < 0:
|
||||
raise IOError("write() returned incorrect number of bytes")
|
||||
|
|
|
@ -54,7 +54,7 @@ import warnings
|
|||
|
||||
import os
|
||||
from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, EINVAL, \
|
||||
ENOTCONN, ESHUTDOWN, EINTR, EISCONN, EBADF, ECONNABORTED, EPIPE, EAGAIN, \
|
||||
ENOTCONN, ESHUTDOWN, EISCONN, EBADF, ECONNABORTED, EPIPE, EAGAIN, \
|
||||
errorcode
|
||||
|
||||
_DISCONNECTED = frozenset((ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED, EPIPE,
|
||||
|
@ -143,11 +143,8 @@ def poll(timeout=0.0, map=None):
|
|||
|
||||
try:
|
||||
r, w, e = select.select(r, w, e, timeout)
|
||||
except select.error as err:
|
||||
if err.args[0] != EINTR:
|
||||
raise
|
||||
else:
|
||||
return
|
||||
except InterruptedError:
|
||||
return
|
||||
|
||||
for fd in r:
|
||||
obj = map.get(fd)
|
||||
|
@ -190,9 +187,7 @@ def poll2(timeout=0.0, map=None):
|
|||
pollster.register(fd, flags)
|
||||
try:
|
||||
r = pollster.poll(timeout)
|
||||
except select.error as err:
|
||||
if err.args[0] != EINTR:
|
||||
raise
|
||||
except InterruptedError:
|
||||
r = []
|
||||
for fd, flags in r:
|
||||
obj = map.get(fd)
|
||||
|
|
|
@ -3903,28 +3903,6 @@ class Context(object):
|
|||
return nc
|
||||
__copy__ = copy
|
||||
|
||||
# _clamp is provided for backwards compatibility with third-party
|
||||
# code. May be removed in Python >= 3.3.
|
||||
def _get_clamp(self):
|
||||
"_clamp mirrors the clamp attribute. Its use is deprecated."
|
||||
import warnings
|
||||
warnings.warn('Use of the _clamp attribute is deprecated. '
|
||||
'Please use clamp instead.',
|
||||
DeprecationWarning)
|
||||
return self.clamp
|
||||
|
||||
def _set_clamp(self, clamp):
|
||||
"_clamp mirrors the clamp attribute. Its use is deprecated."
|
||||
import warnings
|
||||
warnings.warn('Use of the _clamp attribute is deprecated. '
|
||||
'Please use clamp instead.',
|
||||
DeprecationWarning)
|
||||
self.clamp = clamp
|
||||
|
||||
# don't bother with _del_clamp; no sane 3rd party code should
|
||||
# be deleting the _clamp attribute
|
||||
_clamp = property(_get_clamp, _set_clamp)
|
||||
|
||||
def _raise_error(self, condition, explanation = None, *args):
|
||||
"""Handles an error
|
||||
|
||||
|
|
|
@ -175,10 +175,8 @@ class FTP:
|
|||
|
||||
# Internal: "sanitize" a string for printing
|
||||
def sanitize(self, s):
|
||||
if s[:5] == 'pass ' or s[:5] == 'PASS ':
|
||||
i = len(s)
|
||||
while i > 5 and s[i-1] in {'\r', '\n'}:
|
||||
i = i-1
|
||||
if s[:5] in {'pass ', 'PASS '}:
|
||||
i = len(s.rstrip('\r\n'))
|
||||
s = s[:5] + '*'*(i-5) + s[i:]
|
||||
return repr(s)
|
||||
|
||||
|
@ -596,10 +594,7 @@ class FTP:
|
|||
resp = self.sendcmd('SIZE ' + filename)
|
||||
if resp[:3] == '213':
|
||||
s = resp[3:].strip()
|
||||
try:
|
||||
return int(s)
|
||||
except (OverflowError, ValueError):
|
||||
return int(s)
|
||||
return int(s)
|
||||
|
||||
def mkd(self, dirname):
|
||||
'''Make a directory, return its full pathname.'''
|
||||
|
@ -861,11 +856,7 @@ def parse150(resp):
|
|||
m = _150_re.match(resp)
|
||||
if not m:
|
||||
return None
|
||||
s = m.group(1)
|
||||
try:
|
||||
return int(s)
|
||||
except (OverflowError, ValueError):
|
||||
return int(s)
|
||||
return int(m.group(1))
|
||||
|
||||
|
||||
_227_re = None
|
||||
|
|
|
@ -321,7 +321,11 @@ class Pool(object):
|
|||
|
||||
@staticmethod
|
||||
def _handle_workers(pool):
|
||||
while pool._worker_handler._state == RUN and pool._state == RUN:
|
||||
thread = threading.current_thread()
|
||||
|
||||
# Keep maintaining workers until the cache gets drained, unless the pool
|
||||
# is terminated.
|
||||
while thread._state == RUN or (pool._cache and thread._state != TERMINATE):
|
||||
pool._maintain_pool()
|
||||
time.sleep(0.1)
|
||||
# send sentinel to stop workers
|
||||
|
|
|
@ -327,15 +327,12 @@ class ForkAwareLocal(threading.local):
|
|||
# Automatic retry after EINTR
|
||||
#
|
||||
|
||||
def _eintr_retry(func, _errors=(EnvironmentError, select.error)):
|
||||
def _eintr_retry(func):
|
||||
@functools.wraps(func)
|
||||
def wrapped(*args, **kwargs):
|
||||
while True:
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except _errors as e:
|
||||
# select.error has no `errno` attribute
|
||||
if e.args[0] == errno.EINTR:
|
||||
continue
|
||||
raise
|
||||
except InterruptedError:
|
||||
continue
|
||||
return wrapped
|
||||
|
|
|
@ -417,11 +417,8 @@ def _parse_num(val, type):
|
|||
def _parse_int(val):
|
||||
return _parse_num(val, int)
|
||||
|
||||
def _parse_long(val):
|
||||
return _parse_num(val, int)
|
||||
|
||||
_builtin_cvt = { "int" : (_parse_int, _("integer")),
|
||||
"long" : (_parse_long, _("long integer")),
|
||||
"long" : (_parse_int, _("integer")),
|
||||
"float" : (float, _("floating-point")),
|
||||
"complex" : (complex, _("complex")) }
|
||||
|
||||
|
|
|
@ -510,10 +510,7 @@ def read_decimalnl_short(f):
|
|||
elif s == b"01":
|
||||
return True
|
||||
|
||||
try:
|
||||
return int(s)
|
||||
except OverflowError:
|
||||
return int(s)
|
||||
return int(s)
|
||||
|
||||
def read_decimalnl_long(f):
|
||||
r"""
|
||||
|
|
|
@ -53,7 +53,6 @@ try:
|
|||
except ImportError:
|
||||
errno = None
|
||||
EBADF = getattr(errno, 'EBADF', 9)
|
||||
EINTR = getattr(errno, 'EINTR', 4)
|
||||
EAGAIN = getattr(errno, 'EAGAIN', 11)
|
||||
EWOULDBLOCK = getattr(errno, 'EWOULDBLOCK', 11)
|
||||
|
||||
|
@ -280,11 +279,10 @@ class SocketIO(io.RawIOBase):
|
|||
except timeout:
|
||||
self._timeout_occurred = True
|
||||
raise
|
||||
except InterruptedError:
|
||||
continue
|
||||
except error as e:
|
||||
n = e.args[0]
|
||||
if n == EINTR:
|
||||
continue
|
||||
if n in _blocking_errnos:
|
||||
if e.args[0] in _blocking_errnos:
|
||||
return None
|
||||
raise
|
||||
|
||||
|
|
|
@ -450,10 +450,8 @@ def _eintr_retry_call(func, *args):
|
|||
while True:
|
||||
try:
|
||||
return func(*args)
|
||||
except (OSError, IOError) as e:
|
||||
if e.errno == errno.EINTR:
|
||||
continue
|
||||
raise
|
||||
except InterruptedError:
|
||||
continue
|
||||
|
||||
|
||||
def call(*popenargs, timeout=None, **kwargs):
|
||||
|
|
|
@ -1834,18 +1834,9 @@ class ContextAPItests(unittest.TestCase):
|
|||
# only, the attribute should be gettable/settable via both
|
||||
# `clamp` and `_clamp`; in Python 3.3, `_clamp` should be
|
||||
# removed.
|
||||
c = Context(clamp = 0)
|
||||
self.assertEqual(c.clamp, 0)
|
||||
|
||||
with check_warnings(("", DeprecationWarning)):
|
||||
c._clamp = 1
|
||||
self.assertEqual(c.clamp, 1)
|
||||
with check_warnings(("", DeprecationWarning)):
|
||||
self.assertEqual(c._clamp, 1)
|
||||
c.clamp = 0
|
||||
self.assertEqual(c.clamp, 0)
|
||||
with check_warnings(("", DeprecationWarning)):
|
||||
self.assertEqual(c._clamp, 0)
|
||||
c = Context()
|
||||
with self.assertRaises(AttributeError):
|
||||
clamp_value = c._clamp
|
||||
|
||||
def test_abs(self):
|
||||
c = Context()
|
||||
|
|
|
@ -43,6 +43,53 @@ DBL_MIN_EXP = sys.float_info.min_exp
|
|||
DBL_MANT_DIG = sys.float_info.mant_dig
|
||||
DBL_MIN_OVERFLOW = 2**DBL_MAX_EXP - 2**(DBL_MAX_EXP - DBL_MANT_DIG - 1)
|
||||
|
||||
|
||||
# Pure Python version of correctly-rounded integer-to-float conversion.
|
||||
def int_to_float(n):
|
||||
"""
|
||||
Correctly-rounded integer-to-float conversion.
|
||||
|
||||
"""
|
||||
# Constants, depending only on the floating-point format in use.
|
||||
# We use an extra 2 bits of precision for rounding purposes.
|
||||
PRECISION = sys.float_info.mant_dig + 2
|
||||
SHIFT_MAX = sys.float_info.max_exp - PRECISION
|
||||
Q_MAX = 1 << PRECISION
|
||||
ROUND_HALF_TO_EVEN_CORRECTION = [0, -1, -2, 1, 0, -1, 2, 1]
|
||||
|
||||
# Reduce to the case where n is positive.
|
||||
if n == 0:
|
||||
return 0.0
|
||||
elif n < 0:
|
||||
return -int_to_float(-n)
|
||||
|
||||
# Convert n to a 'floating-point' number q * 2**shift, where q is an
|
||||
# integer with 'PRECISION' significant bits. When shifting n to create q,
|
||||
# the least significant bit of q is treated as 'sticky'. That is, the
|
||||
# least significant bit of q is set if either the corresponding bit of n
|
||||
# was already set, or any one of the bits of n lost in the shift was set.
|
||||
shift = n.bit_length() - PRECISION
|
||||
q = n << -shift if shift < 0 else (n >> shift) | bool(n & ~(-1 << shift))
|
||||
|
||||
# Round half to even (actually rounds to the nearest multiple of 4,
|
||||
# rounding ties to a multiple of 8).
|
||||
q += ROUND_HALF_TO_EVEN_CORRECTION[q & 7]
|
||||
|
||||
# Detect overflow.
|
||||
if shift + (q == Q_MAX) > SHIFT_MAX:
|
||||
raise OverflowError("integer too large to convert to float")
|
||||
|
||||
# Checks: q is exactly representable, and q**2**shift doesn't overflow.
|
||||
assert q % 4 == 0 and q // 4 <= 2**(sys.float_info.mant_dig)
|
||||
assert q * 2**shift <= sys.float_info.max
|
||||
|
||||
# Some circularity here, since float(q) is doing an int-to-float
|
||||
# conversion. But here q is of bounded size, and is exactly representable
|
||||
# as a float. In a low-level C-like language, this operation would be a
|
||||
# simple cast (e.g., from unsigned long long to double).
|
||||
return math.ldexp(float(q), shift)
|
||||
|
||||
|
||||
# pure Python version of correctly-rounded true division
|
||||
def truediv(a, b):
|
||||
"""Correctly-rounded true division for integers."""
|
||||
|
@ -367,6 +414,23 @@ class LongTest(unittest.TestCase):
|
|||
return 1729
|
||||
self.assertEqual(int(LongTrunc()), 1729)
|
||||
|
||||
def check_float_conversion(self, n):
|
||||
# Check that int -> float conversion behaviour matches
|
||||
# that of the pure Python version above.
|
||||
try:
|
||||
actual = float(n)
|
||||
except OverflowError:
|
||||
actual = 'overflow'
|
||||
|
||||
try:
|
||||
expected = int_to_float(n)
|
||||
except OverflowError:
|
||||
expected = 'overflow'
|
||||
|
||||
msg = ("Error in conversion of integer {} to float. "
|
||||
"Got {}, expected {}.".format(n, actual, expected))
|
||||
self.assertEqual(actual, expected, msg)
|
||||
|
||||
@support.requires_IEEE_754
|
||||
def test_float_conversion(self):
|
||||
|
||||
|
@ -421,6 +485,22 @@ class LongTest(unittest.TestCase):
|
|||
y = 2**p * 2**53
|
||||
self.assertEqual(int(float(x)), y)
|
||||
|
||||
# Compare builtin float conversion with pure Python int_to_float
|
||||
# function above.
|
||||
test_values = [
|
||||
int_dbl_max-1, int_dbl_max, int_dbl_max+1,
|
||||
halfway-1, halfway, halfway + 1,
|
||||
top_power-1, top_power, top_power+1,
|
||||
2*top_power-1, 2*top_power, top_power*top_power,
|
||||
]
|
||||
test_values.extend(exact_values)
|
||||
for p in range(-4, 8):
|
||||
for x in range(-128, 128):
|
||||
test_values.append(2**(p+53) + x)
|
||||
for value in test_values:
|
||||
self.check_float_conversion(value)
|
||||
self.check_float_conversion(-value)
|
||||
|
||||
def test_float_overflow(self):
|
||||
for x in -2.0, -1.0, 0.0, 1.0, 2.0:
|
||||
self.assertEqual(float(int(x)), x)
|
||||
|
|
|
@ -1266,6 +1266,20 @@ class _TestPoolWorkerLifetime(BaseTestCase):
|
|||
p.close()
|
||||
p.join()
|
||||
|
||||
def test_pool_worker_lifetime_early_close(self):
|
||||
# Issue #10332: closing a pool whose workers have limited lifetimes
|
||||
# before all the tasks completed would make join() hang.
|
||||
p = multiprocessing.Pool(3, maxtasksperchild=1)
|
||||
results = []
|
||||
for i in range(6):
|
||||
results.append(p.apply_async(sqr, (i, 0.3)))
|
||||
p.close()
|
||||
p.join()
|
||||
# check the results
|
||||
for (j, res) in enumerate(results):
|
||||
self.assertEqual(res.get(), sqr(j))
|
||||
|
||||
|
||||
#
|
||||
# Test that manager has expected number of shared objects left
|
||||
#
|
||||
|
|
|
@ -3584,7 +3584,7 @@ class FileObjectInterruptedTestCase(unittest.TestCase):
|
|||
|
||||
@staticmethod
|
||||
def _raise_eintr():
|
||||
raise socket.error(errno.EINTR)
|
||||
raise socket.error(errno.EINTR, "interrupted")
|
||||
|
||||
def _textiowrap_mock_socket(self, mock, buffering=-1):
|
||||
raw = socket.SocketIO(mock, "r")
|
||||
|
|
|
@ -141,11 +141,7 @@ class Unpacker:
|
|||
data = self.__buf[i:j]
|
||||
if len(data) < 4:
|
||||
raise EOFError
|
||||
x = struct.unpack('>L', data)[0]
|
||||
try:
|
||||
return int(x)
|
||||
except OverflowError:
|
||||
return x
|
||||
return struct.unpack('>L', data)[0]
|
||||
|
||||
def unpack_int(self):
|
||||
i = self.__pos
|
||||
|
|
|
@ -535,15 +535,6 @@ class Marshaller:
|
|||
write("<value><nil/></value>")
|
||||
dispatch[type(None)] = dump_nil
|
||||
|
||||
def dump_int(self, value, write):
|
||||
# in case ints are > 32 bits
|
||||
if value > MAXINT or value < MININT:
|
||||
raise OverflowError("int exceeds XML-RPC limits")
|
||||
write("<value><int>")
|
||||
write(str(value))
|
||||
write("</int></value>\n")
|
||||
#dispatch[int] = dump_int
|
||||
|
||||
def dump_bool(self, value, write):
|
||||
write("<value><boolean>")
|
||||
write(value and "1" or "0")
|
||||
|
@ -558,6 +549,9 @@ class Marshaller:
|
|||
write("</int></value>\n")
|
||||
dispatch[int] = dump_long
|
||||
|
||||
# backward compatible
|
||||
dump_int = dump_long
|
||||
|
||||
def dump_double(self, value, write):
|
||||
write("<value><double>")
|
||||
write(repr(value))
|
||||
|
|
|
@ -341,6 +341,13 @@ Core and Builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue #10332: multiprocessing: fix a race condition when a Pool is closed
|
||||
before all tasks have completed.
|
||||
|
||||
- Issue #13255: wrong docstrings in array module.
|
||||
|
||||
- Issue #8540: Remove deprecated Context._clamp attribute in Decimal module.
|
||||
|
||||
- Issue #13235: Added PendingDeprecationWarning to warn() method and function.
|
||||
|
||||
- Issue #9168: now smtpd is able to bind privileged port.
|
||||
|
@ -1681,6 +1688,8 @@ C-API
|
|||
Documentation
|
||||
-------------
|
||||
|
||||
- Issue #13141: Demonstrate recommended style for socketserver examples.
|
||||
|
||||
- Issue #11818: Fix tempfile examples for Python 3.
|
||||
|
||||
|
||||
|
|
|
@ -1550,7 +1550,7 @@ PyDoc_STRVAR(fromunicode_doc,
|
|||
\n\
|
||||
Extends this array with data from the unicode string ustr.\n\
|
||||
The array must be a unicode type array; otherwise a ValueError\n\
|
||||
is raised. Use array.frombytes(ustr.decode(...)) to\n\
|
||||
is raised. Use array.frombytes(ustr.encode(...)) to\n\
|
||||
append Unicode data to an array of some other type.");
|
||||
|
||||
|
||||
|
@ -1572,7 +1572,7 @@ PyDoc_STRVAR(tounicode_doc,
|
|||
\n\
|
||||
Convert the array to a unicode string. The array must be\n\
|
||||
a unicode type array; otherwise a ValueError is raised. Use\n\
|
||||
array.tostring().decode() to obtain a unicode string from\n\
|
||||
array.tobytes().decode() to obtain a unicode string from\n\
|
||||
an array of some other type.");
|
||||
|
||||
|
||||
|
@ -2636,7 +2636,7 @@ count() -- return number of occurrences of an object\n\
|
|||
extend() -- extend array by appending multiple elements from an iterable\n\
|
||||
fromfile() -- read items from a file object\n\
|
||||
fromlist() -- append items from the list\n\
|
||||
fromstring() -- append items from the string\n\
|
||||
frombytes() -- append items from the string\n\
|
||||
index() -- return index of first occurrence of an object\n\
|
||||
insert() -- insert a new item into the array at a provided position\n\
|
||||
pop() -- remove and return item (default last)\n\
|
||||
|
@ -2644,7 +2644,7 @@ remove() -- remove first occurrence of an object\n\
|
|||
reverse() -- reverse the order of the items in the array\n\
|
||||
tofile() -- write all items to a file object\n\
|
||||
tolist() -- return the array converted to an ordinary list\n\
|
||||
tostring() -- return the array converted to a string\n\
|
||||
tobytes() -- return the array converted to a string\n\
|
||||
\n\
|
||||
Attributes:\n\
|
||||
\n\
|
||||
|
|
|
@ -322,8 +322,15 @@ PyLong_FromDouble(double dval)
|
|||
#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN)
|
||||
#define PY_ABS_SSIZE_T_MIN (0-(size_t)PY_SSIZE_T_MIN)
|
||||
|
||||
/* Get a C long int from a long int object.
|
||||
Returns -1 and sets an error condition if overflow occurs. */
|
||||
/* Get a C long int from a long int object or any object that has an __int__
|
||||
method.
|
||||
|
||||
On overflow, return -1 and set *overflow to 1 or -1 depending on the sign of
|
||||
the result. Otherwise *overflow is 0.
|
||||
|
||||
For other errors (e.g., TypeError), return -1 and set an error condition.
|
||||
In this case *overflow will be 0.
|
||||
*/
|
||||
|
||||
long
|
||||
PyLong_AsLongAndOverflow(PyObject *vv, int *overflow)
|
||||
|
@ -412,6 +419,9 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow)
|
|||
return res;
|
||||
}
|
||||
|
||||
/* Get a C long int from a long int object or any object that has an __int__
|
||||
method. Return -1 and set an error if overflow occurs. */
|
||||
|
||||
long
|
||||
PyLong_AsLong(PyObject *obj)
|
||||
{
|
||||
|
@ -923,7 +933,7 @@ _PyLong_AsByteArray(PyLongObject* v,
|
|||
|
||||
}
|
||||
|
||||
/* Create a new long (or int) object from a C pointer */
|
||||
/* Create a new long int object from a C pointer */
|
||||
|
||||
PyObject *
|
||||
PyLong_FromVoidPtr(void *p)
|
||||
|
@ -941,15 +951,11 @@ PyLong_FromVoidPtr(void *p)
|
|||
|
||||
}
|
||||
|
||||
/* Get a C pointer from a long object (or an int object in some cases) */
|
||||
/* Get a C pointer from a long int object. */
|
||||
|
||||
void *
|
||||
PyLong_AsVoidPtr(PyObject *vv)
|
||||
{
|
||||
/* This function will allow int or long objects. If vv is neither,
|
||||
then the PyLong_AsLong*() functions will raise the exception:
|
||||
PyExc_SystemError, "bad argument to internal function"
|
||||
*/
|
||||
#if SIZEOF_VOID_P <= SIZEOF_LONG
|
||||
long x;
|
||||
|
||||
|
@ -1130,8 +1136,8 @@ PyLong_FromSize_t(size_t ival)
|
|||
return (PyObject *)v;
|
||||
}
|
||||
|
||||
/* Get a C PY_LONG_LONG int from a long int object.
|
||||
Return -1 and set an error if overflow occurs. */
|
||||
/* Get a C long long int from a long int object or any object that has an
|
||||
__int__ method. Return -1 and set an error if overflow occurs. */
|
||||
|
||||
PY_LONG_LONG
|
||||
PyLong_AsLongLong(PyObject *vv)
|
||||
|
@ -1287,12 +1293,14 @@ PyLong_AsUnsignedLongLongMask(register PyObject *op)
|
|||
}
|
||||
#undef IS_LITTLE_ENDIAN
|
||||
|
||||
/* Get a C long long int from a Python long or Python int object.
|
||||
On overflow, returns -1 and sets *overflow to 1 or -1 depending
|
||||
on the sign of the result. Otherwise *overflow is 0.
|
||||
/* Get a C long long int from a long int object or any object that has an
|
||||
__int__ method.
|
||||
|
||||
For other errors (e.g., type error), returns -1 and sets an error
|
||||
condition.
|
||||
On overflow, return -1 and set *overflow to 1 or -1 depending on the sign of
|
||||
the result. Otherwise *overflow is 0.
|
||||
|
||||
For other errors (e.g., TypeError), return -1 and set an error condition.
|
||||
In this case *overflow will be 0.
|
||||
*/
|
||||
|
||||
PY_LONG_LONG
|
||||
|
|
Loading…
Reference in New Issue