1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
|
.. _mypy_daemon:
.. program:: dmypy
Mypy daemon (mypy server)
=========================
Instead of running mypy as a command-line tool, you can also run it as
a long-running daemon (server) process and use a command-line client to
send type-checking requests to the server. This way mypy can perform type
checking much faster, since program state cached from previous runs is kept
in memory and doesn't have to be read from the file system on each run.
The server also uses finer-grained dependency tracking to reduce the amount
of work that needs to be done.
If you have a large codebase to check, running mypy using the mypy
daemon can be *10 or more times faster* than the regular command-line
``mypy`` tool, especially if your workflow involves running mypy
repeatedly after small edits -- which is often a good idea, as this way
you'll find errors sooner.
.. note::
The command-line interface of mypy daemon may change in future mypy
releases.
.. note::
Each mypy daemon process supports one user and one set of source files,
and it can only process one type checking request at a time. You can
run multiple mypy daemon processes to type check multiple repositories.
Basic usage
***********
The client utility ``dmypy`` is used to control the mypy daemon.
Use ``dmypy run -- <flags> <files>`` to type check a set of files
(or directories). This will launch the daemon if it is not running.
You can use almost arbitrary mypy flags after ``--``. The daemon
will always run on the current host. Example::
dmypy run -- prog.py pkg/*.py
``dmypy run`` will automatically restart the daemon if the
configuration or mypy version changes.
The initial run will process all the code and may take a while to
finish, but subsequent runs will be quick, especially if you've only
changed a few files. (You can use :ref:`remote caching <remote-cache>`
to speed up the initial run. The speedup can be significant if
you have a large codebase.)
.. note::
Mypy 0.780 added support for following imports in dmypy (enabled by
default). This functionality is still experimental. You can use
``--follow-imports=skip`` or ``--follow-imports=error`` to fall
back to the stable functionality. See :ref:`follow-imports` for
details on how these work.
.. note::
The mypy daemon requires ``--local-partial-types`` and automatically enables it.
Daemon client commands
**********************
While ``dmypy run`` is sufficient for most uses, some workflows
(ones using :ref:`remote caching <remote-cache>`, perhaps),
require more precise control over the lifetime of the daemon process:
* ``dmypy stop`` stops the daemon.
* ``dmypy start -- <flags>`` starts the daemon but does not check any files.
You can use almost arbitrary mypy flags after ``--``.
* ``dmypy restart -- <flags>`` restarts the daemon. The flags are the same
as with ``dmypy start``. This is equivalent to a stop command followed
by a start.
* Use ``dmypy run --timeout SECONDS -- <flags>`` (or
``start`` or ``restart``) to automatically
shut down the daemon after inactivity. By default, the daemon runs
until it's explicitly stopped.
* ``dmypy check <files>`` checks a set of files using an already
running daemon.
* ``dmypy recheck`` checks the same set of files as the most recent
``check`` or ``recheck`` command. (You can also use the :option:`--update`
and :option:`--remove` options to alter the set of files, and to define
which files should be processed.)
* ``dmypy status`` checks whether a daemon is running. It prints a
diagnostic and exits with ``0`` if there is a running daemon.
Use ``dmypy --help`` for help on additional commands and command-line
options not discussed here, and ``dmypy <command> --help`` for help on
command-specific options.
Additional daemon flags
***********************
.. option:: --status-file FILE
Use ``FILE`` as the status file for storing daemon runtime state. This is
normally a JSON file that contains information about daemon process and
connection. The default path is ``.dmypy.json`` in the current working
directory.
.. option:: --log-file FILE
Direct daemon stdout/stderr to ``FILE``. This is useful for debugging daemon
crashes, since the server traceback is not always printed by the client.
This is available for the ``start``, ``restart``, and ``run`` commands.
.. option:: --timeout TIMEOUT
Automatically shut down server after ``TIMEOUT`` seconds of inactivity.
This is available for the ``start``, ``restart``, and ``run`` commands.
.. option:: --update FILE
Re-check ``FILE``, or add it to the set of files being
checked (and check it). This option may be repeated, and it's only available for
the ``recheck`` command. By default, mypy finds and checks all files changed
since the previous run and files that depend on them. However, if you use this option
(and/or :option:`--remove`), mypy assumes that only the explicitly
specified files have changed. This is only useful to
speed up mypy if you type check a very large number of files, and use an
external, fast file system watcher, such as `watchman`_ or
`watchdog`_, to determine which files got edited or deleted.
*Note:* This option is never required and is only available for
performance tuning.
.. option:: --remove FILE
Remove ``FILE`` from the set of files being checked. This option may be
repeated. This is only available for the
``recheck`` command. See :option:`--update` above for when this may be useful.
*Note:* This option is never required and is only available for performance
tuning.
.. option:: --fswatcher-dump-file FILE
Collect information about the current internal file state. This is
only available for the ``status`` command. This will dump JSON to
``FILE`` in the format ``{path: [modification_time, size,
content_hash]}``. This is useful for debugging the built-in file
system watcher. *Note:* This is an internal flag and the format may
change.
.. option:: --perf-stats-file FILE
Write performance profiling information to ``FILE``. This is only available
for the ``check``, ``recheck``, and ``run`` commands.
.. option:: --export-types
Store all expression types in memory for future use. This is useful to speed
up future calls to ``dmypy inspect`` (but uses more memory). Only valid for
``check``, ``recheck``, and ``run`` command.
Static inference of annotations
*******************************
The mypy daemon supports (as an experimental feature) statically inferring
draft function and method type annotations. Use ``dmypy suggest FUNCTION`` to
generate a draft signature in the format
``(param_type_1, param_type_2, ...) -> ret_type`` (types are included for all
arguments, including keyword-only arguments, ``*args`` and ``**kwargs``).
This is a low-level feature intended to be used by editor integrations,
IDEs, and other tools (for example, the `mypy plugin for PyCharm`_),
to automatically add annotations to source files, or to propose function
signatures.
In this example, the function ``format_id()`` has no annotation:
.. code-block:: python
def format_id(user):
return f"User: {user}"
root = format_id(0)
``dmypy suggest`` uses call sites, return statements, and other heuristics (such as
looking for signatures in base classes) to infer that ``format_id()`` accepts
an ``int`` argument and returns a ``str``. Use ``dmypy suggest module.format_id`` to
print the suggested signature for the function.
More generally, the target function may be specified in two ways:
* By its fully qualified name, i.e. ``[package.]module.[class.]function``.
* By its location in a source file, i.e. ``/path/to/file.py:line``. The path can be
absolute or relative, and ``line`` can refer to any line number within
the function body.
This command can also be used to find a more precise alternative for an existing,
imprecise annotation with some ``Any`` types.
The following flags customize various aspects of the ``dmypy suggest``
command.
.. option:: --json
Output the signature as JSON, so that `PyAnnotate`_ can read it and add
the signature to the source file. Here is what the JSON looks like:
.. code-block:: python
[{"func_name": "example.format_id",
"line": 1,
"path": "/absolute/path/to/example.py",
"samples": 0,
"signature": {"arg_types": ["int"], "return_type": "str"}}]
.. option:: --no-errors
Only produce suggestions that cause no errors in the checked code. By default,
mypy will try to find the most precise type, even if it causes some type errors.
.. option:: --no-any
Only produce suggestions that don't contain ``Any`` types. By default mypy
proposes the most precise signature found, even if it contains ``Any`` types.
.. option:: --flex-any FRACTION
Only allow some fraction of types in the suggested signature to be ``Any`` types.
The fraction ranges from ``0`` (same as ``--no-any``) to ``1``.
.. option:: --callsites
Only find call sites for a given function instead of suggesting a type.
This will produce a list with line numbers and types of actual
arguments for each call: ``/path/to/file.py:line: (arg_type_1, arg_type_2, ...)``.
.. option:: --use-fixme NAME
Use a dummy name instead of plain ``Any`` for types that cannot
be inferred. This may be useful to emphasize to a user that a given type
couldn't be inferred and needs to be entered manually.
.. option:: --max-guesses NUMBER
Set the maximum number of types to try for a function (default: ``64``).
Statically inspect expressions
******************************
The daemon allows to get declared or inferred type of an expression (or other
information about an expression, such as known attributes or definition location)
using ``dmypy inspect LOCATION`` command. The location of the expression should be
specified in the format ``path/to/file.py:line:column[:end_line:end_column]``.
Both line and column are 1-based. Both start and end position are inclusive.
These rules match how mypy prints the error location in error messages.
If a span is given (i.e. all 4 numbers), then only an exactly matching expression
is inspected. If only a position is given (i.e. 2 numbers, line and column), mypy
will inspect all *expressions*, that include this position, starting from the
innermost one.
Consider this Python code snippet:
.. code-block:: python
def foo(x: int, longer_name: str) -> None:
x
longer_name
Here to find the type of ``x`` one needs to call ``dmypy inspect src.py:2:5:2:5``
or ``dmypy inspect src.py:2:5``. While for ``longer_name`` one needs to call
``dmypy inspect src.py:3:5:3:15`` or, for example, ``dmypy inspect src.py:3:10``.
Please note that this command is only valid after daemon had a successful type
check (without parse errors), so that types are populated, e.g. using
``dmypy check``. In case where multiple expressions match the provided location,
their types are returned separated by a newline.
Important note: it is recommended to check files with :option:`--export-types`
since otherwise most inspections will not work without :option:`--force-reload`.
.. option:: --show INSPECTION
What kind of inspection to run for expression(s) found. Currently the supported
inspections are:
* ``type`` (default): Show the best known type of a given expression.
* ``attrs``: Show which attributes are valid for an expression (e.g. for
auto-completion). Format is ``{"Base1": ["name_1", "name_2", ...]; "Base2": ...}``.
Names are sorted by method resolution order. If expression refers to a module,
then module attributes will be under key like ``"<full.module.name>"``.
* ``definition`` (experimental): Show the definition location for a name
expression or member expression. Format is ``path/to/file.py:line:column:Symbol``.
If multiple definitions are found (e.g. for a Union attribute), they are
separated by comma.
.. option:: --verbose
Increase verbosity of types string representation (can be repeated).
For example, this will print fully qualified names of instance types (like
``"builtins.str"``), instead of just a short name (like ``"str"``).
.. option:: --limit NUM
If the location is given as ``line:column``, this will cause daemon to
return only at most ``NUM`` inspections of innermost expressions.
Value of 0 means no limit (this is the default). For example, if one calls
``dmypy inspect src.py:4:10 --limit=1`` with this code
.. code-block:: python
def foo(x: int) -> str: ..
def bar(x: str) -> None: ...
baz: int
bar(foo(baz))
This will output just one type ``"int"`` (for ``baz`` name expression).
While without the limit option, it would output all three types: ``"int"``,
``"str"``, and ``"None"``.
.. option:: --include-span
With this option on, the daemon will prepend each inspection result with
the full span of corresponding expression, formatted as ``1:2:1:4 -> "int"``.
This may be useful in case multiple expressions match a location.
.. option:: --include-kind
With this option on, the daemon will prepend each inspection result with
the kind of corresponding expression, formatted as ``NameExpr -> "int"``.
If both this option and :option:`--include-span` are on, the kind will
appear first, for example ``NameExpr:1:2:1:4 -> "int"``.
.. option:: --include-object-attrs
This will make the daemon include attributes of ``object`` (excluded by
default) in case of an ``atts`` inspection.
.. option:: --union-attrs
Include attributes valid for some of possible expression types (by default
an intersection is returned). This is useful for union types of type variables
with values. For example, with this code:
.. code-block:: python
from typing import Union
class A:
x: int
z: int
class B:
y: int
z: int
var: Union[A, B]
var
The command ``dmypy inspect --show attrs src.py:10:1`` will return
``{"A": ["z"], "B": ["z"]}``, while with ``--union-attrs`` it will return
``{"A": ["x", "z"], "B": ["y", "z"]}``.
.. option:: --force-reload
Force re-parsing and re-type-checking file before inspection. By default
this is done only when needed (for example file was not loaded from cache
or daemon was initially run without ``--export-types`` mypy option),
since reloading may be slow (up to few seconds for very large files).
.. TODO: Add similar section about find usages when added, and then move
this to a separate file.
.. _watchman: https://facebook.github.io/watchman/
.. _watchdog: https://pypi.org/project/watchdog/
.. _PyAnnotate: https://github.com/dropbox/pyannotate
.. _mypy plugin for PyCharm: https://github.com/dropbox/mypy-PyCharm-plugin
|