dmypy
Run Mypy type checks via daemon
TLDR
Type check a file, and start the daemon if it is not running
Start the daemon
Type check a file (requires the daemon to be running)
Stop the daemon
SYNOPSIS
dmypy [GLOBAL_OPTIONS] COMMAND [COMMAND_OPTIONS] [FILES...]
Commands:
dmypy run [MYPY_OPTIONS] [FILES...]
dmypy status
dmypy stop
dmypy restart
dmypy kill
dmypy recheck [FILES...]
dmypy check [FILES...]
dmypy configure [MYPY_OPTIONS]
PARAMETERS
--log-file FILE
Specify a file to write daemon logs to. By default, logs go to stderr or a temporary file.
--log-level LEVEL
Set the log level for the daemon. Common levels include info, debug, warning, error.
--unix-socket FILE
Specify the path to the Unix socket for inter-process communication. Overrides the default location (usually in /tmp).
--tcp-port PORT
Specify a TCP port for communication instead of a Unix socket. Useful for remote access or containerized environments.
--pid-file FILE
Specify a file to write the daemon's process ID (PID) to. Useful for process management.
--skip-fine-grained
Skip fine-grained dependency tracking. This can sometimes improve performance at the cost of less precise invalidation.
--verbose
Enable verbose logging output from the daemon.
--timeout SECONDS
Set a timeout for client commands (e.g., run, status) to connect to the daemon. Default is 5 seconds.
run
Starts a mypy daemon (if not running) and then performs a type check using the provided MYPY_OPTIONS and FILES. This is the most commonly used command.
status
Checks and reports the status of the dmypy daemon (running, not running, etc.).
stop
Gracefully stops the running dmypy daemon.
restart
Stops the daemon if running, then starts it again. Useful for applying configuration changes or clearing state.
kill
Forcefully terminates the dmypy daemon process.
recheck [FILES...]
Instructs the daemon to re-check specific files or all files if none are specified. This command often implies that the daemon has already loaded the project.
check [FILES...]
Similar to run, but typically assumes the daemon is already running and configured. It performs a type check and reports errors.
configure [MYPY_OPTIONS]
Applies new mypy configuration options to the running daemon without restarting it. These options will be used for subsequent run or check commands.
--update
(Used with run) Only re-check files that have changed since the last run. This is part of mypy's incremental checking capabilities.
DESCRIPTION
dmypy is a client-server daemon for mypy, the static type checker for Python. Its primary purpose is to significantly speed up incremental type checking by keeping a mypy instance and the Python program's type information in memory across multiple runs. Instead of restarting mypy and reloading all source files for every check, dmypy maintains the necessary state, allowing for much quicker re-checks, especially during development cycles where small changes are made frequently. When a dmypy client command is executed, it communicates with the running dmypy daemon (server) to initiate a type-checking run, obtain the status, or control the daemon's lifecycle. This persistent memory state drastically reduces overhead, making type checking a more integrated and less disruptive part of the development workflow. It's particularly beneficial for large codebases where full mypy runs can be time-consuming.
The daemon can be configured to use either a Unix socket (default) or a TCP port for communication.
CAVEATS
While dmypy significantly speeds up type checking for incremental changes, the initial full run can still take time. It also consumes system resources (memory and CPU) as long as the daemon is running. Ensuring the daemon is stopped when not needed, or restarting it periodically for a clean state, can be beneficial. Compatibility issues with specific mypy versions or project configurations might arise, requiring restarts or debugging through log files. File system events are typically used to detect changes, but in some environments (e.g., network mounts), this detection might not be instantaneous or reliable.
CONFIGURATION AND PROJECT SETUP
dmypy inherits its configuration from your mypy setup (e.g., pyproject.toml, mypy.ini). When you run dmypy, it typically looks for a .dmypy.json file in the current directory or parent directories to determine its operating parameters like socket paths. It's crucial that the daemon is started in the root directory of your project or configured to correctly locate your project's mypy configuration.
DAEMON LIFECYCLE
Managing the dmypy daemon's lifecycle is key to its effective use. You typically start it implicitly with dmypy run for the first time or explicitly with dmypy start (though less common in direct usage). The dmypy stop and dmypy restart commands are essential for resetting its state or applying new global configurations. In CI/CD pipelines or automated environments, ensuring the daemon is properly shut down is important to prevent orphaned processes.
HISTORY
dmypy emerged as a solution to address the performance bottlenecks of mypy in large Python codebases. As static type checking became more prevalent in the Python ecosystem, the time taken for full mypy runs became a significant concern for developers' inner loops. Inspired by similar daemonized type checkers in other languages (e.g., TypeScript's `tsc --watch`), dmypy was developed as part of the mypy project itself to provide a persistent process that could maintain the type analysis state in memory. This allows subsequent checks to only re-analyze changed files and their dependencies, drastically reducing execution time. Its development has been driven by the need for more efficient developer workflows, making static analysis a less intrusive and more integrated part of continuous development.