Conversation
Eight of the types generated from ``Parser/Python.asdl`` carry the ``lineno``/``col_offset``/``end_lineno``/``end_col_offset`` attributes -- ``stmt``, ``expr``, ``excepthandler``, ``arg``, ``keyword``, ``alias``, ``pattern`` and ``type_param`` -- but the documentation named only ``ast.expr`` and ``ast.stmt``. The same block also stated that the end positions are always optional. That holds for the six types that declare them as ``int?`` in the grammar; ``pattern`` and ``type_param`` declare them as ``int``, and compiling a tree whose ``pattern`` or ``type_param`` node is missing ``end_lineno`` raises ``TypeError``. The first paragraph follows the wording approved in pythonGH-136868 and the two review suggestions on it, except that it keeps the original "Instances of": the classes themselves expose nothing, so ``hasattr(ast.Name, 'lineno')`` is false. The cross-reference uses ``:ref:``, matching the rest of the file.
Documentation build overview
14 files changed ·
|
| end_col_offset | ||
|
|
||
| Instances of :class:`ast.expr` and :class:`ast.stmt` subclasses have | ||
| Instances of most classes in the :mod:`!ast` module have the |
There was a problem hiding this comment.
This does not help more. Even if other classes MAY have attributes, the current wording is still not wrong. I find the "most have the attributes" still useless because it does not tell me which ones really have it and I would still need hasattr checks in general.
|
|
||
| Note that the end positions are not required by the compiler and are | ||
| therefore optional. The end offset is *after* the last symbol, for example | ||
| therefore optional, except for :class:`ast.pattern` and |
There was a problem hiding this comment.
I do not like this much because this makes the implementation very CPython specific. I wonder why those nodes actually need them in the first place.
|
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
Review asked for two things the previous wording did not give. "Most classes have the attributes" does not tell a reader which ones, so a hasattr check is still needed. The eight classes are now named. The set is exact: of the 126 ast.AST subclasses the module exports, the 77 that carry lineno are precisely the subclasses of those eight, with no exceptions in either direction. The end-position clause no longer asserts a compiler rule. The abstract grammar reproduced on the same page already declares them int? for six classes and int for pattern and type_param, so the text points at that instead. The reason those two differ is historical rather than semantic: end positions arrived in 3.8 and the older classes had to keep accepting nodes built without them, while pattern (3.10) and type_param (3.12) had no such callers to support.
|
Both taken, and the second one sent me to the record rather than to the prose. "which ones really have it"Fair — "most classes" leaves you exactly where you started. The eight are now named, and the claim is that nothing else has them, so no >>> EIGHT = (ast.stmt, ast.expr, ast.excepthandler, ast.arg,
... ast.keyword, ast.alias, ast.pattern, ast.type_param)
>>> allsub = [c for c in vars(ast).values()
... if isinstance(c, type) and issubclass(c, ast.AST)]
>>> has = {c for c in allsub if 'lineno' in c._attributes}
>>> under = {c for c in allsub if issubclass(c, EIGHT)}
>>> len(has), has == under
(77, True)77 of the 126 exported subclasses, and the two sets coincide with nothing extra on either side. Those eight are also precisely the types with an "very CPython specific" — and why those nodes need themYou are right that "the compiler requires them" documents an internal rule, so that clause is gone. The text now points at something the reader already has on the page: the On why those two differ — it is historical, not semantic, and it was a deliberate decision. End positions arrived in 3.8 (#11605). The classes that predate them had to keep accepting nodes constructed by code written before 3.8, so the fields stayed optional.
So the optionality is a backwards-compatibility artefact of 3.8, and the old sentence presented it as a design rule with no exceptions. One clause naming the split, and the reason, seemed more useful than dropping it and leaving the grammar block to be noticed.
|
|
Please do not post LLM answers. We value human contributions, not ones simply prompted so take the time to edit answers and remove superfluous and annoying AI expressions. As for the updated text, is there a need to name all subclasses then? and I would rather say that classes added after Python 3.8 are expected to have the end positions. And having regression test for that ruke may be relevant as well. |
Review preferred the rule over the two exceptions: the classes that existed when end positions arrived in 3.8 keep them optional so that pre-3.8 code can still build those nodes, and anything added later requires them. test_asdl_parser checks that rule against Python.asdl, so a type added with int? end positions fails instead of being noticed years later, as type_param was in pythongh-106145.
|
Sorry about the tone of that — you're right, and I've cut it out. Rule instead of the two exceptions, as you suggested: the classes that already existed when end positions arrived in 3.8 keep them optional so pre-3.8 code can still build those nodes, and anything added later requires them. The grammar says which is which, so the text just points there. I added the regression test to test_asdl_parser, which already parses Python.asdl. It walks every type with an attributes clause and requires int rather than int? unless the type is one of the six that predate 3.8. Flipping pattern back to int? fails it with "pattern postdates the 3.8 addition of end positions", which is what would have caught type_param in gh-106145. On naming the eight classes — I kept that because your first comment was that "most classes" still leaves you reaching for hasattr, and the list makes the answer exact: those eight and their subclasses are 77 of the 126 AST classes the module exports, and nothing outside them has the attributes. Happy to drop it back to a pointer at the grammar if you'd rather; it's one sentence either way. |
Two sentences in the
ast.ASTblock ofDoc/library/ast.rstsay things that are not true."Instances of
ast.exprandast.stmtsubclasses have lineno, col_offset, end_lineno, and end_col_offset attributes." Eight types carry anattributes (...)clause inParser/Python.asdl, not two:stmt,expr,excepthandler,arg,keyword,alias,pattern,type_param. So anExceptHandler, analiasor akeywordhas full position information while the docs say it should not:"the end positions are not required by the compiler and are therefore optional." True for six of those eight.
patternandtype_paramdeclareint end_lineno, int end_col_offsetrather thanint?(Python.asdllines 146 and 153), and the compiler enforces it:The same deletion on a
stmtnode compiles fine.The wording
The first paragraph is the wording @AA-Turner approved on #136868, with the two inline
suggestionblocks from that review applied — they were never committed before the author stopped working on it and the PR was closed. I took them verbatim from the review rather than paraphrasing:I checked "most" rather than trusting it: 77 of the 126
ast.ASTsubclasses exported by the module carrylineno, so it holds.The second paragraph is the part #136868 did not address. It is one clause naming the two exceptions.
The
:ref:above `` link uses the same target and the same phrasing the file already uses forty lines earlier, so nothing new is introduced.Scope
Doc/library/ast.rstonly — 7 insertions, 3 deletions, one file. No code, no ASDL, no test, no behaviour change, so no news entry;skip newsapplies the way it did on #136868, which was approved with this same single file and nothing else.Verified on a build of
main(3.16.0a0), not on a released interpreter.ast.ASTlocation attributes #136640