merge heads

This commit is contained in:
Gregory P. Smith 2012-07-21 21:23:00 -07:00
commit ea2ce47958
15 changed files with 173 additions and 85 deletions

View File

@ -1558,7 +1558,7 @@ available. They are listed here in alphabetical order.
.. note:: .. note::
This is an advanced function that is not needed in everyday Python 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 This function is invoked by the :keyword:`import` statement. It can be
replaced (by importing the :mod:`__builtin__` module and assigning to replaced (by importing the :mod:`__builtin__` module and assigning to
@ -1609,15 +1609,8 @@ available. They are listed here in alphabetical order.
names. names.
If you simply want to import a module (potentially within a package) by name, 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 .. versionchanged:: 2.5
The level parameter was added. The level parameter was added.

View File

@ -629,6 +629,9 @@ format string.
.. versionchanged:: 2.5 .. versionchanged:: 2.5
*funcName* was added. *funcName* was added.
.. versionchanged:: 2.6
*processName* was added.
.. _logger-adapter: .. _logger-adapter:
LoggerAdapter Objects LoggerAdapter Objects

View File

@ -289,7 +289,7 @@ functions.
Popen(['/bin/sh', '-c', args[0], args[1], ...]) 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 child program, which operates on strings. If *args* is a sequence, it will
be converted to a string in a manner described in be converted to a string in a manner described in
:ref:`converting-argument-sequence`. :ref:`converting-argument-sequence`.

View File

@ -740,10 +740,10 @@ class Action(_AttributeHolder):
- default -- The value to be produced if the option is not specified. - default -- The value to be produced if the option is not specified.
- type -- The type which the command-line arguments should be converted - type -- A callable that accepts a single string argument, and
to, should be one of 'string', 'int', 'float', 'complex' or a returns the converted value. The standard Python types str, int,
callable object that accepts a single string argument. If None, float, and complex are useful examples of such callables. If None,
'string' is assumed. str is used.
- choices -- A container of values that should be allowed. If not None, - choices -- A container of values that should be allowed. If not None,
after a command-line argument has been converted to the appropriate 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 arg_string in arg_strings:
# for regular arguments, just add them back into the list # 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) new_arg_strings.append(arg_string)
# replace arguments referencing files with the file content # replace arguments referencing files with the file content
@ -2174,9 +2174,12 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
# Value conversion methods # Value conversion methods
# ======================== # ========================
def _get_values(self, action, arg_strings): 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]: 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 # optional argument produces a default when not present
if not arg_strings and action.nargs == OPTIONAL: if not arg_strings and action.nargs == OPTIONAL:

View File

@ -240,5 +240,25 @@ class BitFieldTest(unittest.TestCase):
_anonymous_ = ["_"] _anonymous_ = ["_"]
_fields_ = [("_", X)] _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__": if __name__ == "__main__":
unittest.main() unittest.main()

View File

@ -68,7 +68,8 @@ def isabs(s):
def join(a, *p): def join(a, *p):
"""Join two or more pathname components, inserting '/' as needed. """Join two or more pathname components, inserting '/' as needed.
If any component is an absolute path, all previous path components 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 path = a
for b in p: for b in p:
if b.startswith('/'): if b.startswith('/'):

View File

@ -1374,6 +1374,7 @@ class TestArgumentsFromFile(TempDirMixin, ParserTestCase):
('X @hello', NS(a=None, x='X', y=['hello world!'])), ('X @hello', NS(a=None, x='X', y=['hello world!'])),
('-a B @recursive Y Z', NS(a='A', x='hello world!', y=['Y', 'Z'])), ('-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'])), ('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('-y', choices='123', help='y help')
parser2.add_argument('z', type=complex, nargs='*', help='z 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 the main parser
return parser return parser
@ -1792,6 +1801,10 @@ class TestAddSubparsers(TestCase):
self.parser.parse_args('--foo 0.125 1 c'.split()), self.parser.parse_args('--foo 0.125 1 c'.split()),
NS(foo=True, bar=0.125, w=None, x='c'), 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): def test_parse_known_args(self):
self.assertEqual( self.assertEqual(
@ -1826,15 +1839,15 @@ class TestAddSubparsers(TestCase):
def test_help(self): def test_help(self):
self.assertEqual(self.parser.format_usage(), 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('''\ 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 main description
positional arguments: positional arguments:
bar bar help bar bar help
{1,2} command help {1,2,3} command help
optional arguments: optional arguments:
-h, --help show this help message and exit -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 # Make sure - is still used for help if it is a non-first prefix char
parser = self._get_parser(prefix_chars='+:-') parser = self._get_parser(prefix_chars='+:-')
self.assertEqual(parser.format_usage(), 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('''\ self.assertEqual(parser.format_help(), textwrap.dedent('''\
usage: PROG [-h] [++foo] bar {1,2} ... usage: PROG [-h] [++foo] bar {1,2,3} ...
main description main description
positional arguments: positional arguments:
bar bar help bar bar help
{1,2} command help {1,2,3} command help
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
@ -1864,15 +1877,15 @@ class TestAddSubparsers(TestCase):
def test_help_alternate_prefix_chars(self): def test_help_alternate_prefix_chars(self):
parser = self._get_parser(prefix_chars='+:/') parser = self._get_parser(prefix_chars='+:/')
self.assertEqual(parser.format_usage(), 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('''\ self.assertEqual(parser.format_help(), textwrap.dedent('''\
usage: PROG [+h] [++foo] bar {1,2} ... usage: PROG [+h] [++foo] bar {1,2,3} ...
main description main description
positional arguments: positional arguments:
bar bar help bar bar help
{1,2} command help {1,2,3} command help
optional arguments: optional arguments:
+h, ++help show this help message and exit +h, ++help show this help message and exit
@ -1881,18 +1894,19 @@ class TestAddSubparsers(TestCase):
def test_parser_command_help(self): def test_parser_command_help(self):
self.assertEqual(self.command_help_parser.format_usage(), 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(), self.assertEqual(self.command_help_parser.format_help(),
textwrap.dedent('''\ textwrap.dedent('''\
usage: PROG [-h] [--foo] bar {1,2} ... usage: PROG [-h] [--foo] bar {1,2,3} ...
main description main description
positional arguments: positional arguments:
bar bar help bar bar help
{1,2} command help {1,2,3} command help
1 1 help 1 1 help
2 2 help 2 2 help
3 3 help
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit

View File

@ -495,7 +495,19 @@ class UTF16LETest(ReadTest):
) )
def test_errors(self): 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): class UTF16BETest(ReadTest):
encoding = "utf-16-be" encoding = "utf-16-be"
@ -516,7 +528,19 @@ class UTF16BETest(ReadTest):
) )
def test_errors(self): 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): class UTF8Test(ReadTest):
encoding = "utf-8" encoding = "utf-8"

View File

@ -462,6 +462,7 @@ Thomas Kluyver
Kim Knapp Kim Knapp
Lenny Kneler Lenny Kneler
Pat Knight Pat Knight
Jeff Knupp
Greg Kochanski Greg Kochanski
Damon Kohler Damon Kohler
Marko Kohtala Marko Kohtala

View File

@ -9,6 +9,12 @@ What's New in Python 2.7.4
Core and Builtins 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, - 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. return the proper failure return value (1). Patch contributed by Jeff Knupp.
@ -84,6 +90,14 @@ Core and Builtins
Library 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 - Issue #14635: telnetlib will use poll() rather than select() when possible
to avoid failing due to the select() file descriptor limit. to avoid failing due to the select() file descriptor limit.

View File

@ -431,12 +431,8 @@ get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
#define LOW_BIT(x) ((x) & 0xFFFF) #define LOW_BIT(x) ((x) & 0xFFFF)
#define NUM_BITS(x) ((x) >> 16) #define NUM_BITS(x) ((x) >> 16)
/* This seems nore a compiler issue than a Windows/non-Windows one */ /* Doesn't work if NUM_BITS(size) == 0, but it never happens in SET() call. */
#ifdef MS_WIN32 #define BIT_MASK(type, size) (((((type)1 << (NUM_BITS(size) - 1)) - 1) << 1) + 1)
# define BIT_MASK(size) ((1 << NUM_BITS(size))-1)
#else
# define BIT_MASK(size) ((1LL << NUM_BITS(size))-1)
#endif
/* This macro CHANGES the first parameter IN PLACE. For proper sign handling, /* This macro CHANGES the first parameter IN PLACE. For proper sign handling,
we must first shift left, then right. 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. */ /* 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) ? \ (NUM_BITS(size) ? \
( ( x & ~(BIT_MASK(size) << LOW_BIT(size)) ) | ( (v & BIT_MASK(size)) << LOW_BIT(size) ) ) \ ( ( (type)x & ~(BIT_MASK(type, size) << LOW_BIT(size)) ) | ( ((type)v & BIT_MASK(type, size)) << LOW_BIT(size) ) ) \
: v) : (type)v)
/* byte swapping macros */ /* byte swapping macros */
#define SWAP_2(v) \ #define SWAP_2(v) \
@ -523,7 +519,7 @@ b_set(void *ptr, PyObject *value, Py_ssize_t size)
long val; long val;
if (get_long(value, &val) < 0) if (get_long(value, &val) < 0)
return NULL; 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); _RET(value);
} }
@ -542,8 +538,7 @@ B_set(void *ptr, PyObject *value, Py_ssize_t size)
unsigned long val; unsigned long val;
if (get_ulong(value, &val) < 0) if (get_ulong(value, &val) < 0)
return NULL; return NULL;
*(unsigned char *)ptr = (unsigned char)SET(*(unsigned char*)ptr, *(unsigned char *)ptr = SET(unsigned char, *(unsigned char*)ptr, val, size);
(unsigned short)val, size);
_RET(value); _RET(value);
} }
@ -564,7 +559,7 @@ h_set(void *ptr, PyObject *value, Py_ssize_t size)
if (get_long(value, &val) < 0) if (get_long(value, &val) < 0)
return NULL; return NULL;
memcpy(&x, ptr, sizeof(x)); memcpy(&x, ptr, sizeof(x));
x = SET(x, (short)val, size); x = SET(short, x, val, size);
memcpy(ptr, &x, sizeof(x)); memcpy(ptr, &x, sizeof(x));
_RET(value); _RET(value);
} }
@ -579,7 +574,7 @@ h_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
return NULL; return NULL;
memcpy(&field, ptr, sizeof(field)); memcpy(&field, ptr, sizeof(field));
field = SWAP_2(field); field = SWAP_2(field);
field = SET(field, (short)val, size); field = SET(short, field, val, size);
field = SWAP_2(field); field = SWAP_2(field);
memcpy(ptr, &field, sizeof(field)); memcpy(ptr, &field, sizeof(field));
_RET(value); _RET(value);
@ -612,7 +607,7 @@ H_set(void *ptr, PyObject *value, Py_ssize_t size)
if (get_ulong(value, &val) < 0) if (get_ulong(value, &val) < 0)
return NULL; return NULL;
memcpy(&x, ptr, sizeof(x)); memcpy(&x, ptr, sizeof(x));
x = SET(x, (unsigned short)val, size); x = SET(unsigned short, x, val, size);
memcpy(ptr, &x, sizeof(x)); memcpy(ptr, &x, sizeof(x));
_RET(value); _RET(value);
} }
@ -626,7 +621,7 @@ H_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
return NULL; return NULL;
memcpy(&field, ptr, sizeof(field)); memcpy(&field, ptr, sizeof(field));
field = SWAP_2(field); field = SWAP_2(field);
field = SET(field, (unsigned short)val, size); field = SET(unsigned short, field, val, size);
field = SWAP_2(field); field = SWAP_2(field);
memcpy(ptr, &field, sizeof(field)); memcpy(ptr, &field, sizeof(field));
_RET(value); _RET(value);
@ -660,7 +655,7 @@ i_set(void *ptr, PyObject *value, Py_ssize_t size)
if (get_long(value, &val) < 0) if (get_long(value, &val) < 0)
return NULL; return NULL;
memcpy(&x, ptr, sizeof(x)); memcpy(&x, ptr, sizeof(x));
x = SET(x, (int)val, size); x = SET(int, x, val, size);
memcpy(ptr, &x, sizeof(x)); memcpy(ptr, &x, sizeof(x));
_RET(value); _RET(value);
} }
@ -674,7 +669,7 @@ i_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
return NULL; return NULL;
memcpy(&field, ptr, sizeof(field)); memcpy(&field, ptr, sizeof(field));
field = SWAP_INT(field); field = SWAP_INT(field);
field = SET(field, (int)val, size); field = SET(int, field, val, size);
field = SWAP_INT(field); field = SWAP_INT(field);
memcpy(ptr, &field, sizeof(field)); memcpy(ptr, &field, sizeof(field));
_RET(value); _RET(value);
@ -761,7 +756,7 @@ I_set(void *ptr, PyObject *value, Py_ssize_t size)
if (get_ulong(value, &val) < 0) if (get_ulong(value, &val) < 0)
return NULL; return NULL;
memcpy(&x, ptr, sizeof(x)); memcpy(&x, ptr, sizeof(x));
x = SET(x, (unsigned int)val, size); x = SET(unsigned int, x, val, size);
memcpy(ptr, &x, sizeof(x)); memcpy(ptr, &x, sizeof(x));
_RET(value); _RET(value);
} }
@ -774,7 +769,7 @@ I_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
if (get_ulong(value, &val) < 0) if (get_ulong(value, &val) < 0)
return NULL; return NULL;
memcpy(&field, ptr, sizeof(field)); 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); field = SWAP_INT(field);
memcpy(ptr, &field, sizeof(field)); memcpy(ptr, &field, sizeof(field));
_RET(value); _RET(value);
@ -808,7 +803,7 @@ l_set(void *ptr, PyObject *value, Py_ssize_t size)
if (get_long(value, &val) < 0) if (get_long(value, &val) < 0)
return NULL; return NULL;
memcpy(&x, ptr, sizeof(x)); memcpy(&x, ptr, sizeof(x));
x = SET(x, val, size); x = SET(long, x, val, size);
memcpy(ptr, &x, sizeof(x)); memcpy(ptr, &x, sizeof(x));
_RET(value); _RET(value);
} }
@ -822,7 +817,7 @@ l_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
return NULL; return NULL;
memcpy(&field, ptr, sizeof(field)); memcpy(&field, ptr, sizeof(field));
field = SWAP_LONG(field); field = SWAP_LONG(field);
field = (long)SET(field, val, size); field = SET(long, field, val, size);
field = SWAP_LONG(field); field = SWAP_LONG(field);
memcpy(ptr, &field, sizeof(field)); memcpy(ptr, &field, sizeof(field));
_RET(value); _RET(value);
@ -856,7 +851,7 @@ L_set(void *ptr, PyObject *value, Py_ssize_t size)
if (get_ulong(value, &val) < 0) if (get_ulong(value, &val) < 0)
return NULL; return NULL;
memcpy(&x, ptr, sizeof(x)); memcpy(&x, ptr, sizeof(x));
x = SET(x, val, size); x = SET(unsigned long, x, val, size);
memcpy(ptr, &x, sizeof(x)); memcpy(ptr, &x, sizeof(x));
_RET(value); _RET(value);
} }
@ -870,7 +865,7 @@ L_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
return NULL; return NULL;
memcpy(&field, ptr, sizeof(field)); memcpy(&field, ptr, sizeof(field));
field = SWAP_LONG(field); field = SWAP_LONG(field);
field = (unsigned long)SET(field, val, size); field = SET(unsigned long, field, val, size);
field = SWAP_LONG(field); field = SWAP_LONG(field);
memcpy(ptr, &field, sizeof(field)); memcpy(ptr, &field, sizeof(field));
_RET(value); _RET(value);
@ -905,7 +900,7 @@ q_set(void *ptr, PyObject *value, Py_ssize_t size)
if (get_longlong(value, &val) < 0) if (get_longlong(value, &val) < 0)
return NULL; return NULL;
memcpy(&x, ptr, sizeof(x)); memcpy(&x, ptr, sizeof(x));
x = SET(x, val, size); x = SET(PY_LONG_LONG, x, val, size);
memcpy(ptr, &x, sizeof(x)); memcpy(ptr, &x, sizeof(x));
_RET(value); _RET(value);
} }
@ -919,7 +914,7 @@ q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
return NULL; return NULL;
memcpy(&field, ptr, sizeof(field)); memcpy(&field, ptr, sizeof(field));
field = SWAP_8(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); field = SWAP_8(field);
memcpy(ptr, &field, sizeof(field)); memcpy(ptr, &field, sizeof(field));
_RET(value); _RET(value);
@ -952,7 +947,7 @@ Q_set(void *ptr, PyObject *value, Py_ssize_t size)
if (get_ulonglong(value, &val) < 0) if (get_ulonglong(value, &val) < 0)
return NULL; return NULL;
memcpy(&x, ptr, sizeof(x)); memcpy(&x, ptr, sizeof(x));
x = SET(x, val, size); x = SET(PY_LONG_LONG, x, val, size);
memcpy(ptr, &x, sizeof(x)); memcpy(ptr, &x, sizeof(x));
_RET(value); _RET(value);
} }
@ -966,7 +961,7 @@ Q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
return NULL; return NULL;
memcpy(&field, ptr, sizeof(field)); memcpy(&field, ptr, sizeof(field));
field = SWAP_8(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); field = SWAP_8(field);
memcpy(ptr, &field, sizeof(field)); memcpy(ptr, &field, sizeof(field));
_RET(value); _RET(value);

View File

@ -2564,7 +2564,7 @@ PyUnicode_DecodeUTF16Stateful(const char *s,
} }
/* UTF-16 code pair: */ /* UTF-16 code pair: */
if (q >= e) { if (e - q < 2) {
errmsg = "unexpected end of data"; errmsg = "unexpected end of data";
startinpos = (((const char *)q)-2)-starts; startinpos = (((const char *)q)-2)-starts;
endinpos = ((const char *)e)-starts; endinpos = ((const char *)e)-starts;

View File

@ -53,8 +53,12 @@ builtin___import__(PyObject *self, PyObject *args, PyObject *kwds)
PyDoc_STRVAR(import_doc, PyDoc_STRVAR(import_doc,
"__import__(name, globals={}, locals={}, fromlist=[], level=-1) -> module\n\ "__import__(name, globals={}, locals={}, fromlist=[], level=-1) -> module\n\
\n\ \n\
Import a module. The globals are only used to determine the context;\n\ Import a module. Because this function is meant for use by the Python\n\
they are not modified. The locals are currently unused. The fromlist\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\ should be a list of names to emulate ``from name import ...'', or an\n\
empty list to emulate ``import name''.\n\ empty list to emulate ``import name''.\n\
When importing a module from a package, note that __import__('A.B', ...)\n\ When importing a module from a package, note that __import__('A.B', ...)\n\

View File

@ -359,14 +359,31 @@ each key.
static PyObject * static PyObject *
dictbytype(PyObject *src, int scope_type, int flag, int offset) 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 *k, *v, *dest = PyDict_New();
PyObject *sorted_keys;
assert(offset >= 0); assert(offset >= 0);
if (dest == NULL) if (dest == NULL)
return 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 */ /* XXX this should probably be a macro in symtable.h */
assert(PyInt_Check(v)); assert(PyInt_Check(v));
scope = (PyInt_AS_LONG(v) >> SCOPE_OFF) & SCOPE_MASK; 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) { if (scope == scope_type || PyInt_AS_LONG(v) & flag) {
PyObject *tuple, *item = PyInt_FromLong(i); PyObject *tuple, *item = PyInt_FromLong(i);
if (item == NULL) { if (item == NULL) {
Py_DECREF(sorted_keys);
Py_DECREF(dest); Py_DECREF(dest);
return NULL; return NULL;
} }
i++; i++;
tuple = PyTuple_Pack(2, k, k->ob_type); tuple = PyTuple_Pack(2, k, k->ob_type);
if (!tuple || PyDict_SetItem(dest, tuple, item) < 0) { if (!tuple || PyDict_SetItem(dest, tuple, item) < 0) {
Py_DECREF(sorted_keys);
Py_DECREF(item); Py_DECREF(item);
Py_DECREF(dest); Py_DECREF(dest);
Py_XDECREF(tuple); Py_XDECREF(tuple);
@ -389,6 +408,7 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset)
Py_DECREF(tuple); Py_DECREF(tuple);
} }
} }
Py_DECREF(sorted_keys);
return dest; return dest;
} }

View File

@ -532,8 +532,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
tgt = GETJUMPTGT(codestr, i); tgt = GETJUMPTGT(codestr, i);
j = codestr[tgt]; j = codestr[tgt];
if (CONDITIONAL_JUMP(j)) { if (CONDITIONAL_JUMP(j)) {
/* NOTE: all possible jumps here are /* NOTE: all possible jumps here are absolute! */
absolute! */
if (JUMPS_ON_TRUE(j) == JUMPS_ON_TRUE(opcode)) { if (JUMPS_ON_TRUE(j) == JUMPS_ON_TRUE(opcode)) {
/* The second jump will be /* The second jump will be
taken iff the first is. */ taken iff the first is. */
@ -544,13 +543,10 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
SETARG(codestr, i, tgttgt); SETARG(codestr, i, tgttgt);
goto reoptimize_current; goto reoptimize_current;
} else { } else {
/* The second jump is not taken /* The second jump is not taken if the first is (so
if the first is (so jump past jump past it), and all conditional jumps pop their
it), and all conditional argument when they're not taken (so change the
jumps pop their argument when first jump to pop its argument when it's taken). */
they're not taken (so change
the first jump to pop its
argument when it's taken). */
if (JUMPS_ON_TRUE(opcode)) if (JUMPS_ON_TRUE(opcode))
codestr[i] = POP_JUMP_IF_TRUE; codestr[i] = POP_JUMP_IF_TRUE;
else else