> I just noticed a module on PyPI to implement this behaviour on Python > functions:
> https://pypi.python.org/pypi/positional This library seem to do the opposite of what you ask and force kwarg only. In [11]: @positional.positional(1) ...: def foo(a=1,b=2): ...: print(a,b) ...: In [12]: foo(a=1,b=2) # should have raised. 1 2 In [13]: foo(1,b=2) 1 2 This seem to be the right thing: https://pypi.python.org/pypi/positionalonly In [1]: @positionalonly(1) ...: def foo(a=1,b=2): ...: print(a,b) In [2]: foo(1, 2) 1 2 In [3]: foo(a=1,b=2) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-3-78db88131ebc> in <module>() ----> 1 foo(a=1,b=2) /Users/bussonniermatthias/anaconda/lib/python3.5/site-packages/positionalonly/__init__.py in fun(*args, **kwargs) 208 ]) 209 raise TypeError("The following parameters of `{}` are positional only.\n" --> 210 "They were used as keywords arguments:\n{}".format(function.__qualname__, lst)) 211 if insertn and len(args) >= insertn: 212 args = args[:insertn] + (None,) + args[insertn:] TypeError: The following parameters of `foo` are positional only. They were used as keywords arguments: - 'a' (1) should be in 0th position -- M On Tue, Feb 28, 2017 at 2:17 PM, M.-A. Lemburg <m...@egenix.com> wrote: > On 28.02.2017 22:17, Victor Stinner wrote: >> Hi, >> >> For technical reasons, many functions of the Python standard libraries >> implemented in C have positional-only parameters. > > Keyword argument handling is comparatively slow and rarely > needed for non-optional positional parameters of built-ins. > > You might make a case for optional ones, but then: how often are > these used in practice to warrant the drop in performance ? > > Note: All this is different for Python methods/functions. The > overhead of keyword parsing is small compared to what Python > has to do to setup new frames for execution. > >> Example: >> ------- >> $ ./python >> Python 3.7.0a0 (default, Feb 25 2017, 04:30:32) >>>>> help(str.replace) >> replace(self, old, new, count=-1, /) # <== notice "/" at the end >> ... >>>>> "a".replace("x", "y") # ok >> 'a' >> >>>>> "a".replace(old="x", new="y") # ERR! >> TypeError: replace() takes at least 2 arguments (0 given) >> ------- >> >> When converting the methods of the builtin str type to the internal >> "Argument Clinic" tool (tool to generate the function signature, >> function docstring and the code to parse arguments in C), I asked if >> we should add support for keyword arguments in str.replace(). The >> answer was quick: no! It's a deliberate design choice. >> >> Quote of Yury Selivanov's message: >> """ >> I think Guido explicitly stated that he doesn't like the idea to >> always allow keyword arguments for all methods. I.e. `str.find('aaa')` >> just reads better than `str.find(needle='aaa')`. Essentially, the idea >> is that for most of the builtins that accept one or two arguments, >> positional-only parameters are better. >> """ >> http://bugs.python.org/issue29286#msg285578 >> >> I just noticed a module on PyPI to implement this behaviour on Python >> functions: >> >> https://pypi.python.org/pypi/positional >> >> My question is: would it make sense to implement this feature in >> Python directly? If yes, what should be the syntax? Use "/" marker? >> Use the @positional() decorator? >> >> Do you see concrete cases where it's a deliberate choice to deny >> passing arguments as keywords? >> >> Don't you like writing int(x="123") instead of int("123")? :-) (I know >> that Serhiy Storshake hates the name of the "x" parameter of the int >> constructor ;-)) > > ... and that's another reason why to avoid them: the naming > of positional parameters was never really taken into account > when writing the C functions and it does even change > sometimes without warning. > >> By the way, I read that "/" marker is unknown by almost all Python >> developers, and [...] syntax should be preferred, but >> inspect.signature() doesn't support this syntax. Maybe we should fix >> signature() and use [...] format instead? > > +1 > >> Replace "replace(self, old, new, count=-1, /)" with "replace(self, >> old, new[, count=-1])" (or maybe even not document the default >> value?). >> >> Python 3.5 help (docstring) uses "S.replace(old, new[, count])". > > Using "count=-1" looks confusing when the method doesn't > allow keyword arguments, so it's probably better to use the 3.5 > style and document the defaults in the doc-string. > > AFAIR, some of these don't even have a (documented) default value. > > -- > Marc-Andre Lemburg > eGenix.com > > Professional Python Services directly from the Experts (#1, Feb 28 2017) >>>> Python Projects, Coaching and Consulting ... http://www.egenix.com/ >>>> Python Database Interfaces ... http://products.egenix.com/ >>>> Plone/Zope Database Interfaces ... http://zope.egenix.com/ > ________________________________________________________________________ > > ::: We implement business ideas - efficiently in both time and costs ::: > > eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 > D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg > Registered at Amtsgericht Duesseldorf: HRB 46611 > http://www.egenix.com/company/contact/ > http://www.malemburg.com/ > > _______________________________________________ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/