mypy icon indicating copy to clipboard operation
mypy copied to clipboard

Running mypy on doctests

Open sobolevn opened this issue 6 years ago • 3 comments

Hi!

I am trying to make a custom tool to run mypy on doctests inside my project. Because I want to be sure that my examples are correct. And since pytest / doctest modules do it with ease I am seeking the similar solution but for types. Examples, where I need this:

  • https://github.com/dry-python/classes/blob/master/docs/pages/concept.rst
  • https://github.com/dry-python/returns/blob/master/returns/result.py#L135

So, I have started with using api. It works fine, but requires to create temp files with extracted doctest code contents. This is a working solution, but the only ugly part is that it is based on temporary files. And reports incorrect filenames, locations, etc.

I have tried to go deeper and pass just the source code / ast parts. But, it does not look like it works this way. Is there a way to make it work without touching a lot of protected / private APIs?

Maybe this can be implemented in mypy itself at sometime?

Thanks!

sobolevn avatar Nov 18 '19 14:11 sobolevn

Using a mypy plugin hook for this may be an option, though no existing hook seems to fit the bill.

The existing API may be enough to get the right kind of output however. One idea would be to include empty lines to align line numbers. Another idea would be to have a postprocessing step that translates the files names in mypy output. It's a bit hacky, but it has the benefit of working right now.

JukkaL avatar Nov 18 '19 14:11 JukkaL

I did both (align numbers and translate file names) here. It ain't great (it still uses temporary files), but it works. Bear in mind that I only spent a couple hours hacking this together, so reserve judgment. Improvements are likely many and obvious. Suggestions are invited.

% cat -n doctest.txt
     1  Ready to have your mind blown? Check *this* out!
     2
     3  >>> a = 0
     4  >>> a = "zero"  # <- typing error here
     5  >>> a
     6  'zero'
     7
     8  *Crazy*, right?!
% ./helpers/mypy-doctests.py doctest.txt
doctest.txt:4: error: Incompatible types in assignment (expression has type "str", variable has type "int")
Found 1 error in 1 file (checked 1 source file)

Help is built in:

% ./helpers/mypy-doctests.py --help
usage: mypy-doctests.py [-h] [-a ARG] [-A] [--exclude-dir-names PATTERN]
                        [--include-file-names PATTERN] [--log-level LEVEL]
                        [--tmp-file-suffix SUFFIX] [-k] [-K]
                        PATH [PATH ...]

Extract doctests and check them with mypy.

positional arguments:
  PATH                  paths to check for doctests; PATH can be a file or
                        directory

optional arguments:
  -h, --help            show this help message and exit
  -a ARG, --mypyp-arg ARG
                        append ARG to mypy command
  -A, --clear-mypy-args
                        clear any mypy command arguments
  --exclude-dir-names PATTERN, --exclude PATTERN
                        exclude directories matching PATTERN from inspection
                        (default is "\A(\..*|__pycache__|node_modules|site-
                        packages)\Z")
  --include-file-names PATTERN
                        include files matching PATTERN (default is
                        "\.(md|py|pyi|rst|txt)\Z")
  --log-level LEVEL     set logging verbosity to LEVEL (default is WARNING)
  --tmp-file-suffix SUFFIX
                        use SUFFIX when creating temporary files (default is
                        ".doctest.py")
  -k, --keep-temp-files
                        keep temporary files on exit (e.g., for debugging or
                        inspection)
  -K, --no-keep-temp-files
                        remove temporary files on exit (default)

posita avatar Jun 08 '21 23:06 posita

@posita would you consider publishing it as a standalone CLI on PyPI? It would be nice to be able to use it that way.

m-aciek avatar Nov 26 '25 22:11 m-aciek