merge heads
This commit is contained in:
commit
ea2ce47958
|
@ -1558,7 +1558,7 @@ available. They are listed here in alphabetical order.
|
|||
.. note::
|
||||
|
||||
This is an advanced function that is not needed in everyday Python
|
||||
programming.
|
||||
programming, unlike :func:`importlib.import_module`.
|
||||
|
||||
This function is invoked by the :keyword:`import` statement. It can be
|
||||
replaced (by importing the :mod:`__builtin__` module and assigning to
|
||||
|
@ -1609,15 +1609,8 @@ available. They are listed here in alphabetical order.
|
|||
names.
|
||||
|
||||
If you simply want to import a module (potentially within a package) by name,
|
||||
you can call :func:`__import__` and then look it up in :data:`sys.modules`::
|
||||
use :func:`importlib.import_module`.
|
||||
|
||||
>>> import sys
|
||||
>>> name = 'foo.bar.baz'
|
||||
>>> __import__(name)
|
||||
<module 'foo' from ...>
|
||||
>>> baz = sys.modules[name]
|
||||
>>> baz
|
||||
<module 'foo.bar.baz' from ...>
|
||||
|
||||
.. versionchanged:: 2.5
|
||||
The level parameter was added.
|
||||
|
|
|
@ -629,6 +629,9 @@ format string.
|
|||
.. versionchanged:: 2.5
|
||||
*funcName* was added.
|
||||
|
||||
.. versionchanged:: 2.6
|
||||
*processName* was added.
|
||||
|
||||
.. _logger-adapter:
|
||||
|
||||
LoggerAdapter Objects
|
||||
|
|
|
@ -289,7 +289,7 @@ functions.
|
|||
|
||||
Popen(['/bin/sh', '-c', args[0], args[1], ...])
|
||||
|
||||
On Windows: the :class:`Popen` class uses CreateProcess() to execute the child
|
||||
On Windows: the :class:`Popen` class uses CreateProcess() to execute the
|
||||
child program, which operates on strings. If *args* is a sequence, it will
|
||||
be converted to a string in a manner described in
|
||||
:ref:`converting-argument-sequence`.
|
||||
|
|
|
@ -740,10 +740,10 @@ class Action(_AttributeHolder):
|
|||
|
||||
- default -- The value to be produced if the option is not specified.
|
||||
|
||||
- type -- The type which the command-line arguments should be converted
|
||||
to, should be one of 'string', 'int', 'float', 'complex' or a
|
||||
callable object that accepts a single string argument. If None,
|
||||
'string' is assumed.
|
||||
- type -- A callable that accepts a single string argument, and
|
||||
returns the converted value. The standard Python types str, int,
|
||||
float, and complex are useful examples of such callables. If None,
|
||||
str is used.
|
||||
|
||||
- choices -- A container of values that should be allowed. If not None,
|
||||
after a command-line argument has been converted to the appropriate
|
||||
|
@ -1967,7 +1967,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
|
|||
for arg_string in arg_strings:
|
||||
|
||||
# for regular arguments, just add them back into the list
|
||||
if arg_string[0] not in self.fromfile_prefix_chars:
|
||||
if not arg_string or arg_string[0] not in self.fromfile_prefix_chars:
|
||||
new_arg_strings.append(arg_string)
|
||||
|
||||
# replace arguments referencing files with the file content
|
||||
|
@ -2174,9 +2174,12 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
|
|||
# Value conversion methods
|
||||
# ========================
|
||||
def _get_values(self, action, arg_strings):
|
||||
# for everything but PARSER args, strip out '--'
|
||||
# for everything but PARSER, REMAINDER args, strip out first '--'
|
||||
if action.nargs not in [PARSER, REMAINDER]:
|
||||
arg_strings = [s for s in arg_strings if s != '--']
|
||||
try:
|
||||
arg_strings.remove('--')
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# optional argument produces a default when not present
|
||||
if not arg_strings and action.nargs == OPTIONAL:
|
||||
|
|
|
@ -240,5 +240,25 @@ class BitFieldTest(unittest.TestCase):
|
|||
_anonymous_ = ["_"]
|
||||
_fields_ = [("_", X)]
|
||||
|
||||
@unittest.skipUnless(hasattr(ctypes, "c_uint32"), "c_int32 is required")
|
||||
def test_uint32(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_uint32, 32)]
|
||||
x = X()
|
||||
x.a = 10
|
||||
self.assertEquals(x.a, 10)
|
||||
x.a = 0xFDCBA987
|
||||
self.assertEquals(x.a, 0xFDCBA987)
|
||||
|
||||
@unittest.skipUnless(hasattr(ctypes, "c_uint64"), "c_int64 is required")
|
||||
def test_uint64(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_uint64, 64)]
|
||||
x = X()
|
||||
x.a = 10
|
||||
self.assertEquals(x.a, 10)
|
||||
x.a = 0xFEDCBA9876543211
|
||||
self.assertEquals(x.a, 0xFEDCBA9876543211)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -68,7 +68,8 @@ def isabs(s):
|
|||
def join(a, *p):
|
||||
"""Join two or more pathname components, inserting '/' as needed.
|
||||
If any component is an absolute path, all previous path components
|
||||
will be discarded."""
|
||||
will be discarded. An empty last part will result in a path that
|
||||
ends with a separator."""
|
||||
path = a
|
||||
for b in p:
|
||||
if b.startswith('/'):
|
||||
|
|
|
@ -1374,6 +1374,7 @@ class TestArgumentsFromFile(TempDirMixin, ParserTestCase):
|
|||
('X @hello', NS(a=None, x='X', y=['hello world!'])),
|
||||
('-a B @recursive Y Z', NS(a='A', x='hello world!', y=['Y', 'Z'])),
|
||||
('X @recursive Z -a B', NS(a='B', x='X', y=['hello world!', 'Z'])),
|
||||
(["-a", "", "X", "Y"], NS(a='', x='X', y=['Y'])),
|
||||
]
|
||||
|
||||
|
||||
|
@ -1763,6 +1764,14 @@ class TestAddSubparsers(TestCase):
|
|||
parser2.add_argument('-y', choices='123', help='y help')
|
||||
parser2.add_argument('z', type=complex, nargs='*', help='z help')
|
||||
|
||||
# add third sub-parser
|
||||
parser3_kwargs = dict(description='3 description')
|
||||
if subparser_help:
|
||||
parser3_kwargs['help'] = '3 help'
|
||||
parser3 = subparsers.add_parser('3', **parser3_kwargs)
|
||||
parser3.add_argument('t', type=int, help='t help')
|
||||
parser3.add_argument('u', nargs='...', help='u help')
|
||||
|
||||
# return the main parser
|
||||
return parser
|
||||
|
||||
|
@ -1792,6 +1801,10 @@ class TestAddSubparsers(TestCase):
|
|||
self.parser.parse_args('--foo 0.125 1 c'.split()),
|
||||
NS(foo=True, bar=0.125, w=None, x='c'),
|
||||
)
|
||||
self.assertEqual(
|
||||
self.parser.parse_args('-1.5 3 11 -- a --foo 7 -- b'.split()),
|
||||
NS(foo=False, bar=-1.5, t=11, u=['a', '--foo', '7', '--', 'b']),
|
||||
)
|
||||
|
||||
def test_parse_known_args(self):
|
||||
self.assertEqual(
|
||||
|
@ -1826,15 +1839,15 @@ class TestAddSubparsers(TestCase):
|
|||
|
||||
def test_help(self):
|
||||
self.assertEqual(self.parser.format_usage(),
|
||||
'usage: PROG [-h] [--foo] bar {1,2} ...\n')
|
||||
'usage: PROG [-h] [--foo] bar {1,2,3} ...\n')
|
||||
self.assertEqual(self.parser.format_help(), textwrap.dedent('''\
|
||||
usage: PROG [-h] [--foo] bar {1,2} ...
|
||||
usage: PROG [-h] [--foo] bar {1,2,3} ...
|
||||
|
||||
main description
|
||||
|
||||
positional arguments:
|
||||
bar bar help
|
||||
{1,2} command help
|
||||
{1,2,3} command help
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
|
@ -1845,15 +1858,15 @@ class TestAddSubparsers(TestCase):
|
|||
# Make sure - is still used for help if it is a non-first prefix char
|
||||
parser = self._get_parser(prefix_chars='+:-')
|
||||
self.assertEqual(parser.format_usage(),
|
||||
'usage: PROG [-h] [++foo] bar {1,2} ...\n')
|
||||
'usage: PROG [-h] [++foo] bar {1,2,3} ...\n')
|
||||
self.assertEqual(parser.format_help(), textwrap.dedent('''\
|
||||
usage: PROG [-h] [++foo] bar {1,2} ...
|
||||
usage: PROG [-h] [++foo] bar {1,2,3} ...
|
||||
|
||||
main description
|
||||
|
||||
positional arguments:
|
||||
bar bar help
|
||||
{1,2} command help
|
||||
{1,2,3} command help
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
|
@ -1864,15 +1877,15 @@ class TestAddSubparsers(TestCase):
|
|||
def test_help_alternate_prefix_chars(self):
|
||||
parser = self._get_parser(prefix_chars='+:/')
|
||||
self.assertEqual(parser.format_usage(),
|
||||
'usage: PROG [+h] [++foo] bar {1,2} ...\n')
|
||||
'usage: PROG [+h] [++foo] bar {1,2,3} ...\n')
|
||||
self.assertEqual(parser.format_help(), textwrap.dedent('''\
|
||||
usage: PROG [+h] [++foo] bar {1,2} ...
|
||||
usage: PROG [+h] [++foo] bar {1,2,3} ...
|
||||
|
||||
main description
|
||||
|
||||
positional arguments:
|
||||
bar bar help
|
||||
{1,2} command help
|
||||
{1,2,3} command help
|
||||
|
||||
optional arguments:
|
||||
+h, ++help show this help message and exit
|
||||
|
@ -1881,18 +1894,19 @@ class TestAddSubparsers(TestCase):
|
|||
|
||||
def test_parser_command_help(self):
|
||||
self.assertEqual(self.command_help_parser.format_usage(),
|
||||
'usage: PROG [-h] [--foo] bar {1,2} ...\n')
|
||||
'usage: PROG [-h] [--foo] bar {1,2,3} ...\n')
|
||||
self.assertEqual(self.command_help_parser.format_help(),
|
||||
textwrap.dedent('''\
|
||||
usage: PROG [-h] [--foo] bar {1,2} ...
|
||||
usage: PROG [-h] [--foo] bar {1,2,3} ...
|
||||
|
||||
main description
|
||||
|
||||
positional arguments:
|
||||
bar bar help
|
||||
{1,2} command help
|
||||
{1,2,3} command help
|
||||
1 1 help
|
||||
2 2 help
|
||||
3 3 help
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
|
|
|
@ -495,7 +495,19 @@ class UTF16LETest(ReadTest):
|
|||
)
|
||||
|
||||
def test_errors(self):
|
||||
self.assertRaises(UnicodeDecodeError, codecs.utf_16_le_decode, "\xff", "strict", True)
|
||||
tests = [
|
||||
(b'\xff', u'\ufffd'),
|
||||
(b'A\x00Z', u'A\ufffd'),
|
||||
(b'A\x00B\x00C\x00D\x00Z', u'ABCD\ufffd'),
|
||||
(b'\x00\xd8', u'\ufffd'),
|
||||
(b'\x00\xd8A', u'\ufffd'),
|
||||
(b'\x00\xd8A\x00', u'\ufffdA'),
|
||||
(b'\x00\xdcA\x00', u'\ufffdA'),
|
||||
]
|
||||
for raw, expected in tests:
|
||||
self.assertRaises(UnicodeDecodeError, codecs.utf_16_le_decode,
|
||||
raw, 'strict', True)
|
||||
self.assertEqual(raw.decode('utf-16le', 'replace'), expected)
|
||||
|
||||
class UTF16BETest(ReadTest):
|
||||
encoding = "utf-16-be"
|
||||
|
@ -516,7 +528,19 @@ class UTF16BETest(ReadTest):
|
|||
)
|
||||
|
||||
def test_errors(self):
|
||||
self.assertRaises(UnicodeDecodeError, codecs.utf_16_be_decode, "\xff", "strict", True)
|
||||
tests = [
|
||||
(b'\xff', u'\ufffd'),
|
||||
(b'\x00A\xff', u'A\ufffd'),
|
||||
(b'\x00A\x00B\x00C\x00DZ', u'ABCD\ufffd'),
|
||||
(b'\xd8\x00', u'\ufffd'),
|
||||
(b'\xd8\x00\xdc', u'\ufffd'),
|
||||
(b'\xd8\x00\x00A', u'\ufffdA'),
|
||||
(b'\xdc\x00\x00A', u'\ufffdA'),
|
||||
]
|
||||
for raw, expected in tests:
|
||||
self.assertRaises(UnicodeDecodeError, codecs.utf_16_be_decode,
|
||||
raw, 'strict', True)
|
||||
self.assertEqual(raw.decode('utf-16be', 'replace'), expected)
|
||||
|
||||
class UTF8Test(ReadTest):
|
||||
encoding = "utf-8"
|
||||
|
|
|
@ -462,6 +462,7 @@ Thomas Kluyver
|
|||
Kim Knapp
|
||||
Lenny Kneler
|
||||
Pat Knight
|
||||
Jeff Knupp
|
||||
Greg Kochanski
|
||||
Damon Kohler
|
||||
Marko Kohtala
|
||||
|
|
14
Misc/NEWS
14
Misc/NEWS
|
@ -9,6 +9,12 @@ What's New in Python 2.7.4
|
|||
Core and Builtins
|
||||
-----------------
|
||||
|
||||
- Issue #14579: Fix error handling bug in the utf-16 decoder. Patch by
|
||||
Serhiy Storchaka.
|
||||
|
||||
- Issue #15368: An issue that caused bytecode generation to be
|
||||
non-deterministic when using randomized hashing (-R) has been fixed.
|
||||
|
||||
- Issue #15033: Fix the exit status bug when modules invoked using -m swith,
|
||||
return the proper failure return value (1). Patch contributed by Jeff Knupp.
|
||||
|
||||
|
@ -84,6 +90,14 @@ Core and Builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue #13922: argparse no longer incorrectly strips '--'s that appear
|
||||
after the first one.
|
||||
|
||||
- Issue #12353: argparse now correctly handles null argument values.
|
||||
|
||||
- Issue #6493: An issue in ctypes on Windows that caused structure bitfields
|
||||
of type ctypes.c_uint32 and width 32 to incorrectly be set has been fixed.
|
||||
|
||||
- Issue #14635: telnetlib will use poll() rather than select() when possible
|
||||
to avoid failing due to the select() file descriptor limit.
|
||||
|
||||
|
|
|
@ -431,12 +431,8 @@ get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
|
|||
#define LOW_BIT(x) ((x) & 0xFFFF)
|
||||
#define NUM_BITS(x) ((x) >> 16)
|
||||
|
||||
/* This seems nore a compiler issue than a Windows/non-Windows one */
|
||||
#ifdef MS_WIN32
|
||||
# define BIT_MASK(size) ((1 << NUM_BITS(size))-1)
|
||||
#else
|
||||
# define BIT_MASK(size) ((1LL << NUM_BITS(size))-1)
|
||||
#endif
|
||||
/* Doesn't work if NUM_BITS(size) == 0, but it never happens in SET() call. */
|
||||
#define BIT_MASK(type, size) (((((type)1 << (NUM_BITS(size) - 1)) - 1) << 1) + 1)
|
||||
|
||||
/* This macro CHANGES the first parameter IN PLACE. For proper sign handling,
|
||||
we must first shift left, then right.
|
||||
|
@ -448,10 +444,10 @@ get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
|
|||
}
|
||||
|
||||
/* This macro RETURNS the first parameter with the bit field CHANGED. */
|
||||
#define SET(x, v, size) \
|
||||
#define SET(type, x, v, size) \
|
||||
(NUM_BITS(size) ? \
|
||||
( ( x & ~(BIT_MASK(size) << LOW_BIT(size)) ) | ( (v & BIT_MASK(size)) << LOW_BIT(size) ) ) \
|
||||
: v)
|
||||
( ( (type)x & ~(BIT_MASK(type, size) << LOW_BIT(size)) ) | ( ((type)v & BIT_MASK(type, size)) << LOW_BIT(size) ) ) \
|
||||
: (type)v)
|
||||
|
||||
/* byte swapping macros */
|
||||
#define SWAP_2(v) \
|
||||
|
@ -523,7 +519,7 @@ b_set(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
long val;
|
||||
if (get_long(value, &val) < 0)
|
||||
return NULL;
|
||||
*(signed char *)ptr = (signed char)SET(*(signed char *)ptr, (signed char)val, size);
|
||||
*(signed char *)ptr = SET(signed char, *(signed char *)ptr, val, size);
|
||||
_RET(value);
|
||||
}
|
||||
|
||||
|
@ -542,8 +538,7 @@ B_set(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
unsigned long val;
|
||||
if (get_ulong(value, &val) < 0)
|
||||
return NULL;
|
||||
*(unsigned char *)ptr = (unsigned char)SET(*(unsigned char*)ptr,
|
||||
(unsigned short)val, size);
|
||||
*(unsigned char *)ptr = SET(unsigned char, *(unsigned char*)ptr, val, size);
|
||||
_RET(value);
|
||||
}
|
||||
|
||||
|
@ -564,7 +559,7 @@ h_set(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
if (get_long(value, &val) < 0)
|
||||
return NULL;
|
||||
memcpy(&x, ptr, sizeof(x));
|
||||
x = SET(x, (short)val, size);
|
||||
x = SET(short, x, val, size);
|
||||
memcpy(ptr, &x, sizeof(x));
|
||||
_RET(value);
|
||||
}
|
||||
|
@ -579,7 +574,7 @@ h_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
return NULL;
|
||||
memcpy(&field, ptr, sizeof(field));
|
||||
field = SWAP_2(field);
|
||||
field = SET(field, (short)val, size);
|
||||
field = SET(short, field, val, size);
|
||||
field = SWAP_2(field);
|
||||
memcpy(ptr, &field, sizeof(field));
|
||||
_RET(value);
|
||||
|
@ -612,7 +607,7 @@ H_set(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
if (get_ulong(value, &val) < 0)
|
||||
return NULL;
|
||||
memcpy(&x, ptr, sizeof(x));
|
||||
x = SET(x, (unsigned short)val, size);
|
||||
x = SET(unsigned short, x, val, size);
|
||||
memcpy(ptr, &x, sizeof(x));
|
||||
_RET(value);
|
||||
}
|
||||
|
@ -626,7 +621,7 @@ H_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
return NULL;
|
||||
memcpy(&field, ptr, sizeof(field));
|
||||
field = SWAP_2(field);
|
||||
field = SET(field, (unsigned short)val, size);
|
||||
field = SET(unsigned short, field, val, size);
|
||||
field = SWAP_2(field);
|
||||
memcpy(ptr, &field, sizeof(field));
|
||||
_RET(value);
|
||||
|
@ -660,7 +655,7 @@ i_set(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
if (get_long(value, &val) < 0)
|
||||
return NULL;
|
||||
memcpy(&x, ptr, sizeof(x));
|
||||
x = SET(x, (int)val, size);
|
||||
x = SET(int, x, val, size);
|
||||
memcpy(ptr, &x, sizeof(x));
|
||||
_RET(value);
|
||||
}
|
||||
|
@ -674,7 +669,7 @@ i_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
return NULL;
|
||||
memcpy(&field, ptr, sizeof(field));
|
||||
field = SWAP_INT(field);
|
||||
field = SET(field, (int)val, size);
|
||||
field = SET(int, field, val, size);
|
||||
field = SWAP_INT(field);
|
||||
memcpy(ptr, &field, sizeof(field));
|
||||
_RET(value);
|
||||
|
@ -761,7 +756,7 @@ I_set(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
if (get_ulong(value, &val) < 0)
|
||||
return NULL;
|
||||
memcpy(&x, ptr, sizeof(x));
|
||||
x = SET(x, (unsigned int)val, size);
|
||||
x = SET(unsigned int, x, val, size);
|
||||
memcpy(ptr, &x, sizeof(x));
|
||||
_RET(value);
|
||||
}
|
||||
|
@ -774,7 +769,7 @@ I_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
if (get_ulong(value, &val) < 0)
|
||||
return NULL;
|
||||
memcpy(&field, ptr, sizeof(field));
|
||||
field = (unsigned int)SET(field, (unsigned int)val, size);
|
||||
field = SET(unsigned int, field, (unsigned int)val, size);
|
||||
field = SWAP_INT(field);
|
||||
memcpy(ptr, &field, sizeof(field));
|
||||
_RET(value);
|
||||
|
@ -808,7 +803,7 @@ l_set(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
if (get_long(value, &val) < 0)
|
||||
return NULL;
|
||||
memcpy(&x, ptr, sizeof(x));
|
||||
x = SET(x, val, size);
|
||||
x = SET(long, x, val, size);
|
||||
memcpy(ptr, &x, sizeof(x));
|
||||
_RET(value);
|
||||
}
|
||||
|
@ -822,7 +817,7 @@ l_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
return NULL;
|
||||
memcpy(&field, ptr, sizeof(field));
|
||||
field = SWAP_LONG(field);
|
||||
field = (long)SET(field, val, size);
|
||||
field = SET(long, field, val, size);
|
||||
field = SWAP_LONG(field);
|
||||
memcpy(ptr, &field, sizeof(field));
|
||||
_RET(value);
|
||||
|
@ -856,7 +851,7 @@ L_set(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
if (get_ulong(value, &val) < 0)
|
||||
return NULL;
|
||||
memcpy(&x, ptr, sizeof(x));
|
||||
x = SET(x, val, size);
|
||||
x = SET(unsigned long, x, val, size);
|
||||
memcpy(ptr, &x, sizeof(x));
|
||||
_RET(value);
|
||||
}
|
||||
|
@ -870,7 +865,7 @@ L_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
return NULL;
|
||||
memcpy(&field, ptr, sizeof(field));
|
||||
field = SWAP_LONG(field);
|
||||
field = (unsigned long)SET(field, val, size);
|
||||
field = SET(unsigned long, field, val, size);
|
||||
field = SWAP_LONG(field);
|
||||
memcpy(ptr, &field, sizeof(field));
|
||||
_RET(value);
|
||||
|
@ -905,7 +900,7 @@ q_set(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
if (get_longlong(value, &val) < 0)
|
||||
return NULL;
|
||||
memcpy(&x, ptr, sizeof(x));
|
||||
x = SET(x, val, size);
|
||||
x = SET(PY_LONG_LONG, x, val, size);
|
||||
memcpy(ptr, &x, sizeof(x));
|
||||
_RET(value);
|
||||
}
|
||||
|
@ -919,7 +914,7 @@ q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
return NULL;
|
||||
memcpy(&field, ptr, sizeof(field));
|
||||
field = SWAP_8(field);
|
||||
field = (PY_LONG_LONG)SET(field, val, size);
|
||||
field = SET(PY_LONG_LONG, field, val, size);
|
||||
field = SWAP_8(field);
|
||||
memcpy(ptr, &field, sizeof(field));
|
||||
_RET(value);
|
||||
|
@ -952,7 +947,7 @@ Q_set(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
if (get_ulonglong(value, &val) < 0)
|
||||
return NULL;
|
||||
memcpy(&x, ptr, sizeof(x));
|
||||
x = SET(x, val, size);
|
||||
x = SET(PY_LONG_LONG, x, val, size);
|
||||
memcpy(ptr, &x, sizeof(x));
|
||||
_RET(value);
|
||||
}
|
||||
|
@ -966,7 +961,7 @@ Q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
return NULL;
|
||||
memcpy(&field, ptr, sizeof(field));
|
||||
field = SWAP_8(field);
|
||||
field = (unsigned PY_LONG_LONG)SET(field, val, size);
|
||||
field = SET(unsigned PY_LONG_LONG, field, val, size);
|
||||
field = SWAP_8(field);
|
||||
memcpy(ptr, &field, sizeof(field));
|
||||
_RET(value);
|
||||
|
|
|
@ -2564,7 +2564,7 @@ PyUnicode_DecodeUTF16Stateful(const char *s,
|
|||
}
|
||||
|
||||
/* UTF-16 code pair: */
|
||||
if (q >= e) {
|
||||
if (e - q < 2) {
|
||||
errmsg = "unexpected end of data";
|
||||
startinpos = (((const char *)q)-2)-starts;
|
||||
endinpos = ((const char *)e)-starts;
|
||||
|
|
|
@ -53,8 +53,12 @@ builtin___import__(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
PyDoc_STRVAR(import_doc,
|
||||
"__import__(name, globals={}, locals={}, fromlist=[], level=-1) -> module\n\
|
||||
\n\
|
||||
Import a module. The globals are only used to determine the context;\n\
|
||||
they are not modified. The locals are currently unused. The fromlist\n\
|
||||
Import a module. Because this function is meant for use by the Python\n\
|
||||
interpreter and not for general use it is better to use\n\
|
||||
importlib.import_module() to programmatically import a module.\n\
|
||||
\n\
|
||||
The globals argument is only used to determine the context;\n\
|
||||
they are not modified. The locals argument is unused. The fromlist\n\
|
||||
should be a list of names to emulate ``from name import ...'', or an\n\
|
||||
empty list to emulate ``import name''.\n\
|
||||
When importing a module from a package, note that __import__('A.B', ...)\n\
|
||||
|
|
|
@ -359,14 +359,31 @@ each key.
|
|||
static PyObject *
|
||||
dictbytype(PyObject *src, int scope_type, int flag, int offset)
|
||||
{
|
||||
Py_ssize_t pos = 0, i = offset, scope;
|
||||
Py_ssize_t i = offset, scope, num_keys, key_i;
|
||||
PyObject *k, *v, *dest = PyDict_New();
|
||||
PyObject *sorted_keys;
|
||||
|
||||
assert(offset >= 0);
|
||||
if (dest == NULL)
|
||||
return NULL;
|
||||
|
||||
while (PyDict_Next(src, &pos, &k, &v)) {
|
||||
/* Sort the keys so that we have a deterministic order on the indexes
|
||||
saved in the returned dictionary. These indexes are used as indexes
|
||||
into the free and cell var storage. Therefore if they aren't
|
||||
deterministic, then the generated bytecode is not deterministic.
|
||||
*/
|
||||
sorted_keys = PyDict_Keys(src);
|
||||
if (sorted_keys == NULL)
|
||||
return NULL;
|
||||
if (PyList_Sort(sorted_keys) != 0) {
|
||||
Py_DECREF(sorted_keys);
|
||||
return NULL;
|
||||
}
|
||||
num_keys = PyList_GET_SIZE(sorted_keys);
|
||||
|
||||
for (key_i = 0; key_i < num_keys; key_i++) {
|
||||
k = PyList_GET_ITEM(sorted_keys, key_i);
|
||||
v = PyDict_GetItem(src, k);
|
||||
/* XXX this should probably be a macro in symtable.h */
|
||||
assert(PyInt_Check(v));
|
||||
scope = (PyInt_AS_LONG(v) >> SCOPE_OFF) & SCOPE_MASK;
|
||||
|
@ -374,12 +391,14 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset)
|
|||
if (scope == scope_type || PyInt_AS_LONG(v) & flag) {
|
||||
PyObject *tuple, *item = PyInt_FromLong(i);
|
||||
if (item == NULL) {
|
||||
Py_DECREF(sorted_keys);
|
||||
Py_DECREF(dest);
|
||||
return NULL;
|
||||
}
|
||||
i++;
|
||||
tuple = PyTuple_Pack(2, k, k->ob_type);
|
||||
if (!tuple || PyDict_SetItem(dest, tuple, item) < 0) {
|
||||
Py_DECREF(sorted_keys);
|
||||
Py_DECREF(item);
|
||||
Py_DECREF(dest);
|
||||
Py_XDECREF(tuple);
|
||||
|
@ -389,6 +408,7 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset)
|
|||
Py_DECREF(tuple);
|
||||
}
|
||||
}
|
||||
Py_DECREF(sorted_keys);
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
|
|
@ -347,7 +347,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
|
|||
codestr = (unsigned char *)memcpy(codestr,
|
||||
PyString_AS_STRING(code), codelen);
|
||||
|
||||
/* Verify that RETURN_VALUE terminates the codestring. This allows
|
||||
/* Verify that RETURN_VALUE terminates the codestring. This allows
|
||||
the various transformation patterns to look ahead several
|
||||
instructions without additional checks to make sure they are not
|
||||
looking beyond the end of the code string.
|
||||
|
@ -445,8 +445,8 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
|
|||
case BUILD_LIST:
|
||||
j = GETARG(codestr, i);
|
||||
h = i - 3 * j;
|
||||
if (h >= 0 &&
|
||||
j <= lastlc &&
|
||||
if (h >= 0 &&
|
||||
j <= lastlc &&
|
||||
((opcode == BUILD_TUPLE &&
|
||||
ISBASICBLOCK(blocks, h, 3*(j+1))) ||
|
||||
(opcode == BUILD_LIST &&
|
||||
|
@ -490,8 +490,8 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
|
|||
case BINARY_AND:
|
||||
case BINARY_XOR:
|
||||
case BINARY_OR:
|
||||
if (lastlc >= 2 &&
|
||||
ISBASICBLOCK(blocks, i-6, 7) &&
|
||||
if (lastlc >= 2 &&
|
||||
ISBASICBLOCK(blocks, i-6, 7) &&
|
||||
fold_binops_on_constants(&codestr[i-6], consts)) {
|
||||
i -= 2;
|
||||
assert(codestr[i] == LOAD_CONST);
|
||||
|
@ -500,13 +500,13 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
|
|||
break;
|
||||
|
||||
/* Fold unary ops on constants.
|
||||
LOAD_CONST c1 UNARY_OP --> LOAD_CONST unary_op(c) */
|
||||
LOAD_CONST c1 UNARY_OP --> LOAD_CONST unary_op(c) */
|
||||
case UNARY_NEGATIVE:
|
||||
case UNARY_CONVERT:
|
||||
case UNARY_INVERT:
|
||||
if (lastlc >= 1 &&
|
||||
ISBASICBLOCK(blocks, i-3, 4) &&
|
||||
fold_unaryops_on_constants(&codestr[i-3], consts)) {
|
||||
if (lastlc >= 1 &&
|
||||
ISBASICBLOCK(blocks, i-3, 4) &&
|
||||
fold_unaryops_on_constants(&codestr[i-3], consts)) {
|
||||
i -= 2;
|
||||
assert(codestr[i] == LOAD_CONST);
|
||||
cumlc = 1;
|
||||
|
@ -532,8 +532,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
|
|||
tgt = GETJUMPTGT(codestr, i);
|
||||
j = codestr[tgt];
|
||||
if (CONDITIONAL_JUMP(j)) {
|
||||
/* NOTE: all possible jumps here are
|
||||
absolute! */
|
||||
/* NOTE: all possible jumps here are absolute! */
|
||||
if (JUMPS_ON_TRUE(j) == JUMPS_ON_TRUE(opcode)) {
|
||||
/* The second jump will be
|
||||
taken iff the first is. */
|
||||
|
@ -544,13 +543,10 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
|
|||
SETARG(codestr, i, tgttgt);
|
||||
goto reoptimize_current;
|
||||
} else {
|
||||
/* The second jump is not taken
|
||||
if the first is (so jump past
|
||||
it), and all conditional
|
||||
jumps pop their argument when
|
||||
they're not taken (so change
|
||||
the first jump to pop its
|
||||
argument when it's taken). */
|
||||
/* The second jump is not taken if the first is (so
|
||||
jump past it), and all conditional jumps pop their
|
||||
argument when they're not taken (so change the
|
||||
first jump to pop its argument when it's taken). */
|
||||
if (JUMPS_ON_TRUE(opcode))
|
||||
codestr[i] = POP_JUMP_IF_TRUE;
|
||||
else
|
||||
|
@ -586,8 +582,8 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
|
|||
if (opcode == JUMP_FORWARD) /* JMP_ABS can go backwards */
|
||||
opcode = JUMP_ABSOLUTE;
|
||||
if (!ABSOLUTE_JUMP(opcode))
|
||||
tgttgt -= i + 3; /* Calc relative jump addr */
|
||||
if (tgttgt < 0) /* No backward relative jumps */
|
||||
tgttgt -= i + 3; /* Calc relative jump addr */
|
||||
if (tgttgt < 0) /* No backward relative jumps */
|
||||
continue;
|
||||
codestr[i] = opcode;
|
||||
SETARG(codestr, i, tgttgt);
|
||||
|
|
Loading…
Reference in New Issue