Mypy: strict mode?

Created on 16 Oct 2015  路  9Comments  路  Source: python/mypy

Is there any feature I can turn on to require that an entire file is statically typed?

Or in general, what sort of tools would you use to enforce good mypy habits in a large project?

needs discussion

Most helpful comment

This functionality is now available under the flag --disallow-untyped-calls.

All 9 comments

cat file.py | sed 's/^\(\s*def.*)\):/\1 -> None/

Having a flag that actually causes mypy to throw an error if it encounters something that isn't type'd would be potentially useful, actually.

Here's what Facebook did with HHVM: http://docs.hhvm.com/manual/en/hack.modes.strict.php

A strict mode has actually been on my own to-do list since somewhere around 2013, but I never created an issue for it.

Something like this could do the trick:

# mypy: strict

def f(x: int):   # Error: Return type missing and defaults to 'Any'
    ...

This would be especially useful if/when we are going to use a 'weak' type checking mode by default for module top levels. It wouldn't complain about things like this:

x = []   # Error in strict mode but okay in weak mode

I would love to have this feature. Where would be a place to start? I'm completely unfamiliar with Mypy (but I am with Python).

The following is an example of what I would like to be warned on.

Here is correct code with type annotations:

def greeting() -> List[str]:
    return ["zapu"]

def main() -> None:
    print("Hello", ', '.join(greeting()))

Here is code that will fail type-check (and rightfully so):

def greeting() -> List[int]:
    return [1]

def main() -> None:
    print("Hello", ', '.join(greeting()))

output:

test.py: note: In function "main":
test.py:28: error: Argument 1 to "join" of "str" has incompatible type List[int]; expected Iterable[str]

Here is code that passes type-check but fails at runtime:

def greeting():
    return [1]

def main() -> None:
    print("Hello", ', '.join(greeting()))

output:

Traceback (most recent call last):
  File "test.py", line 32, in <module>
    main()
  File "test.py", line 28, in main
    print("Hello", ', '.join(greeting()))
TypeError: sequence item 0: expected str instance, int found

I am unsure what's the correct approach here, but consider that this could be avoided if type annotations were contagious. That is, every function that is type-annotated can only call type-annotated functions. So even if greeting() was in some other module, it would keep failing to type-check until I make a stub for it.

That sounds like the right approach to me. I realized that that shouldn't be too hard to implement, so I took a stab at it above. With #1230 (and mypy --strict test.py), here's what I get for your last example:

def greeting():
    return [1]

def main() -> None:
    print("Hello", ', '.join(greeting()))
test.py: note: In function "main":
test.py:5: error: call to untyped function "greeting" in typed context

Wow, thanks! I'll take a look later in the day.

This functionality is now available under the flag --disallow-untyped-calls.

Cool!

Was this page helpful?
0 / 5 - 0 ratings