How to make mypy complain about assigning an Any t

2019-08-03 18:30发布

问题:

(This is a follow-up to this question.)

My code base is fully statically typed (annotation) but at some points there is the Any type, for example because a value was parsed from a JSON string. Here is my minimal example:

import json
from typing import Any, Dict, Union

def main() -> None:
    data = json.loads('{"value" = "three"}')
    my_int: int = data['value']

if __name__ == "__main__":
    main()

mypy --strict accepts this code. However I would like to find these places automatically, to take the appropriate security measures.

Is there any possibility to make mypy complain about the my_int: int = data['value'] assignment?

回答1:

Yes -- use the "disallow any" family of command line flags.

In this case, I think you want to use specifically --disallow-any-expr, though I recommend you also experiment with the other flags.

(These flags are not automatically enabled as a part of --strict because they end up causing a lot of false positives on certain codebases, especially ones that make extensive use of untyped libraries.)


As an aside, something you may discover is that enabling all of the "disallow any" flags can end up being a little inconvenient, especially if you have a certain region of your code that needs to do a lot of runtime checks.

To help mitigate this, what I personally like to do is have all of the disallow-any flags enabled by default, but disable a few of them for certain modules. You can do this using mypy's config files. For example, you could do:

[mypy]
# Specify any other global flags you want to customize here
disallow_any_unimported = True
disallow_any_expr = True
disallow_any_decorated = True
disallow_any_explicit = True
disallow_any_generics = True
disallow_subclassing_any = True

[mypy-mymodule.validation]
# Weaken, just for this module
disallow_any_expr = False

And run mypy --strict --config my_config.ini mymodule.

This config file would disallow the use of Any from almost the entire codebase, except within the validation module. (And then, I'd go out of my way to add a bunch of unit tests for that specific module to make up for the weakened static type checks.)