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/