-
-
Save BradyHu/f4dc997d4b53f9b23e1120940fb8f0d1 to your computer and use it in GitHub Desktop.
| #! /usr/bin python3 | |
| # -*- coding:utf-8 -*- | |
| """ | |
| Add mypy type-checking ability to jupyter/ipython. | |
| Save this script to your ipython profile's startup directory. | |
| IPython's directories can be found via `ipython locate [profile]` to find the current ipython directory and ipython profile directory, respectively. | |
| For example, this file could exist on a path like this on mac: | |
| /Users/yourusername/.ipython/profile_default/startup/typecheck.py | |
| where /Users/yourusername/.ipython/profile_default/ is the ipython directory for the default profile. | |
| and the jupyter/ipython shell will do typecheck automatically. | |
| """ | |
| import re | |
| from IPython import get_ipython | |
| mypy_cells = '' | |
| mypy_shell = get_ipython() | |
| mypy_tmp_func = mypy_shell.run_cell | |
| mypy_typecheck=True | |
| def mypy_tmp(cell,*args,**kwargs): | |
| if mypy_typecheck: | |
| from mypy import api | |
| global mypy_cells | |
| mypy_cells_length = len(mypy_cells.split('\n'))-1 | |
| mypy_cells+=(cell+'\n') | |
| mypy_result = api.run(['-c', mypy_cells]) | |
| if mypy_result[0]: | |
| for line in mypy_result[0].strip().split('\n'): | |
| l,n,r = re.compile('(<[a-z]+>:)(\d+)(.*?)$').findall(line)[0] | |
| if int(n)>mypy_cells_length: | |
| n = str(int(n)-mypy_cells_length) | |
| print("".join([l,n,r])) | |
| if mypy_result[1]: | |
| print(mypy_result[1]) | |
| return mypy_tmp_func(cell,*args,**kwargs) | |
| mypy_shell.run_cell = mypy_tmp |
... works for a single run-through but not optimal for interactive use: mypy_cells keeps growing. Should be tracking cell modifications and deletions. Another question is - which cells should be re-evaluated by mypy to create the context for the current cell? All cells in the notebook? Perhaps not; maybe all cells with a magic marker.
The standard operating mechanism for a jupyter notebook is that the context for evaluating the current cell is precisely evaluating all previous cells in the order in which they were evaluated. Clearly any type-checking must use the same semantics.
I'm working on a facility based on this, to have some interactive use. It is internal for now, but I'll share it when I can.
Thanks for the initial gist btw!
We've made it into an iPython extension, which can be found here: https://pypi.org/project/nb-mypy/
... works for a single run-through but not optimal for interactive use: mypy_cells keeps growing. Should be tracking cell modifications and deletions. Another question is - which cells should be re-evaluated by mypy to create the context for the current cell? All cells in the notebook? Perhaps not; maybe all cells with a magic marker. This functionality could be folded into a jupyter extension.