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)
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.

View File

@ -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

View File

@ -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.

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
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`,

View File

@ -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

View File

@ -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.

View File

@ -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")

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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")) }

View File

@ -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"""

View File

@ -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

View File

@ -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):

View File

@ -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()

View File

@ -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)

View File

@ -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
#

View File

@ -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")

View File

@ -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

View File

@ -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))

View File

@ -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.

View File

@ -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\

View File

@ -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