[Tim Delaney <timothy.c.dela...@gmail.com>] >>> My big concern here involves the: >>> >>> if local(m = re.match(regexp, line)): >>> print(m.group(0)) >>> >>> example. The entire block needs to be implicitly local for that to work >>> - >>> what happens if I assign a new name in that block?
[Tim Peters] >> I really don't know what you're asking there. Can you make it >> concrete? If, e.g., you're asking what happens if this appeared after >> the `print`: >> >> x = 3.14 >> >> then the answer is "the same as what would happen if `local` had not >> been used". We can't know what that is without context, though. >> Maybe x is global. Maybe x was declared nonlocal earlier. Maybe it's >> function-local. ... [Tim D] > That's exactly what I was asking, and as I understand what you're saying, we > would have a local name m available in the indented block which went away > when the block ended, but any names modified in the block are not local to > the block. That seems likely to be a source of errors. If you what you _want_ is a genuinely new scope, yes. But no actual use cases so far wanted that at all. This is the kind of code about which there have been background complaints "forever": m1 = regexp1.match(line) m2 = regexp2.match(iine) if m1 and m2: do all sorts of stuff with m1 and/or m2, including perhaps modifying local variables and/or global variables and/or nonlocal variables The complaints are of two distinct kinds: 1. "I want to compute m1 and m2 _in_ the `if` test". 2. "I don't want these temp names (m1 and m2) accidentally conflicting with local names already in scope - if these names already exist, I want the temp names to shadow their current bindings until the `if` structure is done". So, if local(m1=regexp1.match(line), m2 = regexp2.match(iine), m1 and m2): intends to address both complaints via means embarrassingly obvious to the most casual observer ;-) This is, e.g., the same kind of name-specific "shadowing" magically done by list and dict comprehensions now, and by generator expressions. For example, [i**2 for i in range(10)] has no effect on whatever `i` meant before the listcomp was executed. > To clarify my understanding, if the names 'x' and 'm' did not exist prior to > the following code, what would x and m refer to after the block completed? > > if local(m = re.match(regexp, line)): > x = 1 > m = 2 I hope the explanation above made that clear. What's wanted is exactly what the current m = re.match(regexp, line): if m: x =1 m = 2 _would_ do if only there were a sane way to spell "save m's current status before that all started and restore it after that all ends". So they want `x == 1` after it's over, and `m` to raise NameError. >>> if local { m = re.match(regexp, line) }: >>> print(m.group(0)) >> OK, this is the only case in which you used it in an `if` or `while` >> expression. All the questions you asked of me at the start can be >> asked of this spelling too. >> You seemed to imply at the start that the >> right curly brace would always mark the end of the new scope. But if >> that's so, the `m` in `m.group()` has nothing to do with the `m` >> assigned to in the `local` block - _that_ scope ended before `print` >> was reached. > Yes - I think this is exactly the same issue as with your proposed syntax. Wholly agreed :-) >> So if you're not just trying to increase the level of complexity of >> what can appear in a local block, a fundamental problem still needs >> solving ;-) I suppose you could solve it like so: >> >> local { m = re.match(regexp, line) >> if m: >> print(m.group(0)) >> } >> >> but, besides losing the "shortcut", it would also mean something >> radically different if >> >> x = 3.14 >> >> appeared after the "print". Right? If a "local block" is taken >> seriously, then _all_ names bound inside it vanish when the block >> ends. > Indeed, and I don't have a proposal - just concerns it wold be very > difficult to explain and understand exactly what would happen in the case of > something like: > > if local(m = re.match(regexp, line)): > x = 1 > m = 2 Only names appearing as targets _in_ the `local(...)` are affected in any way. The states of those names are captured, then those names are bound to the values of the associated expressions in the `local(...)`, and when the scope of the `local` construct ends (which _is_ hard to explain!) those names' original states are restored. So the effects on names are actually pretty easy to explain: all and only the names appearing inside the `local(...)` are affected. > Regarding the syntax, I didn't want to really change your proposal, but just > thought the functionality was different enough from the function call it > appears to be that it probably merits different syntax. Probably so! _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/