compiler parity for typealias by youknowone · Pull Request #7645 · RustPython/RustPython
🏁 Script executed:
#!/bin/bash # Confirm the type of StmtTypeAlias.name in ruff_python_ast and whether non-Name is reachable. rg -nP 'struct\s+StmtTypeAlias\b' -C 10 rg -nP '\bTypeAlias\s*\{' -C 5 --type=rust
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
#!/bin/bash # Search for StmtTypeAlias definition with broader patterns fd -i typealias -t f --type rust | head -20 rg -l 'StmtTypeAlias' --type=rust
Repository: RustPython/RustPython
Length of output: 391
🏁 Script executed:
#!/bin/bash # Look in the symboltable.rs file itself for context around the error cat -n crates/codegen/src/symboltable.rs | sed -n '1760,1790p'
Repository: RustPython/RustPython
Length of output: 1649
🏁 Script executed:
#!/bin/bash # Search for the as_name_expr method to understand what it does rg -B 3 -A 3 'fn as_name_expr' --type=rust
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
#!/bin/bash # Search for StmtTypeAlias struct definition rg 'struct StmtTypeAlias' -A 10
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
#!/bin/bash # Search for as_name_expr method implementation in the Expr type rg 'as_name_expr' -B 2 -A 5
Repository: RustPython/RustPython
Length of output: 1268
🏁 Script executed:
#!/bin/bash # Look for the definition of Expr type and Name variant rg 'pub enum Expr' -A 50 | head -100
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
#!/bin/bash # Search for StmtTypeAlias in the AST files rg 'StmtTypeAlias' crates/vm/src/stdlib/_ast/ -A 8
Repository: RustPython/RustPython
Length of output: 3722
🏁 Script executed:
#!/bin/bash # Look for the Expr enum definition rg -l 'pub enum Expr' crates/
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
#!/bin/bash # Search for as_name_expr implementation more broadly rg 'as_name_expr' --type-list | head -5 find crates/ -name '*.rs' -exec grep -l 'as_name_expr' {} \;
Repository: RustPython/RustPython
Length of output: 535
🏁 Script executed:
#!/bin/bash # Look for the Expr enum or struct in parser crates find crates/ -name '*.rs' | xargs grep -l 'enum Expr' | head -5
Repository: RustPython/RustPython
Length of output: 98
🏁 Script executed:
#!/bin/bash # Search for the actual Rust ast module definition of StmtTypeAlias rg 'pub struct StmtTypeAlias' -A 5
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
#!/bin/bash # Search more broadly for TypeAlias struct rg 'struct.*TypeAlias' -B 2 -A 8 | head -60
Repository: RustPython/RustPython
Length of output: 2337
🏁 Script executed:
#!/bin/bash # Look for impl blocks with as_name_expr rg 'impl.*Expr' -A 30 | grep -A 30 'as_name_expr'
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
#!/bin/bash # Find files that define StmtTypeAlias (the Rust struct, not Python wrapper) find crates/ -name '*.rs' -exec grep -l 'ast::StmtTypeAlias' {} \;
Repository: RustPython/RustPython
Length of output: 133
🏁 Script executed:
#!/bin/bash # Look in the ast module definition find crates/ -path '*/ast/*.rs' -o -path '*/ast.rs' | head -20
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
#!/bin/bash # Search for where StmtTypeAlias struct is defined with name field rg 'StmtTypeAlias.*{' -B 2 -A 15 | head -80
Repository: RustPython/RustPython
Length of output: 160
🏁 Script executed:
#!/bin/bash # Check crates directory structure ls -la crates/ | grep -E 'parser|ast'
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
#!/bin/bash # Look at imports in symboltable.rs to find where ast types come from head -50 crates/codegen/src/symboltable.rs | grep -E 'use|import'
Repository: RustPython/RustPython
Length of output: 341
🏁 Script executed:
#!/bin/bash # Look for where the ast module is imported rg 'use.*ast' crates/codegen/src/symboltable.rs | head -10
Repository: RustPython/RustPython
Length of output: 161
🏁 Script executed:
#!/bin/bash # Find all ast modules find crates/ -name 'lib.rs' -o -name 'mod.rs' | xargs grep -l 'StmtTypeAlias' 2>/dev/null
Repository: RustPython/RustPython
Length of output: 49
🏁 Script executed:
#!/bin/bash # Check if there's a ruff dependency rg 'ruff' crates/codegen/Cargo.toml
Repository: RustPython/RustPython
Length of output: 183
🏁 Script executed:
#!/bin/bash # Check if ruff_python_ast is available in the workspace or external grep -r 'ruff_python_ast' crates/codegen/Cargo.toml cat crates/codegen/Cargo.toml | grep -A 5 -B 5 'ruff'
Repository: RustPython/RustPython
Length of output: 679
🏁 Script executed:
#!/bin/bash # Look at Cargo.lock or workspace definition for ruff version find . -name 'Cargo.lock' -o -name 'workspace.toml' | head -3
Repository: RustPython/RustPython
Length of output: 77
🌐 Web query:
ruff_python_ast StmtTypeAlias name field type
💡 Result:
In the ruff_python_ast crate, StmtTypeAlias (corresponding to Python's PEP 695 type statement) is a struct with the following fields: pub struct StmtTypeAlias { range: TextRange, node_index: AtomicNodeIndex, name: Expr, // The name of the type alias (typically an ExprName) type_params: Option<Box>, value: Expr, // The type expression assigned to the alias } The name field is an Expr (usually ExprName for simple identifiers), not a direct string or Identifier type. This matches the ast.toml definition used to generate the Rust AST models.
Citations:
- 1: https://github.com/astral-sh/ruff/blob/main/crates/ruff_python_ast/ast.toml
- 2: https://github.com/astral-sh/ruff/blob/main/crates/ruff_python_ast/src/generated.rs
- 3: https://github.com/astral-sh/ruff/blob/56eb6b62/crates/ruff_python_ast/src/helpers.rs
🏁 Script executed:
#!/bin/bash # Now search for as_name_expr implementation in ruff-related code or in RustPython rg 'as_name_expr' -B 3 -A 10
Repository: RustPython/RustPython
Length of output: 2178
🌐 Web query:
ruff as_name_expr Expr method implementation
💡 Result:
In Ruff's ruff_python_ast crate, Expr is an enum representing Python expressions. The as_name_expr method is a helper function (likely defined via a trait or extension) that pattern-matches an Expr to check if it is an Expr::Name variant and returns Option<&ExprName> if true, allowing safe downcasting to access the name identifier (id: &Name). This pattern is used extensively in Ruff's linter rules for semantic analysis, such as: - Checking if call arguments or attribute values are simple names (e.g., in PERF rules for list comprehensions: value.as_name_expr). - Resolving identifiers in type checking and binding analysis (e.g., func.as_name_expr in rule checks). - Validating targets in named expressions (walrus operator :=, Expr::Named). Example usage from source: let Some(list_name) = value.as_name_expr else { return; }; If value is Expr::Name(ExprName { id, .. }), it extracts the ExprName; otherwise, None. The method follows Rust's pattern-matching idiom for AST node visitors, similar to as_name, as_call, etc. No official documentation found, but implementation is in crates/ruff_python_ast, used across ruff_linter rules.
Citations:
- 1: https://github.com/astral-sh/ruff/blob/main/crates%2Fruff_linter%2Fsrc%2Frules%2Fperflint%2Frules%2Fmanual_list_comprehension.rs
- 2: https://github.com/astral-sh/ruff/blob/main/crates%2Fruff_linter%2Fsrc%2Frules%2Fpyupgrade%2Frules%2Fconvert_typed_dict_functional_to_class.rs
- 3: https://github.com/astral-sh/ruff/blob/main/crates%2Fruff_linter%2Fsrc%2Frules%2Fpylint%2Frules%2Fnamed_expr_without_context.rs
- 4: https://github.com/astral-sh/ruff/blob/56eb6b62/crates/ruff_python_ast/src/helpers.rs
- 5: https://github.com/astral-sh/ruff/blob/56eb6b62/crates/ruff_linter/src/checkers/ast/analyze/expression.rs
- 6: https://github.com/astral-sh/ruff/blob/56eb6b62/crates/ruff_python_ast/src/nodes.rs
🏁 Script executed:
#!/bin/bash # Search for test cases related to TypeAlias error handling rg 'type alias' -i crates/ | grep -i 'test\|error' | head -20
Repository: RustPython/RustPython
Length of output: 292
🏁 Script executed:
#!/bin/bash # Look for how other syntax errors are phrased in the codebase rg 'error.*expect' -i crates/codegen/src/ | head -10
Repository: RustPython/RustPython
Length of output: 278
🏁 Script executed:
#!/bin/bash # Check if there are tests for invalid TypeAlias syntax find crates/ -name '*.py' -o -name '*.rs' | xargs grep -l 'type.*=' | grep test
Repository: RustPython/RustPython
Length of output: 125
🌐 Web query:
Python PEP 695 type alias syntax error message name must be identifier
💡 Result:
The error message "name must be identifier" in Python PEP 695 type alias syntax occurs when the name after the type keyword is not a valid Python identifier. According to PEP 695, the syntax is type NAME = expression, where NAME must follow Python's identifier rules: it must start with a letter (a-z, A-Z) or underscore (_), followed by letters, digits (0-9), or underscores. Invalid characters (e.g., numbers at start, special chars like -, $, @) or keywords trigger a SyntaxError with this message during parsing. Examples: - Valid: type MyAlias = list[int] - Invalid: type 1alias = int (starts with digit) → SyntaxError: name must be identifier - Invalid: type my-alias = str (contains '-') → SyntaxError: invalid character in identifier or similar, but parser expects NAME token. This is enforced by the grammar rule type_alias: "type" n=NAME t=[type_params] '=' b=expression in PEP 695. Python's lexer defines identifiers strictly (docs.python.org/3/reference/lexical_analysis.html#identifiers), and the PEG parser raises precise SyntaxErrors for violations in type statements (Python 3.12+). To fix: Use a valid identifier name (e.g., capitalize like MyType, avoid reserved words/special chars).
Citations:
- 1: https://peps.python.org/pep-0695/
- 2: https://typing.python.org/en/latest/spec/aliases.html
- 3: https://docs.python.org/3/reference/lexical_analysis.html
- 4: https://jellezijlstra.github.io/pep695.html
- 5: misleading SyntaxError (f-string and type alias related) python/cpython#109114
Fix grammatically incorrect error message.
"type alias expect name" is grammatically incorrect. It should be "type alias expects name" or restructured as "type alias must be a Name node".
The error path is reachable when the parser produces non-Name expressions during error recovery or for malformed input. Adding a unit test for this path would be beneficial.