merge heads

This commit is contained in:
Petri Lehtinen 2011-10-24 21:22:39 +03:00
commit 08a95cabe3
25 changed files with 283 additions and 243 deletions

View File

@ -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) 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 provides a way of doing this from C++ (i.e. you can inherit from an extension
class written in C++ using the BPL). 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.

View File

@ -123,7 +123,9 @@ and off individually. They are described here in more detail.
.. 2to3fixer:: callable .. 2to3fixer:: callable
Converts ``callable(x)`` to ``isinstance(x, collections.Callable)``, adding 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 .. 2to3fixer:: dict

View File

@ -427,7 +427,7 @@ FTP_TLS Objects
.. method:: FTP_TLS.ccc() .. 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 advantage of firewalls that know how to handle NAT with non-secure FTP
without opening fixed ports. without opening fixed ports.

View File

@ -353,8 +353,8 @@ The :mod:`signal` module defines the following functions:
signals in *sigset* is already pending for the calling thread, the function signals in *sigset* is already pending for the calling thread, the function
will return immediately with information about that signal. The signal will return immediately with information about that signal. The signal
handler is not called for the delivered signal. The function raises an 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 :exc:`InterruptedError` if it is interrupted by a signal that is not in
interrupted by a signal that is not in *sigset*. *sigset*.
The return value is an object representing the data contained in the The return value is an object representing the data contained in the
:c:type:`siginfo_t` structure, namely: :attr:`si_signo`, :attr:`si_code`, :c:type:`siginfo_t` structure, namely: :attr:`si_signo`, :attr:`si_code`,

View File

@ -361,7 +361,7 @@ This is the server side::
def handle(self): def handle(self):
# self.request is the TCP socket connected to the client # self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip() self.data = self.request.recv(1024).strip()
print("%s wrote:" % self.client_address[0]) print("{} wrote:".format(self.client_address[0]))
print(self.data) print(self.data)
# just send back the same data, but upper-cased # just send back the same data, but upper-cased
self.request.send(self.data.upper()) 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; # self.rfile is a file-like object created by the handler;
# we can now use e.g. readline() instead of raw recv() calls # we can now use e.g. readline() instead of raw recv() calls
self.data = self.rfile.readline().strip() self.data = self.rfile.readline().strip()
print("%s wrote:" % self.client_address[0]) print("{} wrote:".format(self.client_address[0]))
print(self.data) print(self.data)
# Likewise, self.wfile is a file-like object used to write back # Likewise, self.wfile is a file-like object used to write back
# to the client # to the client
@ -408,16 +408,18 @@ This is the client side::
# Create a socket (SOCK_STREAM means a TCP socket) # Create a socket (SOCK_STREAM means a TCP socket)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# Connect to server and send data # Connect to server and send data
sock.connect((HOST, PORT)) sock.connect((HOST, PORT))
sock.send(bytes(data + "\n","utf8")) sock.send(bytes(data + "\n", "utf-8"))
# Receive data from the server and shut down # Receive data from the server and shut down
received = sock.recv(1024) received = str(sock.recv(1024), "utf-8")
finally:
sock.close() sock.close()
print("Sent: %s" % data) print("Sent: {}".format(data))
print("Received: %s" % received) print("Received: {}".format(received))
The output of the example should look something like this: The output of the example should look something like this:
@ -434,10 +436,10 @@ Client::
$ python TCPClient.py hello world with TCP $ python TCPClient.py hello world with TCP
Sent: 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 $ python TCPClient.py python is nice
Sent: python is nice Sent: python is nice
Received: b'PYTHON IS NICE' Received: PYTHON IS NICE
:class:`socketserver.UDPServer` Example :class:`socketserver.UDPServer` Example
@ -458,7 +460,7 @@ This is the server side::
def handle(self): def handle(self):
data = self.request[0].strip() data = self.request[0].strip()
socket = self.request[1] socket = self.request[1]
print("%s wrote:" % self.client_address[0]) print("{} wrote:".format(self.client_address[0]))
print(data) print(data)
socket.sendto(data.upper(), self.client_address) 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. # As you can see, there is no connect() call; UDP has no connections.
# Instead, data is directly sent to the recipient via sendto(). # Instead, data is directly sent to the recipient via sendto().
sock.sendto(bytes(data + "\n","utf8"), (HOST, PORT)) sock.sendto(bytes(data + "\n", "utf-8"), (HOST, PORT))
received = sock.recv(1024) received = str(sock.recv(1024), "utf-8")
print("Sent: %s" % data) print("Sent: {}".format(data))
print("Received: %s" % received) print("Received: {}".format(received))
The output of the example should look exactly like for the TCP server example. 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): class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
def handle(self): def handle(self):
data = self.request.recv(1024) data = str(self.request.recv(1024), 'ascii')
cur_thread = threading.current_thread() 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) self.request.send(response)
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
@ -515,9 +517,11 @@ An example for the :class:`ThreadingMixIn` class::
def client(ip, port, message): def client(ip, port, message):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port)) sock.connect((ip, port))
sock.send(message) try:
response = sock.recv(1024) sock.send(bytes(message, 'ascii'))
print("Received: %s" % response) response = str(sock.recv(1024), 'ascii')
print("Received: {}".format(response))
finally:
sock.close() sock.close()
if __name__ == "__main__": if __name__ == "__main__":
@ -531,13 +535,13 @@ An example for the :class:`ThreadingMixIn` class::
# more thread for each request # more thread for each request
server_thread = threading.Thread(target=server.serve_forever) server_thread = threading.Thread(target=server.serve_forever)
# Exit the server thread when the main thread terminates # Exit the server thread when the main thread terminates
server_thread.setDaemon(True) server_thread.daemon = True
server_thread.start() server_thread.start()
print("Server loop running in thread:", server_thread.name) print("Server loop running in thread:", server_thread.name)
client(ip, port, b"Hello World 1") client(ip, port, "Hello World 1")
client(ip, port, b"Hello World 2") client(ip, port, "Hello World 2")
client(ip, port, b"Hello World 3") client(ip, port, "Hello World 3")
server.shutdown() server.shutdown()
@ -546,9 +550,9 @@ The output of the example should look something like this::
$ python ThreadedTCPServer.py $ python ThreadedTCPServer.py
Server loop running in thread: Thread-1 Server loop running in thread: Thread-1
Received: b"Thread-2: b'Hello World 1'" Received: Thread-2: Hello World 1
Received: b"Thread-3: b'Hello World 2'" Received: Thread-3: Hello World 2
Received: b"Thread-4: b'Hello World 3'" Received: Thread-4: Hello World 3
The :class:`ForkingMixIn` class is used in the same way, except that the server The :class:`ForkingMixIn` class is used in the same way, except that the server

View File

@ -49,28 +49,32 @@
This article explains the new features in Python 3.3, compared to 3.2. This article explains the new features in Python 3.3, compared to 3.2.
.. _pep-393:
PEP 393: Flexible String Representation PEP 393: Flexible String Representation
======================================= =======================================
[Abstract copied from the PEP: The Unicode string type is changed to support The Unicode string type is changed to support multiple internal
multiple internal representations, depending on the character with the largest representations, depending on the character with the largest Unicode ordinal
Unicode ordinal (1, 2, or 4 bytes). This allows a space-efficient (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. representation in common cases, but gives access to full UCS-4 on all
For compatibility with existing APIs, several representations may exist in systems. For compatibility with existing APIs, several representations may
parallel; over time, this compatibility should be phased out.] exist in parallel; over time, this compatibility should be phased out.
PEP 393 is fully backward compatible. The legacy API should remain On the Python side, there should be no downside to this change.
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).
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 * 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 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 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: * 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 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. 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, * :func:`len` now always returns 1 for non-BMP characters,
so ``len('\U0010FFFF') == 1``; 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, * surrogate pairs are not recombined in string literals,
so ``'\uDBFF\uDFFF' != '\U0010FFFF'``; 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'``; 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`` * The value of :data:`sys.maxunicode` is now always ``1114111`` (``0x10FFFF``
in hexadecimal). The :c:func:`PyUnicode_GetMax` function still returns 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:`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` You don't have to worry anymore about choosing the appropriate exception
* :exc:`ChildProcessError` type between :exc:`OSError`, :exc:`IOError`, :exc:`EnvironmentError`,
* :exc:`ConnectionError` :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` Also, it is now easier to catch a specific error condition. Instead of
* :exc:`ConnectionAbortedError` inspecting the ``errno`` attribute (or ``args[0]``) for a particular
* :exc:`ConnectionRefusedError` constant from the :mod:`errno` module, you can catch the adequate
* :exc:`ConnectionResetError` :exc:`OSError` subclass. The available subclasses are the following:
* :exc:`FileExistsError` * :exc:`BlockingIOError`
* :exc:`FileNotFoundError` * :exc:`ChildProcessError`
* :exc:`InterruptedError` * :exc:`ConnectionError`
* :exc:`IsADirectoryError` * :exc:`FileExistsError`
* :exc:`NotADirectoryError` * :exc:`FileNotFoundError`
* :exc:`PermissionError` * :exc:`InterruptedError`
* :exc:`ProcessLookupError` * :exc:`IsADirectoryError`
* :exc:`TimeoutError` * :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:`BrokenPipeError`
* :exc:`IOError` * :exc:`ConnectionAbortedError`
* :exc:`WindowsError` * :exc:`ConnectionRefusedError`
* :exc:`VMSError` * :exc:`ConnectionResetError`
* :exc:`socket.error`
* :exc:`select.error`
* :exc:`mmap.error`
Thanks to the new exceptions, common usages of the :mod:`errno` can now be 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 from errno import ENOENT, EACCES, EPERM
@ -161,7 +171,8 @@ avoided. For example, the following code written for Python 3.2: ::
else: else:
raise 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: try:
with open("document.txt") as f: with open("document.txt") as f:
@ -180,7 +191,7 @@ Some smaller changes made to the core Python language are:
* Stub * Stub
Added support for Unicode name aliases and named sequences. 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. and :func:`unicodedata.lookup()` resolves named sequences too.
(Contributed by Ezio Melotti in :issue:`12753`) (Contributed by Ezio Melotti in :issue:`12753`)
@ -267,7 +278,7 @@ ftplib
The :class:`~ftplib.FTP_TLS` class now provides a new The :class:`~ftplib.FTP_TLS` class now provides a new
:func:`~ftplib.FTP_TLS.ccc` function to revert control channel back to :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. handle NAT with non-secure FTP without opening fixed ports.
(Contributed by Giampaolo Rodolà in :issue:`12139`) (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 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 * Issue #12326: On Linux, sys.platform doesn't contain the major version
anymore. It is now always 'linux', instead of 'linux2' or 'linux3' depending 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 with sys.platform.startswith('linux'), or directly sys.platform == 'linux' if
you don't need to support older Python versions. 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`, .. Issue #11591: When :program:`python` was started with :option:`-S`,
``import site`` will not add site-specific paths to the module search ``import site`` will not add site-specific paths to the module search
paths. In previous versions, it did. See changeset for doc changes in 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. removed. Code checking sys.flags.division_warning will need updating.
Contributed by Éric Araujo. 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.

View File

@ -14,7 +14,6 @@ except ImportError:
import io import io
from io import (__all__, SEEK_SET, SEEK_CUR, SEEK_END) from io import (__all__, SEEK_SET, SEEK_CUR, SEEK_END)
from errno import EINTR
# open() uses st_blksize whenever we can # open() uses st_blksize whenever we can
DEFAULT_BUFFER_SIZE = 8 * 1024 # bytes DEFAULT_BUFFER_SIZE = 8 * 1024 # bytes
@ -948,9 +947,7 @@ class BufferedReader(_BufferedIOMixin):
# Read until EOF or until read() would block. # Read until EOF or until read() would block.
try: try:
chunk = self.raw.read() chunk = self.raw.read()
except IOError as e: except InterruptedError:
if e.errno != EINTR:
raise
continue continue
if chunk in empty_values: if chunk in empty_values:
nodata_val = chunk nodata_val = chunk
@ -972,9 +969,7 @@ class BufferedReader(_BufferedIOMixin):
while avail < n: while avail < n:
try: try:
chunk = self.raw.read(wanted) chunk = self.raw.read(wanted)
except IOError as e: except InterruptedError:
if e.errno != EINTR:
raise
continue continue
if chunk in empty_values: if chunk in empty_values:
nodata_val = chunk nodata_val = chunk
@ -1007,9 +1002,7 @@ class BufferedReader(_BufferedIOMixin):
while True: while True:
try: try:
current = self.raw.read(to_read) current = self.raw.read(to_read)
except IOError as e: except InterruptedError:
if e.errno != EINTR:
raise
continue continue
break break
if current: if current:
@ -1120,9 +1113,7 @@ class BufferedWriter(_BufferedIOMixin):
while self._write_buf: while self._write_buf:
try: try:
n = self.raw.write(self._write_buf) n = self.raw.write(self._write_buf)
except IOError as e: except InterruptedError:
if e.errno != EINTR:
raise
continue continue
if n > len(self._write_buf) or n < 0: if n > len(self._write_buf) or n < 0:
raise IOError("write() returned incorrect number of bytes") raise IOError("write() returned incorrect number of bytes")

View File

@ -54,7 +54,7 @@ import warnings
import os import os
from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, EINVAL, \ from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, EINVAL, \
ENOTCONN, ESHUTDOWN, EINTR, EISCONN, EBADF, ECONNABORTED, EPIPE, EAGAIN, \ ENOTCONN, ESHUTDOWN, EISCONN, EBADF, ECONNABORTED, EPIPE, EAGAIN, \
errorcode errorcode
_DISCONNECTED = frozenset((ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED, EPIPE, _DISCONNECTED = frozenset((ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED, EPIPE,
@ -143,10 +143,7 @@ def poll(timeout=0.0, map=None):
try: try:
r, w, e = select.select(r, w, e, timeout) r, w, e = select.select(r, w, e, timeout)
except select.error as err: except InterruptedError:
if err.args[0] != EINTR:
raise
else:
return return
for fd in r: for fd in r:
@ -190,9 +187,7 @@ def poll2(timeout=0.0, map=None):
pollster.register(fd, flags) pollster.register(fd, flags)
try: try:
r = pollster.poll(timeout) r = pollster.poll(timeout)
except select.error as err: except InterruptedError:
if err.args[0] != EINTR:
raise
r = [] r = []
for fd, flags in r: for fd, flags in r:
obj = map.get(fd) obj = map.get(fd)

View File

@ -3903,28 +3903,6 @@ class Context(object):
return nc return nc
__copy__ = copy __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): def _raise_error(self, condition, explanation = None, *args):
"""Handles an error """Handles an error

View File

@ -175,10 +175,8 @@ class FTP:
# Internal: "sanitize" a string for printing # Internal: "sanitize" a string for printing
def sanitize(self, s): def sanitize(self, s):
if s[:5] == 'pass ' or s[:5] == 'PASS ': if s[:5] in {'pass ', 'PASS '}:
i = len(s) i = len(s.rstrip('\r\n'))
while i > 5 and s[i-1] in {'\r', '\n'}:
i = i-1
s = s[:5] + '*'*(i-5) + s[i:] s = s[:5] + '*'*(i-5) + s[i:]
return repr(s) return repr(s)
@ -596,9 +594,6 @@ class FTP:
resp = self.sendcmd('SIZE ' + filename) resp = self.sendcmd('SIZE ' + filename)
if resp[:3] == '213': if resp[:3] == '213':
s = resp[3:].strip() s = resp[3:].strip()
try:
return int(s)
except (OverflowError, ValueError):
return int(s) return int(s)
def mkd(self, dirname): def mkd(self, dirname):
@ -861,11 +856,7 @@ def parse150(resp):
m = _150_re.match(resp) m = _150_re.match(resp)
if not m: if not m:
return None return None
s = m.group(1) return int(m.group(1))
try:
return int(s)
except (OverflowError, ValueError):
return int(s)
_227_re = None _227_re = None

View File

@ -321,7 +321,11 @@ class Pool(object):
@staticmethod @staticmethod
def _handle_workers(pool): 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() pool._maintain_pool()
time.sleep(0.1) time.sleep(0.1)
# send sentinel to stop workers # send sentinel to stop workers

View File

@ -327,15 +327,12 @@ class ForkAwareLocal(threading.local):
# Automatic retry after EINTR # Automatic retry after EINTR
# #
def _eintr_retry(func, _errors=(EnvironmentError, select.error)): def _eintr_retry(func):
@functools.wraps(func) @functools.wraps(func)
def wrapped(*args, **kwargs): def wrapped(*args, **kwargs):
while True: while True:
try: try:
return func(*args, **kwargs) return func(*args, **kwargs)
except _errors as e: except InterruptedError:
# select.error has no `errno` attribute
if e.args[0] == errno.EINTR:
continue continue
raise
return wrapped return wrapped

View File

@ -417,11 +417,8 @@ def _parse_num(val, type):
def _parse_int(val): def _parse_int(val):
return _parse_num(val, int) return _parse_num(val, int)
def _parse_long(val):
return _parse_num(val, int)
_builtin_cvt = { "int" : (_parse_int, _("integer")), _builtin_cvt = { "int" : (_parse_int, _("integer")),
"long" : (_parse_long, _("long integer")), "long" : (_parse_int, _("integer")),
"float" : (float, _("floating-point")), "float" : (float, _("floating-point")),
"complex" : (complex, _("complex")) } "complex" : (complex, _("complex")) }

View File

@ -510,9 +510,6 @@ def read_decimalnl_short(f):
elif s == b"01": elif s == b"01":
return True return True
try:
return int(s)
except OverflowError:
return int(s) return int(s)
def read_decimalnl_long(f): def read_decimalnl_long(f):

View File

@ -53,7 +53,6 @@ try:
except ImportError: except ImportError:
errno = None errno = None
EBADF = getattr(errno, 'EBADF', 9) EBADF = getattr(errno, 'EBADF', 9)
EINTR = getattr(errno, 'EINTR', 4)
EAGAIN = getattr(errno, 'EAGAIN', 11) EAGAIN = getattr(errno, 'EAGAIN', 11)
EWOULDBLOCK = getattr(errno, 'EWOULDBLOCK', 11) EWOULDBLOCK = getattr(errno, 'EWOULDBLOCK', 11)
@ -280,11 +279,10 @@ class SocketIO(io.RawIOBase):
except timeout: except timeout:
self._timeout_occurred = True self._timeout_occurred = True
raise raise
except error as e: except InterruptedError:
n = e.args[0]
if n == EINTR:
continue continue
if n in _blocking_errnos: except error as e:
if e.args[0] in _blocking_errnos:
return None return None
raise raise

View File

@ -450,10 +450,8 @@ def _eintr_retry_call(func, *args):
while True: while True:
try: try:
return func(*args) return func(*args)
except (OSError, IOError) as e: except InterruptedError:
if e.errno == errno.EINTR:
continue continue
raise
def call(*popenargs, timeout=None, **kwargs): def call(*popenargs, timeout=None, **kwargs):

View File

@ -1834,18 +1834,9 @@ class ContextAPItests(unittest.TestCase):
# only, the attribute should be gettable/settable via both # only, the attribute should be gettable/settable via both
# `clamp` and `_clamp`; in Python 3.3, `_clamp` should be # `clamp` and `_clamp`; in Python 3.3, `_clamp` should be
# removed. # removed.
c = Context(clamp = 0) c = Context()
self.assertEqual(c.clamp, 0) with self.assertRaises(AttributeError):
clamp_value = c._clamp
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)
def test_abs(self): def test_abs(self):
c = Context() c = Context()

View File

@ -43,6 +43,53 @@ DBL_MIN_EXP = sys.float_info.min_exp
DBL_MANT_DIG = sys.float_info.mant_dig DBL_MANT_DIG = sys.float_info.mant_dig
DBL_MIN_OVERFLOW = 2**DBL_MAX_EXP - 2**(DBL_MAX_EXP - DBL_MANT_DIG - 1) 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 # pure Python version of correctly-rounded true division
def truediv(a, b): def truediv(a, b):
"""Correctly-rounded true division for integers.""" """Correctly-rounded true division for integers."""
@ -367,6 +414,23 @@ class LongTest(unittest.TestCase):
return 1729 return 1729
self.assertEqual(int(LongTrunc()), 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 @support.requires_IEEE_754
def test_float_conversion(self): def test_float_conversion(self):
@ -421,6 +485,22 @@ class LongTest(unittest.TestCase):
y = 2**p * 2**53 y = 2**p * 2**53
self.assertEqual(int(float(x)), y) 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): def test_float_overflow(self):
for x in -2.0, -1.0, 0.0, 1.0, 2.0: for x in -2.0, -1.0, 0.0, 1.0, 2.0:
self.assertEqual(float(int(x)), x) self.assertEqual(float(int(x)), x)

View File

@ -1266,6 +1266,20 @@ class _TestPoolWorkerLifetime(BaseTestCase):
p.close() p.close()
p.join() 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 # Test that manager has expected number of shared objects left
# #

View File

@ -3584,7 +3584,7 @@ class FileObjectInterruptedTestCase(unittest.TestCase):
@staticmethod @staticmethod
def _raise_eintr(): def _raise_eintr():
raise socket.error(errno.EINTR) raise socket.error(errno.EINTR, "interrupted")
def _textiowrap_mock_socket(self, mock, buffering=-1): def _textiowrap_mock_socket(self, mock, buffering=-1):
raw = socket.SocketIO(mock, "r") raw = socket.SocketIO(mock, "r")

View File

@ -141,11 +141,7 @@ class Unpacker:
data = self.__buf[i:j] data = self.__buf[i:j]
if len(data) < 4: if len(data) < 4:
raise EOFError raise EOFError
x = struct.unpack('>L', data)[0] return struct.unpack('>L', data)[0]
try:
return int(x)
except OverflowError:
return x
def unpack_int(self): def unpack_int(self):
i = self.__pos i = self.__pos

View File

@ -535,15 +535,6 @@ class Marshaller:
write("<value><nil/></value>") write("<value><nil/></value>")
dispatch[type(None)] = dump_nil 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): def dump_bool(self, value, write):
write("<value><boolean>") write("<value><boolean>")
write(value and "1" or "0") write(value and "1" or "0")
@ -558,6 +549,9 @@ class Marshaller:
write("</int></value>\n") write("</int></value>\n")
dispatch[int] = dump_long dispatch[int] = dump_long
# backward compatible
dump_int = dump_long
def dump_double(self, value, write): def dump_double(self, value, write):
write("<value><double>") write("<value><double>")
write(repr(value)) write(repr(value))

View File

@ -341,6 +341,13 @@ Core and Builtins
Library 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 #13235: Added PendingDeprecationWarning to warn() method and function.
- Issue #9168: now smtpd is able to bind privileged port. - Issue #9168: now smtpd is able to bind privileged port.
@ -1681,6 +1688,8 @@ C-API
Documentation Documentation
------------- -------------
- Issue #13141: Demonstrate recommended style for socketserver examples.
- Issue #11818: Fix tempfile examples for Python 3. - Issue #11818: Fix tempfile examples for Python 3.

View File

@ -1550,7 +1550,7 @@ PyDoc_STRVAR(fromunicode_doc,
\n\ \n\
Extends this array with data from the unicode string ustr.\n\ Extends this array with data from the unicode string ustr.\n\
The array must be a unicode type array; otherwise a ValueError\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."); append Unicode data to an array of some other type.");
@ -1572,7 +1572,7 @@ PyDoc_STRVAR(tounicode_doc,
\n\ \n\
Convert the array to a unicode string. The array must be\n\ Convert the array to a unicode string. The array must be\n\
a unicode type array; otherwise a ValueError is raised. Use\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."); 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\ extend() -- extend array by appending multiple elements from an iterable\n\
fromfile() -- read items from a file object\n\ fromfile() -- read items from a file object\n\
fromlist() -- append items from the list\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\ index() -- return index of first occurrence of an object\n\
insert() -- insert a new item into the array at a provided position\n\ insert() -- insert a new item into the array at a provided position\n\
pop() -- remove and return item (default last)\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\ reverse() -- reverse the order of the items in the array\n\
tofile() -- write all items to a file object\n\ tofile() -- write all items to a file object\n\
tolist() -- return the array converted to an ordinary list\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\ \n\
Attributes:\n\ Attributes:\n\
\n\ \n\

View File

@ -322,8 +322,15 @@ PyLong_FromDouble(double dval)
#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN) #define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN)
#define PY_ABS_SSIZE_T_MIN (0-(size_t)PY_SSIZE_T_MIN) #define PY_ABS_SSIZE_T_MIN (0-(size_t)PY_SSIZE_T_MIN)
/* Get a C long int from a long int object. /* Get a C long int from a long int object or any object that has an __int__
Returns -1 and sets an error condition if overflow occurs. */ 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 long
PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) PyLong_AsLongAndOverflow(PyObject *vv, int *overflow)
@ -412,6 +419,9 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow)
return res; 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 long
PyLong_AsLong(PyObject *obj) 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 * PyObject *
PyLong_FromVoidPtr(void *p) 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 * void *
PyLong_AsVoidPtr(PyObject *vv) 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 #if SIZEOF_VOID_P <= SIZEOF_LONG
long x; long x;
@ -1130,8 +1136,8 @@ PyLong_FromSize_t(size_t ival)
return (PyObject *)v; return (PyObject *)v;
} }
/* Get a C PY_LONG_LONG int from a long int object. /* Get a C long long int from a long int object or any object that has an
Return -1 and set an error if overflow occurs. */ __int__ method. Return -1 and set an error if overflow occurs. */
PY_LONG_LONG PY_LONG_LONG
PyLong_AsLongLong(PyObject *vv) PyLong_AsLongLong(PyObject *vv)
@ -1287,12 +1293,14 @@ PyLong_AsUnsignedLongLongMask(register PyObject *op)
} }
#undef IS_LITTLE_ENDIAN #undef IS_LITTLE_ENDIAN
/* Get a C long long int from a Python long or Python int object. /* Get a C long long int from a long int object or any object that has an
On overflow, returns -1 and sets *overflow to 1 or -1 depending __int__ method.
on the sign of the result. Otherwise *overflow is 0.
For other errors (e.g., type error), returns -1 and sets an error On overflow, return -1 and set *overflow to 1 or -1 depending on the sign of
condition. 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 PY_LONG_LONG