agronholm / agronholm/typeguard

Check annotated locals bound by `for` and `with` targets

Offen
#586 4 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
enhancement
Vorherrschende Sprache
Python
Sterne
1.8k
Forks
145
Ø Merge
8 T. 12 Std.
Gemergte PRs (30 T.)
1

Beschreibung

Reframed as a feature request, per agronholm's comment below. Originally filed as a bug report.

Typeguard checks the value assigned to an annotated local by `=`, by the walrus operator, by chained assignment and by tuple unpacking. It does not check a value bound to the same annotated name by a `for` target or a `with ... as` target. Same for `async for`, `async with ... as`, `except ... as`, `except* ... as`, a `match` capture pattern and `import ... as`.

The request is to extend the local-variable check to those binding forms, or to whichever subset is worth the transformer complexity. `for` and `with` are the two that turn up in ordinary code.

Same behaviour on 4.6.0 and on main at `123f1abc7e82bbe980c779005de858533e1786c3`, python 3.11.16 / 3.12.14 / 3.13.15. `install_import_hook` behaves like `@typechecked` here, so it is not specific to the decorator. mypy flags all three cases below as `Incompatible types in assignment`.

```python
import io

from typeguard import TypeCheckError, typechecked

@typechecked
def plain_assign() -> None:
x: int
x = "not an int"

@typechecked
def for_target() -> None:
x: int
for x in ["not an int"]:
pass

@typechecked
def with_target() -> None:
x: io.BytesIO
with io.StringIO() as x:
pass

for func in (plain_assign, for_target, with_target):
try:
func()
print(f"{func.__name__}: no error")
except TypeCheckError as exc:
print(f"{func.__name__}: TypeCheckError: {exc}")
```

```
plain_assign: TypeCheckError: value assigned to x (str) is not an instance of int
for_target: no error
with_target: no error
```

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.