Skip to content

Commit

Permalink
Prepare for version 2024.10.11
Browse files Browse the repository at this point in the history
- Update `__version__.py`
- Summarize changes from 2024.09.13...feaa7a2 in CHANGELOG
- Update docs

PiperOrigin-RevId: 684739987
  • Loading branch information
frigus02 authored and copybara-github committed Oct 11, 2024
1 parent b78f7e5 commit ecdf41f
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 33 deletions.
25 changes: 25 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
Version 2024.10.11:

Updates:
* Drop support for Python 3.8 and 3.9.

* Make merge_pyi not to overwrite existing type annotations.

* When printing types (e.g. in error messages or `reveal_type`), print generic
builtin names in lowercase.

Old: `from typing import List; List[Foo]`
New: `list[Foo]`

Bug fixes:
* Unpin dependency on networkx, which means pytype now supports >=3.3.
* Emit all unused/duplicate files with --unused_imports_info_files option,
rather than only one per unique module name.
* Change return types of AsyncGenerator's methods to coroutines. This brings
pytype's definition in line with the definition on typeshed and reflects the
fact that asynchronous generators defined using the `async def`/`yield` syntax
have methods returning coroutines rather than just arbitrary awaitables.
* Fix type guards propagating invisibile bindings. Fixes some incorrect "used
after deleted" errors with Python 3.12.
* Fix resolution of ParamSpec in files with circular imports.

Version 2024.09.13:

Updates:
Expand Down
34 changes: 15 additions & 19 deletions docs/developers/typegraph.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,19 +80,19 @@ that a Variable is connected to represent the possible values for that Variable.

Building up the CFG in this way allows pytype to perform type checking. When
pytype reaches Node 5 (`z = x.upper() + str(y)`), it queries the CFG to find
what `x` may be. Depending on the value of `some_val`, `x` could an `int` or a
`str`. Since `int` doesn't have a method called `upper`, pytype reports an
`attribute-error`, even though `str` _does_ have an `upper` method.

However, pytype is limited in what it knows. Looking at the example again, we
know that `y` won't be defined if `some_val` is `False`, which would make
`str(y)` fail. But pytype can't know for sure if `some_val` will evaluate to
`True` or `False`. Since there's a path through the CFG where `y` is defined
(`y = 6` if `some_val == True`), pytype won't report an error for `str(y)`. If
we change the condition to `if False`, so that pytype knows unambiguously that
only the code under `else:` will be executed, then pytype will report a
`name-error` on `str(y)` because there is no path through the CFG where `y` is
defined.
what `x` may be. Depending on the value of `some_val`, `x` could be an `int` or
a `str`. Since `int` doesn't have a method called `upper`, pytype reports an
`attribute-error`, even though `str` *does* have an `upper` method.

However, pytype sometimes chooses a more lenient approach. Looking at the
example again, we know that `y` won't be defined if `some_val` is `False`, which
would make `str(y)` fail. But pytype can't know for sure if `some_val` will
evaluate to `True` or `False`. With `--strict-undefined-checks` turned off,
pytype won't report an error for `str(y)`, since there's a path through the CFG
where `y` is defined (`y = 6` if `some_val == True`). If we change the condition
to `if False`, so that pytype knows unambiguously that only the code under
`else:` will be executed, then pytype will report a `name-error` on `str(y)`
because there is no path through the CFG where `y` is defined.

[wiki-cfg]: https://en.wikipedia.org/wiki/Control-flow_graph

Expand All @@ -104,10 +104,6 @@ are in scope and the types of those objects at any point in the program. The
source code for the CFG lives in the `typegraph/` directory. It's written in C++
for performance reasons.

(Note: there is also a Python implementation, `cfg.py` and `cfg_utils.py`, which
is no longer used and is not guaranteed to match the semantics of the C++
implementation.)

### Typegraph

A CFG maps the paths of execution through a program; similarly, a typegraph maps
Expand Down Expand Up @@ -150,8 +146,8 @@ The condition of the if-statement is `some_val`, or more explicitly `some_val ==
True`. Pytype understands that the path `1 -> 2 -> 3 -> 5` can only be taken
when `some_val` evaluates to `True`, while `1 -> 4 -> 5` is taken when
`some_val` evaluates to False. This is accomplished by adding the condition to
the list of goals in a query. (Queries and goals are discussed in the [Solver]
section.)
the list of goals in a query. (Queries and goals are discussed in the
[Solver](#the-solver-algorithm) section.)

CFGNodes may be associated with **Variables** by one or more **Bindings**. A
simple case, `x = 5`, was explained above. In more complex cases, such as `y =
Expand Down
27 changes: 24 additions & 3 deletions docs/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -550,9 +550,30 @@ class A(Generic[T]):
## invalid-super-call

A call to super without any arguments (Python 3) is being made from an invalid
context. A super call without any arguments should be made from a method or a
function defined within a class. Also, the caller should have at least one
positional argument.
context:

<!-- bad -->
```python
super().foo()
```

<!-- bad -->
```python
class A(B):
def f():
super().foo()
```

A super call without any arguments should be made from a method or a function
defined within a class, and the caller should have at least one positional
argument:

<!-- good -->
```python
class A(B):
def f(self):
super().foo()
```

## invalid-typevar

Expand Down
40 changes: 39 additions & 1 deletion docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,47 @@ the analysis:

* Split up the file. Anecdotally, pytype gets noticeable slower once a file
grows past ~1500 lines.
* Annotate the return types of functions to speed up inference.

* Annotate parameter and return types of functions to speed up inference.

* Simplify function inputs (e.g., by reducing the number of types in unions)
to speed up checking.

* Split complex variable initializations (i.e. with multiple if-else branches)
into separate functions. Tracking multiple variable values across multiple
conditional branches can quickly get unwieldy.

<!-- bad -->
```python
def foo(config: Config):
if config.bar:
a = config.bar.a()
else:
a = config.default()
if config.baz:
a = config.baz(a)
# ... similar branching for `b` and `c` ...
do_foo(a, b, c)
```

<!-- good -->
```python
def _get_a(config: Config) -> A:
if config.bar:
a = config.bar.a()
else:
a = config.default()
if config.baz:
a = config.baz(a)
return a

def foo(config: Config):
a = _get_a(config)
b = _get_b(config)
c = _get_c(config)
do_foo(a, b, c)
```

* Add type annotations to large concrete data structures (e.g., a module-level
dict of a hundred constants). pytype tracks individual values for some
builtin data structures, which can quickly get unwieldy. Adding a type
Expand Down
13 changes: 4 additions & 9 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# pytype - 🦆✔

<!--* freshness: { exempt: true } *-->

Pytype checks and infers types for your Python code - without requiring type
annotations. Pytype can:

Expand Down Expand Up @@ -89,9 +87,9 @@ merge-pyi -i <filepath>.py .pytype/pyi/<filename>.pyi

## Requirements

You need a Python 3.8-3.11 interpreter to run pytype, as well as an
You need a Python 3.8-3.12 interpreter to run pytype, as well as an
interpreter in `$PATH` for the Python version of the code you're analyzing
(supported: 3.8-3.11).
(supported: 3.8-3.12).

Platform support:

Expand Down Expand Up @@ -259,15 +257,12 @@ single Python file assuming that .pyi files have already been generated for all
of its dependencies.
* `pyxref`, a cross-references generator.

## 2023 Roadmap

* Typegraph rewrite for improved correctness and performance.
* Basic Python 3.11 support.

## License

[Apache 2.0][license]

## Disclaimer

This is not an official Google product.

[error-classes]: errors.md
Expand Down
2 changes: 1 addition & 1 deletion pytype/__version__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# pylint: skip-file
__version__ = '2024.09.13'
__version__ = '2024.10.11'

0 comments on commit ecdf41f

Please sign in to comment.