merge heads
This commit is contained in:
commit
ea2ce47958
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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`.
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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('/'):
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
14
Misc/NEWS
14
Misc/NEWS
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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\
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue