I’m with Steven.

On Fri, Oct 29, 2021 at 06:22 Chris Angelico <ros...@gmail.com> wrote:

> On Fri, Oct 29, 2021 at 11:52 PM Steven D'Aprano <st...@pearwood.info>
> wrote:
> > > Except that that's still backward-incompatible, since None is a very
> > > common value.
> >
> > How is it backwards incompatible? Any tool that looks at __defaults__
> > finds *exactly* what was there before: a tuple of default values, not a
> > tuple of tuples (desc, value) or (value,) as in your implementation.
>
> It's fundamentally impossible to make this change without some measure
> of backward incompatibility. Is it such an advantage to be almost the
> same? It means that tools will be correct often enough that people
> might not even notice a problem, and then they subtly give a
> completely false value. With my scheme, they *always* give a clear and
> obviously wrong value, and it's easy to see what has to be done.
>
> Python doesn't, as a general rule, opt for things that encourage
> subtle data-dependent bugs.
>
> > With your implementation, it will always lie. Always. Every single time,
> > no exceptions: it will report that the default value is a tuple
> > (desc, value), which is wrong.
>
> Yes, it will clearly need to be updated for the new version. Instead
> of being almost correct, and then flat-out lying in situations where
> it should learn a better way.
>
> > With mine, it will be correct nearly always, especially if we use
> > NotImplemented as the sentinel instead of None. And the cases that it
> > gets wrong will only be the ones that use late-binding. It will never
> > get an early-bound default wrong.
>
> I disagree that "correct nearly always" is a good thing.
>
> > > which is basically the same as I have,
> > > only all in a single attribute.
> >
> > Right. And by combining them into a single attribute, you break
> > backwards compatibility. I think unnecessarily, at the cost of more
> > complexity.
>
> What if, in the future, a third type of optional argument is added -
> such as "leave it unbound, no default given"? How would your scheme
> handle this? Mine handles it just fine: give a new kind of value in
> __defaults__. (Maybe None would work for that.)
>
> > Remember that __defaults__ is writable. What happens if somebody sticks
> > a non-tuple into the __defaults__? Or a tuple with more than two items?
> >
> >     func.__defaults__ = ((desc, value), (descr, value), 999, (1, 2, 3))
>
> Writing to it goes through a checker already. You already can't write
> func.__defaults__ = "foo".
>
> > So under your scheme, the interpreter cannot trust that the defaults are
> > tuples that can be interpreted as (desc, value).
>
> Technically that's true in my current implementation, because I
> haven't written the proper checks, but the interpreter is in full
> control of what goes into that attribute.
>
> > Right, but you said that the early bound defaults **currently** have a
> > None there. They don't. The current status quo of early bound defaults
> > is that they are set to the actual default value, not a tuple with None
> > in it. Obviously you know that. So that's why I'm asking, what have
> > I misunderstood?
>
> You've misunderstood what I meant by "currently". Ignore it. That was
> just one of the open issues.
>
> > > even do up their own from scratch, I would welcome it. It's much
> > > easier to poke holes in an implementation than to actually write one
> > > that is perfect.
> >
> > I've suggested an implementation that, I think, will be less complex and
> > backwards compatible. I don't know if it will be faster. I expect in the
> > common case of early binding, it will be, but what do I know about C?
>
> I asked for someone to WRITE an implementation, not suggest one. :)
> It's easy to poke holes in someone else's plans. Much harder to
> actually write something. Go ahead and put some code behind your
> words, and then we can test them both.
>
> > > And fundamentally, there WILL be behavioural changes
> > > here, so I'm not hugely bothered by the fact that the inspect module
> > > needs to change for this.
> >
> > It's not just the inspect module. __defaults__ is public[1]. Anyone and
> > everyone can read it and write it. Your implementation is breaking
> > backwards compatibility, and I believe you don't need to.
> >
> > [1] Whether it is *officially* public or not, it is de facto public.
> >
>
> What does "de facto public" mean, and does the language guarantee that
> its format will never change?
>
> And, once again, you're offering something that is often correct and
> sometimes a flat-out lie, where I'm offering something that adds a
> clear and obvious structure. If you naively assume that everything in
> __defaults__ is a two-element tuple (which is the case for early-bound
> defaults), you'll get an obvious IndexError when you hit a late-bound
> default, so even a basic adjustment will still be safe. By your
> method, unless something is aware of late defaults, it will subtly get
> things wrong.
>
> 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/BEQ25J4HICMLQVSQNNLGHAZNAXTJ74TL/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-- 
--Guido (mobile)
_______________________________________________
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/HJVU57PV4OUOQEXV5FGOUCY5NYU56OKQ/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to