Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-34822: Simplify AST for subscription. #9605

Merged
merged 19 commits into from
Mar 10, 2020

Conversation

serhiy-storchaka
Copy link
Member

@serhiy-storchaka serhiy-storchaka commented Sep 27, 2018

  • Remove the slice type.
  • Make Slice a kind of the expr type instead of the slice type.
  • Replace ExtSlice(slices) with Tuple(slices, Load()).
  • Replace Index(value) with a value itself.

All non-terminal nodes in AST for expressions will be now of the expr type.

https://bugs.python.org/issue34822

* Remove the slice type.
* Make Slice a kind of the expr type instead of the slice type.
* Replace ExtSlice(slices) with Tuple(slices, Load()).
* Replace Index(value) with a value itself.

All non-terminal nodes in AST for expressions will be now of the expr type.
@thautwarm
Copy link
Contributor

thautwarm commented Sep 28, 2018

This enhancement is quite exciting, in fact, I've found the same problem at the midnight of yesterday, and it looks like a surprise to me that you made this PR now.

I'm working at an implementation of ast.parse through pure Python, and I found builtin ast.parse generates ast.ExtSlice instead of a composition of ast.Slice and ast.Tuple, which might produce inconsistency about ast structures.

However, for many projects depends on current AST structures, the changes might cause lots of incompatibilities. For instance, Hy project uses ExtSlice, and PonyORM, which uses Python ast to build SQL queries and related stuffs, and if they have used visit_Index or visit_ExtSlice, things would go bad.

AFAICS, we could add some facilities to ast module to guarantee compatibility to avoid the breakage of some 3-party packages that take advantage of python ast.

@serhiy-storchaka
Copy link
Member Author

Hy project currently doesn't use ExtSlice and doesn't properly support extended slices (hylang/hy#1492). Seems merging this PR will make Hy automatically supporting extended slices.

PonyORM doesn't use Indox and ExtSlice.

Any project that just creates AST using functional style (Index(value=...) and ExtSlice(dims=...)) will continue to work (at least in few future releases). These names will be completely removed after they will grow out of use.

Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG, except for some wording nits.

(I say this even though merging this will complicate the PEG parser integration, because that currently can only be tested with Python 3.8.)


Old classes :class:`ast.Index` and :class:`ast.ExtSlice` are still
available, but they will be removed in future Python releases.
In the meanwhile, instantiating them will return an instance of
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I Googled this expression, and there seems to be a preference for either "In the meantime" or "Meanwhile" over "In the meantime". Up to you though, it's not wrong.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

ctx=Load()))


.. class:: Slice(lower, upper, step)

Regular slicing (on the form x:y).
Regular slicing (on the form ``lower:upper`` or ``lower:upper:step``).
Can occur only in the *slice* field of :class:`Subscript`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe clarify that it can occur inside a Tuple that's directly inside a Subscript's slice field?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done (not sure about correctness of my wording).

Lib/ast.py Outdated
@@ -557,6 +558,15 @@ def __new__(cls, *args, **kwargs):
type(...): 'Ellipsis',
}

class Index(AST):
def __new__(cls, value, *args, **kwargs):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there ever any additional positional args? (I presume kwargs could be lineno etc.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No!

Lib/ast.py Outdated
return value

class ExtSlice(AST):
def __new__(cls, dims=(), *args, **kwargs):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not make dims a mandatory argument, like value for Index?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Index without value cannot work. This change breaks the following code

node = Index()
node.value = Constant(1)

but we cannot keep it working. We should have something to return from Index().

On other side, ExtSlice with empty dims is invalid, and the following legal code

node = ExtSlice()
node.dims.append(Ellipsis())

will be broken because Tuple has the elts filed instead of dims. We can add an alias dims in Tuple to make the above example working. Should we? If not, than making dims a required parameter will not break anything that is not broken.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P.S. There is a test (test_field_attr_existence) which tests that all node classes are callable without arguments (Index is an exception now). Should we make ExtSlice an exception too?

Lib/ast.py Outdated
Comment on lines 1264 to 1280
if (isinstance(node.slice, Index)
and isinstance(node.slice.value, Tuple)
and node.slice.value.elts):
if len(node.slice.value.elts) == 1:
elt = node.slice.value.elts[0]
if isinstance(node.slice, Tuple) and node.slice.elts:
if len(node.slice.elts) == 1:
elt = node.slice.elts[0]
self.traverse(elt)
self.write(",")
else:
self.interleave(lambda: self.write(", "), self.traverse, node.slice.value.elts)
self.interleave(lambda: self.write(", "), self.traverse, node.slice.elts)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing you'll get a merge conflict here if GH-17892 is merged first (which I think it should be).

Comment on lines 1 to 5
Simplified AST for subscription. Simple indices will be represented by their
value, extended slices will be represented as tuples. :mod:`ast` classes
``Index`` and ``ExtSlice`` are considered deprecated and will be removed in
future Python versions. In meanwhile, ``Index(value)`` will return a ``value``
itself, ``ExtSlice(slices)`` will return ``Tuple(slices, Load())``.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe replace "will be" with "are now"? Also change "will return" into "now returns". (But "will be removed" must stay, since it is truly in the future.)

Doc/whatsnew/3.9.rst Outdated Show resolved Hide resolved
Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM now. Go ahead!

Copy link
Member

@isidentical isidentical left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great.

@serhiy-storchaka serhiy-storchaka merged commit 13d52c2 into python:master Mar 10, 2020
@serhiy-storchaka serhiy-storchaka deleted the ast-slice branch March 10, 2020 16:52
@serhiy-storchaka
Copy link
Member Author

Thank you for your review @gvanrossum!

@gvanrossum
Copy link
Member

You're welcome. Thanks for caring so much about Python.

gvanrossum added a commit to python/mypy that referenced this pull request Apr 23, 2020
The structure of the AST for subscripts was changed in
python/cpython#9605

Fixes #8627
gvanrossum added a commit to python/mypy that referenced this pull request Apr 25, 2020
The structure of the AST for subscripts was changed in python/cpython#9605.

This also fixes some systemic issues with the tests under Python 3.9, but not all.

Fixes #8627
colesbury referenced this pull request in colesbury/nogil Oct 6, 2021
* Remove the slice type.
* Make Slice a kind of the expr type instead of the slice type.
* Replace ExtSlice(slices) with Tuple(slices, Load()).
* Replace Index(value) with a value itself.

All non-terminal nodes in AST for expressions are now of the expr type.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-feature A feature request or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants