On Wed, Oct 27, 2021 at 2:30 PM Ethan Furman <et...@stoneleaf.us> wrote:
>
> On 10/23/21 5:13 PM, Chris Angelico wrote:
>
>  > PEP: 671
>  > Title: Syntax for late-bound function argument defaults
>
> I have a major concern about the utility of this addition -- it was mentioned 
> already (sorry, I don't remember who) and
> I don't think it has yet been addressed.
>
> Using the `bisect()` function as a stand-in for the 20+ years worth of Python 
> APIs in existence:
>
>      def bisect_right(a, x, lo=0, hi=None, *, key=None):
>          if hi is None:
>              hi = len(a)
>          while lo < hi:
>              ...
>
> That function would be transformed to:
>
>      def bisect_right(a, x, lo=0, @hi=len(a), *, key=None):
>          if hi is None:
>              hi = len(a)
>          while lo < hi:
>              ...
>
>
> Notice that the `None` check is still in the body -- why?  Backwards 
> compatibility: there is code out there that
> actually passes in `None` for `hi`, and removing the None-check in the body 
> will suddenly cause TypeErrors.
>
> This seems like a lot of effort for a very marginal gain.
>

The question then becomes: How important is this feature of being able
to pass None as a stand-in for the length of the list? If it's
important, then don't change the style of the code at all. But since
help(bisect) clearly states that the default is len(a), and doesn't
say anything about passing None, so it would be just as valid to deem
such code to be buggy. Obviously that decision has to be made
individually for each use-case, but one thing is clear: newly-defined
APIs will not need to have None-pollution in this way. Also, anything
that uses a dedicated sentinel should be safe to convert; consider:

# Inspired by socket.create_connection, but simplified:
_USE_GLOBAL_DEFAULT = object()
def connect(timeout=_USE_GLOBAL_DEFAULT):
    if timeout is _USE_GLOBAL_DEFAULT:
        timeout = default_timeout


If any outside caller is reaching into the module and referring to
this underscore-preceded name, it is buggy, and I would have no qualms
in breaking that code. (The inspiration for this can't actually be
converted, since socket.create_connection with the global default just
doesn't call the settimeout() method, but there will be other cases
where the same applies.)

As with every new feature, a decision has to be made as to whether old
code should be changed. This is no different, but I do believe that in
many cases, it will be safe to do so.

ChrisA
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/YBJS3EJOLRKS4FSJDGXNVBMHRM6LQQZH/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to