Skip to content
This repository has been archived by the owner on Jul 27, 2023. It is now read-only.

Merge upstream changes for PEP695 support (rebase) #25

Closed
wants to merge 29 commits into from

Conversation

zanieb
Copy link
Member

@zanieb zanieb commented Jul 17, 2023

Performed with the nightmarish git rebase upstream/main --rebase-merges

zanieb and others added 29 commits July 10, 2023 13:15
Update to the latest ASDL
* Parse type parameters in function definitions
* Add test for combined items
…hon#97)

Extends RustPython#95
Closes RustPython#82 

Adds parsing of new `type` soft keyword for defining type aliases.

Supports type alias statements as defined in PEP 695 e.g. 

```python
# A non-generic type alias
type IntOrStr = int | str

# A generic type alias
type ListOrSet[T] = list[T] | set[T]

# A type alias that includes a forward reference
type AnimalOrVegetable = Animal | "Vegetable"

# A generic self-referential type alias
type RecursiveList[T] = T | list[RecursiveList[T]]
```

All type parameter kinds are supported as in RustPython#95.

Builds on soft keyword abstractions introduced in RustPython/RustPython#4519
# Conflicts:
#	parser/src/parser.rs
#	parser/src/python.rs
#	parser/src/snapshots/rustpython_parser__parser__tests__decorator_ranges.snap
This PR adds `TextRange` to `Identifier`. Right now, the AST only
includes ranges for identifiers in certain cases (`Expr::Name`,
`Keyword`, etc.), namely when the identifier comprises an entire AST
node. In Ruff, we do additional ad-hoc lexing to extract identifiers
from source code.

One frequent example: given a function `def f(): ...`, we lex to find
the range of `f`, for use in diagnostics.

Another: `except ValueError as e`, for which the AST doesn't include a
range for `e`.

Note that, as an optimization, we avoid storing the `TextRange` for
`Expr::Name`, since it's already included.
In the example below, `arg` is `&Expr`, so `&Ranged`, but `entries()`
want a `T: Ranged`. This adds the missing bridge impl.

```rust
        let all_args = format_with(|f| {
            f.join_comma_separated()
                .entries(
                    // We have the parentheses from the call so the arguments never need any
                    args.iter()
                        .map(|arg| (arg, arg.format().with_options(Parenthesize::Never))),
                )
                .nodes(keywords.iter())
                .finish()
        });
```
This adds the missing implementation of `Ranged` for `TextRange` itself

```rust
impl Ranged for TextRange {
    fn range(&self) -> TextRange {
        *self
    }
}
```

This allows e.g. using `has_comments` with arbitrary ranges instead of
just a node.

It also adds .venv to the .gitignore
This removes the ASDL code generation in favor of handwriting the AST.

The motivations for moving away from the ASDL are:

* CPython compatibility is no longer a goal
* The ASDL grammar isn't as expressive as we would like
* The codegen scripts have a high complexity which makes extensions time
consuming
* We don't make heavy use of code generation (compared to e.g.
RustPython that generates Pyo3 bindings, a fold implementation etc).

We may want to revisit a grammar based code generation in the future,
e.g. by using [ungrammar](https://github.com/rust-analyzer/ungrammar)
@zanieb zanieb changed the title Merge upstream changes for PEP695 support Merge upstream changes for PEP695 support (rebase) Jul 17, 2023
@zanieb
Copy link
Member Author

zanieb commented Jul 17, 2023

Favoring #27

@zanieb zanieb closed this Jul 17, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants