From 07d9f08f616a34e4b47656f04eb20b255f7b41e8 Mon Sep 17 00:00:00 2001 From: Michael Foord <michael@voidspace.org.uk> Date: Tue, 17 May 2011 19:12:06 +0100 Subject: [PATCH] Recursive function references work with _spec_signature --- mock.py | 18 +++++++++++------- tests/testhelpers.py | 10 ++++++++++ tests/testmagicmethods.py | 2 ++ tox.ini | 5 ++--- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/mock.py b/mock.py index 78eec96..f0528c7 100644 --- a/mock.py +++ b/mock.py @@ -114,7 +114,7 @@ def _getsignature(func, skipfirst): def _copy_func_details(func, funcopy): funcopy.__name__ = func.__name__ funcopy.__doc__ = func.__doc__ - funcopy.__dict__.update(func.__dict__) + #funcopy.__dict__.update(func.__dict__) funcopy.__module__ = func.__module__ if not inPy3k: funcopy.func_defaults = func.func_defaults @@ -1148,9 +1148,12 @@ def _spec_signature(spec, spec_set=False, inherit=False, _parent=None, # allow a mock to actually be a function from mocksignature continue - # XXXX need a better way of getting attributes - # without triggering code execution (?) + # XXXX do we need a better way of getting attributes + # without triggering code execution (?) (possibly not)s original = getattr(spec, entry) + kwargs = {'spec': original} + if spec_set: + kwargs = {'spec_set': original} if not isinstance(original, FunctionTypes): if type(spec) in (int, float, bool): @@ -1159,16 +1162,17 @@ def _spec_signature(spec, spec_set=False, inherit=False, _parent=None, # pypy 1.5.1 which is fixed in trunk.) # Instead we could check for attributes that have the same # type as the parent - this might solve the general problem. - kwargs = {'spec': original} - if spec_set: - kwargs = {'spec_set': original} new = MagicMock(parent=mock, name=entry, **kwargs) mock._mock_children[entry] = new else: new = _spec_signature(original, spec_set, inherit, mock, entry, _ids) else: - existing = getattr(mock, entry) + if isinstance(spec, FunctionTypes): + existing = MagicMock(parent=mock.mock, name=entry, **kwargs) + mock._mock_children[entry] = existing + else: + existing = getattr(mock, entry) skipfirst = _must_skip(spec, entry, is_type) new = mocksignature(original, existing, skipfirst=skipfirst) diff --git a/tests/testhelpers.py b/tests/testhelpers.py index bb665da..5b0b94e 100644 --- a/tests/testhelpers.py +++ b/tests/testhelpers.py @@ -365,6 +365,16 @@ class SpecSignatureTest(unittest2.TestCase): mock = _spec_signature(f) self.assertRaises(TypeError, mock) + mock(1, 2) + mock.assert_called_with(1, 2) + + f.f = f + mock = _spec_signature(f) + self.assertRaises(TypeError, mock.f) + mock.f(1, 2) + mock.f.assert_called_with(1, 2) + # XXX Note that this is *not* recursive, the function is only copied + # for one level deep. def test_none(self): diff --git a/tests/testmagicmethods.py b/tests/testmagicmethods.py index 00c24a2..a8cf02c 100644 --- a/tests/testmagicmethods.py +++ b/tests/testmagicmethods.py @@ -162,6 +162,8 @@ class TestMockingMagicMethods(unittest2.TestCase): def testComparison(self): + # note: this test fails with Jython 2.5.1 due to a Jython bug + # it is fixed in jython 2.5.2 if not inPy3k: # incomparable in Python 3 self. assertEqual(Mock() < 3, object() < 3) diff --git a/tox.ini b/tox.ini index c6b7477..6f4c22b 100644 --- a/tox.ini +++ b/tox.ini @@ -32,6 +32,5 @@ commands= {envbindir}/python -m unittest discover [] deps = -[testenv:pypy] -deps=unittest2 -commands={envbindir}/unit2 discover [] +# note for jython. Execute in tests directory: +# rm `find . -name '*$py.class'` \ No newline at end of file -- GitLab