/mypy-upgrade

automatic error suppression for mypy

Primary LanguagePythonMIT LicenseMIT

mypy-upgrade

PyPI - Version PyPI - Python Version Wheel Support Supported Implementations Hatch project linting - Ruff code style - Black types - Mypy Tests Coverage License - MIT


Table of Contents

What is mypy-upgrade?

mypy-upgrade provides automatic error suppression for mypy (analogous to pyre-upgrade and pylint-silent). In addition, mypy-upgrade exposes an API with the same functionality.

Given a type checking report from mypy, mypy-upgrade will silence the listed errors using error suppression comments. For example, with the following output from mypy:

package/subpackage/module.py:13: error: Incompatible default for argument "filename" (default has type "None", argument has type "str") [assignment]

mypy-upgrade will place a # type: ignore[assignment] # FIX ME comment at the end of line 13 in package/subpackage/module.py. If error codes are not present in the mypy report (e.g., the --hide-error-codes flag is set when mypy was invoked), then a non-specific # type: ignore # FIX ME comment will be added instead.

Features

  • Removal of unused type: ignore comments

  • Replacement of blanket type: ignore comments with error code-specific comments

  • Support for suppressing multiple mypy errors per-line

  • Preservation of existing in-line comments

  • Optional inclusion of mypy error description messages

  • Selective suppression of type errors by file, directory, package, module, or mypy error codes

Quick Start

mypy-upgrade can be installed via pip.

python3 -m pip install mypy-upgrade

If you want to run the latest version of the code, you can install from the repo directly:

python3 -m pip install -U git+https://github.com/ugognw/mypy-upgrade.git@development
# or if you don't have 'git' installed
python3 -m pip install -U https://github.com/ugognw/mypy-upgrade/tree/development

Basic Usage

There are two idioms for invocation. To silence all errors in a package, one can:

  1. pipe mypy's output directly to mypy-upgrade

     mypy --strict -p my_package | mypy-upgrade
    
  2. create a mypy type checking report text file

     mypy --strict -p my_package > mypy_report.txt
    

    and then pass the file to mypy-upgrade

     mypy-upgrade --report mypy_report.txt
    

Advanced Usage

You may want to include the error messages provided by mypy in the suppression comments so that you can fix them later. You can do so using the -d (or --description-style) option

mypy-upgrade --report mypy_report.txt -d full -p package

You can also customize the "fix me" message placed after the error suppression comment using the --fix-me option

mypy-upgrade --report mypy_report.txt --fix-me "FIX THIS" -p package

To selectively silence errors in packages and modules, use the -p (--package) and -m (--module) options along with the fully qualified module/package name, respectively:

mypy-upgrade --report mypy_report.txt -p package1 -p package2 -m package1.module1 -m package2.module2

Similarly, to selectively silence errors in files and directories, pass them in as positional arguments:

mypy-upgrade --report mypy_report.txt path/to/a/package/ path/to/a/module.py

To selectively silence a particular kind of type error, use the --silence-error option:

mypy-upgrade --report mypy_report.txt --silence-error "type-arg"

For a full list of all options and their descriptions, run mypy-upgrade --help

usage: mypy-upgrade [-h] [-v] [-V] [more options; see below]
                    [-m MODULE] [-p PACKAGE] [-r REPORT] [-s ERROR_CODE] [files ...]

Place in-line comments into files to silence mypy errors.


options:
-h, --help            show this help message and exit
-V, --version         Show program's version number and exit.
--dry-run             Don't actually silence anything, just print what would
                      be.

Printing:
Control what information is printed and how.

-v, --verbose         Control the verbosity. 0=Print warnings and messages
                      for each unsilenced error. 1=Also print messages for
                      each silenced error. 2=Used for debugging. Defaults to
                      0.
-q, --quiet, --suppress-warnings
                      Suppress all warnings. Disabled by default.
-S, --summarize       Print a summary after running. If the verbosity is
                      greater than zero, a detailed summary will also be
                      printed.
-c, --colours         Enable coloured output.

Comment Formatting:
Format how error suppression comments are placed.

-d {full,none}, --description-style {full,none}
                      Specify the style in which mypy error descriptions are
                      expressed in the error suppression comment. Defaults
                      to "none".
--fix-me FIX_ME       Specify a custom 'Fix Me' message to be placed after
                      the error suppression comment. Pass " " to omit a 'Fix
                      Me' message altogether. Defaults to "FIX ME".

Error Filtering:
Specify which errors will be silenced.

-r REPORT, --report REPORT
                      The path to a text file containing a mypy type
                      checking report. If not specified, input is read from
                      standard input.
-m MODULE, --module MODULE
                      Silence errors from the provided (importable) module.
                      This flag may be repeated multiple times.
-p PACKAGE, --package PACKAGE
                      Silence errors from the provided (importable) package.
                      This flag may be repeated multiple times.
-s ERROR_CODE, --silence-error ERROR_CODE
                      Silence mypy errors by error code. This flag may be
                      repeated multiple times.
files                 Silence errors from the provided files/directories.

Using the API

Identical functionality to the command-line utility can be obtained using the API. In addition, one obtains detailed information on the results of running mypy-upgrade. Assuming the mypy type checking report is saved as mypy_report.txt, we have

import pathlib

from mypy_upgrade.silence import silence_errors_in_report

mypy_report = pathlib.Path("mypy_report.txt")

with mypy_report.open(mode="r", encoding="utf-8") as report:
    result = silence_errors_in_report(
        report=report,
        packages=["package1", "package2"],
        modules=["package1.module1", "package2.module2"],
        files=["path/to/a/package/", "path/to/a/module.py"],
        description_style="full",
        fix_me="FIX THIS",
        codes_to_silence=["arg-type", "no-untyped-def"],
        dry_run=False,
    )

silenced, failures, ignored = result

Recommended Mypy Flags

To enable all checks utilized by mypy-upgrade to silence as many errors as possible, the following flags should be set when creating the type checking report to pass to mypy-upgrade:

  • --show-absolute-path

    • Required if running mypy-upgrade in a separate directory than mypy
  • --strict

    • Enables mypy-upgrade to silence all possible mypy errors (see Known Limitations for exceptions)
  • --show-error-codes

    • Ensures that error-code specific comments are added instead of blanket type: ignore comments
  • --warn-unused-ignores

    • Ensures that unused type: ignore comments are removed
  • ignore-without-code

    • When used with --show-error-codes, permits mypy-upgrade to replace existing type: ignore comments with code-specific type: ignore comments (enable from the command line with the mypy option --enable-error-code)

Known Limitations

The following limitations derive mainly from Python syntax issues and are unable to be handled by mypy-upgrade. If you can't resolve the error directly, please consider refactoring to permit error suppression.

  • Type errors on lines ending in line continuation characters or within multiline f-strings

    • Comments are not permitted within multiline strings or following line continuation characters and Mypy only recognizes inline type: ignore comments (see #3448)

    • Pre-formatting your code with a PEP8 adherent formatter (e.g., black) to replace such lines with parentheses is recommended.

  • Improperly specified type hints within comments

    • mypy will report a type error if a type hint is improperly specified; for example, given the following code:

        x = {}  # type: set
      

    mypy will produce a type-arg error in column 1 and mypy-upgrade will place a # type: ignore[type-arg] comment at the end, which will, in turn, negate the effectiveness of the # type: set commment and eliminate the need for the # type: ignore[type-arg] comment

  • mypy "syntax" errors are not silenced

    • It is recommended that you fix your code such that it is syntactically valid prior to using mypy-upgrade

Similar Projects

If this doesn't fit your use-case, maybe one of these other projects will!

  • geo7/mypy_clean_slate: mypy reports are generated internally in --strict mode; includes support for suppressing multiple errors on a single line; an inspiration for much of mypy-upgrade's implementation

  • whtsky/mypy-silent: relies solely on typer + the standard library; includes support for removing unused type: ignore comments but no support for suppressing multiple errors on a single line; another inspiration for much of mypy-upgrade's implementation

  • patrick91/mypy-silent: a fork of whtsky/mypy-silent with support for suppressing multiple errors on a single line (on the feature/multiple-errors branch)

  • uptickmetachu/mypy-silent: a fork of whtsky/mypy-silent with support for suppressing multiple errors on a single line