Skip to content

ast.MatchStar.name incorrectly has class-level default value #134674

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

Closed
hunterhogan opened this issue May 25, 2025 · 4 comments
Closed

ast.MatchStar.name incorrectly has class-level default value #134674

hunterhogan opened this issue May 25, 2025 · 4 comments
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-parser type-bug An unexpected behavior, bug, or error

Comments

@hunterhogan
Copy link
Contributor

hunterhogan commented May 25, 2025

Bug report

Bug description:

I apologize for my ignorance of most technical terms and the awkward explanation that flows from it.

Minimal, reproducible example

import ast
print(ast.dump(MatchStar(name=None)))

# Output
MatchStar()

But, is that really a problem?

(.venv) C:\clones\cpython>mypy -c "import ast; print(ast.dump(ast.MatchStar(name=None)))"
Success: no issues found in 1 source file

(.venv) C:\clones\cpython>mypy -c "import ast; print(ast.dump(ast.MatchStar()))"
<string>:1: error: Missing positional argument "name" in call to "MatchStar"  [call-arg]
Found 1 error in 1 file (checked 1 source file)

Ok, but is it a bug?

I'm assuming that design goals include one or more of the following:

  • ast.dump() produces code that does not generate errors.
  • Similar classes should behave similarly.

(Nevertheless, I am confident there are factors about which I am ignorant.)

Therefore, I compared ast.MatchStar to ast.Constant and ast.MatchSingleton:

# MatchStar.py
from ast import Constant, MatchSingleton, MatchStar
import ast

nodeConstructors: list[str] = [
    "ast.Constant(value=None, kind=None)",
    "ast.MatchSingleton(value=None)",
    "ast.MatchStar(name=None)",
]

for nodeAsStr in nodeConstructors:
    print(nodeAsStr, ast.dump(eval(nodeAsStr)), "", sep="\n")

# Output:
ast.Constant(value=None, kind=None)
Constant(value=None)

ast.MatchSingleton(value=None)
MatchSingleton(value=None)

ast.MatchStar(name=None)
MatchStar()

Ask mypy to lint the file above, including the output statements:

(.venv) C:\clones\cpython>mypy MatchStar.py
MatchStar.py:22: error: Missing positional argument "name" in call to "MatchStar"  [call-arg]
Found 1 error in 1 file (checked 1 source file)

Proposed changes

From

| MatchStar(identifier? name)

To

            | MatchStar(identifier name)

From

cpython/Lib/ast.py

Lines 154 to 162 in f331d03

if (
not show_empty
and (value is None or value == [])
# Special cases:
# `Constant(value=None)` and `MatchSingleton(value=None)`
and not isinstance(node, (Constant, MatchSingleton))
):
args_buffer.append(repr(value))
continue

To

                if (
                    not show_empty
                    and (value is None or value == [])
                    # Special cases:
                    # `Constant(value=None)` and `MatchSingleton(value=None)` and `MatchStar(name=None)`
                    and not isinstance(node, (Constant, MatchSingleton, MatchStar))
                ):
                    args_buffer.append(repr(value))
                    continue

Changes tested in 3.13.3+ build

After compiling with the above changes, compare:

(.venv) C:\clones\cpython>PCbuild\amd64\python_d.exe -V && PCbuild\amd64\python_d.exe -c "import ast; print(ast.dump(ast.MatchStar(name=None)))"
Python 3.13.3+
MatchStar(name=None)

(.venv) C:\clones\cpython>py -V && py -c "import ast; print(ast.dump(ast.MatchStar(name=None)))"                        
Python 3.13.3
MatchStar()

Appendix: output from Python versions 3.9 to 3.12, and CPython main branch

(.venv) C:\clones\cpython>py -3.9 -V && py -3.9 -c "import ast; print(ast.dump(ast.MatchStar(name=None)))"              
Python 3.9.13
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AttributeError: module 'ast' has no attribute 'MatchStar'

(.venv) C:\clones\cpython>py -3.10 -V && py -3.10 -c "import ast; print(ast.dump(ast.MatchStar(name=None)))" 
Python 3.10.11
MatchStar()

(.venv) C:\clones\cpython>py -3.11 -V && py -3.11 -c "import ast; print(ast.dump(ast.MatchStar(name=None)))" 
Python 3.11.9
MatchStar()

(.venv) C:\clones\cpython>py -3.12 -V && py -3.12 -c "import ast; print(ast.dump(ast.MatchStar(name=None)))" 
Python 3.12.10
MatchStar()

(.venv) c:\clones\cpython>PCbuild\amd64\python_d.exe -V && PCbuild\amd64\python_d.exe -c "import ast; print(ast.dump(ast.MatchStar(name=None)))"
Python 3.15.0a0
MatchStar()

CPython versions tested on:

3.13, 3.9, 3.10, 3.11, 3.12, CPython main branch

Operating systems tested on:

Windows

Linked PRs

@bedevere-app
Copy link

bedevere-app bot commented May 25, 2025

GH-134681 is a backport of this pull request to the 3.13 branch.

@serhiy-storchaka
Copy link
Member

identifier can only be a string. MatchStar(None) is invalid if you change the declaration to MatchStar(identifier name).

@serhiy-storchaka
Copy link
Member

It looks to me that this is a MyPy issue.

@JelleZijlstra
Copy link
Member

I think MatchStar is behaving correctly here. ast.MatchStar(name=None) is different from ast.MatchSingleton(value=None) because in the former case the None indicates the absence of value (it corresponds to *_ in a sequence pattern); in the latter case the None indicates a value that is specifically None.

However, reading this did lead me to a real opportunity for improvement: #134718.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-parser type-bug An unexpected behavior, bug, or error
Projects
None yet
4 participants