5

The following script contains an intentional type error:

def foo(x, y):
    print(x[:y])

def main():
    foo('abcde', '2')

if __name__ == "__main__":
    main()

The error can be confirmed by running it:

$ python3 untyped_test.py 
Traceback (most recent call last):
  File "untyped_test.py", line 8, in <module>
    main()
  File "untyped_test.py", line 5, in main
    foo('abcde', '2')
  File "untyped_test.py", line 2, in foo
    print(x[:y])
TypeError: slice indices must be integers or None or have an __index__ method

However I was hoping to catch something like this not only at runtime but before executing the code using:

mypy --check-untyped-defs untyped_test.py 

But it does not find any errors:

$ mypy --check-untyped-defs untyped_test.py 
$ mypy --version
mypy 0.590

Only when I annotate foo:

def foo(x: str, y: int):
    print(x[:y])

I get:

untyped_test.py:5: error: Argument 2 to "foo" has incompatible type "str"; expected "int"

Is it possible to find errors like this without any manual type annotations?

5
  • 1
    foo('abcde', '2')foo('abcde', 2) Commented Apr 25, 2018 at 12:00
  • @KlausD. Yes, I know what the mistake is. ;) It is there by intention to test if mypy can find it. I will adjust the question to clarify this. Commented Apr 25, 2018 at 12:30
  • With your intention you would take away one of the most important language features of Python, the duck typing. It's a thing that many programmer coming from statically typed languages like Java consider strange at first. And IMHO if you enforce static typing, then it's not Python anymore. Commented Apr 25, 2018 at 12:41
  • @KlausD. I don't want to remove duck typing from Python. I'm just looking for a possibility to catch as many errors using mypy as possible. Every Python user is free to choose not to do type checking, and instead wait until the error explodes at runtime right in front of the customer. ;) Commented Apr 25, 2018 at 12:59
  • @KlausD. Just to check, you know type hints have basically been a part of Python for ~2-3 years now? Of course, Python itself doesn't check them and you need to use 3rd party tools like [mypy](mypy-lang.org), but there's an [official spec](python.org/dev/peps/pep-0484) for their semantics and the language itself has been modified several times to make them more ergonomic. (E.g. see [PEP 526](python.org/dev/peps/pep-0526), [PEP 560](python.org/dev/peps/pep-0560), and [PEP 563](python.org/dev/peps/pep-0563)). So saying "it wouldn't be Python" is a bit moot at this point imo :) Commented Apr 25, 2018 at 17:08

1 Answer 1

2

This is not possible to do in mypy. Mypy follows PEP 484 semantics, which states that if a function's parameters are unannotated, they are assumed to have a type of Any, which represents a fully dynamic value of unknown type.

This design decision is intentional. This is in part because doing whole-program type inference is challenging, especially once you permit objects, subtyping, mutability, and so forth: asking the user to fix types at the "boundary" helps make type hinting tractable.

This is also in part to help ensure backwards compatibility. Type hints were intentionally designed such that it's possible to mix untyped and dynamic code with typed code in a meaningful way. This is particularly useful if you want to introduce type hinting to an existing project: everything, by default, is guaranteed to be considered dynamically typed, which lets you slowly add in types without being overwhelmed with errors. (That's the dream, at least -- I don't think mypy doesn't quite let you do this.)

That said, there are some people who are attempting to implement whole-program type inference -- see the pytype project, for example. However, my understanding is that it's still very much in alpha stage.

Sign up to request clarification or add additional context in comments.

1 Comment

Great answer. Thanks a lot. I will check out pytype. I'm really looking forward to finding bugs like this more early.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.