How do you get mypy to recognize a newer version of python?

Viewed 1992

I just updated my project to Python 3.7 and I'm seeing this error when I run mypy on the project: error: "Type[datetime]" has no attribute "fromisoformat"

datetime does have a function fromisoformat in Python 3.7, but not in previous versions of Python. Why is mypy reporting this error, and how can I get it to analyze Python 3.7 correctly?

Things I've tried so far:

  • Deleting .mypy_cache (which has a suspicious looking subfolder titled 3.6)
  • Reinstalling mypy with pip install --upgrade --force-reinstall mypy

To reproduce:

  • Create a python 3.6 project

  • install mypy 0.761 (latest) in the project venv

  • scan the project with mypy (mypy .)

  • update the project to python 3.7

  • add a file with this code in it:

    from datetime import datetime
    datetime.fromisoformat('2011-11-04 00:05:23.283')
    
  • scan the project again (mypy .) [UPDATE: this actually works fine. It was rerunning my precommit hooks without reinstalling pre-commit on the new Python version venv that was causing the problems.]

2 Answers

The solution was simple: simply run mypy with the --python-version flag. so in my case it was --python-version=3.7.

If you use pre-commit, you can also add this as an argument in a precommit check in your .pre-commit-config.yaml. Mine looks like this:

repos:

...

- repo: https://github.com/pre-commit/mirrors-mypy
  rev: v0.750  # Use the sha / tag you want to point at
  hooks:
      - id: mypy
        args: [--python-version=3.7]

If you run mypy often from the command line you can also add it to a config file as described herehttps://mypy.readthedocs.io/en/stable/config_file.html.

Another note: if mypy is reporting errors when your pre-commit hooks run, but not when it is run by itself from the project venv, then you need to either

  • add python-version as an argument like I do above, or
  • reinstall pre-commit in the new project venv (with the correct python version)

You are running mypy under an older version of Python. mypy defaults to the version of Python that is used to run it.

You have two options:

  • You can change the Python language version with the --python-version command-line option:

    This flag will make mypy type check your code as if it were run under Python version X.Y. Without this option, mypy will default to using whatever version of Python is running mypy.

    I'd put this in the project mypy configuration file; the equivalent of the command-line switch is named python_version; put it in the global [mypy] section:

    [mypy]
    python_version = 3.7
    
  • Install mypy into the virtualenv of your project, so that it uses the exact same Python version.

Note that if you see this issue (and didn't accidentally set --python-version, on the command-line or in a configuration file, you are certainly not running mypy from your project venv.

Related