summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2020-05-24 15:52:36 +0200
committerStefan Behnel <stefan_ml@behnel.de>2020-05-24 15:52:36 +0200
commit764b952616b068c5c5f49ebd7df4462a2154f78b (patch)
treeb2afce31ba300c522e015de944b6f1957eba1727
parentaa8f579f8cd4da0ba40b875fac2d42650a6d7c9e (diff)
downloadcython-gh3090_always_allow_keywords.tar.gz
Extend "always_allow_keywords" test to cover some edge cases.gh3090_always_allow_keywords
Some are commented out as they currently only work with the fastcall implementation.
-rw-r--r--tests/run/always_allow_keywords_T295.pyx143
1 files changed, 129 insertions, 14 deletions
diff --git a/tests/run/always_allow_keywords_T295.pyx b/tests/run/always_allow_keywords_T295.pyx
index 806a8abf0..aabae5b36 100644
--- a/tests/run/always_allow_keywords_T295.pyx
+++ b/tests/run/always_allow_keywords_T295.pyx
@@ -1,7 +1,12 @@
+# mode: run
# ticket: 295
cimport cython
+import sys
+IS_PY2 = sys.version_info[0] == 2
+
+
def assert_typeerror_no_keywords(func, *args, **kwds):
# Python 3.9 produces an slightly different error message
# to previous versions, so doctest isn't matching the
@@ -14,13 +19,18 @@ def assert_typeerror_no_keywords(func, *args, **kwds):
assert False, "call did not raise TypeError"
+def func0():
+ """
+ >>> func0()
+ >>> func0(**{})
+ """
+
def func1(arg):
"""
>>> func1(None)
>>> func1(*[None])
>>> func1(arg=None)
"""
- pass
@cython.always_allow_keywords(False)
def func2(arg):
@@ -29,7 +39,6 @@ def func2(arg):
>>> func2(*[None])
>>> assert_typeerror_no_keywords(func2, arg=None)
"""
- pass
@cython.always_allow_keywords(True)
def func3(arg):
@@ -40,26 +49,132 @@ def func3(arg):
"""
pass
+
cdef class A:
"""
- >>> A().meth1(None)
- >>> A().meth1(*[None])
- >>> A().meth1(arg=None)
- >>> A().meth2(None)
- >>> A().meth2(*[None])
- >>> assert_typeerror_no_keywords(A().meth2, arg=None)
- >>> A().meth3(None)
- >>> A().meth3(*[None])
- >>> A().meth3(arg=None)
+ >>> class PyA(object):
+ ... def meth0(self): pass
+ ... def meth1(self, arg): pass
+
+ >>> PyA().meth0()
+ >>> PyA.meth0(PyA())
+ >>> if not IS_PY2: PyA.meth0(self=PyA())
+ >>> try: PyA().meth0(self=PyA())
+ ... except TypeError as exc: assert 'multiple' in str(exc), "Unexpected message: %s" % exc
+ ... else: assert False, "No TypeError when passing 'self' argument twice"
+
+ >>> PyA().meth1(1)
+ >>> PyA.meth1(PyA(), 1)
+ >>> PyA.meth1(PyA(), arg=1)
+ >>> if not IS_PY2: PyA.meth1(self=PyA(), arg=1)
"""
+ @cython.always_allow_keywords(False)
+ def meth0_nokw(self):
+ """
+ >>> A().meth0_nokw()
+ >>> A().meth0_nokw(**{})
+ >>> try: pass #A.meth0_nokw(self=A())
+ ... except TypeError as exc: assert 'needs an argument' in str(exc), "Unexpected message: %s" % exc
+ ... else: pass #assert False, "No TypeError for missing 'self' positional argument"
+ """
+
+ @cython.always_allow_keywords(True)
+ def meth0_kw(self):
+ """
+ >>> A().meth0_kw()
+ >>> A().meth0_kw(**{})
+ >>> A.meth0_kw(A())
+ >>> #A.meth0_kw(self=A())
+ >>> try: pass #A().meth0_kw(self=A())
+ ... except TypeError as exc: assert 'multiple' in str(exc), "Unexpected message: %s" % exc
+ ... else: pass #assert False, "No TypeError when passing 'self' argument twice"
+ """
+
+ @cython.always_allow_keywords(True)
+ def meth1_kw(self, arg):
+ """
+ >>> A().meth1_kw(None)
+ >>> A().meth1_kw(*[None])
+ >>> A().meth1_kw(arg=None)
+ >>> A.meth1_kw(A(), arg=None)
+ >>> #A.meth1_kw(self=A(), arg=None)
+ """
+
+ @cython.always_allow_keywords(False)
+ def meth1_nokw(self, arg):
+ """
+ >>> A().meth1_nokw(None)
+ >>> A().meth1_nokw(*[None])
+ >>> assert_typeerror_no_keywords(A().meth1_nokw, arg=None)
+ >>> assert_typeerror_no_keywords(A.meth1_nokw, A(), arg=None)
+ >>> try: pass # A.meth1_nokw(self=A(), arg=None)
+ ... except TypeError as exc: assert 'needs an argument' in str(exc), "Unexpected message: %s" % exc
+ ... else: pass # assert False, "No TypeError for missing 'self' positional argument"
+ """
+
+ @cython.always_allow_keywords(False)
+ def meth2(self, arg):
+ """
+ >>> A().meth2(None)
+ >>> A().meth2(*[None])
+ >>> assert_typeerror_no_keywords(A().meth2, arg=None)
+ """
+
+ @cython.always_allow_keywords(True)
+ def meth3(self, arg):
+ """
+ >>> A().meth3(None)
+ >>> A().meth3(*[None])
+ >>> A().meth3(arg=None)
+ """
+
+
+class B(object):
+ @cython.always_allow_keywords(False)
+ def meth0_nokw(self):
+ """
+ >>> B().meth0_nokw()
+ >>> B().meth0_nokw(**{})
+ >>> if not IS_PY2: assert_typeerror_no_keywords(B.meth0_nokw, self=B())
+ """
+
+ @cython.always_allow_keywords(True)
+ def meth0_kw(self):
+ """
+ >>> B().meth0_kw()
+ >>> B().meth0_kw(**{})
+ >>> B.meth0_kw(B())
+ >>> if not IS_PY2: B.meth0_kw(self=B())
+ >>> try: B().meth0_kw(self=B())
+ ... except TypeError as exc: assert 'multiple' in str(exc), "Unexpected message: %s" % exc
+ ... else: assert False, "No TypeError when passing 'self' argument twice"
+ """
+
+ @cython.always_allow_keywords(True)
def meth1(self, arg):
- pass
+ """
+ >>> B().meth1(None)
+ >>> B().meth1(*[None])
+ >>> B().meth1(arg=None)
+ >>> B.meth1(B(), arg=None)
+ >>> if not IS_PY2: B.meth1(self=B(), arg=None)
+ """
@cython.always_allow_keywords(False)
def meth2(self, arg):
- pass
+ """
+ >>> B().meth2(None)
+ >>> B().meth2(*[None])
+ >>> B.meth2(B(), None)
+ >>> if not IS_PY2: B.meth2(self=B(), arg=None)
+ >>> B().meth2(arg=None) # assert_typeerror_no_keywords(B().meth2, arg=None) -> not a cdef class!
+ """
@cython.always_allow_keywords(True)
def meth3(self, arg):
- pass
+ """
+ >>> B().meth3(None)
+ >>> B().meth3(*[None])
+ >>> B().meth3(arg=None)
+ """