Commit Graph

128 Commits

Author SHA1 Message Date
Charlie Marsh c74ef77e85
Move binding accesses into `SemanticModel` method (#5084) 2023-06-14 14:07:46 +00:00
Charlie Marsh 1e497162d1
Add a dedicated read result for unbound locals (#5083)
## Summary

Small follow-up to #4888 to add a dedicated `ResolvedRead` case for
unbound locals, mostly for clarity and documentation purposes (no
behavior changes).

## Test Plan

`cargo test`
2023-06-14 09:58:48 -04:00
Charlie Marsh aa41ffcfde
Add `BindingKind` variants to represent deleted bindings (#5071)
## Summary

Our current mechanism for handling deletions (e.g., `del x`) is to
remove the symbol from the scope's `bindings` table. This "does the
right thing", in that if we then reference a deleted symbol, we're able
to determine that it's unbound -- but it causes a variety of problems,
mostly in that it makes certain bindings and references unreachable
after-the-fact.

Consider:

```python
x = 1
print(x)
del x
```

If we analyze this code _after_ running the semantic model over the AST,
we'll have no way of knowing that `x` was ever introduced in the scope,
much less that it was bound to a value, read, and then deleted --
because we effectively erased `x` from the model entirely when we hit
the deletion.

In practice, this will make it impossible for us to support local symbol
renames. It also means that certain rules that we want to move out of
the model-building phase and into the "check dead scopes" phase wouldn't
work today, since we'll have lost important information about the source
code.

This PR introduces two new `BindingKind` variants to model deletions:

- `BindingKind::Deletion`, which represents `x = 1; del x`.
- `BindingKind::UnboundException`, which represents:

```python
try:
  1 / 0
except Exception as e:
  pass
```

In the latter case, `e` gets unbound after the exception handler
(assuming it's triggered), so we want to handle it similarly to a
deletion.

The main challenge here is auditing all of our existing `Binding` and
`Scope` usages to understand whether they need to accommodate deletions
or otherwise behave differently. If you look one commit back on this
branch, you'll see that the code is littered with `NOTE(charlie)`
comments that describe the reasoning behind changing (or not) each of
those call sites. I've also augmented our test suite in preparation for
this change over a few prior PRs.

### Alternatives

As an alternative, I considered introducing a flag to `BindingFlags`,
like `BindingFlags::UNBOUND`, and setting that at the appropriate time.

This turned out to be a much more difficult change, because we tend to
match on `BindingKind` all over the place (e.g., we have a bunch of code
blocks that only run when a `BindingKind` is
`BindingKind::Importation`). As a result, introducing these new
`BindingKind` variants requires only a few changes at the client sites.
Adding a flag would've required a much wider-reaching change.
2023-06-14 09:27:24 -04:00
Charlie Marsh 1895011ac2
Document some attributes on the semantic model (#5064) 2023-06-13 20:45:24 +00:00
Charlie Marsh 364bd82aee
Don't treat annotations as resolved in forward references (#5060)
## Summary

This behavior dates back to a Pyflakes commit (5fc37cbd), which was used
to allow this test to pass:

```py
from __future__ import annotations
T: object
def f(t: T): pass
def g(t: 'T'): pass
```

But, I think this is an error. Mypy and Pyright don't accept it -- you
can only use variables as type annotations if they're type aliases
(i.e., annotated with `TypeAlias`), in which case, there has to be an
assignment on the right-hand side (see: [PEP
613](https://peps.python.org/pep-0613/)).
2023-06-13 14:47:29 -04:00
Charlie Marsh 19f972a305
Use `Scope#has` in lieu of `Scope#get` (#5051)
## Summary

These usages don't actually need the `BindingId`.
2023-06-13 15:59:53 +00:00
Charlie Marsh e86f12a1ec
Rename some methods on `SemanticModel` (#4990) 2023-06-09 19:36:59 +00:00
Davide Canton 63fdcea29e
Handled dict and set inside f-string (#4249) (#4563) 2023-06-09 04:53:13 +00:00
Charlie Marsh ae75b303f0
Avoid attributing runtime references to module-level imports (#4942) 2023-06-07 21:56:03 +00:00
Charlie Marsh 8938b2d555
Use `qualified_name` terminology in more structs for consistency (#4873) 2023-06-05 19:06:48 +00:00
Charlie Marsh 466719247b
Invert parent-shadowed bindings map (#4847) 2023-06-04 00:18:46 -04:00
Charlie Marsh 3fa4440d87
Modify semantic model API to push bindings upon creation (#4846) 2023-06-04 02:28:25 +00:00
Charlie Marsh c14896b42c
Move `Binding` initialization into `SemanticModel` (#4819) 2023-06-03 15:26:55 -04:00
Charlie Marsh 935094c2ff
Move import-name matching into methods on `BindingKind` (#4818) 2023-06-03 15:01:27 -04:00
Charlie Marsh 26b1dd0ca2
Remove `name` field from import binding kinds (#4817) 2023-06-02 23:02:47 -04:00
Charlie Marsh ea3cbcc362
Avoid enforcing native-literals rule within nested f-strings (#4488) 2023-06-02 04:00:31 +00:00
qdegraaf fcbf5c3fae
Add PYI034 for `flake8-pyi` plugin (#4764) 2023-06-02 02:15:57 +00:00
Charlie Marsh 80fa3f2bfa
Add a convenience method to check if a name is bound (#4718) 2023-05-30 01:52:41 +00:00
Charlie Marsh 9741f788c7
Remove globals table from `Scope` (#4686) 2023-05-27 22:35:20 -04:00
Charlie Marsh af433ac14d
Avoid using typing-imported symbols for runtime edits (#4649) 2023-05-26 20:36:37 -04:00
Charlie Marsh 0f610f2cf7
Remove dedicated ScopeKind structs in favor of AST nodes (#4648) 2023-05-25 19:31:02 +00:00
Charlie Marsh f0e173d9fd
Use `BindingId` copies in lieu of `&BindingId` in semantic model methods (#4633) 2023-05-24 15:55:45 +00:00
Charlie Marsh fcdc7bdd33
Remove separate `ReferenceContext` enum (#4631) 2023-05-24 15:12:38 +00:00
Charlie Marsh 8961d8eb6f
Track all read references in semantic model (#4610) 2023-05-24 14:14:27 +00:00
Charlie Marsh ba4c0a21fa
Rename `ContextFlags` to `SemanticModelFlags` (#4611) 2023-05-23 17:47:07 -04:00
Charlie Marsh 74effb40b9
Rename `index` to `binding_id` in a few iterators (#4594) 2023-05-23 03:56:00 +00:00
Micha Reiser cbe344f4d5
Rename `Checker::model` to `semantic_model` (#4573) 2023-05-22 15:14:30 +02:00
Charlie Marsh 19c4b7bee6
Rename ruff_python_semantic's `Context` struct to `SemanticModel` (#4565) 2023-05-22 02:35:03 +00:00