Whitespace handling for indexing

I think that it would be beneficial for PEP 8 conformance, in the case of large nested dicts, if one were able to separate dict indices by a newline. What I mean is shown below: foo["bar"] ["baz"] ["eggs"] ["spam"] = 1

While that formatting does look nice, this would be a huge change to the parser just to allow a new formatting style. Right now lines are only logically joined if they appear between a pair of () [] or {}, or if the line ends in a \. Besides the complication of joining lines under new circumstances, all the current options have a marker that the parser knows about before it encounters the newline. With this new proposal the parser will have to walk an arbitrary number of lines ahead to determine if there are going to be new indexing operations. That won't really work at all in the REPL or any other line-fed interpreter loop. Currently you can add parentheses to get just about the same visual: (foo["bar"] ["baz"] ["eggs"] ["spam"] = 1) On Tue, May 24, 2022 at 7:44 AM Jan Costandius <jcostandius@gmail.com> wrote:

On Wed, 25 May 2022 at 01:08, Jeremiah Paige <ucodery@gmail.com> wrote:
Not for assignment, unfortunately. And you can't cheat with := either, since only simple names are permitted. I don't often need to do deep assignment like this though. Is it possible to put something into a variable? parent = foo["bar"]["baz"]["eggs"] parent["spam"] = 1 And if it still needs to go over multiple lines, parens can work on that. ChrisA

On Tue, 24 May 2022 at 15:42, Jan Costandius <jcostandius@gmail.com> wrote:
I don't think this looks particularly nice, nor do I see how it helps with PEP 8. And if the keys are very long, naming the sub-parts is perfectly viable: baz = foo["bar"]["baz"] baz["eggs"]["spam"] = 1 and backslashes, while not particularly attractive, do the job just fine: foo["bar"] \ ["baz"] \ ["eggs"] \ ["spam"] = 1 Do you have a real-world example of when this would be useful? Something that doesn't use "fake" keys like bar or baz? Paul

There are at least three existing ways to already do this. (foo["bar"] ["baz"] ["eggs"] ["spam"]) = 1 foo["bar"][ "baz"][ "eggs"][ "spam"] = 1 foo["bar"]\ ["baz"]\ ["eggs"]\ ["spam"] = 1 I think the first one is the clear winner. The difficulty with your proposal is that without the indent, it is ambiguous: foo["bar"] ["baz"] ["eggs"] ["spam"] = value The first three lines of that are legal code. Pointless, but legal. It is only when we get to the last line, the assignment, that it fails, and only because the unpacking assignment target is a literal. If it were a name, it could succeed: [spam] = value # succeeds with value = (1,) for example unpacks `value` and assigns the results to the list of names `[spam]`. So this syntax will *require* indentation to avoid the ambiguity. But that breaks the rule that indentation is only required for a block following a keyword such as class, def, for, if etc. Okay, so perhaps it is not quite a hard rule, more of a convention or expectation, but *requiring* such indentation would still violate it. So given that there are already at least three adequate solutions to the problem, I don't see the need to complicate the language to support another. -- Steve

While that formatting does look nice, this would be a huge change to the parser just to allow a new formatting style. Right now lines are only logically joined if they appear between a pair of () [] or {}, or if the line ends in a \. Besides the complication of joining lines under new circumstances, all the current options have a marker that the parser knows about before it encounters the newline. With this new proposal the parser will have to walk an arbitrary number of lines ahead to determine if there are going to be new indexing operations. That won't really work at all in the REPL or any other line-fed interpreter loop. Currently you can add parentheses to get just about the same visual: (foo["bar"] ["baz"] ["eggs"] ["spam"] = 1) On Tue, May 24, 2022 at 7:44 AM Jan Costandius <jcostandius@gmail.com> wrote:

On Wed, 25 May 2022 at 01:08, Jeremiah Paige <ucodery@gmail.com> wrote:
Not for assignment, unfortunately. And you can't cheat with := either, since only simple names are permitted. I don't often need to do deep assignment like this though. Is it possible to put something into a variable? parent = foo["bar"]["baz"]["eggs"] parent["spam"] = 1 And if it still needs to go over multiple lines, parens can work on that. ChrisA

On Tue, 24 May 2022 at 15:42, Jan Costandius <jcostandius@gmail.com> wrote:
I don't think this looks particularly nice, nor do I see how it helps with PEP 8. And if the keys are very long, naming the sub-parts is perfectly viable: baz = foo["bar"]["baz"] baz["eggs"]["spam"] = 1 and backslashes, while not particularly attractive, do the job just fine: foo["bar"] \ ["baz"] \ ["eggs"] \ ["spam"] = 1 Do you have a real-world example of when this would be useful? Something that doesn't use "fake" keys like bar or baz? Paul

There are at least three existing ways to already do this. (foo["bar"] ["baz"] ["eggs"] ["spam"]) = 1 foo["bar"][ "baz"][ "eggs"][ "spam"] = 1 foo["bar"]\ ["baz"]\ ["eggs"]\ ["spam"] = 1 I think the first one is the clear winner. The difficulty with your proposal is that without the indent, it is ambiguous: foo["bar"] ["baz"] ["eggs"] ["spam"] = value The first three lines of that are legal code. Pointless, but legal. It is only when we get to the last line, the assignment, that it fails, and only because the unpacking assignment target is a literal. If it were a name, it could succeed: [spam] = value # succeeds with value = (1,) for example unpacks `value` and assigns the results to the list of names `[spam]`. So this syntax will *require* indentation to avoid the ambiguity. But that breaks the rule that indentation is only required for a block following a keyword such as class, def, for, if etc. Okay, so perhaps it is not quite a hard rule, more of a convention or expectation, but *requiring* such indentation would still violate it. So given that there are already at least three adequate solutions to the problem, I don't see the need to complicate the language to support another. -- Steve
participants (6)
-
Benedict Verhegghe
-
Chris Angelico
-
Jan Costandius
-
Jeremiah Paige
-
Paul Moore
-
Steven D'Aprano