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:
make update
make dist SPHINXOPTS='-A daily=1 -A versionswitcher=1'
-make suspicious
# for quick rebuilds (HTML only)
autobuild-html:

View file

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

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

View file

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

View file

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

View file

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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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('_')]

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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