merge 2.7.11 branch
diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst
index 9f778f5..217cdc0 100644
--- a/Doc/library/logging.rst
+++ b/Doc/library/logging.rst
@@ -622,7 +622,9 @@
| Attribute name | Format | Description |
+================+=========================+===============================================+
| args | You shouldn't need to | The tuple of arguments merged into ``msg`` to |
-| | format this yourself. | produce ``message``. |
+| | format this yourself. | produce ``message``, or a dict whose values |
+| | | are used for the merge (when there is only one|
+| | | argument, and it is a dictionary). |
+----------------+-------------------------+-----------------------------------------------+
| asctime | ``%(asctime)s`` | Human-readable time when the |
| | | :class:`LogRecord` was created. By default |
diff --git a/Lib/_strptime.py b/Lib/_strptime.py
index 1bd570d..63dca02 100644
--- a/Lib/_strptime.py
+++ b/Lib/_strptime.py
@@ -75,6 +75,8 @@
self.__calc_date_time()
if _getlang() != self.lang:
raise ValueError("locale changed during initialization")
+ if time.tzname != self.tzname or time.daylight != self.daylight:
+ raise ValueError("timezone changed during initialization")
def __pad(self, seq, front):
# Add '' to seq to either the front (is True), else the back.
@@ -159,15 +161,17 @@
def __calc_timezone(self):
# Set self.timezone by using time.tzname.
- # Do not worry about possibility of time.tzname[0] == timetzname[1]
- # and time.daylight; handle that in strptime .
+ # Do not worry about possibility of time.tzname[0] == time.tzname[1]
+ # and time.daylight; handle that in strptime.
try:
time.tzset()
except AttributeError:
pass
- no_saving = frozenset(["utc", "gmt", time.tzname[0].lower()])
- if time.daylight:
- has_saving = frozenset([time.tzname[1].lower()])
+ self.tzname = time.tzname
+ self.daylight = time.daylight
+ no_saving = frozenset(["utc", "gmt", self.tzname[0].lower()])
+ if self.daylight:
+ has_saving = frozenset([self.tzname[1].lower()])
else:
has_saving = frozenset()
self.timezone = (no_saving, has_saving)
@@ -296,12 +300,15 @@
"""Return a time struct based on the input string and the format string."""
global _TimeRE_cache, _regex_cache
with _cache_lock:
- if _getlang() != _TimeRE_cache.locale_time.lang:
+ locale_time = _TimeRE_cache.locale_time
+ if (_getlang() != locale_time.lang or
+ time.tzname != locale_time.tzname or
+ time.daylight != locale_time.daylight):
_TimeRE_cache = TimeRE()
_regex_cache.clear()
+ locale_time = _TimeRE_cache.locale_time
if len(_regex_cache) > _CACHE_MAX_SIZE:
_regex_cache.clear()
- locale_time = _TimeRE_cache.locale_time
format_regex = _regex_cache.get(format)
if not format_regex:
try:
diff --git a/Lib/collections.py b/Lib/collections.py
index 1dcd233..7ecfd46 100644
--- a/Lib/collections.py
+++ b/Lib/collections.py
@@ -1,3 +1,15 @@
+'''This module implements specialized container datatypes providing
+alternatives to Python's general purpose built-in containers, dict,
+list, set, and tuple.
+
+* namedtuple factory function for creating tuple subclasses with named fields
+* deque list-like container with fast appends and pops on either end
+* Counter dict subclass for counting hashable objects
+* OrderedDict dict subclass that remembers the order entries were added
+* defaultdict dict subclass that calls a factory function to supply missing values
+
+'''
+
__all__ = ['Counter', 'deque', 'defaultdict', 'namedtuple', 'OrderedDict']
# For bootstrapping reasons, the collection ABCs are defined in _abcoll.py.
# They should however be considered an integral part of collections.py.
diff --git a/Lib/copy.py b/Lib/copy.py
index c227a2e..daf81a3 100644
--- a/Lib/copy.py
+++ b/Lib/copy.py
@@ -315,7 +315,7 @@
if n > 2:
state = info[2]
else:
- state = {}
+ state = None
if n > 3:
listiter = info[3]
else:
@@ -329,7 +329,7 @@
y = callable(*args)
memo[id(x)] = y
- if state:
+ if state is not None:
if deep:
state = deepcopy(state, memo)
if hasattr(y, '__setstate__'):
diff --git a/Lib/ctypes/test/test_values.py b/Lib/ctypes/test/test_values.py
index 14d69fe..fe7dcf0 100644
--- a/Lib/ctypes/test/test_values.py
+++ b/Lib/ctypes/test/test_values.py
@@ -22,8 +22,7 @@
ctdll = CDLL(_ctypes_test.__file__)
self.assertRaises(ValueError, c_int.in_dll, ctdll, "Undefined_Symbol")
-@unittest.skipUnless(sys.platform == 'win32', 'Windows-specific test')
-class Win_ValuesTestCase(unittest.TestCase):
+class PythonValuesTestCase(unittest.TestCase):
"""This test only works when python itself is a dll/shared library"""
def test_optimizeflag(self):
diff --git a/Lib/locale.py b/Lib/locale.py
index 15c53ba..f547bab 100644
--- a/Lib/locale.py
+++ b/Lib/locale.py
@@ -18,6 +18,10 @@
import operator
import functools
+# keep a copy of the builtin str type, because 'str' name is overriden
+# in globals by a function below
+_str = str
+
try:
_unicode = unicode
except NameError:
@@ -573,7 +577,7 @@
category may be given as one of the LC_* values.
"""
- if locale and type(locale) is not type(""):
+ if locale and not isinstance(locale, (_str, _unicode)):
# convert to string
locale = normalize(_build_localename(locale))
return _setlocale(category, locale)
diff --git a/Lib/rlcompleter.py b/Lib/rlcompleter.py
index 73f8d80..7f61c67 100644
--- a/Lib/rlcompleter.py
+++ b/Lib/rlcompleter.py
@@ -102,13 +102,16 @@
"""
import keyword
matches = []
+ seen = {"__builtins__"}
n = len(text)
for word in keyword.kwlist:
if word[:n] == text:
+ seen.add(word)
matches.append(word)
- for nspace in [__builtin__.__dict__, self.namespace]:
+ for nspace in [self.namespace, __builtin__.__dict__]:
for word, val in nspace.items():
- if word[:n] == text and word != "__builtins__":
+ if word[:n] == text and word not in seen:
+ seen.add(word)
matches.append(self._callable_postfix(val, word))
return matches
diff --git a/Lib/runpy.py b/Lib/runpy.py
index c4d7cc2..ad4d077 100644
--- a/Lib/runpy.py
+++ b/Lib/runpy.py
@@ -97,27 +97,35 @@
return None
# Helper to get the loader, code and filename for a module
-def _get_module_details(mod_name):
- loader = get_loader(mod_name)
- if loader is None:
- raise ImportError("No module named %s" % mod_name)
- if loader.is_package(mod_name):
+def _get_module_details(mod_name, error=ImportError):
+ try:
+ loader = get_loader(mod_name)
+ if loader is None:
+ raise error("No module named %s" % mod_name)
+ ispkg = loader.is_package(mod_name)
+ except ImportError as e:
+ raise error(format(e))
+ if ispkg:
if mod_name == "__main__" or mod_name.endswith(".__main__"):
- raise ImportError("Cannot use package as __main__ module")
+ raise error("Cannot use package as __main__ module")
+ __import__(mod_name) # Do not catch exceptions initializing package
try:
pkg_main_name = mod_name + ".__main__"
return _get_module_details(pkg_main_name)
except ImportError, e:
- raise ImportError(("%s; %r is a package and cannot " +
+ raise error(("%s; %r is a package and cannot " +
"be directly executed") %(e, mod_name))
- code = loader.get_code(mod_name)
+ try:
+ code = loader.get_code(mod_name)
+ except ImportError as e:
+ raise error(format(e))
if code is None:
- raise ImportError("No code object available for %s" % mod_name)
+ raise error("No code object available for %s" % mod_name)
filename = _get_filename(loader, mod_name)
return mod_name, loader, code, filename
-def _get_main_module_details():
+def _get_main_module_details(error=ImportError):
# Helper that gives a nicer error message when attempting to
# execute a zipfile or directory by invoking __main__.py
main_name = "__main__"
@@ -125,10 +133,13 @@
return _get_module_details(main_name)
except ImportError as exc:
if main_name in str(exc):
- raise ImportError("can't find %r module in %r" %
+ raise error("can't find %r module in %r" %
(main_name, sys.path[0]))
raise
+class _Error(Exception):
+ """Error that _run_module_as_main() should report without a traceback"""
+
# This function is the actual implementation of the -m switch and direct
# execution of zipfiles and directories and is deliberately kept private.
# This avoids a repeat of the situation where run_module() no longer met the
@@ -148,11 +159,12 @@
"""
try:
if alter_argv or mod_name != "__main__": # i.e. -m switch
- mod_name, loader, code, fname = _get_module_details(mod_name)
+ mod_name, loader, code, fname = _get_module_details(
+ mod_name, _Error)
else: # i.e. directory or zipfile execution
- mod_name, loader, code, fname = _get_main_module_details()
- except ImportError as exc:
- msg = "%s: %s" % (sys.executable, str(exc))
+ mod_name, loader, code, fname = _get_main_module_details(_Error)
+ except _Error as exc:
+ msg = "%s: %s" % (sys.executable, exc)
sys.exit(msg)
pkg_name = mod_name.rpartition('.')[0]
main_globals = sys.modules["__main__"].__dict__
diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py
index d8346ea..78e5943 100644
--- a/Lib/test/pickletester.py
+++ b/Lib/test/pickletester.py
@@ -6,7 +6,9 @@
import cStringIO
import pickletools
import copy_reg
+import sys
+from test import test_support as support
from test.test_support import TestFailed, verbose, have_unicode, TESTFN
try:
from test.test_support import _2G, _1M, precisionbigmemtest
@@ -473,6 +475,24 @@
self.assertEqual(getattr(obj, slot, None),
getattr(objcopy, slot, None), msg=msg)
+ def check_unpickling_error(self, errors, data):
+ try:
+ try:
+ self.loads(data)
+ except:
+ if support.verbose > 1:
+ exc_type, exc, tb = sys.exc_info()
+ print '%-32r - %s: %s' % (data, exc_type.__name__, exc)
+ raise
+ except errors:
+ pass
+ else:
+ try:
+ exc_name = errors.__name__
+ except AttributeError:
+ exc_name = str(errors)
+ raise self.failureException('%s not raised' % exc_name)
+
def test_load_from_canned_string(self):
expected = self._testdata
for canned in DATA0, DATA1, DATA2:
@@ -480,7 +500,7 @@
self.assert_is_copy(expected, got)
def test_garyp(self):
- self.assertRaises(self.error, self.loads, 'garyp')
+ self.check_unpickling_error(self.error, 'garyp')
def test_maxint64(self):
maxint64 = (1L << 63) - 1
@@ -490,7 +510,7 @@
# Try too with a bogus literal.
data = 'I' + str(maxint64) + 'JUNK\n.'
- self.assertRaises(ValueError, self.loads, data)
+ self.check_unpickling_error(ValueError, data)
def test_insecure_strings(self):
insecure = ["abc", "2 + 2", # not quoted
@@ -511,7 +531,7 @@
]
for s in insecure:
buf = "S" + s + "\n."
- self.assertRaises(ValueError, self.loads, buf)
+ self.check_unpickling_error(ValueError, buf)
def test_correctly_quoted_string(self):
goodpickles = [("S''\n.", ''),
@@ -578,11 +598,6 @@
'q\x00oq\x01}q\x02b.').replace('X', xname)
self.assert_is_copy(X(*args), self.loads(pickle2))
- def test_pop_empty_stack(self):
- # Test issue7455
- s = '0'
- self.assertRaises((cPickle.UnpicklingError, IndexError), self.loads, s)
-
def test_load_str(self):
# From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
self.assertEqual(self.loads("S'a\\x00\\xa0'\n."), 'a\x00\xa0')
@@ -607,8 +622,8 @@
self.assertIs(self.loads('I00\n.'), False)
def test_misc_get(self):
- self.assertRaises(self.error, self.loads, 'g0\np0\n')
- self.assertRaises(self.error, self.loads, 'h\x00q\x00')
+ self.check_unpickling_error(self.error, 'g0\np0\n')
+ self.check_unpickling_error(self.error, 'h\x00q\x00')
def test_get(self):
pickled = '((lp100000\ng100000\nt.'
@@ -634,6 +649,148 @@
self.assertEqual(unpickled, ([],)*2)
self.assertIs(unpickled[0], unpickled[1])
+ def test_bad_stack(self):
+ badpickles = [
+ '.', # STOP
+ '0', # POP
+ '1', # POP_MARK
+ '2', # DUP
+ # '(2', # PyUnpickler doesn't raise
+ 'R', # REDUCE
+ ')R',
+ 'a', # APPEND
+ 'Na',
+ 'b', # BUILD
+ 'Nb',
+ 'd', # DICT
+ 'e', # APPENDS
+ # '(e', # PyUnpickler raises AttributeError
+ 'i__builtin__\nlist\n', # INST
+ 'l', # LIST
+ 'o', # OBJ
+ '(o',
+ 'p1\n', # PUT
+ 'q\x00', # BINPUT
+ 'r\x00\x00\x00\x00', # LONG_BINPUT
+ 's', # SETITEM
+ 'Ns',
+ 'NNs',
+ 't', # TUPLE
+ 'u', # SETITEMS
+ # '(u', # PyUnpickler doesn't raise
+ '}(Nu',
+ '\x81', # NEWOBJ
+ ')\x81',
+ '\x85', # TUPLE1
+ '\x86', # TUPLE2
+ 'N\x86',
+ '\x87', # TUPLE3
+ 'N\x87',
+ 'NN\x87',
+ ]
+ for p in badpickles:
+ self.check_unpickling_error(self.bad_stack_errors, p)
+
+ def test_bad_mark(self):
+ badpickles = [
+ # 'N(.', # STOP
+ 'N(2', # DUP
+ 'c__builtin__\nlist\n)(R', # REDUCE
+ 'c__builtin__\nlist\n()R',
+ ']N(a', # APPEND
+ # BUILD
+ 'c__builtin__\nValueError\n)R}(b',
+ 'c__builtin__\nValueError\n)R(}b',
+ '(Nd', # DICT
+ 'N(p1\n', # PUT
+ 'N(q\x00', # BINPUT
+ 'N(r\x00\x00\x00\x00', # LONG_BINPUT
+ '}NN(s', # SETITEM
+ '}N(Ns',
+ '}(NNs',
+ '}((u', # SETITEMS
+ # NEWOBJ
+ 'c__builtin__\nlist\n)(\x81',
+ 'c__builtin__\nlist\n()\x81',
+ 'N(\x85', # TUPLE1
+ 'NN(\x86', # TUPLE2
+ 'N(N\x86',
+ 'NNN(\x87', # TUPLE3
+ 'NN(N\x87',
+ 'N(NN\x87',
+ ]
+ for p in badpickles:
+ self.check_unpickling_error(self.bad_mark_errors, p)
+
+ def test_truncated_data(self):
+ self.check_unpickling_error(EOFError, '')
+ self.check_unpickling_error(EOFError, 'N')
+ badpickles = [
+ 'F', # FLOAT
+ 'F0.0',
+ 'F0.00',
+ 'G', # BINFLOAT
+ 'G\x00\x00\x00\x00\x00\x00\x00',
+ 'I', # INT
+ 'I0',
+ 'J', # BININT
+ 'J\x00\x00\x00',
+ 'K', # BININT1
+ 'L', # LONG
+ 'L0',
+ 'L10',
+ 'L0L',
+ 'L10L',
+ 'M', # BININT2
+ 'M\x00',
+ # 'P', # PERSID
+ # 'Pabc',
+ 'S', # STRING
+ "S'abc'",
+ 'T', # BINSTRING
+ 'T\x03\x00\x00',
+ 'T\x03\x00\x00\x00',
+ 'T\x03\x00\x00\x00ab',
+ 'U', # SHORT_BINSTRING
+ 'U\x03',
+ 'U\x03ab',
+ 'V', # UNICODE
+ 'Vabc',
+ 'X', # BINUNICODE
+ 'X\x03\x00\x00',
+ 'X\x03\x00\x00\x00',
+ 'X\x03\x00\x00\x00ab',
+ '(c', # GLOBAL
+ '(c__builtin__',
+ '(c__builtin__\n',
+ '(c__builtin__\nlist',
+ 'Ng', # GET
+ 'Ng0',
+ '(i', # INST
+ '(i__builtin__',
+ '(i__builtin__\n',
+ '(i__builtin__\nlist',
+ 'Nh', # BINGET
+ 'Nj', # LONG_BINGET
+ 'Nj\x00\x00\x00',
+ 'Np', # PUT
+ 'Np0',
+ 'Nq', # BINPUT
+ 'Nr', # LONG_BINPUT
+ 'Nr\x00\x00\x00',
+ '\x80', # PROTO
+ '\x82', # EXT1
+ '\x83', # EXT2
+ '\x84\x01',
+ '\x84', # EXT4
+ '\x84\x01\x00\x00',
+ '\x8a', # LONG1
+ '\x8b', # LONG4
+ '\x8b\x00\x00\x00',
+ ]
+ for p in badpickles:
+ self.check_unpickling_error(self.truncated_errors, p)
+
class AbstractPickleTests(unittest.TestCase):
# Subclass must define self.dumps, self.loads.
@@ -1396,11 +1553,7 @@
# Test issue4298
s = '\x58\0\0\0\x54'
self.assertRaises(EOFError, self.module.loads, s)
- # Test issue7455
- s = '0'
- # XXX Why doesn't pickle raise UnpicklingError?
- self.assertRaises((IndexError, cPickle.UnpicklingError),
- self.module.loads, s)
+
class AbstractPersistentPicklerTests(unittest.TestCase):
diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py
index 0007da6..5239d5a 100755
--- a/Lib/test/regrtest.py
+++ b/Lib/test/regrtest.py
@@ -462,7 +462,7 @@
test_times = []
test_support.use_resources = use_resources
- save_modules = sys.modules.keys()
+ save_modules = set(sys.modules.keys())
def accumulate_result(test, result):
ok, test_time = result
diff --git a/Lib/test/script_helper.py b/Lib/test/script_helper.py
index 7f7c70e..6be47bd 100644
--- a/Lib/test/script_helper.py
+++ b/Lib/test/script_helper.py
@@ -134,9 +134,9 @@
# zip_file.close()
return zip_name, os.path.join(zip_name, name_in_zip)
-def make_pkg(pkg_dir):
+def make_pkg(pkg_dir, init_source=''):
os.mkdir(pkg_dir)
- make_script(pkg_dir, '__init__', '')
+ make_script(pkg_dir, '__init__', init_source)
def make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename,
source, depth=1, compiled=False):
diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py
index 8b05227..cefa1e9 100644
--- a/Lib/test/test_cmd_line_script.py
+++ b/Lib/test/test_cmd_line_script.py
@@ -1,5 +1,6 @@
# Tests command line execution of scripts
+import contextlib
import unittest
import os
import os.path
@@ -207,18 +208,69 @@
launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg')
self._check_import_error(launch_name, msg)
+ @contextlib.contextmanager
+ def setup_test_pkg(self, *args):
+ with temp_dir() as script_dir, \
+ test.test_support.change_cwd(script_dir):
+ pkg_dir = os.path.join(script_dir, 'test_pkg')
+ make_pkg(pkg_dir, *args)
+ yield pkg_dir
+
+ def check_dash_m_failure(self, *args):
+ rc, out, err = assert_python_failure('-m', *args)
+ if verbose > 1:
+ print(out)
+ self.assertEqual(rc, 1)
+ return err
+
def test_dash_m_error_code_is_one(self):
# If a module is invoked with the -m command line flag
# and results in an error that the return code to the
# shell is '1'
- with temp_dir() as script_dir:
- pkg_dir = os.path.join(script_dir, 'test_pkg')
- make_pkg(pkg_dir)
+ with self.setup_test_pkg() as pkg_dir:
script_name = _make_test_script(pkg_dir, 'other', "if __name__ == '__main__': raise ValueError")
- rc, out, err = assert_python_failure('-m', 'test_pkg.other', *example_args)
- if verbose > 1:
- print(out)
+ err = self.check_dash_m_failure('test_pkg.other', *example_args)
+ self.assertIn(b'ValueError', err)
+
+ def test_dash_m_errors(self):
+ # Exercise error reporting for various invalid package executions
+ tests = (
+ ('__builtin__', br'No code object available'),
+ ('__builtin__.x', br'No module named'),
+ ('__builtin__.x.y', br'No module named'),
+ ('os.path', br'Loader.*cannot handle'),
+ ('importlib', br'No module named.*'
+ br'is a package and cannot be directly executed'),
+ ('importlib.nonexistant', br'No module named'),
+ )
+ for name, regex in tests:
+ rc, _, err = assert_python_failure('-m', name)
self.assertEqual(rc, 1)
+ self.assertRegexpMatches(err, regex)
+ self.assertNotIn(b'Traceback', err)
+
+ def test_dash_m_init_traceback(self):
+ # These were wrapped in an ImportError and tracebacks were
+ # suppressed; see Issue 14285
+ exceptions = (ImportError, AttributeError, TypeError, ValueError)
+ for exception in exceptions:
+ exception = exception.__name__
+ init = "raise {0}('Exception in __init__.py')".format(exception)
+ with self.setup_test_pkg(init) as pkg_dir:
+ err = self.check_dash_m_failure('test_pkg')
+ self.assertIn(exception.encode('ascii'), err)
+ self.assertIn(b'Exception in __init__.py', err)
+ self.assertIn(b'Traceback', err)
+
+ def test_dash_m_main_traceback(self):
+ # Ensure that an ImportError's traceback is reported
+ with self.setup_test_pkg() as pkg_dir:
+ main = "raise ImportError('Exception in __main__ module')"
+ _make_test_script(pkg_dir, '__main__', main)
+ err = self.check_dash_m_failure('test_pkg')
+ self.assertIn(b'ImportError', err)
+ self.assertIn(b'Exception in __main__ module', err)
+ self.assertIn(b'Traceback', err)
def test_main():
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index 09b5c54..125a68f 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -1,19 +1,24 @@
-
-import unittest, doctest, operator
-import inspect
-from test import test_support
-from collections import namedtuple, Counter, OrderedDict
-from test import mapping_tests
-import pickle, cPickle, copy
-from random import randrange, shuffle
+import collections
+import copy
+import doctest
import keyword
+import operator
+import pickle
+import cPickle
+from random import choice, randrange
import re
+import string
import sys
+from test import test_support
+import unittest
+
+from collections import namedtuple, Counter, OrderedDict
from collections import Hashable, Iterable, Iterator
from collections import Sized, Container, Callable
from collections import Set, MutableSet
from collections import Mapping, MutableMapping
from collections import Sequence, MutableSequence
+
# Silence deprecation warning
sets = test_support.import_module('sets', deprecated=True)
@@ -178,8 +183,7 @@
self.assertEqual(Dot(1)._fields, ('d',))
n = 5000
- import string, random
- names = list(set(''.join([random.choice(string.ascii_letters)
+ names = list(set(''.join([choice(string.ascii_letters)
for j in range(10)]) for i in range(n)))
n = len(names)
Big = namedtuple('Big', names)
@@ -556,7 +560,7 @@
def test_issue_4920(self):
# MutableSet.pop() method did not work
- class MySet(collections.MutableSet):
+ class MySet(MutableSet):
__slots__=['__s']
def __init__(self,items=None):
if items is None:
@@ -802,7 +806,7 @@
self.assertTrue(issubclass(sample, Mapping))
self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
'__getitem__')
- class MyMapping(collections.Mapping):
+ class MyMapping(Mapping):
def __len__(self):
return 0
def __getitem__(self, i):
@@ -1038,290 +1042,11 @@
self.assertRaises(TypeError, Counter().subtract, {}, {})
self.assertRaises(TypeError, Counter.subtract)
-class TestOrderedDict(unittest.TestCase):
-
- def test_init(self):
- with self.assertRaises(TypeError):
- OrderedDict([('a', 1), ('b', 2)], None) # too many args
- pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
- self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs) # dict input
- self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs) # kwds input
- self.assertEqual(list(OrderedDict(pairs).items()), pairs) # pairs input
- self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)],
- c=3, e=5).items()), pairs) # mixed input
-
- # make sure no positional args conflict with possible kwdargs
- self.assertEqual(list(OrderedDict(self=42).items()), [('self', 42)])
- self.assertEqual(list(OrderedDict(other=42).items()), [('other', 42)])
- self.assertRaises(TypeError, OrderedDict, 42)
- self.assertRaises(TypeError, OrderedDict, (), ())
- self.assertRaises(TypeError, OrderedDict.__init__)
-
- # Make sure that direct calls to __init__ do not clear previous contents
- d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
- d.__init__([('e', 5), ('f', 6)], g=7, d=4)
- self.assertEqual(list(d.items()),
- [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
-
- def test_update(self):
- with self.assertRaises(TypeError):
- OrderedDict().update([('a', 1), ('b', 2)], None) # too many args
- pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
- od = OrderedDict()
- od.update(dict(pairs))
- self.assertEqual(sorted(od.items()), pairs) # dict input
- od = OrderedDict()
- od.update(**dict(pairs))
- self.assertEqual(sorted(od.items()), pairs) # kwds input
- od = OrderedDict()
- od.update(pairs)
- self.assertEqual(list(od.items()), pairs) # pairs input
- od = OrderedDict()
- od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5)
- self.assertEqual(list(od.items()), pairs) # mixed input
-
- # Issue 9137: Named argument called 'other' or 'self'
- # shouldn't be treated specially.
- od = OrderedDict()
- od.update(self=23)
- self.assertEqual(list(od.items()), [('self', 23)])
- od = OrderedDict()
- od.update(other={})
- self.assertEqual(list(od.items()), [('other', {})])
- od = OrderedDict()
- od.update(red=5, blue=6, other=7, self=8)
- self.assertEqual(sorted(list(od.items())),
- [('blue', 6), ('other', 7), ('red', 5), ('self', 8)])
-
- # Make sure that direct calls to update do not clear previous contents
- # add that updates items are not moved to the end
- d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
- d.update([('e', 5), ('f', 6)], g=7, d=4)
- self.assertEqual(list(d.items()),
- [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
-
- self.assertRaises(TypeError, OrderedDict().update, 42)
- self.assertRaises(TypeError, OrderedDict().update, (), ())
- self.assertRaises(TypeError, OrderedDict.update)
-
- def test_abc(self):
- self.assertIsInstance(OrderedDict(), MutableMapping)
- self.assertTrue(issubclass(OrderedDict, MutableMapping))
-
- def test_clear(self):
- pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
- shuffle(pairs)
- od = OrderedDict(pairs)
- self.assertEqual(len(od), len(pairs))
- od.clear()
- self.assertEqual(len(od), 0)
-
- def test_delitem(self):
- pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
- od = OrderedDict(pairs)
- del od['a']
- self.assertNotIn('a', od)
- with self.assertRaises(KeyError):
- del od['a']
- self.assertEqual(list(od.items()), pairs[:2] + pairs[3:])
-
- def test_setitem(self):
- od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)])
- od['c'] = 10 # existing element
- od['f'] = 20 # new element
- self.assertEqual(list(od.items()),
- [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)])
-
- def test_iterators(self):
- pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
- shuffle(pairs)
- od = OrderedDict(pairs)
- self.assertEqual(list(od), [t[0] for t in pairs])
- self.assertEqual(od.keys()[:], [t[0] for t in pairs])
- self.assertEqual(od.values()[:], [t[1] for t in pairs])
- self.assertEqual(od.items()[:], pairs)
- self.assertEqual(list(od.iterkeys()), [t[0] for t in pairs])
- self.assertEqual(list(od.itervalues()), [t[1] for t in pairs])
- self.assertEqual(list(od.iteritems()), pairs)
- self.assertEqual(list(reversed(od)),
- [t[0] for t in reversed(pairs)])
-
- def test_popitem(self):
- pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
- shuffle(pairs)
- od = OrderedDict(pairs)
- while pairs:
- self.assertEqual(od.popitem(), pairs.pop())
- with self.assertRaises(KeyError):
- od.popitem()
- self.assertEqual(len(od), 0)
-
- def test_pop(self):
- pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
- shuffle(pairs)
- od = OrderedDict(pairs)
- shuffle(pairs)
- while pairs:
- k, v = pairs.pop()
- self.assertEqual(od.pop(k), v)
- with self.assertRaises(KeyError):
- od.pop('xyz')
- self.assertEqual(len(od), 0)
- self.assertEqual(od.pop(k, 12345), 12345)
-
- # make sure pop still works when __missing__ is defined
- class Missing(OrderedDict):
- def __missing__(self, key):
- return 0
- m = Missing(a=1)
- self.assertEqual(m.pop('b', 5), 5)
- self.assertEqual(m.pop('a', 6), 1)
- self.assertEqual(m.pop('a', 6), 6)
- with self.assertRaises(KeyError):
- m.pop('a')
-
- def test_equality(self):
- pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
- shuffle(pairs)
- od1 = OrderedDict(pairs)
- od2 = OrderedDict(pairs)
- self.assertEqual(od1, od2) # same order implies equality
- pairs = pairs[2:] + pairs[:2]
- od2 = OrderedDict(pairs)
- self.assertNotEqual(od1, od2) # different order implies inequality
- # comparison to regular dict is not order sensitive
- self.assertEqual(od1, dict(od2))
- self.assertEqual(dict(od2), od1)
- # different length implied inequality
- self.assertNotEqual(od1, OrderedDict(pairs[:-1]))
-
- def test_copying(self):
- # Check that ordered dicts are copyable, deepcopyable, picklable,
- # and have a repr/eval round-trip
- pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
- od = OrderedDict(pairs)
- update_test = OrderedDict()
- update_test.update(od)
- for i, dup in enumerate([
- od.copy(),
- copy.copy(od),
- copy.deepcopy(od),
- pickle.loads(pickle.dumps(od, 0)),
- pickle.loads(pickle.dumps(od, 1)),
- pickle.loads(pickle.dumps(od, 2)),
- pickle.loads(pickle.dumps(od, -1)),
- eval(repr(od)),
- update_test,
- OrderedDict(od),
- ]):
- self.assertTrue(dup is not od)
- self.assertEqual(dup, od)
- self.assertEqual(list(dup.items()), list(od.items()))
- self.assertEqual(len(dup), len(od))
- self.assertEqual(type(dup), type(od))
-
- def test_yaml_linkage(self):
- # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature.
- # In yaml, lists are native but tuples are not.
- pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
- od = OrderedDict(pairs)
- # yaml.dump(od) -->
- # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n'
- self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1]))
-
- def test_reduce_not_too_fat(self):
- # do not save instance dictionary if not needed
- pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
- od = OrderedDict(pairs)
- self.assertEqual(len(od.__reduce__()), 2)
- od.x = 10
- self.assertEqual(len(od.__reduce__()), 3)
-
- def test_repr(self):
- od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])
- self.assertEqual(repr(od),
- "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])")
- self.assertEqual(eval(repr(od)), od)
- self.assertEqual(repr(OrderedDict()), "OrderedDict()")
-
- def test_repr_recursive(self):
- # See issue #9826
- od = OrderedDict.fromkeys('abc')
- od['x'] = od
- self.assertEqual(repr(od),
- "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])")
-
- def test_setdefault(self):
- pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
- shuffle(pairs)
- od = OrderedDict(pairs)
- pair_order = list(od.items())
- self.assertEqual(od.setdefault('a', 10), 3)
- # make sure order didn't change
- self.assertEqual(list(od.items()), pair_order)
- self.assertEqual(od.setdefault('x', 10), 10)
- # make sure 'x' is added to the end
- self.assertEqual(list(od.items())[-1], ('x', 10))
-
- # make sure setdefault still works when __missing__ is defined
- class Missing(OrderedDict):
- def __missing__(self, key):
- return 0
- self.assertEqual(Missing().setdefault(5, 9), 9)
-
- def test_reinsert(self):
- # Given insert a, insert b, delete a, re-insert a,
- # verify that a is now later than b.
- od = OrderedDict()
- od['a'] = 1
- od['b'] = 2
- del od['a']
- od['a'] = 1
- self.assertEqual(list(od.items()), [('b', 2), ('a', 1)])
-
- def test_views(self):
- s = 'the quick brown fox jumped over a lazy dog yesterday before dawn'.split()
- od = OrderedDict.fromkeys(s)
- self.assertEqual(list(od.viewkeys()), s)
- self.assertEqual(list(od.viewvalues()), [None for k in s])
- self.assertEqual(list(od.viewitems()), [(k, None) for k in s])
-
- # See http://bugs.python.org/issue24286
- self.assertEqual(od.viewkeys(), dict(od).viewkeys())
- self.assertEqual(od.viewitems(), dict(od).viewitems())
-
- def test_override_update(self):
- # Verify that subclasses can override update() without breaking __init__()
- class MyOD(OrderedDict):
- def update(self, *args, **kwds):
- raise Exception()
- items = [('a', 1), ('c', 3), ('b', 2)]
- self.assertEqual(list(MyOD(items).items()), items)
-
-class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
- type2test = OrderedDict
-
- def test_popitem(self):
- d = self._empty_mapping()
- self.assertRaises(KeyError, d.popitem)
-
-class MyOrderedDict(OrderedDict):
- pass
-
-class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
- type2test = MyOrderedDict
-
- def test_popitem(self):
- d = self._empty_mapping()
- self.assertRaises(KeyError, d.popitem)
-
-import collections
def test_main(verbose=None):
NamedTupleDocs = doctest.DocTestSuite(module=collections)
test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
- TestCollectionABCs, TestCounter,
- TestOrderedDict, GeneralMappingTests, SubclassMappingTests]
+ TestCollectionABCs, TestCounter]
test_support.run_unittest(*test_classes)
test_support.run_doctest(collections, verbose)
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index 6a6ef0e..c9f2835 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -576,14 +576,15 @@
# objects are accepted, which could be not terminated.
with self.assertRaisesRegexp(TypeError, "without null bytes"):
compile(u"123\x00", "<dummy>", "eval")
- with self.assertRaisesRegexp(TypeError, "without null bytes"):
- compile(buffer("123\x00"), "<dummy>", "eval")
- code = compile(buffer("123\x00", 1, 2), "<dummy>", "eval")
- self.assertEqual(eval(code), 23)
- code = compile(buffer("1234", 1, 2), "<dummy>", "eval")
- self.assertEqual(eval(code), 23)
- code = compile(buffer("$23$", 1, 2), "<dummy>", "eval")
- self.assertEqual(eval(code), 23)
+ with test_support.check_py3k_warnings():
+ with self.assertRaisesRegexp(TypeError, "without null bytes"):
+ compile(buffer("123\x00"), "<dummy>", "eval")
+ code = compile(buffer("123\x00", 1, 2), "<dummy>", "eval")
+ self.assertEqual(eval(code), 23)
+ code = compile(buffer("1234", 1, 2), "<dummy>", "eval")
+ self.assertEqual(eval(code), 23)
+ code = compile(buffer("$23$", 1, 2), "<dummy>", "eval")
+ self.assertEqual(eval(code), 23)
class TestStackSize(unittest.TestCase):
# These tests check that the computed stack size for a code object
diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py
index 6b64f10..aefc433 100644
--- a/Lib/test/test_copy.py
+++ b/Lib/test/test_copy.py
@@ -165,6 +165,9 @@
return cmp(self.foo, other.foo)
x = C(42)
self.assertEqual(copy.copy(x), x)
+ # State with boolean value is false (issue #25718)
+ x = C(0.0)
+ self.assertEqual(copy.copy(x), x)
# The deepcopy() method
@@ -395,6 +398,12 @@
x = C([42])
y = copy.deepcopy(x)
self.assertEqual(y, x)
+ self.assertIsNot(y, x)
+ self.assertIsNot(y.foo, x.foo)
+ # State with boolean value is false (issue #25718)
+ x = C([])
+ y = copy.deepcopy(x)
+ self.assertEqual(y, x)
self.assertTrue(y is not x)
self.assertTrue(y.foo is not x.foo)
diff --git a/Lib/test/test_cpickle.py b/Lib/test/test_cpickle.py
index 0a1eb43..c9ec788 100644
--- a/Lib/test/test_cpickle.py
+++ b/Lib/test/test_cpickle.py
@@ -51,6 +51,10 @@
error = cPickle.BadPickleGet
module = cPickle
+ bad_stack_errors = (cPickle.UnpicklingError,)
+ bad_mark_errors = (EOFError,)
+ truncated_errors = (cPickle.UnpicklingError, EOFError,
+ AttributeError, ValueError)
class cPickleUnpicklerTests(AbstractUnpickleTests):
@@ -63,6 +67,10 @@
self.close(f)
error = cPickle.BadPickleGet
+ bad_stack_errors = (cPickle.UnpicklingError,)
+ bad_mark_errors = (EOFError,)
+ truncated_errors = (cPickle.UnpicklingError, EOFError,
+ AttributeError, ValueError)
class cStringIOCUnpicklerTests(cStringIOMixin, cPickleUnpicklerTests):
pass
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 25f65c5..0861bcc 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -4763,6 +4763,26 @@
type.mro(tuple)
+class PicklingTests(unittest.TestCase):
+
+ def test_issue24097(self):
+ # Slot name is freed inside __getattr__ and is later used.
+ class S(str): # Not interned
+ pass
+ class A(object):
+ __slotnames__ = [S('spam')]
+ def __getattr__(self, attr):
+ if attr == 'spam':
+ A.__slotnames__[:] = [S('spam')]
+ return 42
+ else:
+ raise AttributeError
+
+ import copy_reg
+ expected = (copy_reg.__newobj__, (A,), ({}, {'spam': 42}), None, None)
+ self.assertEqual(A().__reduce__(2), expected)
+
+
def test_main():
deprecations = [(r'complex divmod\(\), // and % are deprecated$',
DeprecationWarning)]
@@ -4774,7 +4794,8 @@
with test_support.check_warnings(*deprecations):
# Run all local test cases, with PTypesLongInitTest first.
test_support.run_unittest(PTypesLongInitTest, OperatorsTest,
- ClassPropertiesAndMethods, DictProxyTests)
+ ClassPropertiesAndMethods, DictProxyTests,
+ PicklingTests)
if __name__ == "__main__":
test_main()
diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py
index c1e4c13..4a341ed 100644
--- a/Lib/test/test_doctest.py
+++ b/Lib/test/test_doctest.py
@@ -2582,7 +2582,7 @@
>>> fn = tempfile.mktemp()
>>> with open(fn, 'wb') as f:
... f.write('Test:\r\n\r\n >>> x = 1 + 1\r\n\r\nDone.\r\n')
- >>> doctest.testfile(fn, False)
+ >>> doctest.testfile(fn, module_relative=False, verbose=False)
TestResults(failed=0, attempted=1)
>>> os.remove(fn)
@@ -2591,7 +2591,7 @@
>>> fn = tempfile.mktemp()
>>> with open(fn, 'wb') as f:
... f.write('Test:\n\n >>> x = 1 + 1\n\nDone.\n')
- >>> doctest.testfile(fn, False)
+ >>> doctest.testfile(fn, module_relative=False, verbose=False)
TestResults(failed=0, attempted=1)
>>> os.remove(fn)
diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py
index 4224306..c917c1e 100644
--- a/Lib/test/test_float.py
+++ b/Lib/test/test_float.py
@@ -27,6 +27,12 @@
test_dir = os.path.dirname(__file__) or os.curdir
format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt')
+class FloatSubclass(float):
+ pass
+
+class OtherFloatSubclass(float):
+ pass
+
class GeneralFloatCases(unittest.TestCase):
def test_float(self):
@@ -65,7 +71,8 @@
factories += [unicode, CustomUnicode]
for f in factories:
- x = f(" 3.14 ")
+ with test_support.check_py3k_warnings(quiet=True):
+ x = f(" 3.14 ")
msg = 'x has value %s and type %s' % (x, type(x).__name__)
try:
self.assertEqual(float(x), 3.14, msg=msg)
@@ -73,15 +80,17 @@
raise AssertionError('For %s got TypeError: %s' %
(type(x).__name__, err))
errmsg = "could not convert"
- with self.assertRaisesRegexp(ValueError, errmsg, msg=msg):
+ with self.assertRaisesRegexp(ValueError, errmsg, msg=msg), \
+ test_support.check_py3k_warnings(quiet=True):
float(f('A' * 0x10))
def test_float_buffer(self):
- self.assertEqual(float(buffer('12.3', 1, 3)), 2.3)
- self.assertEqual(float(buffer('12.3\x00', 1, 3)), 2.3)
- self.assertEqual(float(buffer('12.3 ', 1, 3)), 2.3)
- self.assertEqual(float(buffer('12.3A', 1, 3)), 2.3)
- self.assertEqual(float(buffer('12.34', 1, 3)), 2.3)
+ with test_support.check_py3k_warnings():
+ self.assertEqual(float(buffer('12.3', 1, 3)), 2.3)
+ self.assertEqual(float(buffer('12.3\x00', 1, 3)), 2.3)
+ self.assertEqual(float(buffer('12.3 ', 1, 3)), 2.3)
+ self.assertEqual(float(buffer('12.3A', 1, 3)), 2.3)
+ self.assertEqual(float(buffer('12.34', 1, 3)), 2.3)
def check_conversion_to_int(self, x):
"""Check that int(x) has the correct value and type, for a float x."""
@@ -200,6 +209,15 @@
return ""
self.assertRaises(TypeError, time.sleep, Foo5())
+ # Issue #24731
+ class F:
+ def __float__(self):
+ return OtherFloatSubclass(42.)
+ self.assertAlmostEqual(float(F()), 42.)
+ self.assertIs(type(float(F())), OtherFloatSubclass)
+ self.assertAlmostEqual(FloatSubclass(F()), 42.)
+ self.assertIs(type(FloatSubclass(F())), FloatSubclass)
+
def test_is_integer(self):
self.assertFalse((1.1).is_integer())
self.assertTrue((1.).is_integer())
diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py
index 2ca6cf2..ea5c0e3 100644
--- a/Lib/test/test_int.py
+++ b/Lib/test/test_int.py
@@ -45,6 +45,9 @@
(unichr(0x200), ValueError),
]
+class IntSubclass(int):
+ pass
+
class IntLongCommonTests(object):
"""Mixin of test cases to share between both test_int and test_long."""
@@ -348,7 +351,8 @@
factories += [unicode, CustomUnicode]
for f in factories:
- x = f('100')
+ with test_support.check_py3k_warnings(quiet=True):
+ x = f('100')
msg = 'x has value %s and type %s' % (x, type(x).__name__)
try:
self.assertEqual(int(x), 100, msg=msg)
@@ -362,15 +366,17 @@
with self.assertRaisesRegexp(TypeError, errmsg, msg=msg):
int(x, 2)
errmsg = 'invalid literal'
- with self.assertRaisesRegexp(ValueError, errmsg, msg=msg):
+ with self.assertRaisesRegexp(ValueError, errmsg, msg=msg), \
+ test_support.check_py3k_warnings(quiet=True):
int(f('A' * 0x10))
def test_int_buffer(self):
- self.assertEqual(int(buffer('123', 1, 2)), 23)
- self.assertEqual(int(buffer('123\x00', 1, 2)), 23)
- self.assertEqual(int(buffer('123 ', 1, 2)), 23)
- self.assertEqual(int(buffer('123A', 1, 2)), 23)
- self.assertEqual(int(buffer('1234', 1, 2)), 23)
+ with test_support.check_py3k_warnings():
+ self.assertEqual(int(buffer('123', 1, 2)), 23)
+ self.assertEqual(int(buffer('123\x00', 1, 2)), 23)
+ self.assertEqual(int(buffer('123 ', 1, 2)), 23)
+ self.assertEqual(int(buffer('123A', 1, 2)), 23)
+ self.assertEqual(int(buffer('1234', 1, 2)), 23)
def test_error_on_string_float_for_x(self):
self.assertRaises(ValueError, int, '1.2')
@@ -477,6 +483,18 @@
self.fail("Failed to raise TypeError with %s" %
((base, trunc_result_base),))
+ class TruncReturnsIntSubclass(base):
+ def __trunc__(self):
+ return True
+ good_int = TruncReturnsIntSubclass()
+ n = int(good_int)
+ self.assertEqual(n, 1)
+ self.assertIs(type(n), bool)
+ n = IntSubclass(good_int)
+ self.assertEqual(n, 1)
+ self.assertIs(type(n), IntSubclass)
+
+
def test_main():
run_unittest(IntTestCases)
diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py
index 719175b..563ddb1 100644
--- a/Lib/test/test_locale.py
+++ b/Lib/test/test_locale.py
@@ -493,6 +493,16 @@
# longer accept unicode strings.
self.assertEqual(locale.normalize(u'en_US'), 'en_US.ISO8859-1')
+ def test_setlocale_unicode(self):
+ oldlocale = locale.getlocale()
+ self.addCleanup(locale.setlocale, locale.LC_CTYPE, oldlocale)
+
+ user_locale = locale.setlocale(locale.LC_CTYPE, '')
+ unicode_locale = user_locale.decode('utf-8')
+
+ user_locale2 = locale.setlocale(locale.LC_CTYPE, unicode_locale)
+ self.assertEqual(user_locale, user_locale2)
+
def test_main():
tests = [
diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py
index ffa4774..b65d24c 100644
--- a/Lib/test/test_long.py
+++ b/Lib/test/test_long.py
@@ -79,6 +79,12 @@
(unichr(0x200), ValueError),
]
+class LongSubclass(long):
+ pass
+
+class OtherLongSubclass(long):
+ pass
+
class LongTest(test_int.IntLongCommonTests, unittest.TestCase):
ntype = long
@@ -539,6 +545,17 @@
self.fail("Failed to raise TypeError with %s" %
((base, trunc_result_base),))
+ class TruncReturnsLongSubclass(base):
+ def __long__(self):
+ return OtherLongSubclass(42L)
+ good_int = TruncReturnsLongSubclass()
+ n = long(good_int)
+ self.assertEqual(n, 42L)
+ self.assertIs(type(n), OtherLongSubclass)
+ n = LongSubclass(good_int)
+ self.assertEqual(n, 42L)
+ self.assertIs(type(n), LongSubclass)
+
def test_misc(self):
# check the extremes in int<->long conversion
diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py
index a962ddc..b6d88d2 100644
--- a/Lib/test/test_minidom.py
+++ b/Lib/test/test_minidom.py
@@ -1,5 +1,6 @@
# test for xml.dom.minidom
+import copy
import pickle
from StringIO import StringIO
from test.test_support import verbose, run_unittest, findfile
@@ -14,7 +15,13 @@
tstfile = findfile("test.xml", subdir="xmltestdata")
-
+sample = ("<?xml version='1.0' encoding='us-ascii'?>\n"
+ "<!DOCTYPE doc PUBLIC 'http://xml.python.org/public'"
+ " 'http://xml.python.org/system' [\n"
+ " <!ELEMENT e EMPTY>\n"
+ " <!ENTITY ent SYSTEM 'http://xml.python.org/entity'>\n"
+ "]><doc attr='value'> text\n"
+ "<?pi sample?> <!-- comment --> <e/> </doc>")
# The tests of DocumentType importing use these helpers to construct
# the documents to work with, since not all DOM builders actually
@@ -1377,52 +1384,54 @@
self.confirm(e.isSameNode(doc.getElementById("w"))
and a2.isId)
+ def assert_recursive_equal(self, doc, doc2):
+ stack = [(doc, doc2)]
+ while stack:
+ n1, n2 = stack.pop()
+ self.assertEqual(n1.nodeType, n2.nodeType)
+ self.assertEqual(len(n1.childNodes), len(n2.childNodes))
+ self.assertEqual(n1.nodeName, n2.nodeName)
+ self.assertFalse(n1.isSameNode(n2))
+ self.assertFalse(n2.isSameNode(n1))
+ if n1.nodeType == Node.DOCUMENT_TYPE_NODE:
+ len(n1.entities)
+ len(n2.entities)
+ len(n1.notations)
+ len(n2.notations)
+ self.assertEqual(len(n1.entities), len(n2.entities))
+ self.assertEqual(len(n1.notations), len(n2.notations))
+ for i in range(len(n1.notations)):
+ # XXX this loop body doesn't seem to be executed?
+ no1 = n1.notations.item(i)
+ no2 = n1.notations.item(i)
+ self.assertEqual(no1.name, no2.name)
+ self.assertEqual(no1.publicId, no2.publicId)
+ self.assertEqual(no1.systemId, no2.systemId)
+ stack.append((no1, no2))
+ for i in range(len(n1.entities)):
+ e1 = n1.entities.item(i)
+ e2 = n2.entities.item(i)
+ self.assertEqual(e1.notationName, e2.notationName)
+ self.assertEqual(e1.publicId, e2.publicId)
+ self.assertEqual(e1.systemId, e2.systemId)
+ stack.append((e1, e2))
+ if n1.nodeType != Node.DOCUMENT_NODE:
+ self.assertTrue(n1.ownerDocument.isSameNode(doc))
+ self.assertTrue(n2.ownerDocument.isSameNode(doc2))
+ for i in range(len(n1.childNodes)):
+ stack.append((n1.childNodes[i], n2.childNodes[i]))
+
def testPickledDocument(self):
- doc = parseString("<?xml version='1.0' encoding='us-ascii'?>\n"
- "<!DOCTYPE doc PUBLIC 'http://xml.python.org/public'"
- " 'http://xml.python.org/system' [\n"
- " <!ELEMENT e EMPTY>\n"
- " <!ENTITY ent SYSTEM 'http://xml.python.org/entity'>\n"
- "]><doc attr='value'> text\n"
- "<?pi sample?> <!-- comment --> <e/> </doc>")
- for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
+ doc = parseString(sample)
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
s = pickle.dumps(doc, proto)
doc2 = pickle.loads(s)
- stack = [(doc, doc2)]
- while stack:
- n1, n2 = stack.pop()
- self.confirm(n1.nodeType == n2.nodeType
- and len(n1.childNodes) == len(n2.childNodes)
- and n1.nodeName == n2.nodeName
- and not n1.isSameNode(n2)
- and not n2.isSameNode(n1))
- if n1.nodeType == Node.DOCUMENT_TYPE_NODE:
- len(n1.entities)
- len(n2.entities)
- len(n1.notations)
- len(n2.notations)
- self.confirm(len(n1.entities) == len(n2.entities)
- and len(n1.notations) == len(n2.notations))
- for i in range(len(n1.notations)):
- # XXX this loop body doesn't seem to be executed?
- no1 = n1.notations.item(i)
- no2 = n1.notations.item(i)
- self.confirm(no1.name == no2.name
- and no1.publicId == no2.publicId
- and no1.systemId == no2.systemId)
- stack.append((no1, no2))
- for i in range(len(n1.entities)):
- e1 = n1.entities.item(i)
- e2 = n2.entities.item(i)
- self.confirm(e1.notationName == e2.notationName
- and e1.publicId == e2.publicId
- and e1.systemId == e2.systemId)
- stack.append((e1, e2))
- if n1.nodeType != Node.DOCUMENT_NODE:
- self.confirm(n1.ownerDocument.isSameNode(doc)
- and n2.ownerDocument.isSameNode(doc2))
- for i in range(len(n1.childNodes)):
- stack.append((n1.childNodes[i], n2.childNodes[i]))
+ self.assert_recursive_equal(doc, doc2)
+
+ def testDeepcopiedDocument(self):
+ doc = parseString(sample)
+ doc2 = copy.deepcopy(doc)
+ self.assert_recursive_equal(doc, doc2)
def testSerializeCommentNodeWithDoubleHyphen(self):
doc = create_doc_without_doctype()
diff --git a/Lib/test/test_ordered_dict.py b/Lib/test/test_ordered_dict.py
new file mode 100644
index 0000000..78b3e83
--- /dev/null
+++ b/Lib/test/test_ordered_dict.py
@@ -0,0 +1,293 @@
+import copy
+import pickle
+from random import shuffle
+import unittest
+from collections import OrderedDict
+from collections import MutableMapping
+from test import mapping_tests, test_support
+
+
+class TestOrderedDict(unittest.TestCase):
+
+ def test_init(self):
+ with self.assertRaises(TypeError):
+ OrderedDict([('a', 1), ('b', 2)], None) # too many args
+ pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
+ self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs) # dict input
+ self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs) # kwds input
+ self.assertEqual(list(OrderedDict(pairs).items()), pairs) # pairs input
+ self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)],
+ c=3, e=5).items()), pairs) # mixed input
+
+ # make sure no positional args conflict with possible kwdargs
+ self.assertEqual(list(OrderedDict(self=42).items()), [('self', 42)])
+ self.assertEqual(list(OrderedDict(other=42).items()), [('other', 42)])
+ self.assertRaises(TypeError, OrderedDict, 42)
+ self.assertRaises(TypeError, OrderedDict, (), ())
+ self.assertRaises(TypeError, OrderedDict.__init__)
+
+ # Make sure that direct calls to __init__ do not clear previous contents
+ d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
+ d.__init__([('e', 5), ('f', 6)], g=7, d=4)
+ self.assertEqual(list(d.items()),
+ [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
+
+ def test_update(self):
+ with self.assertRaises(TypeError):
+ OrderedDict().update([('a', 1), ('b', 2)], None) # too many args
+ pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
+ od = OrderedDict()
+ od.update(dict(pairs))
+ self.assertEqual(sorted(od.items()), pairs) # dict input
+ od = OrderedDict()
+ od.update(**dict(pairs))
+ self.assertEqual(sorted(od.items()), pairs) # kwds input
+ od = OrderedDict()
+ od.update(pairs)
+ self.assertEqual(list(od.items()), pairs) # pairs input
+ od = OrderedDict()
+ od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5)
+ self.assertEqual(list(od.items()), pairs) # mixed input
+
+ # Issue 9137: Named argument called 'other' or 'self'
+ # shouldn't be treated specially.
+ od = OrderedDict()
+ od.update(self=23)
+ self.assertEqual(list(od.items()), [('self', 23)])
+ od = OrderedDict()
+ od.update(other={})
+ self.assertEqual(list(od.items()), [('other', {})])
+ od = OrderedDict()
+ od.update(red=5, blue=6, other=7, self=8)
+ self.assertEqual(sorted(list(od.items())),
+ [('blue', 6), ('other', 7), ('red', 5), ('self', 8)])
+
+ # Make sure that direct calls to update do not clear previous contents
+ # add that updates items are not moved to the end
+ d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
+ d.update([('e', 5), ('f', 6)], g=7, d=4)
+ self.assertEqual(list(d.items()),
+ [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
+
+ self.assertRaises(TypeError, OrderedDict().update, 42)
+ self.assertRaises(TypeError, OrderedDict().update, (), ())
+ self.assertRaises(TypeError, OrderedDict.update)
+
+ def test_abc(self):
+ self.assertIsInstance(OrderedDict(), MutableMapping)
+ self.assertTrue(issubclass(OrderedDict, MutableMapping))
+
+ def test_clear(self):
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ shuffle(pairs)
+ od = OrderedDict(pairs)
+ self.assertEqual(len(od), len(pairs))
+ od.clear()
+ self.assertEqual(len(od), 0)
+
+ def test_delitem(self):
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ od = OrderedDict(pairs)
+ del od['a']
+ self.assertNotIn('a', od)
+ with self.assertRaises(KeyError):
+ del od['a']
+ self.assertEqual(list(od.items()), pairs[:2] + pairs[3:])
+
+ def test_setitem(self):
+ od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)])
+ od['c'] = 10 # existing element
+ od['f'] = 20 # new element
+ self.assertEqual(list(od.items()),
+ [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)])
+
+ def test_iterators(self):
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ shuffle(pairs)
+ od = OrderedDict(pairs)
+ self.assertEqual(list(od), [t[0] for t in pairs])
+ self.assertEqual(od.keys()[:], [t[0] for t in pairs])
+ self.assertEqual(od.values()[:], [t[1] for t in pairs])
+ self.assertEqual(od.items()[:], pairs)
+ self.assertEqual(list(od.iterkeys()), [t[0] for t in pairs])
+ self.assertEqual(list(od.itervalues()), [t[1] for t in pairs])
+ self.assertEqual(list(od.iteritems()), pairs)
+ self.assertEqual(list(reversed(od)),
+ [t[0] for t in reversed(pairs)])
+
+ def test_popitem(self):
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ shuffle(pairs)
+ od = OrderedDict(pairs)
+ while pairs:
+ self.assertEqual(od.popitem(), pairs.pop())
+ with self.assertRaises(KeyError):
+ od.popitem()
+ self.assertEqual(len(od), 0)
+
+ def test_pop(self):
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ shuffle(pairs)
+ od = OrderedDict(pairs)
+ shuffle(pairs)
+ while pairs:
+ k, v = pairs.pop()
+ self.assertEqual(od.pop(k), v)
+ with self.assertRaises(KeyError):
+ od.pop('xyz')
+ self.assertEqual(len(od), 0)
+ self.assertEqual(od.pop(k, 12345), 12345)
+
+ # make sure pop still works when __missing__ is defined
+ class Missing(OrderedDict):
+ def __missing__(self, key):
+ return 0
+ m = Missing(a=1)
+ self.assertEqual(m.pop('b', 5), 5)
+ self.assertEqual(m.pop('a', 6), 1)
+ self.assertEqual(m.pop('a', 6), 6)
+ with self.assertRaises(KeyError):
+ m.pop('a')
+
+ def test_equality(self):
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ shuffle(pairs)
+ od1 = OrderedDict(pairs)
+ od2 = OrderedDict(pairs)
+ self.assertEqual(od1, od2) # same order implies equality
+ pairs = pairs[2:] + pairs[:2]
+ od2 = OrderedDict(pairs)
+ self.assertNotEqual(od1, od2) # different order implies inequality
+ # comparison to regular dict is not order sensitive
+ self.assertEqual(od1, dict(od2))
+ self.assertEqual(dict(od2), od1)
+ # different length implied inequality
+ self.assertNotEqual(od1, OrderedDict(pairs[:-1]))
+
+ def test_copying(self):
+ # Check that ordered dicts are copyable, deepcopyable, picklable,
+ # and have a repr/eval round-trip
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ od = OrderedDict(pairs)
+ update_test = OrderedDict()
+ update_test.update(od)
+ for i, dup in enumerate([
+ od.copy(),
+ copy.copy(od),
+ copy.deepcopy(od),
+ pickle.loads(pickle.dumps(od, 0)),
+ pickle.loads(pickle.dumps(od, 1)),
+ pickle.loads(pickle.dumps(od, 2)),
+ pickle.loads(pickle.dumps(od, -1)),
+ eval(repr(od)),
+ update_test,
+ OrderedDict(od),
+ ]):
+ self.assertTrue(dup is not od)
+ self.assertEqual(dup, od)
+ self.assertEqual(list(dup.items()), list(od.items()))
+ self.assertEqual(len(dup), len(od))
+ self.assertEqual(type(dup), type(od))
+
+ def test_yaml_linkage(self):
+ # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature.
+ # In yaml, lists are native but tuples are not.
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ od = OrderedDict(pairs)
+ # yaml.dump(od) -->
+ # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n'
+ self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1]))
+
+ def test_reduce_not_too_fat(self):
+ # do not save instance dictionary if not needed
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ od = OrderedDict(pairs)
+ self.assertEqual(len(od.__reduce__()), 2)
+ od.x = 10
+ self.assertEqual(len(od.__reduce__()), 3)
+
+ def test_repr(self):
+ od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])
+ self.assertEqual(repr(od),
+ "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])")
+ self.assertEqual(eval(repr(od)), od)
+ self.assertEqual(repr(OrderedDict()), "OrderedDict()")
+
+ def test_repr_recursive(self):
+ # See issue #9826
+ od = OrderedDict.fromkeys('abc')
+ od['x'] = od
+ self.assertEqual(repr(od),
+ "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])")
+
+ def test_setdefault(self):
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ shuffle(pairs)
+ od = OrderedDict(pairs)
+ pair_order = list(od.items())
+ self.assertEqual(od.setdefault('a', 10), 3)
+ # make sure order didn't change
+ self.assertEqual(list(od.items()), pair_order)
+ self.assertEqual(od.setdefault('x', 10), 10)
+ # make sure 'x' is added to the end
+ self.assertEqual(list(od.items())[-1], ('x', 10))
+
+ # make sure setdefault still works when __missing__ is defined
+ class Missing(OrderedDict):
+ def __missing__(self, key):
+ return 0
+ self.assertEqual(Missing().setdefault(5, 9), 9)
+
+ def test_reinsert(self):
+ # Given insert a, insert b, delete a, re-insert a,
+ # verify that a is now later than b.
+ od = OrderedDict()
+ od['a'] = 1
+ od['b'] = 2
+ del od['a']
+ od['a'] = 1
+ self.assertEqual(list(od.items()), [('b', 2), ('a', 1)])
+
+ def test_views(self):
+ s = 'the quick brown fox jumped over a lazy dog yesterday before dawn'.split()
+ od = OrderedDict.fromkeys(s)
+ self.assertEqual(list(od.viewkeys()), s)
+ self.assertEqual(list(od.viewvalues()), [None for k in s])
+ self.assertEqual(list(od.viewitems()), [(k, None) for k in s])
+
+ # See http://bugs.python.org/issue24286
+ self.assertEqual(od.viewkeys(), dict(od).viewkeys())
+ self.assertEqual(od.viewitems(), dict(od).viewitems())
+
+ def test_override_update(self):
+ # Verify that subclasses can override update() without breaking __init__()
+ class MyOD(OrderedDict):
+ def update(self, *args, **kwds):
+ raise Exception()
+ items = [('a', 1), ('c', 3), ('b', 2)]
+ self.assertEqual(list(MyOD(items).items()), items)
+
+class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
+ type2test = OrderedDict
+
+ def test_popitem(self):
+ d = self._empty_mapping()
+ self.assertRaises(KeyError, d.popitem)
+
+class MyOrderedDict(OrderedDict):
+ pass
+
+class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
+ type2test = MyOrderedDict
+
+ def test_popitem(self):
+ d = self._empty_mapping()
+ self.assertRaises(KeyError, d.popitem)
+
+
+def test_main(verbose=None):
+ test_classes = [TestOrderedDict, GeneralMappingTests, SubclassMappingTests]
+ test_support.run_unittest(*test_classes)
+
+if __name__ == "__main__":
+ test_main(verbose=True)
diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py
index 2db7589..bb43656 100644
--- a/Lib/test/test_pickle.py
+++ b/Lib/test/test_pickle.py
@@ -1,4 +1,5 @@
import pickle
+import struct
from cStringIO import StringIO
from test import test_support
@@ -23,17 +24,30 @@
module = pickle
error = KeyError
+ bad_stack_errors = (IndexError,)
+ bad_mark_errors = (IndexError, pickle.UnpicklingError,
+ TypeError, AttributeError, EOFError)
+ truncated_errors = (pickle.UnpicklingError, EOFError,
+ AttributeError, ValueError,
+ struct.error, IndexError, ImportError,
+ TypeError, KeyError)
class UnpicklerTests(AbstractUnpickleTests):
error = KeyError
+ bad_stack_errors = (IndexError,)
+ bad_mark_errors = (IndexError, pickle.UnpicklingError,
+ TypeError, AttributeError, EOFError)
+ truncated_errors = (pickle.UnpicklingError, EOFError,
+ AttributeError, ValueError,
+ struct.error, IndexError, ImportError,
+ TypeError, KeyError)
def loads(self, buf):
f = StringIO(buf)
u = pickle.Unpickler(f)
return u.load()
-
class PicklerTests(AbstractPickleTests):
def dumps(self, arg, proto=0, fast=0):
diff --git a/Lib/test/test_rlcompleter.py b/Lib/test/test_rlcompleter.py
index c969d27..99f0480 100644
--- a/Lib/test/test_rlcompleter.py
+++ b/Lib/test/test_rlcompleter.py
@@ -81,6 +81,27 @@
def test_main():
support.run_unittest(TestRlcompleter)
+ def test_duplicate_globals(self):
+ namespace = {
+ 'False': None, # Keyword vs builtin vs namespace
+ 'assert': None, # Keyword vs namespace
+ 'try': lambda: None, # Keyword vs callable
+ 'memoryview': None, # Callable builtin vs non-callable
+ 'Ellipsis': lambda: None, # Non-callable builtin vs callable
+ }
+ completer = rlcompleter.Completer(namespace)
+ self.assertEqual(completer.complete('False', 0), 'False')
+ self.assertIsNone(completer.complete('False', 1)) # No duplicates
+ self.assertEqual(completer.complete('assert', 0), 'assert')
+ self.assertIsNone(completer.complete('assert', 1))
+ self.assertEqual(completer.complete('try', 0), 'try')
+ self.assertIsNone(completer.complete('try', 1))
+ # No opening bracket "(" because we overrode the built-in class
+ self.assertEqual(completer.complete('memoryview', 0), 'memoryview')
+ self.assertIsNone(completer.complete('memoryview', 1))
+ self.assertEqual(completer.complete('Ellipsis', 0), 'Ellipsis(')
+ self.assertIsNone(completer.complete('Ellipsis', 1))
+
if __name__ == '__main__':
test_main()
diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py
index 76858d5..7f9fefa 100644
--- a/Lib/test/test_runpy.py
+++ b/Lib/test/test_runpy.py
@@ -270,6 +270,30 @@
if verbose: print "Testing package depth:", depth
self._check_package(depth)
+ def test_run_package_init_exceptions(self):
+ # These were previously wrapped in an ImportError; see Issue 14285
+ exceptions = (ImportError, AttributeError, TypeError, ValueError)
+ for exception in exceptions:
+ name = exception.__name__
+ source = "raise {0}('{0} in __init__.py.')".format(name)
+
+ result = self._make_pkg("", 1, "__main__")
+ pkg_dir, _, mod_name = result
+ mod_name = mod_name.replace(".__main__", "")
+ try:
+ init = os.path.join(pkg_dir, "__runpy_pkg__", "__init__.py")
+ with open(init, "wt") as mod_file:
+ mod_file.write(source)
+ try:
+ run_module(mod_name)
+ except exception as err:
+ msg = "cannot be directly executed"
+ self.assertNotIn(msg, format(err))
+ else:
+ self.fail("Nothing raised; expected {}".format(name))
+ finally:
+ self._del_pkg(pkg_dir, 1, mod_name)
+
def test_explicit_relative_import(self):
for depth in range(2, 5):
if verbose: print "Testing relative imports at depth:", depth
diff --git a/Lib/test/test_str.py b/Lib/test/test_str.py
index 774c634..5bb9f48 100644
--- a/Lib/test/test_str.py
+++ b/Lib/test/test_str.py
@@ -4,6 +4,9 @@
from test import test_support, string_tests
+class StrSubclass(str):
+ pass
+
class StrTest(
string_tests.CommonTest,
string_tests.MixinStrUnicodeUserStringTest,
@@ -107,6 +110,9 @@
self.assertEqual(str(Foo6("bar")), "foos")
self.assertEqual(str(Foo7("bar")), "foos")
self.assertEqual(str(Foo8("foo")), "foofoo")
+ self.assertIs(type(str(Foo8("foo"))), Foo8)
+ self.assertEqual(StrSubclass(Foo8("foo")), "foofoo")
+ self.assertIs(type(StrSubclass(Foo8("foo"))), StrSubclass)
self.assertEqual(str(Foo9("foo")), "string")
self.assertEqual(unicode(Foo9("foo")), u"not unicode")
diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py
index 7a47f9e..e309d06 100644
--- a/Lib/test/test_strptime.py
+++ b/Lib/test/test_strptime.py
@@ -4,8 +4,9 @@
import time
import locale
import re
+import os
import sys
-from test import test_support
+from test import test_support as support
from datetime import date as datetime_date
import _strptime
@@ -314,9 +315,10 @@
tz_name = time.tzname[0]
if tz_name.upper() in ("UTC", "GMT"):
self.skipTest('need non-UTC/GMT timezone')
- try:
- original_tzname = time.tzname
- original_daylight = time.daylight
+
+ with support.swap_attr(time, 'tzname', (tz_name, tz_name)), \
+ support.swap_attr(time, 'daylight', 1), \
+ support.swap_attr(time, 'tzset', lambda: None):
time.tzname = (tz_name, tz_name)
time.daylight = 1
tz_value = _strptime._strptime_time(tz_name, "%Z")[8]
@@ -324,9 +326,6 @@
"%s lead to a timezone value of %s instead of -1 when "
"time.daylight set to %s and passing in %s" %
(time.tzname, tz_value, time.daylight, tz_name))
- finally:
- time.tzname = original_tzname
- time.daylight = original_daylight
def test_date_time(self):
# Test %c directive
@@ -538,7 +537,7 @@
_strptime._strptime_time("10", "%d")
self.assertIsNot(locale_time_id, _strptime._TimeRE_cache.locale_time)
- def test_TimeRE_recreation(self):
+ def test_TimeRE_recreation_locale(self):
# The TimeRE instance should be recreated upon changing the locale.
locale_info = locale.getlocale(locale.LC_TIME)
try:
@@ -567,9 +566,36 @@
finally:
locale.setlocale(locale.LC_TIME, locale_info)
+ @support.run_with_tz('STD-1DST')
+ def test_TimeRE_recreation_timezone(self):
+ # The TimeRE instance should be recreated upon changing the timezone.
+ oldtzname = time.tzname
+ tm = _strptime._strptime_time(time.tzname[0], '%Z')
+ self.assertEqual(tm.tm_isdst, 0)
+ tm = _strptime._strptime_time(time.tzname[1], '%Z')
+ self.assertEqual(tm.tm_isdst, 1)
+ # Get id of current cache object.
+ first_time_re = _strptime._TimeRE_cache
+ # Change the timezone and force a recreation of the cache.
+ os.environ['TZ'] = 'EST+05EDT,M3.2.0,M11.1.0'
+ time.tzset()
+ tm = _strptime._strptime_time(time.tzname[0], '%Z')
+ self.assertEqual(tm.tm_isdst, 0)
+ tm = _strptime._strptime_time(time.tzname[1], '%Z')
+ self.assertEqual(tm.tm_isdst, 1)
+ # Get the new cache object's id.
+ second_time_re = _strptime._TimeRE_cache
+ # They should not be equal.
+ self.assertIsNot(first_time_re, second_time_re)
+ # Make sure old names no longer accepted.
+ with self.assertRaises(ValueError):
+ _strptime._strptime_time(oldtzname[0], '%Z')
+ with self.assertRaises(ValueError):
+ _strptime._strptime_time(oldtzname[1], '%Z')
+
def test_main():
- test_support.run_unittest(
+ support.run_unittest(
getlang_Tests,
LocaleTime_Tests,
TimeRETests,
diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py
index 7ce1c73..956936f 100644
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -40,7 +40,7 @@
"threading_cleanup", "reap_threads", "start_threads", "cpython_only",
"check_impl_detail", "get_attribute", "py3k_bytes",
"import_fresh_module", "threading_cleanup", "reap_children",
- "strip_python_stderr", "IPV6_ENABLED"]
+ "strip_python_stderr", "IPV6_ENABLED", "run_with_tz"]
class Error(Exception):
"""Base class for regression test exceptions."""
@@ -1226,6 +1226,39 @@
return decorator
#=======================================================================
+# Decorator for running a function in a specific timezone, correctly
+# resetting it afterwards.
+
+def run_with_tz(tz):
+ def decorator(func):
+ def inner(*args, **kwds):
+ try:
+ tzset = time.tzset
+ except AttributeError:
+ raise unittest.SkipTest("tzset required")
+ if 'TZ' in os.environ:
+ orig_tz = os.environ['TZ']
+ else:
+ orig_tz = None
+ os.environ['TZ'] = tz
+ tzset()
+
+ # now run the function, resetting the tz on exceptions
+ try:
+ return func(*args, **kwds)
+ finally:
+ if orig_tz is None:
+ del os.environ['TZ']
+ else:
+ os.environ['TZ'] = orig_tz
+ time.tzset()
+
+ inner.__name__ = func.__name__
+ inner.__doc__ = func.__doc__
+ return inner
+ return decorator
+
+#=======================================================================
# Big-memory-test support. Separate from 'resources' because memory use should be configurable.
# Some handy shorthands. Note that these are used for byte-limits as well
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index ab35ba4..de13f22 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -412,7 +412,10 @@
def test_43581(self):
# Can't use sys.stdout, as this is a cStringIO object when
# the test runs under regrtest.
- self.assertTrue(sys.__stdout__.encoding == sys.__stderr__.encoding)
+ if not (os.environ.get('PYTHONIOENCODING') or
+ (sys.__stdout__.isatty() and sys.__stderr__.isatty())):
+ self.skipTest('stdout/stderr encoding is not set')
+ self.assertEqual(sys.__stdout__.encoding, sys.__stderr__.encoding)
def test_sys_flags(self):
self.assertTrue(sys.flags)
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
index be8f89b..63fb831 100644
--- a/Lib/test/test_unicode.py
+++ b/Lib/test/test_unicode.py
@@ -33,6 +33,9 @@
return None
codecs.register(search_function)
+class UnicodeSubclass(unicode):
+ pass
+
class UnicodeTest(
string_tests.CommonTest,
string_tests.MixinStrUnicodeUserStringTest,
@@ -685,9 +688,6 @@
u'unicode remains unicode'
)
- class UnicodeSubclass(unicode):
- pass
-
self.assertEqual(
unicode(UnicodeSubclass('unicode subclass becomes unicode')),
u'unicode subclass becomes unicode'
@@ -1037,10 +1037,12 @@
self.assertEqual(unicode('Andr\202 x','ascii','ignore'), u"Andr x")
self.assertEqual(unicode('Andr\202 x','ascii','replace'), u'Andr\uFFFD x')
self.assertEqual(unicode('\202 x', 'ascii', 'replace'), u'\uFFFD x')
- self.assertEqual(u'abcde'.decode('ascii', 'ignore'),
- u'abcde'.decode('ascii', errors='ignore'))
- self.assertEqual(u'abcde'.decode('ascii', 'replace'),
- u'abcde'.decode(encoding='ascii', errors='replace'))
+ with test_support.check_py3k_warnings():
+ self.assertEqual(u'abcde'.decode('ascii', 'ignore'),
+ u'abcde'.decode('ascii', errors='ignore'))
+ with test_support.check_py3k_warnings():
+ self.assertEqual(u'abcde'.decode('ascii', 'replace'),
+ u'abcde'.decode(encoding='ascii', errors='replace'))
# Error handling (unknown character names)
self.assertEqual("\\N{foo}xx".decode("unicode-escape", "ignore"), u"xx")
@@ -1269,6 +1271,9 @@
self.assertEqual(unicode(Foo6("bar")), u"foou")
self.assertEqual(unicode(Foo7("bar")), u"foou")
self.assertEqual(unicode(Foo8("foo")), u"foofoo")
+ self.assertIs(type(unicode(Foo8("foo"))), Foo8)
+ self.assertEqual(UnicodeSubclass(Foo8("foo")), u"foofoo")
+ self.assertIs(type(UnicodeSubclass(Foo8("foo"))), UnicodeSubclass)
self.assertEqual(str(Foo9("foo")), "string")
self.assertEqual(unicode(Foo9("foo")), u"not unicode")
diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py
index 474a4b4..98410c5 100644
--- a/Lib/test/test_xml_etree_c.py
+++ b/Lib/test/test_xml_etree_c.py
@@ -30,6 +30,38 @@
finally:
data = None
+ def test_del_attribute(self):
+ element = cET.Element('tag')
+
+ element.tag = 'TAG'
+ with self.assertRaises(AttributeError):
+ del element.tag
+ self.assertEqual(element.tag, 'TAG')
+
+ with self.assertRaises(AttributeError):
+ del element.text
+ self.assertIsNone(element.text)
+ element.text = 'TEXT'
+ with self.assertRaises(AttributeError):
+ del element.text
+ self.assertEqual(element.text, 'TEXT')
+
+ with self.assertRaises(AttributeError):
+ del element.tail
+ self.assertIsNone(element.tail)
+ element.tail = 'TAIL'
+ with self.assertRaises(AttributeError):
+ del element.tail
+ self.assertEqual(element.tail, 'TAIL')
+
+ with self.assertRaises(AttributeError):
+ del element.attrib
+ self.assertEqual(element.attrib, {})
+ element.attrib = {'A': 'B', 'C': 'D'}
+ with self.assertRaises(AttributeError):
+ del element.attrib
+ self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'})
+
def test_main():
from test import test_xml_etree, test_xml_etree_c
diff --git a/Lib/xml/dom/minicompat.py b/Lib/xml/dom/minicompat.py
index de4cb4f..266a7f4 100644
--- a/Lib/xml/dom/minicompat.py
+++ b/Lib/xml/dom/minicompat.py
@@ -65,10 +65,10 @@
length = property(_get_length, _set_length,
doc="The number of nodes in the NodeList.")
- def __getstate__(self):
- return list(self)
-
+ # For backward compatibility
def __setstate__(self, state):
+ if state is None:
+ state = []
self[:] = state
diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py
index 9f3e75d..c6e3d39 100644
--- a/Lib/xml/etree/ElementTree.py
+++ b/Lib/xml/etree/ElementTree.py
@@ -1198,9 +1198,14 @@
if not hasattr(source, "read"):
source = open(source, "rb")
close_source = True
- if not parser:
- parser = XMLParser(target=TreeBuilder())
- return _IterParseIterator(source, events, parser, close_source)
+ try:
+ if not parser:
+ parser = XMLParser(target=TreeBuilder())
+ return _IterParseIterator(source, events, parser, close_source)
+ except:
+ if close_source:
+ source.close()
+ raise
class _IterParseIterator(object):
@@ -1252,34 +1257,40 @@
raise ValueError("unknown event %r" % event)
def next(self):
- while 1:
- try:
- item = self._events[self._index]
- self._index += 1
- return item
- except IndexError:
- pass
- if self._error:
- e = self._error
- self._error = None
- raise e
- if self._parser is None:
- self.root = self._root
- if self._close_file:
- self._file.close()
- raise StopIteration
- # load event buffer
- del self._events[:]
- self._index = 0
- data = self._file.read(16384)
- if data:
+ try:
+ while 1:
try:
- self._parser.feed(data)
- except SyntaxError as exc:
- self._error = exc
- else:
- self._root = self._parser.close()
- self._parser = None
+ item = self._events[self._index]
+ self._index += 1
+ return item
+ except IndexError:
+ pass
+ if self._error:
+ e = self._error
+ self._error = None
+ raise e
+ if self._parser is None:
+ self.root = self._root
+ break
+ # load event buffer
+ del self._events[:]
+ self._index = 0
+ data = self._file.read(16384)
+ if data:
+ try:
+ self._parser.feed(data)
+ except SyntaxError as exc:
+ self._error = exc
+ else:
+ self._root = self._parser.close()
+ self._parser = None
+ except:
+ if self._close_file:
+ self._file.close()
+ raise
+ if self._close_file:
+ self._file.close()
+ raise StopIteration
def __iter__(self):
return self
diff --git a/Misc/ACKS b/Misc/ACKS
index c1f6481..8c047d8 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -45,8 +45,8 @@
Juancarlo Añez
Chris Angelico
Jérémy Anger
-Ankur Ankan
Jon Anglin
+Ankur Ankan
Heidi Annexstad
Ramchandra Apte
Éric Araujo
@@ -163,8 +163,8 @@
Georg Brandl
Christopher Brannon
Terrence Brannon
-Germán M. Bravo
Sven Brauch
+Germán M. Bravo
Erik Bray
Brian Brazil
Demian Brecht
@@ -336,6 +336,7 @@
Yves Dionne
Daniel Dittmar
Josip Djolonga
+Walter Dörwald
Jaromir Dolecek
Ismail Donmez
Robert Donohue
@@ -362,7 +363,6 @@
Eugene Dvurechenski
Josip Dzolonga
Maxim Dzumanenko
-Walter Dörwald
Hans Eckardt
Rodolpho Eckhardt
Ulrich Eckhardt
@@ -732,9 +732,9 @@
Vajrasky Kok
Guido Kollerie
Jacek Konieczny
-Марк Коренберг
Arkady Koplyarov
Peter A. Koren
+Марк Коренберг
Vlad Korolev
Joseph Koshy
Daniel Kozan
@@ -826,7 +826,9 @@
Mirko Liss
Nick Lockwood
Stephanie Lockwood
+Martin von Löwis
Hugo Lopes Tavares
+Guillermo López-Anglada
Anne Lord
Tom Loredo
Justin Love
@@ -843,8 +845,6 @@
Taras Lyapun
Jim Lynch
Mikael Lyngvig
-Martin von Löwis
-Guillermo López-Anglada
Jeff MacDonald
John Machin
Andrew I MacIntyre
@@ -869,9 +869,9 @@
Alex Martelli
Anthony Martin
Owen Martin
+Sidney San Martín
Westley Martínez
Sébastien Martini
-Sidney San Martín
Roger Masse
Nick Mathewson
Simon Mathieu
@@ -906,15 +906,15 @@
Ezio Melotti
Doug Mennella
Brian Merrell
+Alexis Métaireau
Luke Mewburn
Carl Meyer
Mike Meyer
Piotr Meyer
-Alexis Métaireau
Steven Miale
-Trent Mick
Jason Michalski
Franck Michea
+Trent Mick
Tom Middleton
Thomas Miedema
Stan Mihai
@@ -1013,7 +1013,7 @@
Denis S. Otkidach
Peter Otten
Michael Otteneder
-R. M. Oudkerk
+Richard Oudkerk
Russel Owen
Joonas Paalasmaa
Martin Packman
@@ -1071,8 +1071,8 @@
François Pinard
Tom Pinckney
Zach Pincus
-Zero Piraeus
Michael Piotrowski
+Zero Piraeus
Antoine Pitrou
Jean-François Piéronne
Oleg Plakhotnyuk
@@ -1100,9 +1100,9 @@
Steve Purcell
Eduardo Pérez
Fernando Pérez
+Kevin Jing Qiu
Pierre Quentel
Brian Quinlan
-Kevin Jing Qiu
Anders Qvist
Thomas Rachel
Ram Rachum
@@ -1209,7 +1209,6 @@
Hugh Sasse
Bob Savage
Ben Sayer
-sbt
Luca Sbardella
Marco Scataglini
Andrew Schaaf
@@ -1248,8 +1247,8 @@
Denis Severson
Ian Seyer
Daniel Shahaf
-Ha Shao
Mark Shannon
+Ha Shao
Richard Shapiro
Varun Sharma
Vlad Shcherbina
@@ -1436,6 +1435,7 @@
Guido Vranken
Martijn Vries
Sjoerd de Vries
+Jonas Wagner
Niki W. Waibel
Wojtek Walczak
Charles Waldman
@@ -1448,7 +1448,6 @@
Greg Ward
Tom Wardill
Zachary Ware
-Jonas Wagner
Barry Warsaw
Steve Waterbury
Bob Watson
diff --git a/Misc/NEWS b/Misc/NEWS
index 5b9793b..54dd101 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -2,6 +2,58 @@
Python News
+++++++++++
+What's New in Python 2.7.12?
+============================
+
+*Release date: XXXX-XX-XX*
+
+Core and Builtins
+-----------------
+
+- Issue #19543: Added Py3k warning for decoding unicode.
+
+- Issue #24097: Fixed crash in object.__reduce__() if slot name is freed inside
+ __getattr__.
+
+- Issue #24731: Fixed crash on converting objects with special methods
+ __str__, __trunc__, and __float__ returning instances of subclasses of
+ str, long, and float to subclasses of str, long, and float correspondingly.
+
+Library
+-------
+
+- Issue #14285: When executing a package with the "python -m package" option,
+ and package initialization raises ImportError, a proper traceback is now
+ reported.
+
+- Issue #6478: _strptime's regexp cache now is reset after changing timezone
+ with time.tzset().
+
+- Issue #25718: Fixed copying object with state with boolean value is false.
+
+- Issue #25742: :func:`locale.setlocale` now accepts a Unicode string for
+ its second parameter.
+
+- Issue #10131: Fixed deep copying of minidom documents. Based on patch
+ by Marian Ganisin.
+
+- Issue #25725: Fixed a reference leak in cPickle.loads() when unpickling
+ invalid data including tuple instructions.
+
+- Issue #25663: In the Readline completer, avoid listing duplicate global
+ names, and search the global namespace before searching builtins.
+
+- Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error.
+
+- Issue #23914: Fixed SystemError raised by CPickle unpickler on broken data.
+
+Tests
+-----
+
+- Issue #25616: Tests for OrderedDict are extracted from test_collections
+ into separate file test_ordered_dict.
+
+
What's New in Python 2.7.11?
============================
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
index 837164c..35643a7 100644
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -337,9 +337,9 @@
}
LOCAL(int)
-element_resize(ElementObject* self, int extra)
+element_resize(ElementObject* self, Py_ssize_t extra)
{
- int size;
+ Py_ssize_t size;
PyObject* *children;
/* make sure self->children can hold the given number of extra
@@ -359,6 +359,13 @@
* be safe.
*/
size = size ? size : 1;
+ if ((size_t)size > PY_SSIZE_T_MAX/sizeof(PyObject*))
+ goto nomemory;
+ if (size > INT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "too many children");
+ return -1;
+ }
if (self->extra->children != self->extra->_children) {
/* Coverity CID #182 size_error: Allocating 1 bytes to pointer
* "children", which needs at least 4 bytes. Although it's a
@@ -1253,18 +1260,19 @@
}
static int
-element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item)
+element_setitem(PyObject* self_, Py_ssize_t index_, PyObject* item)
{
ElementObject* self = (ElementObject*) self_;
- int i;
+ int i, index;
PyObject* old;
- if (!self->extra || index < 0 || index >= self->extra->length) {
+ if (!self->extra || index_ < 0 || index_ >= self->extra->length) {
PyErr_SetString(
PyExc_IndexError,
"child assignment index out of range");
return -1;
}
+ index = (int)index_;
old = self->extra->children[index];
@@ -1373,6 +1381,7 @@
&start, &stop, &step, &slicelen) < 0) {
return -1;
}
+ assert(slicelen <= self->extra->length);
if (value == NULL)
newlen = 0;
@@ -1390,15 +1399,17 @@
if (step != 1 && newlen != slicelen)
{
+ Py_XDECREF(seq);
PyErr_Format(PyExc_ValueError,
#if (PY_VERSION_HEX < 0x02050000)
"attempt to assign sequence of size %d "
"to extended slice of size %d",
+ (int)newlen, (int)slicelen
#else
"attempt to assign sequence of size %zd "
"to extended slice of size %zd",
-#endif
newlen, slicelen
+#endif
);
return -1;
}
@@ -1407,12 +1418,12 @@
/* Resize before creating the recycle bin, to prevent refleaks. */
if (newlen > slicelen) {
if (element_resize(self, newlen - slicelen) < 0) {
- if (seq) {
- Py_DECREF(seq);
- }
+ Py_XDECREF(seq);
return -1;
}
}
+ assert(newlen - slicelen <= INT_MAX - self->extra->length);
+ assert(newlen - slicelen >= -self->extra->length);
if (slicelen > 0) {
/* to avoid recursive calls to this method (via decref), move
@@ -1420,9 +1431,7 @@
we're done modifying the element */
recycle = PyList_New(slicelen);
if (!recycle) {
- if (seq) {
- Py_DECREF(seq);
- }
+ Py_XDECREF(seq);
return -1;
}
for (cur = start, i = 0; i < slicelen;
@@ -1448,11 +1457,9 @@
self->extra->children[cur] = element;
}
- self->extra->length += newlen - slicelen;
+ self->extra->length += (int)(newlen - slicelen);
- if (seq) {
- Py_DECREF(seq);
- }
+ Py_XDECREF(seq);
/* discard the recycle bin, and everything in it */
Py_XDECREF(recycle);
@@ -2708,8 +2715,14 @@
break;
}
+ if (PyString_GET_SIZE(buffer) > INT_MAX) {
+ Py_DECREF(buffer);
+ Py_DECREF(reader);
+ PyErr_SetString(PyExc_OverflowError, "size does not fit in an int");
+ return NULL;
+ }
res = expat_parse(
- self, PyString_AS_STRING(buffer), PyString_GET_SIZE(buffer), 0
+ self, PyString_AS_STRING(buffer), (int)PyString_GET_SIZE(buffer), 0
);
Py_DECREF(buffer);
diff --git a/Modules/cPickle.c b/Modules/cPickle.c
index 0e93723..ce9283a 100644
--- a/Modules/cPickle.c
+++ b/Modules/cPickle.c
@@ -3798,35 +3798,26 @@
static int
-load_tuple(Unpicklerobject *self)
+load_counted_tuple(Unpicklerobject *self, int len)
{
PyObject *tup;
- Py_ssize_t i;
- if ((i = marker(self)) < 0) return -1;
- if (!( tup=Pdata_popTuple(self->stack, i))) return -1;
+ if (self->stack->length < len)
+ return stackUnderflow();
+
+ if (!(tup = Pdata_popTuple(self->stack, self->stack->length - len)))
+ return -1;
PDATA_PUSH(self->stack, tup, -1);
return 0;
}
static int
-load_counted_tuple(Unpicklerobject *self, int len)
+load_tuple(Unpicklerobject *self)
{
- PyObject *tup = PyTuple_New(len);
+ Py_ssize_t i;
- if (tup == NULL)
- return -1;
-
- while (--len >= 0) {
- PyObject *element;
-
- PDATA_POP(self->stack, element);
- if (element == NULL)
- return -1;
- PyTuple_SET_ITEM(tup, len, element);
- }
- PDATA_PUSH(self->stack, tup, -1);
- return 0;
+ if ((i = marker(self)) < 0) return -1;
+ return load_counted_tuple(self, self->stack->length - i);
}
static int
@@ -3945,6 +3936,10 @@
Py_ssize_t i;
if ((i = marker(self)) < 0) return -1;
+
+ if (self->stack->length - i < 1)
+ return stackUnderflow();
+
if (!( tup=Pdata_popTuple(self->stack, i+1))) return -1;
PDATA_POP(self->stack, class);
if (class) {
@@ -3974,7 +3969,10 @@
if (!module_name) return -1;
if ((len = self->readline_func(self, &s)) >= 0) {
- if (len < 2) return bad_readline();
+ if (len < 2) {
+ Py_DECREF(module_name);
+ return bad_readline();
+ }
if ((class_name = PyString_FromStringAndSize(s, len - 1))) {
class = find_class(module_name, class_name,
self->find_class);
@@ -4496,6 +4494,8 @@
static int
load_append(Unpicklerobject *self)
{
+ if (self->stack->length - 1 <= 0)
+ return stackUnderflow();
return do_append(self, self->stack->length - 1);
}
@@ -4503,7 +4503,10 @@
static int
load_appends(Unpicklerobject *self)
{
- return do_append(self, marker(self));
+ Py_ssize_t i = marker(self);
+ if (i < 0)
+ return -1;
+ return do_append(self, i);
}
@@ -4515,6 +4518,14 @@
if (!( (len=self->stack->length) >= x
&& x > 0 )) return stackUnderflow();
+ if (len == x) /* nothing to do */
+ return 0;
+ if ((len - x) % 2 != 0) {
+ /* Currupt or hostile pickle -- we never write one like this. */
+ PyErr_SetString(UnpicklingError,
+ "odd number of items for SETITEMS");
+ return -1;
+ }
dict=self->stack->data[x-1];
@@ -4542,7 +4553,10 @@
static int
load_setitems(Unpicklerobject *self)
{
- return do_setitems(self, marker(self));
+ Py_ssize_t i = marker(self);
+ if (i < 0)
+ return -1;
+ return do_setitems(self, i);
}
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 1143fab..82f9960 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -1839,7 +1839,7 @@
tmp = float_new(&PyFloat_Type, args, kwds);
if (tmp == NULL)
return NULL;
- assert(PyFloat_CheckExact(tmp));
+ assert(PyFloat_Check(tmp));
newobj = type->tp_alloc(type, 0);
if (newobj == NULL) {
Py_DECREF(tmp);
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 405be2e..6427f42 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -4068,7 +4068,7 @@
tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds);
if (tmp == NULL)
return NULL;
- assert(PyLong_CheckExact(tmp));
+ assert(PyLong_Check(tmp));
n = Py_SIZE(tmp);
if (n < 0)
n = -n;
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index c1e12a7..14c5177 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -3719,7 +3719,7 @@
tmp = string_new(&PyString_Type, args, kwds);
if (tmp == NULL)
return NULL;
- assert(PyString_CheckExact(tmp));
+ assert(PyString_Check(tmp));
n = PyString_GET_SIZE(tmp);
pnew = type->tp_alloc(type, n);
if (pnew != NULL) {
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 720a84e..38548fd 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -3269,12 +3269,16 @@
for (i = 0; i < PyList_GET_SIZE(names); i++) {
PyObject *name, *value;
name = PyList_GET_ITEM(names, i);
+ Py_INCREF(name);
value = PyObject_GetAttr(obj, name);
- if (value == NULL)
+ if (value == NULL) {
+ Py_DECREF(name);
PyErr_Clear();
+ }
else {
int err = PyDict_SetItem(slots, name,
value);
+ Py_DECREF(name);
Py_DECREF(value);
if (err)
goto end;
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 9368a3a..2925651 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -1288,6 +1288,9 @@
goto onError;
}
+ if (PyErr_WarnPy3k("decoding Unicode is not supported in 3.x", 1) < 0)
+ goto onError;
+
if (encoding == NULL)
encoding = PyUnicode_GetDefaultEncoding();