Mailing List Archive

1 2  View All
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
On Wed, Oct 20, 2021 at 1:16 AM Piotr Waszkiewicz <waszka23@gmail.com>
wrote:

> On Wed, Oct 20, 2021 at 2:33 AM Michael Selik <mike@quantami.com> wrote:
>
>> In case it saves anyone a couple clicks:
>> https://www.python.org/dev/peps/pep-0463/
>> I also prefer more syntactic help with exceptions, rather than more
>> syntax emphasizing None's uniqueness.
>>
>
> Me too, but could you provide me an example where try-except approach is
> more readable when trying to chain attribute lookups (like in the database
> book-publisher-owner example I have provided before).
>

I'd echo the others' examples, taking inspiration from PEP 463.


> If the motivation for this operator is chained lookups, how about adding a
>> feature to the operator module, first? It seems natural to add a
>> keyword-only argument to `attrgetter`, and it's a lighter touch than
>> implementing a new operator. If use becomes widespread, that gives more
>> weight to PEP 505.
>>
>> def attrgetter(*attrs, none_aware=False)
>>
>> https://docs.python.org/3/library/operator.html#operator.attrgetter
>>
>
> I remember using inhouse solution like this at a certain workplace - a
> method accepting list of string arguments and an object, returning the
> value being the result of chained attribute access. And it worked all
> right. The problem I have with such approaches is that the name of the
> attrs are passed as strings.
>

I understand the preference for attributes over strings, but many of the
none-aware examples use keys and indices. If JSON is the main culprit for
deeply nested structures, then you're already using strings and not
attributes. Adding features to `operator` wouldn't preclude accepting PEP
505, so why not get started with a less controversial change that provides
much of the value?

If PEP 505 is accepted, it would need support in the `operator` module.
Might as well design that aspect of the implementation now.
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
Hi,

On Wed, Oct 20, 2021 at 5:44 PM Michael Selik <mike@quantami.com> wrote:

> On Wed, Oct 20, 2021 at 1:16 AM Piotr Waszkiewicz <waszka23@gmail.com>
> wrote:
>
>> On Wed, Oct 20, 2021 at 2:33 AM Michael Selik <mike@quantami.com> wrote:
>>
>>> In case it saves anyone a couple clicks:
>>> https://www.python.org/dev/peps/pep-0463/
>>> I also prefer more syntactic help with exceptions, rather than more
>>> syntax emphasizing None's uniqueness.
>>>
>>
>> Me too, but could you provide me an example where try-except approach is
>> more readable when trying to chain attribute lookups (like in the database
>> book-publisher-owner example I have provided before).
>>
>
> I'd echo the others' examples, taking inspiration from PEP 463.
>

Do you think about something along those lines?
```
phone = book.publisher.owner.phone except AttributeError: None
```

I don't mind this syntax but it would have to be supported by static type
checkers and IDEs. And currently something like this is not:
```
try:
phone = book.publisher.owner.phone
except AttributeError:
phone = None
```

mypy complains:
```
error: Item "None" of "Optional[Publisher]" has no attribute "owner"
```


>
>
>> If the motivation for this operator is chained lookups, how about adding
>>> a feature to the operator module, first? It seems natural to add a
>>> keyword-only argument to `attrgetter`, and it's a lighter touch than
>>> implementing a new operator. If use becomes widespread, that gives more
>>> weight to PEP 505.
>>>
>>> def attrgetter(*attrs, none_aware=False)
>>>
>>> https://docs.python.org/3/library/operator.html#operator.attrgetter
>>>
>>
>> I remember using inhouse solution like this at a certain workplace - a
>> method accepting list of string arguments and an object, returning the
>> value being the result of chained attribute access. And it worked all
>> right. The problem I have with such approaches is that the name of the
>> attrs are passed as strings.
>>
>
> I understand the preference for attributes over strings, but many of the
> none-aware examples use keys and indices. If JSON is the main culprit for
> deeply nested structures, then you're already using strings and not
> attributes. Adding features to `operator` wouldn't preclude accepting PEP
> 505, so why not get started with a less controversial change that provides
> much of the value?
>

I have nothing against introducing such a new feature to the `operator`
apart from this one problem mentioned before (using strings which are not
properly detected by IDE), and I agree that could be a good start.
I've seen chained-attributes-lookups solutions in quite a few places
already and I think that there would actually be people benefiting from
such addition.

Although I must admit that personally I don't see many benefits of using
strings for attribute lookups due to typing and IDE issues mentioned
before. Even for JSON data, in my own projects I tend to write dataclasses
wrapping parsed dict in order to benefit from IDE tooltips.


>
> If PEP 505 is accepted, it would need support in the `operator` module.
> Might as well design that aspect of the implementation now.
>

I'm sorry but I don't know if I understand that sentence correctly. You
mean we would have to add an "explicit" function that behaves like a
maybe-dot operator?
Is it actually a requirement when adding new operators?
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
On Wed, Oct 20, 2021 at 9:18 AM Piotr Waszkiewicz <waszka23@gmail.com>
wrote:

> Do you think about something along those lines?
> ```
> phone = book.publisher.owner.phone except AttributeError: None
> ```
>

Yes, that seems reasonable.


> I don't mind this syntax but it would have to be supported by static type
> checkers and IDEs. And currently something like this is not:
> ```
> try:
> phone = book.publisher.owner.phone
> except AttributeError:
> phone = None
> ```
>
> mypy complains:
> ```
> error: Item "None" of "Optional[Publisher]" has no attribute "owner"
> ```
>

That sounds like a feature request for mypy. Would creating a new operator
make it easier to implement analysis of that situation would mypy? My guess
is not. Checking the AST to see if there's a try/except AttributeError
sounds comparable to checking for the use of a none-aware operator. I'm
completely ignorant of how mypy does its analysis, so that's just a wild
guess.

If PEP 505 is accepted, it would need support in the `operator` module.
>> Might as well design that aspect of the implementation now.
>>
>
> I'm sorry but I don't know if I understand that sentence correctly. You
> mean we would have to add an "explicit" function that behaves like a
> maybe-dot operator? Is it actually a requirement when adding new operators?
>

The documentation of the `operator` module says, "The operator module
exports a set of efficient functions corresponding to the intrinsic
operators of Python." It feels like there's an implicit "all" in there. The
table of correspondences looks exhaustive. I haven't noticed any exceptions.

https://docs.python.org/3/library/operator.html#mapping-operators-to-functions
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
On Wed, Oct 20, 2021 at 9:39 PM Michael Selik <mike@quantami.com> wrote:

>
>
> On Wed, Oct 20, 2021 at 9:18 AM Piotr Waszkiewicz <waszka23@gmail.com>
> wrote:
>
>> Do you think about something along those lines?
>> ```
>> phone = book.publisher.owner.phone except AttributeError: None
>> ```
>>
>
> Yes, that seems reasonable.
>

Nice, I think I would also be able to get used to that notation. It's good
to know that there are others supporting the PEP 463, maybe it'd be
possible to propose it once again.


>
>
>> I don't mind this syntax but it would have to be supported by static type
>> checkers and IDEs. And currently something like this is not:
>> ```
>> try:
>> phone = book.publisher.owner.phone
>> except AttributeError:
>> phone = None
>> ```
>>
>> mypy complains:
>> ```
>> error: Item "None" of "Optional[Publisher]" has no attribute "owner"
>> ```
>>
>
> That sounds like a feature request for mypy. Would creating a new operator
> make it easier to implement analysis of that situation would mypy? My guess
> is not. Checking the AST to see if there's a try/except AttributeError
> sounds comparable to checking for the use of a none-aware operator. I'm
> completely ignorant of how mypy does its analysis, so that's just a wild
> guess.
>

I'm not sure, just wanting to point out that the `AttributeError` syntax is
not completely equivalent to the maybe-dot operator here. This example
would actually hide a real AttributeError problem, e.g. if the `publisher`
didn't have an owner field.
So I guess there may be a need to introduce a new exception type, e.g.
`NoneAttributeAccess` before mypy can safely allow any attribute access in
such situation.


>
> If PEP 505 is accepted, it would need support in the `operator` module.
>>> Might as well design that aspect of the implementation now.
>>>
>>
>> I'm sorry but I don't know if I understand that sentence correctly. You
>> mean we would have to add an "explicit" function that behaves like a
>> maybe-dot operator? Is it actually a requirement when adding new operators?
>>
>
> The documentation of the `operator` module says, "The operator module
> exports a set of efficient functions corresponding to the intrinsic
> operators of Python." It feels like there's an implicit "all" in there. The
> table of correspondences looks exhaustive. I haven't noticed any exceptions.
>
>
> https://docs.python.org/3/library/operator.html#mapping-operators-to-functions
>

Thank you very much, I wasn't aware of that module before. Will look into
that.

I don't want to prolong this conversation too much, as I feel like I get
your point and agree with it to some (rather great) extent. That doesn't
change my attitude towards this PEP 505 proposal though, as I feel that if
the general consensus would be towards accepting this change it will bring
some quality of life improvements in a usual day-to-day work, when dealing
with not-so-ideal code.
I'd be also interested in seeing PEP 463 being resurrected as it looks like
there are some folks here interested in restarting the discussion about it.

Thank you very much for the fruitful discussion and broadening my knowledge.
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
On Tue, Oct 19, 2021 at 05:09:42PM -0700, Michael Selik wrote:

> None and its ilk often conflate too many qualities. For example, is it
> missing because it doesn't exist, it never existed, or because we never
> received a value, despite knowing it must exist?

Does it matter if different functions have different semantic
interpretations for None?


> The languages SAS and R
> support at least 27 varieties of NA, allowing un-tagged, and tagged with
> the letters A-Z to help someone create distinctions between different kinds
> of nothingness. IEEE-754 allows about 16 million possible NaNs, which I
> believe was intended to allow floating point instructions to pass error
> messages along.

Yes, and after something like 30-40 years of IEEE-754 supporting NAN
payloads, the number of systems that actually use them can probably be
counted on the fingers of one hand :-(

Ironically, one of those systems is R, which -- so I have been lead to
believe -- uses distict NANs to represent those 27 tagged NA values.

Back in the 1980s, one of the earliest systems which supported IEEE-754
maths was the Apple Numeric Toolkit. Apple's maths routines generated
NANs with documented payloads for certain errors, e.g:

* NAN(1) invalid sqrt
* NAN(2) invalid addition such as INF + -INF
* NAN(34) invalid argument to inverse trig functions

In a complex computation, it was sometimes useful to see why a NAN was
generated. Alas, when Apple moved their maths routines into hardware,
the MC68881 coprocessor always generated NANs with payload 255, and that
useful debugging information was lost.

30+ years later, and we cannot easily, reliably or portably use NAN
payloads. Most people don't care. If we offerred them a dozen or a
thousand distinct sentinels for all the various kinds of missing data,
how many people would use them and how many would just stick to plain
old None?


> If the motivation for this operator is chained lookups, how about adding a
> feature to the operator module, first? It seems natural to add a
> keyword-only argument to `attrgetter`, and it's a lighter touch than
> implementing a new operator. If use becomes widespread, that gives more
> weight to PEP 505.

I agree that this is a nice way forward, and a useful function in its
own right. The only thing is that I would argue for a different colour
of the bikeshed:

def getattr_chain(obj, *attrs, default):
# like obj.a.b.c.d
# if any attribute is missing,
# raises if default is not given
# otherwise returns default

getattr is far more commonly used than attrgetter.


--
Steve
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/AAHVRF7WXIZRUGBHOVBEB7NEZAYHHL26/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
On Wed, Oct 20, 2021 at 06:17:59PM +0200, Piotr Waszkiewicz wrote:

> Do you think about something along those lines?
> ```
> phone = book.publisher.owner.phone except AttributeError: None
> ```

This is not equivalent to PEP 505's None-aware operators. The semantics
are very different, and it is much less safe.

If you misspell an attribute:

book.publisher.onwer = Owner(...)

then the `except AttributeError` code will silently hide that error and
return None. PEP 505 does not do that.

If you use the wrong type:

book.publisher = "O'Reilly Books"

then the `except` version will silently hide the error and return None.
PEP 505 does not.

Versions of this that rely on catching AttributeError are simply wrong
and are an anti-pattern. They catch too much and silently turn
errors into silent wrong behaviour.

PEP 505 does not fall into that trap.


--
Steve
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/B5LUO5K562IM6667YKDW6N57YEUMJKXG/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
Hello,

Le 21/10/2021 à 07:59, Steven D'Aprano a écrit :
>
> Versions of this that rely on catching AttributeError are simply wrong
> and are an anti-pattern. They catch too much and silently turn
> errors into silent wrong behaviour.
>
> PEP 505 does not fall into that trap.

This is not true as a general rule: the PEP 505 examples with
`dict.get()` do catch too much.

Also, if `None` is not special, you are free to make up your own
`NoValue` sentinel object, which can raise specific exceptions on
attribute access, item access, etc:

class NoValueError(Exception):
pass

class NoValueAttributeError(AttributeError, NoValueError):
pass

and so on…

So this particular point seems solvable.

Cheers,
Baptiste
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/J4R3QHH7GNMJAP6VPP2LVXMAAO2YAKU2/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
On Thu, Oct 21, 2021 at 01:46:27PM +1100, Steven D'Aprano wrote:
> On Tue, Oct 19, 2021 at 05:09:42PM -0700, Michael Selik wrote:

> > If the motivation for this operator is chained lookups, how about adding a
> > feature to the operator module, first? It seems natural to add a
> > keyword-only argument to `attrgetter`, and it's a lighter touch than
> > implementing a new operator. If use becomes widespread, that gives more
> > weight to PEP 505.
>
> I agree that this is a nice way forward, and a useful function in its
> own right.

On further thought, I no longer agree. Or at least, I think we need to
think a lot harder about the API before adding any sort of chained
attribute getter into the stdlib. If we get it wrong, we'll be stuck
with it until Python 5000.

The problem is that any sort of code equivalent to:

try:
return obj.chain.of.attribute.lookups
except AttributeError:
return None

risks silently hiding genuine coding errors. This seems to be an
anti-pattern, or at least a foot-gun. And it is certainly not equivalent
to, or a replacement for, PEP 505.

Same applies to variants similar to attrgetter.



--
Steve
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/IRO7Z2IEV3I7X5EZZRNWCLDMJRCWALGS/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
On Thu, Oct 21, 2021 at 10:49:35AM +0200, Baptiste Carvello wrote:

> > Versions of this that rely on catching AttributeError are simply wrong
> > and are an anti-pattern. They catch too much and silently turn
> > errors into silent wrong behaviour.
> >
> > PEP 505 does not fall into that trap.
>
> This is not true as a general rule: the PEP 505 examples with
> `dict.get()` do catch too much.

The problem there is not the None-aware operators, but the use of
dict.get. That's a good reason to re-think None-aware subscripting.

dict?['key']

will still raise if you mistype the key, while dict.get does not.

Even if we limit ourselves to dict.get:

return obj?.get('spam')?.get('eggs')

doesn't protect against mispellings of the keys, *due to dict.get*, but
it does protect against mispelling "get" (unlikely). More importantly it
also protects against type errors:

obj['spam'] = {'eggs', value} # oops, a set, not a dict

or equivalent. (I don't mean to limit this to just typos.)

Now if we write:

obj?.get('spam')?.get('eggs')

the first attribute lookup will return a set and the second will fail
because sets don't have a get method.

Where as if we use exceptions:

try:
obj['spam]['eggs']
except (TypeError, KeyError):
return None

the error is silently suppressed and we get None when we should get a
TypeError.



--
Steve
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/WYEIZ3IC6P6KN4L2MROV4SBCZ5XOQUV6/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
Most of the discussion so far has been focused on (?.). Tbh though, I'm more interested in (??) and (??=). Just reading through code, I constantly notice boilerplate like this which could easily be substituted.

variable = some_function(...)
if variable is None:
variable = [] # some default value

# a bit better with an assignment expression
if (variable := some_function(...)) is None:
variable = []

# or worse with an if expression
variable = some_function(...) if some_function(...) else []
# also possible with :=, but not much better
variable = x if (x := some_function(...)) else []

# using the coalesce operator would be much more readable IMO
variable = some_function(...) ?? []

If (?.) and (?[) are rejected / deferred, maybe there is interest in seeing at least (??) and (??=) through?
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/7DED2THUJJPBS556YQ4YHH3TN6WGH2UH/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
On Sat, Oct 23, 2021 at 6:20 AM Marc Mueller <cdce8p@gmail.com> wrote:
>
> Most of the discussion so far has been focused on (?.). Tbh though, I'm more interested in (??) and (??=). Just reading through code, I constantly notice boilerplate like this which could easily be substituted.
>
> variable = some_function(...)
> if variable is None:
> variable = [] # some default value
>
> # a bit better with an assignment expression
> if (variable := some_function(...)) is None:
> variable = []
>
> # or worse with an if expression
> variable = some_function(...) if some_function(...) else []
> # also possible with :=, but not much better
> variable = x if (x := some_function(...)) else []

Bear in mind that these last ones are exactly equivalent to the "or"
operator, as they'll use the default if you have any falsy value.

variable = some_function(...) or []

> # using the coalesce operator would be much more readable IMO
> variable = some_function(...) ?? []
>
> If (?.) and (?[) are rejected / deferred, maybe there is interest in seeing at least (??) and (??=) through?

I'm actually more interested in a better idiom for non-constant
function default arguments, since that's the place where this kind of
thing often comes up. A nice ??= operator might help if your default
is None, but if you then change the default to be object(), you can't
use ??= any more. As a bonus, the docs for such an argument could
actually say what the default really is:

def bisect_right(a, x, lo=0, hi=len(a), *, key=None): ...

except that it'd need some adornment to say that it's late-bound.

ChrisA
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/DAD32U6CKSWB3HI322WRKRYYKFNWFPEP/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
> Bear in mind that these last ones are exactly equivalent to the "or"
> operator, as they'll use the default if you have any falsy value.
> variable = some_function(...) or []

Isn't that in itself a good argument in favor of (??) ? By missing to add 'is None', I would have already added a subtle bug that could be quite difficult to find. (??) could prevent that while also being more readable.

> I'm actually more interested in a better idiom for non-constant
> function default arguments, since that's the place where this kind of
> thing often comes up. A nice ??= operator might help if your default
> is None, but if you then change the default to be object(), you can't
> use ??= any more. [...]

True, but from my experience 'None' is just by far the most common default. Why not improve how we handle it?
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/VDMN5ZHPMMBLCHVM63RROZJYAIII74A3/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
Marc Mueller writes:

> True, but from my experience 'None' is just by far the most common
> default. Why not improve how we handle it?

The question is whether this is an improvement in the long run. When
some falsies are expected, in-range values, "if arg is None: ..." or
"x = default if arg is None else arg" is sufficiently precise and
concise. I don't see "arg ?? default" as an improvement worthy of
syntax.

One the minus side, as David Mertz testifies, there is a maze of
missing value use cases, all alike (or is that a missing maze of
values, all alike?) These operators would further encourage
conflating them all into None. At least in theory, that's not an
improvement in handling None, that's a loss of precision in handling
an important subset of Nones.

I just don't see much value in ??. I don't have an opinion on the
?. and ?[] versions. I can see that they could make chained
operations much more concise than nested if ... else expressions, and
at least somewhat more precise (at least if you want to avoid deep
nesting of try ... except KeyError statements, which I suppose most
everybody would like to avoid).

Steve
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/CO7RY5NNCPMYGFH2OYNHU5JWEIP7NGIX/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
On Sun, Oct 24, 2021 at 12:35 AM Marc Mueller <cdce8p@gmail.com> wrote:
>
> > Bear in mind that these last ones are exactly equivalent to the "or"
> > operator, as they'll use the default if you have any falsy value.
> > variable = some_function(...) or []
>
> Isn't that in itself a good argument in favor of (??) ? By missing to add 'is None', I would have already added a subtle bug that could be quite difficult to find. (??) could prevent that while also being more readable.
>

Perhaps, but your alternate versions were identically buggy, which
means that - in all probability - the bug wouldn't have been relevant.
For instance, if you're asking for a file-like object, and will use
stdout if no argument is passed, it's absolutely fine to use None as a
default and "or" to replace it with sys.stdout, because only a
pathological example will actually cause problems. And that's fine.
There are myriad use-cases for a None-coalescing operator that would
work just fine without one; if Python had such an operator, sure, it
could be used, but they're not strong arguments for adding one.

> > I'm actually more interested in a better idiom for non-constant
> > function default arguments, since that's the place where this kind of
> > thing often comes up. A nice ??= operator might help if your default
> > is None, but if you then change the default to be object(), you can't
> > use ??= any more. [...]
>
> True, but from my experience 'None' is just by far the most common default. Why not improve how we handle it?
>

There are three situations to consider here:

1) Situations where there's no falsy value that would make sense
2) Situations where None is used and there are other falsy values that
would make sense
3) Situations where any object makes sense

The only ones where None-coalescing is truly significant are the
second group. In the first group, "or" and "??" would behave
identically, so why bother introducing a new operator? And in the
third group, the default can't be None, so it has to be an
artificially-invented object.

All three would be improved by a late-binding feature, but only a
strict subset of them would benefit from directly replacing None with
something else.

Like several others here, I am much more interested in the operators
that do "if None, give back None, otherwise fetch an attribute/item".
If we end up getting None-coalescing for free along with that, so be
it, but I'm not really pushing for that part. Proper argument
late-binding is an entirely orthogonal proposal, and would have many
benefits that aren't part of PEP 505 or related proposals, but would
do most of what we want from the ?? operator.

PEP 505 has some oddities that are hard to explain, though - and I
mean that not in the sense that the PEP itself is hard to read, but
that I would have to go to some effort to explain what my code does
(picture a mentor/student relationship here). If I offer a line of
code saying <<x = spam()?.ham.eggs or 5>>, what happens if spam
returns None? Unpacking it step by step reveals a bit more complexity
than it first seems to have. Python tries to minimize such situations,
doing them only when there is a very clear benefit (for instance, "3 <
x < 8" is very different from "(3 < x) < 8", but that's because it is
immensely valuable), and I do have misgivings about that part of it.

Otherwise, though, I am in favour of this and would make good use of
it. (And would do so regardless of the ultimate decision on the
chaining.)

ChrisA
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/33M2GBBKPMYRTINEGV5ORG73AXPE643L/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
Hi, I wanted to propose replacing ? with -> in the none aware syntax. This makes the expression look like a chain, and I think that most people intuitively can understand how the chain might get broken (and what would happen in that case). For example:

zipcode = person->.address->['zipcode']

I've proposed this alternative syntax on Doug's github project, and I think he didn't like it so much (or at least, his co-contributor didn't like it), but I still wanted to propose it here as well, because I do think it's a good solution to the complaints that the ? operator looks cryptic.

Best regards,
Maarten
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/UNK66ZORXDNX22IDDFWJHDHVZGPBQETT/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
Hi Maarten,
I like the suggestion but I'm not sure if the real problem with the PEP505
is the symbol/operator used.
Reading through the whole discussion I'm under the impression that the idea
of the None value being treated as an indicator of the missing attribute is
what prevents this PEP from happening.

Apart from that I'm all for it, (probably) regardless of the syntax (as
long as it remains short).

Best regards,
Piotr

On Thu, Sep 15, 2022 at 5:07 PM Maarten Nieber <mnieber@gmail.com> wrote:

> Hi, I wanted to propose replacing ? with -> in the none aware syntax. This
> makes the expression look like a chain, and I think that most people
> intuitively can understand how the chain might get broken (and what would
> happen in that case). For example:
>
> zipcode = person->.address->['zipcode']
>
> I've proposed this alternative syntax on Doug's github project, and I
> think he didn't like it so much (or at least, his co-contributor didn't
> like it), but I still wanted to propose it here as well, because I do think
> it's a good solution to the complaints that the ? operator looks cryptic.
>
> Best regards,
> Maarten
> _______________________________________________
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-leave@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/UNK66ZORXDNX22IDDFWJHDHVZGPBQETT/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
Hi Piotr,

doesn't Doug's reply of 8:03 address this point? As he says, the none-aware operator never gives you None when you ask for a missing attribute (these cases always raise an exception). If we look at these two alternatives

phone1 = book.publisher?.owner.phone
phone2 = book.publisher.owner.phone if book.publisher else None

then they behave exactly the same. If we would misspell "owner" then in both versions we'd get the same AttributeError under the same conditions.

Best,
Maarten
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/KSKTJRNSQSBRYZRY6QQY7B3TZ5J4P2PD/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
Hi Maarten,
I'm sorry for the confusion - it was bad wording on my part.
What I really meant was that the problem with the None-aware operator, and
the reason why PEP505 has not been accepted for such a long time, is that
there's no consensus regarding the need for it (and not necessarily the
problem with the operator used to represent it - although this topic has
also been raised).

Take a look at the response by Steve Dower:
https://mail.python.org/archives/list/python-dev@python.org/message/BRTRKGY6RLTHZJQ2US4LO7DYLSGXQ5GM/

Best regards,
Piotr

On Thu, Sep 15, 2022 at 6:54 PM Maarten Nieber <mnieber@gmail.com> wrote:

> Hi Piotr,
>
> doesn't Doug's reply of 8:03 address this point? As he says, the
> none-aware operator never gives you None when you ask for a missing
> attribute (these cases always raise an exception). If we look at these two
> alternatives
>
> phone1 = book.publisher?.owner.phone
> phone2 = book.publisher.owner.phone if book.publisher else None
>
> then they behave exactly the same. If we would misspell "owner" then in
> both versions we'd get the same AttributeError under the same conditions.
>
> Best,
> Maarten
> _______________________________________________
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-leave@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/KSKTJRNSQSBRYZRY6QQY7B3TZ5J4P2PD/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
Hi all,

I've only here found out that there is a discussion going on about those
none-aware operators and my first thought was "great, finally!". FWIW,
I'd be happy with the syntax suggestion in the PEP, since '?' looks
rather intuitive to me to mean something like "maybe".

However, I then read the mentioned post of Steve Dower, with the final
summary:

> So to summarise my core concern - allowing an API designer to "just
use None" is a cop out, and it lets people write lazy/bad APIs rather
than coming up with good ones.

This is a very good point. In fact, I've never really thought about it
that way and of course he's totally right that "SomeType | None" (or
Optional[SomeType], which also somehow made me feel that this usage is
fairly intended) is not optimal, at least for user defined
types/classes. The problem is, that I never actually thought about his
suggested way. And I wouldn't be surprised if this holds for many other
people as well.

Maybe it would be great to boldly mention these thoughts in the
documentation at an appropriate place. In my opinion, there are at least
the following good places where this would fit nicely:

- The documentation of the dataclasses
(https://docs.python.org/3/library/dataclasses.html), since this is
probably the most common use case for the "| None" pattern. Going
further, the dataclasses functionality might even be extended to make it
simpler to generate such null-types (or however they are called), so
that it is no longer "a tonne more work".

- Linters like pylint could emit a note when seeing the "| None"
pattern, linking to the explanation about why it is possibly not the
best way to do it.

- The documentation of the discussed None-aware operators. Since these
new operators are closely coupled to the arguably suboptimal "| None"
pattern, it is probably good to tell folks right there why they should
consider better alternatives.

As mentioned, I absolutely see Steve's point. However, there are many
Python scripts/programs working without a complex API, where this "|
None" pattern may still have its legitimate uses and the none-aware
operators can make code easier to read (and write).

Best regards,
Philipp
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/Q2MOF5CJ7LSSZMEMB43YVEXD6PFATYTA/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
Personally I think returning None is a fine API design, and IMO the
concerns about this pattern are overblown. Note that X|None is no different
than the "Maybe X" pattern that functional programmers are so fond of.

On Mon, Sep 19, 2022 at 8:02 AM Philipp Burch <phip@hb9etc.ch> wrote:

> Hi all,
>
> I've only here found out that there is a discussion going on about those
> none-aware operators and my first thought was "great, finally!". FWIW,
> I'd be happy with the syntax suggestion in the PEP, since '?' looks
> rather intuitive to me to mean something like "maybe".
>
> However, I then read the mentioned post of Steve Dower, with the final
> summary:
>
> > So to summarise my core concern - allowing an API designer to "just
> use None" is a cop out, and it lets people write lazy/bad APIs rather
> than coming up with good ones.
>
> This is a very good point. In fact, I've never really thought about it
> that way and of course he's totally right that "SomeType | None" (or
> Optional[SomeType], which also somehow made me feel that this usage is
> fairly intended) is not optimal, at least for user defined
> types/classes. The problem is, that I never actually thought about his
> suggested way. And I wouldn't be surprised if this holds for many other
> people as well.
>
> Maybe it would be great to boldly mention these thoughts in the
> documentation at an appropriate place. In my opinion, there are at least
> the following good places where this would fit nicely:
>
> - The documentation of the dataclasses
> (https://docs.python.org/3/library/dataclasses.html), since this is
> probably the most common use case for the "| None" pattern. Going
> further, the dataclasses functionality might even be extended to make it
> simpler to generate such null-types (or however they are called), so
> that it is no longer "a tonne more work".
>
> - Linters like pylint could emit a note when seeing the "| None"
> pattern, linking to the explanation about why it is possibly not the
> best way to do it.
>
> - The documentation of the discussed None-aware operators. Since these
> new operators are closely coupled to the arguably suboptimal "| None"
> pattern, it is probably good to tell folks right there why they should
> consider better alternatives.
>
> As mentioned, I absolutely see Steve's point. However, there are many
> Python scripts/programs working without a complex API, where this "|
> None" pattern may still have its legitimate uses and the none-aware
> operators can make code easier to read (and write).
>
> Best regards,
> Philipp
> _______________________________________________
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-leave@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/Q2MOF5CJ7LSSZMEMB43YVEXD6PFATYTA/
> Code of Conduct: http://python.org/psf/codeofconduct/
>


--
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*
<http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
Hi Philipp,
That's a really good idea, and I'd really want to see it being implemented.

Having said that, I wonder how many people would actually use this concept
of "none-representing" objects. In my 10+ years of programming experience
I've never seen anybody eager to use more complex structures or object
representations of such concepts outside of an academic environment (and
even there usually when dealing with personal or proof-of-concept projects).

Nowadays I write mostly more business-oriented code, and I haven't been
successful in finding a workplace where "business" wants to pay for
preparing "good looking" code - they want a functioning one. That's where
this whole concept of using none values is used the most (at least from my
experience).

So to reiterate: I think that the idea presented by Steve is very
appealing, and I'd really like to work with such projects, but the reality
is that it's really hard to stumble upon such. And I would really much *prefer
to have none-aware operators that would make my life easier working with
"real world" projects that rely too heavily on none values*, even if it's
academically not correct.


On Mon, Sep 19, 2022, 17:06 Philipp Burch <phip@hb9etc.ch> wrote:

> Hi all,
>
> I've only here found out that there is a discussion going on about those
> none-aware operators and my first thought was "great, finally!". FWIW,
> I'd be happy with the syntax suggestion in the PEP, since '?' looks
> rather intuitive to me to mean something like "maybe".
>
> However, I then read the mentioned post of Steve Dower, with the final
> summary:
>
> > So to summarise my core concern - allowing an API designer to "just
> use None" is a cop out, and it lets people write lazy/bad APIs rather
> than coming up with good ones.
>
> This is a very good point. In fact, I've never really thought about it
> that way and of course he's totally right that "SomeType | None" (or
> Optional[SomeType], which also somehow made me feel that this usage is
> fairly intended) is not optimal, at least for user defined
> types/classes. The problem is, that I never actually thought about his
> suggested way. And I wouldn't be surprised if this holds for many other
> people as well.
>
> Maybe it would be great to boldly mention these thoughts in the
> documentation at an appropriate place. In my opinion, there are at least
> the following good places where this would fit nicely:
>
> - The documentation of the dataclasses
> (https://docs.python.org/3/library/dataclasses.html), since this is
> probably the most common use case for the "| None" pattern. Going
> further, the dataclasses functionality might even be extended to make it
> simpler to generate such null-types (or however they are called), so
> that it is no longer "a tonne more work".
>
> - Linters like pylint could emit a note when seeing the "| None"
> pattern, linking to the explanation about why it is possibly not the
> best way to do it.
>
> - The documentation of the discussed None-aware operators. Since these
> new operators are closely coupled to the arguably suboptimal "| None"
> pattern, it is probably good to tell folks right there why they should
> consider better alternatives.
>
> As mentioned, I absolutely see Steve's point. However, there are many
> Python scripts/programs working without a complex API, where this "|
> None" pattern may still have its legitimate uses and the none-aware
> operators can make code easier to read (and write).
>
> Best regards,
> Philipp
> _______________________________________________
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-leave@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/Q2MOF5CJ7LSSZMEMB43YVEXD6PFATYTA/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
On 19. 09. 22 17:58, Guido van Rossum wrote:
> Personally I think returning None is a fine API design, and IMO the
> concerns about this pattern are overblown. Note that X|None is no
> different than the "Maybe X" pattern that functional programmers are so
> fond of.

I must disagree here. With `X|None` there is no way to do
`Maybe[Maybe[X]]`, and FP is all about proper composition.

One practical consequence is that "Maybe X" doesn't have the problem
that PEP 661 (Sentinel Values) tries to solve.


> On Mon, Sep 19, 2022 at 8:02 AM Philipp Burch <phip@hb9etc.ch
> <mailto:phip@hb9etc.ch>> wrote:
>
> Hi all,
>
> I've only here found out that there is a discussion going on about
> those
> none-aware operators and my first thought was "great, finally!". FWIW,
> I'd be happy with the syntax suggestion in the PEP, since '?' looks
> rather intuitive to me to mean something like "maybe".
>
> However, I then read the mentioned post of Steve Dower, with the final
> summary:
>
>  > So to summarise my core concern - allowing an API designer to "just
> use None" is a cop out, and it lets people write lazy/bad APIs rather
> than coming up with good ones.
>
> This is a very good point. In fact, I've never really thought about it
> that way and of course he's totally right that "SomeType | None" (or
> Optional[SomeType], which also somehow made me feel that this usage is
> fairly intended) is not optimal, at least for user defined
> types/classes. The problem is, that I never actually thought about his
> suggested way. And I wouldn't be surprised if this holds for many other
> people as well.
>
> Maybe it would be great to boldly mention these thoughts in the
> documentation at an appropriate place. In my opinion, there are at
> least
> the following good places where this would fit nicely:
>
> - The documentation of the dataclasses
> (https://docs.python.org/3/library/dataclasses.html
> <https://docs.python.org/3/library/dataclasses.html>), since this is
> probably the most common use case for the "| None" pattern. Going
> further, the dataclasses functionality might even be extended to
> make it
> simpler to generate such null-types (or however they are called), so
> that it is no longer "a tonne more work".
>
> - Linters like pylint could emit a note when seeing the "| None"
> pattern, linking to the explanation about why it is possibly not the
> best way to do it.
>
> - The documentation of the discussed None-aware operators. Since these
> new operators are closely coupled to the arguably suboptimal "| None"
> pattern, it is probably good to tell folks right there why they should
> consider better alternatives.
>
> As mentioned, I absolutely see Steve's point. However, there are many
> Python scripts/programs working without a complex API, where this "|
> None" pattern may still have its legitimate uses and the none-aware
> operators can make code easier to read (and write).
>
> Best regards,
> Philipp
> _______________________________________________
> Python-Dev mailing list -- python-dev@python.org
> <mailto:python-dev@python.org>
> To unsubscribe send an email to python-dev-leave@python.org
> <mailto:python-dev-leave@python.org>
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> <https://mail.python.org/mailman3/lists/python-dev.python.org/>
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/Q2MOF5CJ7LSSZMEMB43YVEXD6PFATYTA/ <https://mail.python.org/archives/list/python-dev@python.org/message/Q2MOF5CJ7LSSZMEMB43YVEXD6PFATYTA/>
> Code of Conduct: http://python.org/psf/codeofconduct/
> <http://python.org/psf/codeofconduct/>
>
>
>
> --
> --Guido van Rossum (python.org/~guido <http://python.org/~guido>)
> /Pronouns: he/him //(why is my pronoun here?)/
> <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
>
> _______________________________________________
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-leave@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/7HEZXSLT2A63RDLXTJAOQWGBHNU3WDCR/
> Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/MB6DFTH3CEDKP45YELP4GZ7R7LZSPTZ2/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
On 20. 09. 22 10:59, Petr Viktorin wrote:
> On 19. 09. 22 17:58, Guido van Rossum wrote:
>> Personally I think returning None is a fine API design, and IMO the
>> concerns about this pattern are overblown. Note that X|None is no
>> different than the "Maybe X" pattern that functional programmers are
>> so fond of.
>
> I must disagree here. With `X|None` there is no way to do
> `Maybe[Maybe[X]]`, and FP is all about proper composition.
>
> One practical consequence is that "Maybe X" doesn't have the problem
> that PEP 661 (Sentinel Values) tries to solve.

Sorry, hit Send too soon: I'm not arguing against returning None being
good design. Just the note that compares it to FP's Maybe.


>> On Mon, Sep 19, 2022 at 8:02 AM Philipp Burch <phip@hb9etc.ch
>> <mailto:phip@hb9etc.ch>> wrote:
>>
>>     Hi all,
>>
>>     I've only here found out that there is a discussion going on about
>>     those
>>     none-aware operators and my first thought was "great, finally!".
>> FWIW,
>>     I'd be happy with the syntax suggestion in the PEP, since '?' looks
>>     rather intuitive to me to mean something like "maybe".
>>
>>     However, I then read the mentioned post of Steve Dower, with the
>> final
>>     summary:
>>
>>       > So to summarise my core concern - allowing an API designer to
>> "just
>>     use None" is a cop out, and it lets people write lazy/bad APIs rather
>>     than coming up with good ones.
>>
>>     This is a very good point. In fact, I've never really thought
>> about it
>>     that way and of course he's totally right that "SomeType | None" (or
>>     Optional[SomeType], which also somehow made me feel that this
>> usage is
>>     fairly intended) is not optimal, at least for user defined
>>     types/classes. The problem is, that I never actually thought about
>> his
>>     suggested way. And I wouldn't be surprised if this holds for many
>> other
>>     people as well.
>>
>>     Maybe it would be great to boldly mention these thoughts in the
>>     documentation at an appropriate place. In my opinion, there are at
>>     least
>>     the following good places where this would fit nicely:
>>
>>     - The documentation of the dataclasses
>>     (https://docs.python.org/3/library/dataclasses.html
>>     <https://docs.python.org/3/library/dataclasses.html>), since this is
>>     probably the most common use case for the "| None" pattern. Going
>>     further, the dataclasses functionality might even be extended to
>>     make it
>>     simpler to generate such null-types (or however they are called), so
>>     that it is no longer "a tonne more work".
>>
>>     - Linters like pylint could emit a note when seeing the "| None"
>>     pattern, linking to the explanation about why it is possibly not the
>>     best way to do it.
>>
>>     - The documentation of the discussed None-aware operators. Since
>> these
>>     new operators are closely coupled to the arguably suboptimal "| None"
>>     pattern, it is probably good to tell folks right there why they
>> should
>>     consider better alternatives.
>>
>>     As mentioned, I absolutely see Steve's point. However, there are many
>>     Python scripts/programs working without a complex API, where this "|
>>     None" pattern may still have its legitimate uses and the none-aware
>>     operators can make code easier to read (and write).
>>
>>     Best regards,
>>     Philipp
>>     _______________________________________________
>>     Python-Dev mailing list -- python-dev@python.org
>>     <mailto:python-dev@python.org>
>>     To unsubscribe send an email to python-dev-leave@python.org
>>     <mailto:python-dev-leave@python.org>
>>     https://mail.python.org/mailman3/lists/python-dev.python.org/
>>     <https://mail.python.org/mailman3/lists/python-dev.python.org/>
>>     Message archived at
>>
>> https://mail.python.org/archives/list/python-dev@python.org/message/Q2MOF5CJ7LSSZMEMB43YVEXD6PFATYTA/ <https://mail.python.org/archives/list/python-dev@python.org/message/Q2MOF5CJ7LSSZMEMB43YVEXD6PFATYTA/>
>>     Code of Conduct: http://python.org/psf/codeofconduct/
>>     <http://python.org/psf/codeofconduct/>
>>
>>
>>
>> --
>> --Guido van Rossum (python.org/~guido <http://python.org/~guido>)
>> /Pronouns: he/him //(why is my pronoun here?)/
>> <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
>>
>> _______________________________________________
>> Python-Dev mailing list -- python-dev@python.org
>> To unsubscribe send an email to python-dev-leave@python.org
>> https://mail.python.org/mailman3/lists/python-dev.python.org/
>> Message archived at
>> https://mail.python.org/archives/list/python-dev@python.org/message/7HEZXSLT2A63RDLXTJAOQWGBHNU3WDCR/
>> Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/2SLIUFU5YZJVBSVKYNKWE5ATESAZWYD6/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
On Sun, Sep 18, 2022 at 09:43:26PM +0200, Philipp Burch wrote:

> However, I then read the mentioned post of Steve Dower, with the final
> summary:
>
> > So to summarise my core concern - allowing an API designer to "just
> use None" is a cop out, and it lets people write lazy/bad APIs rather
> than coming up with good ones.
>
> This is a very good point. In fact, I've never really thought about it
> that way and of course he's totally right that "SomeType | None" (or
> Optional[SomeType], which also somehow made me feel that this usage is
> fairly intended) is not optimal, at least for user defined
> types/classes.

I don't think that `SomeType|None` is necessarily a lazy or bad API.
Whether it is "optimal" or not will depend on the specific SomeType
involved, not to mention other tradeoffs and constraints such as time
and money available.

(Oh, to have the luxury of spending two months to "Do It Right" for a
project needed in a week on a budget...)

But what's not "optimal" is expecting everyone who writes a class and
needs to represent the lack of an instance to duplicate those None-like
semantics within the class.

The distinction you make between user-defined and non-user-defined
classes doesn't hold water. If you allow that (say) `int|None` **might**
be acceptable, then why would `Integer|None` **necessarily** be lazy and
bad just because int is written in C and built into the intepreter while
Integer is written in Python by a user?

The laziness/badness of `SomeType|None` must depend on the semantics of
SomeType, not the implementation language or who wrote it.

"Our API was lazy and bad because it uses None, but then it got accepted
into Python as a builtin, so now it is no longer lazy or bad." /s

Of course people can write None-like instances of their SomeType
classes, if it makes sense for their application. But the idea that any
and every use (or even a majority) of Optional types is a "lazy/bad API"
is, I think, unrealistic puritism, not to mention unfairly disparaging
towards the programmers who write those APIs.

> The problem is, that I never actually thought about his suggested way.

Some people have, and found that it doesn't always simplify the API that
much, or at all. If you end up replacing `obj is None` with `obj == NULL`
or `obj.isnull()` then you haven't really gained much.


--
Steven
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/C4GJX5O7FX2WBZMJ6DU5PVI5LUV5NCT5/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: PEP 505 (None-aware operators) for Python 3.11 [ In reply to ]
Hi Steven!

On 21.09.22 13:17, Steven D'Aprano wrote:
> The distinction you make between user-defined and non-user-defined
> classes doesn't hold water. If you allow that (say) `int|None` **might**
> be acceptable, then why would `Integer|None` **necessarily** be lazy and
> bad just because int is written in C and built into the intepreter while
> Integer is written in Python by a user?
>
> The laziness/badness of `SomeType|None` must depend on the semantics of
> SomeType, not the implementation language or who wrote it.
>
> "Our API was lazy and bad because it uses None, but then it got accepted
> into Python as a builtin, so now it is no longer lazy or bad." /s

I considered a while if "user-defined types/classes" is the right
wording, but didn't find a better alternative. The point I'm making is
that `X|None` could especially then hide bugs if X defines attributes
that will often be accessed in a chain. For int or float, there are only
a few methods, which are arguably rarely used and chaining is probably
not used at all. Plus, providing nulltypes for primitives would feel
very awkward.

Consider

```
x: int | None = 5
# ...
if x is not None:
y = 1 << x.bit_cont()
```

The typo with bit_cont() is hidden whenever x is None, so it might be
missed by unit tests with limited coverage. However, using a nullable
variant of it would probably make it look like this:

```
class Int(int):
# ...

class NoneInt(Int):
# ...

x = Int(5) # With the option for NoneInt()
# ...
x_bit_count = x.bit_cont()
if x_bit_count == NoneInt:
y = 1 << x_bit_count
```

This is certainly not pretty for something basic as an int, plus there
will most likely be a performance hit when replacing every int by Int(),
not to mention compatibility issues with APIs/libraries expecting plain int.

On the other hand, more complex classes like in the mentioned publisher
API could indeed profit from such null-types, since a chain like

```
book?.publisher?.owner?.namme
```

will hide the typo with namme whenever any of book, publisher or owner
is None, so there is much more potential here to miss it in a unit test.

This is actually the distinction that I wanted to make, not in the
technical sense if a class is defined in the standard library or not.

>> The problem is, that I never actually thought about his suggested way.
>
> Some people have, and found that it doesn't always simplify the API that
> much, or at all. If you end up replacing `obj is None` with `obj == NULL`
> or `obj.isnull()` then you haven't really gained much.

Certainly. But without None-aware operators, the gain in readability can
be large, if you can just write

```
name = book.publisher.owner.name
if name is not None: # No NoneStr here, see above
# ...
```

versus

```
if (book is not None) and (book.publisher is not None) and ...:
# ...
```

Just to be clear: I've been thankful for the comment and explanation of
Steve Dower, because I've never thought about it that way and now see
constructs in my code, where such a concept really would have simplified
things and improved robustness. For others to profit as well, I would be
glad to see this mentioned in the docs, so that it can be found even
when not actually looking for it.
But I certainly don't want to say that this concept must be followed
everywhere or that "X|None" is necessarily a bad thing. After all, I'd
still love to see Python supporting such None-aware operators.

Best regards,
Philipp
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/ZZ7VO54KYRJY3SATL6XBZZ4AHE54PG6B/
Code of Conduct: http://python.org/psf/codeofconduct/

1 2  View All