A simple plugin that allows running mypy from PyCharm and navigate between errors

Overview

mypy logo

mypy-PyCharm-plugin

The plugin provides a simple terminal to run fast mypy daemon from PyCharm with a single click or hotkey and easily navigate through type checking results. The idea of the mypy terminal is different from the normal PyCharm type checking that highlights the errors in a current file. The mypy terminal shows errors in all files in your project (even in those not currently open). Also mypy provides a bit stricter type checking and is tunable by various flags and config settings.

mypy plugin screenshot

Installation

The plugin can be installed directly from JetBrains plugin repository

Installing developer build

Requirements for building the plugin:

  • Oracle JDK 8
    • Either javac should be available on your PATH or JAVA_HOME environment variable should contain your JDK installation path

Requirements for running the plugin:

  • Mypy
    • The plugin runs the mypy executable to check types

Installation steps:

  1. Clone the GitHub repository.

  2. Open the cloned directory in your terminal and build it using this shell command:

    ./gradlew clean buildPlugin
    

    or on Windows:

    gradlew clean buildPlugin
    

    The plugin file mypy-PyCharm-plugin.zip will be built in build/distributions.

  3. In PyCharm go to Preferences -> Plugins -> Install plugins from disk -> Select the plugin file -> Restart PyCharm when prompted.

  4. After restart you should find the plugin in View -> Tool windows -> Mypy terminal.

Configuration

Normally, plugin should not require any configuration steps. However, sometimes plugin cannot find dmypy command because it doesn't have the full environment. If the plugin says something like dmypy command not found when you try to run mypy, then this is likely the cause. In this case right click in mypy terminal in PyCharm -> Configure plugin. Then enter the path where mypy is installed as PATH suffix. If you are using a virtual environment, this will look like /my/project/bin (or C:\my\project\Scripts if you are on Windows). If necessary, you can also configure mypy command to use your custom .ini file and flags.

Usage

You can pin the terminal to either side of PyCharm window: click on window toolbar → Move. The current default is bottom, which works best if you typically have only a few errors. If you are working on legacy code with many mypy errors, you may want to use the ‘left’ or ‘right’ setting. Finally, if you have multiple monitors you might find the floating mode convenient.

Currently supported features and keyboard shortcuts:

  • Show/hide mypy terminal: Ctrl + Shift + X
  • Run mypy type checking: Ctrl + Shift + M or click Run
  • Go to error: click on error line, or use Ctrl + Shift + <arrows> to navigate between errors
  • Copy current error: right click → Copy error text, or Ctrl + Shift + C
  • Collapse/expand errors: click on file name in the mypy terminal, or Ctrl + Shift + Enter when a file name is selected
  • Sometimes mypy shows links to online documentation; to follow links use Alt + <click>

Contributing

External contributions to the project should be subject to Dropbox Contributor License Agreement (CLA).

  1. Open the repository in IntelliJ 2019.1 or newer via File -> Open. IntelliJ will import it as a Gradle project.

  2. Set up a project JDK via File -> Project Structure -> Project -> Project SDK. JDK 8 or newer is required.

  3. Build and run the plugin via a Gradle task runIde available as View -> Tool Windows -> Gradle -> Tasks -> intellij -> runIde.


Copyright (c) 2018 Dropbox, Inc.

Comments
  • Error: There are no .py[i] files in directory '.'

    Error: There are no .py[i] files in directory '.'

    I've just installed the plugin and I get this error: There are no .py[i] files in directory '.'

    There are certainly many python files in my directory structure, and I'm hitting 'run' while I have a Python file open. There's even an init.py file in the directory I'm running in.

    I'm unsure what '.' is referring to, but if I specify the full path to the directory I'm trying to scan it does get the files (though it is giving incorrect errors about imports that it can't find, I suspect it can't understand that it should follow the venv/../site-packages/ ?)

    I suspect that there are two issues here:

    1. The '.' is referring to the root of my project, but the Python code is nested multiple folders deep before I get to the init.py

    2. For some reason mypy needs an explicit MYPYPATH for the intellij configured venv

    Regardless, the default installation of this plugin is broken for what I imagine is not an uncommon use case.

    It seems like the plugin should

    • Understand the file being viewed, and override the '.' to be a fully qualified path to that file
    • Set MYPYPATH to the venv automatically

    Assuming I understand the issues correctly.

    opened by insanitybit 15
  • Distribute the plugin via JetBrains plugins repository

    Distribute the plugin via JetBrains plugins repository

    It's more convenient for PyCharm / IntelliJ users to get their plugins as in-app updates via the JetBrains repository. Please consider distributing the plugin via this channel instead of a manual download + install via a file.

    enhancement priority-high 
    opened by vlasovskikh 13
  • Installation errors

    Installation errors

    When loading the mypy-plugin.jar I get the following error:

    Fail to load plugin descriptor from file mypy-plugin.jar

    My Specs PyCharm 2018.1.4 (Professional Edition) Build #PY-181.5087.37, built on May 24, 2018 JRE: 1.8.0_152-release-1136-b39 x86_64 JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o macOS 10.13.5

    opened by nschejtman 10
  • hdpi support

    hdpi support

    On a 4k 15" the font is all messed up (really small).

    image

    PY-182.2574.7, JRE 1.8.0_152-release-1226-b7x64 JetBrains s.r.o, OS Linux(amd64) v4.16.11-1-ARCH unknown, screens 3840x2160

    @ilevkivskyi

    bug 
    opened by gaborbernat 10
  • java.lang.NullPointerException

    java.lang.NullPointerException

    The plugin crashes with a NPE with this mypy output:

    gsi/model.py:101:5: error: Function is missing a type annotation
    gsi/model.py:111:5: error: Function is missing a type annotation
    gsi/model.py:119:5: error: Function is missing a type annotation
    gsi/model.py:160:5: error: Function is missing a type annotation
    gsi/model.py:169:80: error: Call to untyped function "Processor" in typed context
    gsi/model.py:174:5: error: Function is missing a type annotation
    gsi/model.py:187:5: error: Function is missing a type annotation
    gsi/model.py:195: error: Function is missing a type annotation
    gsi/model.py:196:34: error: Call to untyped function "CpuInfo" in typed context
    gsi/model.py:197:36: error: Call to untyped function "MoboInfo" in typed context
    gsi/repository.py:43:1: error: Function is missing a type annotation
    gsi/repository.py:72:1: error: Function is missing a type annotation
    gsi/repository.py:79: error: Function is missing a type annotation
    gsi/repository.py:87:9: warning: Returning Any from function declared to return "Optional[CpuDbModel]"
    gsi/repository.py:93: error: The return type of "__init__" must be None
    gsi/repository.py:93: error: Function is missing a return type annotation
    gsi/repository.py:98: error: Function is missing a type annotation for one or more arguments
    gsi/repository.py:124:5: error: Function is missing a return type annotation
    gsi/repository.py:139:9: error: Incompatible types in assignment (expression has type "None", variable has type "Processor")
    gsi/repository.py:146:38: error: Call to untyped function "Processor" in typed context
    gsi/repository.py:148:17: error: Call to untyped function "__parse_data" in typed context
    gsi/repository.py:157:17: error: Argument 2 to "__update_processor_with_cpu" of "ProcCpuinfoRepository" has incompatible type "Optional[CpuDbModel]"; expected "CpuDbModel"
    gsi/repository.py:167:5: error: Function is missing a type annotation
    gsi/repository.py:178:47: error: Call to untyped function "clean_cpu_string" in typed context
    gsi/repository.py:183: error: Function is missing a return type annotation
    gsi/repository.py:206: error: Function is missing a type annotation
    gsi/repository.py:213:5: error: Function is missing a return type annotation
    gsi/repository.py:230:17: error: Call to untyped function "__read_cache_info" in typed context
    gsi/repository.py:233:19: error: Call to untyped function "__update_cache_count" in typed context
    gsi/repository.py:243: error: Function is missing a type annotation
    gsi/repository.py:245:21: error: Call to untyped function "Cache" in typed context
    gsi/repository.py:265: error: Function is missing a type annotation
    gsi/repository.py:266:9: error: Incompatible types in assignment (expression has type "None", variable has type "Cache")
    gsi/repository.py:267:9: error: Incompatible types in assignment (expression has type "None", variable has type "Cache")
    gsi/repository.py:268:9: error: Incompatible types in assignment (expression has type "None", variable has type "Cache")
    gsi/repository.py:269:9: error: Incompatible types in assignment (expression has type "None", variable has type "Cache")
    gsi/repository.py:294: error: Function is missing a type annotation
    gsi/repository.py:301:5: error: Function is missing a return type annotation
    gsi/util.py:109:5: warning: Returning Any from function declared to return "Optional[str]"
    gsi/util.py:144: error: Syntax error in type annotation
    gsi/util.py:144: note: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn)
    gsi/interactor.py:32: error: The return type of "__init__" must be None
    gsi/interactor.py:32: error: Function is missing a return type annotation
    gsi/interactor.py:45: error: The return type of "__init__" must be None
    gsi/interactor.py:45: error: Function is missing a return type annotation
    gsi/interactor.py:58: error: The return type of "__init__" must be None
    gsi/interactor.py:58: error: Function is missing a return type annotation
    gsi/interactor.py:70: error: Function is missing a type annotation
    gsi/interactor.py:73:5: error: Function is missing a type annotation
    gsi/presenter.py:35:5: error: Function is missing a type annotation
    gsi/presenter.py:38:5: error: Function is missing a type annotation
    gsi/presenter.py:41:5: error: Function is missing a type annotation
    gsi/presenter.py:44:5: error: Function is missing a return type annotation
    gsi/presenter.py:47:5: error: Function is missing a return type annotation
    gsi/presenter.py:50:5: error: Function is missing a type annotation
    gsi/presenter.py:53:5: error: Function is missing a type annotation
    gsi/presenter.py:56:5: error: Function is missing a type annotation
    gsi/presenter.py:59:5: error: Function is missing a type annotation
    gsi/presenter.py:66: error: The return type of "__init__" must be None
    gsi/presenter.py:66: error: Function is missing a return type annotation
    gsi/presenter.py:74:9: error: Incompatible types in assignment (expression has type "None", variable has type "ViewInterface")
    gsi/presenter.py:81:5: error: Function is missing a type annotation
    gsi/presenter.py:96:5: error: Function is missing a type annotation
    gsi/presenter.py:109:5: error: Function is missing a type annotation
    gsi/presenter.py:112:5: error: Function is missing a type annotation
    gsi/presenter.py:115:5: error: Function is missing a type annotation
    gsi/presenter.py:118:5: error: Function is missing a type annotation
    gsi/presenter.py:121:5: error: Function is missing a type annotation
    gsi/presenter.py:124:5: error: Function is missing a type annotation
    gsi/presenter.py:127:5: error: Function is missing a type annotation
    gsi/presenter.py:143: error: Function is missing a type annotation for one or more arguments
    gsi/view.py:40: error: The return type of "__init__" must be None
    gsi/view.py:40: error: Function is missing a return type annotation
    gsi/view.py:50:9: error: Call to untyped function "__init_widgets" in typed context
    gsi/view.py:52:5: error: Function is missing a type annotation
    gsi/view.py:62:5: error: Function is missing a type annotation
    gsi/view.py:65:5: error: Function is missing a type annotation
    gsi/view.py:73:5: error: Function is missing a type annotation
    gsi/view.py:78:5: error: Function is missing a type annotation
    gsi/view.py:82:5: error: Function is missing a return type annotation
    gsi/view.py:85:13: error: Call to untyped function "init_system_info" in typed context
    gsi/view.py:87:5: error: Function is missing a return type annotation
    gsi/view.py:90:13: error: Call to untyped function "init_system_info" in typed context
    gsi/view.py:92:5: error: Function is missing a type annotation
    gsi/view.py:95:5: error: Function is missing a type annotation
    gsi/view.py:98:5: error: Function is missing a type annotation
    gsi/view.py:101:5: error: Function is missing a type annotation
    gsi/view.py:104:5: error: Function is missing a return type annotation
    gsi/view.py:127:13: error: Argument 2 to "__set_entries_with_label_text" of "View" has incompatible type "Dict[str, Optional[str]]"; expected "Dict[str, str]"
    gsi/view.py:133:13: error: Argument 2 to "__set_entries_with_label_text" of "View" has incompatible type "Dict[str, Optional[str]]"; expected "Dict[str, str]"
    gsi/view.py:139:13: error: Argument 2 to "__set_entries_with_label_text" of "View" has incompatible type "Dict[str, Optional[str]]"; expected "Dict[str, str]"
    gsi/view.py:145:13: error: Argument 2 to "__set_entries_with_label_text" of "View" has incompatible type "Dict[str, Optional[str]]"; expected "Dict[str, str]"
    gsi/view.py:170:5: error: Function is missing a return type annotation
    gsi/view.py:182:5: error: Function is missing a return type annotation
    gsi/view.py:194:5: error: Function is missing a return type annotation
    gsi/view.py:205:5: error: Function is missing a return type annotation
    gsi/view.py:216:5: error: Function is missing a return type annotation
    gsi/view.py:225:5: error: Function is missing a return type annotation
    gsi/view.py:240:5: error: Function is missing a return type annotation
    gsi/view.py:256:5: error: Function is missing a return type annotation
    gsi/app.py:33: error: The return type of "__init__" must be None
    gsi/app.py:33: error: Function is missing a return type annotation
    gsi/app.py:33: error: Function is missing a type annotation for one or more arguments
    gsi/app.py:54:5: error: Function is missing a type annotation
    gsi/app.py:64:5: error: Function is missing a type annotation
    gsi/app.py:67:5: error: Function is missing a type annotation
    

    Stacktrace:

    java.lang.NullPointerException
    	at javax.swing.JComponent.scrollRectToVisible(JComponent.java:3109)
    	at com.dropbox.plugins.mypy_plugin.MypyRunner.runMypyDaemon(MypyRunner.java:86)
    	at com.dropbox.plugins.mypy_plugin.MypyTerminal$10.run(MypyTerminal.java:344)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    	at java.lang.Thread.run(Thread.java:745)
    

    mypy.ini

    [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
    
    show_column_numbers=True
    
    # show error messages from unrelated files
    follow_imports=skip
    
    # suppress errors about unsatisfied imports
    ignore_missing_imports=True
    
    # be strict
    disallow_untyped_calls=True
    warn_return_any=True
    strict_optional=True
    warn_no_return=True
    warn_redundant_casts=True
    warn_unused_ignores=True
    
    # The following are off by default.  Flip them on if you feel
    # adventurous.
    disallow_untyped_defs=True
    check_untyped_defs=True
    
    # No incremental mode
    cache_dir=/dev/null
    

    PyCharm 2018.2.1 (Community Edition) Build #PC-182.3911.33, built on August 5, 2018 JRE: 1.8.0_152-release-1248-b8 amd64 JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o Linux 4.15.0-32-generic

    bug priority-high 
    opened by leinardi 7
  • /bin/bash: dmypy: command not found

    /bin/bash: dmypy: command not found

    This is with PyCharm 2018.1.3 CE on macOS High Sierra 10.13.4, Python 3.6.1, mypy 0.600.

    In a regular bash:

    $ which mypy
    /Library/Frameworks/Python.framework/Versions/3.6/bin/mypy
    $ which dmypy
    /Library/Frameworks/Python.framework/Versions/3.6/bin/dmypy
    

    So everything seems to be fine, except that the plugin can't find dmypy. Could it be that the plugin is using the wrong Python version (Macs also have a Python 2.7 version)?

    opened by fniessink 6
  • Installation Instructions?

    Installation Instructions?

    Hi, wanted to use it. Can't find it in Pycharm plugins or repositories. Could you please add installation? I also downloaded the repo and trying to import setting mypy-plugin.jar, It didn't work. Please let me know if I am doing something wrong.

    Thanks :)

    opened by vinitkumar 6
  • MyPy plugin doesn't work when the Python interpreter (and MyPy installation) are in a dockerized Python

    MyPy plugin doesn't work when the Python interpreter (and MyPy installation) are in a dockerized Python

    The plugin works fine if we use base system python or a virtual environment, however, if the Project's interpreter is running from Docker or a docker-compose configuration, the plugin doesn't seem to run.

    I have a Python interpreter running from a Docker-Compose image. The image contains Python 3.6 and the MyPy library.

    When you try to run the plugin you get a bubble:

    Mypy Plugin
    No Pythion interpreter is configured for the project.
    Configure Python interpreter
    

    If you click on "Configure Python Interpreter" it takes you to the Project Interpreter settings, however, there already is a Python interpreter for the project.

    opened by salimfadhley 5
  • Cannot run Program under Windows

    Cannot run Program under Windows

    A Plugin Exeption was raised after hitting the Run button: Cannot run program "/bin/bash" (in directory "...my project directory..."): \dev\null (The system cannot find the specified path.)

    My System: Windows 7 PyCharm Professional 2018.1 Python 3.6 (Anaconda)

    enhancement priority-high 
    opened by stschroe 5
  • 'dmypy' is not recognized as an internal or external command, operable program or batch file.

    'dmypy' is not recognized as an internal or external command, operable program or batch file.

    Hello,

    I would like to ask for your kind support.

    My problem is that: 'dmypy' is not recognized as an internal or external command, operable program or batch file.

    I have Windows10 and Python 3.8, PyCharm with mypy-PyCharm-plugin installed from Marketplace.

    dmypy

    Thanks for your help in advance.

    opened by mozesa 4
  • Change plugin display name

    Change plugin display name

    This is in preparation to publishing this on JetBrains repo.

    Note:

    • The word "plugin" should not appear in the display name
    • Each display name should be unique there, and "Mypy" is already taken (and the author prefers to keep it)
    • This will be considered as an update for existing installs, since the plugins are identified by id in PyCharm

    @JukkaL @msullivan @gvanrossum I think I discussed this with, but just to double-check I tag you here.

    opened by ilevkivskyi 4
  • Very slow on large projects

    Very slow on large projects

    This plugin is very slow on larger projects. It can sometimes hang or crash pycharm.

    I am running Pop OS with 8gb ram and core i5 5th gen (Macbook air 2017). PyCharm was fast until I installed the plugin.

    opened by arnu515 0
  • Can't configure which folder (d)mypy is run from

    Can't configure which folder (d)mypy is run from

    Mypy seems to have problems with Django projects containing multiple apps, not being able to follow imports to the other apps when running from the root directory. I've already filed a ticket with mypy itself about this, but there's no answer there yet.

    A workaround I've found using the console that when I cd into the main source folder instead of the project root and list all apps manually, the imports work as expected. However, that's not possible with the mypy plugin, and I hate having to switch out of my IDE just for running mypy when a plugin already exists - adding the option to choose where to run mypy from should be easy to configure. I've already tried appending cd <foldername>; to the mypy command, but that doesn't work (error: The system cannot find the path specified.). It works just fine if the command field only contains the cd command, without mypy, but combining both doesn't work.

    The reason why the project root is not the source root in my case is that I have a multilanguage project (Python / Django for the backend, Typescript / ReactJS for the frontend).

    opened by LanDinh 2
  • Does not work with intellij IDEA

    Does not work with intellij IDEA

    Hi there, I tried to make this plugin work with intelliJ idea but there is simply no way to configure the plugin from within the IDE - right clicking the terminal does nothing in IDEA. Could you guy please expose a proper configuration in the preferences for the plugin?

    opened by Goldziher 1
  • Automatically detect dmypy in virtualenv/conda

    Automatically detect dmypy in virtualenv/conda

    Using virtualenv or conda, the user needs to manually select dmypy which is a bit annoying. it would be great if the plugin could detect it automatically.

    opened by omry 1
Owner
Dropbox
Dropbox
A simple program which checks Python source files for errors

Pyflakes A simple program which checks Python source files for errors. Pyflakes analyzes programs and detects various errors. It works by parsing the

Python Code Quality Authority 1.2k Dec 30, 2022
A framework for detecting, highlighting and correcting grammatical errors on natural language text.

Gramformer Human and machine generated text often suffer from grammatical and/or typographical errors. It can be spelling, punctuation, grammatical or

Prithivida 1.3k Jan 8, 2023
Mypy stubs, i.e., type information, for numpy, pandas and matplotlib

Mypy type stubs for NumPy, pandas, and Matplotlib This is a PEP-561-compliant stub-only package which provides type information for matplotlib, numpy

Predictive Analytics Lab 194 Dec 19, 2022
:sparkles: Surface lint errors during code review

✨ Linty Fresh ✨ Keep your codebase sparkly clean with the power of LINT! Linty Fresh parses lint errors and report them back to GitHub as comments on

Lyft 183 Dec 18, 2022
open source tools to generate mypy stubs from protobufs

mypy-protobuf: Generate mypy stub files from protobuf specs We just released a new major release mypy-protobuf 2. on 02/02/2021! It includes some back

Dropbox 527 Jan 3, 2023
Easy saving and switching between multiple KDE configurations.

Konfsave Konfsave is a config manager. That is, it allows you to save, back up, and easily switch between different (per-user) system configurations.

null 42 Sep 25, 2022
A plugin for Flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle.

flake8-bugbear A plugin for Flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycode

Python Code Quality Authority 869 Dec 30, 2022
Pylint plugin for improving code analysis for when using Django

pylint-django About pylint-django is a Pylint plugin for improving code analysis when analysing code using Django. It is also used by the Prospector t

Python Code Quality Authority 544 Jan 6, 2023
❄️ A flake8 plugin to help you write better list/set/dict comprehensions.

flake8-comprehensions A flake8 plugin that helps you write better list/set/dict comprehensions. Requirements Python 3.6 to 3.9 supported. Installation

Adam Johnson 398 Dec 23, 2022
Flake8 plugin that checks import order against various Python Style Guides

flake8-import-order A flake8 and Pylama plugin that checks the ordering of your imports. It does not check anything else about the imports. Merely tha

Python Code Quality Authority 270 Nov 24, 2022
flake8 plugin that integrates isort

Flake8 meet isort Use isort to check if the imports on your python files are sorted the way you expect. Add an .isort.cfg to define how you want your

Gil Forcada Codinachs 139 Nov 8, 2022
Flake8 plugin to find commented out or dead code

flake8-eradicate flake8 plugin to find commented out (or so called "dead") code. This is quite important for the project in a long run. Based on eradi

wemake.services 277 Dec 27, 2022
A Pylint plugin to analyze Flask applications.

pylint-flask About pylint-flask is Pylint plugin for improving code analysis when editing code using Flask. Inspired by pylint-django. Problems pylint

Joe Schafer 62 Sep 18, 2022
flake8 plugin to run black for checking Python coding style

flake8-black Introduction This is an MIT licensed flake8 plugin for validating Python code style with the command line code formatting tool black. It

Peter Cock 146 Dec 15, 2022
A plugin for Flake8 that checks pandas code

pandas-vet pandas-vet is a plugin for flake8 that provides opinionated linting for pandas code. It began as a project during the PyCascades 2019 sprin

Jacob Deppen 146 Dec 28, 2022
flake8 plugin to catch useless `assert` statements

flake8-useless-assert flake8 plugin to catch useless assert statements Download or install on the PyPI page Violations Code Description Example ULA001

null 1 Feb 12, 2022
Simple Python style checker in one Python file

pycodestyle (formerly called pep8) - Python style guide checker pycodestyle is a tool to check your Python code against some of the style conventions

Python Code Quality Authority 4.7k Jan 1, 2023
Mylint - My really simple rendition of how a linter works.

mylint My really simple rendition of how a linter works. This original version was written for my AST article. Since then I've added tests and turned

Tushar Sadhwani 2 Dec 29, 2021
Optional static typing for Python 3 and 2 (PEP 484)

Mypy: Optional Static Typing for Python Got a question? Join us on Gitter! We don't have a mailing list; but we are always happy to answer questions o

Python 14.4k Jan 8, 2023