Commit Graph

377 Commits

Author SHA1 Message Date
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 68b6d30c46
Use consistent `Cargo.toml` metadata in all crates (#5015) 2023-06-12 00:02:40 +00:00
Charlie Marsh e86f12a1ec
Rename some methods on `SemanticModel` (#4990) 2023-06-09 19:36:59 +00:00
Charlie Marsh 5c502a3320
Add documentation for `BindingKind` variants (#4989) 2023-06-09 18:32:50 +00:00
Davide Canton 63fdcea29e
Handled dict and set inside f-string (#4249) (#4563) 2023-06-09 04:53:13 +00:00
Micha Reiser 39a1f3980f
Upgrade RustPython (#4900) 2023-06-08 05:53:14 +00:00
Charlie Marsh ae75b303f0
Avoid attributing runtime references to module-level imports (#4942) 2023-06-07 21:56:03 +00:00
Charlie Marsh 780d153ae8
Replace one-off locals property with `ScopeFlags` (#4912) 2023-06-06 21:22:21 -04:00
Charlie Marsh 8c048b463c
Track symbol deletions separately from bindings (#4888) 2023-06-06 18:49:36 +00:00
Charlie Marsh 7b0fb1a3b4
Respect noqa directives on `ImportFrom` parents for type-checking rules (#4889) 2023-06-06 02:37:07 +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 d31eb87877
Extract shared simple AST node inference utility (#4871) 2023-06-05 18:23:37 +00:00
Charlie Marsh a0721912a4
Invert structure of Scope#shadowed_bindings (#4855) 2023-06-05 02:03:21 +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 211d8e170d
Ignore error calls with `exc_info` in TRY400 (#4797) 2023-06-02 04:59:45 +00: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
Jonathan Plasse edadd7814f
Add `pyflakes.extend-generics` setting (#4677) 2023-06-01 22:19:37 +00:00
Charlie Marsh ea31229be0
Track `TYPE_CHECKING` blocks in `Importer` (#4593) 2023-05-30 16:18:10 +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
Aarni Koskela 0106bce02f
[`flake8-future-annotations`] Implement `FA102` (#4702) 2023-05-29 22:41:45 +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
qdegraaf ccca11839a
Allow more immutable funcs for RUF009 (#4660) 2023-05-26 15:18:52 -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 5cedf0f724
Remove `ReferenceContext::Synthetic` (#4612) 2023-05-24 14:30:35 +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
Micha Reiser 652c644c2a
Introduce `ruff_index` crate (#4597) 2023-05-23 17:40:35 +02:00
Charlie Marsh 74effb40b9
Rename `index` to `binding_id` in a few iterators (#4594) 2023-05-23 03:56:00 +00:00
Micha Reiser daadd24bde
Include decorators in `Function` and `Class` definition ranges (#4467) 2023-05-22 17:50:42 +02:00
Micha Reiser cbe344f4d5
Rename `Checker::model` to `semantic_model` (#4573) 2023-05-22 15:14:30 +02:00
Charlie Marsh d70f899f71
Use `SemanticModel` in lieu of `Checker` in more methods (#4568) 2023-05-22 02:58:47 +00:00
Charlie Marsh 19c4b7bee6
Rename ruff_python_semantic's `Context` struct to `SemanticModel` (#4565) 2023-05-22 02:35:03 +00:00
Charlie Marsh fe7f2e2e4d
Move submodule alias resolution into `Context` (#4543) 2023-05-20 16:34:10 +00:00
Charlie Marsh 6aa9900c03
Improve handling of `__qualname__`, `__module__`, and `__class__` (#4512) 2023-05-20 03:03:45 +00:00
Charlie Marsh 9e21414294
Improve reference resolution for deferred-annotations-within-classes (#4509) 2023-05-20 02:54:18 +00:00
Charlie Marsh bb4e674415
Move reference-resolution into Context (#4510) 2023-05-20 02:47:15 +00:00
Charlie Marsh 73efbeb581
Invert quote-style when generating code within f-strings (#4487) 2023-05-18 14:33:33 +00:00
Micha Reiser fa26860296
Refactor range from `Attributed` to `Node`s (#4422) 2023-05-16 06:36:32 +00:00
Charlie Marsh 2414469ac3
Enable automatic rewrites of `typing.Deque` and `typing.DefaultDict` (#4420) 2023-05-15 22:33:24 +00:00
Tyler Yep 01b372a75c
Implement `flake8-future-annotations` FA100 (#3979) 2023-05-14 03:00:06 +00:00
Charlie Marsh 7e3ba7f32a
Use `bitflags` for tracking `Context` flags (#4381) 2023-05-12 16:07:26 +00:00
Charlie Marsh 9158f13ee6
Respect `__all__` imports when determining definition visibility (#4357) 2023-05-11 17:43:51 +00:00
Charlie Marsh 72e0ffc1ac
Delay computation of `Definition` visibility (#4339) 2023-05-11 17:14:29 +00:00
Jeong, YunWon be6e00ef6e
Re-integrate RustPython parser repository (#4359)
Co-authored-by: Micha Reiser <micha@reiser.io>
2023-05-11 07:47:17 +00:00
Charlie Marsh f4f88308ae
Remove `Copy` and destructure `Snapshot` (#4358) 2023-05-10 19:46:18 +00:00
Charlie Marsh ea3d3a655d
Add a `Snapshot` abstraction for deferring and restoring visitor context (#4353) 2023-05-10 16:50:47 +00:00
Charlie Marsh 6d6d7abf70
Use short-import for `HashMap` (#4351) 2023-05-10 15:46:55 +00:00
Charlie Marsh 7b91a162c6
Remove `current_` prefix from some Context methods (#4325) 2023-05-09 19:40:12 +00:00
Charlie Marsh d365dab904
Include static and class methods in in abstract decorator list (#4298) 2023-05-08 21:54:02 -04:00
Charlie Marsh 539af34f58
Add a utility method to detect top-level state (#4259) 2023-05-06 20:24:27 +00:00
Charlie Marsh 983bb31577
Remove `RefEquality` usages from `Context` (#4257) 2023-05-06 15:55:14 -04:00
Charlie Marsh cd27b39aff
Re-order some code in scope.rs (#4255) 2023-05-06 16:36:20 +00:00
Charlie Marsh a9fc648faf
Use `NodeId` for `Binding` source (#4234) 2023-05-06 16:20:08 +00:00
Charlie Marsh c1f0661225
Replace `parents` statement stack with a `Nodes` abstraction (#4233) 2023-05-06 16:12:41 +00:00
Dhruv Manilawala 2c91412321
Consider Flask app logger as logger candidate (#4253) 2023-05-06 11:31:10 -04:00
Charlie Marsh 64b7280eb8
Respect parent-scoping rules for `NamedExpr` assignments (#4145) 2023-04-29 22:45:30 +00:00
Charlie Marsh 2115d99c43
Remove `ScopeStack` in favor of child-parent `ScopeId` pointers (#4138) 2023-04-29 18:23:51 -04:00
Moritz Sauter ee6d8f7467
Add bugbear immutable functions as allowed in dataclasses (#4122) 2023-04-27 21:23:06 -04:00
Micha Reiser cab65b25da
Replace row/column based `Location` with byte-offsets. (#3931) 2023-04-26 18:11:02 +00:00
Jonathan Plasse 5e91211e6d
Add `in_boolean_test` to `Context` (#4072) 2023-04-23 23:18:23 -06:00
Micha Reiser ba4f4f4672
Upgrade dependencies (#4064) 2023-04-22 18:04:01 +01:00
Dhruv Manilawala ba98149022
Avoid `RUF008` if field annotation is immutable (#4039) 2023-04-20 16:02:12 -04:00
Charlie Marsh 10d5415bcb
Ignore certain flake8-pyi errors within function bodies (#4029) 2023-04-19 15:10:29 -04:00
Charlie Marsh 7fa1da20fb
Support relative imports in `banned-api` enforcement (#4025) 2023-04-19 14:30:13 -04:00
Dhruv Manilawala b6155232ac
Consider logger candidate from `logging` module only (#3878) 2023-04-04 19:52:57 +00:00
Charlie Marsh d919adc13c
Introduce a `ruff_python_semantic` crate (#3865) 2023-04-04 16:50:47 +00:00