• This repository has been archived on 20/Jun/2020
  • Stars
    star
    102
  • Rank 335,584 (Top 7 %)
  • Language
    Python
  • License
    MIT License
  • Created over 7 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A plugin for flake8 integrating Mypy.

flake8-mypy

NOTE: THIS PROJECT IS DEAD

It was created in early 2017 when Mypy performance was often insufficient for in-editor linting. The Flake8 plugin traded correctness for performance, making Mypy only check a bare minimum of problems. These days Mypy is accelerated with mypyc, as well as uses aggressive caching to speed up incremental checks. It's no longer worth it to use hacks such as flake8-mypy.

What was the project anyway?

A plugin for Flake8 integrating mypy. The idea is to enable limited type checking as a linter inside editors and other tools that already support Flake8 warning syntax and config.

List of warnings

flake8-mypy reserves T4 for all current and future codes, T being the natural letter for typing-related errors. There are other plugins greedily reserving the entire letter T. To this I say: ¯\_(ツ)_/¯.

T400: any typing note.

T484: any typing error (after PEP 484, geddit?).

T498: internal mypy error.

T499: internal mypy traceback, stderr output, or an unmatched line.

I plan to support more fine-grained error codes for specific mypy errors in the future.

Two levels of type checking

mypy shines when given a full program to analyze. You can then use options like --follow-imports or --disallow-untyped-calls to exercise the full transitive closure of your modules, catching errors stemming from bad API usage or incompatible types. That being said, those checks take time, and require access to the entire codebase. For some tools, like an editor with an open file, or a code review tool, achieving this is not trivial. This is where a more limited approach inside a linter comes in.

Flake8 operates on unrelated files, it doesn't perform full program analysis. In other words, it doesn't follow imports. This is a curse and a blessing. We cannot find complex problems and the number of warnings we can safely show without risking false positives is lower. In return, we can provide useful warnings with great performance, usable for realtime editor integration.

As it turns out, in this mode of operation, mypy is still able to provide useful information on the annotations within and at least usage of stubbed standard library and third party libraries. However, for best effects, you will want to use separate configuration for mypy's standalone mode and for usage as a Flake8 plugin.

Configuration

Due to the reasoning above, by default flake8-mypy will operate with options equivalent to the following:

[mypy]
# Specify the target platform details in config, so your developers are
# free to run mypy on Windows, Linux, or macOS and get consistent
# results.
python_version=3.6
platform=linux

# flake8-mypy expects the two following for sensible formatting
show_column_numbers=True
show_error_context=False

# do not follow imports (except for ones found in typeshed)
follow_imports=skip

# since we're ignoring imports, writing .mypy_cache doesn't make any sense
cache_dir=/dev/null

# suppress errors about unsatisfied imports
ignore_missing_imports=True

# allow untyped calls as a consequence of the options above
disallow_untyped_calls=False

# allow returning Any as a consequence of the options above
warn_return_any=False

# treat Optional per PEP 484
strict_optional=True

# ensure all execution paths are returning
warn_no_return=True

# lint-style cleanliness for typing needs to be disabled; returns more errors
# than the full run.
warn_redundant_casts=False
warn_unused_ignores=False

# The following are off by default since they're too noisy.
# Flip them on if you feel adventurous.
disallow_untyped_defs=False
check_untyped_defs=False

If you disagree with the defaults above, you can specify your own mypy configuration by providing the --mypy-config= command-line option to Flake8 (with the .flake8/setup.cfg equivalent being called mypy_config). The value of that option should be a path to a mypy.ini or setup.cfg compatible file. For full configuration syntax, follow mypy documentation.

For the sake of simplicity and readability, the config you provide will fully replace the one listed above. Values left out will be using mypy's own defaults.

Remember that for the best user experience, your linter integration mode shouldn't generally display errors that a full run of mypy wouldn't. This would be confusing.

Note: chaing the follow_imports option might have surprising effects. If the file you're linting with Flake8 has other files around it, then in "silent" or "normal" mode those files will be used to follow imports. This includes imports from typeshed.

Tests

Just run:

python setup.py test

OMG, this is Python 3 only!

Yes, so is mypy. Relax, you can run Flake8 with all popular plugins as a tool perfectly fine under Python 3.5+ even if you want to analyze Python 2 code. This way you'll be able to parse all of the new syntax supported on Python 3 but also effectively all the Python 2 syntax at the same time.

By making the code exclusively Python 3.5+, I'm able to focus on the quality of the checks and re-use all the nice features of the new releases (check out pathlib) instead of wasting cycles on Unicode compatibility, etc.

License

MIT

Change Log

17.8.0

  • avoid raising errors in the default config which don't happen during a full run (disable warn_unused_ignores and warn_redundant_casts)

  • always run type checks from a temporary directory to avoid clashing with unrelated files in the same directory

17.3.3

  • suppress mypy messages about relative imports

17.3.2

  • bugfix: using Flake8 with absolute paths now correctly matches mypy messages

  • bugfix: don't crash on relative imports in the form from . import X

17.3.1

  • switch follow_imports from "silent" to "skip" to avoid name clashing files being used to follow imports within typeshed

  • set MYPYPATH by default to give stubs from typeshed higher priority than local sources

17.3.0

  • performance optimization: skip running mypy over files that contain no annotations or imports from typing

  • bugfix: when running over an entire directory, T484 is now correctly used instead of T499

17.2.0

  • first published version

  • date-versioned

Authors

Glued together by Łukasz Langa.

More Repositories

1

bitrot

Detects bit rotten files on the hard drive to save your precious photo and music collection from slow decay.
Python
186
star
2

retype

Re-apply type annotations from .pyi stubs to your codebase.
Python
134
star
3

aiotone

A demo of using AsyncIO for music sequencing
Python
105
star
4

dj.choices

An enum implementation for Django forms and models
Python
30
star
5

commonplace

A basic Python-based publishing platform based around the idea of commonplace books
Python
29
star
6

kitdjango

lck.django: a reusable library of typical Django routines, apps, filters, template tags and configuration techniques.
Python
26
star
7

httproxy

Tiny HTTP proxy based on work by Suzuki Hisao and Mitko Haralanov
Python
24
star
8

fm-demo

FM synthesis in Python from scratch, accompanying my PyCon US 2021 talk
Python
23
star
9

dj.chain

An object that enables chaining multiple iterables to serve them lazily as a queryset-compatible object.
Python
21
star
10

.dot_files

My distributed configuration
Shell
17
star
11

aioecho

A non-broken echo protocol example for asyncio
Python
16
star
12

static-annotations

PEP 563: Postponed Evaluation of Annotations
15
star
13

cpython-stats

Gathering stats about python/cpython
Python
15
star
14

singledispatch

Implements PEP443. This is a synchronized copy from Bitbucket kept for Travis support.
Python
11
star
15

rename

Renames files using regular expression matching. This enables elegant handling of multiple renames using a single command.
Python
7
star
16

gha-issuenumber

A GitHub action that enforces all commits have issue numbers linked
Python
6
star
17

requests-testadapter

An adapter for unit testing with requests
Python
5
star
18

requests-robotstxt

Support for robots.txt in a requests Session
Python
4
star
19

kitpy

lck.common: A library of various simple common routines that keep being rewritten all over again in every project we're working on.
Python
4
star
20

kiti18n

lck.i18n: a reusable library of typical i18n routines.
Python
4
star
21

oblique

Shows koans from Oblique Strategies.
Python
3
star
22

benchmark-annotations

A very simple benchmark of `from __future__ import annotations`
Python
3
star
23

spectro

Creates a spectrogram PNG suited for synchronized Full HD display.
Python
3
star
24

modalcommands

Custom commands for vscode-modaledit
TypeScript
2
star
25

django-crystal-big

Everaldo's Crystal icons bundled for direct consumption from Django applications
Python
2
star
26

django-crystal-small

Everaldo's Crystal icons bundled for direct consumption from Django applications. Sizes up to 48x48.
Python
2
star
27

gol

Game of Life talk material from EuroPython 2023
Python
2
star
28

casecheck

Lists all paths that would clash on a case-insensitive filesystem.
Python
1
star
29

thingsweforget-fetcher

Synchronization of images at thingsweforget.blogspot.com for offline use
Python
1
star
30

mudmafia

Managing extortion.
Python
1
star
31

zamawiacz

Simplistic application for managing orders in a shop. Made for a specific client, not meant to be generic.
Python
1
star
32

null

Implements the null object pattern. This is a synchronized copy from Bitbucket kept for Travis support.
Python
1
star
33

dj

This is just a namespace package for Django-related packages. Feel free to use it.
Python
1
star