
That looks great to me! I also think the '/' syntax looks fine and the pun works. If part of the motivation for position-only arguments was better performance and that motivation still holds water, then it makes sense to allow Python to support that optimization, but I would be happy with just a decorator too. I definitely DON'T like the double-underscore. On top of all the other complaints, I think it's more prone to break code. It's also more ugly than '/' IMHO. On Thu, Mar 2, 2017 at 5:10 AM אלעזר <elazarg@gmail.com> wrote:
Here's a proof-of-concept for the decorator. It does not address the issue of passing aliases to positional arguments to **kwargs - I guess this requires changes in the CPython's core.
(Sorry about the coloring, that's how it's pasted)
from inspect import signature, Parameter from functools import wraps
def positional_only(n): def wrap(f): s = signature(f) params = list(s.parameters.values()) for i in range(n): if params[i].kind != Parameter.POSITIONAL_OR_KEYWORD: raise TypeError('{} has less than {} positional arguments'.format(f.__name__, n)) params[i] = params[i].replace(kind=Parameter.POSITIONAL_ONLY) f.__signature__ = s.replace(parameters=params) @wraps(f) def inner(*args, **kwargs): if len(args) < n: raise TypeError('{} takes at least {} positional arguments'.format(f.__name__, n)) return f(*args, **kwargs) return inner return wrap
@positional_only(2) def f(a, b, c): print(a, b, c)
help(f) # f(a, b, /, c, **kwargs)
f(1, 2, c=2)
# f(1, b=2, c=3) # TypeError: f takes at least 2 positional arguments
@positional_only(3) def g(a, b, *, c): print(a, b, c)
# TypeError: g has less than 3 positional arguments
Elazar _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/