ruff/crates/ruff_python_semantic/src
Charlie Marsh bf4b96c5de
Differentiate between runtime and typing-time annotations (#5575)
## Summary

In Python, the annotations on `x` and `y` here have very different
treatment:

```python
def foo(x: int):
  y: int
```

The `int` in `x: int` is a runtime-required annotation, because `x` gets
added to the function's `__annotations__`. You'll notice, for example,
that this fails:

```python
from typing import TYPE_CHECKING

if TYPE_CHECKING:
  from foo import Bar

def f(x: Bar):
  ...
```

Because `Bar` is required to be available at runtime, not just at typing
time. Meanwhile, this succeeds:

```python
from typing import TYPE_CHECKING

if TYPE_CHECKING:
  from foo import Bar

def f():
  x: Bar = 1

f()
```

(Both cases are fine if you use `from __future__ import annotations`.)

Historically, we've tracked those annotations that are _not_
runtime-required via the semantic model's `ANNOTATION` flag. But
annotations that _are_ runtime-required have been treated as "type
definitions" that aren't annotations.

This causes problems for the flake8-future-annotations rules, which try
to detect whether adding `from __future__ import annotations` would
_allow_ you to rewrite a type annotation. We need to know whether we're
in _any_ type annotation, runtime-required or not, since adding `from
__future__ import annotations` will convert any runtime-required
annotation to a typing-only annotation.

This PR adds separate state to track these runtime-required annotations.
The changes in the test fixtures are correct -- these were false
negatives before.

Closes https://github.com/astral-sh/ruff/issues/5574.
2023-07-07 00:21:44 -04:00
..
analyze Remove some additional manual iterator matches (#5482) 2023-07-03 16:29:59 +00:00
binding.rs Enable attribute lookups via semantic model (#5536) 2023-07-05 15:19:14 -04:00
context.rs Remove separate ReferenceContext enum (#4631) 2023-05-24 15:12:38 +00:00
definition.rs Run rustfmt on nightly to clean up erroneous comments (#5106) 2023-06-15 00:19:05 +00:00
globals.rs Make some of ruff_python_semantic pub(crate) (#5093) 2023-06-14 17:49:37 +00:00
lib.rs Move StarImport to its own module (#5186) 2023-06-20 13:12:46 -04:00
model.rs Differentiate between runtime and typing-time annotations (#5575) 2023-07-07 00:21:44 -04:00
node.rs Make some of ruff_python_semantic pub(crate) (#5093) 2023-06-14 17:49:37 +00:00
reference.rs Make some of ruff_python_semantic pub(crate) (#5093) 2023-06-14 17:49:37 +00:00
scope.rs Run shadowed-variable analyses in deferred handlers (#5181) 2023-06-29 00:08:18 +00:00
star_import.rs Move StarImport to its own module (#5186) 2023-06-20 13:12:46 -04:00