|
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