Oddity in AST for 3-argument slices

I've discovered a slightly surprising thing about the way AST objects for slices are constructed. According to Python.asdl, all three parts of a slice are optional: slice = Slice(expr? lower, expr? upper, expr? step) But that's not quite the way the parser sees things: Python 3.1.2 (r312:79147, Aug 19 2010, 20:26:20) [GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin Type "help", "copyright", "credits" or "license" for more information.
import ast t = ast.parse("x[::]", mode='eval') ast.dump(t) "Expression(body=Subscript(value=Name(id='x', ctx=Load()), slice=Slice(lower=None, upper=None, step=Name(id='None', ctx=Load())), ctx=Load()))"
In other words, x[::] is being parsed as though it had been written x[::None] Is there a good reason for an omitted third slice argument being treated differently from the others? -- Greg

On Thu, Aug 19, 2010 at 6:36 PM, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
In other words,
x[::]
is being parsed as though it had been written
x[::None]
Is there a good reason for an omitted third slice argument being treated differently from the others?
Probably so it looks different from the AST for x[:]
ast.dump(ast.parse("x[:]", mode='eval')) "Expression(body=Subscript(value=Name(id='x', ctx=Load()), slice=Slice(lower=None, upper=None, step=None), ctx=Load()))" ast.dump(ast.parse("x[::]", mode='eval')) "Expression(body=Subscript(value=Name(id='x', ctx=Load()), slice=Slice(lower=None, upper=None, step=Name(id='None', ctx=Load())), ctx=Load()))"
Or else it's just an accident of implementation, since the AST doesn't actually *need* to distinguish those two cases. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

Nick Coghlan wrote:
Or else it's just an accident of implementation, since the AST doesn't actually *need* to distinguish those two cases.
It doesn't seem to be an accident, because ast_for_slice() goes out of its way to manufacture a Name node for the missing argument. It doesn't seem to significantly simplify the compiler either, because compiler_slice() could just as easily treat it the same way as the other slice arguments and emit an instruction to load None if it's missing. So it's a mystery. Perhaps it made life easier for some earlier version of the compiler. -- Greg

On Thu, Aug 19, 2010 at 8:35 PM, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Nick Coghlan wrote:
Or else it's just an accident of implementation, since the AST doesn't actually *need* to distinguish those two cases.
It doesn't seem to be an accident, because ast_for_slice() goes out of its way to manufacture a Name node for the missing argument.
It doesn't seem to significantly simplify the compiler either, because compiler_slice() could just as easily treat it the same way as the other slice arguments and emit an instruction to load None if it's missing.
So it's a mystery. Perhaps it made life easier for some earlier version of the compiler.
Ah, it's a 2.x-ism. The old compiler needed to know whether or not to try __get/set/delslice__ (yes for x[:], no for x[::]). With those magic methods gone, that would make it obsolete in 3.x, so x[::] should probably just be changed to generate the same AST as x[:] now. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
participants (2)
-
Greg Ewing
-
Nick Coghlan