summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Foord <michael@voidspace.org.uk>2012-04-21 18:39:34 +0100
committerMichael Foord <michael@voidspace.org.uk>2012-04-21 18:39:34 +0100
commit7807e0cc076b35915d03fae1887bdd107cc37469 (patch)
tree4fef0768711ce2153279864f0beab2ce38f79812
parent72af501f32378e84af6f5407cab4a79d7ec453ac (diff)
downloadmock-7807e0cc076b35915d03fae1887bdd107cc37469.tar.gz
Support keyword only arguments in Python 3
-rw-r--r--docs/changelog.txt1
-rw-r--r--mock.py29
-rw-r--r--tests/testhelpers.py14
3 files changed, 36 insertions, 8 deletions
diff --git a/docs/changelog.txt b/docs/changelog.txt
index ad16637..8c324c5 100644
--- a/docs/changelog.txt
+++ b/docs/changelog.txt
@@ -13,6 +13,7 @@ CHANGELOG
can't be fetched from the object's class. Contributed by Konstantine Rybnikov
* Any exceptions in an iterable `side_effect` will be raised instead of
returned
+* In Python 3, `create_autospec` now supports keyword only arguments
2012/03/25 Version 1.0.0 alpha 1
diff --git a/mock.py b/mock.py
index 16f0fc8..88ceec2 100644
--- a/mock.py
+++ b/mock.py
@@ -154,11 +154,19 @@ def _getsignature(func, skipfirst, instance=False):
except AttributeError:
return
- try:
- regargs, varargs, varkwargs, defaults = inspect.getargspec(func)
- except TypeError:
- # C function / method, possibly inherited object().__init__
- return
+ if inPy3k:
+ try:
+ argspec = inspect.getfullargspec(func)
+ except TypeError:
+ # C function / method, possibly inherited object().__init__
+ return
+ regargs, varargs, varkw, defaults, kwonly, kwonlydef, ann = argspec
+ else:
+ try:
+ regargs, varargs, varkwargs, defaults = inspect.getargspec(func)
+ except TypeError:
+ # C function / method, possibly inherited object().__init__
+ return
# instance methods and classmethods need to lose the self argument
if getattr(func, self, None) is not None:
@@ -167,8 +175,14 @@ def _getsignature(func, skipfirst, instance=False):
# this condition and the above one are never both True - why?
regargs = regargs[1:]
- signature = inspect.formatargspec(regargs, varargs, varkwargs, defaults,
- formatvalue=lambda value: "")
+ if inPy3k:
+ signature = inspect.formatargspec(
+ regargs, varargs, varkw, defaults,
+ kwonly, kwonlydef, ann, formatvalue=lambda value: "")
+ else:
+ signature = inspect.formatargspec(
+ regargs, varargs, varkwargs, defaults,
+ formatvalue=lambda value: "")
return signature[1:-1], func
@@ -981,7 +995,6 @@ class CallableMixin(Base):
if _is_exception(effect):
raise effect
- ret_val = DEFAULT
if not _callable(effect):
result = next(effect)
if _is_exception(result):
diff --git a/tests/testhelpers.py b/tests/testhelpers.py
index aa59e99..b3b31ac 100644
--- a/tests/testhelpers.py
+++ b/tests/testhelpers.py
@@ -393,6 +393,20 @@ class SpecSignatureTest(unittest2.TestCase):
m = create_autospec(Foo, a='3')
self.assertEqual(m.a, '3')
+ @unittest2.skipUnless(inPy3k, "Keyword only arguments Python 3 specific")
+ def test_create_autospec_keyword_only_arguments(self):
+ func_def = "def foo(a, *, b=None):\n pass\n"
+ namespace = {}
+ exec (func_def, namespace)
+ foo = namespace['foo']
+
+ m = create_autospec(foo)
+ m(1)
+ m.assert_called_with(1)
+ self.assertRaises(TypeError, m, 1, 2)
+
+ m(2, b=3)
+ m.assert_called_with(2, b=3)
def test_function_as_instance_attribute(self):
obj = SomeClass()