|
1 |
| -[](https://github.com/google/pytype/actions/workflows/ci.yml?query=branch%3Amain) |
2 |
| -[](https://pypi.org/project/pytype/#files) |
3 |
| - |
4 |
| -# pytype - 🦆✔ |
5 |
| - |
6 |
| -Pytype checks and infers types for your Python code - without requiring type |
7 |
| -annotations. Pytype can: |
8 |
| - |
9 |
| -* Lint plain Python code, flagging common mistakes such as misspelled attribute |
10 |
| -names, incorrect function calls, and [much more][error-classes], even across |
11 |
| -file boundaries. |
12 |
| -* Enforce user-provided [type annotations][pep-484]. While annotations are |
13 |
| -optional for pytype, it will check and apply them where present. |
14 |
| -* Generate type annotations in standalone files ("[pyi files][pyi-stub-files]"), |
15 |
| -which can be merged back into the Python source with a provided |
16 |
| -[merge-pyi][merge-pyi] tool. |
17 |
| - |
18 |
| -Pytype is a static analyzer; it does not execute the code it runs on. |
19 |
| - |
20 |
| -Thousands of projects at Google rely on pytype to keep their Python code |
21 |
| -well-typed and error-free. |
22 |
| - |
23 |
| -For more information, check out the [user guide][user-guide], [FAQ][faq], or |
24 |
| -[supported features][supported-features]. |
25 |
| - |
26 |
| -## How is pytype different from other type checkers? |
27 |
| - |
28 |
| -1. Pytype uses **inference** instead of gradual typing. This means it will |
29 |
| -infer types on code even when the code has no type hints on it. So it can |
30 |
| -detect issues with code like this, which other type checkers would miss: |
31 |
| - |
32 |
| - ```python |
33 |
| - def f(): |
34 |
| - return "PyCon" |
35 |
| - def g(): |
36 |
| - return f() + 2019 |
37 |
| - |
38 |
| - # pytype: line 4, in g: unsupported operand type(s) for +: 'str' |
39 |
| - # and 'int' [unsupported-operands] |
40 |
| - ``` |
41 |
| - |
42 |
| -1. Pytype is **lenient** instead of strict. That means it allows all |
43 |
| -operations that succeed at runtime and don't contradict annotations. For |
44 |
| -instance, this code will pass as safe in pytype, but fail in other type |
45 |
| -checkers, which assign types to variables as soon as they are initialized: |
46 |
| - |
47 |
| - ```python |
48 |
| - from typing import List |
49 |
| - def get_list() -> List[str]: |
50 |
| - lst = ["PyCon"] |
51 |
| - lst.append(2019) |
52 |
| - return [str(x) for x in lst] |
53 |
| - |
54 |
| - # mypy: line 4: error: Argument 1 to "append" of "list" has |
55 |
| - # incompatible type "int"; expected "str" |
56 |
| - ``` |
57 |
| - |
58 |
| -Also see the corresponding [FAQ entry][faq-diff]. |
59 |
| - |
60 |
| -## Quickstart |
61 |
| - |
62 |
| -To quickly get started with type-checking a file or directory, run the |
63 |
| -following, replacing `file_or_directory` with your input: |
64 |
| - |
65 |
| -```shell |
66 |
| -pip install pytype |
67 |
| -pytype file_or_directory |
68 |
| -``` |
69 |
| - |
70 |
| -To set up pytype on an entire package, add the following to a `pyproject.toml` |
71 |
| -file in the directory immediately above the package, replacing `package_name` |
72 |
| -with the package name: |
73 |
| - |
74 |
| -```toml |
75 |
| -[tool.pytype] |
76 |
| -inputs = ['package_name'] |
77 |
| -``` |
78 |
| - |
79 |
| -Now you can run the no-argument command `pytype` to type-check the package. It's |
80 |
| -also easy to add pytype to your automated testing; see this |
81 |
| -[example][importlab-github-actions] of a GitHub project that runs pytype on GitHub Actions. |
82 |
| - |
83 |
| -Finally, pytype generates files of inferred type information, located by default |
84 |
| -in `.pytype/pyi`. You can use this information to type-annotate the |
85 |
| -corresponding source file: |
86 |
| - |
87 |
| -```shell |
88 |
| -merge-pyi -i <filepath>.py .pytype/pyi/<filename>.pyi |
89 |
| -``` |
90 |
| - |
91 |
| -## Requirements |
92 |
| - |
93 |
| -You need a Python 3.8-3.12 interpreter to run pytype, as well as an |
94 |
| -interpreter in `$PATH` for the Python version of the code you're analyzing |
95 |
| -(supported: 3.8-3.12). |
96 |
| - |
97 |
| -Platform support: |
98 |
| - |
99 |
| -* Pytype is currently developed and tested on Linux\*, which is the main supported |
100 |
| - platform. |
101 |
| -* Installation on MacOSX requires OSX 10.7 or higher and Xcode v8 or higher**. |
102 |
| -* Windows is currently not supported unless you use [WSL][wsl]. |
103 |
| - |
104 |
| -<sub>\* |
105 |
| -On Alpine Linux, installation may fail due to issues with upstream |
106 |
| -dependencies. See the details of [this issue][scikit-build-issue] for a |
107 |
| -possible fix. |
108 |
| -<br /> |
109 |
| -\*\* |
110 |
| -If the ninja dependency fails to install, make sure cmake is installed. See |
111 |
| -[this issue][ninja-build-issue] for details. |
112 |
| -</sub> |
113 |
| - |
114 |
| -## Installing |
115 |
| - |
116 |
| -Pytype can be installed via pip. Note that the installation requires `wheel` |
117 |
| -and `setuptools`. (If you're working in a virtualenv, these two packages should |
118 |
| -already be present.) |
119 |
| - |
120 |
| -```shell |
121 |
| -pip install pytype |
122 |
| -``` |
123 |
| - |
124 |
| -Or from the source code [on GitHub][github]. |
125 |
| - |
126 |
| -```shell |
127 |
| -git clone --recurse-submodules https://github.com/google/pytype.git |
128 |
| -cd pytype |
129 |
| -pip install . |
130 |
| -``` |
131 |
| - |
132 |
| -Instead of using `--recurse-submodules`, you could also have run |
133 |
| - |
134 |
| -```shell |
135 |
| -git submodule init |
136 |
| -git submodule update |
137 |
| -``` |
138 |
| - |
139 |
| -in the `pytype` directory. To edit the code and have your edits tracked live, |
140 |
| -replace the pip install command with: |
141 |
| - |
142 |
| -```shell |
143 |
| -pip install -e . |
144 |
| -``` |
145 |
| - |
146 |
| -### Installing on WSL |
147 |
| - |
148 |
| -Follow the steps above, but make sure you have the correct libraries first: |
149 |
| - |
150 |
| -```shell |
151 |
| -sudo apt install build-essential python3-dev libpython3-dev |
152 |
| -``` |
153 |
| - |
154 |
| -## Usage |
155 |
| - |
156 |
| -``` |
157 |
| -usage: pytype [options] input [input ...] |
158 |
| -
|
159 |
| -positional arguments: |
160 |
| - input file or directory to process |
161 |
| -``` |
162 |
| - |
163 |
| -Common options: |
164 |
| - |
165 |
| -* `-V, --python-version`: Python version (major.minor) of the target code. |
166 |
| - Defaults to the version that pytype is running under. |
167 |
| -* `-o, --output`: The directory into which all pytype output goes, including |
168 |
| - generated .pyi files. Defaults to `.pytype`. |
169 |
| -* `-d, --disable`. Comma or space-separated list of error names to ignore. |
170 |
| - Detailed explanations of pytype's error names are in |
171 |
| - [this doc][error-classes]. Defaults to empty. |
172 |
| - |
173 |
| -For a full list of options, run `pytype --help`. |
174 |
| - |
175 |
| -In addition to the above, you can direct pytype to use a custom typeshed |
176 |
| -installation instead of its own bundled copy by setting `$TYPESHED_HOME`. |
177 |
| - |
178 |
| -### Config File |
179 |
| - |
180 |
| -For convenience, you can save your pytype configuration in a file. The config |
181 |
| -file can be a TOML-style file with a `[tool.pytype]` section (preferred) or an |
182 |
| -INI-style file with a `[pytype]` section. If an explicit config file is not |
183 |
| -supplied, pytype will look for a pytype section in the first `pyproject.toml` or |
184 |
| -`setup.cfg` file found by walking upwards from the current working directory. |
185 |
| - |
186 |
| -Start off by generating a sample config file: |
187 |
| - |
188 |
| -```shell |
189 |
| -$ pytype --generate-config pytype.toml |
190 |
| -``` |
191 |
| - |
192 |
| -Now customize the file based on your local setup, keeping only the sections you |
193 |
| -need. Directories may be relative to the location of the config file, which is |
194 |
| -useful if you want to check in the config file as part of your project. |
195 |
| - |
196 |
| -For example, suppose you have the following directory structure and want to |
197 |
| -analyze package `~/repo1/foo`, which depends on package `~/repo2/bar`: |
198 |
| - |
199 |
| -``` |
200 |
| -~/ |
201 |
| -├── repo1 |
202 |
| -│ └── foo |
203 |
| -│ ├── __init__.py |
204 |
| -│ └── file_to_check.py |
205 |
| -└── repo2 |
206 |
| - └── bar |
207 |
| - ├── __init__.py |
208 |
| - └── dependency.py |
209 |
| -``` |
210 |
| - |
211 |
| -Here is the filled-in config file, which instructs pytype to type-check |
212 |
| -`~/repo1/foo` as Python 3.9 code, look for packages in `~/repo1` and `~/repo2`, |
213 |
| -and ignore attribute errors. Notice that the path to a package does not include |
214 |
| -the package itself. |
215 |
| - |
216 |
| -```toml |
217 |
| -$ cat ~/repo1/pytype.toml |
218 |
| - |
219 |
| -# NOTE: All relative paths are relative to the location of this file. |
220 |
| - |
221 |
| -[tool.pytype] |
222 |
| - |
223 |
| -# Space-separated list of files or directories to process. |
224 |
| -inputs = [ |
225 |
| - 'foo', |
226 |
| -] |
227 |
| - |
228 |
| -# Python version (major.minor) of the target code. |
229 |
| -python_version = '3.9' |
230 |
| - |
231 |
| -# Paths to source code directories, separated by ':'. |
232 |
| -pythonpath = .:~/repo2 |
233 |
| - |
234 |
| -# Space-separated list of error names to ignore. |
235 |
| -disable = [ |
236 |
| - 'attribute-error', |
237 |
| -] |
238 |
| -``` |
239 |
| - |
240 |
| -We could've discovered that `~/repo2` needed to be added to the pythonpath by |
241 |
| -running pytype's broken dependency checker: |
242 |
| - |
243 |
| -``` |
244 |
| -$ pytype --config=~/repo1/pytype.toml ~/repo1/foo/*.py --unresolved |
245 |
| -
|
246 |
| -Unresolved dependencies: |
247 |
| - bar.dependency |
248 |
| -``` |
249 |
| - |
250 |
| -### Subtools |
251 |
| - |
252 |
| -Pytype ships with a few scripts in addition to `pytype` itself: |
253 |
| - |
254 |
| -* `annotate-ast`, an in-progress type annotator for ASTs. |
255 |
| -* [`merge-pyi`][merge-pyi], for merging type information from a .pyi file into a |
256 |
| -Python file. |
257 |
| -* `pytd-tool`, a parser for .pyi files. |
258 |
| -* `pytype-single`, a debugging tool for pytype developers, which analyzes a |
259 |
| -single Python file assuming that .pyi files have already been generated for all |
260 |
| -of its dependencies. |
261 |
| -* `pyxref`, a cross-references generator. |
262 |
| - |
263 |
| -## License |
264 |
| - |
265 |
| -[Apache 2.0][license] |
266 |
| - |
267 |
| -## Disclaimer |
268 |
| - |
269 |
| -This is not an official Google product. |
270 |
| - |
271 |
| -[error-classes]: docs/errors.md |
272 |
| -[faq]: docs/faq.md |
273 |
| -[faq-diff]: docs/faq.md#how-is-pytype-different-from-other-type-checkers |
274 |
| -[github]: https://github.com/google/pytype/ |
275 |
| -[importlab-github-actions]: https://github.com/google/importlab/blob/main/.github/workflows/ci.yml |
276 |
| -[license]: https://github.com/google/pytype/blob/main/LICENSE |
277 |
| -[merge-pyi]: https://github.com/google/pytype/tree/main/pytype/tools/merge_pyi |
278 |
| -[ninja-build-issue]: https://github.com/google/pytype/issues/957 |
279 |
| -[pep-484]: https://www.python.org/dev/peps/pep-0484 |
280 |
| -[pyi-stub-files]: docs/user_guide.md#pyi-stub-files |
281 |
| -[scikit-build-issue]: https://github.com/scikit-build/ninja-python-distributions/issues/27 |
282 |
| -[supported-features]: docs/support.md |
283 |
| -[user-guide]: docs/user_guide.md |
284 |
| -[wsl]: https://docs.microsoft.com/en-us/windows/wsl/faq |
| 1 | +# An update on pytype |
| 2 | + |
| 3 | +**TL;DR**: The last supported Python version for Pytype will be 3.12. We are |
| 4 | +still very actively interested in the space of Python type checking, but |
| 5 | +shifting our investments towards new ideas and different frameworks. |
| 6 | + |
| 7 | +Pytype's development began in 2012 to meet Google developers' demand for |
| 8 | +compile-time checking. Pytype started with using type inference and interface |
| 9 | +files, and then switched to inline annotations (while retaining the inference |
| 10 | +engine) after the acceptance of PEP 484. Later, pytype's team collaborated with |
| 11 | +Guido and mypy to create typeshed, a central repository for type annotations. |
| 12 | + |
| 13 | +While pytype has been effective, its bytecode-based design has presented |
| 14 | +challenges in implementing new features (e.g. faster adoption of new typing |
| 15 | +PEPs) due to bytecode’s inherent instability and propensity to change. |
| 16 | +Consequently, we intend to focus our investments on exploring new typing |
| 17 | +approaches that are better suited for Google’s Python user base and make |
| 18 | +Python 3.12 the last supported version for pytype. |
| 19 | + |
| 20 | +We encourage folks to investigate the mature and excellent alternative solutions |
| 21 | +for Python typing going forward. We would like to note that the Python typing |
| 22 | +ecosystem is very robust now, offering a wider array of mature solutions (see |
| 23 | +[FAQ](https://github.com/google/pytype/issues/1925)). |
| 24 | + |
| 25 | +The creation and development of pytype was a collaborative effort, and we would |
| 26 | +like to thank all contributors to pytype, especially the four main contributors: |
| 27 | +Rebecca Chen, Martin DeMello, Teddy Sudol, and initial lead Matthias Kramm. |
| 28 | +We particularly recognize Rebecca Chen for her decade-long commitment to pytype |
| 29 | +and her significant contributions to Python's type system as a long-standing |
| 30 | +member of the typing council. |
0 commit comments