mirror of
https://github.com/python/cpython.git
synced 2025-08-03 00:23:06 +00:00
Merged 3.4.0b1 release head back into trunk.
This commit is contained in:
commit
99e101013f
27 changed files with 1133 additions and 368 deletions
|
@ -186,6 +186,7 @@ serve:
|
|||
autobuild-dev:
|
||||
make update
|
||||
make dist SPHINXOPTS='-A daily=1 -A versionswitcher=1'
|
||||
-make suspicious
|
||||
|
||||
# for quick rebuilds (HTML only)
|
||||
autobuild-html:
|
||||
|
|
|
@ -96,7 +96,7 @@ this module.
|
|||
only it when looking for candidate matches. Otherwise consider only the
|
||||
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``.
|
||||
|
||||
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,
|
||||
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)
|
||||
|
|
|
@ -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`
|
||||
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
|
||||
the Python 3.2 version of the email package. For more information see the
|
||||
:mod:`~email.policy` documentation.
|
||||
|
|
|
@ -476,9 +476,9 @@ applications.)
|
|||
|
||||
:program:`xgettext`, :program:`pygettext`, and similar tools generate
|
||||
:file:`.po` files that are message catalogs. They are structured
|
||||
:human-readable files that contain every marked string in the source
|
||||
:code, along with a placeholder for the translated versions of these
|
||||
:strings.
|
||||
human-readable files that contain every marked string in the source
|
||||
code, along with a placeholder for the translated versions of these
|
||||
strings.
|
||||
|
||||
Copies of these :file:`.po` files are then handed over to the
|
||||
individual human translators who write translations for every
|
||||
|
|
|
@ -901,8 +901,8 @@ Test cases
|
|||
| :meth:`assertWarnsRegex(warn, r, fun, *args, **kwds) | ``fun(*args, **kwds)`` raises *warn* | 3.2 |
|
||||
| <TestCase.assertWarnsRegex>` | and the message matches regex *r* | |
|
||||
+---------------------------------------------------------+--------------------------------------+------------+
|
||||
| :meth:`assertLogs(logger, level)` | The ``with`` block logs on *logger* | 3.4 |
|
||||
| <TestCase.assertWarns>` | with minimum *level* | |
|
||||
| :meth:`assertLogs(logger, level) | The ``with`` block logs on *logger* | 3.4 |
|
||||
| <TestCase.assertLogs>` | with minimum *level* | |
|
||||
+---------------------------------------------------------+--------------------------------------+------------+
|
||||
|
||||
.. method:: assertRaises(exception, callable, *args, **kwds)
|
||||
|
|
|
@ -141,15 +141,8 @@ library/linecache,,:sys,"sys:x:3:3:sys:/dev:/bin/sh"
|
|||
library/logging.handlers,,:port,host:port
|
||||
library/mmap,,:i2,obj[i1:i2]
|
||||
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('__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,,`,# register the Foo class; make `f()` and `g()` 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/optparse,,:len,"del parser.rargs[:len(value)]"
|
||||
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/pickle,,:memory,"conn = sqlite3.connect("":memory:"")"
|
||||
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/time,,:mm,
|
||||
library/time,,:ss,
|
||||
library/tracemalloc,,:limit,"for index, stat in enumerate(top_stats[:limit], 1):"
|
||||
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,,: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"""
|
||||
|
|
|
|
@ -424,7 +424,7 @@ base64
|
|||
|
||||
The encoding and decoding functions in :mod:`base64` now accept any
|
||||
: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
|
||||
|
|
|
@ -329,7 +329,7 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
|
|||
(bad_directive, format)) from None
|
||||
# IndexError only occurs when the format string is "%"
|
||||
except IndexError:
|
||||
raise ValueError("stray %% in format '%s'" % format)
|
||||
raise ValueError("stray %% in format '%s'" % format) from None
|
||||
_regex_cache[format] = format_regex
|
||||
found = format_regex.match(data_string)
|
||||
if not found:
|
||||
|
|
|
@ -327,14 +327,21 @@ class IocpProactor:
|
|||
handle, self._iocp, ov.address, ms)
|
||||
f = _WaitHandleFuture(wh, loop=self._loop)
|
||||
|
||||
def finish(timed_out, _, ov):
|
||||
def finish(trans, key, ov):
|
||||
if not f.cancelled():
|
||||
try:
|
||||
_overlapped.UnregisterWait(wh)
|
||||
except OSError as e:
|
||||
if e.winerror != _overlapped.ERROR_IO_PENDING:
|
||||
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)
|
||||
return f
|
||||
|
|
|
@ -140,6 +140,7 @@ __all__ = [
|
|||
|
||||
__version__ = '1.70' # Highest version of the spec this complies with
|
||||
# See http://speleotrove.com/decimal/
|
||||
__libmpdec_version__ = "2.4.0" # compatible libmpdec version
|
||||
|
||||
import copy as _copy
|
||||
import math as _math
|
||||
|
|
|
@ -224,7 +224,7 @@ class FileInput:
|
|||
"'r', 'rU', 'U' and 'rb'")
|
||||
if 'U' in mode:
|
||||
import warnings
|
||||
warnings.warn("Use of 'U' mode is deprecated",
|
||||
warnings.warn("'U' mode is deprecated",
|
||||
DeprecationWarning, 2)
|
||||
self._mode = mode
|
||||
if openhook:
|
||||
|
|
|
@ -602,7 +602,9 @@ class UTF16Test(ReadTest, unittest.TestCase):
|
|||
self.addCleanup(support.unlink, support.TESTFN)
|
||||
with open(support.TESTFN, 'wb') as fp:
|
||||
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)
|
||||
|
||||
class UTF16LETest(ReadTest, unittest.TestCase):
|
||||
|
|
|
@ -4149,6 +4149,7 @@ class CheckAttributes(unittest.TestCase):
|
|||
self.assertTrue(P.HAVE_THREADS is True or P.HAVE_THREADS is False)
|
||||
|
||||
self.assertEqual(C.__version__, P.__version__)
|
||||
self.assertEqual(C.__libmpdec_version__, P.__libmpdec_version__)
|
||||
|
||||
x = dir(C)
|
||||
y = [s for s in dir(P) if '__' in s or not s.startswith('_')]
|
||||
|
|
|
@ -22,7 +22,7 @@ except ImportError:
|
|||
from io import StringIO
|
||||
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
|
||||
|
||||
|
||||
|
@ -224,8 +224,10 @@ class FileInputTests(unittest.TestCase):
|
|||
try:
|
||||
# try opening in universal newline mode
|
||||
t1 = writeTmp(1, [b"A\nB\r\nC\rD"], mode="wb")
|
||||
fi = FileInput(files=t1, mode="U")
|
||||
lines = list(fi)
|
||||
with check_warnings(('', DeprecationWarning)):
|
||||
fi = FileInput(files=t1, mode="U")
|
||||
with check_warnings(('', DeprecationWarning)):
|
||||
lines = list(fi)
|
||||
self.assertEqual(lines, ["A\n", "B\n", "C\n", "D"])
|
||||
finally:
|
||||
remove_tempfiles(t1)
|
||||
|
|
|
@ -170,6 +170,7 @@ class DebuggerTests(unittest.TestCase):
|
|||
'Do you need "set solib-search-path" or '
|
||||
'"set sysroot"?',
|
||||
'warning: Source file is more recent than executable.',
|
||||
'Missing separate debuginfo for ',
|
||||
)
|
||||
for line in errlines:
|
||||
if not line.startswith(ignore_patterns):
|
||||
|
|
|
@ -2777,7 +2777,8 @@ class MiscIOTest(unittest.TestCase):
|
|||
self.assertEqual(f.mode, "wb")
|
||||
f.close()
|
||||
|
||||
f = self.open(support.TESTFN, "U")
|
||||
with support.check_warnings(('', DeprecationWarning)):
|
||||
f = self.open(support.TESTFN, "U")
|
||||
self.assertEqual(f.name, support.TESTFN)
|
||||
self.assertEqual(f.buffer.name, support.TESTFN)
|
||||
self.assertEqual(f.buffer.raw.name, support.TESTFN)
|
||||
|
|
|
@ -223,6 +223,10 @@ class StrptimeTests(unittest.TestCase):
|
|||
with self.assertRaises(ValueError) as e:
|
||||
_strptime._strptime_time('', '%D')
|
||||
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):
|
||||
# Check ValueError is raised when there is unconverted data
|
||||
|
|
|
@ -198,6 +198,10 @@ class TimeTestCase(unittest.TestCase):
|
|||
with self.assertRaises(ValueError) as e:
|
||||
time.strptime('', '%D')
|
||||
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):
|
||||
time.asctime(time.gmtime(self.t))
|
||||
|
|
|
@ -14,7 +14,7 @@ from random import randint, random, getrandbits
|
|||
|
||||
from test.support import (TESTFN, findfile, unlink,
|
||||
requires_zlib, requires_bz2, requires_lzma,
|
||||
captured_stdout)
|
||||
captured_stdout, check_warnings)
|
||||
|
||||
TESTFN2 = TESTFN + "2"
|
||||
TESTFNDIR = TESTFN + "d"
|
||||
|
@ -35,6 +35,10 @@ def get_files(test):
|
|||
yield f
|
||||
test.assertFalse(f.closed)
|
||||
|
||||
def openU(zipfp, fn):
|
||||
with check_warnings(('', DeprecationWarning)):
|
||||
return zipfp.open(fn, 'rU')
|
||||
|
||||
class AbstractTestsWithSourceFile:
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
@ -875,6 +879,17 @@ class OtherTests(unittest.TestCase):
|
|||
data += zipfp.read(info)
|
||||
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):
|
||||
f = io.BytesIO()
|
||||
|
||||
|
@ -884,7 +899,7 @@ class OtherTests(unittest.TestCase):
|
|||
|
||||
data2 = b''
|
||||
with zipfile.ZipFile(f, 'r') as zipfp, \
|
||||
zipfp.open(TESTFN, 'rU') as zipopen:
|
||||
openU(zipfp, TESTFN) as zipopen:
|
||||
for line in zipopen:
|
||||
data2 += line
|
||||
|
||||
|
@ -1613,7 +1628,7 @@ class AbstractUniversalNewlineTests:
|
|||
# Read the ZIP archive
|
||||
with zipfile.ZipFile(f, "r") as zipfp:
|
||||
for sep, fn in self.arcfiles.items():
|
||||
with zipfp.open(fn, "rU") as fp:
|
||||
with openU(zipfp, fn) as fp:
|
||||
zipdata = fp.read()
|
||||
self.assertEqual(self.arcdata[sep], zipdata)
|
||||
|
||||
|
@ -1627,7 +1642,7 @@ class AbstractUniversalNewlineTests:
|
|||
# Read the ZIP archive
|
||||
with zipfile.ZipFile(f, "r") as zipfp:
|
||||
for sep, fn in self.arcfiles.items():
|
||||
with zipfp.open(fn, "rU") as zipopen:
|
||||
with openU(zipfp, fn) as zipopen:
|
||||
data = b''
|
||||
while True:
|
||||
read = zipopen.readline()
|
||||
|
@ -1652,7 +1667,7 @@ class AbstractUniversalNewlineTests:
|
|||
# Read the ZIP archive
|
||||
with zipfile.ZipFile(f, "r") as zipfp:
|
||||
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:
|
||||
linedata = zipopen.readline()
|
||||
self.assertEqual(linedata, line + b'\n')
|
||||
|
@ -1667,7 +1682,7 @@ class AbstractUniversalNewlineTests:
|
|||
# Read the ZIP archive
|
||||
with zipfile.ZipFile(f, "r") as zipfp:
|
||||
for sep, fn in self.arcfiles.items():
|
||||
with zipfp.open(fn, "rU") as fp:
|
||||
with openU(zipfp, fn) as fp:
|
||||
ziplines = fp.readlines()
|
||||
for line, zipline in zip(self.line_gen, ziplines):
|
||||
self.assertEqual(zipline, line + b'\n')
|
||||
|
@ -1682,7 +1697,7 @@ class AbstractUniversalNewlineTests:
|
|||
# Read the ZIP archive
|
||||
with zipfile.ZipFile(f, "r") as zipfp:
|
||||
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):
|
||||
self.assertEqual(zipline, line + b'\n')
|
||||
|
||||
|
|
23
Misc/NEWS
23
Misc/NEWS
|
@ -2,6 +2,21 @@
|
|||
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?
|
||||
==================================
|
||||
|
||||
|
@ -2518,7 +2533,7 @@ Library
|
|||
- 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
|
||||
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.
|
||||
Patch by Atsuo Ishimoto.
|
||||
|
@ -6091,7 +6106,7 @@ Library
|
|||
given as a low fd, it gets overwritten.
|
||||
|
||||
- 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.
|
||||
|
||||
|
@ -6686,7 +6701,7 @@ Library
|
|||
|
||||
- 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
|
||||
contributions by Jeff McNeil and Nadeem Vawda.
|
||||
|
||||
|
@ -7262,7 +7277,7 @@ Tests
|
|||
- Issue #11505: improves test coverage of string.py. Patch by Alicia
|
||||
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.
|
||||
|
||||
- Issue #11223: Fix test_threadsignals to fail, not hang, when the
|
||||
|
|
|
@ -39,6 +39,11 @@
|
|||
#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:
|
||||
* sizeof(size_t) == sizeof(Py_ssize_t)
|
||||
|
@ -5730,7 +5735,8 @@ PyInit__decimal(void)
|
|||
}
|
||||
|
||||
/* 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;
|
||||
|
|
|
@ -97,6 +97,8 @@ static void _settriple(mpd_t *result, uint8_t sign, mpd_uint_t a,
|
|||
mpd_ssize_t exp);
|
||||
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,
|
||||
const mpd_context_t *ctx, uint32_t *status);
|
||||
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);
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Version */
|
||||
/******************************************************************************/
|
||||
|
||||
const char *
|
||||
mpd_version(void)
|
||||
{
|
||||
return MPD_VERSION;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Performance critical inline functions */
|
||||
/******************************************************************************/
|
||||
|
@ -1345,6 +1358,91 @@ mpd_qget_ssize(const mpd_t *a, uint32_t *status)
|
|||
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
|
||||
/* quietly get a uint64_t from a decimal */
|
||||
uint64_t
|
||||
|
@ -1359,7 +1457,57 @@ mpd_qget_i64(const mpd_t *a, uint32_t *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
|
||||
#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 */
|
||||
uint32_t
|
||||
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);
|
||||
}
|
||||
#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
|
||||
|
||||
/* 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);
|
||||
}
|
||||
#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
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
#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
|
||||
|
||||
/* 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);
|
||||
}
|
||||
#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
|
||||
|
||||
/* Like the minus operator. */
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -56,12 +55,18 @@ extern "C" {
|
|||
#define MPD_HIDE_SYMBOLS_END
|
||||
#define EXTINLINE extern inline
|
||||
#else
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#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__
|
||||
#define __GNUC_STDC_INLINE__ 1
|
||||
#endif
|
||||
|
@ -99,6 +104,19 @@ MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
|
|||
#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 */
|
||||
/******************************************************************************/
|
||||
|
@ -241,7 +259,7 @@ extern const char *mpd_round_string[MPD_ROUND_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 emax; /* max positive 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)
|
||||
|
||||
/* mpd_t */
|
||||
typedef struct {
|
||||
typedef struct mpd_t {
|
||||
uint8_t flags;
|
||||
mpd_ssize_t exp;
|
||||
mpd_ssize_t digits;
|
||||
|
@ -371,7 +389,7 @@ typedef unsigned char uchar;
|
|||
/******************************************************************************/
|
||||
|
||||
/* format specification */
|
||||
typedef struct {
|
||||
typedef struct mpd_spec_t {
|
||||
mpd_ssize_t min_width; /* minimum field width */
|
||||
mpd_ssize_t prec; /* fraction digits or significant digits */
|
||||
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_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 */
|
||||
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_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);
|
||||
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_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);
|
||||
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_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);
|
||||
|
@ -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_invroot(mpd_t *result, 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);
|
||||
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);
|
||||
|
||||
#ifndef LEGACY_COMPILER
|
||||
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_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_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);
|
||||
#else
|
||||
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);
|
||||
#endif
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* 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
|
||||
|
||||
|
||||
|
|
|
@ -567,8 +567,9 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
PyObject* attrib = NULL;
|
||||
if (!PyArg_ParseTuple(args, "O!O|O!:SubElement",
|
||||
&Element_Type, &parent, &tag,
|
||||
&PyDict_Type, &attrib))
|
||||
&PyDict_Type, &attrib)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (attrib) {
|
||||
/* attrib passed as positional arg */
|
||||
|
@ -652,7 +653,6 @@ element_dealloc(ElementObject* self)
|
|||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* methods (in alphabetical order) */
|
||||
|
||||
static PyObject*
|
||||
element_append(ElementObject* self, PyObject* args)
|
||||
|
@ -696,8 +696,7 @@ element_copy(ElementObject* self, PyObject* args)
|
|||
return NULL;
|
||||
|
||||
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)
|
||||
return NULL;
|
||||
|
||||
|
@ -710,7 +709,6 @@ element_copy(ElementObject* self, PyObject* args)
|
|||
Py_INCREF(JOIN_OBJ(element->tail));
|
||||
|
||||
if (self->extra) {
|
||||
|
||||
if (element_resize(element, self->extra->length) < 0) {
|
||||
Py_DECREF(element);
|
||||
return NULL;
|
||||
|
@ -722,7 +720,6 @@ element_copy(ElementObject* self, PyObject* args)
|
|||
}
|
||||
|
||||
element->extra->length = self->extra->length;
|
||||
|
||||
}
|
||||
|
||||
return (PyObject*) element;
|
||||
|
@ -779,7 +776,6 @@ element_deepcopy(ElementObject* self, PyObject* args)
|
|||
element->tail = JOIN_SET(tail, JOIN_GET(self->tail));
|
||||
|
||||
if (self->extra) {
|
||||
|
||||
if (element_resize(element, self->extra->length) < 0)
|
||||
goto error;
|
||||
|
||||
|
@ -793,7 +789,6 @@ element_deepcopy(ElementObject* self, PyObject* args)
|
|||
}
|
||||
|
||||
element->extra->length = self->extra->length;
|
||||
|
||||
}
|
||||
|
||||
/* 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++) {
|
||||
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);
|
||||
if (text == Py_None)
|
||||
return PyUnicode_New(0, 0);
|
||||
|
@ -1207,12 +1202,12 @@ element_iterfind(ElementObject *self, PyObject *args, PyObject *kwds)
|
|||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:iterfind", kwlist,
|
||||
&tag, &namespaces))
|
||||
&tag, &namespaces)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return _PyObject_CallMethodId(
|
||||
st->elementpath_obj, &PyId_iterfind, "OOO", self, tag, namespaces
|
||||
);
|
||||
st->elementpath_obj, &PyId_iterfind, "OOO", self, tag, namespaces);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -385,6 +385,8 @@ static int win32_can_symlink = 0;
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#define DWORD_MAX 4294967295U
|
||||
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
static int
|
||||
|
@ -897,7 +899,7 @@ path_converter(PyObject *o, void *p) {
|
|||
|
||||
length = PyBytes_GET_SIZE(bytes);
|
||||
#ifdef MS_WINDOWS
|
||||
if (length > MAX_PATH) {
|
||||
if (length > MAX_PATH-1) {
|
||||
FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
|
||||
Py_DECREF(bytes);
|
||||
return 0;
|
||||
|
@ -1376,18 +1378,18 @@ posix_1str(const char *func_name, PyObject *args, char *format,
|
|||
static BOOL __stdcall
|
||||
win32_chdir(LPCSTR path)
|
||||
{
|
||||
char new_path[MAX_PATH+1];
|
||||
char new_path[MAX_PATH];
|
||||
int result;
|
||||
char env[4] = "=x:";
|
||||
|
||||
if(!SetCurrentDirectoryA(path))
|
||||
return FALSE;
|
||||
result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
|
||||
result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
|
||||
if (!result)
|
||||
return FALSE;
|
||||
/* In the ANSI API, there should not be any paths longer
|
||||
than MAX_PATH. */
|
||||
assert(result <= MAX_PATH+1);
|
||||
than MAX_PATH-1 (not including the final null character). */
|
||||
assert(result < Py_ARRAY_LENGTH(new_path));
|
||||
if (strncmp(new_path, "\\\\", 2) == 0 ||
|
||||
strncmp(new_path, "//", 2) == 0)
|
||||
/* UNC path, nothing to do. */
|
||||
|
@ -1401,16 +1403,16 @@ win32_chdir(LPCSTR path)
|
|||
static BOOL __stdcall
|
||||
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;
|
||||
wchar_t env[4] = L"=x:";
|
||||
|
||||
if(!SetCurrentDirectoryW(path))
|
||||
return FALSE;
|
||||
result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
|
||||
result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(new_path), new_path);
|
||||
if (!result)
|
||||
return FALSE;
|
||||
if (result > MAX_PATH+1) {
|
||||
if (result > Py_ARRAY_LENGTH(new_path)) {
|
||||
new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
|
||||
if (!new_path) {
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
|
@ -3396,11 +3398,11 @@ posix_getcwd(int use_bytes)
|
|||
PyObject *resobj;
|
||||
DWORD len;
|
||||
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
|
||||
terminating \0. If the buffer is too small, len includes
|
||||
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));
|
||||
if (wbuf2)
|
||||
len = GetCurrentDirectoryW(len, wbuf2);
|
||||
|
@ -3581,10 +3583,10 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list)
|
|||
HANDLE hFindFile = INVALID_HANDLE_VALUE;
|
||||
BOOL result;
|
||||
WIN32_FIND_DATA FileData;
|
||||
char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
|
||||
char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
|
||||
char *bufptr = namebuf;
|
||||
/* 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;
|
||||
wchar_t *wnamebuf = NULL;
|
||||
|
||||
|
@ -3873,14 +3875,14 @@ static PyObject *
|
|||
posix__getfullpathname(PyObject *self, PyObject *args)
|
||||
{
|
||||
const char *path;
|
||||
char outbuf[MAX_PATH*2];
|
||||
char outbuf[MAX_PATH];
|
||||
char *temp;
|
||||
PyObject *po;
|
||||
|
||||
if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
|
||||
{
|
||||
wchar_t *wpath;
|
||||
wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
|
||||
wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
|
||||
wchar_t *wtemp;
|
||||
DWORD result;
|
||||
PyObject *v;
|
||||
|
@ -4039,24 +4041,31 @@ posix__getvolumepathname(PyObject *self, PyObject *args)
|
|||
{
|
||||
PyObject *po, *result;
|
||||
wchar_t *path, *mountpath=NULL;
|
||||
size_t bufsize;
|
||||
size_t buflen;
|
||||
BOOL ret;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po))
|
||||
return NULL;
|
||||
path = PyUnicode_AsUnicode(po);
|
||||
path = PyUnicode_AsUnicodeAndSize(po, &buflen);
|
||||
if (path == NULL)
|
||||
return NULL;
|
||||
buflen += 1;
|
||||
|
||||
/* Volume path should be shorter than entire path */
|
||||
bufsize = max(MAX_PATH, wcslen(path) * 2 * sizeof(wchar_t)+1);
|
||||
mountpath = (wchar_t *)PyMem_Malloc(bufsize);
|
||||
buflen = Py_MAX(buflen, MAX_PATH);
|
||||
|
||||
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)
|
||||
return PyErr_NoMemory();
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
ret = GetVolumePathNameW(path, mountpath,
|
||||
Py_SAFE_DOWNCAST(bufsize, size_t, DWORD));
|
||||
Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
if (!ret) {
|
||||
|
|
2
setup.py
2
setup.py
|
@ -1956,7 +1956,7 @@ class PyBuildExt(build_ext):
|
|||
undef_macros = []
|
||||
if '--with-system-libmpdec' in sysconfig.get_config_var("CONFIG_ARGS"):
|
||||
include_dirs = []
|
||||
libraries = ['mpdec']
|
||||
libraries = [':libmpdec.so.2']
|
||||
sources = ['_decimal/_decimal.c']
|
||||
depends = ['_decimal/docstrings.h']
|
||||
else:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue