Commit 086f4098 authored by Stefan Behnel's avatar Stefan Behnel

almost complete in-place implementation of Python's ParseTupleAndKeywords()

use argument exception messages from Python 2.6
TODO: handling of keyword-only arguments seems to require more work
TODO: clean up helper functions (currently somewhat redundant)
parent 5091aefd
This diff is collapsed.
def f(*args, **kwargs):
pass
args = (1,2,3)
kwargs = {u"test" : "toast"}
def test():
f(*args, 1, 2, 3)
f(**kwargs, 1, 2, c=3)
f(*args, **kwargs, *args)
f(1, 2, c=3, *args, **kwargs, *args)
f(1, 2, c=3, *args, d=5, **kwargs, **kwargs)
f(1, 2, c=3, *args, d=5, **kwargs, x=6)
f(1=2)
# too bad we don't get more errors here ...
_ERRORS = u"""
8:13: Non-keyword arg following star-arg
"""
__doc__ = u"""
>>> test()
1 2 3 * 0 0
1 2 3 * 0 0
1 2 9 * 2 1
1 2 7 * 2 1
1 2 9 * 2 2
1 2 9 * 2 2
1 2 9 * 2 3
"""
def f(a, b, c, *args, **kwargs):
print a, b, c, u'*', len(args), len(kwargs)
args = (9,8,7)
import sys
if sys.version_info[0] >= 3:
kwargs = {u"test" : u"toast"}
else:
kwargs = {"test" : u"toast"}
def test():
f(1,2,3)
f(1,2, c=3)
f(1,2, d=3, *args)
f(1,2, d=3, *(7,8,9))
f(1,2, d=3, *args, **kwargs)
f(1,2, d=3, *args, e=5)
f(1,2, d=3, *args, e=5, **kwargs)
...@@ -5,20 +5,20 @@ __doc__ = u""" ...@@ -5,20 +5,20 @@ __doc__ = u"""
>>> b(1,2,3) >>> b(1,2,3)
>>> b(1,2,3,4) >>> b(1,2,3,4)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 4 arguments (5 given) TypeError: b() takes at most 4 positional arguments (5 given)
>>> c(1,2) >>> c(1,2)
>>> c(1,2,3) >>> c(1,2,3)
>>> c(1,2,3,4) >>> c(1,2,3,4)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 4 arguments (5 given) TypeError: c() takes at most 4 positional arguments (5 given)
>>> d(1,2) >>> d(1,2)
>>> d(1,2, c=1) >>> d(1,2, c=1)
>>> d(1,2,3) >>> d(1,2,3)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 3 positional arguments (4 given) TypeError: d() takes at most 3 positional arguments (4 given)
>>> d(1,2, d=1) >>> d(1,2, d=1)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: 'd' is an invalid keyword argument for this function TypeError: 'd' is an invalid keyword argument for this function
...@@ -30,14 +30,14 @@ __doc__ = u""" ...@@ -30,14 +30,14 @@ __doc__ = u"""
>>> e(1,2,3) >>> e(1,2,3)
>>> e(1,2,3,4) >>> e(1,2,3,4)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 4 positional arguments (5 given) TypeError: e() takes at most 4 positional arguments (5 given)
>>> f(1,2, c=1) >>> f(1,2, c=1)
>>> f(1,2, c=1, d=2) >>> f(1,2, c=1, d=2)
>>> f(1,2,3) >>> f(1,2,3)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 3 positional arguments (4 given) TypeError: f() takes at most 3 positional arguments (4 given)
>>> f(1,2) >>> f(1,2)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing TypeError: required keyword argument 'c' is missing
...@@ -51,7 +51,7 @@ __doc__ = u""" ...@@ -51,7 +51,7 @@ __doc__ = u"""
>>> g(1,2,3) #doctest: +ELLIPSIS >>> g(1,2,3) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 3 positional arguments (4 given) TypeError: g() takes at most 3 positional arguments (4 given)
>>> g(1,2) >>> g(1,2)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing TypeError: required keyword argument 'c' is missing
......
...@@ -5,20 +5,20 @@ __doc__ = u""" ...@@ -5,20 +5,20 @@ __doc__ = u"""
>>> b(1,2,3) >>> b(1,2,3)
>>> b(1,2,3,4) >>> b(1,2,3,4)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (4 given) TypeError: b() takes at most 3 positional arguments (4 given)
>>> c(1,2) >>> c(1,2)
>>> c(1,2,3) >>> c(1,2,3)
>>> c(1,2,3,4) >>> c(1,2,3,4)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 3 arguments (4 given) TypeError: c() takes at most 3 positional arguments (4 given)
>>> d(1,2) >>> d(1,2)
>>> d(1,2, c=1) >>> d(1,2, c=1)
>>> d(1,2,3) >>> d(1,2,3)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given) TypeError: d() takes at most 2 positional arguments (3 given)
>>> d(1,2, d=1) >>> d(1,2, d=1)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: 'd' is an invalid keyword argument for this function TypeError: 'd' is an invalid keyword argument for this function
...@@ -30,14 +30,14 @@ __doc__ = u""" ...@@ -30,14 +30,14 @@ __doc__ = u"""
>>> e(1,2,3) >>> e(1,2,3)
>>> e(1,2,3,4) >>> e(1,2,3,4)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 3 positional arguments (4 given) TypeError: e() takes at most 3 positional arguments (4 given)
>>> f(1,2, c=1) >>> f(1,2, c=1)
>>> f(1,2, c=1, d=2) >>> f(1,2, c=1, d=2)
>>> f(1,2,3) >>> f(1,2,3)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given) TypeError: f() takes at most 2 positional arguments (3 given)
>>> f(1,2) >>> f(1,2)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing TypeError: required keyword argument 'c' is missing
...@@ -51,7 +51,7 @@ __doc__ = u""" ...@@ -51,7 +51,7 @@ __doc__ = u"""
>>> g(1,2,3) >>> g(1,2,3)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given) TypeError: g() takes at most 2 positional arguments (3 given)
>>> g(1,2) >>> g(1,2)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing TypeError: required keyword argument 'c' is missing
...@@ -84,10 +84,6 @@ __doc__ = u""" ...@@ -84,10 +84,6 @@ __doc__ = u"""
TypeError: required keyword argument 'f' is missing TypeError: required keyword argument 'f' is missing
""" """
import sys, re
if sys.version_info >= (2,6):
__doc__ = re.sub(u"Error: (.*)exactly(.*)", u"Error: \\1at most\\2", __doc__)
cdef class Ext: cdef class Ext:
def b(self, a, b, c): def b(self, a, b, c):
pass pass
......
...@@ -7,10 +7,10 @@ __doc__ = u""" ...@@ -7,10 +7,10 @@ __doc__ = u"""
(1, 2, 3) (1, 2, 3)
>>> spam(1,2) #doctest: +ELLIPSIS >>> spam(1,2) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (2 given) TypeError: spam() takes at least 3 positional arguments (2 given)
>>> spam(1,2,3,4) >>> spam(1,2,3,4)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (4 given) TypeError: spam() takes at most 3 positional arguments (4 given)
>>> spam(1,2,3, a=1) #doctest: +ELLIPSIS >>> spam(1,2,3, a=1) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: 'a' is an invalid keyword argument for this function TypeError: 'a' is an invalid keyword argument for this function
...@@ -23,7 +23,7 @@ __doc__ = u""" ...@@ -23,7 +23,7 @@ __doc__ = u"""
(1, 2, 3, (4, 5, 6, 7, 8, 9)) (1, 2, 3, (4, 5, 6, 7, 8, 9))
>>> grail(1,2) #doctest: +ELLIPSIS >>> grail(1,2) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (2 given) TypeError: grail() takes exactly 3 arguments (2 given)
>>> grail(1,2,3, a=1) #doctest: +ELLIPSIS >>> grail(1,2,3, a=1) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: 'a' is an invalid keyword argument for this function TypeError: 'a' is an invalid keyword argument for this function
...@@ -32,7 +32,7 @@ __doc__ = u""" ...@@ -32,7 +32,7 @@ __doc__ = u"""
(1, 2, 3, ()) (1, 2, 3, ())
>>> swallow(1,2,3,4) >>> swallow(1,2,3,4)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 3 positional arguments (4 given) TypeError: swallow() takes at most 3 positional arguments (4 given)
>>> swallow(1,2,3, a=1, b=2) >>> swallow(1,2,3, a=1, b=2)
(1, 2, 3, (('a', 1), ('b', 2))) (1, 2, 3, (('a', 1), ('b', 2)))
>>> swallow(1,2,3, x=1) #doctest: +ELLIPSIS >>> swallow(1,2,3, x=1) #doctest: +ELLIPSIS
...@@ -68,13 +68,13 @@ __doc__ = u""" ...@@ -68,13 +68,13 @@ __doc__ = u"""
(('a', 1), ('b', 2)) (('a', 1), ('b', 2))
>>> onlyk(1) >>> onlyk(1)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 0 positional arguments (1 given) TypeError: onlyk() takes at most 0 positional arguments (1 given)
>>> onlyk(1, 2) >>> onlyk(1, 2)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 0 positional arguments (2 given) TypeError: onlyk() takes at most 0 positional arguments (2 given)
>>> onlyk(1, a=1, b=2) >>> onlyk(1, a=1, b=2)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 0 positional arguments (1 given) TypeError: onlyk() takes at most 0 positional arguments (1 given)
>>> tk(a=1) >>> tk(a=1)
(('a', 1),) (('a', 1),)
...@@ -88,10 +88,6 @@ __doc__ = u""" ...@@ -88,10 +88,6 @@ __doc__ = u"""
(1, ('a', 1), ('b', 2)) (1, ('a', 1), ('b', 2))
""" """
import sys, re
if sys.version_info >= (2,6):
__doc__ = re.sub(u"Error: (.*)exactly(.*)", u"Error: \\1at most\\2", __doc__)
import sys, re import sys, re
if sys.version_info >= (2,6): if sys.version_info >= (2,6):
__doc__ = re.sub(u"(ELLIPSIS[^>]*Error: )[^\n]*\n", u"\\1...\n", __doc__, re.M) __doc__ = re.sub(u"(ELLIPSIS[^>]*Error: )[^\n]*\n", u"\\1...\n", __doc__, re.M)
......
...@@ -2,20 +2,20 @@ __doc__ = u""" ...@@ -2,20 +2,20 @@ __doc__ = u"""
>>> b(1,2,3) >>> b(1,2,3)
>>> b(1,2,3,4) >>> b(1,2,3,4)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (4 given) TypeError: b() takes at most 3 positional arguments (4 given)
>>> c(1,2) >>> c(1,2)
>>> c(1,2,3) >>> c(1,2,3)
>>> c(1,2,3,4) >>> c(1,2,3,4)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 3 arguments (4 given) TypeError: c() takes at most 3 positional arguments (4 given)
>>> d(1,2) >>> d(1,2)
>>> d(1,2, c=1) >>> d(1,2, c=1)
>>> d(1,2,3) >>> d(1,2,3)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given) TypeError: d() takes at most 2 positional arguments (3 given)
>>> d(1,2, d=1) >>> d(1,2, d=1)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: 'd' is an invalid keyword argument for this function TypeError: 'd' is an invalid keyword argument for this function
...@@ -27,14 +27,14 @@ __doc__ = u""" ...@@ -27,14 +27,14 @@ __doc__ = u"""
>>> e(1,2,3) >>> e(1,2,3)
>>> e(1,2,3,4) >>> e(1,2,3,4)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 3 positional arguments (4 given) TypeError: e() takes at most 3 positional arguments (4 given)
>>> f(1,2, c=1) >>> f(1,2, c=1)
>>> f(1,2, c=1, d=2) >>> f(1,2, c=1, d=2)
>>> f(1,2,3) >>> f(1,2,3)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given) TypeError: f() takes at most 2 positional arguments (3 given)
>>> f(1,2) >>> f(1,2)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing TypeError: required keyword argument 'c' is missing
...@@ -48,7 +48,7 @@ __doc__ = u""" ...@@ -48,7 +48,7 @@ __doc__ = u"""
>>> g(1,2,3) >>> g(1,2,3)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given) TypeError: g() takes at most 2 positional arguments (3 given)
>>> g(1,2) >>> g(1,2)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing TypeError: required keyword argument 'c' is missing
...@@ -81,10 +81,6 @@ __doc__ = u""" ...@@ -81,10 +81,6 @@ __doc__ = u"""
TypeError: required keyword argument 'f' is missing TypeError: required keyword argument 'f' is missing
""" """
import sys, re
if sys.version_info >= (2,6):
__doc__ = re.sub(u"Error: (.*)exactly(.*)", u"Error: \\1at most\\2", __doc__)
def b(a, b, c): def b(a, b, c):
pass pass
......
...@@ -2,20 +2,20 @@ __doc__ = u""" ...@@ -2,20 +2,20 @@ __doc__ = u"""
>>> call3(b) >>> call3(b)
>>> call4(b) >>> call4(b)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (4 given) TypeError: b() takes at most 3 positional arguments (4 given)
>>> call2(c) >>> call2(c)
>>> call3(c) >>> call3(c)
>>> call4(c) >>> call4(c)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 3 arguments (4 given) TypeError: c() takes at most 3 positional arguments (4 given)
>>> call2(d) >>> call2(d)
>>> call2c(d) >>> call2c(d)
>>> call3(d) >>> call3(d)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given) TypeError: d() takes at most 2 positional arguments (3 given)
>>> call2d(d) >>> call2d(d)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: 'd' is an invalid keyword argument for this function TypeError: 'd' is an invalid keyword argument for this function
...@@ -27,14 +27,14 @@ __doc__ = u""" ...@@ -27,14 +27,14 @@ __doc__ = u"""
>>> call3(e) >>> call3(e)
>>> call4(e) >>> call4(e)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 3 positional arguments (4 given) TypeError: e() takes at most 3 positional arguments (4 given)
>>> call2c(f) >>> call2c(f)
>>> call2cd(f) >>> call2cd(f)
>>> call3(f) >>> call3(f)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given) TypeError: f() takes at most 2 positional arguments (3 given)
>>> call2(f) >>> call2(f)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing TypeError: required keyword argument 'c' is missing
...@@ -48,7 +48,7 @@ __doc__ = u""" ...@@ -48,7 +48,7 @@ __doc__ = u"""
>>> call3(g) >>> call3(g)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given) TypeError: g() takes at most 2 positional arguments (3 given)
>>> call2(g) >>> call2(g)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing TypeError: required keyword argument 'c' is missing
...@@ -132,6 +132,10 @@ def call2cefd(f): ...@@ -132,6 +132,10 @@ def call2cefd(f):
def call2cfex(f): def call2cfex(f):
f(1,2, c=1, f=2, e=0, x=25) f(1,2, c=1, f=2, e=0, x=25)
def call6argscfexy(f):
args = (1,2,3,4,5,6)
f(*args, c=1, f=2, e=3, x=25, y=11)
def call6cfexy(f): def call6cfexy(f):
f(1,2,3,4,5,6, c=1, f=2, e=3, x=25, y=11) f(1,2,3,4,5,6, c=1, f=2, e=3, x=25, y=11)
......
...@@ -3,10 +3,10 @@ __doc__ = u""" ...@@ -3,10 +3,10 @@ __doc__ = u"""
(1, 2, 3) (1, 2, 3)
>>> spam(1,2) #doctest: +ELLIPSIS >>> spam(1,2) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (2 given) TypeError: spam() takes at least 3 positional arguments (2 given)
>>> spam(1,2,3,4) >>> spam(1,2,3,4)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (4 given) TypeError: spam() takes at most 3 positional arguments (4 given)
>>> spam(1,2,3, a=1) #doctest: +ELLIPSIS >>> spam(1,2,3, a=1) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: 'a' is an invalid keyword argument for this function TypeError: 'a' is an invalid keyword argument for this function
...@@ -19,7 +19,7 @@ __doc__ = u""" ...@@ -19,7 +19,7 @@ __doc__ = u"""
(1, 2, 3, (4, 5, 6, 7, 8, 9)) (1, 2, 3, (4, 5, 6, 7, 8, 9))
>>> grail(1,2) #doctest: +ELLIPSIS >>> grail(1,2) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (2 given) TypeError: grail() takes at least 3 positional arguments (2 given)
>>> grail(1,2,3, a=1) #doctest: +ELLIPSIS >>> grail(1,2,3, a=1) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: 'a' is an invalid keyword argument for this function TypeError: 'a' is an invalid keyword argument for this function
...@@ -28,7 +28,7 @@ __doc__ = u""" ...@@ -28,7 +28,7 @@ __doc__ = u"""
(1, 2, 3, ()) (1, 2, 3, ())
>>> swallow(1,2,3,4) >>> swallow(1,2,3,4)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 3 positional arguments (4 given) TypeError: swallow() takes at most 3 positional arguments (4 given)
>>> swallow(1,2,3, a=1, b=2) >>> swallow(1,2,3, a=1, b=2)
(1, 2, 3, (('a', 1), ('b', 2))) (1, 2, 3, (('a', 1), ('b', 2)))
>>> swallow(1,2,3, x=1) #doctest: +ELLIPSIS >>> swallow(1,2,3, x=1) #doctest: +ELLIPSIS
...@@ -64,13 +64,13 @@ __doc__ = u""" ...@@ -64,13 +64,13 @@ __doc__ = u"""
(('a', 1), ('b', 2)) (('a', 1), ('b', 2))
>>> onlyk(1) >>> onlyk(1)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 0 positional arguments (1 given) TypeError: onlyk() takes at most 0 positional arguments (1 given)
>>> onlyk(1, 2) >>> onlyk(1, 2)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 0 positional arguments (2 given) TypeError: onlyk() takes at most 0 positional arguments (2 given)
>>> onlyk(1, a=1, b=2) >>> onlyk(1, a=1, b=2)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 0 positional arguments (1 given) TypeError: onlyk() takes at most 0 positional arguments (1 given)
>>> tk(a=1) >>> tk(a=1)
(('a', 1),) (('a', 1),)
...@@ -84,10 +84,6 @@ __doc__ = u""" ...@@ -84,10 +84,6 @@ __doc__ = u"""
(1, ('a', 1), ('b', 2)) (1, ('a', 1), ('b', 2))
""" """
import sys, re
if sys.version_info >= (2,6):
__doc__ = re.sub(u"Error: (.*)exactly(.*)", u"Error: \\1at most\\2", __doc__)
import sys, re import sys, re
if sys.version_info >= (2,6): if sys.version_info >= (2,6):
__doc__ = re.sub(u"(ELLIPSIS[^>]*Error: )[^\n]*\n", u"\\1...\n", __doc__, re.M) __doc__ = re.sub(u"(ELLIPSIS[^>]*Error: )[^\n]*\n", u"\\1...\n", __doc__, re.M)
......
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