mirror of
https://github.com/python/cpython.git
synced 2025-09-30 12:21:51 +00:00
merge heads
This commit is contained in:
commit
5a4ffdbe3d
3 changed files with 26 additions and 50 deletions
|
@ -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
|
That's a tough one, in general. First, here are a list of things to
|
||||||
remember before diving further:
|
remember before diving further:
|
||||||
|
|
||||||
* Performance characteristics vary accross Python implementations. This FAQ
|
* Performance characteristics vary across Python implementations. This FAQ
|
||||||
focusses on :term:`CPython`.
|
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.
|
I/O or multi-threading.
|
||||||
* You should always find the hot spots in your program *before* attempting to
|
* You should always find the hot spots in your program *before* attempting to
|
||||||
optimize any code (see the :mod:`profile` module).
|
optimize any code (see the :mod:`profile` module).
|
||||||
|
|
|
@ -143,13 +143,10 @@ def _instance_callable(obj):
|
||||||
# already an instance
|
# already an instance
|
||||||
return getattr(obj, '__call__', None) is not None
|
return getattr(obj, '__call__', None) is not None
|
||||||
|
|
||||||
klass = obj
|
# *could* be broken by a class overriding __mro__ or __dict__ via
|
||||||
# uses __bases__ instead of __mro__ so that we work with old style classes
|
# a metaclass
|
||||||
if klass.__dict__.get('__call__') is not None:
|
for base in (obj,) + obj.__mro__:
|
||||||
return True
|
if base.__dict__.get('__call__') is not None:
|
||||||
|
|
||||||
for base in klass.__bases__:
|
|
||||||
if _instance_callable(base):
|
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -622,9 +619,7 @@ class NonCallableMock(Base):
|
||||||
|
|
||||||
|
|
||||||
def __dir__(self):
|
def __dir__(self):
|
||||||
"""Filter the output of `dir(mock)` to only useful members.
|
"""Filter the output of `dir(mock)` to only useful members."""
|
||||||
XXXX
|
|
||||||
"""
|
|
||||||
extras = self._mock_methods or []
|
extras = self._mock_methods or []
|
||||||
from_type = dir(type(self))
|
from_type = dir(type(self))
|
||||||
from_dict = list(self.__dict__)
|
from_dict = list(self.__dict__)
|
||||||
|
@ -1060,31 +1055,28 @@ class _patch(object):
|
||||||
|
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def patched(*args, **keywargs):
|
def patched(*args, **keywargs):
|
||||||
# could use with statement here
|
|
||||||
extra_args = []
|
extra_args = []
|
||||||
entered_patchers = []
|
entered_patchers = []
|
||||||
|
|
||||||
# could use try..except...finally here
|
|
||||||
try:
|
try:
|
||||||
try:
|
for patching in patched.patchings:
|
||||||
for patching in patched.patchings:
|
arg = patching.__enter__()
|
||||||
arg = patching.__enter__()
|
entered_patchers.append(patching)
|
||||||
entered_patchers.append(patching)
|
if patching.attribute_name is not None:
|
||||||
if patching.attribute_name is not None:
|
keywargs.update(arg)
|
||||||
keywargs.update(arg)
|
elif patching.new is DEFAULT:
|
||||||
elif patching.new is DEFAULT:
|
extra_args.append(arg)
|
||||||
extra_args.append(arg)
|
|
||||||
|
|
||||||
args += tuple(extra_args)
|
args += tuple(extra_args)
|
||||||
return func(*args, **keywargs)
|
return func(*args, **keywargs)
|
||||||
except:
|
except:
|
||||||
if (patching not in entered_patchers and
|
if (patching not in entered_patchers and
|
||||||
_is_started(patching)):
|
_is_started(patching)):
|
||||||
# the patcher may have been started, but an exception
|
# the patcher may have been started, but an exception
|
||||||
# raised whilst entering one of its additional_patchers
|
# raised whilst entering one of its additional_patchers
|
||||||
entered_patchers.append(patching)
|
entered_patchers.append(patching)
|
||||||
# re-raise the exception
|
# re-raise the exception
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
for patching in reversed(entered_patchers):
|
for patching in reversed(entered_patchers):
|
||||||
patching.__exit__()
|
patching.__exit__()
|
||||||
|
@ -2064,11 +2056,7 @@ def _must_skip(spec, entry, is_type):
|
||||||
if entry in getattr(spec, '__dict__', {}):
|
if entry in getattr(spec, '__dict__', {}):
|
||||||
# instance attribute - shouldn't skip
|
# instance attribute - shouldn't skip
|
||||||
return False
|
return False
|
||||||
# can't use type because of old style classes
|
|
||||||
spec = spec.__class__
|
spec = spec.__class__
|
||||||
if not hasattr(spec, '__mro__'):
|
|
||||||
# old style class: can't have descriptors anyway
|
|
||||||
return is_type
|
|
||||||
|
|
||||||
for klass in spec.__mro__:
|
for klass in spec.__mro__:
|
||||||
result = klass.__dict__.get(entry, DEFAULT)
|
result = klass.__dict__.get(entry, DEFAULT)
|
||||||
|
|
|
@ -107,19 +107,9 @@ class TestCallable(unittest.TestCase):
|
||||||
class Multi(SomeClass, Sub):
|
class Multi(SomeClass, Sub):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class OldStyle:
|
|
||||||
def __call__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class OldStyleSub(OldStyle):
|
|
||||||
pass
|
|
||||||
|
|
||||||
for arg in 'spec', 'spec_set':
|
for arg in 'spec', 'spec_set':
|
||||||
for Klass in CallableX, Sub, Multi, OldStyle, OldStyleSub:
|
for Klass in CallableX, Sub, Multi:
|
||||||
patcher = patch('%s.X' % __name__, **{arg: Klass})
|
with patch('%s.X' % __name__, **{arg: Klass}) as mock:
|
||||||
mock = patcher.start()
|
|
||||||
|
|
||||||
try:
|
|
||||||
instance = mock()
|
instance = mock()
|
||||||
mock.assert_called_once_with()
|
mock.assert_called_once_with()
|
||||||
|
|
||||||
|
@ -136,8 +126,6 @@ class TestCallable(unittest.TestCase):
|
||||||
result.assert_called_once_with(3, 2, 1)
|
result.assert_called_once_with(3, 2, 1)
|
||||||
result.foo(3, 2, 1)
|
result.foo(3, 2, 1)
|
||||||
result.foo.assert_called_once_with(3, 2, 1)
|
result.foo.assert_called_once_with(3, 2, 1)
|
||||||
finally:
|
|
||||||
patcher.stop()
|
|
||||||
|
|
||||||
|
|
||||||
def test_create_autopsec(self):
|
def test_create_autopsec(self):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue