Merged 3.4.0b1 release head back into trunk.

This commit is contained in:
Larry Hastings 2013-11-24 14:05:57 -08:00
commit 99e101013f
27 changed files with 1133 additions and 368 deletions

View file

@ -186,6 +186,7 @@ serve:
autobuild-dev: autobuild-dev:
make update make update
make dist SPHINXOPTS='-A daily=1 -A versionswitcher=1' make dist SPHINXOPTS='-A daily=1 -A versionswitcher=1'
-make suspicious
# for quick rebuilds (HTML only) # for quick rebuilds (HTML only)
autobuild-html: autobuild-html:

View file

@ -96,7 +96,7 @@ this module.
only it when looking for candidate matches. Otherwise consider only the only it when looking for candidate matches. Otherwise consider only the
first (default root) part of the ``multipart/related``. first (default root) part of the ``multipart/related``.
If a part has a :mailheader:``Content-Disposition`` header, only consider If a part has a :mailheader:`Content-Disposition` header, only consider
the part a candidate match if the value of the header is ``inline``. the part a candidate match if the value of the header is ``inline``.
If none of the candidates matches any of the preferences in If none of the candidates matches any of the preferences in
@ -134,7 +134,7 @@ this module.
Return an iterator over all of the immediate sub-parts of the message, Return an iterator over all of the immediate sub-parts of the message,
which will be empty for a non-``multipart``. (See also which will be empty for a non-``multipart``. (See also
:meth:``~email.message.walk``.) :meth:`~email.message.walk`.)
.. method:: get_content(*args, content_manager=None, **kw) .. method:: get_content(*args, content_manager=None, **kw)

View file

@ -35,7 +35,7 @@ Here are the methods of the :class:`Message` class:
If *policy* is specified (it must be an instance of a :mod:`~email.policy` If *policy* is specified (it must be an instance of a :mod:`~email.policy`
class) use the rules it specifies to udpate and serialize the representation class) use the rules it specifies to udpate and serialize the representation
of the message. If *policy* is not set, use the :class`compat32 of the message. If *policy* is not set, use the :class:`compat32
<email.policy.Compat32>` policy, which maintains backward compatibility with <email.policy.Compat32>` policy, which maintains backward compatibility with
the Python 3.2 version of the email package. For more information see the the Python 3.2 version of the email package. For more information see the
:mod:`~email.policy` documentation. :mod:`~email.policy` documentation.

View file

@ -476,9 +476,9 @@ applications.)
:program:`xgettext`, :program:`pygettext`, and similar tools generate :program:`xgettext`, :program:`pygettext`, and similar tools generate
:file:`.po` files that are message catalogs. They are structured :file:`.po` files that are message catalogs. They are structured
:human-readable files that contain every marked string in the source human-readable files that contain every marked string in the source
:code, along with a placeholder for the translated versions of these code, along with a placeholder for the translated versions of these
:strings. strings.
Copies of these :file:`.po` files are then handed over to the Copies of these :file:`.po` files are then handed over to the
individual human translators who write translations for every individual human translators who write translations for every

View file

@ -901,8 +901,8 @@ Test cases
| :meth:`assertWarnsRegex(warn, r, fun, *args, **kwds) | ``fun(*args, **kwds)`` raises *warn* | 3.2 | | :meth:`assertWarnsRegex(warn, r, fun, *args, **kwds) | ``fun(*args, **kwds)`` raises *warn* | 3.2 |
| <TestCase.assertWarnsRegex>` | and the message matches regex *r* | | | <TestCase.assertWarnsRegex>` | and the message matches regex *r* | |
+---------------------------------------------------------+--------------------------------------+------------+ +---------------------------------------------------------+--------------------------------------+------------+
| :meth:`assertLogs(logger, level)` | The ``with`` block logs on *logger* | 3.4 | | :meth:`assertLogs(logger, level) | The ``with`` block logs on *logger* | 3.4 |
| <TestCase.assertWarns>` | with minimum *level* | | | <TestCase.assertLogs>` | with minimum *level* | |
+---------------------------------------------------------+--------------------------------------+------------+ +---------------------------------------------------------+--------------------------------------+------------+
.. method:: assertRaises(exception, callable, *args, **kwds) .. method:: assertRaises(exception, callable, *args, **kwds)

View file

@ -141,15 +141,8 @@ library/linecache,,:sys,"sys:x:3:3:sys:/dev:/bin/sh"
library/logging.handlers,,:port,host:port library/logging.handlers,,:port,host:port
library/mmap,,:i2,obj[i1:i2] library/mmap,,:i2,obj[i1:i2]
library/multiprocessing,,`,# Add more tasks using `put()` library/multiprocessing,,`,# Add more tasks using `put()`
library/multiprocessing,,`,# A test file for the `multiprocessing` package
library/multiprocessing,,`,# A test of `multiprocessing.Pool` class
library/multiprocessing,,`,# `BaseManager`.
library/multiprocessing,,`,# in the original order then consider using `Pool.map()` or
library/multiprocessing,,`,">>> l._callmethod('__getitem__', (20,)) # equiv to `l[20]`" library/multiprocessing,,`,">>> l._callmethod('__getitem__', (20,)) # equiv to `l[20]`"
library/multiprocessing,,`,">>> l._callmethod('__getslice__', (2, 7)) # equiv to `l[2:7]`" library/multiprocessing,,`,">>> l._callmethod('__getslice__', (2, 7)) # equiv to `l[2:7]`"
library/multiprocessing,,`,# Not sure if we should synchronize access to `socket.accept()` method by
library/multiprocessing,,`,# object. (We import `multiprocessing.reduction` to enable this pickling.)
library/multiprocessing,,`,# `Pool.imap()` (which will save on the amount of code needed anyway).
library/multiprocessing,,:queue,">>> QueueManager.register('get_queue', callable=lambda:queue)" library/multiprocessing,,:queue,">>> QueueManager.register('get_queue', callable=lambda:queue)"
library/multiprocessing,,`,# register the Foo class; make `f()` and `g()` accessible via proxy library/multiprocessing,,`,# register the Foo class; make `f()` and `g()` accessible via proxy
library/multiprocessing,,`,# register the Foo class; make `g()` and `_h()` accessible via proxy library/multiprocessing,,`,# register the Foo class; make `g()` and `_h()` accessible via proxy
@ -158,6 +151,10 @@ library/nntplib,,:bytes,:bytes
library/nntplib,,:lines,:lines library/nntplib,,:lines,:lines
library/optparse,,:len,"del parser.rargs[:len(value)]" library/optparse,,:len,"del parser.rargs[:len(value)]"
library/os.path,,:foo,c:foo library/os.path,,:foo,c:foo
library/pathlib,,:bar,">>> PureWindowsPath('c:/Windows', 'd:bar')"
library/pathlib,,:bar,PureWindowsPath('d:bar')
library/pathlib,,:Program,>>> PureWindowsPath('c:Program Files/').root
library/pathlib,,:Program,>>> PureWindowsPath('c:Program Files/').anchor
library/pdb,,:lineno,filename:lineno library/pdb,,:lineno,filename:lineno
library/pickle,,:memory,"conn = sqlite3.connect("":memory:"")" library/pickle,,:memory,"conn = sqlite3.connect("":memory:"")"
library/posix,,`,"CFLAGS=""`getconf LFS_CFLAGS`"" OPT=""-g -O2 $CFLAGS""" library/posix,,`,"CFLAGS=""`getconf LFS_CFLAGS`"" OPT=""-g -O2 $CFLAGS"""
@ -200,7 +197,12 @@ library/tarfile,,:xz,'r:xz'
library/tarfile,,:xz,'w:xz' library/tarfile,,:xz,'w:xz'
library/time,,:mm, library/time,,:mm,
library/time,,:ss, library/time,,:ss,
library/tracemalloc,,:limit,"for index, stat in enumerate(top_stats[:limit], 1):"
library/turtle,,::,Example:: library/turtle,,::,Example::
library/unittest,1412,:foo,"self.assertEqual(cm.output, ['INFO:foo:first message',"
library/unittest,1412,:first,"self.assertEqual(cm.output, ['INFO:foo:first message',"
library/unittest,1412,:foo,'ERROR:foo.bar:second message'])
library/unittest,1412,:second,'ERROR:foo.bar:second message'])
library/urllib.request,,:close,Connection:close library/urllib.request,,:close,Connection:close
library/urllib.request,,:lang,"xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en"" lang=""en"">\n\n<head>\n" library/urllib.request,,:lang,"xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en"" lang=""en"">\n\n<head>\n"
library/urllib.request,,:password,"""joe:password@python.org""" library/urllib.request,,:password,"""joe:password@python.org"""

1 c-api/arg :ref PyArg_ParseTuple(args, "O|O:ref", &object, &callback)
141 library/logging.handlers :port host:port
142 library/mmap :i2 obj[i1:i2]
143 library/multiprocessing ` # Add more tasks using `put()`
library/multiprocessing ` # A test file for the `multiprocessing` package
library/multiprocessing ` # A test of `multiprocessing.Pool` class
library/multiprocessing ` # `BaseManager`.
library/multiprocessing ` # in the original order then consider using `Pool.map()` or
144 library/multiprocessing ` >>> l._callmethod('__getitem__', (20,)) # equiv to `l[20]`
145 library/multiprocessing ` >>> l._callmethod('__getslice__', (2, 7)) # equiv to `l[2:7]`
library/multiprocessing ` # Not sure if we should synchronize access to `socket.accept()` method by
library/multiprocessing ` # object. (We import `multiprocessing.reduction` to enable this pickling.)
library/multiprocessing ` # `Pool.imap()` (which will save on the amount of code needed anyway).
146 library/multiprocessing :queue >>> QueueManager.register('get_queue', callable=lambda:queue)
147 library/multiprocessing ` # register the Foo class; make `f()` and `g()` accessible via proxy
148 library/multiprocessing ` # register the Foo class; make `g()` and `_h()` accessible via proxy
151 library/nntplib :lines :lines
152 library/optparse :len del parser.rargs[:len(value)]
153 library/os.path :foo c:foo
154 library/pathlib :bar >>> PureWindowsPath('c:/Windows', 'd:bar')
155 library/pathlib :bar PureWindowsPath('d:bar')
156 library/pathlib :Program >>> PureWindowsPath('c:Program Files/').root
157 library/pathlib :Program >>> PureWindowsPath('c:Program Files/').anchor
158 library/pdb :lineno filename:lineno
159 library/pickle :memory conn = sqlite3.connect(":memory:")
160 library/posix ` CFLAGS="`getconf LFS_CFLAGS`" OPT="-g -O2 $CFLAGS"
197 library/tarfile :xz 'w:xz'
198 library/time :mm
199 library/time :ss
200 library/tracemalloc :limit for index, stat in enumerate(top_stats[:limit], 1):
201 library/turtle :: Example::
202 library/unittest 1412 :foo self.assertEqual(cm.output, ['INFO:foo:first message',
203 library/unittest 1412 :first self.assertEqual(cm.output, ['INFO:foo:first message',
204 library/unittest 1412 :foo 'ERROR:foo.bar:second message'])
205 library/unittest 1412 :second 'ERROR:foo.bar:second message'])
206 library/urllib.request :close Connection:close
207 library/urllib.request :lang xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n\n<head>\n
208 library/urllib.request :password "joe:password@python.org"

View file

@ -424,7 +424,7 @@ base64
The encoding and decoding functions in :mod:`base64` now accept any The encoding and decoding functions in :mod:`base64` now accept any
:term:`bytes-like object` in cases where it previously required a :term:`bytes-like object` in cases where it previously required a
:class:`bytes` or :class:`bytearray` instance (:issue`17839`) :class:`bytes` or :class:`bytearray` instance (:issue:`17839`).
colorsys colorsys

View file

@ -329,7 +329,7 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
(bad_directive, format)) from None (bad_directive, format)) from None
# IndexError only occurs when the format string is "%" # IndexError only occurs when the format string is "%"
except IndexError: except IndexError:
raise ValueError("stray %% in format '%s'" % format) raise ValueError("stray %% in format '%s'" % format) from None
_regex_cache[format] = format_regex _regex_cache[format] = format_regex
found = format_regex.match(data_string) found = format_regex.match(data_string)
if not found: if not found:

View file

@ -327,14 +327,21 @@ class IocpProactor:
handle, self._iocp, ov.address, ms) handle, self._iocp, ov.address, ms)
f = _WaitHandleFuture(wh, loop=self._loop) f = _WaitHandleFuture(wh, loop=self._loop)
def finish(timed_out, _, ov): def finish(trans, key, ov):
if not f.cancelled(): if not f.cancelled():
try: try:
_overlapped.UnregisterWait(wh) _overlapped.UnregisterWait(wh)
except OSError as e: except OSError as e:
if e.winerror != _overlapped.ERROR_IO_PENDING: if e.winerror != _overlapped.ERROR_IO_PENDING:
raise raise
return not timed_out # Note that this second wait means that we should only use
# this with handles types where a successful wait has no
# effect. So events or processes are all right, but locks
# or semaphores are not. Also note if the handle is
# signalled and then quickly reset, then we may return
# False even though we have not timed out.
return (_winapi.WaitForSingleObject(handle, 0) ==
_winapi.WAIT_OBJECT_0)
self._cache[ov.address] = (f, ov, None, finish) self._cache[ov.address] = (f, ov, None, finish)
return f return f

View file

@ -140,6 +140,7 @@ __all__ = [
__version__ = '1.70' # Highest version of the spec this complies with __version__ = '1.70' # Highest version of the spec this complies with
# See http://speleotrove.com/decimal/ # See http://speleotrove.com/decimal/
__libmpdec_version__ = "2.4.0" # compatible libmpdec version
import copy as _copy import copy as _copy
import math as _math import math as _math

View file

@ -224,7 +224,7 @@ class FileInput:
"'r', 'rU', 'U' and 'rb'") "'r', 'rU', 'U' and 'rb'")
if 'U' in mode: if 'U' in mode:
import warnings import warnings
warnings.warn("Use of 'U' mode is deprecated", warnings.warn("'U' mode is deprecated",
DeprecationWarning, 2) DeprecationWarning, 2)
self._mode = mode self._mode = mode
if openhook: if openhook:

View file

@ -602,7 +602,9 @@ class UTF16Test(ReadTest, unittest.TestCase):
self.addCleanup(support.unlink, support.TESTFN) self.addCleanup(support.unlink, support.TESTFN)
with open(support.TESTFN, 'wb') as fp: with open(support.TESTFN, 'wb') as fp:
fp.write(s) fp.write(s)
with codecs.open(support.TESTFN, 'U', encoding=self.encoding) as reader: with support.check_warnings(('', DeprecationWarning)):
reader = codecs.open(support.TESTFN, 'U', encoding=self.encoding)
with reader:
self.assertEqual(reader.read(), s1) self.assertEqual(reader.read(), s1)
class UTF16LETest(ReadTest, unittest.TestCase): class UTF16LETest(ReadTest, unittest.TestCase):

View file

@ -4149,6 +4149,7 @@ class CheckAttributes(unittest.TestCase):
self.assertTrue(P.HAVE_THREADS is True or P.HAVE_THREADS is False) self.assertTrue(P.HAVE_THREADS is True or P.HAVE_THREADS is False)
self.assertEqual(C.__version__, P.__version__) self.assertEqual(C.__version__, P.__version__)
self.assertEqual(C.__libmpdec_version__, P.__libmpdec_version__)
x = dir(C) x = dir(C)
y = [s for s in dir(P) if '__' in s or not s.startswith('_')] y = [s for s in dir(P) if '__' in s or not s.startswith('_')]

View file

@ -22,7 +22,7 @@ except ImportError:
from io import StringIO from io import StringIO
from fileinput import FileInput, hook_encoded from fileinput import FileInput, hook_encoded
from test.support import verbose, TESTFN, run_unittest from test.support import verbose, TESTFN, run_unittest, check_warnings
from test.support import unlink as safe_unlink from test.support import unlink as safe_unlink
@ -224,7 +224,9 @@ class FileInputTests(unittest.TestCase):
try: try:
# try opening in universal newline mode # try opening in universal newline mode
t1 = writeTmp(1, [b"A\nB\r\nC\rD"], mode="wb") t1 = writeTmp(1, [b"A\nB\r\nC\rD"], mode="wb")
with check_warnings(('', DeprecationWarning)):
fi = FileInput(files=t1, mode="U") fi = FileInput(files=t1, mode="U")
with check_warnings(('', DeprecationWarning)):
lines = list(fi) lines = list(fi)
self.assertEqual(lines, ["A\n", "B\n", "C\n", "D"]) self.assertEqual(lines, ["A\n", "B\n", "C\n", "D"])
finally: finally:

View file

@ -170,6 +170,7 @@ class DebuggerTests(unittest.TestCase):
'Do you need "set solib-search-path" or ' 'Do you need "set solib-search-path" or '
'"set sysroot"?', '"set sysroot"?',
'warning: Source file is more recent than executable.', 'warning: Source file is more recent than executable.',
'Missing separate debuginfo for ',
) )
for line in errlines: for line in errlines:
if not line.startswith(ignore_patterns): if not line.startswith(ignore_patterns):

View file

@ -2777,6 +2777,7 @@ class MiscIOTest(unittest.TestCase):
self.assertEqual(f.mode, "wb") self.assertEqual(f.mode, "wb")
f.close() f.close()
with support.check_warnings(('', DeprecationWarning)):
f = self.open(support.TESTFN, "U") f = self.open(support.TESTFN, "U")
self.assertEqual(f.name, support.TESTFN) self.assertEqual(f.name, support.TESTFN)
self.assertEqual(f.buffer.name, support.TESTFN) self.assertEqual(f.buffer.name, support.TESTFN)

View file

@ -223,6 +223,10 @@ class StrptimeTests(unittest.TestCase):
with self.assertRaises(ValueError) as e: with self.assertRaises(ValueError) as e:
_strptime._strptime_time('', '%D') _strptime._strptime_time('', '%D')
self.assertIs(e.exception.__suppress_context__, True) self.assertIs(e.exception.__suppress_context__, True)
# additional check for IndexError branch (issue #19545)
with self.assertRaises(ValueError) as e:
_strptime._strptime_time('19', '%Y %')
self.assertIs(e.exception.__suppress_context__, True)
def test_unconverteddata(self): def test_unconverteddata(self):
# Check ValueError is raised when there is unconverted data # Check ValueError is raised when there is unconverted data

View file

@ -198,6 +198,10 @@ class TimeTestCase(unittest.TestCase):
with self.assertRaises(ValueError) as e: with self.assertRaises(ValueError) as e:
time.strptime('', '%D') time.strptime('', '%D')
self.assertIs(e.exception.__suppress_context__, True) self.assertIs(e.exception.__suppress_context__, True)
# additional check for IndexError branch (issue #19545)
with self.assertRaises(ValueError) as e:
time.strptime('19', '%Y %')
self.assertIs(e.exception.__suppress_context__, True)
def test_asctime(self): def test_asctime(self):
time.asctime(time.gmtime(self.t)) time.asctime(time.gmtime(self.t))

View file

@ -14,7 +14,7 @@ from random import randint, random, getrandbits
from test.support import (TESTFN, findfile, unlink, from test.support import (TESTFN, findfile, unlink,
requires_zlib, requires_bz2, requires_lzma, requires_zlib, requires_bz2, requires_lzma,
captured_stdout) captured_stdout, check_warnings)
TESTFN2 = TESTFN + "2" TESTFN2 = TESTFN + "2"
TESTFNDIR = TESTFN + "d" TESTFNDIR = TESTFN + "d"
@ -35,6 +35,10 @@ def get_files(test):
yield f yield f
test.assertFalse(f.closed) test.assertFalse(f.closed)
def openU(zipfp, fn):
with check_warnings(('', DeprecationWarning)):
return zipfp.open(fn, 'rU')
class AbstractTestsWithSourceFile: class AbstractTestsWithSourceFile:
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
@ -875,6 +879,17 @@ class OtherTests(unittest.TestCase):
data += zipfp.read(info) data += zipfp.read(info)
self.assertIn(data, {b"foobar", b"barfoo"}) self.assertIn(data, {b"foobar", b"barfoo"})
def test_universal_deprecation(self):
f = io.BytesIO()
with zipfile.ZipFile(f, "w") as zipfp:
zipfp.writestr('spam.txt', b'ababagalamaga')
with zipfile.ZipFile(f, "r") as zipfp:
for mode in 'U', 'rU':
with self.assertWarns(DeprecationWarning):
zipopen = zipfp.open('spam.txt', mode)
zipopen.close()
def test_universal_readaheads(self): def test_universal_readaheads(self):
f = io.BytesIO() f = io.BytesIO()
@ -884,7 +899,7 @@ class OtherTests(unittest.TestCase):
data2 = b'' data2 = b''
with zipfile.ZipFile(f, 'r') as zipfp, \ with zipfile.ZipFile(f, 'r') as zipfp, \
zipfp.open(TESTFN, 'rU') as zipopen: openU(zipfp, TESTFN) as zipopen:
for line in zipopen: for line in zipopen:
data2 += line data2 += line
@ -1613,7 +1628,7 @@ class AbstractUniversalNewlineTests:
# Read the ZIP archive # Read the ZIP archive
with zipfile.ZipFile(f, "r") as zipfp: with zipfile.ZipFile(f, "r") as zipfp:
for sep, fn in self.arcfiles.items(): for sep, fn in self.arcfiles.items():
with zipfp.open(fn, "rU") as fp: with openU(zipfp, fn) as fp:
zipdata = fp.read() zipdata = fp.read()
self.assertEqual(self.arcdata[sep], zipdata) self.assertEqual(self.arcdata[sep], zipdata)
@ -1627,7 +1642,7 @@ class AbstractUniversalNewlineTests:
# Read the ZIP archive # Read the ZIP archive
with zipfile.ZipFile(f, "r") as zipfp: with zipfile.ZipFile(f, "r") as zipfp:
for sep, fn in self.arcfiles.items(): for sep, fn in self.arcfiles.items():
with zipfp.open(fn, "rU") as zipopen: with openU(zipfp, fn) as zipopen:
data = b'' data = b''
while True: while True:
read = zipopen.readline() read = zipopen.readline()
@ -1652,7 +1667,7 @@ class AbstractUniversalNewlineTests:
# Read the ZIP archive # Read the ZIP archive
with zipfile.ZipFile(f, "r") as zipfp: with zipfile.ZipFile(f, "r") as zipfp:
for sep, fn in self.arcfiles.items(): for sep, fn in self.arcfiles.items():
with zipfp.open(fn, "rU") as zipopen: with openU(zipfp, fn) as zipopen:
for line in self.line_gen: for line in self.line_gen:
linedata = zipopen.readline() linedata = zipopen.readline()
self.assertEqual(linedata, line + b'\n') self.assertEqual(linedata, line + b'\n')
@ -1667,7 +1682,7 @@ class AbstractUniversalNewlineTests:
# Read the ZIP archive # Read the ZIP archive
with zipfile.ZipFile(f, "r") as zipfp: with zipfile.ZipFile(f, "r") as zipfp:
for sep, fn in self.arcfiles.items(): for sep, fn in self.arcfiles.items():
with zipfp.open(fn, "rU") as fp: with openU(zipfp, fn) as fp:
ziplines = fp.readlines() ziplines = fp.readlines()
for line, zipline in zip(self.line_gen, ziplines): for line, zipline in zip(self.line_gen, ziplines):
self.assertEqual(zipline, line + b'\n') self.assertEqual(zipline, line + b'\n')
@ -1682,7 +1697,7 @@ class AbstractUniversalNewlineTests:
# Read the ZIP archive # Read the ZIP archive
with zipfile.ZipFile(f, "r") as zipfp: with zipfile.ZipFile(f, "r") as zipfp:
for sep, fn in self.arcfiles.items(): for sep, fn in self.arcfiles.items():
with zipfp.open(fn, "rU") as fp: with openU(zipfp, fn) as fp:
for line, zipline in zip(self.line_gen, fp): for line, zipline in zip(self.line_gen, fp):
self.assertEqual(zipline, line + b'\n') self.assertEqual(zipline, line + b'\n')

View file

@ -2,6 +2,21 @@
Python News Python News
+++++++++++ +++++++++++
What's New in Python 3.4.0 Beta 2?
==================================
Release date: 2014-01-05
Core and Builtins
-----------------
Library
-------
- Issue #19545: Avoid chained exceptions while passing stray % to
time.strptime(). Initial patch by Claudiu Popa.
What's New in Python 3.4.0 Beta 1? What's New in Python 3.4.0 Beta 1?
================================== ==================================
@ -2518,7 +2533,7 @@ Library
- Issue #14398: Fix size truncation and overflow bugs in the bz2 module. - Issue #14398: Fix size truncation and overflow bugs in the bz2 module.
- Issue #12692: Fix resource leak in urllib.request when talking to an HTTP - Issue #12692: Fix resource leak in urllib.request when talking to an HTTP
server that does not include a "Connection: close" header in its responses. server that does not include a ``Connection: close`` header in its responses.
- Issue #12034: Fix bogus caching of result in check_GetFinalPathNameByHandle. - Issue #12034: Fix bogus caching of result in check_GetFinalPathNameByHandle.
Patch by Atsuo Ishimoto. Patch by Atsuo Ishimoto.
@ -6091,7 +6106,7 @@ Library
given as a low fd, it gets overwritten. given as a low fd, it gets overwritten.
- Issue #12576: Fix urlopen behavior on sites which do not send (or obfuscates) - Issue #12576: Fix urlopen behavior on sites which do not send (or obfuscates)
Connection:close header. ``Connection: close`` header.
- Issue #12560: Build libpython.so on OpenBSD. Patch by Stefan Sperling. - Issue #12560: Build libpython.so on OpenBSD. Patch by Stefan Sperling.
@ -6686,7 +6701,7 @@ Library
- Issue #11127: Raise a TypeError when trying to pickle a socket object. - Issue #11127: Raise a TypeError when trying to pickle a socket object.
- Issue #11563: Connection:close header is sent by requests using URLOpener - Issue #11563: ``Connection: close`` header is sent by requests using URLOpener
class which helps in closing of sockets after connection is over. Patch class which helps in closing of sockets after connection is over. Patch
contributions by Jeff McNeil and Nadeem Vawda. contributions by Jeff McNeil and Nadeem Vawda.
@ -7262,7 +7277,7 @@ Tests
- Issue #11505: improves test coverage of string.py. Patch by Alicia - Issue #11505: improves test coverage of string.py. Patch by Alicia
Arlen Arlen
- Issue #11490: test_subprocess:test_leaking_fds_on_error no longer gives a - Issue #11490: test_subprocess.test_leaking_fds_on_error no longer gives a
false positive if the last directory in the path is inaccessible. false positive if the last directory in the path is inaccessible.
- Issue #11223: Fix test_threadsignals to fail, not hang, when the - Issue #11223: Fix test_threadsignals to fail, not hang, when the

View file

@ -39,6 +39,11 @@
#include "memory.h" #include "memory.h"
#if MPD_MAJOR_VERSION != 2
#error "libmpdec major version 2 required"
#endif
/* /*
* Type sizes with assertions in mpdecimal.h and pyport.h: * Type sizes with assertions in mpdecimal.h and pyport.h:
* sizeof(size_t) == sizeof(Py_ssize_t) * sizeof(size_t) == sizeof(Py_ssize_t)
@ -5731,6 +5736,7 @@ PyInit__decimal(void)
/* Add specification version number */ /* Add specification version number */
CHECK_INT(PyModule_AddStringConstant(m, "__version__", "1.70")); CHECK_INT(PyModule_AddStringConstant(m, "__version__", "1.70"));
CHECK_INT(PyModule_AddStringConstant(m, "__libmpdec_version__", mpd_version()));
return m; return m;

View file

@ -97,6 +97,8 @@ static void _settriple(mpd_t *result, uint8_t sign, mpd_uint_t a,
mpd_ssize_t exp); mpd_ssize_t exp);
static inline mpd_ssize_t _mpd_real_size(mpd_uint_t *data, mpd_ssize_t size); static inline mpd_ssize_t _mpd_real_size(mpd_uint_t *data, mpd_ssize_t size);
static int _mpd_cmp_abs(const mpd_t *a, const mpd_t *b);
static void _mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b, static void _mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b,
const mpd_context_t *ctx, uint32_t *status); const mpd_context_t *ctx, uint32_t *status);
static inline void _mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b, static inline void _mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b,
@ -110,6 +112,17 @@ static inline void _mpd_qpow_uint(mpd_t *result, const mpd_t *base,
static mpd_uint_t mpd_qsshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n); static mpd_uint_t mpd_qsshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n);
/******************************************************************************/
/* Version */
/******************************************************************************/
const char *
mpd_version(void)
{
return MPD_VERSION;
}
/******************************************************************************/ /******************************************************************************/
/* Performance critical inline functions */ /* Performance critical inline functions */
/******************************************************************************/ /******************************************************************************/
@ -1345,6 +1358,91 @@ mpd_qget_ssize(const mpd_t *a, uint32_t *status)
return MPD_SSIZE_MAX; return MPD_SSIZE_MAX;
} }
#if defined(CONFIG_32) && !defined(LEGACY_COMPILER)
/*
* Quietly get a uint64_t from a decimal. If the operation is impossible,
* MPD_Invalid_operation is set.
*/
static uint64_t
_c32_qget_u64(int use_sign, const mpd_t *a, uint32_t *status)
{
MPD_NEW_STATIC(tmp,0,0,20,3);
mpd_context_t maxcontext;
uint64_t ret;
tmp_data[0] = 709551615;
tmp_data[1] = 446744073;
tmp_data[2] = 18;
if (mpd_isspecial(a)) {
*status |= MPD_Invalid_operation;
return UINT64_MAX;
}
if (mpd_iszero(a)) {
return 0;
}
if (use_sign && mpd_isnegative(a)) {
*status |= MPD_Invalid_operation;
return UINT64_MAX;
}
if (!_mpd_isint(a)) {
*status |= MPD_Invalid_operation;
return UINT64_MAX;
}
if (_mpd_cmp_abs(a, &tmp) > 0) {
*status |= MPD_Invalid_operation;
return UINT64_MAX;
}
mpd_maxcontext(&maxcontext);
mpd_qrescale(&tmp, a, 0, &maxcontext, &maxcontext.status);
maxcontext.status &= ~MPD_Rounded;
if (maxcontext.status != 0) {
*status |= (maxcontext.status|MPD_Invalid_operation); /* GCOV_NOT_REACHED */
return UINT64_MAX; /* GCOV_NOT_REACHED */
}
ret = 0;
switch (tmp.len) {
case 3:
ret += (uint64_t)tmp_data[2] * 1000000000000000000ULL;
case 2:
ret += (uint64_t)tmp_data[1] * 1000000000ULL;
case 1:
ret += tmp_data[0];
break;
default:
abort(); /* GCOV_NOT_REACHED */
}
return ret;
}
static int64_t
_c32_qget_i64(const mpd_t *a, uint32_t *status)
{
uint64_t u;
int isneg;
u = _c32_qget_u64(0, a, status);
if (*status&MPD_Invalid_operation) {
return INT64_MAX;
}
isneg = mpd_isnegative(a);
if (u <= INT64_MAX) {
return isneg ? -((int64_t)u) : (int64_t)u;
}
else if (isneg && u+(INT64_MIN+INT64_MAX) == INT64_MAX) {
return INT64_MIN;
}
*status |= MPD_Invalid_operation;
return INT64_MAX;
}
#endif /* CONFIG_32 && !LEGACY_COMPILER */
#ifdef CONFIG_64 #ifdef CONFIG_64
/* quietly get a uint64_t from a decimal */ /* quietly get a uint64_t from a decimal */
uint64_t uint64_t
@ -1359,7 +1457,57 @@ mpd_qget_i64(const mpd_t *a, uint32_t *status)
{ {
return mpd_qget_ssize(a, status); return mpd_qget_ssize(a, status);
} }
/* quietly get a uint32_t from a decimal */
uint32_t
mpd_qget_u32(const mpd_t *a, uint32_t *status)
{
uint64_t x = mpd_qget_uint(a, status);
if (*status&MPD_Invalid_operation) {
return UINT32_MAX;
}
if (x > UINT32_MAX) {
*status |= MPD_Invalid_operation;
return UINT32_MAX;
}
return (uint32_t)x;
}
/* quietly get an int32_t from a decimal */
int32_t
mpd_qget_i32(const mpd_t *a, uint32_t *status)
{
int64_t x = mpd_qget_ssize(a, status);
if (*status&MPD_Invalid_operation) {
return INT32_MAX;
}
if (x < INT32_MIN || x > INT32_MAX) {
*status |= MPD_Invalid_operation;
return INT32_MAX;
}
return (int32_t)x;
}
#else #else
#ifndef LEGACY_COMPILER
/* quietly get a uint64_t from a decimal */
uint64_t
mpd_qget_u64(const mpd_t *a, uint32_t *status)
{
return _c32_qget_u64(1, a, status);
}
/* quietly get an int64_t from a decimal */
int64_t
mpd_qget_i64(const mpd_t *a, uint32_t *status)
{
return _c32_qget_i64(a, status);
}
#endif
/* quietly get a uint32_t from a decimal */ /* quietly get a uint32_t from a decimal */
uint32_t uint32_t
mpd_qget_u32(const mpd_t *a, uint32_t *status) mpd_qget_u32(const mpd_t *a, uint32_t *status)
@ -3386,6 +3534,34 @@ mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b,
{ {
mpd_qadd_uint(result, a, b, ctx, status); mpd_qadd_uint(result, a, b, ctx, status);
} }
#elif !defined(LEGACY_COMPILER)
/* Add decimal and int64_t. */
void
mpd_qadd_i64(mpd_t *result, const mpd_t *a, int64_t b,
const mpd_context_t *ctx, uint32_t *status)
{
mpd_context_t maxcontext;
MPD_NEW_STATIC(bb,0,0,0,0);
mpd_maxcontext(&maxcontext);
mpd_qset_i64(&bb, b, &maxcontext, status);
mpd_qadd(result, a, &bb, ctx, status);
mpd_del(&bb);
}
/* Add decimal and uint64_t. */
void
mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b,
const mpd_context_t *ctx, uint32_t *status)
{
mpd_context_t maxcontext;
MPD_NEW_STATIC(bb,0,0,0,0);
mpd_maxcontext(&maxcontext);
mpd_qset_u64(&bb, b, &maxcontext, status);
mpd_qadd(result, a, &bb, ctx, status);
mpd_del(&bb);
}
#endif #endif
/* Subtract int32_t from decimal. */ /* Subtract int32_t from decimal. */
@ -3420,6 +3596,34 @@ mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b,
{ {
mpd_qsub_uint(result, a, b, ctx, status); mpd_qsub_uint(result, a, b, ctx, status);
} }
#elif !defined(LEGACY_COMPILER)
/* Subtract int64_t from decimal. */
void
mpd_qsub_i64(mpd_t *result, const mpd_t *a, int64_t b,
const mpd_context_t *ctx, uint32_t *status)
{
mpd_context_t maxcontext;
MPD_NEW_STATIC(bb,0,0,0,0);
mpd_maxcontext(&maxcontext);
mpd_qset_i64(&bb, b, &maxcontext, status);
mpd_qsub(result, a, &bb, ctx, status);
mpd_del(&bb);
}
/* Subtract uint64_t from decimal. */
void
mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b,
const mpd_context_t *ctx, uint32_t *status)
{
mpd_context_t maxcontext;
MPD_NEW_STATIC(bb,0,0,0,0);
mpd_maxcontext(&maxcontext);
mpd_qset_u64(&bb, b, &maxcontext, status);
mpd_qsub(result, a, &bb, ctx, status);
mpd_del(&bb);
}
#endif #endif
@ -3871,6 +4075,34 @@ mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b,
{ {
mpd_qdiv_uint(result, a, b, ctx, status); mpd_qdiv_uint(result, a, b, ctx, status);
} }
#elif !defined(LEGACY_COMPILER)
/* Divide decimal by int64_t. */
void
mpd_qdiv_i64(mpd_t *result, const mpd_t *a, int64_t b,
const mpd_context_t *ctx, uint32_t *status)
{
mpd_context_t maxcontext;
MPD_NEW_STATIC(bb,0,0,0,0);
mpd_maxcontext(&maxcontext);
mpd_qset_i64(&bb, b, &maxcontext, status);
mpd_qdiv(result, a, &bb, ctx, status);
mpd_del(&bb);
}
/* Divide decimal by uint64_t. */
void
mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b,
const mpd_context_t *ctx, uint32_t *status)
{
mpd_context_t maxcontext;
MPD_NEW_STATIC(bb,0,0,0,0);
mpd_maxcontext(&maxcontext);
mpd_qset_u64(&bb, b, &maxcontext, status);
mpd_qdiv(result, a, &bb, ctx, status);
mpd_del(&bb);
}
#endif #endif
/* Pad the result with trailing zeros if it has fewer digits than prec. */ /* Pad the result with trailing zeros if it has fewer digits than prec. */
@ -5664,6 +5896,34 @@ mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b,
{ {
mpd_qmul_uint(result, a, b, ctx, status); mpd_qmul_uint(result, a, b, ctx, status);
} }
#elif !defined(LEGACY_COMPILER)
/* Multiply decimal and int64_t. */
void
mpd_qmul_i64(mpd_t *result, const mpd_t *a, int64_t b,
const mpd_context_t *ctx, uint32_t *status)
{
mpd_context_t maxcontext;
MPD_NEW_STATIC(bb,0,0,0,0);
mpd_maxcontext(&maxcontext);
mpd_qset_i64(&bb, b, &maxcontext, status);
mpd_qmul(result, a, &bb, ctx, status);
mpd_del(&bb);
}
/* Multiply decimal and uint64_t. */
void
mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b,
const mpd_context_t *ctx, uint32_t *status)
{
mpd_context_t maxcontext;
MPD_NEW_STATIC(bb,0,0,0,0);
mpd_maxcontext(&maxcontext);
mpd_qset_u64(&bb, b, &maxcontext, status);
mpd_qmul(result, a, &bb, ctx, status);
mpd_del(&bb);
}
#endif #endif
/* Like the minus operator. */ /* Like the minus operator. */

View file

@ -32,7 +32,6 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#define __STDC_LIMIT_MACROS
#endif #endif
@ -56,12 +55,18 @@ extern "C" {
#define MPD_HIDE_SYMBOLS_END #define MPD_HIDE_SYMBOLS_END
#define EXTINLINE extern inline #define EXTINLINE extern inline
#else #else
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_INTTYPES_H #ifdef HAVE_INTTYPES_H
#include <inttypes.h> #include <inttypes.h>
#endif #endif
#ifdef HAVE_STDINT_H
#if defined(__cplusplus) && !defined(__STDC_LIMIT_MACROS)
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#undef __STDC_LIMIT_MACROS
#else
#include <stdint.h>
#endif
#endif
#ifndef __GNUC_STDC_INLINE__ #ifndef __GNUC_STDC_INLINE__
#define __GNUC_STDC_INLINE__ 1 #define __GNUC_STDC_INLINE__ 1
#endif #endif
@ -99,6 +104,19 @@ MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
#endif #endif
/******************************************************************************/
/* Version */
/******************************************************************************/
#define MPD_MAJOR_VERSION 2
#define MPD_MINOR_VERSION 4
#define MPD_MICRO_VERSION 0
#define MPD_VERSION "2.4.0"
const char *mpd_version(void);
/******************************************************************************/ /******************************************************************************/
/* Configuration */ /* Configuration */
/******************************************************************************/ /******************************************************************************/
@ -241,7 +259,7 @@ extern const char *mpd_round_string[MPD_ROUND_GUARD];
extern const char *mpd_clamp_string[MPD_CLAMP_GUARD]; extern const char *mpd_clamp_string[MPD_CLAMP_GUARD];
typedef struct { typedef struct mpd_context_t {
mpd_ssize_t prec; /* precision */ mpd_ssize_t prec; /* precision */
mpd_ssize_t emax; /* max positive exp */ mpd_ssize_t emax; /* max positive exp */
mpd_ssize_t emin; /* min negative exp */ mpd_ssize_t emin; /* min negative exp */
@ -353,7 +371,7 @@ void mpd_addstatus_raise(mpd_context_t *ctx, uint32_t flags);
#define MPD_DATAFLAGS (MPD_STATIC_DATA|MPD_SHARED_DATA|MPD_CONST_DATA) #define MPD_DATAFLAGS (MPD_STATIC_DATA|MPD_SHARED_DATA|MPD_CONST_DATA)
/* mpd_t */ /* mpd_t */
typedef struct { typedef struct mpd_t {
uint8_t flags; uint8_t flags;
mpd_ssize_t exp; mpd_ssize_t exp;
mpd_ssize_t digits; mpd_ssize_t digits;
@ -371,7 +389,7 @@ typedef unsigned char uchar;
/******************************************************************************/ /******************************************************************************/
/* format specification */ /* format specification */
typedef struct { typedef struct mpd_spec_t {
mpd_ssize_t min_width; /* minimum field width */ mpd_ssize_t min_width; /* minimum field width */
mpd_ssize_t prec; /* fraction digits or significant digits */ mpd_ssize_t prec; /* fraction digits or significant digits */
char type; /* conversion specifier */ char type; /* conversion specifier */
@ -437,6 +455,12 @@ mpd_ssize_t mpd_qget_ssize(const mpd_t *dec, uint32_t *status);
mpd_uint_t mpd_qget_uint(const mpd_t *dec, uint32_t *status); mpd_uint_t mpd_qget_uint(const mpd_t *dec, uint32_t *status);
mpd_uint_t mpd_qabs_uint(const mpd_t *dec, uint32_t *status); mpd_uint_t mpd_qabs_uint(const mpd_t *dec, uint32_t *status);
int32_t mpd_qget_i32(const mpd_t *dec, uint32_t *status);
uint32_t mpd_qget_u32(const mpd_t *dec, uint32_t *status);
#ifndef LEGACY_COMPILER
int64_t mpd_qget_i64(const mpd_t *dec, uint32_t *status);
uint64_t mpd_qget_u64(const mpd_t *dec, uint32_t *status);
#endif
/* quiet functions */ /* quiet functions */
int mpd_qcheck_nan(mpd_t *nanresult, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); int mpd_qcheck_nan(mpd_t *nanresult, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
@ -528,6 +552,17 @@ void mpd_qlog10(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_
void mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); void mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
void mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); void mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
#ifndef LEGACY_COMPILER
void mpd_qadd_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
void mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
void mpd_qsub_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
void mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
void mpd_qmul_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
void mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
void mpd_qdiv_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
void mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
#endif
size_t mpd_sizeinbase(const mpd_t *a, uint32_t base); size_t mpd_sizeinbase(const mpd_t *a, uint32_t base);
void mpd_qimport_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen, void mpd_qimport_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen,
@ -571,6 +606,12 @@ void mpd_set_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx);
mpd_ssize_t mpd_get_ssize(const mpd_t *a, mpd_context_t *ctx); mpd_ssize_t mpd_get_ssize(const mpd_t *a, mpd_context_t *ctx);
mpd_uint_t mpd_get_uint(const mpd_t *a, mpd_context_t *ctx); mpd_uint_t mpd_get_uint(const mpd_t *a, mpd_context_t *ctx);
mpd_uint_t mpd_abs_uint(const mpd_t *a, mpd_context_t *ctx); mpd_uint_t mpd_abs_uint(const mpd_t *a, mpd_context_t *ctx);
int32_t mpd_get_i32(const mpd_t *a, mpd_context_t *ctx);
uint32_t mpd_get_u32(const mpd_t *a, mpd_context_t *ctx);
#ifndef LEGACY_COMPILER
int64_t mpd_get_i64(const mpd_t *a, mpd_context_t *ctx);
uint64_t mpd_get_u64(const mpd_t *a, mpd_context_t *ctx);
#endif
void mpd_and(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); void mpd_and(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
void mpd_copy(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); void mpd_copy(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
void mpd_canonical(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); void mpd_canonical(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
@ -641,31 +682,7 @@ void mpd_ceil(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
void mpd_sqrt(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); void mpd_sqrt(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
void mpd_invroot(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); void mpd_invroot(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
#ifndef LEGACY_COMPILER
/******************************************************************************/
/* Configuration specific */
/******************************************************************************/
#ifdef CONFIG_64
void mpd_qsset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, uint32_t *status);
void mpd_qsset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, uint32_t *status);
int64_t mpd_qget_i64(const mpd_t *dec, uint32_t *status);
uint64_t mpd_qget_u64(const mpd_t *dec, uint32_t *status);
void mpd_qadd_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
void mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
void mpd_qsub_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
void mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
void mpd_qmul_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
void mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
void mpd_qdiv_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
void mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
void mpd_sset_i64(mpd_t *result, int64_t a, mpd_context_t *ctx);
void mpd_sset_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx);
int64_t mpd_get_i64(const mpd_t *a, mpd_context_t *ctx);
uint64_t mpd_get_u64(const mpd_t *a, mpd_context_t *ctx);
void mpd_add_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx); void mpd_add_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
void mpd_add_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx); void mpd_add_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
void mpd_sub_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx); void mpd_sub_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
@ -674,11 +691,18 @@ void mpd_div_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
void mpd_div_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx); void mpd_div_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
void mpd_mul_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx); void mpd_mul_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
void mpd_mul_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx); void mpd_mul_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
#else #endif
int32_t mpd_qget_i32(const mpd_t *dec, uint32_t *status);
uint32_t mpd_qget_u32(const mpd_t *dec, uint32_t *status);
int32_t mpd_get_i32(const mpd_t *a, mpd_context_t *ctx); /******************************************************************************/
uint32_t mpd_get_u32(const mpd_t *a, mpd_context_t *ctx); /* Configuration specific */
/******************************************************************************/
#ifdef CONFIG_64
void mpd_qsset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, uint32_t *status);
void mpd_qsset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, uint32_t *status);
void mpd_sset_i64(mpd_t *result, int64_t a, mpd_context_t *ctx);
void mpd_sset_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx);
#endif #endif

View file

@ -567,8 +567,9 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds)
PyObject* attrib = NULL; PyObject* attrib = NULL;
if (!PyArg_ParseTuple(args, "O!O|O!:SubElement", if (!PyArg_ParseTuple(args, "O!O|O!:SubElement",
&Element_Type, &parent, &tag, &Element_Type, &parent, &tag,
&PyDict_Type, &attrib)) &PyDict_Type, &attrib)) {
return NULL; return NULL;
}
if (attrib) { if (attrib) {
/* attrib passed as positional arg */ /* attrib passed as positional arg */
@ -652,7 +653,6 @@ element_dealloc(ElementObject* self)
} }
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/* methods (in alphabetical order) */
static PyObject* static PyObject*
element_append(ElementObject* self, PyObject* args) element_append(ElementObject* self, PyObject* args)
@ -696,8 +696,7 @@ element_copy(ElementObject* self, PyObject* args)
return NULL; return NULL;
element = (ElementObject*) create_new_element( element = (ElementObject*) create_new_element(
self->tag, (self->extra) ? self->extra->attrib : Py_None self->tag, (self->extra) ? self->extra->attrib : Py_None);
);
if (!element) if (!element)
return NULL; return NULL;
@ -710,7 +709,6 @@ element_copy(ElementObject* self, PyObject* args)
Py_INCREF(JOIN_OBJ(element->tail)); Py_INCREF(JOIN_OBJ(element->tail));
if (self->extra) { if (self->extra) {
if (element_resize(element, self->extra->length) < 0) { if (element_resize(element, self->extra->length) < 0) {
Py_DECREF(element); Py_DECREF(element);
return NULL; return NULL;
@ -722,7 +720,6 @@ element_copy(ElementObject* self, PyObject* args)
} }
element->extra->length = self->extra->length; element->extra->length = self->extra->length;
} }
return (PyObject*) element; return (PyObject*) element;
@ -779,7 +776,6 @@ element_deepcopy(ElementObject* self, PyObject* args)
element->tail = JOIN_SET(tail, JOIN_GET(self->tail)); element->tail = JOIN_SET(tail, JOIN_GET(self->tail));
if (self->extra) { if (self->extra) {
if (element_resize(element, self->extra->length) < 0) if (element_resize(element, self->extra->length) < 0)
goto error; goto error;
@ -793,7 +789,6 @@ element_deepcopy(ElementObject* self, PyObject* args)
} }
element->extra->length = self->extra->length; element->extra->length = self->extra->length;
} }
/* add object to memo dictionary (so deepcopy won't visit it again) */ /* add object to memo dictionary (so deepcopy won't visit it again) */
@ -1141,8 +1136,8 @@ element_findtext(ElementObject *self, PyObject *args, PyObject *kwds)
for (i = 0; i < self->extra->length; i++) { for (i = 0; i < self->extra->length; i++) {
ElementObject* item = (ElementObject*) self->extra->children[i]; ElementObject* item = (ElementObject*) self->extra->children[i];
if (Element_CheckExact(item) && (PyObject_RichCompareBool(item->tag, tag, Py_EQ) == 1)) { if (Element_CheckExact(item) &&
(PyObject_RichCompareBool(item->tag, tag, Py_EQ) == 1)) {
PyObject* text = element_get_text(item); PyObject* text = element_get_text(item);
if (text == Py_None) if (text == Py_None)
return PyUnicode_New(0, 0); return PyUnicode_New(0, 0);
@ -1207,12 +1202,12 @@ element_iterfind(ElementObject *self, PyObject *args, PyObject *kwds)
elementtreestate *st = ET_STATE_GLOBAL; elementtreestate *st = ET_STATE_GLOBAL;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:iterfind", kwlist, if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:iterfind", kwlist,
&tag, &namespaces)) &tag, &namespaces)) {
return NULL; return NULL;
}
return _PyObject_CallMethodId( return _PyObject_CallMethodId(
st->elementpath_obj, &PyId_iterfind, "OOO", self, tag, namespaces st->elementpath_obj, &PyId_iterfind, "OOO", self, tag, namespaces);
);
} }
static PyObject* static PyObject*

File diff suppressed because it is too large Load diff

View file

@ -385,6 +385,8 @@ static int win32_can_symlink = 0;
#endif #endif
#endif #endif
#define DWORD_MAX 4294967295U
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
static int static int
@ -897,7 +899,7 @@ path_converter(PyObject *o, void *p) {
length = PyBytes_GET_SIZE(bytes); length = PyBytes_GET_SIZE(bytes);
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
if (length > MAX_PATH) { if (length > MAX_PATH-1) {
FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Py_DECREF(bytes); Py_DECREF(bytes);
return 0; return 0;
@ -1376,18 +1378,18 @@ posix_1str(const char *func_name, PyObject *args, char *format,
static BOOL __stdcall static BOOL __stdcall
win32_chdir(LPCSTR path) win32_chdir(LPCSTR path)
{ {
char new_path[MAX_PATH+1]; char new_path[MAX_PATH];
int result; int result;
char env[4] = "=x:"; char env[4] = "=x:";
if(!SetCurrentDirectoryA(path)) if(!SetCurrentDirectoryA(path))
return FALSE; return FALSE;
result = GetCurrentDirectoryA(MAX_PATH+1, new_path); result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
if (!result) if (!result)
return FALSE; return FALSE;
/* In the ANSI API, there should not be any paths longer /* In the ANSI API, there should not be any paths longer
than MAX_PATH. */ than MAX_PATH-1 (not including the final null character). */
assert(result <= MAX_PATH+1); assert(result < Py_ARRAY_LENGTH(new_path));
if (strncmp(new_path, "\\\\", 2) == 0 || if (strncmp(new_path, "\\\\", 2) == 0 ||
strncmp(new_path, "//", 2) == 0) strncmp(new_path, "//", 2) == 0)
/* UNC path, nothing to do. */ /* UNC path, nothing to do. */
@ -1401,16 +1403,16 @@ win32_chdir(LPCSTR path)
static BOOL __stdcall static BOOL __stdcall
win32_wchdir(LPCWSTR path) win32_wchdir(LPCWSTR path)
{ {
wchar_t _new_path[MAX_PATH+1], *new_path = _new_path; wchar_t _new_path[MAX_PATH], *new_path = _new_path;
int result; int result;
wchar_t env[4] = L"=x:"; wchar_t env[4] = L"=x:";
if(!SetCurrentDirectoryW(path)) if(!SetCurrentDirectoryW(path))
return FALSE; return FALSE;
result = GetCurrentDirectoryW(MAX_PATH+1, new_path); result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(new_path), new_path);
if (!result) if (!result)
return FALSE; return FALSE;
if (result > MAX_PATH+1) { if (result > Py_ARRAY_LENGTH(new_path)) {
new_path = PyMem_RawMalloc(result * sizeof(wchar_t)); new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
if (!new_path) { if (!new_path) {
SetLastError(ERROR_OUTOFMEMORY); SetLastError(ERROR_OUTOFMEMORY);
@ -3396,11 +3398,11 @@ posix_getcwd(int use_bytes)
PyObject *resobj; PyObject *resobj;
DWORD len; DWORD len;
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf); len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
/* If the buffer is large enough, len does not include the /* If the buffer is large enough, len does not include the
terminating \0. If the buffer is too small, len includes terminating \0. If the buffer is too small, len includes
the space needed for the terminator. */ the space needed for the terminator. */
if (len >= sizeof wbuf/ sizeof wbuf[0]) { if (len >= Py_ARRAY_LENGTH(wbuf)) {
wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t)); wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
if (wbuf2) if (wbuf2)
len = GetCurrentDirectoryW(len, wbuf2); len = GetCurrentDirectoryW(len, wbuf2);
@ -3581,10 +3583,10 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list)
HANDLE hFindFile = INVALID_HANDLE_VALUE; HANDLE hFindFile = INVALID_HANDLE_VALUE;
BOOL result; BOOL result;
WIN32_FIND_DATA FileData; WIN32_FIND_DATA FileData;
char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */ char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
char *bufptr = namebuf; char *bufptr = namebuf;
/* only claim to have space for MAX_PATH */ /* only claim to have space for MAX_PATH */
Py_ssize_t len = sizeof(namebuf)-5; Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
PyObject *po = NULL; PyObject *po = NULL;
wchar_t *wnamebuf = NULL; wchar_t *wnamebuf = NULL;
@ -3873,14 +3875,14 @@ static PyObject *
posix__getfullpathname(PyObject *self, PyObject *args) posix__getfullpathname(PyObject *self, PyObject *args)
{ {
const char *path; const char *path;
char outbuf[MAX_PATH*2]; char outbuf[MAX_PATH];
char *temp; char *temp;
PyObject *po; PyObject *po;
if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
{ {
wchar_t *wpath; wchar_t *wpath;
wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf; wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
wchar_t *wtemp; wchar_t *wtemp;
DWORD result; DWORD result;
PyObject *v; PyObject *v;
@ -4039,24 +4041,31 @@ posix__getvolumepathname(PyObject *self, PyObject *args)
{ {
PyObject *po, *result; PyObject *po, *result;
wchar_t *path, *mountpath=NULL; wchar_t *path, *mountpath=NULL;
size_t bufsize; size_t buflen;
BOOL ret; BOOL ret;
if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po)) if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po))
return NULL; return NULL;
path = PyUnicode_AsUnicode(po); path = PyUnicode_AsUnicodeAndSize(po, &buflen);
if (path == NULL) if (path == NULL)
return NULL; return NULL;
buflen += 1;
/* Volume path should be shorter than entire path */ /* Volume path should be shorter than entire path */
bufsize = max(MAX_PATH, wcslen(path) * 2 * sizeof(wchar_t)+1); buflen = Py_MAX(buflen, MAX_PATH);
mountpath = (wchar_t *)PyMem_Malloc(bufsize);
if (buflen > DWORD_MAX) {
PyErr_SetString(PyExc_OverflowError, "path too long");
return NULL;
}
mountpath = (wchar_t *)PyMem_Malloc(buflen * sizeof(wchar_t));
if (mountpath == NULL) if (mountpath == NULL)
return PyErr_NoMemory(); return PyErr_NoMemory();
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
ret = GetVolumePathNameW(path, mountpath, ret = GetVolumePathNameW(path, mountpath,
Py_SAFE_DOWNCAST(bufsize, size_t, DWORD)); Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (!ret) { if (!ret) {

View file

@ -1956,7 +1956,7 @@ class PyBuildExt(build_ext):
undef_macros = [] undef_macros = []
if '--with-system-libmpdec' in sysconfig.get_config_var("CONFIG_ARGS"): if '--with-system-libmpdec' in sysconfig.get_config_var("CONFIG_ARGS"):
include_dirs = [] include_dirs = []
libraries = ['mpdec'] libraries = [':libmpdec.so.2']
sources = ['_decimal/_decimal.c'] sources = ['_decimal/_decimal.c']
depends = ['_decimal/docstrings.h'] depends = ['_decimal/docstrings.h']
else: else: