Skip to content

fix: ast.NameConstant missing fields #14353

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

hunterhogan
Copy link
Contributor

(.venv) C:\apps\astToolkit>py
Python 3.13.5 (tags/v3.13.5:6cb20a2, Jun 11 2025, 16:15:46) [MSC v.1943 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ast
>>> ast.Str._fields
<stdin>-1:1: DeprecationWarning: ast.Str is deprecated and will be removed in Python 3.14; use ast.Constant instead
('s',)
>>> ast.Bytes._fields
<stdin>-2:1: DeprecationWarning: ast.Bytes is deprecated and will be removed in Python 3.14; use ast.Constant instead
('s',)
>>> ast.Num._fields  
<stdin>-3:1: DeprecationWarning: ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead
('n',)
>>> ast.NameConstant._fields
<stdin>-4:1: DeprecationWarning: ast.NameConstant is deprecated and will be removed in Python 3.14; use ast.Constant instead
('value', 'kind')

Comment on lines +1714 to +1716
class NameConstant(Constant, metaclass=_ABC):
value: _ConstantValue
kind: str | None
Copy link
Member

@brianschubert brianschubert Jul 1, 2025

Choose a reason for hiding this comment

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

Hmm, I think these attributes are already inherited from Constant? Or am I missing something?

typeshed/stdlib/ast.pyi

Lines 1092 to 1096 in 3f727b0

class Constant(expr):
if sys.version_info >= (3, 10):
__match_args__ = ("value", "kind")
value: _ConstantValue
kind: str | None

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Frankly, I don't know.

Elephant

By my count, there are five (deprecated) subclasses of ast.Constant. Of the five, only NameConstant has those two "attributes". (I'm intentionally avoiding _fields.)

(.venv) C:\apps\astToolFactory>py
Python 3.13.5 (tags/v3.13.5:6cb20a2, Jun 11 2025, 16:15:46) [MSC v.1943 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ast
>>> ast.Ellipsis._fields
<stdin>-1:1: DeprecationWarning: ast.Ellipsis is deprecated and will be removed in Python 3.14; use ast.Constant instead
()

The three in the first comment above have "attributes", and their attributes are defined in ast.pyi. Similarly, ast.Ellipsis does not seem to inherit anything from ast.Constant. Those things point towards a desire to add them to the stub.

Rhino

On the other hand, I don't know where ast.NameConstant is. I mean, it's not in Python.asdl, and I haven't searched super hard, but I don't know how any of the deprecated classes come to "exist". I just looked more closely at ast.py, and it seems to be flawed, also.

class Num(Constant, metaclass=_ABC):
    _fields = ('n',)
    __new__ = _new


class Str(Constant, metaclass=_ABC):
    _fields = ('s',)
    __new__ = _new


class Bytes(Constant, metaclass=_ABC):
    _fields = ('s',)
    __new__ = _new


class NameConstant(Constant, metaclass=_ABC):
    __new__ = _new


class Ellipsis(Constant, metaclass=_ABC):
    _fields = ()

https://github.com/python/cpython/blob/1e3466a1ae5bdcee42a3dfdbd8aaa17135a6ecc2/Lib/ast.py#L605-L622

It doesn't name the fields, but the interpreter knows the fields exist.

Elephino

So, I just now did _field_types on everything, and even ast.Ellipsis seems to have inherited from ast.Constant!

>>> ast.NameConstant._field_types
<stdin>-2:1: DeprecationWarning: ast.NameConstant is deprecated and will be removed in Python 3.14; use ast.Constant instead
{'value': <class 'object'>, 'kind': str | None}
>>> ast.Constant._field_types    
{'value': <class 'object'>, 'kind': str | None}
>>> ast.Num._field_types     
<stdin>-4:1: DeprecationWarning: ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead
{'value': <class 'object'>, 'kind': str | None}
>>> ast.Str._field_types
<stdin>-5:1: DeprecationWarning: ast.Str is deprecated and will be removed in Python 3.14; use ast.Constant instead
{'value': <class 'object'>, 'kind': str | None}
>>> ast.Bytes._field_types
<stdin>-6:1: DeprecationWarning: ast.Bytes is deprecated and will be removed in Python 3.14; use ast.Constant instead
{'value': <class 'object'>, 'kind': str | None}
>>> ast.Ellipsis._field_types
{'value': <class 'object'>, 'kind': str | None}

I feel like the stub file helps to provide clarity and precision. If that is a goal, then I feel it suggests to add the "attributes" and their types.

On the other hand, I feel that the stub file should not be used to fix code that could be fixed directly.

I have a package, astToolfactory, that creates another package, astToolkit, mostly by using the ast module. I am also using the CPython asdl parser to parse "Python.asdl" and extract the match_args parameters for the classes. In astToolFactory, I was parsing "ast.pyi" with an ast.NodeVisitor I created through astToolkit, when I got an error because I expected to find type annotations for ast.NameConstant.value and ast.NameConstant.kind because for each of the ast.AST subclasses, I collected the "attribute" names from ast.class._fields. I think I am a character in "Being John Malkovich," written by Kurt Vonnegut, and adapted to cinema by Christopher Nolan. "Malkovich Malkovich ast Malkovich ast ast Malkovich Malkovich Malkovich."

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just looked more closely at ast.py, and it seems to be flawed, also.

Or, it is not flawed because the intention was to let ast.NameConstant inherit from ast.Constant but to override the inheritance in the other four subclasses. But _field_types is still messed up for those four subclasses. Malkovich Malkovich Malkovich.

Copy link
Contributor

github-actions bot commented Jul 1, 2025

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants