Re: [Python-Dev] PEP 572: Do we really need a ":" in ":="?
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
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 ":="?)
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 ":="?
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 ":="?
[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 ":="?
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 ":="?
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
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 ":="?
[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 ":="?
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 ":="?
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 ":="?
[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
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 ":="?
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 ":="?
[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 ":="?
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
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
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 ":="?
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 ":="?
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
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 ":="?
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"
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
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
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
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
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
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
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
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
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"
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
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
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"
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"
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
[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"
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"
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"
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
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
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
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 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
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
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
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
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
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
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 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
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
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"
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
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
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
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
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
[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
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
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
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"
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