python / mypy

Optional static typing for Python
https://www.mypy-lang.org/
Other
18.56k stars 2.84k forks source link

Question: Mypy day to day tips/tricks #971

Closed EntilZha closed 8 years ago

EntilZha commented 9 years ago

I am just starting to use mypy and PEP484 type hints since I was tired of not having types to reason about/auto check. I am wondering what do common users have in their day to day use that makes it easier.

The docs point primarily to mypy filename.py.

  1. Is there a way to auto run it on detecting file change?
  2. Is there a way to run it on a module or specify something like mypy packagename/*.py to run on everything (I know this could be done with a bash script, but builtin would be nice). (found -m, but it doesn't seem to be returning any errors at all)
  3. I get some pretty common errors about mypy throwing a No module named 'modulename' which are pip packages I have installed like numpy, sklearn, etc. How can you fix this?
  4. It seems like mypy treats np.array as Any, is there a good workaround for this, or is it a bug?
  5. Any general tips/tricks?

For some of these things, I would be willing to contribute a patch if it doesn't exist already.

refi64 commented 9 years ago

For 1, on Linux, you can do:

while inotifywait -e close_write filename.py; do mypy filename.py; done
EntilZha commented 9 years ago

Thanks @kirbyfan64, that should do the trick.

I looked more into 3, is it possibly because the libraries I am importing don't have stub files? For larger projects like numpy/sklearn/etc, do you know if the plan on adding them, or is it a better idea to write a few short ones for only the things I use?

I also maintain a library I would like to write stub files for, anything I should know beyond the docs?

JukkaL commented 9 years ago

3: You can try using the --use-python-path argument or MYPYPATH to let mypy look into installed packages, but this still has known issues (#638 is about addressing these, at least for non-C modules). Alternatively, you can look into mypy/stubgen.py in the git repo which can generate library stubs for you. This is experimental but it works in many cases.

4: Properly type checking code using numpy (and many third party modules) is currently not supported. Numpy, in particular, would require some new type system features and is not trivial to support. This is something I'd like to have but we don't have resources to work on this in the near future, and other modules like SQLAlchemy, Flask and Tornado are higher on the priority list :-(

fiatjaf commented 9 years ago

About 3:

  1. I get some pretty common errors about mypy throwing a No module named 'modulename' which are pip packages I have installed like numpy, sklearn, etc. How can you fix this?

Could it be possible to add an option to not check for modules, or simply assume all modules exist and all methods on these modules exist and are valid? I'm using mypy with Syntastic inside vim, and I think it is impossible to make it stop complaining. --use-python-path and MYPYPATH will not work because my packages are in a project-specific virtualenv directory and mypy is installed globally.

ecprice commented 9 years ago

You can try adding # mypy: weak=import at the top of the file, which I think will do what you want. Note that this behavior is pretty experimental, so the interface will change in the future.

JukkaL commented 9 years ago

More about 3: You can always annotate every import with missing stub using # type: ignore and mypy will not complain about that import any more. Example:

import numpy # type: ignore
# now you can use numpy, as the name numpy has an implicit Any type

We don't have a perfect story for missing stub files. Here are some things we could consider:

  1. Collect a list of 1000 most popular third party packages (+ std lib modules) without stubs and teach mypy to not complain about them, and instead just silently ignore imports targeting those modules. Everything imported from those modules would get type Any.
  2. (Together with 1) Also support a 'strict' type checking mode, which can be enabled on a file-by-file basis (using something like # mypy: strict, maybe) or for the entire program. In this mode missing stub files are an error that needs to be explicitly ignored.
  3. Support -p <python-binary> option for mypy, where <python-binary> can point to any Python interpreter (in a venv or not, Python 2 or 3). Mypy will use that Python interpreter to look for the implementations of module files and automatically generate stubs for C extension modules. All type errors from modules found in this fashion will be ignored.
  4. (Together with 3) Teach mypy about 3rd party modules for which automatic stub generation or analysis fails for whatever reason (such as PyQt, I think) and fall back to ignoring those modules silently.
  5. Support something like mypy --ignore-modules=numpy to ignore a given set of modules without stubs.
  6. Additionally, support a config file such as .mypyconfig where you can define things like ignore-modules=numpy to ignore an arbitrary set of modules.
  7. Have a CI build that verifies that mypy doesn't crash or complain when importing the newest version of any of the top 1000 most common modules.

(The number is 1000 is, of course, totally arbitrary and we could choose any reasonable number.)

Any thoughts about these?

fiatjaf commented 9 years ago

Thank you very much! I'm pretty happy with these solutions for ignoring modules (but surely my use-case is simple and modest).

tony commented 8 years ago

Something similar has been done before with JS and TypeScript and wanted to make a note about it.

Its not realistic to contribute type definitions upstream to JavaScript libraries that already exist, so they have DefinitlyTyped, their github is at https://github.com/DefinitelyTyped/DefinitelyTyped. They made it into a community effort and its pretty successful for them.

They also have a package manager for definitions: http://definitelytyped.org/tsd/

gvanrossum commented 8 years ago

For PEP 484 we have typeshed: https://github.com/python/typeshed -- it's shared between mypy, pytype, and PyCharm.

gvanrossum commented 8 years ago

Let's close this. I think most ideas here have been implemented or have their own issue tracking them. If you disagree, please open a new issue for specific issues.