On 2/18/16, Pavel Stehule <pavel.stehule@gmail.com> wrote: > it doesn't look badly. Is there any possibility how to emulate it with > Python2 ? What do you think about some similar implementation on Python2?
is similar to doing this which also works in Python2
def f(a, b, *ignore, key1, key2): if ignore: raise TypeError('too many positional arguments')
For our case, we want to accept any number of positional arguments due to compatibility so we don't need or want the check for 'too many positional arguments'.
Note that in both Python 2 and 3, invoking f(1, 2, key1='k1', key2='k2') is just syntactic sugar for constructing the (1, 2) tuple and {'key1': 'k1', 'key2': 'k2'} dict and passing those to f which then unpacks them into a, b, key1 and key2. You see that reflected in the C API where you get PyObject* args and PyObject* kw and you unpack them explicitly with PyArg_ParseTupleAndKeywords or just use tuple and dict calls to peek inside.
What you loose by not having Python3 is that you can't use PyArg_ParseTupleAndKeywords and tell it that detail and so on are keywork only arguments. But because we don't want to unpack args we probably couldn't use that anyway even if we wouldn't support Python2.
Therefore you need to look inside the kw dictionary manually as my example shows. What we could also do is check that the kw dictionary *only* contains detail, hint and so on and raise a TypeError if it has more things to avoid silently accepting stuff like: plpy.error('message', some_param='abc'). In Python3 PyArg_ParseTupleAndKeywords would ensure that, but we need to do it manually.
It looks like good idea. Last version are not breaking compatibility - and I think so it can works.
I wrote the code, that works on Python2 and Python3