Re: [Python-Dev] PEP 572: Do we really need a ":" in ":="?

2018-07-05 Thread Fred Drake
On Thu, Jul 5, 2018 at 9:02 PM Alexander Belopolsky
 wrote:
> What happened to the "consenting adults" philosophy?

Just anecdotally, I've run into a number of professionals recently
who've come out of Java environments who really dislike the
"consenting adults" approach.  While they value much that Python
offers them, they still really want some of the hand-holding languages
like Java give them.  What exactly they identify as "compelling"
varies based on their past experiences, but it's not completely
without reason.  The reasoning is often tied to providing APIs
"less-experienced" programmers can use without breaking things.

Some of these programmers at least claim to understand that bigger
risks come from not dealing with API boundaries that check input
values carefully, or that don't deal cleanly with exception
propagation; that seems to be fairly difficult for many.  The
idiomatic models I've found most desirable in Python are not as widely
valued as I'd hope.

It's hard to say what that tells us, and I think we'd want more
quantifiable evidence before drawing conclusions.  The prevalence of
expectation that an API constrains the mechanics of how it is used is
something I find surprising.  While I can suspect that it's misguided,
I keep running into situations where code needs to be maintained by
people who just aren't as familiar with the idioms I'm accustomed to,
so... considering the issue has value.


  -Fred

--
Fred L. Drake, Jr.
"A storm broke loose in my mind."  --Albert Einstein
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] On the METH_FASTCALL calling convention

2018-07-05 Thread INADA Naoki
I don't know Serhiy's idea about how METH_FASTCALL | METH_KEYWORDS
calling convention can be improved in the future.

When I reading PEP 580, I liked your Py PyCCall_FastCall signature.
Maybe, one way to improve METH_FASTCALL | METH_KEYWORDS can be this.
kwds can be either tuple or dict.

---

Anyway, if we don't make METH_FASTCALL | METH_KEYWORDS public for now,
can we continue both PEPs without exposing keyword arguments support?

For example, PEP 576 defines new signature:

typedef PyObject *(*extended_call_ptr)(PyObject *callable, PyObject** args,
   int positional_argcount, PyTupleObject* kwnames);

`PyTupleObject *kwnames` can be `PyObject *reserved` and "should be NULL always"
in document?

PEP 580 is more simple.  Keeping CCALL_KEYWORDS private.

I think Cython is the most important user of these PEPs.  And Cython creates
functions supporting keywords easily, like Python.  So this can be worthless...

--
INADA Naoki  
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Symmetric vs asymmetric symbols (was PEP 572: Do we really need a ":" in ":="?)

2018-07-05 Thread Chris Angelico
On Fri, Jul 6, 2018 at 12:48 PM, Alexander Belopolsky
 wrote:
>
> Python really has a strong C legacy and this is the area where I agree that
> C designers made a mistake by picking a symmetric symbol (=) for an
> asymmetric operation. On top of that, they picked an asymmetric digraph (!=)
> for a symmetric operation as well and Python (unfortunately) followed the
> crowd and ditched a much better alternative (<>).  My only hope is that
> Python 4.0 will allow ← to be used in place of either = or :=. :-)

Interesting. Looking over Python's binary operators, we have:

|, ^, &, +, *: symmetric (on ints)
-, /, //, **: asymmetric
<, >: mirrored operations
<=, >=: mirrored operations but not reflected
<<, >>: non-mirrored asymmetric
and, or: technically asymmetric but often treated as symmetric
in, not in: asymmetric
is, is not: symmetric

Which ones ought to have symmetric symbols, in an ideal world? Should
<= and >= be proper mirrors of each other? Are << and >> confusing? Is
it a problem that the ** operator is most decidedly asymmetric?

Personally, I'm very happy that the operators use the same symbols
that they do in other languages - U+002B PLUS SIGN means addition, for
instance - and everything else is secondary. But maybe this is one of
those "hidden elegances" that you're generally not *consciously* aware
of, but which makes things "feel right", like how Disney's "Moana" has
freedom to the right of the screen and duty to the left. Are there
languages where symmetric operations are always represented with
symmetric symbols and vice versa?

ChrisA
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: Do we really need a ":" in ":="?

2018-07-05 Thread David Mertz
On Thu, Jul 5, 2018, 7:46 PM Alexander Belopolsky <
alexander.belopol...@gmail.com> wrote:

>  It also appears that there are no cases where = can be substituted for :=
> and not cause a syntax error.  This means that ":" in ":=" is strictly
> redundant.
>

Under your proposal, this is ambiguous: 'myfun(foo=5, bar=7)'
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: Do we really need a ":" in ":="?

2018-07-05 Thread Tim Peters
[Tim]

>  It doesn't even exist yet, but Googling on


> python operator :=
>
> already returns a directly relevant hit on the first page for me:
>
>
> https://stackoverflow.com/questions/26000198/what-does-colon-equal-in-python-mean
> ...
>

[Guido, who later apologized for unclear quoting, hilariously trying to pin
the blame on GMail ;-)]

Since they moved to the "new" GMail, quoting selected pieces in replies has
become a nightmare for me too.  I don't understand the options, and it
seems there's no option at all to do "just plain text, please - nothing
fancy" anymore :-(


Since this thread is dead and everybody is just posting to get the last
> word,
>

You're such a cynic.  We're competing to get the _first_ word on something
destined to convince you that PEP 572 can be vastly improved via a
one-character change ;-)


> I can report that for me, Googling for "Python :=" gives PEP 572 as the
> first non-ad hit. Also among the top hits are section 6 (Expressions) and
> section 7 (Simple statements) of the Python 3.7.0 docs.
>

And I get essentially the same Google results too when I leave out
"operator" from my original

To verify the obvious guess, Googling on just plain

:=

does indeed return hits supremely relevant to the colon-equal "symbol"
regardless of context.

 Seems there is at least one thing that Google still does right. :-)


I'm sure it will be improved out of existence soon enough ;-)


> ...
>
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: Do we really need a ":" in ":="?

2018-07-05 Thread Guido van Rossum
Sorry for messing up the quoting. I blame GMail. Only the text starting
"Since this thread is dead" was mine.

On Thu, Jul 5, 2018 at 8:20 PM Guido van Rossum  wrote:

> On Thu, Jul 5, 2018 at 7:12 PM Tim Peters  wrote:
> It doesn't even exist yet, but Googling on
>
> python operator :=
>
> already returns a directly relevant hit on the first page for me:
>
>
> https://stackoverflow.com/questions/26000198/what-does-colon-equal-in-python-mean
>
> The hits above it are all to overviews of Python operators.  Here on
> Windows, the interface to the Python doc files in IDLE contains an entry
> for each operator, so just typing := in the index search box will
> eventually go directly to its docs.  If you can't do something similar on
> Linux, upgrade to Windows ;-)
>
> Since this thread is dead and everybody is just posting to get the last
> word, I can report that for me, Googling for "Python :=" gives PEP 572 as
> the first non-ad hit. Also among the top hits are section 6 (Expressions)
> and section 7 (Simple statements) of the Python 3.7.0 docs. Seems there is
> at least one thing that Google still does right. :-)
>
> (Though Bing also has an ironically relevant hit: apart from the above
> StackOverflow issue, it found a piece of third party documentation titled
> Conditionals and loops. :-)
>
> --
> --Guido van Rossum (python.org/~guido)
>


-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: Do we really need a ":" in ":="?

2018-07-05 Thread Guido van Rossum
On Thu, Jul 5, 2018 at 7:12 PM Tim Peters  wrote:
It doesn't even exist yet, but Googling on

python operator :=

already returns a directly relevant hit on the first page for me:


https://stackoverflow.com/questions/26000198/what-does-colon-equal-in-python-mean

The hits above it are all to overviews of Python operators.  Here on
Windows, the interface to the Python doc files in IDLE contains an entry
for each operator, so just typing := in the index search box will
eventually go directly to its docs.  If you can't do something similar on
Linux, upgrade to Windows ;-)

Since this thread is dead and everybody is just posting to get the last
word, I can report that for me, Googling for "Python :=" gives PEP 572 as
the first non-ad hit. Also among the top hits are section 6 (Expressions)
and section 7 (Simple statements) of the Python 3.7.0 docs. Seems there is
at least one thing that Google still does right. :-)

(Though Bing also has an ironically relevant hit: apart from the above
StackOverflow issue, it found a piece of third party documentation titled
Conditionals and loops. :-)

-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] On the METH_FASTCALL calling convention

2018-07-05 Thread Guido van Rossum
I'm not the world's leading expert on Python bytecode anymore, but unless
there's something I'm missing your conclusion looks eminently reasonable,
and so I expect you'll get very little traction on this thread. (If you had
wanted to get a megathread you should have written "FASTCALL considered
harmful". :-)

I think there was one person in another thread (INADA Naoki?) who thought
METH_FASTCALL could use improvements. Maybe that person can write back to
this thread? Or perhaps Victor Stinner (who seems to have touched it last)
has a suggestion for what could be improved about it?

--Guido

On Thu, Jul 5, 2018 at 7:55 AM Jeroen Demeyer  wrote:

> Hello all,
>
> As discussed in some other threads ([1], [2]), we should discuss the
> METH_FASTCALL calling convention.
>
> For passing only positional arguments, a C array of Python objects is
> used, which is as fast as it can get. When the Python interpreter calls
> a function, it builds that C array on the interpreter stack:
>
>  >>> from dis import dis
>  >>> def f(x, y): return g(x, y, 12)
>  >>> dis(f)
>1   0 LOAD_GLOBAL  0 (g)
>2 LOAD_FAST0 (x)
>4 LOAD_FAST1 (y)
>6 LOAD_CONST   1 (12)
>8 CALL_FUNCTION3
>   10 RETURN_VALUE
>
> A C array can also easily and efficiently be handled by the C function
> receiving it. So I consider this uncontroversial.
>
> The convention for METH_FASTCALL|METH_KEYWORDS is that keyword *names*
> are passed as a tuple and keyword *values* in the same C array with
> positional arguments. An example:
>
>  >>> from dis import dis
>  >>> def f(x, y, z): return f(x, foo=y, bar=z)
>  >>> dis(f)
>1   0 LOAD_GLOBAL  0 (f)
>2 LOAD_FAST0 (x)
>4 LOAD_FAST1 (y)
>6 LOAD_FAST2 (z)
>8 LOAD_CONST   1 (('foo', 'bar'))
>   10 CALL_FUNCTION_KW 3
>   12 RETURN_VALUE
>
> This is pretty clever: it exploits the fact that ('foo', 'bar') is a
> constant tuple stored in f.__code__.co_consts. Also, a tuple can be
> efficiently handled by the called code: it is essentially a thin wrapper
> around a C array of Python objects. So this works well.
>
> The only case when this handling of keywords is suboptimal is when using
> **kwargs. In that case, a dict must be converted to a tuple. It looks
> hard to me to support efficiently both the case of fixed keyword
> arguments (f(foo=x)) and a keyword dict (f(**kwargs)). Since the former
> is more common than the latter, the current choice is optimal.
>
> In other words: I see nothing to improve in the calling convention of
> METH_FASTCALL. I suggest to keep it and make it public as-is.
>
>
> Jeroen.
>
>
> [1] https://mail.python.org/pipermail/python-dev/2018-June/153945.html
> [2] https://mail.python.org/pipermail/python-dev/2018-July/154251.html
> ___
> Python-Dev mailing list
> Python-Dev@python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/guido%40python.org
>


-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: Do we really need a ":" in ":="?

2018-07-05 Thread Tim Peters
[Alexander Belopolsky]

> > Do we want to protect users who
> > cannot tell = from == so much that  we are willing to cause Python to be
> > the first language with two non-interchangeable assignment operators?
>

[Steven D'Aprano][

Not even close to the first. Go beat us to it -- it has both = and :=
> assignment operators.
>
> Ocaml also has := for regular assignment and <- for assignment to
> mutable fields.
>
> Similarly, Haskall has = for assignment definitions and <- for binding
> in monads.
>

I skipped that part, because nobody actually cares ;-)

But back when I looked at this, R had them all beat, and I never found a
single source that actually managed to list _all_ of R's variations  This
source was clearest, but is missing (at least) all the ways to spell all
the variations as function calls too:

https://stat.ethz.ch/R-manual/R-devel/library/base/html/assignOps.html

There are three different assignment operators: two of them have leftwards
> and rightwards forms.
>


The operators <- and = assign into the environment in which they are
> evaluated. The operator <- can be used anywhere, whereas the operator = is
> only allowed at the top level (e.g., in the complete expression typed at
> the command prompt) or as one of the subexpressions in a braced list of
> expressions.
>


The operators <<- and ->> are normally only used in functions, and cause a
> ...
> .[click the link if you're still awake]
>
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: Do we really need a ":" in ":="?

2018-07-05 Thread Alexander Belopolsky
On Thu, Jul 5, 2018 at 10:10 PM Tim Peters  wrote:

> ..
> I solved the problem in my own code by using an editor that displays a
> single "=" in C source as a left-arrow graphic (that's one of its
> C-specific display options - again a response to how notorious this
> bug-magnet is).  So assignment and equality-testing in C code look
> entirely different to me, regardless of context.
>
> But to this day, I routinely get a SyntaxError when writing new Python
> code because I _think_ "if x equals y" and _type_ "if x = y:".  So I know
> for sure that it's still a typo I'm way too prone to make.
>

Python really has a strong C legacy and this is the area where I agree that
C designers made a mistake by picking a symmetric symbol (=) for an
asymmetric operation. On top of that, they picked an asymmetric digraph
(!=) for a symmetric operation as well and Python (unfortunately) followed
the crowd and ditched a much better alternative (<>).  My only hope is that
Python 4.0 will allow ← to be used in place of either = or :=. :-)
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: Do we really need a ":" in ":="?

2018-07-05 Thread Steven D'Aprano
On Thu, Jul 05, 2018 at 09:00:39PM -0400, Alexander Belopolsky wrote:

> Do we want to protect users who
> cannot tell = from == so much that  we are willing to cause Python to be
> the first language with two non-interchangeable assignment operators?

Not even close to the first. Go beat us to it -- it has both = and := 
assignment operators.

Ocaml also has := for regular assignment and <- for assignment to 
mutable fields.

Similarly, Haskall has = for assignment definitions and <- for binding 
in monads.



-- 
Steve
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: Do we really need a ":" in ":="?

2018-07-05 Thread Tim Peters
[Alexander Belopolsky]
>>> ...
>>>  I also think that the dreadfulness of mistyping = where == is expected
>>>  is exaggerated.

[Tim]
>> There are a number of core devs who would be rabidly opposed
>> to allowing that confusion in Python, due to still-remembered
>> real-life nightmares in C.  For example, me ;-)  It only takes one
>> wasted day of debugging that typo in a time-critical project to sour
>> you on it for life, and several of us run out of fingers counting the
>> number of days it actually did cost over our C careers.

[Alexander]
> I still do quite a bit of C programming and I have exactly the opposite
> experience

Meaning that confusing "=" and "==" in C _saves_ you days of debugging in
time-critical projects? ;-)

> given modern environments: why is gcc/clang/vs complaining about if (x=a)
-
> I know what I am doing!

Because gcc/clang/vs is acknowledging how widely and deeply this C wart is
despised.  Isn't that obvious?  You're quite the exception here, not "the
rule" - as gcc/clang/vs eternally but apparently futilely remind you ;-)

...
> Seriously, ':=' looks like a reluctantly introduced kludge to allow
> assignment in expressions.

There have been piles of other suggestions, but ":=" remains the least
disliked (at least by Guido, and his opinion actually counts ;-) ).

> We agree that it is sometimes useful to have, but we will make the feature
> really hard to use

?  It's very easy to use.  Try it - I have.  But I've used several
languages in which ":=" was _the_ way to spell assignment, so it felt
familiar at first touch.


> or discover.

It doesn't even exist yet, but Googling on

python operator :=

already returns a directly relevant hit on the first page for me:


https://stackoverflow.com/questions/26000198/what-does-colon-equal-in-python-mean

The hits above it are all to overviews of Python operators.  Here on
Windows, the interface to the Python doc files in IDLE contains an entry
for each operator, so just typing := in the index search box will
eventually go directly to its docs.  If you can't do something similar on
Linux, upgrade to Windows ;-)

>  What happened to the "consenting adults" philosophy?

Struggling mightily the last several months to get consensus on some form
of embedded assignment _at all_ :-(

>  Do we want to protect users who cannot tell = from ==

Yes.

>  so much that  we are willing to cause Python to be the first language
> with two non-interchangeable assignment operators?

Sure - I am.  _Far_ more than I'm willing to reproduce C's mistake.  It's
one of the first things singled out in Andrew Koenig's "C Traps and
Pitfalls", starting with his original paper that was the basis for his 1989
book of the same name:

http://literateprogramming.com/ctraps.pdf

You can use Google too - it's a top-10 item in every list of "C warts" I've
ever seen.  It's impossible to overstate how hated it is.

But, sure - if you post in its defense a few more times, everyone sensible
is sure to change their mind - and I'll ask Andrew to remove that section
from his still-selling book ;-)

I solved the problem in my own code by using an editor that displays a
single "=" in C source as a left-arrow graphic (that's one of its
C-specific display options - again a response to how notorious this
bug-magnet is).  So assignment and equality-testing in C code look entirely
different to me, regardless of context.

But to this day, I routinely get a SyntaxError when writing new Python code
because I _think_ "if x equals y" and _type_ "if x = y:".  So I know for
sure that it's still a typo I'm way too prone to make.

I've picked up that you're not, but that's scant comfort ;-)
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Examples for PEP 572

2018-07-05 Thread Devin Jeanpierre
On Wed, Jul 4, 2018 at 7:42 PM Steven D'Aprano  wrote:
> On Wed, Jul 04, 2018 at 01:00:41PM -0700, Devin Jeanpierre wrote:
> > On Wed, Jul 4, 2018 at 11:04 AM Steven D'Aprano  wrote:
> > > Did you actually mean arbitrary simple statements?
> > >
> > > if import math; mylist.sort(); print("WTF am I reading?"); True:
> > > pass
> >
> > Yes.
>
> Okay, you just broke my brain.
>
> I was *sure* that you were going to complain that I was misrepresenting
> your position, or attacking a strawman, or something.

This "brain-breaking" experience is something to keep in mind when we
read the reactions to the acceptance assignment expressions, so that
we can better empathize with the people who are so shocked by it.
After all, assignment expressions allow nearly word for word the same
abuse you posted:

if [(math := __import__('math')), mylist.sort(), print('WTF?'), True][-1]:
  ...

Anything that allows assignment in an if statement is going to allow
some messed up stuff. The PEP seems to intentionally take the stance
that it is OK to allow super-ugly code, because we can trust people to
just not do that.

> I did not imagine for a second that you *actually* would prefer
> to allow the above code over assignment expressions.

I don't really know how to bridge that disconnect. I thought Nathaniel
argued very well what is lost with assignment expressions.

-- Devin
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: Do we really need a ":" in ":="?

2018-07-05 Thread Alexander Belopolsky
On Thu, Jul 5, 2018 at 8:28 PM Tim Peters  wrote:

> [Alexander Belopolsky]
> > ...
> >  I also think that the dreadfulness of mistyping = where == is expected
> >  is exaggerated.
>
> There are a number of core devs who would be rabidly opposed to allowing
> that confusion in Python, due to still-remembered real-life nightmares in
> C.  For example, me ;-)  It only takes one wasted day of debugging that
> typo in a time-critical project to sour you on it for life, and several of
> us run out of fingers counting the number of days it actually did cost over
> our C careers.
>

I still do quite a bit of C programming and I have exactly the opposite
experience given modern environments: why is gcc/clang/vs complaining about
if (x=a) - I know what I am doing!  No, I don't want to put two pairs of
(..) around condition - one is one too many!



> Alas, many people new to Python put parens around _all_ `if` and `while`
> conditions, due to habit carried over from other languages (common as
> newbies on, e.g., StackOverflow).  They're the most vulnerable.  Nobody in
> their right mind even suspects that putting parens around an entire
> expression could have semantic significance.
>
> a = 1 + 2  # OK, adds 1 and 2
> a = (1 + 2) # but who could possibly guess what this means? ;-)
>
> But I expect the idea was DOA for the first reason above.
>

Not that unlike Yuri, I don't think the language should require (..) around
assignment expressions.

Seriously, ':=' looks like a reluctantly introduced kludge to allow
assignment in expressions.  We agree that it is sometimes useful to have,
but we will make the feature really hard to use or discover.  What happened
to the "consenting adults" philosophy?  Do we want to protect users who
cannot tell = from == so much that  we are willing to cause Python to be
the first language with two non-interchangeable assignment operators?
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: Do we really need a ":" in ":="?

2018-07-05 Thread Tim Peters
[Alexander Belopolsky]
> ...
>  I also think that the dreadfulness of mistyping = where == is expected
>  is exaggerated.

There are a number of core devs who would be rabidly opposed to allowing
that confusion in Python, due to still-remembered real-life nightmares in
C.  For example, me ;-)  It only takes one wasted day of debugging that
typo in a time-critical project to sour you on it for life, and several of
us run out of fingers counting the number of days it actually did cost over
our C careers.

>  In all motivating cases, := is used to introduce new bindings rather than
> rebinding existing names.

I've heard people say that several times now, but suspect that's due to
that they're looking at "motivating cases" in isolation.  In a function,
for example, doing a lot with regexps, blocks like

if m := pat1.search(string):
...

if m := pat2.search(substring):
   ...

may be present any number of times.  Only the first such block is _not_ a
rebinding.  Reusing short temp names for stuff like this may be almost as
common as using `i` and `j` as for-loop target names.


>  Automated code checkers can easily warn users when they rebind
> variables in if statements and suggest that they silence the warnings
> with redundant (..) if they really want what they wrote.

Alas, many people new to Python put parens around _all_ `if` and `while`
conditions, due to habit carried over from other languages (common as
newbies on, e.g., StackOverflow).  They're the most vulnerable.  Nobody in
their right mind even suspects that putting parens around an entire
expression could have semantic significance.

a = 1 + 2  # OK, adds 1 and 2
a = (1 + 2) # but who could possibly guess what this means? ;-)

But I expect the idea was DOA for the first reason above.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: Do we really need a ":" in ":="?

2018-07-05 Thread Guido van Rossum
Sorry, I tried this too. If you think the response to the current version
of the PEP is strong, the negative reaction to that version was way
stronger, and I decided not to pursue it.

On Thu, Jul 5, 2018 at 5:00 PM Alexander Belopolsky <
alexander.belopol...@gmail.com> wrote:

>
>
> On Thu, Jul 5, 2018 at 7:47 PM Yury Selivanov 
> wrote:
>
>> I think I tried a variation of your proposal here
>> https://mail.python.org/pipermail/python-dev/2018-April/152939.html
>> and nobody really liked it.
>>
>> Right. I now recall your proposal.  I think I did not support it at the
> time because I was against having expressions with side-effects regardless
> of syntax.  Now, as I mentioned, in the current form the PEP makes a strong
> case for allowing a limited form of variable assignment in expressions.  I
> also think that the dreadfulness of mistyping = where == is expected is
> exaggerated.  In all motivating cases, := is used to introduce new bindings
> rather than rebinding existing names.  Automated code checkers can easily
> warn users when they rebind variables in if statements and suggest that
> they silence the warnings with redundant (..) if they really want what they
> wrote.
>
> ___
> Python-Dev mailing list
> Python-Dev@python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/guido%40python.org
>


-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572 semantics

2018-07-05 Thread Chris Angelico
On Fri, Jul 6, 2018 at 10:17 AM, Guido van Rossum  wrote:
>> I'm still wondering if it might make sense to define a new
>> "TargetScopeError" subclass of SyntaxError for that last case, since it
>> isn't the assignment expression syntax itself that's the problem: it's where
>> that expression is located.
>
>
> Yeah, that would be a good idea. (Though do we currently have any subclasses
> of SyntaxError? And if so, do any of them have a name that does not include
> the substring "SyntaxError"?)
>

There's IndentationError. +1 on the dedicated exception type.

ChrisA
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572 semantics

2018-07-05 Thread Guido van Rossum
On Thu, Jul 5, 2018 at 3:35 PM Nick Coghlan  wrote:

> Guido did fully specify this in his post on "__parentlocal" scoping, in
> response to my request that this be clearly spelled out in the PEP (that
> specification just hasn't been rolled back into the PEP yet).
>

Having written it up that way, I don't think it actually would add clarity
to the PEP. What would probably add clarity is some examples showing the
equivalent "classic" code for the various edge cases involving
comprehensions, showing where the "nonlocal" or "global" would go.


> While Tim's correct that the underlying runtime semantics here aren't new
> (which is why PEP 558 doesn't need to change), there's a new requirement
> imposed on a Python compiler's symbol table analysis pass to see "A :=
> expr" in a comprehension or generator expression scope
>

(To clarify: as always, this scope excludes the "outermost iterable".)


> and interpret that as equivalent to either:
>
> 1. An implied "global A" in the child scope if the parent scope is the
> module scope, or A is explicitly declared as global in the parent scope
>

Yes. Two examples (so I can copy them easily into the PEP):

# Module scope
x = [a := i for i in range(10)]

# Translates roughly into
def comprehension(iterator):
global a
result = []
for i in iterator:
result.append(a := i)  # The meaning of this := should be clear
return result
x = comprehension(iter(range(10)))

# Explicit global declaration
def foo():
global a
x = [a := i for i in range(10)]

# The translation is identical to the above except nested inside foo()

2. An implied "nonlocal A" in the child scope if the parent scope is a
> function scope and A is not defined as global in that scope. If A is not
> already declared as local or nonlocal in the parent scope, then it is
> implicitly declared as local in that scope with no associated annotation
> (akin to "if 0: for A in (): pass")
>

I'm confused why you use both "if 0:" and "for A in ():" here -- I'd think
that you can use either "if 0: A = 0" or "for A in (): pass" (the latter
without the "if 0:" prefix). My personal favorite here is currently "A:
object" -- since PEP 526 this already means "A is local in this function"
without giving it a value. But any of the others will work too.

Anyway you're right there are three subcases here:

- explicit nonlocal in the parent scope
- variable is already assigned to or declared in the parent scope (at least
one of "A = ..." or "A: ...")
- neither

Only the third subcase requires adding a dummy local declaration (i.e., "if
0: A = 0" or one of the others discussed above). (Note that all three
subcases add "nonlocal A" to the implied function).

There's also another special case when one comprehension occurs inside
another comprehension, e.g.

[[A := i+j for i in range(3)] for j in range(5)]

In this case the function generated for *both* comprehensions needs to
contain "nonlocal A" (or, if case (1) above applies, both should "global
A"). I believe this case is currently not mentioned in the PEP, though I
recall mentioning it before in one of the many threads. I've made a mental
note of this.

The prohibition on assignment to loop control variables applies to all loop
control variables that are visible from the point of the ":=" operator: in
this example, the variable at position A is not allowed to reference either
i or j. I would also disallow assignment to the loop control variable in
the "outer iterable" of a comprehension, since I don't think there's any
point in allowing that: [i for i in i := range(3)] should be disallowed.
All such prohibitions should be syntax errors.


> 3. A compile time error if the parent scope is a class scope (since we
> don't have any existing scope declaration semantics that can be used to
> make that case work sensibly)
>

Right.


> I'm still wondering if it might make sense to define a new
> "TargetScopeError" subclass of SyntaxError for that last case, since it
> isn't the assignment expression syntax itself that's the problem: it's
> where that expression is located.
>

Yeah, that would be a good idea. (Though do we currently have any
subclasses of SyntaxError? And if so, do any of them have a name that does
not include the substring "SyntaxError"?)

-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: Do we really need a ":" in ":="?

2018-07-05 Thread Alexander Belopolsky
On Thu, Jul 5, 2018 at 7:47 PM Yury Selivanov 
wrote:

> I think I tried a variation of your proposal here
> https://mail.python.org/pipermail/python-dev/2018-April/152939.html
> and nobody really liked it.
>
> Right. I now recall your proposal.  I think I did not support it at the
time because I was against having expressions with side-effects regardless
of syntax.  Now, as I mentioned, in the current form the PEP makes a strong
case for allowing a limited form of variable assignment in expressions.  I
also think that the dreadfulness of mistyping = where == is expected is
exaggerated.  In all motivating cases, := is used to introduce new bindings
rather than rebinding existing names.  Automated code checkers can easily
warn users when they rebind variables in if statements and suggest that
they silence the warnings with redundant (..) if they really want what they
wrote.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: Do we really need a ":" in ":="?

2018-07-05 Thread Yury Selivanov
I think I tried a variation of your proposal here
https://mail.python.org/pipermail/python-dev/2018-April/152939.html
and nobody really liked it.

Yury
On Thu, Jul 5, 2018 at 7:44 PM Alexander Belopolsky
 wrote:
>
> I wish I had more time to make my case, but with the PEP 572 pronouncement 
> imminent, let me make an attempt to save Python from having two assignment 
> operators.
>
> I've re-read the PEP, and honestly I am warming up to the idea of allowing a 
> limited form of assignment in expressions.  It looks like in the current 
> form, the PEP supports only well-motivated cases where the return value of 
> the assignment expression is non-controversial.  It also appears that there 
> are no cases where = can be substituted for := and not cause a syntax error.  
> This means that ":" in ":=" is strictly redundant.
>
> Interestingly, Python already has a precedent for using redundant ":" - the 
> line-ending ":" in various statements is redundant, but it is helpful both 
> when reading and writing the code.
>
> On the other hand, ':' in ':=' looks like an unnecessary embellishment.  When 
> we use ':=', we already know that we are inside an expression and being 
> inside an expression is an obvious context for the reader, the writer and the 
> interpreter.
>
> I also believe, allowing a limited form of assignment in expressions is a 
> simpler story to tell to the existing users than an introduction of a new 
> operator that is somewhat like '=', but cannot be used where you currently 
> use '=' and only in places where '=' is currently prohibited.
>
> ___
> Python-Dev mailing list
> Python-Dev@python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: 
> https://mail.python.org/mailman/options/python-dev/yselivanov.ml%40gmail.com



-- 
 Yury
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572 semantics: all capabilities of the assignment statement

2018-07-05 Thread Guido van Rossum
On Thu, Jul 5, 2018 at 3:45 PM Nick Coghlan  wrote:

>
>
> On Thu., 5 Jul. 2018, 3:17 pm Guido van Rossum,  wrote:
>
>> Let me be slightly contrarian. :-)
>>
>> On Wed, Jul 4, 2018 at 9:12 PM Chris Angelico  wrote:
>>
>>> Definitely against augmentation, for several reasons:
>>>
>>> 1) Spelling - should it be :+= or +:= ?
>>>
>>
>> That one's easy. As Nick's (withdrawn) PEP 577 shows it should be simply
>> `+=`.
>>
>>
>>> 2) Is the result of the expression the modified value or the original?
>>>
>>
>> Someone (sadly I forget who) showed, convincingly (to me anyways :-) that
>> it should return whatever the `__iadd__` method returns, or (if there isn't
>> one) the result of `a = a + b`.
>>
>
> I think I had it as an open question in one of the earlier drafts of PEP
> 577.
>
> The subsequent rationale for it returning the modified value was that we
> have this existing equivalence at the statement level:
>
> a += b
> a = operator.iadd(a, b)
>
> So the natural expression level semantics would be:
>
> a := operator.iadd(a, b)
>

Thinking about it more, I think the real stumper was what should happen for
either of these:

x = (a.b := 1)
x = (a.b += 1)

Take the first one and let's try to compile it to pseudo bytecode (which
I'm making up on the spot but should be simple enough to understand if
you've seen output from the "dis" module):

LOAD 1
LOAD a
SETATTR b
???

What do we do next? We could do

LOAD a
GETATTR b
STORE x

But this gives a's class the opportunity to change the value (because its
__setattr__ could normalize the value, e.g. to a string or a float, and
then its __getattribute__ would return the normalized value). But this
seems a rare case and wastes time in the common case, and also seems
somewhat more surprising than always assinging 1 to x regardless of what
SETATTR did, so I'd rather forgo the extra GETATTR operation. So I think it
should be

LOAD 1
DUP
LOAD a
SETATTR b
LOAD r1
STORE x

I think the second example could be translated as follows (using a register
rather than a sequence of DUPs and ROTs to save the extra copy of the
result of the IADD that we want to store into x).

LOAD a
DUP
GETATTR b
LOAD 1
IADD
COPY .r1  # copy into register r1
SETATTR b  # this uses the reference to a that was left on the stack by DUP
LOAD .r1
STORE x

I used pen and paper to figure out what was on the stack at each point and
had to rewrite the pseudo bytecode several times. But now I'm pretty sure
this will pose no serious challenge for bytecode generation.

But I'd like to point out to anyone who made it this far that this is not
part of PEP 572! The PEP currently proposes neither "+=" in expressions nor
targets that are attributes -- it only proposes "NAME := EXPR" because for
the others the use cases are just too thin. (But in the past we said that
about things like "(1, 2, *args, *more_args)" and eventually we found
enough use cases for them that they were added. :-)

-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] PEP 572: Do we really need a ":" in ":="?

2018-07-05 Thread Alexander Belopolsky
I wish I had more time to make my case, but with the PEP 572 pronouncement
imminent, let me make an attempt to save Python from having two assignment
operators.

I've re-read the PEP, and honestly I am warming up to the idea of allowing
a limited form of assignment in expressions.  It looks like in the current
form, the PEP supports only well-motivated cases where the return value of
the assignment expression is non-controversial.  It also appears that there
are no cases where = can be substituted for := and not cause a syntax
error.  This means that ":" in ":=" is strictly redundant.

Interestingly, Python already has a precedent for using redundant ":" - the
line-ending ":" in various statements is redundant, but it is helpful both
when reading and writing the code.

On the other hand, ':' in ':=' looks like an unnecessary embellishment.
When we use ':=', we already know that we are inside an expression and
being inside an expression is an obvious context for the reader, the writer
and the interpreter.

I also believe, allowing a limited form of assignment in expressions is a
simpler story to tell to the existing users than an introduction of a new
operator that is somewhat like '=', but cannot be used where you currently
use '=' and only in places where '=' is currently prohibited.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572, VF/B, and "Shark Jumping"

2018-07-05 Thread Guido van Rossum
Please, Mike, can you stop? The race is over and your horse has lost. I
really value all the input I've received during the months of discussion
(including your research into what other languages do), but in the end my
"evaluation function" (to use somewhat hip lingo :-) is different from
yours. For a while I seriously considered "EXPR as NAME", but when
comparing examples written in one style vs. another I just liked "NAME :=
EXPR" better every time. In addition to the problems with "with" (which
everyone has read about already) and the general rule that "as" is preceded
by specific syntax that predicts it (i.e. "import", "except" or "with"), I
found that when skimming the code it was easier to miss the definition of
NAME with the "as" form than with the ":=" variant.

There was also someone who posted that they believe that the problems with
evaluation order (alluded to in the PEP) would be solved by the "as" form.
However that's not the case -- in fact I believe that Python would have to
generate exactly the same bytecode for "EXPR as NAME" as for " NAME :=
EXPR", since in both cases it comes down to "LOAD EXPR; STORE NAME" (in
pseudo bytecode). So neither form supports things like "x == (x := f())"
since this comes down to

LOAD x
LOAD f
CALL
STORE x
COMPARE

with either syntax variant (again, in pseudo bytecode).

On Wed, Jul 4, 2018 at 5:09 PM Mike Miller  wrote:

> Recently on Python-Dev:
>
> On 2018-07-03 15:24, Chris Barker wrote:
>  > On Tue, Jul 3, 2018 at 2:51 PM, Chris Angelico   > On Wed, Jul 4, 2018 at 7:37 AM, Serhiy Storchaka <
> storch...@gmail.com>
>  >
>  > > I believe most Python users are not
>  > > professional programmers -- they are sysadmins, scientists,
> hobbyists
>  > > and kids --
>  >
>  > [citation needed]
>  >
>  > fair enough, but I think we all agree that *many*, if not most, Python
> users
>  > are "not professional programmers". While on the other hand everyone
> involved
>  > in discussion on python-dev and python-ideas is a serious (If not
>  > "professional") programmer.
>
>
> Python Audience - wants clarity:
>
> Not sure I'd say that most users are not professionals, but one major
> strength
> of Python is its suitability as a teaching language, which enlarges the
> community every year.
>
> Additionally, I have noticed a dichotomy between prolific "C programmers"
> who've
> supported this PEP and many Python programmers who don't want it.  While
> C-devs
> use this construct all the time, their stereotypical Python counterpart is
> often
> looking for simplicity and clarity instead.  That's why we're here, folks.
>
>
> Value - good:
>
> Several use cases are handled well by PEP 572.  However it has been noted
> that
> complexity must be capped voluntarily relatively early—or the cure soon
> becomes
> worse than the disease.
>
>
> Frequency - not much:
>
> The use cases for assignment-expressions are not exceedingly common,
> coming up
> here and there.  Their omission has been a very mild burden and we've done
> without for a quarter century.
>
> Believe the authors agreed that it won't be used too often and won't
> typically
> be mis- or overused.
>
>
> New Syntax - a high burden:
>
> For years I've read on these lists that syntax changes must clear a high
> threshold of the (Value*Frequency)/Burden (or VF/B) ratio.
>
> Likewise, a few folks have compared PEP 572 to 498 (f-strings) which some
> former
> detractors have come to appreciate.  Don't believe this comparison applies
> well,
> since string interpolation is useful a hundred times a day, more concise,
> clear,
> and runs faster than previous functionality.  Threshold was easily cleared
> there.
>
>
> Conclusion:
>
> An incongruous/partially redundant new syntax to perform existing
> functionality
> more concisely feels too low on the VF/B ratio IMHO.  Value is good though
> mixed, frequency is low, and burden is higher than we'd like, resulting in
> "meh"
> and binary reactions.
>
> Indeed many modern languages omit this feature specifically in an effort
> to
> reduce complexity, ironically citing the success of Python in support.
> Less is
> more.
>
>
> Compromise:
>
> Fortunately there is a compromise design that is chosen often these days
> in new
> languages---restricting these assignments to if/while (potentially
> comp/gen)
> statements.  We can also reuse the existing "EXPR as NAME" syntax that
> already
> exists and is widely enjoyed.
>
> This compromise design:
>
>  1  Handles the most common cases (of a group of infrequent cases)
>  0  Doesn't handle more obscure cases.
>  1  No new syntax (through reuse)
>  1  Looks Pythonic as hell
>  1  Difficult to misuse, complexity capped
>
>  Score: 4/5
>
> PEP 572:
>
>  1  Handles the most common cases (of a group of infrequent cases)
>  1  Handles even more obscure cases.
>  0  New syntax
>  0  Denser look: more colons, parens, expression last
>  0  Some potential for misuse, complexity 

Re: [Python-Dev] Checking that PEP 558 (defined semantics for locals()) handles assignment expressions

2018-07-05 Thread Guido van Rossum
On Thu, Jul 5, 2018 at 3:06 PM Nick Coghlan  wrote:

>
>
> On Thu., 5 Jul. 2018, 1:21 am Guido van Rossum,  wrote:
>
>> Correct, there shouldn't be any additional corner cases for your PEP due
>> to inline assignments. We're not introducing new scopes nor other runtime
>> mechanisms; the target of an inline assignment is either a global or a cell
>> (nonlocal) defined at a specific outer level.
>>
>
> Cool. I'll still review the PEP to see if it makes sense to mention this
> as a side note anywhere, but it may turn out to make more sense to simply
> not mention it at all.
>

Would it be helpful if PEP 572 spelled out the translations of some common
and corner cases? It's difficult to present a general rule for translating
because of the required static analysis (not impossible but it would be low
information density compared to the spec that's already there), but it
might help clarify the spec for implementers who aren't from Mars.


> What I wish we had (quite independent from PEP 572) is a way in a debugger
>> to evaluate a comprehension that references a local in the current stack
>> frame. E.g. here's something I had in a pdb session yesterday:
>>
>> (Pdb) p [getattr(context.context, x) for x in dir(context.context)]
>> *** NameError: name 'context' is not defined
>> (Pdb) global cc; cc = context
>> (Pdb) p [getattr(cc.context, x) for x in dir(cc.context)]
>> [, ]
>> (Pdb)
>>
>> The first attempt failed because the outer `context` was a local variable
>> in some function, and pdb uses eval() to evaluate expressions.
>>
>
> Perhaps pdb should be passing something like "ChainMap(frame.f_locals,
> frame.f_globals)" to the eval call as its global namespace when the current
> frame uses optimized local variable references? That way even lexically
> nested scopes inside the eval call will all be able to see the current
> local variables via dynamic name lookup, even though they still won't see
> them as lexical closure references.
>

That sounds intriguing, but I can't easily get it to work. I get either
"TypeError: globals must be a real dict; try eval(expr, {}, mapping)", when
I pass that for globals, or the same error as before, "NameError: name 'a'
is not defined", when I follow that advice and pass the ChainMap instance
as the locals. Plus it(ironically, perhaps :-) it screws up the output of
"p locals()".

-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572 semantics: all capabilities of the assignment statement

2018-07-05 Thread Nick Coghlan
On Thu., 5 Jul. 2018, 3:17 pm Guido van Rossum,  wrote:

> Let me be slightly contrarian. :-)
>
> On Wed, Jul 4, 2018 at 9:12 PM Chris Angelico  wrote:
>
>> Definitely against augmentation, for several reasons:
>>
>> 1) Spelling - should it be :+= or +:= ?
>>
>
> That one's easy. As Nick's (withdrawn) PEP 577 shows it should be simply
> `+=`.
>
>
>> 2) Is the result of the expression the modified value or the original?
>>
>
> Someone (sadly I forget who) showed, convincingly (to me anyways :-) that
> it should return whatever the `__iadd__` method returns, or (if there isn't
> one) the result of `a = a + b`.
>

I think I had it as an open question in one of the earlier drafts of PEP
577.

The subsequent rationale for it returning the modified value was that we
have this existing equivalence at the statement level:

a += b
a = operator.iadd(a, b)

So the natural expression level semantics would be:

a := operator.iadd(a, b)

Cheers,
Nick.

>
>
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] How about integrating "as" semantics and postpone PEP 572 to Python 4.0

2018-07-05 Thread Guido van Rossum
Thanks you for writing up a proposal. There have been many proposals made,
including 'EXPR as NAME', similar to yours. It even has a small section in
the PEP: https://www.python.org/dev/peps/pep-0572/#alternative-spellings.
It's really hard to choose between alternatives, but all things considered
I have decided in favor of `NAME := EXPR` instead. Your efforts are
appreciated but you would just be wasting your time if you wrote a PEP. If
you're interested in helping out, would you be interested in working on the
implementation of PEP 572?

On Thu, Jul 5, 2018 at 12:21 PM Rin Arakaki  wrote:

> Hi,
>
> I bring a strong proposal that is prematurely rejected but indeed the most 
> likely to be accepted to our community.
> That is to select `as` spelling not `:=` and modify `with` and `except` 
> statements. Here is this.
>
> * Below is copy-pasted from my gist: 
> https://gist.github.com/rnarkk/cdabceaedbdb498d99802a76cc08b549
>
>
> # `as` assignment expression
>
> ```python
> # This
> STATEMENT(EXPR_0 as NAME_0, EXPR_1 as NAME_2, ..., EXPR_n as NAME_n)
>
> # can always be replaced by
> NAME_0 = EXPR_0
> NAME_1 = EXPR_1
> ...
> NAME_n = EXPR_n
> STATEMENT(NAME_0, NAME_1, ..., NAME_n)
>
> # except `import` statement since it's special from the beginning which means 
> no `EXPR` cannot be the left hand of `as` in its statement but simply `NAME`: 
> `import NAME_0 as NAME_1`
>
> # This interpretation above is valid no matter how `EXPR_i` uses `NAME_j` (i 
> > j).
>
> # When you write
> EXPR as NAME_0, NAME_1
>
> # it's interpreted as
> (EXPR as NAME_0), NAME_1
>
> # TODO Should unpacking is allowed by this?
> EXPR as (NAME_0, NAME_1)
>
> # `EXPR as NAME` itself can be `EXPR` and it returns just `EXPR` in `EXPR as 
> NAME` which means you can write
> ((EXPR as NAME_0) as NAME_1) ... as NAME_n
>
> # or simply like this even at the top level since it's determininable.
> EXPR as NAME_0 as NAME_1 ... as NAME_n
>
> NAME_0 = EXPR as NAME_1 ... as NAME_n
>
> # Also you can write
> f(x=EXPR as NAME)
>
> # since this is valid and `EXPR as NAME` can be `EXPR`.
> f(x=EXPR)
>
> # And also this is passible.
> if (EXPR as NAME).method(): ...
>
> # The `EXPR` in `EXPR as NAME` is matched as long as possible which means
> if 0 < 1 as x: ...
>
> # is interpreted as
> if (0 < 1) as x: ...
>
> # not
> if 0 < (1 as x): ...
>
> # but also `EXPR` is separated by `,` which means
> EXPR_0, EXPR_1 as NAME
>
> # is interpreted as
> EXPR_0, (EXPR_1 as NAME)
>
> # rather than
> (EXPR_0, EXPR_1) as NAME
>
> # even when used `as` assignment expression in list comprehension,
> # you can apply the same rules above first by putting it to `for` loop form.
>
> # There is no equivalence to type annotation and augmented assignment.
> ```
>
>
> # `with` statement
>
> - `with` statement will no longer responsible for passing returned value from 
> `__enter__` to the right hand of `as` in its statement and merely call 
> `__enter__` when enter the statement and `__exit__` when exit from it an
> - Context manager can be renamed simply to context since it will no longer be 
> manager but context itself. Context object has status of the context and 
> encapsulates it.
>
> # `except` statement
>
> - `except` statement will no longer responsible for passing instance of the 
> right hand of `as` in its statement.
> - Exceptions must be instanciated and also it must be confirmed otherwise 
> `except` statement could rewrite the class globally.
>
>
> Thanks,
> Rin Arakaki
>
> ___
> Python-Dev mailing list
> Python-Dev@python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/guido%40python.org
>


-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572 semantics

2018-07-05 Thread Nick Coghlan
On Thu., 5 Jul. 2018, 10:23 am Steve Dower,  wrote:

> On 04Jul2018 1518, Tim Peters wrote:
> > The only new thing is specifying the scope of `a`, where "local to f"
> > means exactly the same thing as for any other name local to a function
> > today.  So far as the PEP semantics go, it doesn't even matter whether
> > an implementation _does_ implement some form of closure as such.  It
> > just has to provide the visible semantics of _lexically_ nested scopes
> > with indefinite extent, by whatever means it likes best.  That's what
> > "local to f" means (and has meant all along - well, since lexically
> > nested scopes were first introduced).
>
> In that case, please provide more examples of how it should work when
> the assignment expression appears to define a variable in a scope that
> is not on the call stack.
>
> Whether intentional or not, there will be changes to how and when names
> are resolved. The specification should provide enough information to
> determine the preferred behaviour, so we can tell the difference between
> intention changes and implementation bugs.
>
> For example, what should be returned from this function?
>
> >>> A = 0
> >>> def f(x):
> ... if x:
> ... [A := i for i in [1]]
> ... return A
>
> As far as I can tell, the closest current equivalent will not compile:
>
> >>> A = 0
> >>> def f(x):
> ... if x:
> ... def g():
> ... nonlocal A
> ... A = 1
> ... g()
> ... return A
> ...
>   File "", line 4
> SyntaxError: no binding for nonlocal 'A' found
>
> Is this the equivalent behaviour you want? Or do you want an
> UnboundLocalError when calling f(0)? Or do you want the global A to be
> returned? How should we approach decision making about these cases as we
> implement this? The PEP does not provide enough information for me to
> choose the right behaviour here, and I argue that it should.
>

Guido did fully specify this in his post on "__parentlocal" scoping, in
response to my request that this be clearly spelled out in the PEP (that
specification just hasn't been rolled back into the PEP yet).

While Tim's correct that the underlying runtime semantics here aren't new
(which is why PEP 558 doesn't need to change), there's a new requirement
imposed on a Python compiler's symbol table analysis pass to see "A :=
expr" in a comprehension or generator expression scope and interpret that
as equivalent to either:

1. An implied "global A" in the child scope if the parent scope is the
module scope, or A is explicitly declared as global in the parent scope

2. An implied "nonlocal A" in the child scope if the parent scope is a
function scope and A is not defined as global in that scope. If A is not
already declared as local or nonlocal in the parent scope, then it is
implicitly declared as local in that scope with no associated annotation
(akin to "if 0: for A in (): pass")

3. A compile time error if the parent scope is a class scope (since we
don't have any existing scope declaration semantics that can be used to
make that case work sensibly)

I'm still wondering if it might make sense to define a new
"TargetScopeError" subclass of SyntaxError for that last case, since it
isn't the assignment expression syntax itself that's the problem: it's
where that expression is located.

Cheers,
Nick.


> Cheers,
> Steve
> ___
> Python-Dev mailing list
> Python-Dev@python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com
>
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Checking that PEP 558 (defined semantics for locals()) handles assignment expressions

2018-07-05 Thread Nick Coghlan
On Thu., 5 Jul. 2018, 1:21 am Guido van Rossum,  wrote:

> Correct, there shouldn't be any additional corner cases for your PEP due
> to inline assignments. We're not introducing new scopes nor other runtime
> mechanisms; the target of an inline assignment is either a global or a cell
> (nonlocal) defined at a specific outer level.
>

Cool. I'll still review the PEP to see if it makes sense to mention this as
a side note anywhere, but it may turn out to make more sense to simply not
mention it at all.


> What I wish we had (quite independent from PEP 572) is a way in a debugger
> to evaluate a comprehension that references a local in the current stack
> frame. E.g. here's something I had in a pdb session yesterday:
>
> (Pdb) p [getattr(context.context, x) for x in dir(context.context)]
> *** NameError: name 'context' is not defined
> (Pdb) global cc; cc = context
> (Pdb) p [getattr(cc.context, x) for x in dir(cc.context)]
> [, ]
> (Pdb)
>
> The first attempt failed because the outer `context` was a local variable
> in some function, and pdb uses eval() to evaluate expressions.
>

Perhaps pdb should be passing something like "ChainMap(frame.f_locals,
frame.f_globals)" to the eval call as its global namespace when the current
frame uses optimized local variable references? That way even lexically
nested scopes inside the eval call will all be able to see the current
local variables via dynamic name lookup, even though they still won't see
them as lexical closure references.

Cheers,
Nick.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Assignment expression and coding style: the while True case

2018-07-05 Thread Victor Stinner
Hi,

I wrote more pull requests in the meanwhile to see how assignment
expressions could be used in the standard library. I combined my 5 PR
into a new single PR to see all changes at once:

   https://github.com/python/cpython/pull/8122/files

Again, all these PR must not be merged. I only wrote them to discuss
when it's appropriate or not to use assingment expressions.

Victor
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Examples for PEP 572

2018-07-05 Thread Chris Barker via Python-Dev
On Wed, Jul 4, 2018 at 7:20 AM, David Mertz  wrote:

>
> That said, this is a silly game either way.  And even though you CAN
> (sometimes) bind in an expression pre-572, that's one of those perverse
> corners that one shouldn't actually use.
>

not only shouldn't by hardly anyone ever does / would.

A lot of the argument for this feature is that it doesn't really let you do
things you couldn't do before (like manipulate the local namespace in side
comprehensions, or the nonocal one, or...)

But this IS a silly game -- Python is highly dynamic, you can do all sorts
of metaprogamming tricks. I'm pretty sure you can even alter the byte code
in a running interpreter (but only pretty sure, 'cause why would I ever try
to do that?)

But the point is not that you can do tricky namespace manipulations now,
it's that you need to do advanced (and obvious) thinks like call locals()
or globals() or use nonlocal, or...

I don't think these concerns have been ignored, but I also don't think that
I've heard anyone on the pro side say something along the line of:

"Yes, this does add a significant complication to the language, but we
think it will be unlikely to be mis-used in confusing ways, and that
complication is worth it."

Rather, I've heard a  lot of "but you can already do that" or "but we added
[ternary expressions, augmented assignment, f-strings, ...]" And none of
those add *complication* to the language itself -- they add one more
feature that needs to be looked up when you encounter it -- but only effect
the line of code where there are used.

-CHB



-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR(206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115   (206) 526-6317   main reception

chris.bar...@noaa.gov
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Comparing PEP 576 and PEP 580

2018-07-05 Thread Guido van Rossum
Would it be possible to get outside experts to help? Like Cython or numpy
devs?

On Thu, Jul 5, 2018 at 8:09 AM Jeroen Demeyer  wrote:

> On 2018-07-05 14:20, INADA Naoki wrote:
> > What you can do is "divide and conquer".  Split PEP in small topics we
> > can focus.
>
> The PEP is already small and focused, I really did my best to make it as
> minimal as possible. I don't see a meaningful way to split it up even
> further.
> ___
> Python-Dev mailing list
> Python-Dev@python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/guido%40python.org
>
-- 
--Guido (mobile)
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572, VF/B, and "Shark Jumping"

2018-07-05 Thread Mike Miller




On 2018-07-05 10:52, Ivan Pozdeev via Python-Dev wrote:
>

Perhaps, however I'm not advocating using "EXPR as NAME" with "with" as it 
wouldn't be useful enough, only limited to if/while/comp.


-Mike
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] How about integrating "as" semantics and postpone PEP 572 to Python 4.0

2018-07-05 Thread Rin Arakaki
Hi,

I bring a strong proposal that is prematurely rejected but indeed the
most likely to be accepted to our community.
That is to select `as` spelling not `:=` and modify `with` and
`except` statements. Here is this.

* Below is copy-pasted from my gist:
https://gist.github.com/rnarkk/cdabceaedbdb498d99802a76cc08b549


# `as` assignment expression

```python
# This
STATEMENT(EXPR_0 as NAME_0, EXPR_1 as NAME_2, ..., EXPR_n as NAME_n)

# can always be replaced by
NAME_0 = EXPR_0
NAME_1 = EXPR_1
...
NAME_n = EXPR_n
STATEMENT(NAME_0, NAME_1, ..., NAME_n)

# except `import` statement since it's special from the beginning
which means no `EXPR` cannot be the left hand of `as` in its statement
but simply `NAME`: `import NAME_0 as NAME_1`

# This interpretation above is valid no matter how `EXPR_i` uses
`NAME_j` (i > j).

# When you write
EXPR as NAME_0, NAME_1

# it's interpreted as
(EXPR as NAME_0), NAME_1

# TODO Should unpacking is allowed by this?
EXPR as (NAME_0, NAME_1)

# `EXPR as NAME` itself can be `EXPR` and it returns just `EXPR` in
`EXPR as NAME` which means you can write
((EXPR as NAME_0) as NAME_1) ... as NAME_n

# or simply like this even at the top level since it's determininable.
EXPR as NAME_0 as NAME_1 ... as NAME_n

NAME_0 = EXPR as NAME_1 ... as NAME_n

# Also you can write
f(x=EXPR as NAME)

# since this is valid and `EXPR as NAME` can be `EXPR`.
f(x=EXPR)

# And also this is passible.
if (EXPR as NAME).method(): ...

# The `EXPR` in `EXPR as NAME` is matched as long as possible which means
if 0 < 1 as x: ...

# is interpreted as
if (0 < 1) as x: ...

# not
if 0 < (1 as x): ...

# but also `EXPR` is separated by `,` which means
EXPR_0, EXPR_1 as NAME

# is interpreted as
EXPR_0, (EXPR_1 as NAME)

# rather than
(EXPR_0, EXPR_1) as NAME

# even when used `as` assignment expression in list comprehension,
# you can apply the same rules above first by putting it to `for` loop form.

# There is no equivalence to type annotation and augmented assignment.
```


# `with` statement

- `with` statement will no longer responsible for passing returned
value from `__enter__` to the right hand of `as` in its statement and
merely call `__enter__` when enter the statement and `__exit__` when
exit from it an
- Context manager can be renamed simply to context since it will no
longer be manager but context itself. Context object has status of the
context and encapsulates it.

# `except` statement

- `except` statement will no longer responsible for passing instance
of the right hand of `as` in its statement.
- Exceptions must be instanciated and also it must be confirmed
otherwise `except` statement could rewrite the class globally.


Thanks,
Rin Arakaki
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Removal of install_misc command from distutils

2018-07-05 Thread Alexander Belopolsky
I started porting my project [1] to Python 3.7 and came across bpo-29218:

"The unused distutils install_misc command has been removed."  [2]

Historically, the distutils package was very conservative about changes
because many 3rd party packages extended it in ways unforeseen by the
Python core developers.  As far as I can tell, this removal was done
without a deprecation period or any public discussion.

The comment above the command class [3] was there for 18 years and promised
to "keep it around for the time being."  Why did it suddenly become
necessary to remove it in 3.7?  Is shedding 20 lines of code really worth
the risk of breaking user code?

[1]: https://github.com/KxSystems/pyq
[2]: https://docs.python.org/3/whatsnew/3.7.html#api-and-feature-removals
[3]:
https://github.com/python/cpython/commit/aae45f93e7b7708deb1ce9d69b58fa029106613d
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572, VF/B, and "Shark Jumping"

2018-07-05 Thread Steven D'Aprano
On Thu, Jul 05, 2018 at 08:52:24PM +0300, Ivan Pozdeev via Python-Dev wrote:

> * Same goes for `except`: doesn't accept expressions, same semantic.


py> def make_exception(arg):
... return ValueError if arg else TypeError
...
py> expr = [make_exception]
py> try:
... 1+"1"
... except expr[0](None) as err:
... print("caught", type(err))
... print(err)
...
caught 
unsupported operand type(s) for +: 'int' and 'str'


-- 
Steve
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572, VF/B, and "Shark Jumping"

2018-07-05 Thread Ivan Pozdeev via Python-Dev

On 05.07.2018 3:22, Chris Angelico wrote:

Python uses "as NAME" for things that
are quite different from this, so it's confusing
I wrote in 
https://mail.python.org/pipermail/python-dev/2018-June/154066.html that 
this is easily refutable.

Looks like not for everybody. Okay, here goes:

The constructs that currently use `as' are:

* import module as m
* except Exception as e:
* with expr as obj:

* In `with', there's no need to assign both `expr' and its __enter__() 
result -- because the whole idea of `with' is to put the object through 
`__enter__', and because a sane `__enter__()' implementation will return 
`self' anyway (or something with the same semantic -- i.e. _effectively_ 
`self'). But just in case, the double-assignment can be written as:


with (expr as obj) as ctx_obj:

by giving "as" lower priority than `with'. As I said, the need for this 
is nigh-nonexistent.


* `import' doesn't allow expressions (so no syntactic clash here), but 
the semantic of "as" here is equivalent to the AE, so no confusion here.

* Same goes for `except`: doesn't accept expressions, same semantic.

So, with "as" only `with' becomes the exception -- and an easily 
explainable one since its whole purpose is to implicitly call the 
context manager interface.

___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Assignment expression and coding style: the while True case

2018-07-05 Thread Tim Peters
[Victor Stinner]

> FYI I'm trying to use assignment expressions on the stdlib because
> *all* examples of the PEP 572 look artificial to me.
>

All the examples in my Appendix A were derived from real. pre-existing code
(although mostly my own).  It's turned out that several others with your
complaint above never read the PEP after that Appendix was added, so it's
possible that applies to you too.


> Like "group = re.match(data).group(1) if re.match(data) else None"
> which is followed by "(TODO: Include Guido's evidence, and do a more
> systematic search.)" I cannot find such inefficient code in the
> stdlib. I'm not saying that nobody writes code like that, just that
> developers with a good Python expertise would avoid to write such
> code.
>

Sure.  It happens, but it's rare.  As I've said many times already, I was
slightly surprised to conclude that the PEP was a win, but very surprised
to conclude it was the frequent dead- obvious little wins that added up to
its strongest case.

But that's mostly from staring at my code, and there's really nobody on
Earth better qualified to make my tradeoffs than I am ;-)

I don't discount Guido's impressions either.  While it's unlikely you're
going to find needlessly inefficient code in my Python, or the std lib, to
save a line, I'm not surprised at all that he found people writing worse
(on several counts - readability, maintainability, and speed) code _ just_
to save a line in "industrial Python".  Rather than dismiss the value for
them because they're not as expert as I am, or as our std lib authors have
been, I take it as evidence that the PEP provides value to others in ways
that don't really apply to bona-fide-Python-expert code.  I suspect, but
don't know, Guido is more moved by _that_ factor than by the dead obvious
little wins in experts' code.

 "filtered_data = [y for x in data if (y := f(x)) is not None]" also

seems artificial. In the 711,617 lines of Python code of the stdlib, I
> only found *one* example:
>

Well, you can't have it both ways.  That is, you can't fret that the
feature will be massively used while simultaneously claiming there are
almost no plausible uses at all ;-)


>...

And I also only found a single for loop which can be converted to a
> list comprehension thanks to assignement expression.


> lines = []
> for raw_line in raw_lines:
> match = line_pat.search(raw_line.strip())
> if match:
> lines.append(match.group(1, 2))
>

And I don't see it as "an obvious win" _to_ change it, so wouldn't rewrite
it anyway.  Then again, my bar for "obvious win" may be higher than others'.


[Tim]

> > Wholesale changes to the std lib are unlikely to happen regardless.
> Broad
> > patches just to spell things differently without _need_ are discouraged.
>


> So PEP 572 is purely syntax sugar? It doesn't bring anything to the
> stdlib for example?
>

Insert the standard tedious observation about "Turing complete" here.  I'm
too old to bear it again ;-)

Patches to make widespread more-or-less mindless changes are _always_
frowned on, unless it's truly necessary (because, e.g., a language change
means the existing idiom will no longer work in the next release, or the
existing idiom is known to be 10x slower than a new alternative, or ...).
It clutters the history, greatly obscures who is "really responsible" for
the line that just showed up in a critical-failure traceback, and any code
churn risks introducing bugs.  Especially when people with little knowledge
of a module are changing it.  No matter how careful they are, they suffer
brain farts when making widespread changes to code they've basically never
seen before, and do introduce errors.  That's empirical historic fact.

Instead module experts introduce such changes incrementally while going
about their regular business, if they so choose.  If, for example, Raymond
despises assignment expressions. it's fine by me if itertools and random.py
(two modules for which he's the primary maintainer) never use them - and
it's a Bad Thing if someone else forces them on him without his approval.

In any case, I'd be -1 on your current approach regardless, until you drop
the outer parens in

if (name := f()):

etc.  It reads better as the intended:

if name := f():

and that can matter.  There _is_ a side effect going on here, and on
general principle it's better to avoid "hiding it" inside parentheses
unless there's a need to.  There's no possible way to misread the
unparenthesized form in this context, so there's no point at all to adding
redundant parens.  "But some earlier version of the PEP may or may not have
required them - I don't recall" is no longer a real point ;-)


My current 3 pull requests showing how assignment expressions can be
> used in the stdlib:
>
> while True: https://github.com/python/cpython/pull/8095/files
> match/group: https://github.com/python/cpython/pull/8097/files
> list comp: 

Re: [Python-Dev] PEP 572, VF/B, and "Shark Jumping"

2018-07-05 Thread Mike Miller



On 2018-07-05 04:28, Ivan Pozdeev via Python-Dev wrote:

This is as intended.
I wanted to show my summary and Chris' refuttal, with links to both original 
posts. Because my letter is much shorter than the originals while carrying the 
same message. Also to show that I've made the same mistake, which puts things in 
perspective: how an outsider could get the wrong idea.



There will always be a long tail of new languages doing any and everything. 
Which new languages are actually being used?  The more limited ones.  Static 
typing, fewer foot-guns.


Arguably Elixir should have been in the original list, but it is practically 
unknown compared to Kotlin, for example.


-Mike
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572, VF/B, and "Shark Jumping"

2018-07-05 Thread Mike Miller



On 2018-07-04 17:22, Chris Angelico wrote:

- the "if expr as name:" syntax is able to handle only the tiniest
proportion of cases, because many MANY situations require a condition
after that. You can't write this, for instance:

if f(x) as spam < 0:
 print(spam)


The original use cases didn't ask for these compound conditions.  In fact many 
of the other threads this week are advising folks to break up an expression with 
compound conditions due to lack of readability.


The common cases described:

- compute value once in a comprehension
- loop and a half (reading file, socket)
- common regex match

More complex cases can be handled the old way.

> Python uses "as NAME" for things that
> are quite different from this, so it's confusing),

It's less confusing, and limited.  No one bats an eyelash after using "as" day 
after day in Python and SQL.


Good day,
-Mike
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572, VF/B, and "Shark Jumping"

2018-07-05 Thread Mike Miller



On 2018-07-04 23:20, Steven D'Aprano wrote:

It simply isn't true that modern languages are moving away from
assignment expressions. Some are. Some aren't. Even those that don't
support assignment expressions in general usually support special syntax
to allow it in a few contexts.


The older post you are referring and this thread describe the exact situation in 
your last sentence.  The limited assignment "compromise" is a common solution 
nowadays, just as this thread discusses.


Repeating "it won't work" when it has been shown to work well in several 
languages is nonsensical.  Yes, the available solutions are not perfect, but I 
still maintain "as" is less disruptive and doesn't reverse 25 year-old design 
choices, but rather works with them.


-Mike
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: intended scope of assignment expression

2018-07-05 Thread Ivan Pozdeev via Python-Dev

On 05.07.2018 15:20, Victor Stinner wrote:

Hi,

My work (*) in the "Assignment expression and coding style: the while
True case" thread helped me to understand something about the
*intended* scope.

While technically, assignment expressions keep the same scoping rules
than assignment statements, writing "if (x := func()): ..." or "while
(x := func()): ..." shows the "intented" scope of the variable. Even
if, as explained properly in the PEP, the scope is wider (for good
reasons) as "for line in file: ..." keeps line alive after the loop
(nothing new under the sun). It's something subtle that I missed at
the first read (of the code and the PEP), the difference is not
obvious.

x = func()
if x:
 ... # obviously use x
# do we still plan to use x here?
# it's non obvious just by reading the if

versus

if (x := func()):
 ... # obviously use x
# ":=" in the if "announces" that usually x is no longer used
# here, even if technically x is still defined


The construct for temporary variables is `with'. `if' carries no such 
implications.



See my match/group PR for more concrete examples:
https://github.com/python/cpython/pull/8097/files

I understand the current PEP 572 rationale as: assignment expressions
reduces the number of lines and the indentation level... pure syntax
sugar.

IMHO this "intended" scope is a much better way to sell assignment
expressions than the current rationale. In fact, it's explained later
very quickly in the PEP:
https://www.python.org/dev/peps/pep-0572/#capturing-condition-values

But it could be better explained than just "good effect in the header
of an if or while statement".

The PEP contains a good example of the intended scope:

if pid := os.fork():
 # Parent code
 # pid is valid and is only intended to be used in this scope
 ... # use pid
else:
 # Child code
 # pid is "invalid" (equal to zero)
 ... # don't use pid
# since this code path is common to parent and child,
# the pid is considered invalid again here
# (since the child does also into this path)
... # don't use pid


(*) My work: my current 3 pull requests showing how assignment
expressions can be
used in the stdlib:

while True: https://github.com/python/cpython/pull/8095/files
match/group: https://github.com/python/cpython/pull/8097/files
list comp: https://github.com/python/cpython/pull/8098/files

Victor
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/vano%40mail.mipt.ru


___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: intended scope of assignment expression

2018-07-05 Thread Victor Stinner
After "Assignment expression and coding style: the while True case",
here is the part 2: analysis of the "if (var := expr): ..." case.

2018-07-05 14:20 GMT+02:00 Victor Stinner :
> *intended* scope.

I generated the giant pull request #8116 to show where I consider that
"if (var := expr): ..." would be appropriate in the stdlib:

   https://github.com/python/cpython/pull/8116/files

In short, replace:

var = expr
if var:
...

with:

if (var := expr):
...


I used a script to replace "var = expr; if var: ..." with "if (var :=
expr): ...". I restricted my change to the simplest test "if var:",
other conditions like "if var > 0:" are left unchaned to keep this
change reviewable (short enough). The change is already big enough (62
files modified) to have enough examples! Then I validated each change
manually:

(*) I reverted all changes when 'var' is still used after the if.

(*) I also reverted some changes like "var = regex.match(); if var:
return var.group(1)", since it's already handled by my PR 8097:
https://github.com/python/cpython/pull/8097/files

(*) Sometimes, 'var' is only used in the condition and so has been
removed in this change. Example:

ans = self._compare_check_nans(other, context)
if ans:
return False
return self._cmp(other) < 0

replaced with:

if self._compare_check_nans(other, context):
return False
return self._cmp(other) < 0

(Maybe such changes should be addressed in a different pull request.)


Below, some examples where I consider that assignment expressions give
a value to the reader.


== Good: site (straighforward) ==

env_base = os.environ.get("PYTHONUSERBASE", None)
if env_base:
return env_base

replaced with:

if (env_base := os.environ.get("PYTHONUSERBASE", None)):
return env_base

Note: env_base is only used inside the if block.

== Good: datetime (more concise code) ==

New code:

def isoformat(self, timespec='auto'):
s = _format_time(self._hour, self._minute, self._second,
  self._microsecond, timespec)
if (tz := self._tzstr()):
s += tz
return s

This example shows the benefit of the PEP 572: remove one line without
making the code worse to read.

== Good: logging.handlers ==

def close(self):
self.acquire()
try:
sock = self.sock
if sock:
self.sock = None
sock.close()
logging.Handler.close(self)
finally:
self.release()

replaced with:

def close(self):
self.acquire()
try:
if (sock := self.sock):
self.sock = None
sock.close()
logging.Handler.close(self)
finally:
self.release()

== Good: doctest ==

New code:

# Deal with exact matches possibly needed at one or both ends.
startpos, endpos = 0, len(got)
if (w := ws[0]):   # starts with exact match
if got.startswith(w):
startpos = len(w)
del ws[0]
else:
return False

if (w := ws[-1]):   # ends with exact match
if got.endswith(w):
endpos -= len(w)
del ws[-1]
else:
return False

...

This example is interesting: the 'w' variable is reused, but ":="
announces to the reader that the w is only intended to be used in one
if block.

== Good: csv (reuse var) ==

New code:

n = groupindex['quote'] - 1
if (key := m[n]):
quotes[key] = quotes.get(key, 0) + 1
try:
n = groupindex['delim'] - 1
key = m[n]
except KeyError:
continue
if key and (delimiters is None or key in delimiters):
delims[key] = delims.get(key, 0) + 1

As for doctest: "key := ..." shows that this value is only used in one
if block, but later key is reassigned to a new value.

== Good: difflib ==

New code using (isjunk := self.isjunk):

# Purge junk elements
self.bjunk = junk = set()
if (isjunk := self.isjunk):
for elt in b2j.keys():
if isjunk(elt):
junk.add(elt)
for elt in junk: # separate loop avoids separate list of keys
del b2j[elt]

-*-*-*-

== Borderline? sre_parse (two conditions) ==

code = CATEGORIES.get(escape)
if code and code[0] is IN:
return code

replaced with:

if (code := CATEGORIES.get(escape)) and code[0] is IN:
return code

The test "code[0] is IN" uses 'code' just after it's defined on the
same line. Maybe it is surprising me, since I'm not sure to assignment
expressions yet.

-*-*-*-

== BAD! argparse (use after if) ==

Ok, now let's see cases where I consider that assignment expressions
are inappropriate! Here is a first example.

help = self._root_section.format_help()
if help:
help = self._long_break_matcher.sub('\n\n', help)
help = help.strip('\n') + '\n'
return 

Re: [Python-Dev] PEP 572: intended scope of assignment expression

2018-07-05 Thread MRAB

On 2018-07-05 16:07, Victor Stinner wrote:

2018-07-05 15:14 GMT+02:00 Gustavo Carneiro :

I don't know if you're trying to propose something clever here, like "if (x
:= func()):" would assign to 'x' only inside the "then" body of the if, but
IMHO that would be a terrible idea:


I don't propose to change the PEP 572. I'm trying to explain to myself
where "if (var := expr): ..." would add anything to readers compared
to "var = expr; if var: ...". I know that var is still valid after the
if.

I'm not asking to raise a syntax error or even emit a linter warning
if var is used after the if. I'm just thinking loudly where the PEP
572 is appropriate.

IMHO the following code should not use assignement expression.

Good:

 help = self._root_section.format_help()
 if help:
 help = self._long_break_matcher.sub('\n\n', help)
 help = help.strip('\n') + '\n'
 return help

Bad?

 if (help := self._root_section.format_help()):
 help = self._long_break_matcher.sub('\n\n', help)
 help = help.strip('\n') + '\n'
 return help

IHMO using "help :=" here would send the wrong signal to the reader:
as if help is not going to be used after the if, whereas it's the case
("return help").


I think it's OK if it's:

Do something, and if that succeeded, act on it.

but not if it's:

Do something, but if that failed, do something else.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: intended scope of assignment expression

2018-07-05 Thread Victor Stinner
2018-07-05 15:14 GMT+02:00 Gustavo Carneiro :
> I don't know if you're trying to propose something clever here, like "if (x
> := func()):" would assign to 'x' only inside the "then" body of the if, but
> IMHO that would be a terrible idea:

I don't propose to change the PEP 572. I'm trying to explain to myself
where "if (var := expr): ..." would add anything to readers compared
to "var = expr; if var: ...". I know that var is still valid after the
if.

I'm not asking to raise a syntax error or even emit a linter warning
if var is used after the if. I'm just thinking loudly where the PEP
572 is appropriate.

IMHO the following code should not use assignement expression.

Good:

help = self._root_section.format_help()
if help:
help = self._long_break_matcher.sub('\n\n', help)
help = help.strip('\n') + '\n'
return help

Bad?

if (help := self._root_section.format_help()):
help = self._long_break_matcher.sub('\n\n', help)
help = help.strip('\n') + '\n'
return help

IHMO using "help :=" here would send the wrong signal to the reader:
as if help is not going to be used after the if, whereas it's the case
("return help").

Victor
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Comparing PEP 576 and PEP 580

2018-07-05 Thread Jeroen Demeyer

On 2018-07-05 14:20, INADA Naoki wrote:

What you can do is "divide and conquer".  Split PEP in small topics we
can focus.


The PEP is already small and focused, I really did my best to make it as 
minimal as possible. I don't see a meaningful way to split it up even 
further.

___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] On the METH_FASTCALL calling convention

2018-07-05 Thread Jeroen Demeyer

Hello all,

As discussed in some other threads ([1], [2]), we should discuss the 
METH_FASTCALL calling convention.


For passing only positional arguments, a C array of Python objects is 
used, which is as fast as it can get. When the Python interpreter calls 
a function, it builds that C array on the interpreter stack:


>>> from dis import dis
>>> def f(x, y): return g(x, y, 12)
>>> dis(f)
  1   0 LOAD_GLOBAL  0 (g)
  2 LOAD_FAST0 (x)
  4 LOAD_FAST1 (y)
  6 LOAD_CONST   1 (12)
  8 CALL_FUNCTION3
 10 RETURN_VALUE

A C array can also easily and efficiently be handled by the C function 
receiving it. So I consider this uncontroversial.


The convention for METH_FASTCALL|METH_KEYWORDS is that keyword *names* 
are passed as a tuple and keyword *values* in the same C array with 
positional arguments. An example:


>>> from dis import dis
>>> def f(x, y, z): return f(x, foo=y, bar=z)
>>> dis(f)
  1   0 LOAD_GLOBAL  0 (f)
  2 LOAD_FAST0 (x)
  4 LOAD_FAST1 (y)
  6 LOAD_FAST2 (z)
  8 LOAD_CONST   1 (('foo', 'bar'))
 10 CALL_FUNCTION_KW 3
 12 RETURN_VALUE

This is pretty clever: it exploits the fact that ('foo', 'bar') is a 
constant tuple stored in f.__code__.co_consts. Also, a tuple can be 
efficiently handled by the called code: it is essentially a thin wrapper 
around a C array of Python objects. So this works well.


The only case when this handling of keywords is suboptimal is when using 
**kwargs. In that case, a dict must be converted to a tuple. It looks 
hard to me to support efficiently both the case of fixed keyword 
arguments (f(foo=x)) and a keyword dict (f(**kwargs)). Since the former 
is more common than the latter, the current choice is optimal.


In other words: I see nothing to improve in the calling convention of 
METH_FASTCALL. I suggest to keep it and make it public as-is.



Jeroen.


[1] https://mail.python.org/pipermail/python-dev/2018-June/153945.html
[2] https://mail.python.org/pipermail/python-dev/2018-July/154251.html
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: intended scope of assignment expression

2018-07-05 Thread Chris Angelico
On Thu, Jul 5, 2018 at 11:14 PM, Gustavo Carneiro  wrote:
> On Thu, 5 Jul 2018 at 13:43, Victor Stinner  wrote:
>>
>> Hi,
>>
>> My work (*) in the "Assignment expression and coding style: the while
>> True case" thread helped me to understand something about the
>> *intended* scope.
>>
>> While technically, assignment expressions keep the same scoping rules
>> than assignment statements, writing "if (x := func()): ..." or "while
>> (x := func()): ..." shows the "intented" scope of the variable. Even
>> if, as explained properly in the PEP, the scope is wider (for good
>> reasons) as "for line in file: ..." keeps line alive after the loop
>> (nothing new under the sun). It's something subtle that I missed at
>> the first read (of the code and the PEP), the difference is not
>> obvious.
>>
>> x = func()
>> if x:
>> ... # obviously use x
>> # do we still plan to use x here?
>> # it's non obvious just by reading the if
>>
>> versus
>>
>> if (x := func()):
>> ... # obviously use x
>> # ":=" in the if "announces" that usually x is no longer used
>> # here, even if technically x is still defined
>
>
> I don't know if you're trying to propose something clever here, like "if (x
> := func()):" would assign to 'x' only inside the "then" body of the if, but
> IMHO that would be a terrible idea:
>
> 1. it makes AE harder to explain.  Right now you can simply say AE works
> just like any regular assignment, except that you can use in an expression.
> If you start adding exceptions to the rule, things get harder and harder to
> explain;
> 2. it would probably have a cost in terms of performance: you'd have to
> create another scope for every "then" body of any if statement that contains
> an AE.  And, again, more scopes = things harder to understand.
>

The time machine strikes again. There were actually semantics defined
in PEP 572 that would have done exactly this. They were sane,
coherent, and internally consistent, but ultimately, not as useful as
just maintaining the equivalence of "x = 2" and "x := 2". Subscope
semantics aren't as impossible as you're implying here.

ChrisA
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: intended scope of assignment expression

2018-07-05 Thread Gustavo Carneiro
On Thu, 5 Jul 2018 at 13:43, Victor Stinner  wrote:

> Hi,
>
> My work (*) in the "Assignment expression and coding style: the while
> True case" thread helped me to understand something about the
> *intended* scope.
>
> While technically, assignment expressions keep the same scoping rules
> than assignment statements, writing "if (x := func()): ..." or "while
> (x := func()): ..." shows the "intented" scope of the variable. Even
> if, as explained properly in the PEP, the scope is wider (for good
> reasons) as "for line in file: ..." keeps line alive after the loop
> (nothing new under the sun). It's something subtle that I missed at
> the first read (of the code and the PEP), the difference is not
> obvious.
>
> x = func()
> if x:
> ... # obviously use x
> # do we still plan to use x here?
> # it's non obvious just by reading the if
>
> versus
>
> if (x := func()):
> ... # obviously use x
> # ":=" in the if "announces" that usually x is no longer used
> # here, even if technically x is still defined
>

I don't know if you're trying to propose something clever here, like "if (x
:= func()):" would assign to 'x' only inside the "then" body of the if, but
IMHO that would be a terrible idea:

1. it makes AE harder to explain.  Right now you can simply say AE works
just like any regular assignment, except that you can use in an
expression.  If you start adding exceptions to the rule, things get harder
and harder to explain;
2. it would probably have a cost in terms of performance: you'd have to
create another scope for every "then" body of any if statement that
contains an AE.  And, again, more scopes = things harder to understand.

-- 
Gustavo J. A. M. Carneiro
Gambit Research
"The universe is always one step beyond logic." -- Frank Herbert
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Comparing PEP 576 and PEP 580

2018-07-05 Thread INADA Naoki
On Thu, Jul 5, 2018 at 9:02 PM Jeroen Demeyer  wrote:
>
> On 2018-07-05 13:32, INADA Naoki wrote:
> > Core devs interested in this area is limited resource.
>
> I know and unfortunately there is nothing that I can do about that. It
> would be a pity that PEP 580 (or a variant like PEP 576) is not accepted
> simply because no core developer cares enough.

What you can do is "divide and conquer".  Split PEP in small topics we
can focus.

>
> > As far as I understand, there are some important topics to discuss.
> >
> > a. Low level calling convention, including argument parsing API.
> > b. New API for calling objects without argument tuple and dict.
> > c. How more types can support FASTCALL, LOAD_METHOD and CALL_METHOD.
> > d. How to reorganize existing builtin types, without breaking stable ABI.
>
> Right, that's why I wanted PEP 580 to be only about (c) and nothing
> else. I made the mistake in PEP 575 of also involving (d).
>
> I still don't understand why we must finish (a) before we can even start
> discussing (c).

Again, "discussing" takes much critical resources.  And we got nothing
in Python 3.8 in worst case.

(c) won't be public unless (a) is public, although main motivation of (c)
is 3rd party tools.  That's why I prefer discussing (a) first.  Without (a),
discussion about (c) will not born anything in Python 3.8.

This is only advice from me and you can start discussion about (c),
like you ignored my advice about creating realistic benchmark for
calling 3rd party callable before talking about performance...

>
> > Reference implementation helps discussion.
>
> METH_FASTCALL and argument parsing for METH_FASTCALL is already
> implemented in CPython. Not in documented public functions, but the
> implementation exists.
>
> And PEP 580 also has a reference implementation:
> https://github.com/jdemeyer/cpython/tree/pep580
>

Yes I know.  I described just "I didn't say wait for implement".

-- 
INADA Naoki  
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] PEP 572: intended scope of assignment expression

2018-07-05 Thread Victor Stinner
Hi,

My work (*) in the "Assignment expression and coding style: the while
True case" thread helped me to understand something about the
*intended* scope.

While technically, assignment expressions keep the same scoping rules
than assignment statements, writing "if (x := func()): ..." or "while
(x := func()): ..." shows the "intented" scope of the variable. Even
if, as explained properly in the PEP, the scope is wider (for good
reasons) as "for line in file: ..." keeps line alive after the loop
(nothing new under the sun). It's something subtle that I missed at
the first read (of the code and the PEP), the difference is not
obvious.

x = func()
if x:
... # obviously use x
# do we still plan to use x here?
# it's non obvious just by reading the if

versus

if (x := func()):
... # obviously use x
# ":=" in the if "announces" that usually x is no longer used
# here, even if technically x is still defined

See my match/group PR for more concrete examples:
https://github.com/python/cpython/pull/8097/files

I understand the current PEP 572 rationale as: assignment expressions
reduces the number of lines and the indentation level... pure syntax
sugar.

IMHO this "intended" scope is a much better way to sell assignment
expressions than the current rationale. In fact, it's explained later
very quickly in the PEP:
https://www.python.org/dev/peps/pep-0572/#capturing-condition-values

But it could be better explained than just "good effect in the header
of an if or while statement".

The PEP contains a good example of the intended scope:

if pid := os.fork():
# Parent code
# pid is valid and is only intended to be used in this scope
... # use pid
else:
# Child code
# pid is "invalid" (equal to zero)
... # don't use pid
# since this code path is common to parent and child,
# the pid is considered invalid again here
# (since the child does also into this path)
... # don't use pid


(*) My work: my current 3 pull requests showing how assignment
expressions can be
used in the stdlib:

while True: https://github.com/python/cpython/pull/8095/files
match/group: https://github.com/python/cpython/pull/8097/files
list comp: https://github.com/python/cpython/pull/8098/files

Victor
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Assignment expression and coding style: the while True case

2018-07-05 Thread Victor Stinner
2018-07-05 9:10 GMT+02:00 Tim Peters :
> I'm all in favor of what Victor is doing:  looking at how this stuff will
> work in actual code.  That's a great antidote to the spread of theoretical
> fears.

FYI I'm trying to use assignment expressions on the stdlib because
*all* examples of the PEP 572 look artificial to me.

Like "group = re.match(data).group(1) if re.match(data) else None"
which is followed by "(TODO: Include Guido's evidence, and do a more
systematic search.)" I cannot find such inefficient code in the
stdlib. I'm not saying that nobody writes code like that, just that
developers with a good Python expertise would avoid to write such
code.

"filtered_data = [y for x in data if (y := f(x)) is not None]" also
seems artificial. In the 711,617 lines of Python code of the stdlib, I
only found *one* example:

labels = [label.strip() for label
in self._file.readline()[1:].split(b',')
if label.strip()]

=> https://github.com/python/cpython/pull/8098/files

And I also only found a single for loop which can be converted to a
list comprehension thanks to assignement expression.

lines = []
for raw_line in raw_lines:
match = line_pat.search(raw_line.strip())
if match:
lines.append(match.group(1, 2))

> Wholesale changes to the std lib are unlikely to happen regardless.  Broad
> patches just to spell things differently without _need_ are discouraged.

So PEP 572 is purely syntax sugar? It doesn't bring anything to the
stdlib for example?

My current 3 pull requests showing how assignment expressions can be
used in the stdlib:

while True: https://github.com/python/cpython/pull/8095/files
match/group: https://github.com/python/cpython/pull/8097/files
list comp: https://github.com/python/cpython/pull/8098/files

Right now, I'm still not really excited by the new code.

If you spotted other parts of the stdlib where assignment expressions
would be appropriate, please tell me and I will try to write more pull
requests :-)

Victor
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Comparing PEP 576 and PEP 580

2018-07-05 Thread Jeroen Demeyer

On 2018-07-05 13:32, INADA Naoki wrote:

Core devs interested in this area is limited resource.


I know and unfortunately there is nothing that I can do about that. It 
would be a pity that PEP 580 (or a variant like PEP 576) is not accepted 
simply because no core developer cares enough.



As far as I understand, there are some important topics to discuss.

a. Low level calling convention, including argument parsing API.
b. New API for calling objects without argument tuple and dict.
c. How more types can support FASTCALL, LOAD_METHOD and CALL_METHOD.
d. How to reorganize existing builtin types, without breaking stable ABI.


Right, that's why I wanted PEP 580 to be only about (c) and nothing 
else. I made the mistake in PEP 575 of also involving (d).


I still don't understand why we must finish (a) before we can even start 
discussing (c).



Reference implementation helps discussion.


METH_FASTCALL and argument parsing for METH_FASTCALL is already 
implemented in CPython. Not in documented public functions, but the 
implementation exists.


And PEP 580 also has a reference implementation:
https://github.com/jdemeyer/cpython/tree/pep580


Jeroen.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Comparing PEP 576 and PEP 580

2018-07-05 Thread INADA Naoki
On Thu, Jul 5, 2018 at 6:31 PM Jeroen Demeyer  wrote:
>
> On 2018-07-05 05:41, INADA Naoki wrote:
> > And stabilizing calling convention is prerequirements of designing new
> > calling APIs.
>
> I don't see why. I made my PEP with the assumption that the
> METH_FASTCALL calling convention won't change. As far as I know, nobody
> advocated for changing it. But even if we decide to change
> METH_FASTCALL, I could trivially adapt my PEP.

Serhiy said "the protocol for keyword parameters is more complex and
still can be changed."
https://mail.python.org/pipermail/python-dev/2018-June/153949.html

>
> > That's why I suggest discussing METH_FASTCALL first.
>
> I certainly agree that it's a good idea to discuss METH_FASTCALL, but I
> still don't see why that should block the discussion of PEP 576/580.

Core devs interested in this area is limited resource.
As far as I understand, there are some important topics to discuss.

a. Low level calling convention, including argument parsing API.
b. New API for calling objects without argument tuple and dict.
c. How more types can support FASTCALL, LOAD_METHOD and CALL_METHOD.
d. How to reorganize existing builtin types, without breaking stable ABI.

It's difficult to understand all topics in both PEPs at once.
I suggested to focus on prerequirements first because it helps us to join
discussion without understand whole two PEPs.

>
> I can understand that you want to wait to *implement* PEP 576/580 as
> long as METH_FASTCALL isn't public. But we should not wait to *discuss*
> those PEPs.
>

I didn't want wait to "implement".  Discussion is the most critical path.
Reference implementation helps discussion.

Regards,

>
> Jeroen.
>

--
INADA Naoki  
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572, VF/B, and "Shark Jumping"

2018-07-05 Thread Ivan Pozdeev via Python-Dev

On 05.07.2018 9:20, Steven D'Aprano wrote:

On Thu, Jul 05, 2018 at 05:33:50AM +0300, Ivan Pozdeev via Python-Dev wrote:


And https://mail.python.org/pipermail/python-dev/2018-June/154160.html
disproves the "chosen often these days in new languages".

Ivan, I think you may have linked to the wrong page. That page was Chris
kindly referring you to my post here:

https://mail.python.org/pipermail/python-ideas/2018-May/050938.html


This is as intended.
I wanted to show my summary and Chris' refuttal, with links to both 
original posts. Because my letter is much shorter than the originals 
while carrying the same message. Also to show that I've made the same 
mistake, which puts things in perspective: how an outsider could get the 
wrong idea.



which refutes Mike's original, biased selection of a handful of
languages. Which he then misrepresented as not including assignment
expressions when half of them actually do, at least in a limited form.

(3 out of the 5 of Mike's examples include *at least* some limited
assignment expression. My survey found 13 out of 18 modern languages
have at least some form of assignment expression. See link above for
details.)

It simply isn't true that modern languages are moving away from
assignment expressions. Some are. Some aren't. Even those that don't
support assignment expressions in general usually support special syntax
to allow it in a few contexts.

But even if we pretended that, let's say, Go for example has no
assignment expressions (it actually does, but limited only to the
special case of if statements), what conclusion should we draw?

That Rob Pike is ever so much a better language designer than Guido?
Maybe he is, maybe he isn't, but Go is just eight years old. Python is
27. When Python was 8, it lacked a lot of features we find indispensible
now:

https://www.python.org/download/releases/1.5/whatsnew/

Who is to say that when Go is 27, or even 10, it won't have added
assignment expressions?

Some of Go's choices seem a bit... idiosyncratic. Strings are still
ASCII byte-strings. Unicode text is relegated to a seperate type,
"runes", the naming of which is a tad patronising and contemptuous of
non-ASCII users. There are no exceptions or try...finally. The designers
bowed to public pressure and added a sort of poor-man's exception system,
panic/recover, but for most purposes, they still requiring the "check a
flag to test success" anti-pattern. The designers are actively opposed
to assertions.

I dare say a lot of Python's choices seem strange to Go programmers too.

Rather than saying "Go got it right", maybe we should be saying "Go got
it wrong".




We can also reuse the existing "EXPR as NAME" syntax that already
exists and is widely enjoyed.


For the record, with "as", Victor Stinner's examples from the 5 Jul 2018
00:51:37 +0200 letter would look like:


Enough with the "as" syntax. This discussion has been going on since
FEBRUARY, and "as" was eliminated as ambiguous months ago. Stop beating
that dead horse.






--
Regards,
Ivan

___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Assignment expression and coding style: the while True case

2018-07-05 Thread Ivan Pozdeev via Python-Dev

On 05.07.2018 9:47, Steven D'Aprano wrote:

On Thu, Jul 05, 2018 at 12:51:37AM +0200, Victor Stinner wrote:


I propose to start the discussion about "coding style" (where are
assignment expressions appropriate or not?) with the "while True"
case.

We don't even have an official implementation yet, and you already want
to start prescribing coding style? We probably have months before 3.8
alpha comes out.


This is an excellent way to look at the picture with a user's eyes. You 
immediately see what parts of the design lend themselves well to 
practice and what don't, which details are unclear, which additional 
features are missing (note how he revealed the lack of tuple unpacking) 
-- by all means, something to do at the design stage, before doing the 
implementation.


It's also a testimony of how much an improvement a feature will _really_ 
be -- something that contrived examples can't tell.


I salute Victor for such an enlightemed idea and going for the trouble 
to carry it out!



I appreciate your enthusiasm, but what's the rush? Give people a chance
to play with the syntax in the REPL before making Thou Shalt and Thou
Shalt Not rules for coding style and making wholesale changes to the std
lib.

This topic has been argued and argued and argued on two mailing lists
for over four months. Let's take a couple of weeks to catch our breath,
wait for the implementation to actually hit the 3.8 repo, before trying
to prescribe coding style or thinking about which parts of the std lib
should be refactored to use it and which shouldn't.

There is no need to rush into making changes. Let them happen naturally.





--
Regards,
Ivan

___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Assignment expression and coding style: the while True case

2018-07-05 Thread Antoine Pitrou
On Thu, 5 Jul 2018 13:58:42 +0300
Ivan Pozdeev via Python-Dev  wrote:

> On 05.07.2018 9:23, Serhiy Storchaka wrote:
> > 05.07.18 01:51, Victor Stinner пише:  
> >> == Pattern 1, straighforward ==
> >>
> >> while True:
> >>  line = input.readline()
> >>  if not line:
> >>  break
> >>  ...
> >>
> >> IMHO here assingment expression is appropriate here. The code remains
> >> straighfoward to read.
> >>
> >> while (line := input.readline()):
> >>  ...  
> >
> > We already have an idiom for this:
> >
> > for line in input:
> >     ...
> >  
> 
> This is not strictly equivalent: it has internal caching unaffected by 
> -u and you can't iterate and .read() at the same time.

You are only talking about Python 2 here.

Regards

Antoine.


___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Assignment expression and coding style: the while True case

2018-07-05 Thread Ivan Pozdeev via Python-Dev

On 05.07.2018 9:23, Serhiy Storchaka wrote:

05.07.18 01:51, Victor Stinner пише:

== Pattern 1, straighforward ==

while True:
 line = input.readline()
 if not line:
 break
 ...

IMHO here assingment expression is appropriate here. The code remains
straighfoward to read.

while (line := input.readline()):
 ...


We already have an idiom for this:

for line in input:
    ...



This is not strictly equivalent: it has internal caching unaffected by 
-u and you can't iterate and .read() at the same time.


Though in this specific case (the example is from Lib\base64.py AFAICS), 
the change to `for' is fine.



___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/vano%40mail.mipt.ru


--
Regards,
Ivan

___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Comparing PEP 576 and PEP 580

2018-07-05 Thread Jeroen Demeyer

On 2018-07-05 05:41, INADA Naoki wrote:

And stabilizing calling convention is prerequirements of designing new
calling APIs.


I don't see why. I made my PEP with the assumption that the 
METH_FASTCALL calling convention won't change. As far as I know, nobody 
advocated for changing it. But even if we decide to change 
METH_FASTCALL, I could trivially adapt my PEP.



That's why I suggest discussing METH_FASTCALL first.


I certainly agree that it's a good idea to discuss METH_FASTCALL, but I 
still don't see why that should block the discussion of PEP 576/580.


I can understand that you want to wait to *implement* PEP 576/580 as 
long as METH_FASTCALL isn't public. But we should not wait to *discuss* 
those PEPs.



Jeroen.

___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Assignment expression and coding style: the while True case

2018-07-05 Thread Tim Peters
[Victor Stinner]
>
> > I propose to start the discussion about "coding style" (where are
> > assignment expressions appropriate or not?) with the "while True"
> > case.
>

[Steven D'Aprano]

> We don't even have an official implementation yet, and you already want
> to start prescribing coding style? We probably have months before 3.8
> alpha comes out.
>
> I appreciate your enthusiasm, but what's the rush? Give people a chance
> to play with the syntax in the REPL before making Thou Shalt and Thou
> Shalt Not rules for coding style and making wholesale changes to the std
> lib.
>

I'm all in favor of what Victor is doing:  looking at how this stuff will
work in actual code.  That's a great antidote to the spread of theoretical
fears.

Wholesale changes to the std lib are unlikely to happen regardless.  Broad
patches just to spell things differently without _need_ are discouraged.



> This topic has been argued and argued and argued on two mailing lists
> for over four months.


Which is why I strongly welcome looking at code instead.  A few people have
already noticed that some of Victor's changes aren't actually disasters ;-)


> Let's take a couple of weeks to catch our breath,

wait for the implementation to actually hit the 3.8 repo, before trying
> to prescribe coding style or thinking about which parts of the std lib
> should be refactored to use it and which shouldn't.
>

The more code people look at, the better.  It won't be merged, but having
the diffs makes it all concrete.  And while I don't particularly care to
argue about coding style myself, at least that would be a _new_ thing to
argue about ;-)
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Assignment expression and coding style: the while True case

2018-07-05 Thread Steven D'Aprano
On Thu, Jul 05, 2018 at 12:51:37AM +0200, Victor Stinner wrote:

> I propose to start the discussion about "coding style" (where are
> assignment expressions appropriate or not?) with the "while True"
> case.

We don't even have an official implementation yet, and you already want 
to start prescribing coding style? We probably have months before 3.8 
alpha comes out.

I appreciate your enthusiasm, but what's the rush? Give people a chance 
to play with the syntax in the REPL before making Thou Shalt and Thou 
Shalt Not rules for coding style and making wholesale changes to the std 
lib.

This topic has been argued and argued and argued on two mailing lists 
for over four months. Let's take a couple of weeks to catch our breath, 
wait for the implementation to actually hit the 3.8 repo, before trying 
to prescribe coding style or thinking about which parts of the std lib 
should be refactored to use it and which shouldn't.

There is no need to rush into making changes. Let them happen naturally.



-- 
Steve
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Assignment expression and coding style: the while True case

2018-07-05 Thread Serhiy Storchaka

05.07.18 03:03, Victor Stinner пише:

+labels = [slabel for label
+  in self._file.readline()[1:].split(b',')
+  if (slabel := label.strip())]


labels = [slabel for label
  in self._file.readline()[1:].split(b',')
  for slabel in [label.strip()]
  if slabel]


+lines = [match.group(1, 2)
+ for raw_line in raw_lines
+ if (match := line_pat.search(raw_line.strip()))]


lines = [match.group(1, 2)
 for raw_line in raw_lines
 for match in [line_pat.search(raw_line.strip())]
 if match]

But in all these cases I prefer the original loop.

___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Assignment expression and coding style: the while True case

2018-07-05 Thread Serhiy Storchaka

05.07.18 01:51, Victor Stinner пише:

== Pattern 1, straighforward ==

while True:
 line = input.readline()
 if not line:
 break
 ...

IMHO here assingment expression is appropriate here. The code remains
straighfoward to read.

while (line := input.readline()):
 ...


We already have an idiom for this:

for line in input:
...

___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572, VF/B, and "Shark Jumping"

2018-07-05 Thread Steven D'Aprano
On Thu, Jul 05, 2018 at 05:33:50AM +0300, Ivan Pozdeev via Python-Dev wrote:

> And https://mail.python.org/pipermail/python-dev/2018-June/154160.html 
> disproves the "chosen often these days in new languages".

Ivan, I think you may have linked to the wrong page. That page was Chris 
kindly referring you to my post here:

https://mail.python.org/pipermail/python-ideas/2018-May/050938.html

which refutes Mike's original, biased selection of a handful of 
languages. Which he then misrepresented as not including assignment 
expressions when half of them actually do, at least in a limited form.

(3 out of the 5 of Mike's examples include *at least* some limited 
assignment expression. My survey found 13 out of 18 modern languages 
have at least some form of assignment expression. See link above for 
details.)

It simply isn't true that modern languages are moving away from 
assignment expressions. Some are. Some aren't. Even those that don't 
support assignment expressions in general usually support special syntax 
to allow it in a few contexts.

But even if we pretended that, let's say, Go for example has no 
assignment expressions (it actually does, but limited only to the 
special case of if statements), what conclusion should we draw?

That Rob Pike is ever so much a better language designer than Guido? 
Maybe he is, maybe he isn't, but Go is just eight years old. Python is 
27. When Python was 8, it lacked a lot of features we find indispensible 
now:

https://www.python.org/download/releases/1.5/whatsnew/

Who is to say that when Go is 27, or even 10, it won't have added 
assignment expressions?

Some of Go's choices seem a bit... idiosyncratic. Strings are still 
ASCII byte-strings. Unicode text is relegated to a seperate type, 
"runes", the naming of which is a tad patronising and contemptuous of 
non-ASCII users. There are no exceptions or try...finally. The designers 
bowed to public pressure and added a sort of poor-man's exception system, 
panic/recover, but for most purposes, they still requiring the "check a 
flag to test success" anti-pattern. The designers are actively opposed 
to assertions.

I dare say a lot of Python's choices seem strange to Go programmers too.

Rather than saying "Go got it right", maybe we should be saying "Go got 
it wrong".



> >We can also reuse the existing "EXPR as NAME" syntax that already 
> >exists and is widely enjoyed.
> >
> 
> For the record, with "as", Victor Stinner's examples from the 5 Jul 2018 
> 00:51:37 +0200 letter would look like:


Enough with the "as" syntax. This discussion has been going on since 
FEBRUARY, and "as" was eliminated as ambiguous months ago. Stop beating 
that dead horse.




-- 
Steve
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com