Re: [Python-ideas] Python docs page: In what ways is None special

2018-07-23 Thread C Anthony Risinger
On Jul 23, 2018 8:43 PM, "Chris Barker - NOAA Federal via Python-ideas" <
python-ideas@python.org> wrote:


> Procedures return None
> ==
 a = [3,1,2]
 b = a.sort()
 a, b
> ([1, 2, 3], None)

This is less about None than about the convention that mutating
methods return None. Maybe that discussion belongs elsewhere.


> None is default return value
> =
 def fn(): pass
> ...
 fn() # No response!
 print(fn()) # Here's why.
> None

Yup.


I believe these two are related and an artifact of how code/function
objects always leave *something* on TOS/top-of-stack.

IIRC even module objects have a discarded "return value" (in CPython at
least). This internal, unseen, and very-much-special-syntax-worthy value,
is None other.

-- 

C Anthony
___
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] A better PEP 505 (test package: coalescing)

2018-07-23 Thread David Mertz
I proposed a very toy example of a coalescing class that would solve the
problem solved by brand new syntax in PEP 505.  In my 5 minute version,
there were several faults or limitations.  For one, the class I wrote was
misnamed, since it wasn't really about None-coalescing, but rather about
exception-free nested access.

I've written a more robust version at https://pypi.org/project/coalescing/.
I encourage issues or contributions at
https://github.com/DavidMertz/coalesce.  Mind you, this is still a
few-hour-of-effort version, not rigorously tested.

I want to thank Antoine Pitrou for proposing using Graham Dumpleton's
warpt.ObjectProxy (which is truly magic).  In almost no lines, I think I
have something perhaps even better than PyMaybe.  In particular, most of
the time, there is no need to do an explicit `.unbox()` call... but at the
suggestion of several people, I changed my first API to optionally pass a
default value other than None within that method, if desired.  I even made
laziness in getting that value the default (but switchable) behavior.

Dumpleton's magic means that boxed values can do pretty much anything the
raw values can, so can generally ignore the .unbox() call at the end.
Perhaps most magic of all, you can even ASSIGN into proxied values and that
gets written to the original value (not shown in the doctests below).  This
adds something powerful that PEP 505 is completely unable to do.

I believe that I have captured ALL the semantics of PEP 505 with no changes
to Python syntax... and in a way that reads FAR better than all those new
operators do.

Access messy nested data structures

GreedyAccess will keep marching down trees even if failure occurred earlier:

>>> from coalesce import GreedyAccess, make_test
>>> cfg = make_test()
>>> GreedyAccess(cfg).user.profile.song

>>> GreedyAccess(cfg).user.profile.song + ' and spam'
'Nightclubbing and spam'
>>> GreedyAccess(cfg).user.profile.food

>>> print(GreedyAccess(cfg).user.profile.food.unbox())
None
>>> GreedyAccess(cfg).user.profile.food.unbox('spam')
'spam'
>>> GreedyAccess(cfg).user.profile.food.unbox('spam') + ' and spam'
'spam and spam'

NoneCoalesce only descends until a None is encountered.  Accessing
attributes
or keys of None will still fail:

>>> from coalesce import NoneCoalesce
>>> NoneCoalesce(cfg).user.profile.song

>>> NoneCoalesce(cfg).user.profile.song.unbox()
'Nightclubbing'
>>> NoneCoalesce(cfg).user.profile.food
Traceback (most recent call last):
...
AttributeError: 'types.SimpleNamespace' object has no attribute 'food'
>>> NoneCoalesce(cfg).user.profile


>>> val = None
>>> print(NoneCoalesce(val).attr)
None

We provide for returning values other than None if some other default is
more
useful for your use case (a zero-argument lambda function would often be
useful here):

>>> def say_spam():
... return "spam"
...
>>> GreedyAccess(cfg).user.profile.food.unbox(say_spam)
'spam'
>>> GreedyAccess(cfg).user.profile.food.unbox(say_spam, lazy=False)
#doctest: +ELLIPSIS



-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Python docs page: In what ways is None special

2018-07-23 Thread Chris Barker - NOAA Federal via Python-ideas
I agree that some more docs on the specialness of None (and, to a
lessor extent, True and False).

A few comments:

> None is a keyword
> ==
 None = 0
> SyntaxError: can't assign to keyword

One of the implications of this is that “None” will always be the
Singleton None object — so you can (and should) use:

Something is None

To test for None.

> The Command Line Interpreter hides None
> =
 None

That’s a good one to highlight!

>
> None is false in a boolean context
> ==
 bool(None)
> False

Maybe this belongs more in a discussion of “Falseyness”

> Procedures return None
> ==
 a = [3,1,2]
 b = a.sort()
 a, b
> ([1, 2, 3], None)

This is less about None than about the convention that mutating
methods return None. Maybe that discussion belongs elsewhere.

> Dictionary get returns None if not found
> ==
 {}.get('dne') is None
> True

Belongs with dict docs really, and not really true — dict.get()
returns the default value, which is None be default.

> None is default return value
> =
 def fn(): pass
> ...
 fn() # No response!
 print(fn()) # Here's why.
> None

Yup.

> None is used as a sentinel default value
> ==
> Particularly useful when default value must be determined
> in body of function.
> ---
> def insort_right(a, x, lo=0, hi=None):
># ...
>if hi is None:
>hi = len(a)
> ---

This is also a convention — and primarily applies to mutable defaults,
which you hardly ever want to assign directly.

So a good example of None being used as a sentinel, but nog really
anything special about None.

-CHB
> /
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Python docs page: In what ways is None special

2018-07-23 Thread Chris Barker - NOAA Federal via Python-ideas
>lot. Actually, the ?. and ?[
> operators seem like they'd be much more useful if I did more JSON
> processing -

This has been mentioned a lot in this discussion—

Maybe what we need is a smarter JSON processing package, rather than
new operators.

Granted, these operators would help the authors of suck a package(s),
but if the bulk of users didn’t need them, then no point in adding
them to the language.

-CHB
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Steven D'Aprano
On Mon, Jul 23, 2018 at 01:55:48PM -0400, David Mertz wrote:
> On Mon, Jul 23, 2018 at 1:28 PM Steven D'Aprano  wrote:
> 
> > There's the first bug right there. foo.bar.blim ought to raise
> > AttributeError, since there is no blim attribute defined on foo.bar.
> >
> 
> Note my observation that this is deliberately different semantics.  I want
> to solve the underlying need, not simply emulate the less useful semantics
> of PEP 505.

I know that "laziness and hubris" are virtues in a programmer, but the 
PEP authors describe use-cases where *testing for None* is precisely the 
semantics wanted. What are your use-cases for greedily swallowing 
AttributeError?

Before telling the PEP authors that they have misunderstood their own 
uses-cases and that their need isn't what they thought (coalescing None) 
but something radically different which they have already explicitly 
rejected (suppressing AttributeError), you better have some damn 
compelling use-cases.

"Laziness and hubris" are supposed to be virtues in programmers, but 
when you insist that people have their own use-cases wrong, and that the 
designers of C#, Dart and Swift made a serious mistake introducing this 
feature, you ought to back it up with more than just an assertion.


[...]
> It does look like PyMaybe does much of what I'm thinking of.  I didn't
> think my toy was the first or best implementation.

Are you aware that the PEP includes pymaybe as a rejected idea?


> > But we aren't entering such a world, at least not in PEP 505. Attribute
> > access can fail.
> > spam.eggs = 42
> > spam?.eggs?.upper
> > is still going to raise AttributeError, because eggs is not None, it is an
> > int, and ints don't have an attribute "upper".
> 
> True enough.  But it's extremely difficult to imagine a real-world case
> where those particular semantics are actually particularly useful.

You can't imagine why it would be useful to NOT suppress the exception 
from a coding error like trying to uppercase an int.



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Steven D'Aprano
On Mon, Jul 23, 2018 at 10:53:11AM -0700, Grégory Lielens wrote:

> The proto here swallow and short circuit on attribute error. Changing 
> to do it on Noneness is easy, and you can choose between the two 
> behavior: it's a strength compared to the operator approach.

Being able to choose between one desirable behaviour and one 
undesirable, rejected behaviour is *not* a strength.

PEP 505 has a section explaining why catching AttributeError 
is undesirable. I find the reasons it gives are compelling.

Can you explain why you reject the PEP's arguments against catching 
AttributeError?



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread MRAB

On 2018-07-23 23:05, Giampaolo Rodola' wrote:

On Mon, Jul 23, 2018 at 6:53 PM Steven D'Aprano  wrote:


On Mon, Jul 23, 2018 at 02:04:17PM +0200, Giampaolo Rodola' wrote:
> "a?.b" does two and that's a fundamental difference (explicitness).

How is "two things" less explicit than "one thing"?
Comments like the above is why I think that "explicit" and "implicit"
are used to mean "I like it" and "I don't like it" rather than being
objective arguments, or indeed having anything to do with explicitness
or implicitness.


This:

 v = a?.b

...*implicitly* checks if value is not None [and continues execution].


It's no more implicit than 'or' checking for falseness.


This:

 v = a
 if a.b is not None:
 v = a.b

...*explicitly* checks if value is not None and continues execution.
If for some reason '?'[ is also going to swallow LookupError then
*that* would further decrease explicitness, because LookupError would
be nowhere in sight, the same way "if", "is", "not", "None", ":", "new
line" are nowhere in sight in the 'a?.b' example. Some argued "A ?? B"
is less explicit than "A if A is not None else B" for the same reason.
One may argue that silently returning None instead of raising
AttributeError is also less explicit.
This - and this only - is my argument about explicitness. It doesn't
have to do with how many things are hidden behind an import statement
or what happens on sorted() (that's comparing apples and oranges).
I hope it's clear now.


> It
> does so by introducing a brand new operator ("?") which can be spelled
> in two forms ("a?.b" and "a?[b]") by using two adjacent symbols not
> interrupted by any space, which is an absolute first in the Python
> syntax

It isn't a first. Many existing operators use two adjacent symbols not
interrupted by a space:

e.g.  ==  <=  >=  !=  **  //  << >> +=  -=  *= etc.


You say 'a == b'. You can't say 'a ?. b' (not that it matters, it
would be less intuitive anyway). You can't because '.?' is the only
couple of contiguous symbols requiring "something" before and after
with no spaces in between, and that's a first in the language.


You _can_ say 'a ?. b', just as you _can_ say 'a . b'.

Also, it's not a couple of contiguous symbols, it's a single symbol, 
just as '<=' is a single symbol (and you can't put a space in the middle 
of that either).

[snip]
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Stephan Hoyer
On Mon, Jul 23, 2018 at 4:19 PM Stefan Behnel  wrote:

> Stephan Hoyer schrieb am 23.07.2018 um 18:01:
> > I think a SliceHelper class like this is a reasonable solution, but there
> > would be a lot of value having it a standard place somewhere in the
> > standard library (e.g., operator.subscript).
> >
> > Both pandas and NumPy include this helper object under different names
> > (pandas.IndexSlice and numpy.index_exp / numpy.s_), but it would be
> > surprising/unexpected for pandas/numpy specific helpers to show up when
> not
> > using one of those libraries. I do the exact same sorts of indexing
> > manipulations with xarray, dask and TensorFlow.
> >
> > Given that this is basically a simple feature to make it easier to work
> > with Python syntax (so there's no danger it will change in the future), I
> > think there is a lot to be said for putting it in the standard library in
> > one place so it's obvious what to use and users don't have to relearn
> that
> > name for this object and/or reimplement it.
>
> Please copy that comment into the ticket and ask for it to be reopened.
>
> https://bugs.python.org/issue24379
>
> Stefan
>

I basically did exactly that last week! See
https://bugs.python.org/issue24379#msg321966

I was told, "You may get more traction on python-ideas" :)

Cheers,
Stephan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Stefan Behnel
David Mertz schrieb am 23.07.2018 um 16:12:
> The need addressed by PEP 505 is real; it's also MUCH more niche and
> uncommon than something that would merit new syntax.  Moreover, the actual
> legitimate purpose served by the PEP 505 syntax is easily served by
> existing Python simply by using a wrapper class.

The discussion so far made it clear to me that

a) there is a use case for this feature, although I never needed it myself
b) throwing new syntax at it is not the right solution

Especially since there seem to be slightly diverging ideas about the exact
details in behaviour. Since this can be done in form of a library, people
should just drop it into a couple of competing libraries and let users
choose what they like better in their specific situation. And since we
already have a PEP now, let's continue to use it as a basis for discussion
about how these libraries should best behave in general and what mistakes
they should avoid.

Stefan

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread David Mertz
I find pandas.IndexSlice makes a lot of operations easier to spell. As
simple as it is, it's a valuable capability. Rather than every library—or a
number of them anyway—creating the same 4 lines of code with a different
name, it would be much nicer to have it as a class __getitem__ method, e.g.
slice[...], or as an attribute of the slice object, such as
slice.literal[...].

On Mon, Jul 23, 2018, 7:20 PM Stefan Behnel  wrote:

> Stephan Hoyer schrieb am 23.07.2018 um 18:01:
> > On Mon, Jul 23, 2018 at 4:24 AM Paul Moore wrote:
> >
> >> I thought the reason the proposal got nowhere was because it's pretty
> >> simple to define it yourself:
> >>
> >> >>> class SliceHelper:
> >> ... def __getitem__(self, slice):
> >> ... return slice
> >> ...
> >> >>> SH = SliceHelper()
> >> >>> SH[1::3]
> >> slice(1, None, 3)
> >>
> >> Did I miss something significant about why this wasn't sufficient?
> >
> >
> > I think a SliceHelper class like this is a reasonable solution, but there
> > would be a lot of value having it a standard place somewhere in the
> > standard library (e.g., operator.subscript).
> >
> > Both pandas and NumPy include this helper object under different names
> > (pandas.IndexSlice and numpy.index_exp / numpy.s_), but it would be
> > surprising/unexpected for pandas/numpy specific helpers to show up when
> not
> > using one of those libraries. I do the exact same sorts of indexing
> > manipulations with xarray, dask and TensorFlow.
> >
> > Given that this is basically a simple feature to make it easier to work
> > with Python syntax (so there's no danger it will change in the future), I
> > think there is a lot to be said for putting it in the standard library in
> > one place so it's obvious what to use and users don't have to relearn
> that
> > name for this object and/or reimplement it.
>
> Please copy that comment into the ticket and ask for it to be reopened.
>
> https://bugs.python.org/issue24379
>
> Stefan
>
> ___
> 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/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Kyle Lahnakoski

I agree a class can provide a very good alternative to PEP505.  I built
one a while ago, and still use it https://github.com/klahnakoski/mo-dots
for most my data transformation code.

The library only boxes dicts and lists, which removes the need for
.unbox() in many of my use cases. My point is, if a class is chosen
instead of PEP505, I doubt the unboxing will be a big issue.


On 2018-07-23 11:12, David Mertz wrote:
> Here is a way of solving the "deep attribute access to messy data"
> problem that is:
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Stefan Behnel
Stephan Hoyer schrieb am 23.07.2018 um 18:01:
> On Mon, Jul 23, 2018 at 4:24 AM Paul Moore wrote:
> 
>> I thought the reason the proposal got nowhere was because it's pretty
>> simple to define it yourself:
>>
>> >>> class SliceHelper:
>> ... def __getitem__(self, slice):
>> ... return slice
>> ...
>> >>> SH = SliceHelper()
>> >>> SH[1::3]
>> slice(1, None, 3)
>>
>> Did I miss something significant about why this wasn't sufficient?
> 
> 
> I think a SliceHelper class like this is a reasonable solution, but there
> would be a lot of value having it a standard place somewhere in the
> standard library (e.g., operator.subscript).
> 
> Both pandas and NumPy include this helper object under different names
> (pandas.IndexSlice and numpy.index_exp / numpy.s_), but it would be
> surprising/unexpected for pandas/numpy specific helpers to show up when not
> using one of those libraries. I do the exact same sorts of indexing
> manipulations with xarray, dask and TensorFlow.
> 
> Given that this is basically a simple feature to make it easier to work
> with Python syntax (so there's no danger it will change in the future), I
> think there is a lot to be said for putting it in the standard library in
> one place so it's obvious what to use and users don't have to relearn that
> name for this object and/or reimplement it.

Please copy that comment into the ticket and ask for it to be reopened.

https://bugs.python.org/issue24379

Stefan

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Thomas Jollans
On 24/07/18 00:39, Chris Angelico wrote:
> On Tue, Jul 24, 2018 at 8:22 AM, Thomas Jollans  wrote:
>> On 18/07/18 19:43, Steve Dower wrote:
>>> When a ``None``-aware operator is present, the left-to-right evaluation
>>> may be
>>> short-circuited. For example, ``await a?.b(c).d?[e]`` is evaluated::
>>>
>>> _v = a
>>> if _v is not None:
>>> _v = _v.b
>>> _v = _v(c)
>>> _v = _v.d
>>> if _v is not None:
>>> _v = _v[e]
>>> await _v
>>
>> ## NB I only skimmed most of this thread after reading the PEP, so I ##
>> ##apologize if this has been discussed before and I missed it.   ##
>>
>> I quite like the general idea, but I'm nervous about a rather
>> fundamental aspect: This adds a special case in which you can't add
>> parentheses to an expression involving a chain of operators to make
>> precedence and evaluation order clear.
>>
>> To use your example,
>> a ?? 2 ** b ?? 3   ===  (a ?? 2) ** (b ?? 3) # fine
>>
>> In the present day,
>> a or 2 + 3 * c()   ===   a or (2 + (3 * (c(
>>
>> a.b(c).d[e]   ===   (((a.b)(c)).d)[e] # silly, but true.
>>
>> Short-circuiting doesn't break this. With and and or, the expression
>> that's short-circuited away is a self-contained expression in imagined
>> (or actual) parentheses.
> 
> What about:
> 
> 5 < x < 10
> 
> Can you add parentheses to that to "make precedence and evaluation order 
> clear"?


Well, no.

TJ wrote:
> [...] becomes one single, long, atomic expression,
> just like a comparison chain. [...]
  

This does leave the question,

> Is introducing the idea of an "attribute reference, call and
> subscription" chain worth it?



___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Chris Angelico
On Tue, Jul 24, 2018 at 8:22 AM, Thomas Jollans  wrote:
> On 18/07/18 19:43, Steve Dower wrote:
>> When a ``None``-aware operator is present, the left-to-right evaluation
>> may be
>> short-circuited. For example, ``await a?.b(c).d?[e]`` is evaluated::
>>
>> _v = a
>> if _v is not None:
>> _v = _v.b
>> _v = _v(c)
>> _v = _v.d
>> if _v is not None:
>> _v = _v[e]
>> await _v
>
> ## NB I only skimmed most of this thread after reading the PEP, so I ##
> ##apologize if this has been discussed before and I missed it.   ##
>
> I quite like the general idea, but I'm nervous about a rather
> fundamental aspect: This adds a special case in which you can't add
> parentheses to an expression involving a chain of operators to make
> precedence and evaluation order clear.
>
> To use your example,
> a ?? 2 ** b ?? 3   ===  (a ?? 2) ** (b ?? 3) # fine
>
> In the present day,
> a or 2 + 3 * c()   ===   a or (2 + (3 * (c(
>
> a.b(c).d[e]   ===   (((a.b)(c)).d)[e] # silly, but true.
>
> Short-circuiting doesn't break this. With and and or, the expression
> that's short-circuited away is a self-contained expression in imagined
> (or actual) parentheses.

What about:

5 < x < 10

Can you add parentheses to that to "make precedence and evaluation order clear"?

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Thomas Jollans
On 18/07/18 19:43, Steve Dower wrote:
> When a ``None``-aware operator is present, the left-to-right evaluation
> may be
> short-circuited. For example, ``await a?.b(c).d?[e]`` is evaluated::
> 
>     _v = a
>     if _v is not None:
>     _v = _v.b
>     _v = _v(c)
>     _v = _v.d
>     if _v is not None:
>     _v = _v[e]
>     await _v

## NB I only skimmed most of this thread after reading the PEP, so I ##
##apologize if this has been discussed before and I missed it.   ##

I quite like the general idea, but I'm nervous about a rather
fundamental aspect: This adds a special case in which you can't add
parentheses to an expression involving a chain of operators to make
precedence and evaluation order clear.

To use your example,
a ?? 2 ** b ?? 3   ===  (a ?? 2) ** (b ?? 3) # fine

In the present day,
a or 2 + 3 * c()   ===   a or (2 + (3 * (c(

a.b(c).d[e]   ===   (((a.b)(c)).d)[e] # silly, but true.

Short-circuiting doesn't break this. With and and or, the expression
that's short-circuited away is a self-contained expression in imagined
(or actual) parentheses.

With this ?. operator, the chain a?.b(c).d?[e] can no longer be broken
into sub-expressions, but becomes one single, long, atomic expression,
just like a comparison chain. If I try:

(a?.b)(c).d?[e] # TypeError: 'NoneType' object is not callable
a?.(b(c).d?[e]) # SyntaxError, and illogical

Also, where does this end? if a is None, is (a?.b,c()) equal to None or
(None, c())? Presumably the latter because of operator precedence, but
still.

Is introducing the idea of an "attribute reference, call and
subscription" chain worth it?

This could be fixed by adding a maybe-call ?( operator, which would allow

a?.b?(C())?.d?[E()]
   ===
a?.b)
?( C() ))
 ?.d)
   ?[ E() ])

_v = a
_v = _v.b if _v is not None else None
_v = _v(C()) if _v is not None else None
_v = _v.d if _v is not None else None
_v = _v[E()] if _v is not None else None

with None falling all the way through, and the calls to C() and E()
being short-circuited out.

Of course you need either attribute-call-subscription chains or ‘?()’
maybe-calls for ‘?.’ to be worthwhile at all, since otherwise you can't
write None-aware method calls.

Aside:  other languages cited
  From a quick look at the C# docs linked in the PEP [1], I'm guessing
  that C# allows A?.B?.C?.Do(E), but does not allow A?.B?.C.Do(E). Does
  anybody know? Obviously method calls work differently in C# than in
  Python.

  Dart? I dunno. The docs aren't as thorough.


Am I missing something?


Cheers
Thomas


[1]
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Chris Angelico
On Tue, Jul 24, 2018 at 8:05 AM, Giampaolo Rodola'  wrote:
> The argument about this is that '?.' short-circuits execution
> *silently*. Instead of AttributeError you get None. You may chain ?.
> in order to lazily traverse a long tree, inadvertently assign None to
> a variable, continue code execution and fail later rather than sooner:
>
>  email = request?.context?.user?.email  # None
>  ...
>  sendmail(subject, body, email)
>
> Some (Antoine) rightly argued this may even have security implications
> (replace 'email' with 'password').
>

This thread has been long and rambling. Can you elaborate on the
security implications? Normally, I would expect that a password of
None would always fail to validate.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Giampaolo Rodola'
On Mon, Jul 23, 2018 at 6:53 PM Steven D'Aprano  wrote:
>
> On Mon, Jul 23, 2018 at 02:04:17PM +0200, Giampaolo Rodola' wrote:
> > "a?.b" does two and that's a fundamental difference (explicitness).
>
> How is "two things" less explicit than "one thing"?
> Comments like the above is why I think that "explicit" and "implicit"
> are used to mean "I like it" and "I don't like it" rather than being
> objective arguments, or indeed having anything to do with explicitness
> or implicitness.

This:

v = a?.b

...*implicitly* checks if value is not None [and continues execution]. This:

v = a
if a.b is not None:
v = a.b

...*explicitly* checks if value is not None and continues execution.
If for some reason '?'[ is also going to swallow LookupError then
*that* would further decrease explicitness, because LookupError would
be nowhere in sight, the same way "if", "is", "not", "None", ":", "new
line" are nowhere in sight in the 'a?.b' example. Some argued "A ?? B"
is less explicit than "A if A is not None else B" for the same reason.
One may argue that silently returning None instead of raising
AttributeError is also less explicit.
This - and this only - is my argument about explicitness. It doesn't
have to do with how many things are hidden behind an import statement
or what happens on sorted() (that's comparing apples and oranges).
I hope it's clear now.

> > It
> > does so by introducing a brand new operator ("?") which can be spelled
> > in two forms ("a?.b" and "a?[b]") by using two adjacent symbols not
> > interrupted by any space, which is an absolute first in the Python
> > syntax
>
> It isn't a first. Many existing operators use two adjacent symbols not
> interrupted by a space:
>
> e.g.  ==  <=  >=  !=  **  //  << >> +=  -=  *= etc.

You say 'a == b'. You can't say 'a ?. b' (not that it matters, it
would be less intuitive anyway). You can't because '.?' is the only
couple of contiguous symbols requiring "something" before and after
with no spaces in between, and that's a first in the language. The
argument about this is that it's ugly and less readable. My additional
argument at the beginning of this thread was that if you add PEP-572
to the mix you dangerously enter into Perl territory:

foo(x=(x := a?.b?[c] ?? d))

> > and that's the second and fundamental difference. I cannot move
> > the same criticism to the "a.b" form: it's simpler, it does one thing
> > and it uses one symbol.
>
> You criticised ?. because it can interupt left-to-right execution:
>
> a?.b?.c?.d
>
> True. But so can a single dot:
>
> a.b.c.d
>
> is no more guaranteed to execute all the way to the right.

The difference is that 'a.b.c.d' will result in AttributeError as soon
as something is None while 'a?.b?.c?.d' will return None instead.

> Likewise the logical operators "or" and "and" are designed to
> short-circuit. If ?? and friends are a mistake because they
> short-circuit, why aren't "or" and "and" mistakes?
> I'm not asking this as a rhetorical question. If you think there is a
> reason why it is okay for or/and to short-circuit, but it is bad for ??
> and friends to short-circuit, then please explain why they are
> different. I will be very happy to listen to your arguments.

The argument about this is that '?.' short-circuits execution
*silently*. Instead of AttributeError you get None. You may chain ?.
in order to lazily traverse a long tree, inadvertently assign None to
a variable, continue code execution and fail later rather than sooner:

 email = request?.context?.user?.email  # None
 ...
 sendmail(subject, body, email)

Some (Antoine) rightly argued this may even have security implications
(replace 'email' with 'password').

-- 
Giampaolo - http://grodola.blogspot.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/


Re: [Python-ideas] Add function readbyte to asyncio.StreamReader

2018-07-23 Thread Gustavo Carneiro
Well, even if it is worth, i.e. your use case is not rare enough, I would
suggest at least making it private, readexactly can call this specialised
function if nbytes==1:

def _readbyte(self):
   

def readexactly(self, num):
   if num == 1:
  return self._readbyte()
  ... the rest stays the same..


But to be honest, you are probably better off managing the buffer yourself:
Just call, e.g., stream.read(4096), it will return a buffer of up to 4k
length, then you can iterate over the buffer byte by byte until the
condition is met, repeat until the end of stream, or whatever.


On Sun, 22 Jul 2018 at 12:11, Jörn Heissler 
wrote:

> Hello,
>
> I'm implementing a protocol where I need to read individual bytes until
> a condition is met (value & 0x80 == 0).
>
> My current approach is: value = (await reader.readexactly(1))[0]
>
> To speed this up, I propose that a new function is added to
> asyncio.StreamReader: value = await reader.readbyte()
>
> I duplicated readexactly and stripped out some parts. Below code appears
> to work:
>
> async def readbyte(self):
> if self._exception is not None:
> raise self._exception
>
> while not self._buffer:
> if self._eof:
> raise EOFError()
> await self._wait_for_data('readbyte')
>
> data = self._buffer[0]
> del self._buffer[0]
> self._maybe_resume_transport()
> return data
>
> For comparing the speed, I'm receiving a 50 MiB file byte-by-byte.
>
> cpython-3.7.0:
> readexactly: 42.43 seconds
> readbyte   : 22.05 seconds
> speedup: 92.4%
>
> pypy3-v6.0.0:
> readexactly: 3.21 seconds
> readbyte   : 2.76 seconds
> speedup: 16.3%
>
> Thanks
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
Gustavo J. A. M. Carneiro
Gambit Research
"The universe is always one step beyond logic." -- Frank Herbert
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread George Leslie-Waksman
May I propose `slice.L` as in "slice literal":

```
class slice:
...
class L:
"""Slice literal.

slice.L[1:2:3, 1] -> (slice(1, 2, 3), slice(1))
"""

@classmethod
def __class_getitem__(cls, item):
return item
```

On Mon, Jul 23, 2018 at 12:02 PM Joseph Jevnik  wrote:

> I still think that 'operator.subscript' would be valuable to me for
> all of the same reasons discussed in the previous threads and issues.
> I don't understand why it was reverted without any serious discussion
> given that it was already accepted and many people find this useful.
>
> On Mon, Jul 23, 2018 at 2:38 PM, Serhiy Storchaka 
> wrote:
> > 23.07.18 18:16, Guido van Rossum пише:
> >>
> >> On Mon, Jul 23, 2018 at 3:24 AM, Jeroen Demeyer  >> > wrote:
> >>
> >> On 2018-07-23 11:58, Grégory Lielens wrote:
> >>
> >> Not sure slice[1::3] can be done
> >>
> >>
> >> It can be done. Since "slice" is a class, it would require a
> >> metaclass though.
> >>
> >>
> >> Since PEP 560 it won't need a metaclass -- it can be implemented as
> >> __class_getitem__.
> >
> >
> > Do you bless using __class_getitem__ for something other than typing?
> >
> >
> > ___
> > 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/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Grégory Lielens
Short circuit is indeed the main difference. 
Makes me re-think about the None trigger subclasses of invalid operations 
exceptions.
Like None.a trigger a NoneAttributeError(AttributeError), and so on...
I think it solves many issues without much problems nor syntax changes, but 
probably I miss something...

Sure, it's a big change, but maybe less so than 3 non-classic operators working 
only on None...___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Michel Desmoulin



Le 23/07/2018 à 17:12, David Mertz a écrit :
> The need addressed by PEP 505 is real; it's also MUCH more niche and
> uncommon than something that would merit new syntax.  Moreover, the
> actual legitimate purpose served by the PEP 505 syntax is easily served
> by existing Python simply by using a wrapper class.
>
> Here is a way of solving the "deep attribute access to messy data"
> problem that is:
>
> (1) Much more explicit
> (2) Requires no change in syntax
> (3) Will not be a bug magnet
> (4) Inasmuch as there are semantic traps, they are announced by the use
> of a class whose documentation would be pointed to for readers
>
> The API that could be useful might be something like this:
>
> In [1]: from none_aware import NoneAware
> In [2]: from types import SimpleNamespace
> In [3]: foo = SimpleNamespace()
> In [4]: foo.bar = SimpleNamespace()
> In [5]: foo.bar.baz = SimpleNamespace()
> In [6]: foo.bar.baz.blat = 42
> In [7]: NoneAware(foo).bar.blim
> Out[7]: 
> In [8]: NoneAware(foo).bar.blim.unbox()
> In [9]: NoneAware(foo).bar.baz.blat.unbox()
> Out[9]: 42
> In [10]: NoneAware(foo).bar.baz.blat
> Out[10]: 
> In [11]: NoneAware(foo).bar.baz.flam.unbox()
> In [12]: NoneAware(foo).bar.baz.flam
> Out[12]: 
This has existed as libs for a while:

https://github.com/ekampf/pymaybe


It's interest is much more limited than in Haskell because in Python,
calls are not lazy, objects are dynamic and function calls are expensive.


Take the following:

foo().bar[0]

Doing it safely would be:

val = foo()

try:
val = val.bar
except AttributeError:
val = None
else:
try:
val = val[0]
except KeyError:
val = None

Clearly we see that the operation goes up to the end if everything goes
right. Otherwise, it jumps to the default value.

With the operator proposal:

val = foo()?.bar?[0]

The "?" operator is like "or" / "and", and it will shotcircuit as well.

With the try / else proposal:

val = try foo().bar[0] else None

This is supposed to transform this ast to into the first try/except
form. So it shortcircuit as well.

But with your proposal, it becomes:

val = maybe(foo()).bar[0].or_else(None)

Which means

foo() # call

maybe(foo()) # call

maybe(foo()).__getattr__('bar') # call

maybe(foo()).__getattr__('bar').__getitem__(0) # call

maybe(foo()).__getattr__('bar').__getitem__(0).or_else(None) # call

There is no shortcircuit, you get 5 calls in all cases, plus the maybe
object proxing the call to the underlying value every time. So that's 7
calls, added to the try/excepts you still have behind the scene.

Plus, you don't get the same calls depending of the values, but the
switch is implicit and behind the maybe object: no linter can save you
from a typo.

So yes, it works right now. But it's a suboptimal solution.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Rhodri James

On 23/07/18 19:21, David Mertz wrote:

On Mon, Jul 23, 2018 at 2:12 PM Rhodri James  wrote:


How are you supposed to do method calling, the equivalent of
"foo?.bar()" ?  "NoneAware(foo).bar.unbox()()" looks downright weird.
Is there more magic in NoneAware to cover this case?  (Not that I think
we should be encouraging people to do this, but...)



Is there more magic? I don't know, and I don't really care that much.
That's the point.  This is just a plain old Python class that will work
back to probably Python 1.4 or so.  If you want to write a version that has
just the right amount of magic, you are free to.


I care only in as much as you were proposing an incomplete solution (in 
my eyes at least).  I'm pretty convinced by now I would never use it.



In my opinion, the need at issue is worthwhile, but niche.  Using a special
class to deal with such a case is absolutely the right level of
abstraction.  Syntax is not! So sure, figure out how to tweak the API to be
most useful, find a better name for the class, etc.


I think part of my point was that a special class is not as readable or 
trap-free as writing the conditions out explicitly, given the unexpected 
"boxed" results, which makes me question whether the issue *is* worthwhile.



I wouldn't think it terrible if a class like this (but better) found a home
in the standard library, but it doesn't deserve more prominence than that.
Not even builtins, and *definitely* not syntax.


I think I might find it terrible.

--
Rhodri James *-* Kynesim Ltd
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Joseph Jevnik
I still think that 'operator.subscript' would be valuable to me for
all of the same reasons discussed in the previous threads and issues.
I don't understand why it was reverted without any serious discussion
given that it was already accepted and many people find this useful.

On Mon, Jul 23, 2018 at 2:38 PM, Serhiy Storchaka  wrote:
> 23.07.18 18:16, Guido van Rossum пише:
>>
>> On Mon, Jul 23, 2018 at 3:24 AM, Jeroen Demeyer > > wrote:
>>
>> On 2018-07-23 11:58, Grégory Lielens wrote:
>>
>> Not sure slice[1::3] can be done
>>
>>
>> It can be done. Since "slice" is a class, it would require a
>> metaclass though.
>>
>>
>> Since PEP 560 it won't need a metaclass -- it can be implemented as
>> __class_getitem__.
>
>
> Do you bless using __class_getitem__ for something other than typing?
>
>
> ___
> 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/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Jonathan Fine
Humour warning.

Serhiy wrote:

> Do you bless using __class_getitem__ for something other than typing?

As in https://perldoc.perl.org/functions/bless.html, perhaps?

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Mark E. Haase
On Mon, Jul 23, 2018 at 2:12 PM Rhodri James  wrote:

>
> How are you supposed to do method calling, the equivalent of
> "foo?.bar()" ?  "NoneAware(foo).bar.unbox()()" looks downright weird.
> Is there more magic in NoneAware to cover this case?  (Not that I think
> we should be encouraging people to do this, but...)
>
>
In PyMaybe, you would do this:

maybe(foo).bar().or_else(None)
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Serhiy Storchaka

23.07.18 18:16, Guido van Rossum пише:
On Mon, Jul 23, 2018 at 3:24 AM, Jeroen Demeyer 
> wrote:


On 2018-07-23 11:58, Grégory Lielens wrote:

Not sure slice[1::3] can be done


It can be done. Since "slice" is a class, it would require a
metaclass though.


Since PEP 560 it won't need a metaclass -- it can be implemented as 
__class_getitem__.


Do you bless using __class_getitem__ for something other than typing?

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Python docs page: In what ways is None special

2018-07-23 Thread Jörn Heissler
On Mon, Jul 23, 2018 at 10:03:10 +0100, Jonathan Fine wrote:
> I thought, a page on how None is special would be nice.
> I've not found such a page on the web. We do have
> ===
> https://docs.python.org/3/library/constants.html

Hi,

there's also
https://docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy

None

This type has a single value. There is a single object with this
value. This object is accessed through the built-in name None. It is
used to signify the absence of a value in many situations, e.g., it
is returned from functions that don’t explicitly return anything.
Its truth value is false.


Cheers
Jörn Heissler
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread David Mertz
On Mon, Jul 23, 2018 at 2:12 PM Rhodri James  wrote:

> How are you supposed to do method calling, the equivalent of
> "foo?.bar()" ?  "NoneAware(foo).bar.unbox()()" looks downright weird.
> Is there more magic in NoneAware to cover this case?  (Not that I think
> we should be encouraging people to do this, but...)
>

Is there more magic? I don't know, and I don't really care that much.
That's the point.  This is just a plain old Python class that will work
back to probably Python 1.4 or so.  If you want to write a version that has
just the right amount of magic, you are free to.

That said, I *DID* give it the wrong name in my first post of this thread.
GreedyAccess is more accurate, and a NoneCoalesce class would behave
somewhat differently.

In my opinion, the need at issue is worthwhile, but niche.  Using a special
class to deal with such a case is absolutely the right level of
abstraction.  Syntax is not! So sure, figure out how to tweak the API to be
most useful, find a better name for the class, etc.

I wouldn't think it terrible if a class like this (but better) found a home
in the standard library, but it doesn't deserve more prominence than that.
Not even builtins, and *definitely* not syntax.

-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Rhodri James

On 23/07/18 16:12, David Mertz wrote:

Here is a way of solving the "deep attribute access to messy data" problem


Before we go too far, and /pace/ Steve's work, how real is this problem? 
 I get that there is a use in accessing JSON trees, but this feels 
awfully like a rather specific issue about avoiding cleaning data before 
using it.  As such, should be really be encouraging it?


(For the avoidance of doubt, this refers to the proposed ?. and ?[] 
operators.



that is:

(1) Much more explicit
(2) Requires no change in syntax
(3) Will not be a bug magnet
(4) Inasmuch as there are semantic traps, they are announced by the use of
a class whose documentation would be pointed to for readers


Worthy goals.


The API that could be useful might be something like this:

In [1]: from none_aware import NoneAware
In [2]: from types import SimpleNamespace
In [3]: foo = SimpleNamespace()
In [4]: foo.bar = SimpleNamespace()
In [5]: foo.bar.baz = SimpleNamespace()
In [6]: foo.bar.baz.blat = 42
In [7]: NoneAware(foo).bar.blim
Out[7]: 


...and here's the first semantic trap.  I was expecting to get None back 
there, and even your pre-announcement in goal (4) didn't stop me 
puzzling over it for a couple of minutes.  The only reason I wasn't 
expecting an AttributeError was that I was confident you wouldn't 
propose this without doing something magic to effectively override the 
meaning of "."  A naive user might be very surprised.



In [8]: NoneAware(foo).bar.blim.unbox()
In [9]: NoneAware(foo).bar.baz.blat.unbox()
Out[9]: 42


[snip]


I don't disagree that needing to call .unbox() at the end of the chained
attribute access is a little bit ugly.  But it's a lot less ugly than large
family of new operators.  And honestly, it's a nice way of being explicit
about the fact that we're entering then leaving a special world where
attribute accesses don't fail.


You and I have very different definitions of "nice" ;-)  I have to say 
it's questionable which of "?." and "NoneAware()...unbox()" are uglier. 
Then again, I go back to my original comment: is this really a problem 
we want to solve?


How are you supposed to do method calling, the equivalent of 
"foo?.bar()" ?  "NoneAware(foo).bar.unbox()()" looks downright weird. 
Is there more magic in NoneAware to cover this case?  (Not that I think 
we should be encouraging people to do this, but...)


--
Rhodri James *-* Kynesim Ltd
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Python docs page: In what ways is None special

2018-07-23 Thread David Mertz
I think your description of the uses of None is really great.  There's
definitely no reason it cannot be a blog post immediately, but perhaps at
some later point included in The Python Tutorial.

On Mon, Jul 23, 2018 at 8:39 AM Jonathan Fine  wrote:

> Hi Steve
>
> You wrote
>
> > I think your document would be a great blog post. I don't think it is
> > very helpful as part of the standard documention, as it is more a
> > collection of arbitrary facts about None than a coherent "big picture"
> > document.
>
> Thank you. That's nice. However, I think there is, or should be, more
> coherence than you're seeing.
>
> Here's something I forgot to say. For standard documentation I was
> thinking The Python Tutorial.  For example, the Brief Tour.
> https://docs.python.org/3/tutorial/stdlib.html
> https://docs.python.org/3/tutorial/stdlib2.html
>
> That said, a blog post would be useful stepping stone, and the
> standard documentation later. (Know where your heading, take one step
> at a time.)
>
> Once again, thank you for your comment.
>
> --
> Jonathan
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread David Mertz
On Mon, Jul 23, 2018 at 1:28 PM Steven D'Aprano  wrote:

> There's the first bug right there. foo.bar.blim ought to raise
> AttributeError, since there is no blim attribute defined on foo.bar.
>

Note my observation that this is deliberately different semantics.  I want
to solve the underlying need, not simply emulate the less useful semantics
of PEP 505.  But those same semantics COULD be perfectly well emulated with
a similar class.


> > In [8]: NoneAware(foo).bar.blim.unbox()
> > In [9]: NoneAware(foo).bar.baz.blat.unbox()
> > Out[9]: 42
>
> How many bugs will be caused by people forgetting to unbox when they're
> done?
>

Far fewer and far more easily caught.  When the object you get wherever the
real failure happens is ` ` or the
like, the source of the problem become dead obvious.  Having `None`
somewhere unexpected is much more mysterious and difficult to diagnose.

That said, NoneAware is the wrong name for the class I wrote.  Maybe
GreedyAccess would be a better name.  Perhaps I'll make slightly less toy
implementations of an actual NoneCoalesce and GreedyAccess class and post
in this thread and/or on PyPI.

It does look like PyMaybe does much of what I'm thinking of.  I didn't
think my toy was the first or best implementation.


> But we aren't entering such a world, at least not in PEP 505. Attribute
> access can fail.



> spam.eggs = 42

spam?.eggs?.upper



> is still going to raise AttributeError, because eggs is not None, it is an
> int, and ints don't have an attribute "upper".


True enough.  But it's extremely difficult to imagine a real-world case
where those particular semantics are actually particularly useful.  I guess
my revulsion at the syntax blinded me to the fact that the semantics are
actually pretty bad on their own.


> How does your class implement short-circuit behaviour?
>

You mean if we want something like this?

favorite = GreedyAccess(cfg,
sentinel=ExpensiveLookup()).user.profile.food.unbox()

It doesn't.  Something else (like PyMaybe) could defer the computation
using a lambda or other means.  My toy code doesn't do that.  We could also
avoid the visible lambda by doing an 'iscallable(sentinel)' and only
calling it if it turns out to be needed, but that might be too magical.
E.g.:

# If we fail, favorite = ExpensiveLookup(), by magic
favorite = GreedyAccess(cfg,
sentinel=ExpensiveLookup).user.profile.food.unbox()

So we don't like operators like ?? because its too cryptic, but you're
> happy to have one-character class and property names.
>

No, I'm not happy with that.  I was just pointing out that code golf is
possible for someone who really wants it.  I'm happy to spend a few
characters for readability.  But one COULD write:

from nested import GreedyAccess as G
G._ = G.unbox


> What happens if you have an attribute that happens to be
> called "unbox" in your attribute look-up chain?
>

Don't use this class and/or modify the API slightly? This is getting
trite.  My 5 minute code isn't a final proposal, just a way of seeing a
napkin-sketch of a better approach.

-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Grégory Lielens
The proto here swallow and short circuit on attribute error. Changing to do it 
on Noneness is easy, and you can choose between the two behavior: it's a 
strength compared to the operator approach.

It's working in current python, another strength.

I think short-circuit behavior is similar: once stopping condition has been 
met, the gard object cascade till the end of the nested attribute lookup. Like 
None do for the operator.

More complex stuff when None-coalescing attribute access is mixed with normal 
access is better done with operators.
Maybe complex operations fine of the middle of the access chain would also be 
easier with the operators.

How many times would you encounter that in real cases? I bet on very few.
In those few case, would a one line ?. chain expression be better than a 
multiple line logic with temporaries? I think no.

That's my feeling, but in the absence of concrete examples, feelings are ok.___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Steven D'Aprano
On Mon, Jul 23, 2018 at 11:12:45AM -0400, David Mertz wrote:

> Here is a way of solving the "deep attribute access to messy data" problem
> that is:
> 
> (1) Much more explicit
> (2) Requires no change in syntax
> (3) Will not be a bug magnet

That's one opinion.


> (4) Inasmuch as there are semantic traps, they are announced by the use of
> a class whose documentation would be pointed to for readers

Operators have documentation too. If you think people won't read the 
documentation for the operator, what makes you think they're read the 
documentation for the class?


> The API that could be useful might be something like this:
> 
> In [1]: from none_aware import NoneAware
> In [2]: from types import SimpleNamespace
> In [3]: foo = SimpleNamespace()
> In [4]: foo.bar = SimpleNamespace()
> In [5]: foo.bar.baz = SimpleNamespace()
> In [6]: foo.bar.baz.blat = 42
> In [7]: NoneAware(foo).bar.blim
> Out[7]: 

There's the first bug right there. foo.bar.blim ought to raise 
AttributeError, since there is no blim attribute defined on foo.bar.

Reminder: the proposal is for a null-coalescing operator, not an 
AttributeError suppressing operator.

The PEP is explicit that catching AttributeError is rejected:

https://www.python.org/dev/peps/pep-0505/#id21


> In [8]: NoneAware(foo).bar.blim.unbox()
> In [9]: NoneAware(foo).bar.baz.blat.unbox()
> Out[9]: 42

How many bugs will be caused by people forgetting to unbox when they're 
done?


> In [10]: NoneAware(foo).bar.baz.blat
> Out[10]: 
> In [11]: NoneAware(foo).bar.baz.flam.unbox()

That ought to be AttributeError again, since there is no "flam" 
attribute defined on foo.bar.baz.


> In [12]: NoneAware(foo).bar.baz.flam
> Out[12]: 
> 
> 
> The particular names I use are nothing special, and better ones might be
> found.  I just called the class NoneAware and the "escape" method
> `.unbox()` because that seemed intuitive at first brush.
> 
> I don't disagree that needing to call .unbox() at the end of the chained
> attribute access is a little bit ugly.  But it's a lot less ugly than large
> family of new operators.  And honestly, it's a nice way of being explicit
> about the fact that we're entering then leaving a special world where
> attribute accesses don't fail.

But we aren't entering such a world, at least not in PEP 505. Attribute 
access can fail.

spam.eggs = 42

spam?.eggs?.upper

is still going to raise AttributeError, because eggs is not None, it is 
an int, and ints don't have an attribute "upper".


> I haven't implemented the equivalent dictionary lookups in the below.  That
> would be straightforward, and I'm sure my 5 minute throwaway code could be
> improved in other ways also.  But something better than this in the
> standard library would address ALL the actual needs described in PEP 505.

How does your class implement short-circuit behaviour?


> Even the pattern Steve Dower is especially fond of like:
> 
> favorite = cfg?.user?.profile?.food ?? "Spam"
> 
> 
> (i.e. a configuration may be incomplete at any level, if levels are missing
> default favorite food is Spam).  We could simply spell that:
> 
> favorite = NoneAware(cfg, "Spam").user.profile.food.unbox()
> 
> 
> I think that's 14 characters more in this example, but still compact.  We
> could get that down to 2 characters if we used one-letter names for the
> class and method.  I suppose down to zero characters if .unbox() was a
> property.

So we don't like operators like ?? because its too cryptic, but you're 
happy to have one-character class and property names.

favorite = N(cfg, "Spam").user.profile.food.u


What happens if you have an attribute that happens to be 
called "unbox" in your attribute look-up chain?

result = NoneAware(something, "default").spam.foo.unbox.eggs.unbox()



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Mark E. Haase
On Mon, Jul 23, 2018 at 11:34 AM Robert Vanden Eynde 
wrote:

> The default could be at the end with an argument to unboxing :
>
> favorite = NoneAware(cfg).user.profile.food.unbox("Spam")
>

That's what PyMaybe does:

https://pymaybe.readthedocs.io/en/latest/readme.html#examples-use-cases

PyMaybe is a great implementation of the idea, but it's obviously limited
in what it can do. It doesn't have short-circuiting (but it uses lambda to
approximate it). It swallows a multitude of attribute and look up errors.
It doesn't support coalescing. And it can't be used with any library that
isn't PyMaybe-aware.

For people who want to explore deeply nested objects/dictionaries (perhaps
from unserialized JSON), there's also a pure Python library for that:

http://objectpath.org/
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread David Mertz
Btw. I *do* realize that the semantics of my suggested NoneAware class is
different from the coalescing syntax.  I just look at whether attribute
access succeeds or fails in that code, not whether the starting value is
specifically None (nor any particular sentinel).

I believe that that behavior better fits the ACTUAL need underlying these
ideas (i.e. potentially deeply nested but messy data; from JSON or similar
sources).  If we wanted to match the semantics of PEP 505 more exactly, it
would be easy enough to compare a current level of the hierarchy to None
specifically rather than check more generically "is this a thing that has
that attribute?"

However, if the PEP 505 semantics really are the ones most desirable (i.e.
including raising AttributeError on things that are
not-None-but-don't-have-attribute), that's perfectly straightforward to
implement using existing syntax and an API very close to what I suggest.

On Mon, Jul 23, 2018 at 11:12 AM David Mertz  wrote:

> The need addressed by PEP 505 is real; it's also MUCH more niche and
> uncommon than something that would merit new syntax.  Moreover, the actual
> legitimate purpose served by the PEP 505 syntax is easily served by
> existing Python simply by using a wrapper class.
>
> Here is a way of solving the "deep attribute access to messy data" problem
> that is:
>
> (1) Much more explicit
> (2) Requires no change in syntax
> (3) Will not be a bug magnet
> (4) Inasmuch as there are semantic traps, they are announced by the use of
> a class whose documentation would be pointed to for readers
>
> The API that could be useful might be something like this:
>
> In [1]: from none_aware import NoneAware
> In [2]: from types import SimpleNamespace
> In [3]: foo = SimpleNamespace()
> In [4]: foo.bar = SimpleNamespace()
> In [5]: foo.bar.baz = SimpleNamespace()
> In [6]: foo.bar.baz.blat = 42
> In [7]: NoneAware(foo).bar.blim
> Out[7]: 
> In [8]: NoneAware(foo).bar.blim.unbox()
> In [9]: NoneAware(foo).bar.baz.blat.unbox()
> Out[9]: 42
> In [10]: NoneAware(foo).bar.baz.blat
> Out[10]: 
> In [11]: NoneAware(foo).bar.baz.flam.unbox()
> In [12]: NoneAware(foo).bar.baz.flam
> Out[12]: 
>
>
> The particular names I use are nothing special, and better ones might be
> found.  I just called the class NoneAware and the "escape" method
> `.unbox()` because that seemed intuitive at first brush.
>
> I don't disagree that needing to call .unbox() at the end of the chained
> attribute access is a little bit ugly.  But it's a lot less ugly than large
> family of new operators.  And honestly, it's a nice way of being explicit
> about the fact that we're entering then leaving a special world where
> attribute accesses don't fail.
>
> I haven't implemented the equivalent dictionary lookups in the below.
> That would be straightforward, and I'm sure my 5 minute throwaway code
> could be improved in other ways also.  But something better than this in
> the standard library would address ALL the actual needs described in PEP
> 505.  Even the pattern Steve Dower is especially fond of like:
>
> favorite = cfg?.user?.profile?.food ?? "Spam"
>
>
> (i.e. a configuration may be incomplete at any level, if levels are
> missing default favorite food is Spam).  We could simply spell that:
>
> favorite = NoneAware(cfg, "Spam").user.profile.food.unbox()
>
>
> I think that's 14 characters more in this example, but still compact.  We
> could get that down to 2 characters if we used one-letter names for the
> class and method.  I suppose down to zero characters if .unbox() was a
> property.
>
> So completely toy implementation:
>
> class NoneAware(object):
> def __init__(self, thing, sentinel=None):
> self.thing = thing
> self.sentinel = sentinal
>
> def __getattr__(self, attr):
> try:
> return NoneAware(getattr(self.thing, attr))
> except AttributeError:
> return NoneAware(self.sentinel)
>
> def unbox(self):
> return self.thing
>
> --
> Keeping medicines from the bloodstreams of the sick; food
> from the bellies of the hungry; books from the hands of the
> uneducated; technology from the underdeveloped; and putting
> advocates of freedom in prisons.  Intellectual property is
> to the 21st century what the slave trade was to the 16th.
>


-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread David Mertz
On Mon, Jul 23, 2018 at 12:47 PM Antoine Pitrou  wrote:

> > favorite = cfg?.user?.profile?.food ?? "Spam"
> > favorite = NoneAware(cfg, "Spam").user.profile.food.unbox()
>


> You could use .__call__() instead of .unbox().  Also you can make
> unboxing unnecessary in most cases by having your class proxy most
> operations, like weakref.proxy does.  The "wrapt" library may help with
> that: http://wrapt.readthedocs.io/en/latest/wrappers.html


I'm not sure I entirely understand how that class proxy could be made
transparent.  Maybe you can make a toy implementation to show me?  How can
we make this work?

favorite = NoneAware(cfg, "Spam").user.profile.food + "and more spam"

I just noticed in my scratch directory that I had implemented almost the
same thing a year ago when this discussion last came up.  It's simple
enough that the code was almost the same back then.  I had included
`.__getitem__()` in that version, but had not considered sentinels.

However, one thing I *did* implement was `.__call__()`, but that reminds me
of why your idea cannot work.  I had it either call or fall back to more
boxing.  The end point of the chained attributes (or dict lookups) can
perfectly well be a callable.  E.g.

favorite = NoneAware(cfg, "Spam").user.profile.get_food()

Well, that's not going to work in my current toy code either since it would
need to be:

favorite = NoneAware(cfg, "Spam").user.profile.get_food.unbox()()

But I could implement special stuff for "if the tail is a callable, unbox
it automatically", I suppose.

However, it would be fundamentally ambiguous, I think, whether those final
parens should mean "unbox" or "call".  Or I guess if calling *always* meant
"unbox" we could have:

favorite = NoneAware(cfg, "Spam").user.profile.get_food()()

That feels weird to me though.

-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Steven D'Aprano
On Sun, Jul 22, 2018 at 11:54:19AM +1000, Steven D'Aprano wrote:

> In my opinion, writing
> 
> expression if expression is None else default
> 
> is the *opposite* of Pythonic, it is verbose and the DRY violation is 
> inelegant (as well as inefficient). I'd much rather use:
> 
> expression ?? default
> 
> although with PEP 572 approved, there is an alternative:
> 
> temp := expression if temp is None else default


I was mistaken. That would need to be written as:

temp if (temp := expression) is None else default

which is obscure enough for me to prefer the ?? syntax again.



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Stephan Hoyer
On Mon, Jul 23, 2018 at 4:24 AM Paul Moore  wrote:

> I thought the reason the proposal got nowhere was because it's pretty
> simple to define it yourself:
>
> >>> class SliceHelper:
> ... def __getitem__(self, slice):
> ... return slice
> ...
> >>> SH = SliceHelper()
> >>> SH[1::3]
> slice(1, None, 3)
>
> Did I miss something significant about why this wasn't sufficient?


I think a SliceHelper class like this is a reasonable solution, but there
would be a lot of value having it a standard place somewhere in the
standard library (e.g., operator.subscript).

Both pandas and NumPy include this helper object under different names
(pandas.IndexSlice and numpy.index_exp / numpy.s_), but it would be
surprising/unexpected for pandas/numpy specific helpers to show up when not
using one of those libraries. I do the exact same sorts of indexing
manipulations with xarray, dask and TensorFlow.

Given that this is basically a simple feature to make it easier to work
with Python syntax (so there's no danger it will change in the future), I
think there is a lot to be said for putting it in the standard library in
one place so it's obvious what to use and users don't have to relearn that
name for this object and/or reimplement it.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread MRAB

On 2018-07-23 13:04, Giampaolo Rodola' wrote:

On Mon, Jul 23, 2018 at 3:12 AM Steven D'Aprano  wrote:

> ? has no spaces, it's literally "variable names interrupted by
> question marks" and evaluation can stop at any time while scanning the
> line from left to right.

Just like ordinary attribute access.

This is the point I was making earlier: you accept existing punctuation
doing these things:

try:
obj.spam.egsg.tomato.cheese  # oops a typo
except AttributeError:
# evaluation can stop at any time
...

while demanding a higher standard for new punctuation.

All of your criticisms of ? punctuation applies to . as well.


I don't think they do. For once, "a.b" does one and one thing only,
"a?.b" does two and that's a fundamental difference (explicitness). It
does so by introducing a brand new operator ("?") which can be spelled
in two forms ("a?.b" and "a?[b]") by using two adjacent symbols not
interrupted by any space, which is an absolute first in the Python
syntax and that's the second and fundamental difference. I cannot move
the same criticism to the "a.b" form: it's simpler, it does one thing
and it uses one symbol.


[snip]
I think you're misunderstanding something: we're not talking about a 
special operator "?" that somehow combines with existing operators, 
we're talking about completely new and separate operators "?.", "?[", 
etc., which resemble the existing ".", "[", etc.

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Steven D'Aprano
On Mon, Jul 23, 2018 at 02:04:17PM +0200, Giampaolo Rodola' wrote:

[I wrote this]
> > This is the point I was making earlier: you accept existing punctuation
> > doing these things:
> >
> > try:
> > obj.spam.egsg.tomato.cheese  # oops a typo
> > except AttributeError:
> > # evaluation can stop at any time
> > ...
> >
> > while demanding a higher standard for new punctuation.
> >
> > All of your criticisms of ? punctuation applies to . as well.

[Giampaolo] 
> I don't think they do. For once, "a.b" does one and one thing only,

Attribute lookup is a bit more complex than just "one thing only", but 
okay, I'll accept that for a sufficiently complex "thing", dot access 
does one thing.


> "a?.b" does two and that's a fundamental difference (explicitness).

How is "two things" less explicit than "one thing"?

Comments like the above is why I think that "explicit" and "implicit" 
are used to mean "I like it" and "I don't like it" rather than being 
objective arguments, or indeed having anything to do with explicitness 
or implicitness.

If this PEP is approved, then *by definition* the ?? operator will mean 

return the first operand if it isn't None
otherwise evaluate and return the second

making it just as explicit as:

   +  # add or concatenate the two operands

   ==  # return True if the two operands are equal otherwise False

   sorted(x)  # make a list copy of x and sort it

etc. Just because the spelling is short doesn't make it implicit.


> It
> does so by introducing a brand new operator ("?") which can be spelled
> in two forms ("a?.b" and "a?[b]") by using two adjacent symbols not
> interrupted by any space, which is an absolute first in the Python
> syntax 

It isn't a first. Many existing operators use two adjacent symbols not 
interrupted by a space:

e.g.  ==  <=  >=  !=  **  //  << >> +=  -=  *= etc.



> and that's the second and fundamental difference. I cannot move
> the same criticism to the "a.b" form: it's simpler, it does one thing
> and it uses one symbol.

You criticised ?. because it can interupt left-to-right execution:

a?.b?.c?.d

True. But so can a single dot:

a.b.c.d

is no more guaranteed to execute all the way to the right.

Likewise the logical operators "or" and "and" are designed to 
short-circuit. If ?? and friends are a mistake because they 
short-circuit, why aren't "or" and "and" mistakes?

I'm not asking this as a rhetorical question. If you think there is a 
reason why it is okay for or/and to short-circuit, but it is bad for ?? 
and friends to short-circuit, then please explain why they are 
different. I will be very happy to listen to your arguments.


> > > Multiple "?" can live on the same line so
> > > that's incentive to write one-liners, really, and to me one-liners are
> > > always less explicit than the same logic split on multiple lines.
> >
> > Explicit is not always better.
> >
> > import this
> >
> > is much better than:
> >
> > for location in sys.path:
> > try:
> > for file in os.listdir(location):
> > if os.splitext(file) in ('.pyc', '.py', '.so'):
> > ...
> 
> I honestly don't see how this example is related with anything discussed so 
> far.

You keep saying that the proposed ?? etc operators aren't explicit and 
you criticise them for doing "two things". The import statement does 
at least ten things:

- searches the cache of modules;
- if not found, traverse the search path looking for not one kind of
  file, but multiple kinds of files that the user has no control over;
- if a matching file is found, check for a pre-compiled version;
- or compile it;
- save the compiled byte-code in a new file;
- load the compiled byte-code into a module object;
- execute that code;
- add the module object to the cache;
- create a new name in the local namespace;
- bind the module object to the name.

If doing "two things" is bad, then doing "ten things" is five times 
worse. If ?? is too implicit, then what is importing? Why is it okay for 
importing to be "implicit" but ?? needs to be written out over two 
lines?

If behaviour that is acceptable, even desirable in existing features is 
harmful in these new ? operators, then please tell us how and why.



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Antoine Pitrou
On Mon, 23 Jul 2018 11:12:45 -0400
David Mertz  wrote:
> 
> The particular names I use are nothing special, and better ones might be
> found.  I just called the class NoneAware and the "escape" method
> `.unbox()` because that seemed intuitive at first brush.
> 
> I don't disagree that needing to call .unbox() at the end of the chained
> attribute access is a little bit ugly.  But it's a lot less ugly than large
> family of new operators.  And honestly, it's a nice way of being explicit
> about the fact that we're entering then leaving a special world where
> attribute accesses don't fail.
> 
> I haven't implemented the equivalent dictionary lookups in the below.  That
> would be straightforward, and I'm sure my 5 minute throwaway code could be
> improved in other ways also.  But something better than this in the
> standard library would address ALL the actual needs described in PEP 505.
> Even the pattern Steve Dower is especially fond of like:
> 
> favorite = cfg?.user?.profile?.food ?? "Spam"
> 
> 
> (i.e. a configuration may be incomplete at any level, if levels are missing
> default favorite food is Spam).  We could simply spell that:
> 
> favorite = NoneAware(cfg, "Spam").user.profile.food.unbox()
> 
> 
> I think that's 14 characters more in this example, but still compact.  We
> could get that down to 2 characters if we used one-letter names for the
> class and method.  I suppose down to zero characters if .unbox() was a
> property.

You could use .__call__() instead of .unbox().  Also you can make
unboxing unnecessary in most cases by having your class proxy most
operations, like weakref.proxy does.  The "wrapt" library may help with
that:
http://wrapt.readthedocs.io/en/latest/wrappers.html

Regards

Antoine.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Mikhail V
I personally do almost only classical programming, and I am somewhat
opposed to OOP in general. So here my somewhat outlandish view,
(and I am biased becase I will probably never need this feature).

First thoughts after reading the PEP: what is so super-special and fundamental
about None value?
Is it more special and required to treat more often than "true" or
"false" values in
similar manner?
Is there statistics for occurence of code checking 'None' versus 'not None'?

So:

if x is None:
   x = 10

converts to:

x ??= 10

But what if one need to do something else than just return a value?
E.g. I want to insert `print(x)` in the first example?
Or check against other value than 'None'?
Supposed to write it so then rewrite it so, then if I need it other way -
again rewrite it so.

So from the PEP I understand only two things:
1) de-facto None became special in some contexts.
2) one may need to short-circuit an expression if None pops up.

So it is syntax good only for special kind of applications I suppose.
It seems motivating examples come mainly from situations where
one has a Python script serving some database framework or something alike.
So it smells like specialized usage and design-specific pattern.
It looks (from a passer-by POV) like the proposed syntax tries to
treat some sticking out
parts of something that may not be necessarily present in an application at all.
Of course that maybe argued easily because many concepts that
does not directly belong to programming are sometimes appearing in form of
dedicated syntax. Though such cases not so common in Python.

I don't know whether the feature adressed by '?.' is often in those contexts,
but first thing that comes to mind - it regards only experts and NOT
intended for reading the code that I am not familiar with.

E.g. this "improved" code in examples:

def find_module(self, fullname, path):
return getattr(self, 'find_spec', None)?.__call__(fullname, path)?.loader

I could not decipher this and I have tried for a while.

I could probably understand the motivation better if it were some
more or less fundamental or general pattern, but is it? IDK


-

More important that the syntax part is really worrying.
Does everybody realize that there are only 2 or 3 ASCII characters left free?
IIRC those are question mark "?", exclamation mark "!" and dollar sign "$".

Imagine that in some time someone comes up with a good general syntax feature
that would require new symbol - and there is nothing left. That's not
funny actually.
This makes decisions about symbols into agony and heats up discussions
to extreme
because some PEP authors maybe hoping for a better-looking symbol for
their 'child' while other proposals and possible future proposals may
be more important.

At this time point I think one should first consider exploring the
possibility to
add non-ASCII characters to syntax. I think it is resonable because Unicode
became standard.
It should at least help to relax the atmosphere around syntax proposals.

'Niche' features IMO should be better added as functions, or, if non-ASCII
symbols could be added, as some '2nd class' symbols (i.e. not so nice looking).
And nicely looking symbols should be reserved for future proposals for
general syntax features which are potentially useful for wider user groups.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Grégory Lielens
Your wrapper class can also, I think:
 Swallow exceptions, especially AttributeError
 Specify the sentinel, if it is not None
 Work for getitem 

Mixing is indeed more difficult, and there is probably performance impact.
Still, it's general and does not need to touch the implementation of the class 
you want to descend...

I like it better than the operators

Another idea, may be stupid, maybe not: what if None fails with a subinstance 
of AttributeError, and a subinstance of KeyError, or IndexError. Then a 
try/except catching only those exceptions would also work quite nicely...___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Brice Parent

Le 23/07/2018 à 18:00, David Mertz a écrit :
On Mon, Jul 23, 2018 at 11:26 AM Paul Moore > wrote:


* Library solution works with all versions of Python
* The need for unbox is a little ugly, but arguably less so than ?.
(conceded that's a subjective view)
* Mixing ?. and . is terser than unboxing and reboxing - but are there
any real examples where that's needed?
* Having the default at the beginning rather than at the end doesn't
follow natural reading order (but again that's pretty subjective)


On the last point, it would be easy enough to change the API to make 
it `NoneAware(obj).a.b.c.unbox(sentinel)` if that was thought a better 
API than `NoneAware(obj, sentinel).a.b.c.unbox()`.
Oh... and the production code should DEFINITELY spell 'sentinel' 
correctly if that's a part of the API. :-)


One of the good things about this proposal, is that it may be expanded 
to other sentinels:


ret = NoneAware(obj, sentinel=0).a.unbox(42)

# would be equivalent to
ret = obj.a if obj.a is not 0 else 42

# or, if tmp_a had side effects
tmp_a = obj.a
ret = tmp_a if tmp_a is not 0 else 42

One thing that this proposal doesn't cover easily (although I'd refactor 
the code before using this syntax, as excepted in some very specific 
cases like when using ORMs, I don't like chaining methods and properties 
like this):


favorite = cfg?.user.profile?.food ?? "Spam"  # every user should have a 
profile


favorite = NoneAware(cfg).user.profile.food.unbox("Spam") # We're 
silencing an exception that I didn't plan to silence


Another thing is that both parts are executed. If instead of "Spam" we 
had any variable with a side effect, it would have been executed even if 
cfg.user.profile.food existed. We're missing the lazy evaluation of this 
part here.


That being said, I deeply believe the use case for that are not spread 
enough to justify such a change. And I can see from here code where 
every '.' is prepended by a '?' just in case (the same way we encounter 
frequently exceptions catching for Exception).


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Steve Dower

On 23Jul2018 1530, David Mertz wrote:
Of course I don't mean that if implemented the semantics 
would be ambiguous... rather, the proper "swallowing" of different kinds 
of exceptions is not intuitively obvious, not even to you, Steve.  And 
if some decision was reached and documented, it would remain unclear to 
new (or even experienced) users of the feature.


As written in the PEP, no exceptions are ever swallowed. The translation 
into existing syntax is very clearly and unambiguously shown, and there 
is no exception handling at all. All the exception handling discussion 
in the PEP is under the heading of "rejected ideas".


This email discussion includes some hypotheticals, since that's the 
point - I want thoughts and counter-proposals for semantics and 
discussion. I am 100% committed to an unambiguous PEP, and I believe the 
current proposal is most defensible. However, I don't want to have a 
"discussion" where I simply assume that I'm right, everyone else is 
wrong, and I refuse to discuss or consider alternatives.


So sorry for letting you all think that everything I write is actually 
the PEP. I had assumed that because my emails are not the PEP that 
people would realise that they are not the PEP. I'm going to duck out of 
the discussions here now, since they are not as productive as I'd hoped, 
and once we have a BDFL-replacement I'll reawaken it and see what is 
required at that point.


Cheers,
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread C Anthony Risinger
On Mon, Jul 23, 2018 at 7:46 AM, Grégory Lielens 
wrote:

>  Paul Moore wrote:
>>
>> This is my impression, as well. It seems like something that's helpful
>> in dealing with unstructured object hierarchies with lots of optional
>> attributes - which is where JSON tends to be used.
>>
>> But given that, I'm really much more interested in seeing the new
>> operators compared against a well-written "JSON object hierarchy
>> traversal" library than against raw Python code.
>>
>
> Good point, I did not think about that when suggesting to give some
> context, but indeed if it's linked to a library in particular, there is
> always the possibility to choose another object than None as the "nothing
> here" marker.
>
>From what I gather, disallowing reassignment all but cements None as the
"nothing here" marker (the originally intent?), _especially_ when "nothing
here" is candidate for replacement by a more appropriate, type- or domain-
or context-specific "nothing here" marker. Imbuing None with any other
meaning brings nothing but headache. It's an attractive nuisance. None is
None is None, there can be only one! You don't know what it is, only that
it's not anything else. What possible meaning can such an object usefully
have in an application built on disparate libraries with their own ideas on
the matter?

Every API I've used (apologies for coming up blank on a concrete example!)
granting None meaning is awkward to consume. `.get()` interfaces are less
useful (must carry your own internal sentinels) or more try/except blocks
are required to achieve the same end (not a bad thing per se, but
a diminished experience to be sure). Early APIs I wrote in this "well it's
None, but but but, with this convenient meaning, see?! SEE??"-style were
later regarded -- quite thoroughly -- as a bad idea by myself, my peers,
and downstream consumers.

I'd personally use these new operators both frequently and judiciously.
They align very well with a "set 'em up and knock 'em down"-style I use:
normalized, progressively conditioned input values fast-followed by
aggressive short-circuits and clear early returns. IME this pattern
generates clean, readable, and performant code. Honestly the
short-circuiting capability alone is enough to sell me :-) This PEP would
find legitimate use by me every day. I'm not 100% sold on `?[` (then again,
attributes are pulled from an object namespace via `?.` and namespaces are
containers by definition) but `?.` and `??` deliver immense value.

Not sure if useful, but this discussion reminds me of a pattern prevalent
in the Elixir community. They use `?` and `!` in function definitions to
denote variants differing only on return behavior (not function clauses!
This is by convention only, they're entirely new functions with a symbol in
their name). It looks something like this:

# Default function.
# Return a tuple {interesting-or-nil, error-or-nil}.
def open(path) do ... end

# Maybe variant.
# Return a boolean, or less often, interesting-or-nil (replaces `is_` or
`can_` methods in Python).
def open?(path) do ... end

# Forceful variant.
# Return interesting or die trying (inverse of `.get()` methods in Python;
raising is not the default expectation in Elixir).
def open!(path) do ... end

The `?.`-operator reminds me of this. It offers to perform an extremely
common operation (simple attribute access) while short-circuiting on the
most frequently triggered guard condition (AttributeError).

I don't think the utility here is restricted to deeply nested JSON
`loads()` or one-off scripts. It better aligns the community on semantics,
encouraging more idiomatic -- and uniform! -- interactions with None.

-- 

C Anthony
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Steven D'Aprano
On Mon, Jul 23, 2018 at 12:09:00PM +0100, Steve Dower wrote:
> On 23Jul2018 1145, Antoine Pitrou wrote:
> >
> >Le 23/07/2018 à 12:38, Steve Dower a écrit :
> >>
> >>General comment to everyone (not just Antoine): these arguments have
> >>zero value to me. Feel free to keep making them, but I am uninterested.
> >
> >So you're uninterested in learning from past mistakes?
> >
> >You sound like a child who thinks their demands should be satisfied
> >because they are the center of the world.
> 
> Sorry if it came across like that, it wasn't the intention. 

Steve, I don't think you should apologise to somebody who has just 
quoted you out of context and insulted you for no good reason.

In context, your comment about "these arguments" was a perfectly 
reasonable thing to say. You didn't say you were uninterested in *all* 
arguments, only certain kinds of low-value arguments that keep getting 
made over and over again. Antoine snipped the context, unfairly accused 
you on zero evidence of being "uninterested in learning from past 
mistakes", and described you as a self-centred child.

I think Antoine should be apologising to you, not the other way around.


-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread David Mertz
On Mon, Jul 23, 2018 at 11:26 AM Paul Moore  wrote:

> * Library solution works with all versions of Python
> * The need for unbox is a little ugly, but arguably less so than ?.
> (conceded that's a subjective view)
> * Mixing ?. and . is terser than unboxing and reboxing - but are there
> any real examples where that's needed?
> * Having the default at the beginning rather than at the end doesn't
> follow natural reading order (but again that's pretty subjective)
>

On the last point, it would be easy enough to change the API to make it
`NoneAware(obj).a.b.c.unbox(sentinel)` if that was thought a better API
than `NoneAware(obj, sentinel).a.b.c.unbox()`.

Oh... and the production code should DEFINITELY spell 'sentinel' correctly
if that's a part of the API. :-)

-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Jonathan Fine
Hi David and Paul

Thank you both for your contributions, and for starting a new thread.

David, you wrote
> The need addressed by PEP 505 is real;

I completely agree. My view is that with PEP 505 as it it, the problem
is better than the solution. But all the same, something can be done
to improve matters.

> Moreover, the actual
> legitimate purpose served by the PEP 505 syntax is easily served by existing
> Python simply by using a wrapper class.

I'm with you here also. First explore solving the problem using
existing syntax. If nothing else, it helps us understand the problem.

There's one area where I find attraction in a new syntax. The ??
operator is well described, I think, as a None-aware 'or'. But not in
the name '??'. We all understand
val1 = EXP1 or EXP2
So how about
val2 = EXP1 or-if-None EXP2
with 'or-if-None' being a new language keyword!

> (1) Much more explicit
> (2) Requires no change in syntax
> (3) Will not be a bug magnet
> (4) [Fewer, clear] semantic traps

These are all good goals. And (2) makes exploration much easier.

> The API that could be useful might be something like this:

I have some different ideas, which I'll post later (to this thread, if
you don't mind).

Paul, you wrote

> I would be very interested to hear discussion of the pros and cons of
> adding new syntax to the language as per PEP 505 in comparison to a
> solution like this (ultimately more fleshed out and "production
> quality") rather than comparisons PEP 505 to raw "roll your own"
> Python code.

I like that approach. I find exploration using Python modules to be
more open (democratic?) than syntax changes that require building a
new executable.

Once again, thank you both for starting at the problem and pointing in
a different direction.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Robert Vanden Eynde
The default could be at the end with an argument to unboxing :

favorite = NoneAware(cfg).user.profile.food.unbox("Spam")


Le lun. 23 juil. 2018 à 17:26, Paul Moore  a écrit :

> On 23 July 2018 at 16:12, David Mertz  wrote:
> > The need addressed by PEP 505 is real; it's also MUCH more niche and
> > uncommon than something that would merit new syntax.  Moreover, the
> actual
> > legitimate purpose served by the PEP 505 syntax is easily served by
> existing
> > Python simply by using a wrapper class.
> >
> > Here is a way of solving the "deep attribute access to messy data"
> problem
> > that is:
> >
> > (1) Much more explicit
> > (2) Requires no change in syntax
> > (3) Will not be a bug magnet
> > (4) Inasmuch as there are semantic traps, they are announced by the use
> of a
> > class whose documentation would be pointed to for readers
>
> [...]
>
> > I haven't implemented the equivalent dictionary lookups in the below.
> That
> > would be straightforward, and I'm sure my 5 minute throwaway code could
> be
> > improved in other ways also.  But something better than this in the
> standard
> > library would address ALL the actual needs described in PEP 505.  Even
> the
> > pattern Steve Dower is especially fond of like:
> >
> > favorite = cfg?.user?.profile?.food ?? "Spam"
> >
> >
> > (i.e. a configuration may be incomplete at any level, if levels are
> missing
> > default favorite food is Spam).  We could simply spell that:
> >
> > favorite = NoneAware(cfg, "Spam").user.profile.food.unbox()
>
> Thank you. That's the sort of "what would this look like if
> implemented as a library rather than language syntax" solution that I
> had in mind with my earlier post.
>
> I would be very interested to hear discussion of the pros and cons of
> adding new syntax to the language as per PEP 505 in comparison to a
> solution like this (ultimately more fleshed out and "production
> quality") rather than comparisons PEP 505 to raw "roll your own"
> Python code.
>
> For me:
>
> * Library solution works with all versions of Python
> * The need for unbox is a little ugly, but arguably less so than ?.
> (conceded that's a subjective view)
> * Mixing ?. and . is terser than unboxing and reboxing - but are there
> any real examples where that's needed?
> * Having the default at the beginning rather than at the end doesn't
> follow natural reading order (but again that's pretty subjective)
>
> There's little here that isn't subjective, so I expect a lot of heated
> debate that ultimately convinces no-one. But the "you can use this
> solution now" aspect of the library solution seems pretty compelling
> to me - at least in terms of "let's publish the library solution and
> then based on experience with it, review PEP 505".
>
> Paul
> ___
> 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/


Re: [Python-ideas] A better (simpler) approach to PEP 505

2018-07-23 Thread Paul Moore
On 23 July 2018 at 16:12, David Mertz  wrote:
> The need addressed by PEP 505 is real; it's also MUCH more niche and
> uncommon than something that would merit new syntax.  Moreover, the actual
> legitimate purpose served by the PEP 505 syntax is easily served by existing
> Python simply by using a wrapper class.
>
> Here is a way of solving the "deep attribute access to messy data" problem
> that is:
>
> (1) Much more explicit
> (2) Requires no change in syntax
> (3) Will not be a bug magnet
> (4) Inasmuch as there are semantic traps, they are announced by the use of a
> class whose documentation would be pointed to for readers

[...]

> I haven't implemented the equivalent dictionary lookups in the below.  That
> would be straightforward, and I'm sure my 5 minute throwaway code could be
> improved in other ways also.  But something better than this in the standard
> library would address ALL the actual needs described in PEP 505.  Even the
> pattern Steve Dower is especially fond of like:
>
> favorite = cfg?.user?.profile?.food ?? "Spam"
>
>
> (i.e. a configuration may be incomplete at any level, if levels are missing
> default favorite food is Spam).  We could simply spell that:
>
> favorite = NoneAware(cfg, "Spam").user.profile.food.unbox()

Thank you. That's the sort of "what would this look like if
implemented as a library rather than language syntax" solution that I
had in mind with my earlier post.

I would be very interested to hear discussion of the pros and cons of
adding new syntax to the language as per PEP 505 in comparison to a
solution like this (ultimately more fleshed out and "production
quality") rather than comparisons PEP 505 to raw "roll your own"
Python code.

For me:

* Library solution works with all versions of Python
* The need for unbox is a little ugly, but arguably less so than ?.
(conceded that's a subjective view)
* Mixing ?. and . is terser than unboxing and reboxing - but are there
any real examples where that's needed?
* Having the default at the beginning rather than at the end doesn't
follow natural reading order (but again that's pretty subjective)

There's little here that isn't subjective, so I expect a lot of heated
debate that ultimately convinces no-one. But the "you can use this
solution now" aspect of the library solution seems pretty compelling
to me - at least in terms of "let's publish the library solution and
then based on experience with it, review PEP 505".

Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Guido van Rossum
On Mon, Jul 23, 2018 at 3:24 AM, Jeroen Demeyer  wrote:

> On 2018-07-23 11:58, Grégory Lielens wrote:
>
>> Not sure slice[1::3] can be done
>>
>
> It can be done. Since "slice" is a class, it would require a metaclass
> though.
>

Since PEP 560 it won't need a metaclass -- it can be implemented as
__class_getitem__.

-- 
--Guido van Rossum (python.org/~guido)
___
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] A better (simpler) approach to PEP 505

2018-07-23 Thread David Mertz
The need addressed by PEP 505 is real; it's also MUCH more niche and
uncommon than something that would merit new syntax.  Moreover, the actual
legitimate purpose served by the PEP 505 syntax is easily served by
existing Python simply by using a wrapper class.

Here is a way of solving the "deep attribute access to messy data" problem
that is:

(1) Much more explicit
(2) Requires no change in syntax
(3) Will not be a bug magnet
(4) Inasmuch as there are semantic traps, they are announced by the use of
a class whose documentation would be pointed to for readers

The API that could be useful might be something like this:

In [1]: from none_aware import NoneAware
In [2]: from types import SimpleNamespace
In [3]: foo = SimpleNamespace()
In [4]: foo.bar = SimpleNamespace()
In [5]: foo.bar.baz = SimpleNamespace()
In [6]: foo.bar.baz.blat = 42
In [7]: NoneAware(foo).bar.blim
Out[7]: 
In [8]: NoneAware(foo).bar.blim.unbox()
In [9]: NoneAware(foo).bar.baz.blat.unbox()
Out[9]: 42
In [10]: NoneAware(foo).bar.baz.blat
Out[10]: 
In [11]: NoneAware(foo).bar.baz.flam.unbox()
In [12]: NoneAware(foo).bar.baz.flam
Out[12]: 


The particular names I use are nothing special, and better ones might be
found.  I just called the class NoneAware and the "escape" method
`.unbox()` because that seemed intuitive at first brush.

I don't disagree that needing to call .unbox() at the end of the chained
attribute access is a little bit ugly.  But it's a lot less ugly than large
family of new operators.  And honestly, it's a nice way of being explicit
about the fact that we're entering then leaving a special world where
attribute accesses don't fail.

I haven't implemented the equivalent dictionary lookups in the below.  That
would be straightforward, and I'm sure my 5 minute throwaway code could be
improved in other ways also.  But something better than this in the
standard library would address ALL the actual needs described in PEP 505.
Even the pattern Steve Dower is especially fond of like:

favorite = cfg?.user?.profile?.food ?? "Spam"


(i.e. a configuration may be incomplete at any level, if levels are missing
default favorite food is Spam).  We could simply spell that:

favorite = NoneAware(cfg, "Spam").user.profile.food.unbox()


I think that's 14 characters more in this example, but still compact.  We
could get that down to 2 characters if we used one-letter names for the
class and method.  I suppose down to zero characters if .unbox() was a
property.

So completely toy implementation:

class NoneAware(object):
def __init__(self, thing, sentinal=None):
self.thing = thing
self.sentinal = sentinal

def __getattr__(self, attr):
try:
return NoneAware(getattr(self.thing, attr))
except AttributeError:
return NoneAware(self.sentinal)

def unbox(self):
return self.thing

-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Giampaolo Rodola'
On Mon, Jul 23, 2018 at 11:52 AM Steve Dower  wrote:

> I'm borderline on ?[] right now. Honestly, I think it works best if it
> also silently handles LookupError (e.g. for traversing a loaded JSON
> dict), but then it's inconsistent with ?. which I think works best if it
> handles None but allows AttributeError.

That would easily make typos pass unnoticed:

request.context.user.usernme  # raises AttributeError
request?.context?.user?.usernme  # return None

Same goes for LookupError: if a key or index is missing on 'a?[b]' I
do want an exception. If I don't, which should be the exception rather
than the rule, I will simply take the risk myself and do:

default = ''
try:
name = d['user']['details']['name'] or default
except KeyError:
name = default

But certainly there should be no native syntax encouraging me to do
any of that. Talking about arbitrarily swallowing exceptions is the
worst direction this proposal can take as it breaks yet another
fundamental Python Zen: "errors should never pass silently". IMO this
shows how fundamentally detached from the base philosophy of the
language this whole idea is.

--
Giampaolo - http://grodola.blogspot.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/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread David Mertz
On Mon, Jul 23, 2018 at 5:52 AM Steve Dower  wrote:

> The PEP author is unsure about how it works
> ---
> I wish this statement had come with some context, because the only thing
> I'm unsure about is what I'm supposed to be unsure about.
>

In general—as I haven't been shy of saying—I find the entire idea awful.  I
recognize you have done sincere and high quality work in arguing for it; it
just feels like a very wrong direction for Python.

But bracketing that, I'm probably the person you have in mind in that
comment.  And it's funny that you write you are unsure what you are
supposed to be unsure about, but the very next section is exactly what I
had in mind.  Of course I don't mean that if implemented the semantics
would be ambiguous... rather, the proper "swallowing" of different kinds of
exceptions is not intuitively obvious, not even to you, Steve.  And if some
decision was reached and documented, it would remain unclear to new (or
even experienced) users of the feature.

I'm borderline on ?[] right now. Honestly, I think it works best if it
> also silently handles LookupError (e.g. for traversing a loaded JSON
> dict), but then it's inconsistent with ?. which I think works best if it
> handles None but allows AttributeError.
>

Moreover, at a couple points in your clarification, you say "ignoring
descriptors." But ultimately, the language cannot do that.  When a
programmer writes `obj?.descriptor?.other_descriptor` SOMETHING has to
happen (no matter what actually happens within the code of the property).

This can certainly be specified in some unambiguous way, but I believe that
any decision made will be strongly counter-intuitive for certain concrete
code.

-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Andre Roberge
On Mon, Jul 23, 2018 at 6:52 AM Steve Dower  wrote:

> Responding to a few more ideas that have come up here.
>


​Thank you for the clarifications.​

​I'm trying to wrap my head around the various facets of None aware
operators proposal after reading the whole discussion - as well as having
read the PEP a few times.  Below is a
summary of what I gathered from the discussion, with a few added other
points that I have not seen addressed.

1. It is an operator present in other languages (e.g. C#, Dart), that uses
the same notation

a) This demonstrates that such an operator has been found to be useful and
is
definitely worth considering.

b) The fact that it uses the same notation is a plus for people that know
these other languages but it does not mean that the notation is necessarily
the best choice for Python. To wit, Python does not use the combination of
? and
: for ternary operator; instead it reuses existing keywords.

c) Some people use languages (e.g. Ruby) that allow ? to be part of an
identifier,
which means that one could, in principle, write something like

a = b?.c

in Ruby with a completely different meaning than what it would mean in C#
or Dart,
or as proposed for Python.Thus, I don't think that that language X uses
this operator written this way is,
**on its own**, a valid justification for using the exact same syntax for
Python.

d) Dart is given as an example. Reading from the link mentioned in the PEP,
I was lead to https://www.dartlang.org/guides/language/language-tour#classes
where the only mention of ?. was the following:

===
// If p is non-null, set its y value to 4.
p?.y = 4;
===

However, PEP 505 mentions that something like the above would raise a
SyntaxError.
Given that Dart's operator has a different semantics than that proposed for
Python,
I do not think that mentioning Dart in this context without any qualifier
is a valid supportive justification for this proposal.

2. On the specific choices of ??, ??=, ?., ?[]

a) Trying to find what Csharp ?? means by doing a quick internet search is
not exactly
productive.  By comparison, if one were to use a new keyword (say ifnone
instead
of ??) or keywords, it would make it easier to find their meaning. The
problem with new
keywords is that they may introduce some backwards incompatibility.

b) Admitedly, there are very few remaining symbols in Python that can be
used for defining new operators. Introducing operators using ? does not
cause problems with existing code.

c) While using a new keyword for ?? and ??= might work, it is less clear,
at least to me, how this could extend to ?. and ?[]

d) ? and ?? are already used by IPython with a totally different meaning.
I almost never use IPython I have no idea what problems this might cause
for IPython users.

3. On some examples given

PEP 505 gives these examples from Request:

data = [] if data is None else data
files = [] if files is None else files
headers = {} if headers is None else headers
params = {} if params is None else params
hooks = {} if hooks is None else hooks

It then argues that this is undesirable and that it could have been written
instead
as

data = data if data is not None else []
files = files if files is not None else []
headers = headers if headers is not None else {}
params = params if params is not None else {}
hooks = hooks if hooks is not None else {}

which, as written in PEP 505, is deemed to be "more intuitive" - but longer.

Having looked at the code in the Request module, I would argue that it
could have been written instead as

if data is None: data = []
if files is None: files = []
if headers is None: headers = {}
if params is None: params = {}
if hooks is None: hooks = {}

which gives the same result and is shorter than the original - but
admittedly longer than
the proposed notation. I do not think that this specific example as
currently written
in PEP 505 gives a fair picture of what is currently possible with Python.

4) On comparisons with other "domain specific operators", like @ and
the bitwise operators.

I do not remember the exact words that were used in the discussions, but
I seem to recall people saying that operators like ??, ?., etc. are no
more "mysterious" than @ or the bitwise operators might be: users should
not be surprised to have to learn new operators.

Anyone that does numerical work knows that matrix multiplications do not
obey the same rules as multiplications of numbers. If you don't do numerical
work, you are almost certain not to encounter @ as an operator (but only
as a symbol for decorator), so there won't be any mystery to solve.
A similar situation exists for bitwise operators.
Having dedicated operators to represent special methods on these types of
objects makes the code easier to read for people working in these fields.
I also note that these operators have corresponding dunder methods.

By contrast, code like

if a is None:
   a = []

can occur in pretty much any type of program and is, arguably, already very

Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Steven D'Aprano
On Mon, Jul 23, 2018 at 10:48:23AM +0100, Steve Dower wrote:
> On 23Jul2018 0151, Steven D'Aprano wrote:
> >What if there was a language
> >supported, non-hackish way to officially delay evaluation of
> >expressions until explicitly requested?
> 
> The current spelling for this is "lambda: delayed-expression" and the 
> way to request the value is "()". :)
> 
> (I'm not even being that facetious here. People ask for delayed 
> expressions all the time, and it's only 7 characters, provided the 
> callee knows they're getting it, and the semantics are already well 
> defined and likely match what you want.)

I know you not being facetious, and delaying computation through a 
function call is not an awful solution. But its not a great solution 
either. Contrast the elegance of syntax with delayed evaluation:

1/x if x != 0 else func(y)

versus the lambda solution:

if_else(lambda: 1/x, x != 0, lambda: func(y))()


For clarity, or perhaps the opposite *wink* I've kept the same order of 
arguments. It's not just the extra seven characters (plus spaces) per 
delayed expression, or the extra parentheses at the end to force 
evaluation, but the ease at which we can forget and write this:

if_else(1/x, x != 0, func(y))


Anyway, it was just an idle thought, not in a state to compete with this 
PEP. And even if it were, I'd still prefer to see at least ?? as a 
dedicated operator rather than a function.



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Nicholas Cole
On Mon, Jul 23, 2018 at 2:37 PM Mark E. Haase  wrote:

>> What does a scan through the existing core library say?
>
>
> Please read the PEP before you shoot it down. It answers this _exact_ 
> question.

My apologies.  I'd missed the line where it says the examples were
taken from the core library. So then a couple of points. Given the
size of the core library, 678 seems like a very low number to me for a
proposal like this -- but then I don't know quite what the threshold
number would be for something like this.  I guess I had expected that
if None really were used in this way that there would be thousands of
places where it might be used in the core libraries.   Secondly (and I
mean this with no animus at all), in some of the examples given I
really struggle to see that the new version is more readable /
maintainable / obvious than the old version.  I can see the point in a
couple of others.  You'll say this is subjective as a test, and it is,
I suppose.

N.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Mark E. Haase
On Mon, Jul 23, 2018 at 2:23 AM Nicholas Cole 
wrote:

> One issue for me is that the trivial case is already a one-liner:
>
> if a is None: a = 10
>

Yes, if you have no indentation and a 1-character name, then it fits on a
single line. If you have a longer expression and/or side effects, then it's
not a one-liner anymore.


> And that leads to a simple question: how many times does this actually
> occur in real-world by python code? -- i.e. how many times do I want
> to check the value of an existing label, and, finding it is None (and
> None specifically), then assign it a value?
>
> What does a scan through the existing core library say?


Please read the PEP before you shoot it down. It answers this _exact_
question.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Grégory Lielens
 Paul Moore wrote:
>
> This is my impression, as well. It seems like something that's helpful
> in dealing with unstructured object hierarchies with lots of optional
> attributes - which is where JSON tends to be used.
>
> But given that, I'm really much more interested in seeing the new
> operators compared against a well-written "JSON object hierarchy
> traversal" library than against raw Python code.
>

Good point, I did not think about that when suggesting to give some 
context, but indeed if it's linked to a library in particular, there is 
always the possibility to choose another object than None as the "nothing 
here" marker. 

One that will absorb getitems and  getattr accesses so that ?.  and ?[] 
behavior is reproduced by plain . and []. Guard/NoValues should be chosen 
so that typical lib use is easier. 


Anyway, addressing partially-populated nodes would need lib support: 
None-coalescence will not help when you traverse a dict/attribute hierarchy 
where some nodes implement some attributes/keys but not others. It help 
only when a node is either regular, or a guard object without any 
attributes...So an irregular tree, but not too irregular ;-)... 


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Paul Moore
On 23 July 2018 at 13:19, Todd  wrote:
> On Mon, Jul 23, 2018 at 7:24 AM, Paul Moore  wrote:
>>
>> On 23 July 2018 at 11:31, Jeroen Demeyer  wrote:
>> > On 2018-07-23 12:24, Jeroen Demeyer wrote:
>> >>
>> >> Another solution that nobody has mentioned (as far as I know) is to add
>> >> additional syntax to the language for that. For example, one could say
>> >> that (1:3) could be used to construct slice(1, 3) directly. The
>> >> parentheses are required to avoid confusion with type hints. I'm not a
>> >> Python language expert, but I don't think that type hints can occur
>> >> inside parentheses like that.
>> >
>> >
>> > And this could be extended to tuples (1:3, 2:4) and lists [1:3, 2:4] of
>> > slices too.
>>
>> I thought the reason the proposal got nowhere was because it's pretty
>> simple to define it yourself:
>>
>> >>> class SliceHelper:
>> ... def __getitem__(self, slice):
>> ... return slice
>> ...
>> >>> SH = SliceHelper()
>> >>> SH[1::3]
>> slice(1, None, 3)
>>
>> Did I miss something significant about why this wasn't sufficient?
>>
>> Paul
>
>
> That involves initializing an instance, which doesn't serve any purpose in
> this case and I was hoping to avoid.

Well it serves the purpose that you can do it already in current
Python, rather than needing a core interpreter change and limiting
your code to Python 3.8+ only ;-)

Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Python docs page: In what ways is None special

2018-07-23 Thread Jonathan Fine
Hi Steve

You wrote

> I think your document would be a great blog post. I don't think it is
> very helpful as part of the standard documention, as it is more a
> collection of arbitrary facts about None than a coherent "big picture"
> document.

Thank you. That's nice. However, I think there is, or should be, more
coherence than you're seeing.

Here's something I forgot to say. For standard documentation I was
thinking The Python Tutorial.  For example, the Brief Tour.
https://docs.python.org/3/tutorial/stdlib.html
https://docs.python.org/3/tutorial/stdlib2.html

That said, a blog post would be useful stepping stone, and the
standard documentation later. (Know where your heading, take one step
at a time.)

Once again, thank you for your comment.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Python docs page: In what ways is None special

2018-07-23 Thread Jonathan Fine
Hi Steve

In this thread you wrote, replying to Paul Moore's comments on PEP 505

> None is already a special value. It is so special, it is one of only
> three built-in values given keyword status. All the other built-ins,
> including such things that are used implicitly by the interpreter (such
> as NotImplemented) are merely ordinary names.

Half an hour earlier, Paul wrote (in reply to me)

>> My goal in this thread is to document clearly and develop a clear
>> shared understanding of the ways in which None is special in Python.
>> Please, please, please can we not discuss PEP 505 in this thread.
>> There's already another thread for that.
>
> OK, apologies for my confusion between the threads.

Paul has implicitly removed from this thread his comments on PEP 505.
If you wish to respond to Paul's comments, please do so elsewhere.
There's already a thread for PEP 505.

-- 
Jonathan
___
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] Idea: msgfmt.py and pygettext..py should be -m executable modules

2018-07-23 Thread Miro Hrončok
Currently, the documentation (as well as plenty of other places on the 
Internet, such as Stack Overflow answers) mentions msgfmt.py and 
pygettext.py.


See https://docs.python.org/3/library/gettext.html

> (Python also includes pure-Python versions of these programs, called
> pygettext.py and msgfmt.py; some Python distributions will install
> them for you. pygettext.py is similar to xgettext, but only
> understands Python source code and cannot handle other programming
> languages such as C or C++. pygettext.py supports a command-line
> interface similar to xgettext; for details on its use, run
> pygettext.py --help. msgfmt.py is binary compatible with GNU msgfmt.
> With these two programs, you may not need the GNU gettext package to
> internationalize your Python applications.)

The problematic part is: "some Python distributions will install them 
for you"


As a Python distributor, I may ask myself a question: Where do I install 
those?


As a Python user, I may ask: Where did the distributors put them, and 
did they?


So I suggest we make those modules instead and we document how to use them.

It might be:

  $ python3 -m gettext

And:

  $ python3 -m gettext.msgfmt

And (provided as a shortcut):

  $ python3 -m msgfmt

I feel that using -m is the general direction Python is going, 
considering this message:


  $ pyvenv ...
  WARNING: the pyenv script is deprecated in favour of `python3.7 -m venv`

It also gives the user a choice for Python version on a system with 
multiple Python versions installed as the user could do:


  $ python3.6 -m gettext

Or

  $ python3.7 -m gettext

While with e.g. /usr/bin/pygettext.py this adds unnecessary burden on 
the distributor to package /usr/bin/pygettext-3.7.py etc...


This idea originates at https://bugzilla.redhat.com/show_bug.cgi?id=1571474

--
Miro Hrončok
--
Phone: +420777974800
IRC: mhroncok
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Python docs page: In what ways is None special

2018-07-23 Thread Steven D'Aprano
On Mon, Jul 23, 2018 at 10:03:10AM +0100, Jonathan Fine wrote:

> I thought, a page on how None is special would be nice.

I think your document would be a great blog post. I don't think it is 
very helpful as part of the standard documention, as it is more a 
collection of arbitrary facts about None than a coherent "big picture" 
document.

We could come up with such arbitrary lists for many other standard 
objects too:

"Did you know... that operator dunder methods should return 
NotImplemented to signal to the interpreter that the other operand's 
method should be called?"

"Did you know that Ellipsis is the sole instance of class ellipsis, 
reversing the usual convention that classes use InitialCaps and 
instances lowercase?"



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Todd
On Mon, Jul 23, 2018 at 7:24 AM, Paul Moore  wrote:

> On 23 July 2018 at 11:31, Jeroen Demeyer  wrote:
> > On 2018-07-23 12:24, Jeroen Demeyer wrote:
> >>
> >> Another solution that nobody has mentioned (as far as I know) is to add
> >> additional syntax to the language for that. For example, one could say
> >> that (1:3) could be used to construct slice(1, 3) directly. The
> >> parentheses are required to avoid confusion with type hints. I'm not a
> >> Python language expert, but I don't think that type hints can occur
> >> inside parentheses like that.
> >
> >
> > And this could be extended to tuples (1:3, 2:4) and lists [1:3, 2:4] of
> > slices too.
>
> I thought the reason the proposal got nowhere was because it's pretty
> simple to define it yourself:
>
> >>> class SliceHelper:
> ... def __getitem__(self, slice):
> ... return slice
> ...
> >>> SH = SliceHelper()
> >>> SH[1::3]
> slice(1, None, 3)
>
> Did I miss something significant about why this wasn't sufficient?
>
> Paul


That involves initializing an instance, which doesn't serve any purpose in
this case and I was hoping to avoid.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Todd
On Mon, Jul 23, 2018 at 6:28 AM, Jonathan Fine  wrote:

> Hi Grégory
>
> You wrote:
> > Oh yes , I see. Seems like almost everybody think using the [...] syntax
> to
> > define reusable slices is a good idea,
>
> > Not sure slice[1::3] can be done, but this has my preference too: it's
> the
> > most direct exposure I can think of...
>
> The slice class already has all the core functionality it needs. This
> thread is looking for something extra. My preference is to create a
> new module, slicetools, that contains the functionality the people on
> this thread want to have.
>
> What I like about this approach is that the code can be written and
> deployed without getting permission from anyone. And when it's done
> and has a body of practice, the PEP would simply be "Add slicetools to
> the standard library".
>
> Anyone here up for working on that sort of approach?
>
>
I only proposed on very limited thing here.  My thought was that if it
wasn't accepted in the slice class the next best place would be a dedicated
class in boltons or toolz or some package like that.

Besides the __getitem__ --> slice classmethod, what other functionality do
you think is needed in such a module?
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Todd
On Mon, Jul 23, 2018 at 6:24 AM, Jeroen Demeyer  wrote:

> On 2018-07-23 11:58, Grégory Lielens wrote:
>
>> Not sure slice[1::3] can be done
>>
>
> It can be done. Since "slice" is a class, it would require a metaclass
> though.
>
> Another solution that nobody has mentioned (as far as I know) is to add
> additional syntax to the language for that. For example, one could say that
> (1:3) could be used to construct slice(1, 3) directly. The parentheses are
> required to avoid confusion with type hints. I'm not a Python language
> expert, but I don't think that type hints can occur inside parentheses like
> that.
>
>
If I remember correctly Guido explicitly rejected requests for such
syntax.  This proposal was intended as a compromise.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Giampaolo Rodola'
On Mon, Jul 23, 2018 at 3:12 AM Steven D'Aprano  wrote:
> > ? has no spaces, it's literally "variable names interrupted by
> > question marks" and evaluation can stop at any time while scanning the
> > line from left to right.
>
> Just like ordinary attribute access.
>
> This is the point I was making earlier: you accept existing punctuation
> doing these things:
>
> try:
> obj.spam.egsg.tomato.cheese  # oops a typo
> except AttributeError:
> # evaluation can stop at any time
> ...
>
> while demanding a higher standard for new punctuation.
>
> All of your criticisms of ? punctuation applies to . as well.

I don't think they do. For once, "a.b" does one and one thing only,
"a?.b" does two and that's a fundamental difference (explicitness). It
does so by introducing a brand new operator ("?") which can be spelled
in two forms ("a?.b" and "a?[b]") by using two adjacent symbols not
interrupted by any space, which is an absolute first in the Python
syntax and that's the second and fundamental difference. I cannot move
the same criticism to the "a.b" form: it's simpler, it does one thing
and it uses one symbol.

Your argument is basically a revisitation of "it's just another
symbol" and "it's like a + b" which you have being pulling different
times in this thread already. You want to imply that since symbols are
already used in the grammar (and "." in particular) then it's
perfectly fine to also have "?" and its spell variants (which are 4 in
total). I don't think that's how changes of such importance should be
discussed.

> > Multiple "?" can live on the same line so
> > that's incentive to write one-liners, really, and to me one-liners are
> > always less explicit than the same logic split on multiple lines.
>
> Explicit is not always better.
>
> import this
>
> is much better than:
>
> for location in sys.path:
> try:
> for file in os.listdir(location):
> if os.splitext(file) in ('.pyc', '.py', '.so'):
> ...

I honestly don't see how this example is related with anything discussed so far.

> If punctuation is unreadable and Perlish, so is "." and ":" punctuation.
> If ?? is bad because it is "implicit", then so is import or sorted.

I'm not even sure how to reply to this.

-- 
Giampaolo - http://grodola.blogspot.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/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Paul Moore
On 23 July 2018 at 12:39, Grégory Lielens  wrote:
> Maybe it would help if you mention in which context you will benefit the
> most? If the python sub-community related to this context agree "?? and
> friends" is a good idea, then it will add weight to the proposal. Else,
> probably better to forget it.
>
> It seems related to JSON, but as I have never used it, it's a wild guess.

This is my impression, as well. It seems like something that's helpful
in dealing with unstructured object hierarchies with lots of optional
attributes - which is where JSON tends to be used.

But given that, I'm really much more interested in seeing the new
operators compared against a well-written "JSON object hierarchy
traversal" library than against raw Python code. I'll happily agree
that traversing JSON-style data in current Python is pretty
unpleasant. But I don't honestly think that anyone has explored how
far a well-written library can go in making it easy to handle such
data (well, I certainly haven't, and I haven't found any particularly
good examples on PyPI). And until that's been tried, I think it's
premature to propose a syntax change (if it *has* been tried, adding
references to the PEP would be useful).

Again, this is more about ?. and ?[. I can see general uses for ??
(and its augmented assignment form ??=), but the None-aware attribute
and item access operators seem to me to be the most domain-specific
aspects of the PEP (as well as being the ugliest IMO ;-)). So
comparing against domain-specific libraries rather than against "write
your own" raw Python code seems reasonable to me.

Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Grégory Lielens
Maybe it would help if you mention in which context you will benefit the 
most? If the python sub-community related to this context agree "?? and 
friends" is a good idea, then it will add weight to the proposal. Else, 
probably better to forget it.

It seems related to JSON, but as I have never used it, it's a wild guess.

Anyway, it's a special pattern with deep attribute hierarchies, whose 
traversal is shortcutted when one attribute happen to be None.
This is common, with 2 exception:
 -it's rare it's really deep, or then it is arbitrarily deep and you need a 
procedural descent, not a fixed expression.
 -None break the descend, but then so does missing attributes.
You address the first with special syntax. not the second, so I suspect in 
your case the second does not happen. Or rarely happen.

Hope this will help finding why some finds the ? operators add little, 
while some others think they add enough to overcome python traditional 
operator-averse nature.


On Monday, July 23, 2018 at 1:10:03 PM UTC+2, Steve Dower wrote:
>
> On 23Jul2018 1145, Antoine Pitrou wrote:
> > 
> > Le 23/07/2018 à 12:38, Steve Dower a écrit :
> >>
> >> General comment to everyone (not just Antoine): these arguments have
> >> zero value to me. Feel free to keep making them, but I am uninterested.
> > 
> > So you're uninterested in learning from past mistakes?
> > 
> > You sound like a child who thinks their demands should be satisfied
> > because they are the center of the world.
>
> Sorry if it came across like that, it wasn't the intention. A bit of 
> context on why you think it's a mistake would have helped, but if it's a 
> purely subjective "I don't like the look of it" (as most similar 
> arguments have turned out) then it doesn't add anything to enhancing the 
> PEP. As a result, I do not see any reason to engage with this class of 
> argument.
>
> I hope you'll also notice that I've been making very few demands in this 
> thread, and have indicated a number of times that I'm very open to 
> adjusting the proposal in the face of honest and useful feedback.
>
> Cheers,
> Steve
> ___
> Python-ideas mailing list
> python...@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/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Antoine Pitrou

Le 23/07/2018 à 13:09, Steve Dower a écrit :
> On 23Jul2018 1145, Antoine Pitrou wrote:
>>
>> Le 23/07/2018 à 12:38, Steve Dower a écrit :
>>>
>>> General comment to everyone (not just Antoine): these arguments have
>>> zero value to me. Feel free to keep making them, but I am uninterested.
>>
>> So you're uninterested in learning from past mistakes?
>>
>> You sound like a child who thinks their demands should be satisfied
>> because they are the center of the world.
> 
> Sorry if it came across like that, it wasn't the intention.

Thanks for your apologies, and I apology for being a bit abrasive too.

Regards

Antoine.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Nicholas Cole
On Mon, Jul 23, 2018 at 8:08 AM Grégory Lielens
 wrote:
>
>
>
> On Monday, July 23, 2018 at 8:24:45 AM UTC+2, Nicholas Cole wrote:
>
>> And that leads to a simple question: how many times does this actually
>> occur in real-world by python code? -- i.e. how many times do I want
>> to check the value of an existing label, and, finding it is None (and
>> None specifically), then assign it a value?
>
>
> The PEP present a few examples.
>
> I think the compactness and clarity is really gained when doing a descent 
> into an "attribute tree", where any (or selected) members can be None, like 
> getting back to the  example by Steven (spell-corrected, and expanded):
>
>  meal = obj?.spam?.eggs.tomato?.cheese ?? "Mozzarella"
>
> Where, to put the proposal in even better light, I have assumed that eggs 
> instances always have a tomato attributes (i.e. are never None).
>
> This is indeed much more compact that the current version, and arguably more 
> readable (it's easier to parse once you know the syntax...but you have to 
> know the special syntax that will be used for this kind of stuff only). The 
> more you deepen the attribute access, the more you gain, but of course deep 
> attribute access is not so common. The new operators may make deep attribute 
> hierarchies (or deeply nested dicts/lists) slightly more common, and there 
> also I do not think it's a good thing.
>

That above example looks terrible to read (to me).  Yes, that's a
subjective statement.  This example from the PEP is even worse:

Example:

if entry.is_dir():
dirs.append(name)
if entries is not None:
entries.append(entry)
else:
nondirs.append(name)

After updating to use the ?. operator:

if entry.is_dir():
dirs.append(name)
entries?.append(entry)
else:
nondirs.append(name)


In the first, it's totally clear to me when entries would be appended
to and when it wouldn't.  The second I had to read several times
before I could see what was going on.  The fact that it is already
embedded in an if...else statement perhaps made it harder to
understand.

I guess people will say that we will just get used to the new syntax,
but I don't see the benefit of making that particular "if" statement
more compact, and leaving all the others in place.  Or to put it
another way, I'm just not convinced that "None" is sufficiently
special.

N.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Grégory Lielens
That would be even more directbut it require syntax support, usefull 
mainly for people doing multdim complex slicing (i.e numpy users). I may be 
wrong, but I do not see it gain much support outside numpy...

slice[] is probably much more easy to swallow for standard python 
users, and almost as good imho.
It reuse getitem, so it imply the produced slice will behaves exactly like 
it would if it was not stored/reused, and almost garantee it will be the 
case indeed (even if the slice syntax is extended)

Getting this to work including a new module would be nice. Eventually, 
having it standard is positive too, it means slice manipulation will become 
more standardised.

On Monday, July 23, 2018 at 12:32:04 PM UTC+2, Jeroen Demeyer wrote:
>
> On 2018-07-23 12:24, Jeroen Demeyer wrote: 
> > Another solution that nobody has mentioned (as far as I know) is to add 
> > additional syntax to the language for that. For example, one could say 
> > that (1:3) could be used to construct slice(1, 3) directly. The 
> > parentheses are required to avoid confusion with type hints. I'm not a 
> > Python language expert, but I don't think that type hints can occur 
> > inside parentheses like that. 
>
> And this could be extended to tuples (1:3, 2:4) and lists [1:3, 2:4] of 
> slices too. 
> ___ 
> Python-ideas mailing list 
> python...@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/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Paul Moore
On 23 July 2018 at 11:31, Jeroen Demeyer  wrote:
> On 2018-07-23 12:24, Jeroen Demeyer wrote:
>>
>> Another solution that nobody has mentioned (as far as I know) is to add
>> additional syntax to the language for that. For example, one could say
>> that (1:3) could be used to construct slice(1, 3) directly. The
>> parentheses are required to avoid confusion with type hints. I'm not a
>> Python language expert, but I don't think that type hints can occur
>> inside parentheses like that.
>
>
> And this could be extended to tuples (1:3, 2:4) and lists [1:3, 2:4] of
> slices too.

I thought the reason the proposal got nowhere was because it's pretty
simple to define it yourself:

>>> class SliceHelper:
... def __getitem__(self, slice):
... return slice
...
>>> SH = SliceHelper()
>>> SH[1::3]
slice(1, None, 3)

Did I miss something significant about why this wasn't sufficient?

Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Python docs page: In what ways is None special

2018-07-23 Thread Jonathan Fine
Hi Paul

Thank you for your contribution

> The examples are interesting, agreed. One thing they highlight to me
> is that most uses of None are effectively convention. The only two
> behaviours that are unique to None and implemented in the interpreter
> are:
>
> 1. Functions that don't return an explicit value return None.
> 2. The interactive interpreter does not display the value of a typed
> expression when that value is None.

I broadly agree with what you say, particularly the compliment.

You also wrote:
> One of the key points about this proposal [PEP 505]

My goal in this thread is to document clearly and develop a clear
shared understanding of the ways in which None is special in Python.
Please, please, please can we not discuss PEP 505 in this thread.
There's already another thread for that.

I want this thread to produce a web page that is useful for beginners
and intermediate Python programmers (which perhaps some experts might
also benefit from reading).

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Python docs page: In what ways is None special

2018-07-23 Thread Paul Moore
On 23 July 2018 at 10:16, Steve Dower  wrote:
> On 23Jul2018 1003, Jonathan Fine wrote:
>>
>> This arises out of PEP 505 - None-aware operators.
>>
>> I thought, a page on how None is special would be nice.
>> I've not found such a page on the web. We do have
>> ===
>> https://docs.python.org/3/library/constants.html
>> None
>> The sole value of the type NoneType. None is
>> frequently used to represent the absence of a
>> value, as when default arguments are not passed
>> to a function. Assignments to None are illegal
>> and raise a SyntaxError.
>> ===
>>
>> So decided to start writing such a page, perhaps to be
>> added to the docs.  All code examples in Python3.4.
>
>
> There's also
> https://docs.python.org/3/c-api/none.html?highlight=py_none#c.Py_None
>
> "The Python None object, denoting lack of value. This object has no methods.
> It needs to be treated just like any other object with respect to reference
> counts."
>
> I don't know that documenting the behaviours of None are that interesting
> (e.g. not displaying anything at the interactive prompt), though it'd be
> perfect for a blog and/or conference talk. But if there appear to be
> behaviours that are not consistent or cannot be easily inferred from the
> existing documentation, then we should think about why that is and how we
> could enhance the documentation to ensure it accurately describes what None
> is supposed to be.
>
> That said, your examples are good :)

The examples are interesting, agreed. One thing they highlight to me
is that most uses of None are effectively convention. The only two
behaviours that are unique to None and implemented in the interpreter
are:

1. Functions that don't return an explicit value return None.
2. The interactive interpreter does not display the value of a typed
expression when that value is None.

(the fact that None is a keyword is not unique - True and False are
also keywords - although it is a distinguishing feature).

One of the key points about this proposal is that it adds a number of
additional ways in which the interpreter treats None specially (i.e.,
four dedicated operators). That elevates None from the position of
being a commonly used sentinel value to one that has language support
for being a sentinel. That's not necessarily a bad thing, but it is a
point that should be considered when reviewing this PEP (people who
prefer to use object() for their sentinels are probably less happy
about making None "special", for example - Pandas uses NaN as the
"missing data" sentinel rather than None, although Pandas' focus on
bulk processing means that dedicated operators probably wouldn't help
anyway).

Overall, my personal feeling is that I do use None specially (and a
lot of code I see does too), so having None-aware operators has some
merit. But I don't find None to be special enough to warrant quite
this *many* operators, nor do I find that the patterns that operators
like ?. and ?[ support are ones I use a lot. Actually, the ?. and ?[
operators seem like they'd be much more useful if I did more JSON
processing - but I don't, so I have little feel for whether language
support is needed here or whether better library support (stdlib
and/or 3rd party) for optional data is sufficient.

Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Steve Dower

On 23Jul2018 1145, Antoine Pitrou wrote:


Le 23/07/2018 à 12:38, Steve Dower a écrit :


General comment to everyone (not just Antoine): these arguments have
zero value to me. Feel free to keep making them, but I am uninterested.


So you're uninterested in learning from past mistakes?

You sound like a child who thinks their demands should be satisfied
because they are the center of the world.


Sorry if it came across like that, it wasn't the intention. A bit of 
context on why you think it's a mistake would have helped, but if it's a 
purely subjective "I don't like the look of it" (as most similar 
arguments have turned out) then it doesn't add anything to enhancing the 
PEP. As a result, I do not see any reason to engage with this class of 
argument.


I hope you'll also notice that I've been making very few demands in this 
thread, and have indicated a number of times that I'm very open to 
adjusting the proposal in the face of honest and useful feedback.


Cheers,
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Antoine Pitrou

Le 23/07/2018 à 12:38, Steve Dower a écrit :
> 
> General comment to everyone (not just Antoine): these arguments have 
> zero value to me. Feel free to keep making them, but I am uninterested. 

So you're uninterested in learning from past mistakes?

You sound like a child who thinks their demands should be satisfied
because they are the center of the world.

Regards

Antoine.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Steve Dower

On 23Jul2018 1129, Antoine Pitrou wrote:


Le 23/07/2018 à 12:25, Steve Dower a écrit :

On 23Jul2018 , Antoine Pitrou wrote:

On Mon, 23 Jul 2018 10:51:31 +0100
Steve Dower  wrote:


Which is the most important operator?
-

Personally, I think '?.' is the most valuable.


For me, it's the most contentious.  The fact that a single '?' added to
a regular line of Python code can short-circuit execution silently is a
net detriment to readability, IMHO.


The only time it would short-circuit is when it would otherwise raise
AttributeError for trying to access an attribute from None, which is
also going to short-circuit.


But AttributeError is going to bubble up as soon as it's raised, unless
it's explicitly handled by an except block.  Simply returning None may
have silent undesired effects (perhaps even security flaws).


You're right that the silent/undesired effects would be bad, which is 
why I'm not proposing silent changes to existing code (such as 
None.__getattr__ always returning None).


This is a substitute for explicitly checking None before the attribute 
access, or explicitly handling AttributeError for this case (and 
unintentionally handling others as well). And "?." may be very small 
compared to the extra 3+ lines required to do exactly the same thing, 
but it is still an explicit change that can be reviewed and evaluated as 
"is None a valid but not-useful value here? or is it an indication of 
another error and should we fail immediately instead".


Cheers,
Steve


This whole thing reminds of PHP's malicious "@" operator.


General comment to everyone (not just Antoine): these arguments have 
zero value to me. Feel free to keep making them, but I am uninterested. 
Perhaps whoever gets to decide on the PEP will be swayed by them?

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Jeroen Demeyer

On 2018-07-23 12:24, Jeroen Demeyer wrote:

Another solution that nobody has mentioned (as far as I know) is to add
additional syntax to the language for that. For example, one could say
that (1:3) could be used to construct slice(1, 3) directly. The
parentheses are required to avoid confusion with type hints. I'm not a
Python language expert, but I don't think that type hints can occur
inside parentheses like that.


And this could be extended to tuples (1:3, 2:4) and lists [1:3, 2:4] of 
slices too.

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Antoine Pitrou

Le 23/07/2018 à 12:25, Steve Dower a écrit :
> On 23Jul2018 , Antoine Pitrou wrote:
>> On Mon, 23 Jul 2018 10:51:31 +0100
>> Steve Dower  wrote:
>>>
>>> Which is the most important operator?
>>> -
>>>
>>> Personally, I think '?.' is the most valuable.
>>
>> For me, it's the most contentious.  The fact that a single '?' added to
>> a regular line of Python code can short-circuit execution silently is a
>> net detriment to readability, IMHO.
> 
> The only time it would short-circuit is when it would otherwise raise 
> AttributeError for trying to access an attribute from None, which is 
> also going to short-circuit.

But AttributeError is going to bubble up as soon as it's raised, unless
it's explicitly handled by an except block.  Simply returning None may
have silent undesired effects (perhaps even security flaws).

This whole thing reminds of PHP's malicious "@" operator.

Regards

Antoine.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Jonathan Fine
Hi Grégory

You wrote:
> Oh yes , I see. Seems like almost everybody think using the [...] syntax to
> define reusable slices is a good idea,

> Not sure slice[1::3] can be done, but this has my preference too: it's the
> most direct exposure I can think of...

The slice class already has all the core functionality it needs. This
thread is looking for something extra. My preference is to create a
new module, slicetools, that contains the functionality the people on
this thread want to have.

What I like about this approach is that the code can be written and
deployed without getting permission from anyone. And when it's done
and has a body of practice, the PEP would simply be "Add slicetools to
the standard library".

Anyone here up for working on that sort of approach?

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Steve Dower

On 23Jul2018 , Antoine Pitrou wrote:

On Mon, 23 Jul 2018 10:51:31 +0100
Steve Dower  wrote:


Which is the most important operator?
-

Personally, I think '?.' is the most valuable.


For me, it's the most contentious.  The fact that a single '?' added to
a regular line of Python code can short-circuit execution silently is a
net detriment to readability, IMHO.


The only time it would short-circuit is when it would otherwise raise 
AttributeError for trying to access an attribute from None, which is 
also going to short-circuit. The difference is that it short-circuits 
the expression only, and not all statements up until the next except 
handler.


Cheers,
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Jeroen Demeyer

On 2018-07-23 11:58, Grégory Lielens wrote:

Not sure slice[1::3] can be done


It can be done. Since "slice" is a class, it would require a metaclass 
though.


Another solution that nobody has mentioned (as far as I know) is to add 
additional syntax to the language for that. For example, one could say 
that (1:3) could be used to construct slice(1, 3) directly. The 
parentheses are required to avoid confusion with type hints. I'm not a 
Python language expert, but I don't think that type hints can occur 
inside parentheses like that.



Jeroen.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Antoine Pitrou
On Mon, 23 Jul 2018 10:51:31 +0100
Steve Dower  wrote:
> 
> Which is the most important operator?
> -
> 
> Personally, I think '?.' is the most valuable.

For me, it's the most contentious.  The fact that a single '?' added to
a regular line of Python code can short-circuit execution silently is a
net detriment to readability, IMHO.

In a code review, this means I must be careful about '?' sigils lest I
miss important bug magnets.

Regards

Antoine.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Grégory Lielens
Oh yes , I see. Seems like almost everybody think using the [...] syntax to 
define reusable slices is a good idea, the discussion is where this could 
be implemented, knowing that numpy.s_ already exists.

Discussion is not easy to follow, with the patch almost accepted then 
delayed then rejected, in a very short amount of time.

In particular, it's not clear why direct indexing of slice type (not 
instance) was not chosen. It was the first proposal, and here again Todd's 
choice. it was silently skipped/changed to slice.literal then moved to 
operators, at least that's the impression I got reading  
https://bugs.python.org/issue24379 ...
Not sure slice[1::3] can be done, but this has my preference too: it's the 
most direct exposure I can think of...


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Steve Dower
Responding to a few more ideas that have come up here. Again, apologies 
for not directing them to the original authors, but I want to focus on 
the ideas that are leading towards a more informed decision, and not 
getting distracted by providing customised examples for people or 
getting into side debates.


I'm also going to try and update the PEP text today (or this week at 
least) to better clarify some of the questions that have come up (and 
fix that embarrassingly broken example :( )


Cheers,
Steve

False: '?.' should be surrounded by spaces
--

It's basically the same as '.'. Spell it 'a?.b', not 'a ?. b' (like 
'a.b' rather than 'a + b').


It's an enhancement to attribute access, not a new type of binary 
operator. The right-hand side cannot be evaluated in isolation.


In my opinion, it can also be read aloud the same as '.' as well (see 
the next point).


False: 'a?.b' is totally different from 'a.b'
-

The expression 'a.b' either results in 'a.b' or AttributeError (assuming 
no descriptors are involved).


The expression 'a?.b' either results in 'a.b' or None (again, assuming 
no descriptors).


This isn't a crazy new idea, it really just short-circuits a specific 
error that can only be precisely avoided with "if None" checks (catching 
AttributeError is not the same).


The trivial case is already a one-liner
---

That may be the case if you have a single character variable, but this 
proposal is not intended to try and further simplify already simple 
cases. It is for complex cases, particularly where you do not want to 
reevaluate the arguments or potentially leak temporary names into a 
module or class namespace.


(Brief aside: 'a if (a := expr) is not None else None' is going to be 
the best workaround. The suggested 'a := expr if a is not None else 
None' is incorrect because the condition is evaluated first and so has 
to contain the assignment.)


False: ??= is a new form of assignment
--

No, it's just augmented assignment for a binary operator. "a ??= b" is 
identical to "a = a ?? b", just like "+=" and friends.


It has no relationship to assignment expressions. '??=' can only be used 
as a statement, and is not strictly necessary, but if we add a new 
binary operator '??' and it does not have an equivalent augmented 
assignment statement, people will justifiably wonder about the 
inconsistency.


The PEP author is unsure about how it works
---

I wish this statement had come with some context, because the only thing 
I'm unsure about is what I'm supposed to be unsure about.


That said, I'm willing to make changes to the PEP based on the feedback 
and discussion. I haven't come into this with a "my way is 100% right 
and it will never change" mindset, so if this is a misinterpretation of 
my willingness to listen to feedback then I'm sorry I wasn't more clear. 
I *do* care about your opinions (when presented fairly and constructively).


Which is the most important operator?
-

Personally, I think '?.' is the most valuable. The value of '??' arises 
because (unless changing the semantics from None-aware to False-aware) 
it provides a way of setting the default that is consistent with how we 
got to the no-value value (e.g. `None?.a ?? b` and `""?.a ?? b` are 
different, whereas `None?.a or b` and `""?.a or b` are equivalent).


I'm borderline on ?[] right now. Honestly, I think it works best if it 
also silently handles LookupError (e.g. for traversing a loaded JSON 
dict), but then it's inconsistent with ?. which I think works best if it 
handles None but allows AttributeError. Either way, both have the 
ability to directly handle the exception. For example, (assuming e1, e2 
are expressions and not values):


v = e1?[e2]

Could be handled as this example (for None-aware):

_temp1 = (e1)
v = _temp1[e2] if _temp1 is not None else None

Or for silent exception handling of the lookup only:

_temp1 = (e1)
_temp2 = (e2)
try:
v = _temp1[_temp2] if _temp1 is not None else None
except LookupError:
v = None

Note that this second example is _not_ how most people protect against 
invalid lookups (most people use `.get` when it's available, or they 
accept that LookupErrors raised from e1 or e2 should also be silently 
handled). So there would be value in ?[] being able to more precisely 
handle the exception.


However, with ?. being available, and _most_ lookups being on dicts that 
have .get(), you can also traverse JSON values fairly easily like this:


d = json.load(f)
name = d.get('user')?.get('details')?.get('name') ?? ''

With ?[] doing the safe lookup as well, this could be:

d = json.load(f)
name = d?['user']?['details']?['name'] ?? ''

Now, my *least* favourite part of this is that (as 

Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Steve Dower

On 23Jul2018 0151, Steven D'Aprano wrote:

What if there was a language
supported, non-hackish way to officially delay evaluation of
expressions until explicitly requested?


The current spelling for this is "lambda: delayed-expression" and the 
way to request the value is "()". :)


(I'm not even being that facetious here. People ask for delayed 
expressions all the time, and it's only 7 characters, provided the 
callee knows they're getting it, and the semantics are already well 
defined and likely match what you want.)


Cheers,
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Jonathan Fine
Hi Grégory

You wrote:
> Seems that the initial proposal was skipped just for timing reasons

The discussion is in https://bugs.python.org/issue24379. It was first
skipped for that reason. Second time around our Then and now Former
BDFL wrote
===
https://bugs.python.org/msg280721
Actually I'm with Raymond -- I'm also not sure or mildly against (-0).
Given how easy it is to do without and how cumbersome using the operator
module is I don't see a great benefit. (IMO the operator module should be
the measure of *last* resort -- it is not to become part of anybody's
toolkit for common operators. But I seem to be a minority opinion here.)
===
and also
===
https://bugs.python.org/msg319695
Let's close it. Just because someone spent a lot of effort on a patch
we don't have to accept it.
===

That said, I see merits in providing standard tools for creating
slices. These tools, as discussed, to take advantage of the power of
the [...] syntax. I'd start here:
https://bugs.python.org/msg244801

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Python docs page: In what ways is None special

2018-07-23 Thread Steve Dower

On 23Jul2018 1003, Jonathan Fine wrote:

This arises out of PEP 505 - None-aware operators.

I thought, a page on how None is special would be nice.
I've not found such a page on the web. We do have
===
https://docs.python.org/3/library/constants.html
None
The sole value of the type NoneType. None is
frequently used to represent the absence of a
value, as when default arguments are not passed
to a function. Assignments to None are illegal
and raise a SyntaxError.
===

So decided to start writing such a page, perhaps to be
added to the docs.  All code examples in Python3.4.


There's also 
https://docs.python.org/3/c-api/none.html?highlight=py_none#c.Py_None


"The Python None object, denoting lack of value. This object has no 
methods. It needs to be treated just like any other object with respect 
to reference counts."


I don't know that documenting the behaviours of None are that 
interesting (e.g. not displaying anything at the interactive prompt), 
though it'd be perfect for a blog and/or conference talk. But if there 
appear to be behaviours that are not consistent or cannot be easily 
inferred from the existing documentation, then we should think about why 
that is and how we could enhance the documentation to ensure it 
accurately describes what None is supposed to be.


That said, your examples are good :)

Cheers,
Steve

___
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] Python docs page: In what ways is None special

2018-07-23 Thread Jonathan Fine
This arises out of PEP 505 - None-aware operators.

I thought, a page on how None is special would be nice.
I've not found such a page on the web. We do have
===
https://docs.python.org/3/library/constants.html
None
The sole value of the type NoneType. None is
frequently used to represent the absence of a
value, as when default arguments are not passed
to a function. Assignments to None are illegal
and raise a SyntaxError.
===

So decided to start writing such a page, perhaps to be
added to the docs.  All code examples in Python3.4.

Here's my first attempt. I'm sure I've missed some
important examples. Please help, if you can.

None is a keyword
==
>>> None = 0
SyntaxError: can't assign to keyword

>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class',
'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for',
'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal',
'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

The Command Line Interpreter hides None
=
>>> None
>>>

None is false in a boolean context
==
>>> bool(None)
False

Procedures return None
==
>>> a = [3,1,2]
>>> b = a.sort()
>>> a, b
([1, 2, 3], None)

Dictionary get returns None if not found
==
>>> {}.get('dne') is None
True

None is default return value
=
>>> def fn(): pass
...
>>> fn() # No response!
>>> print(fn()) # Here's why.
None

None is used as a sentinel default value
==
Particularly useful when default value must be determined
in body of function.
---
def insort_right(a, x, lo=0, hi=None):
# ...
if hi is None:
hi = len(a)
---

Thank you for your attention. What have I missed?

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] slice[] to get more complex slices

2018-07-23 Thread Grégory Lielens
+1 on this. Seems easy a limited in scope, and it reduce the need to 
remember the details of slice constructor, just reuse the same syntax for 
getitem slices.

Seems that the initial proposal was skipped just for timing reasons, and 
have a large support among numpy users. More mixed outside numpy, but still 
I think it was put under the rug a little too quickly...
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Grégory Lielens


On Monday, July 23, 2018 at 8:24:45 AM UTC+2, Nicholas Cole wrote:

And that leads to a simple question: how many times does this actually 
> occur in real-world by python code? -- i.e. how many times do I want 
> to check the value of an existing label, and, finding it is None (and 
> None specifically), then assign it a value? 
>

The PEP present a few examples.

I think the compactness and clarity is really gained when doing a descent 
into an "attribute tree", where any (or selected) members can be None, like 
getting back to the  example by Steven (spell-corrected, and expanded):

 meal = obj?.spam?.eggs.tomato?.cheese ?? "Mozzarella"

Where, to put the proposal in even better light, I have assumed that eggs 
instances always have a tomato attributes (i.e. are never None).

This is indeed much more compact that the current version, and arguably 
more readable (it's easier to parse once you know the syntax...but you have 
to know the special syntax that will be used for this kind of stuff only). 
The more you deepen the attribute access, the more you gain, but of course 
deep attribute access is not so common. The new operators may make deep 
attribute hierarchies (or deeply nested dicts/lists) slightly more common, 
and there also I do not think it's a good thing.

For me the issue is that you gain little, each operator is very limited in 
scope, but at the same it's a operator, and those are introduced very 
carefully in Python (the resistance to line noise is high, it's one of the 
defining aspect of Python since forever).

Each of them do not do enough IMHO, it's too special case and do not unlock 
especially powerfull/elegant/generalization reuse of other part of Python 
syntax. If you add something, it should play nice with the existing feature 
and solve nagging issues that broaden its appeal, or be powerful/general 
enough to justify it's existence on its own, or be so self-evident for a 
python user that it feels it's solving a bug.

It's not the case for ?? and friends imho, far from it.

Also, what happen if you want to modify your deep nested tree, not only 
access it?

obj?.spam?.eggs.tomato?.cheese = "Mozzarella"

will not work, and the proposal will not really help there (Or will it? I 
am not the proposer, I am strongly against it, so I could easily miss 
capabilities).
If it's not possible, you lose a kind of symmetry, and that I do not like 
(orthogonality and symmetries are really nice in in a computer language, it 
helps quickly remembering the syntax as you are not cluttered by special 
cases and exceptions)

Steven wrote:


The Python community has always been conservative and resistant to 
change, but the level of conservativeness is now pushing towards fear 
of change rather than justifiable caution about adding new features that 
cannot easily be reverted. 

That's probably because you like this proposal. Really, compared to the 2.0 
days, it seems that Python has became much less resistant to change. You 
have resistance even when proposing changes in standard library, or even 
the C interpreter internal, unseen in the Python layer, and imho it's often 
justified (what can be discussed is how arbitrary the actual selection of 
change is, but a general resistance is not a bad thing)
It is a little bit optimistic to expect ?? and friends will be a walk in 
the park, especially after := ...


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-23 Thread Nicholas Cole
On Mon, Jul 23, 2018 at 2:38 AM Steven D'Aprano  wrote:
>
> On Mon, Jul 23, 2018 at 12:59:20AM +0200, Giampaolo Rodola' wrote:
>
> > You're back at "since we have X that justifies the addition of Y" [1]
> > and AFAICT that's the only argument you have provided so far in a 100+
> > messages discussion.
>
> The PEP itself justifies the addition of Y.

This thread seems to be unnecessarily heated.

Other languages have these operators, and so they aren't a wild idea.
That said, from what I've seen, Swift optionals are very different
things, and Python really has nothing like them.

In Python, is None really special enough to need an operator like this?

One issue for me is that the trivial case is already a one-liner:

if a is None: a = 10

And it works for other things too:

if a is -1: a = 10

if not a: a = 10

Again, is None special enough in Python to need this operator? I don't know.

And that leads to a simple question: how many times does this actually
occur in real-world by python code? -- i.e. how many times do I want
to check the value of an existing label, and, finding it is None (and
None specifically), then assign it a value?

What does a scan through the existing core library say?

I'm +0 on this proposal.

Best wishes,

N
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/