Commit f6330e33 authored by Matthias Klose's avatar Matthias Klose

merge heads

parents cbcc8ee6 23ced31d
......@@ -794,9 +794,9 @@ My program is too slow. How do I speed it up?
That's a tough one, in general. First, here are a list of things to
remember before diving further:
* Performance characteristics vary accross Python implementations. This FAQ
* Performance characteristics vary across Python implementations. This FAQ
focusses on :term:`CPython`.
* Behaviour can vary accross operating systems, especially when talking about
* Behaviour can vary across operating systems, especially when talking about
I/O or multi-threading.
* You should always find the hot spots in your program *before* attempting to
optimize any code (see the :mod:`profile` module).
......
......@@ -143,13 +143,10 @@ def _instance_callable(obj):
# already an instance
return getattr(obj, '__call__', None) is not None
klass = obj
# uses __bases__ instead of __mro__ so that we work with old style classes
if klass.__dict__.get('__call__') is not None:
return True
for base in klass.__bases__:
if _instance_callable(base):
# *could* be broken by a class overriding __mro__ or __dict__ via
# a metaclass
for base in (obj,) + obj.__mro__:
if base.__dict__.get('__call__') is not None:
return True
return False
......@@ -622,9 +619,7 @@ class NonCallableMock(Base):
def __dir__(self):
"""Filter the output of `dir(mock)` to only useful members.
XXXX
"""
"""Filter the output of `dir(mock)` to only useful members."""
extras = self._mock_methods or []
from_type = dir(type(self))
from_dict = list(self.__dict__)
......@@ -1060,31 +1055,28 @@ class _patch(object):
@wraps(func)
def patched(*args, **keywargs):
# could use with statement here
extra_args = []
entered_patchers = []
# could use try..except...finally here
try:
try:
for patching in patched.patchings:
arg = patching.__enter__()
entered_patchers.append(patching)
if patching.attribute_name is not None:
keywargs.update(arg)
elif patching.new is DEFAULT:
extra_args.append(arg)
args += tuple(extra_args)
return func(*args, **keywargs)
except:
if (patching not in entered_patchers and
_is_started(patching)):
# the patcher may have been started, but an exception
# raised whilst entering one of its additional_patchers
entered_patchers.append(patching)
# re-raise the exception
raise
for patching in patched.patchings:
arg = patching.__enter__()
entered_patchers.append(patching)
if patching.attribute_name is not None:
keywargs.update(arg)
elif patching.new is DEFAULT:
extra_args.append(arg)
args += tuple(extra_args)
return func(*args, **keywargs)
except:
if (patching not in entered_patchers and
_is_started(patching)):
# the patcher may have been started, but an exception
# raised whilst entering one of its additional_patchers
entered_patchers.append(patching)
# re-raise the exception
raise
finally:
for patching in reversed(entered_patchers):
patching.__exit__()
......@@ -2064,11 +2056,7 @@ def _must_skip(spec, entry, is_type):
if entry in getattr(spec, '__dict__', {}):
# instance attribute - shouldn't skip
return False
# can't use type because of old style classes
spec = spec.__class__
if not hasattr(spec, '__mro__'):
# old style class: can't have descriptors anyway
return is_type
for klass in spec.__mro__:
result = klass.__dict__.get(entry, DEFAULT)
......
......@@ -107,19 +107,9 @@ class TestCallable(unittest.TestCase):
class Multi(SomeClass, Sub):
pass
class OldStyle:
def __call__(self):
pass
class OldStyleSub(OldStyle):
pass
for arg in 'spec', 'spec_set':
for Klass in CallableX, Sub, Multi, OldStyle, OldStyleSub:
patcher = patch('%s.X' % __name__, **{arg: Klass})
mock = patcher.start()
try:
for Klass in CallableX, Sub, Multi:
with patch('%s.X' % __name__, **{arg: Klass}) as mock:
instance = mock()
mock.assert_called_once_with()
......@@ -136,8 +126,6 @@ class TestCallable(unittest.TestCase):
result.assert_called_once_with(3, 2, 1)
result.foo(3, 2, 1)
result.foo.assert_called_once_with(3, 2, 1)
finally:
patcher.stop()
def test_create_autopsec(self):
......
......@@ -24,6 +24,11 @@ Core and Builtins
Library
-------
- Issue #14234: CVE-2012-0876: Randomize hashes of xml attributes in the hash
table internal to the pyexpat module's copy of the expat library to avoid a
denial of service due to hash collisions. Patch by David Malcolm with some
modifications by the expat project.
- Issue #14200: Idle shell crash on printing non-BMP unicode character.
- Issue #12818: format address no longer needlessly \ escapes ()s in names when
......
......@@ -883,6 +883,15 @@ XMLPARSEAPI(int)
XML_SetParamEntityParsing(XML_Parser parser,
enum XML_ParamEntityParsing parsing);
/* Sets the hash salt to use for internal hash calculations.
Helps in preventing DoS attacks based on predicting hash
function behavior. This must be called before parsing is started.
Returns 1 if successful, 0 when called after parsing has started.
*/
XMLPARSEAPI(int)
XML_SetHashSalt(XML_Parser parser,
unsigned long hash_salt);
/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
XML_GetErrorCode returns information about the error.
*/
......
......@@ -97,6 +97,7 @@
#define XML_SetEntityDeclHandler PyExpat_XML_SetEntityDeclHandler
#define XML_SetExternalEntityRefHandler PyExpat_XML_SetExternalEntityRefHandler
#define XML_SetExternalEntityRefHandlerArg PyExpat_XML_SetExternalEntityRefHandlerArg
#define XML_SetHashSalt PyExpat_XML_SetHashSalt
#define XML_SetNamespaceDeclHandler PyExpat_XML_SetNamespaceDeclHandler
#define XML_SetNotationDeclHandler PyExpat_XML_SetNotationDeclHandler
#define XML_SetNotStandaloneHandler PyExpat_XML_SetNotStandaloneHandler
......
This diff is collapsed.
......@@ -1156,6 +1156,8 @@ newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)
else {
self->itself = XML_ParserCreate(encoding);
}
XML_SetHashSalt(self->itself,
(unsigned long)_Py_HashSecret.prefix);
self->intern = intern;
Py_XINCREF(self->intern);
PyObject_GC_Track(self);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment