blob: 3da30aeed60b974b848b15079977f48bf0ebc11a [file] [log] [blame] [edit]
-- Tests for command line parsing
-- ------------------------------
--
-- The initial line specifies the command line, in the format
--
-- # cmd: mypy <options>
--
-- Note that # flags: --some-flag IS NOT SUPPORTED.
-- Use # cmd: mypy --some-flag ...
--
-- '== Return code: <value>' is added to the output when the process return code
-- is "nonobvious" -- that is, when it is something other than 0 if there are no
-- messages and 1 if there are.
-- Directories/packages on the command line
-- ----------------------------------------
[case testCmdlinePackage]
# cmd: mypy pkg
[file pkg/__init__.py]
[file pkg/a.py]
undef
[file pkg/subpkg/__init__.py]
[file pkg/subpkg/a.py]
undef
import pkg.subpkg.a
[out]
pkg/a.py:1: error: Name 'undef' is not defined
pkg/subpkg/a.py:1: error: Name 'undef' is not defined
[case testCmdlinePackageSlash]
# cmd: mypy pkg/
[file pkg/__init__.py]
[file pkg/a.py]
undef
[file pkg/subpkg/__init__.py]
[file pkg/subpkg/a.py]
undef
import pkg.subpkg.a
[out]
pkg/a.py:1: error: Name 'undef' is not defined
pkg/subpkg/a.py:1: error: Name 'undef' is not defined
[case testCmdlineNonPackage]
# cmd: mypy dir
[file dir/a.py]
undef
[file dir/subdir/a.py]
undef
[out]
dir/a.py:1: error: Name 'undef' is not defined
[case testCmdlineNonPackageSlash]
# cmd: mypy dir/
[file dir/a.py]
undef
[file dir/subdir/a.py]
undef
[out]
dir/a.py:1: error: Name 'undef' is not defined
[case testCmdlinePackageContainingSubdir]
# cmd: mypy pkg
[file pkg/__init__.py]
[file pkg/a.py]
undef
[file pkg/subdir/a.py]
undef
[out]
pkg/a.py:1: error: Name 'undef' is not defined
[case testCmdlineNonPackageContainingPackage]
# cmd: mypy dir
[file dir/a.py]
undef
import subpkg.a
[file dir/subpkg/__init__.py]
[file dir/subpkg/a.py]
undef
[out]
dir/subpkg/a.py:1: error: Name 'undef' is not defined
dir/a.py:1: error: Name 'undef' is not defined
[case testCmdlineInvalidPackageName]
# cmd: mypy dir/sub.pkg/a.py
[file dir/sub.pkg/__init__.py]
[file dir/sub.pkg/a.py]
undef
[out]
sub.pkg is not a valid Python package name
== Return code: 2
[case testBadFileEncoding]
# cmd: mypy a.py
[file a.py]
# coding: uft-8
[out]
mypy: can't decode file 'a.py': unknown encoding: uft-8
== Return code: 2
-- '
[case testCannotIgnoreDuplicateModule]
# cmd: mypy one/mod/__init__.py two/mod/__init__.py
[file one/mod/__init__.py]
# type: ignore
[file two/mod/__init__.py]
# type: ignore
[out]
two/mod/__init__.py: error: Duplicate module named 'mod' (also at 'one/mod/__init__.py')
== Return code: 2
[case promptsForgotInit]
# cmd: mypy a.py one/mod/a.py
[file one/__init__.py]
# type: ignore
[file a.py]
# type: ignore
[file one/mod/a.py]
#type: ignore
[out]
one/mod/a.py: error: Duplicate module named 'a' (also at 'a.py')
one/mod/a.py: error: Are you missing an __init__.py?
== Return code: 2
[case testFlagsFile]
# cmd: mypy @flagsfile
[file flagsfile]
-2
main.py
[file main.py]
def f():
try:
1/0
except ZeroDivisionError, err:
print err
[case testConfigFile]
# cmd: mypy main.py
[file mypy.ini]
\[mypy]
python_version = 2.7
[file main.py]
def f():
try:
1/0
except ZeroDivisionError, err:
print err
[case testErrorContextConfig]
# cmd: mypy main.py
[file mypy.ini]
\[mypy]
show_error_context=True
[file main.py]
def f() -> None:
0 + ""
[out]
main.py: note: In function "f":
main.py:2: error: Unsupported operand types for + ("int" and "str")
[case testAltConfigFile]
# cmd: mypy --config-file config.ini main.py
[file config.ini]
\[mypy]
python_version = 2.7
[file main.py]
def f():
try:
1/0
except ZeroDivisionError, err:
print err
[case testNoConfigFile]
# cmd: mypy main.py --config-file=
[file mypy.ini]
\[mypy]
warn_unused_ignores = True
[file main.py]
# type: ignore
[case testPerFileConfigSection]
# cmd: mypy x.py y.py z.py
[file mypy.ini]
\[mypy]
disallow_untyped_defs = True
\[mypy-y]
disallow_untyped_defs = False
\[mypy-z]
disallow_untyped_calls = True
[file x.py]
def f(a):
pass
def g(a: int) -> int:
return f(a)
[file y.py]
def f(a):
pass
def g(a: int) -> int:
return f(a)
[file z.py]
def f(a):
pass
def g(a: int) -> int:
return f(a)
[out]
z.py:1: error: Function is missing a type annotation
z.py:4: error: Call to untyped function "f" in typed context
x.py:1: error: Function is missing a type annotation
[case testPerFileConfigSectionMultipleMatchesDisallowed]
# cmd: mypy xx.py xy.py yx.py yy.py
[file mypy.ini]
\[mypy]
\[mypy-*x*]
disallow_untyped_defs = True
\[mypy-*y*]
disallow_untyped_calls = True
[file xx.py]
def f(a): pass
def g(a: int) -> int: return f(a)
[file xy.py]
def f(a): pass
def g(a: int) -> int: return f(a)
[file yx.py]
def f(a): pass
def g(a: int) -> int: return f(a)
[file yy.py]
def f(a): pass
def g(a: int) -> int: return f(a)
[out]
mypy.ini: [mypy-*x*]: Patterns must be fully-qualified module names, optionally with '*' in some components (e.g spam.*.eggs.*)
mypy.ini: [mypy-*y*]: Patterns must be fully-qualified module names, optionally with '*' in some components (e.g spam.*.eggs.*)
== Return code: 0
[case testMultipleGlobConfigSection]
# cmd: mypy x.py y.py z.py
[file mypy.ini]
\[mypy]
\[mypy-x.*,z.*]
disallow_untyped_defs = True
[file x.py]
def f(a): pass
[file y.py]
def f(a): pass
[file z.py]
def f(a): pass
[out]
z.py:1: error: Function is missing a type annotation
x.py:1: error: Function is missing a type annotation
[case testConfigErrorNoSection]
# cmd: mypy -c pass
[file mypy.ini]
[out]
mypy.ini: No [mypy] section in config file
== Return code: 0
[case testConfigErrorUnknownFlag]
# cmd: mypy -c pass
[file mypy.ini]
\[mypy]
bad = 0
[out]
mypy.ini: [mypy]: Unrecognized option: bad = 0
== Return code: 0
[case testConfigErrorBadFlag]
# cmd: mypy a.py
[file mypy.ini]
\[mypy]
disallow-untyped-defs = True
[file a.py]
def f():
pass
[out]
mypy.ini: [mypy]: Unrecognized option: disallow-untyped-defs = True
== Return code: 0
[case testConfigErrorBadBoolean]
# cmd: mypy -c pass
[file mypy.ini]
\[mypy]
ignore_missing_imports = nah
[out]
mypy.ini: [mypy]: ignore_missing_imports: Not a boolean: nah
== Return code: 0
[case testConfigErrorNotPerFile]
# cmd: mypy -c pass
[file mypy.ini]
\[mypy]
\[mypy-*]
python_version = 3.4
[out]
mypy.ini: [mypy-*]: Per-module sections should only specify per-module flags (python_version)
== Return code: 0
[case testConfigMypyPath]
# cmd: mypy file.py
[file mypy.ini]
\[mypy]
mypy_path =
foo:bar
, baz
[file foo/foo.pyi]
def foo(x: int) -> str: ...
[file bar/bar.pyi]
def bar(x: str) -> list: ...
[file baz/baz.pyi]
def baz(x: list) -> dict: ...
[file file.py]
import no_stubs
from foo import foo
from bar import bar
from baz import baz
baz(bar(foo(42)))
baz(bar(foo('oof')))
[out]
file.py:1: error: Cannot find implementation or library stub for module named 'no_stubs'
file.py:1: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports
file.py:6: error: Argument 1 to "foo" has incompatible type "str"; expected "int"
[case testIgnoreErrorsConfig]
# cmd: mypy x.py y.py
[file mypy.ini]
\[mypy]
\[mypy-x]
ignore_errors = True
[file x.py]
"" + 0
[file y.py]
"" + 0
[out]
y.py:1: error: Unsupported operand types for + ("str" and "int")
[case testConfigFollowImportsNormal]
# cmd: mypy main.py
[file main.py]
from a import x
x + 0
x + '' # E
import a
a.x + 0
a.x + '' # E
a.y # E
a + 0 # E
[file mypy.ini]
\[mypy]
follow_imports = normal
[file a.py]
x = 0
x += '' # Error reported here
[out]
a.py:2: error: Unsupported operand types for + ("int" and "str")
main.py:3: error: Unsupported operand types for + ("int" and "str")
main.py:6: error: Unsupported operand types for + ("int" and "str")
main.py:7: error: Module has no attribute "y"
main.py:8: error: Unsupported operand types for + (Module and "int")
[case testConfigFollowImportsSilent]
# cmd: mypy main.py
[file main.py]
from a import x
x + ''
import a
a.x + ''
a.y
a + 0
[file mypy.ini]
\[mypy]
follow_imports = silent
[file a.py]
x = 0
x += '' # No error reported
[out]
main.py:2: error: Unsupported operand types for + ("int" and "str")
main.py:4: error: Unsupported operand types for + ("int" and "str")
main.py:5: error: Module has no attribute "y"
main.py:6: error: Unsupported operand types for + (Module and "int")
[case testConfigFollowImportsSkip]
# cmd: mypy main.py
[file main.py]
from a import x
reveal_type(x) # Expect Any
import a
reveal_type(a.x) # Expect Any
[file mypy.ini]
\[mypy]
follow_imports = skip
[file a.py]
/ # No error reported
[out]
main.py:2: note: Revealed type is 'Any'
main.py:4: note: Revealed type is 'Any'
[case testConfigFollowImportsError]
# cmd: mypy main.py
[file main.py]
from a import x
reveal_type(x) # Expect Any
import a # Error reported here
reveal_type(a.x) # Expect Any
[file mypy.ini]
\[mypy]
follow_imports = error
[file a.py]
/ # No error reported
[out]
main.py:1: error: Import of 'a' ignored
main.py:1: note: (Using --follow-imports=error, module not passed on command line)
main.py:2: note: Revealed type is 'Any'
main.py:4: note: Revealed type is 'Any'
[case testConfigFollowImportsSelective]
# cmd: mypy main.py
[file mypy.ini]
\[mypy]
\[mypy-normal]
follow_imports = normal
\[mypy-silent]
follow_imports = silent
\[mypy-skip]
follow_imports = skip
\[mypy-error]
follow_imports = error
[file main.py]
import normal
import silent
import skip
import error
reveal_type(normal.x)
reveal_type(silent.x)
reveal_type(skip)
reveal_type(error)
[file normal.py]
x = 0
x += ''
[file silent.py]
x = 0
x += ''
[file skip.py]
bla bla
[file error.py]
bla bla
[out]
normal.py:2: error: Unsupported operand types for + ("int" and "str")
main.py:4: error: Import of 'error' ignored
main.py:4: note: (Using --follow-imports=error, module not passed on command line)
main.py:5: note: Revealed type is 'builtins.int'
main.py:6: note: Revealed type is 'builtins.int'
main.py:7: note: Revealed type is 'Any'
main.py:8: note: Revealed type is 'Any'
[case testConfigSilentMissingImportsOff]
# cmd: mypy main.py
[file main.py]
import missing # Expect error here
reveal_type(missing.x) # Expect Any
[file mypy.ini]
\[mypy]
ignore_missing_imports = False
[out]
main.py:1: error: Cannot find implementation or library stub for module named 'missing'
main.py:1: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports
main.py:2: note: Revealed type is 'Any'
[case testConfigSilentMissingImportsOn]
# cmd: mypy main.py
[file main.py]
import missing # No error here
reveal_type(missing.x) # Expect Any
[file mypy.ini]
\[mypy]
ignore_missing_imports = True
[out]
main.py:2: note: Revealed type is 'Any'
[case testConfigNoErrorForUnknownXFlagInSubsection]
# cmd: mypy -c pass
[file mypy.ini]
\[mypy]
\[mypy-foo]
x_bad = 0
[out]
[case testDotInFilenameOKScript]
# cmd: mypy a.b.py c.d.pyi
[file a.b.py]
undef
[file c.d.pyi]
whatever
[out]
c.d.pyi:1: error: Name 'whatever' is not defined
a.b.py:1: error: Name 'undef' is not defined
[case testDotInFilenameOKFolder]
# cmd: mypy my.folder
[file my.folder/tst.py]
undef
[out]
my.folder/tst.py:1: error: Name 'undef' is not defined
[case testDotInFilenameNoImport]
# cmd: mypy main.py
[file main.py]
import a.b
[file a.b.py]
whatever
[out]
main.py:1: error: Cannot find implementation or library stub for module named 'a.b'
main.py:1: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports
main.py:1: error: Cannot find implementation or library stub for module named 'a'
[case testPythonVersionTooOld10]
# cmd: mypy -c pass
[file mypy.ini]
\[mypy]
python_version = 1.0
[out]
mypy.ini: [mypy]: python_version: Python major version '1' out of range (must be 2 or 3)
== Return code: 0
[case testPythonVersionTooOld26]
# cmd: mypy -c pass
[file mypy.ini]
\[mypy]
python_version = 2.6
[out]
mypy.ini: [mypy]: python_version: Python 2.6 is not supported (must be 2.7)
== Return code: 0
[case testPythonVersionTooOld33]
# cmd: mypy -c pass
[file mypy.ini]
\[mypy]
python_version = 3.3
[out]
mypy.ini: [mypy]: python_version: Python 3.3 is not supported (must be 3.4 or higher)
== Return code: 0
[case testPythonVersionTooNew28]
# cmd: mypy -c pass
[file mypy.ini]
\[mypy]
python_version = 2.8
[out]
mypy.ini: [mypy]: python_version: Python 2.8 is not supported (must be 2.7)
== Return code: 0
[case testPythonVersionTooNew40]
# cmd: mypy -c pass
[file mypy.ini]
\[mypy]
python_version = 4.0
[out]
mypy.ini: [mypy]: python_version: Python major version '4' out of range (must be 2 or 3)
== Return code: 0
[case testPythonVersionAccepted27]
# cmd: mypy -c pass
[file mypy.ini]
\[mypy]
python_version = 2.7
[out]
[case testPythonVersionAccepted34]
# cmd: mypy -c pass
[file mypy.ini]
\[mypy]
python_version = 3.4
[out]
[case testPythonVersionAccepted36]
# cmd: mypy -c pass
[file mypy.ini]
\[mypy]
python_version = 3.6
[out]
-- This should be a dumping ground for tests of plugins that are sensitive to
-- typeshed changes.
[case testTypeshedSensitivePlugins]
# cmd: mypy int_pow.py
[file int_pow.py]
a = 1
b = a + 2
reveal_type(a**0) # N: Revealed type is 'builtins.int'
reveal_type(a**1) # N: Revealed type is 'builtins.int'
reveal_type(a**2) # N: Revealed type is 'builtins.int'
reveal_type(a**-0) # N: Revealed type is 'builtins.int'
reveal_type(a**-1) # N: Revealed type is 'builtins.float'
reveal_type(a**(-2)) # N: Revealed type is 'builtins.float'
reveal_type(a**b) # N: Revealed type is 'Any'
reveal_type(a.__pow__(2)) # N: Revealed type is 'builtins.int'
reveal_type(a.__pow__(a)) # N: Revealed type is 'Any'
a.__pow__() # E: Too few arguments for "__pow__" of "int"
[case testDisallowAnyUnimported]
# cmd: mypy main.py
[file mypy.ini]
\[mypy]
disallow_any_unimported = True
ignore_missing_imports = True
[file main.py]
from unreal import F
def f(x: F) -> None: pass
[out]
main.py:3: error: Argument 1 to "f" becomes "Any" due to an unfollowed import
[case testDisallowAnyExplicitDefSignature]
# cmd: mypy m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_explicit = True
[file m.py]
from typing import Any, List
def f(x: Any) -> None:
pass
def g() -> Any:
pass
def h() -> List[Any]:
pass
[out]
m.py:3: error: Explicit "Any" is not allowed
m.py:6: error: Explicit "Any" is not allowed
m.py:9: error: Explicit "Any" is not allowed
[case testDisallowAnyExplicitVarDeclaration]
# cmd: mypy --python-version=3.6 m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_explicit = True
[file m.py]
from typing import Any, List
v: Any = ''
w = '' # type: Any
class X:
y = '' # type: Any
[out]
m.py:2: error: Explicit "Any" is not allowed
m.py:3: error: Explicit "Any" is not allowed
m.py:5: error: Explicit "Any" is not allowed
[case testDisallowAnyExplicitGenericVarDeclaration]
# cmd: mypy --python-version=3.6 m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_explicit = True
[file m.py]
from typing import Any, List
v: List[Any] = []
[out]
m.py:2: error: Explicit "Any" is not allowed
[case testDisallowAnyExplicitInheritance]
# cmd: mypy m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_explicit = True
[file m.py]
from typing import Any, List
class C(Any):
pass
class D(List[Any]):
pass
[out]
m.py:3: error: Explicit "Any" is not allowed
m.py:6: error: Explicit "Any" is not allowed
[case testDisallowAnyExplicitAlias]
# cmd: mypy m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_explicit = True
[file m.py]
from typing import Any, List
X = Any
Y = List[Any]
def foo(x: X) -> Y: # no error
x.nonexistent() # no error
return x
[out]
m.py:3: error: Explicit "Any" is not allowed
m.py:4: error: Explicit "Any" is not allowed
[case testDisallowAnyExplicitGenericAlias]
# cmd: mypy m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_explicit = True
[file m.py]
from typing import Any, List, TypeVar, Tuple
T = TypeVar('T')
TupleAny = Tuple[Any, T] # error
def foo(x: TupleAny[str]) -> None: # no error
pass
def goo(x: TupleAny[Any]) -> None: # error
pass
[out]
m.py:5: error: Explicit "Any" is not allowed
m.py:10: error: Explicit "Any" is not allowed
[case testDisallowAnyExplicitCast]
# cmd: mypy m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_explicit = True
[file m.py]
from typing import Any, List, cast
x = 1
y = cast(Any, x)
z = cast(List[Any], x)
[out]
m.py:4: error: Explicit "Any" is not allowed
m.py:5: error: Explicit "Any" is not allowed
[case testDisallowAnyExplicitNamedTuple]
# cmd: mypy m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_explicit = True
[file m.py]
from typing import Any, List, NamedTuple
Point = NamedTuple('Point', [('x', List[Any]),
('y', Any)])
[out]
m.py:3: error: Explicit "Any" is not allowed
[case testDisallowAnyExplicitTypeVarConstraint]
# cmd: mypy m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_explicit = True
[file m.py]
from typing import Any, List, TypeVar
T = TypeVar('T', Any, List[Any])
[out]
m.py:3: error: Explicit "Any" is not allowed
[case testDisallowAnyExplicitNewType]
# cmd: mypy m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_explicit = True
[file m.py]
from typing import Any, List, NewType
Baz = NewType('Baz', Any) # this error does not come from `--disallow-any-explicit` flag
Bar = NewType('Bar', List[Any])
[out]
m.py:3: error: Argument 2 to NewType(...) must be subclassable (got "Any")
m.py:4: error: Explicit "Any" is not allowed
[case testDisallowAnyExplicitTypedDictSimple]
# cmd: mypy m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_explicit = True
[file m.py]
from mypy_extensions import TypedDict
from typing import Any
M = TypedDict('M', {'x': str, 'y': Any}) # error
M(x='x', y=2) # no error
def f(m: M) -> None: pass # no error
[out]
m.py:4: error: Explicit "Any" is not allowed
[case testDisallowAnyExplicitTypedDictGeneric]
# cmd: mypy m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_explicit = True
[file m.py]
from mypy_extensions import TypedDict
from typing import Any, List
M = TypedDict('M', {'x': str, 'y': List[Any]}) # error
N = TypedDict('N', {'x': str, 'y': List}) # no error
[out]
m.py:4: error: Explicit "Any" is not allowed
[case testDisallowAnyGenericsTupleNoTypeParams]
# cmd: mypy --python-version=3.6 m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_generics = True
[file m.py]
from typing import Tuple
def f(s: Tuple) -> None: pass # error
def g(s) -> Tuple: # error
return 'a', 'b'
def h(s) -> Tuple[str, str]: # no error
return 'a', 'b'
x: Tuple = () # error
[out]
m.py:3: error: Missing type parameters for generic type "Tuple"
m.py:4: error: Missing type parameters for generic type "Tuple"
m.py:8: error: Missing type parameters for generic type "Tuple"
[case testDisallowAnyGenericsTupleWithNoTypeParamsGeneric]
# cmd: mypy m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_generics = True
[file m.py]
from typing import Tuple, List
def f(s: List[Tuple]) -> None: pass # error
def g(s: List[Tuple[str, str]]) -> None: pass # no error
[out]
m.py:3: error: Missing type parameters for generic type "Tuple"
[case testDisallowAnyGenericsTypeType]
# cmd: mypy --python-version=3.6 m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_generics = True
[file m.py]
from typing import Type, Any
def f(s: Type[Any]) -> None: pass # no error
def g(s) -> Type: # error
return s
def h(s) -> Type[str]: # no error
return s
x: Type = g(0) # error
[out]
m.py:4: error: Missing type parameters for generic type "Type"
m.py:8: error: Missing type parameters for generic type "Type"
[case testDisallowAnyGenericsAliasGenericType]
# cmd: mypy m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_generics = True
[file m.py]
from typing import List
L = List # no error
def f(l: L) -> None: pass # error
def g(l: L[str]) -> None: pass # no error
[out]
m.py:5: error: Missing type parameters for generic type "L"
[case testDisallowAnyGenericsGenericAlias]
# cmd: mypy --python-version=3.6 m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_generics = True
[file m.py]
from typing import List, TypeVar, Tuple
T = TypeVar('T')
A = Tuple[T, str, T]
def f(s: A) -> None: pass # error
def g(s) -> A: # error
return 'a', 'b', 1
def h(s) -> A[str]: # no error
return 'a', 'b', 'c'
x: A = ('a', 'b', 1) # error
[out]
m.py:6: error: Missing type parameters for generic type "A"
m.py:7: error: Missing type parameters for generic type "A"
m.py:11: error: Missing type parameters for generic type "A"
[case testDisallowAnyGenericsPlainList]
# cmd: mypy --python-version=3.6 m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_generics = True
[file m.py]
from typing import List
def f(l: List) -> None: pass # error
def g(l: List[str]) -> None: pass # no error
def h(l: List[List]) -> None: pass # error
def i(l: List[List[List[List]]]) -> None: pass # error
x = [] # error: need type annotation
y: List = [] # error
[out]
m.py:3: error: Missing type parameters for generic type "List"
m.py:5: error: Missing type parameters for generic type "List"
m.py:6: error: Missing type parameters for generic type "List"
m.py:8: error: Need type annotation for 'x' (hint: "x: List[<type>] = ...")
m.py:9: error: Missing type parameters for generic type "List"
[case testDisallowAnyGenericsCustomGenericClass]
# cmd: mypy --python-version=3.6 m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_generics = True
[file m.py]
from typing import Generic, TypeVar, Any
T = TypeVar('T')
class G(Generic[T]): pass
def f() -> G: # error
return G()
x: G[Any] = G() # no error
y: G = x # error
[out]
m.py:6: error: Missing type parameters for generic type "G"
m.py:10: error: Missing type parameters for generic type "G"
[case testDisallowAnyGenericsBuiltinCollections]
# cmd: mypy m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_generics = True
[file m.py]
s = tuple([1, 2, 3]) # no error
def f(t: tuple) -> None: pass
def g() -> list: pass
def h(s: dict) -> None: pass
def i(s: set) -> None: pass
def j(s: frozenset) -> None: pass
[out]
m.py:3: error: Implicit generic "Any". Use "typing.Tuple" and specify generic parameters
m.py:4: error: Implicit generic "Any". Use "typing.List" and specify generic parameters
m.py:5: error: Implicit generic "Any". Use "typing.Dict" and specify generic parameters
m.py:6: error: Implicit generic "Any". Use "typing.Set" and specify generic parameters
m.py:7: error: Implicit generic "Any". Use "typing.FrozenSet" and specify generic parameters
[case testDisallowAnyGenericsTypingCollections]
# cmd: mypy m.py
[file mypy.ini]
\[mypy]
\[mypy-m]
disallow_any_generics = True
[file m.py]
from typing import Tuple, List, Dict, Set, FrozenSet
def f(t: Tuple) -> None: pass
def g() -> List: pass
def h(s: Dict) -> None: pass
def i(s: Set) -> None: pass
def j(s: FrozenSet) -> None: pass
[out]
m.py:3: error: Missing type parameters for generic type "Tuple"
m.py:4: error: Missing type parameters for generic type "List"
m.py:5: error: Missing type parameters for generic type "Dict"
m.py:6: error: Missing type parameters for generic type "Set"
m.py:7: error: Missing type parameters for generic type "FrozenSet"
[case testDisallowSubclassingAny]
# cmd: mypy m.py y.py
[file mypy.ini]
\[mypy]
disallow_subclassing_any = True
\[mypy-m]
disallow_subclassing_any = False
[file m.py]
from typing import Any
x = None # type: Any
class ShouldBeFine(x): ...
[file y.py]
from typing import Any
x = None # type: Any
class ShouldNotBeFine(x): ...
[out]
y.py:5: error: Class cannot subclass 'x' (has type 'Any')
[case testSectionInheritance]
# cmd: mypy a
[file a/__init__.py]
0()
[file a/foo.py]
0()
[file a/b/__init__.py]
[file a/b/c/__init__.py]
0()
[file a/b/c/d/__init__.py]
[file a/b/c/d/e/__init__.py]
from typing import List
def g(x: List) -> None: pass
g(None)
[file mypy.ini]
\[mypy]
allow_any_generics = True
\[mypy-a.*]
ignore_errors = True
\[mypy-a.b.*]
disallow_any_generics = True
ignore_errors = True
\[mypy-a.b.c.*]
ignore_errors = True
\[mypy-a.b.c.d.*]
ignore_errors = True
\[mypy-a.b.c.d.e.*]
ignore_errors = True
strict_optional = True
\[mypy-a.b.c.d.e]
ignore_errors = False
[out]
a/b/c/d/e/__init__.py:2: error: Missing type parameters for generic type "List"
a/b/c/d/e/__init__.py:3: error: Argument 1 to "g" has incompatible type "None"; expected "List[Any]"
[case testDisallowUntypedDefsAndGenerics]
# cmd: mypy a.py
[file mypy.ini]
\[mypy]
disallow_untyped_defs = True
disallow_any_generics = True
[file a.py]
def get_tasks(self):
return 'whatever'
[out]
a.py:1: error: Function is missing a return type annotation
[case testMissingFile]
# cmd: mypy nope.py
[out]
mypy: can't read file 'nope.py': No such file or directory
== Return code: 2
--'
[case testParseError]
# cmd: mypy a.py
[file a.py]
def foo(
[out]
a.py:1: error: unexpected EOF while parsing
== Return code: 2
[case testParseErrorAnnots]
# cmd: mypy a.py
[file a.py]
def foo(x):
# type: (str, int) -> None
return
[out]
a.py:1: error: Type signature has too many arguments
[case testModulesAndPackages]
# cmd: mypy --package p.a --package p.b --module c
[file p/__init__.py]
[file p/a.py]
def foo(x):
# type: (int) -> str
return "x"
foo("wrong")
[file p/b/__init__.py]
from ..a import foo
def bar(a):
# type: (int) -> str
return foo(a)
bar("wrong")
[file c.py]
import p.b
p.b.bar("wrong")
[out]
p/a.py:4: error: Argument 1 to "foo" has incompatible type "str"; expected "int"
p/b/__init__.py:5: error: Argument 1 to "bar" has incompatible type "str"; expected "int"
c.py:2: error: Argument 1 to "bar" has incompatible type "str"; expected "int"
[case testSrcPEP420Packages]
# cmd: mypy -p anamespace --namespace-packages
[file mypy.ini]
\[mypy]]
mypy_path = src
[file src/setup.cfg]
[file src/anamespace/foo/__init__.py]
[file src/anamespace/foo/bar.py]
def bar(a: int, b: int) -> str:
return a + b
[out]
src/anamespace/foo/bar.py:2: error: Incompatible return value type (got "int", expected "str")
[case testFollowImportStubs1]
# cmd: mypy main.py
[file mypy.ini]
\[mypy]
\[mypy-math.*]
follow_imports = error
follow_imports_for_stubs = True
[file main.py]
import math
math.frobnicate()
[out]
main.py:1: error: Import of 'math' ignored
main.py:1: note: (Using --follow-imports=error, module not passed on command line)
[case testFollowImportStubs2]
# cmd: mypy main.py
[file mypy.ini]
\[mypy]
\[mypy-math.*]
follow_imports = skip
follow_imports_for_stubs = True
[file main.py]
import math
math.frobnicate()
[case testShadowFile1]
# cmd: mypy --shadow-file source.py shadow.py source.py
[file source.py]
def foo() -> str:
return "bar"
[file shadow.py]
def bar() -> str:
return 14
[out]
source.py:2: error: Incompatible return value type (got "int", expected "str")
[case testShadowFile2]
# cmd: mypy --shadow-file s1.py shad1.py --shadow-file s2.py shad2.py --shadow-file s3.py shad3.py s1.py s2.py s3.py s4.py
[file s1.py]
def foo() -> str:
return "bar"
[file shad1.py]
def bar() -> str:
return 14
[file s2.py]
def baz() -> str:
return 14
[file shad2.py]
def baz() -> int:
return 14
[file s3.py]
def qux() -> str:
return "bar"
[file shad3.py]
def foo() -> int:
return [42]
[file s4.py]
def foo() -> str:
return 9
[out]
s4.py:2: error: Incompatible return value type (got "int", expected "str")
s3.py:2: error: Incompatible return value type (got "List[int]", expected "int")
s1.py:2: error: Incompatible return value type (got "int", expected "str")
[case testConfigWarnUnusedSection1]
# cmd: mypy foo.py quux.py spam/eggs.py
[file mypy.ini]
\[mypy]
warn_unused_configs = True
incremental = False
\[mypy-bar]
\[mypy-foo]
\[mypy-baz.*]
\[mypy-quux.*]
\[mypy-spam.*]
\[mypy-spam.eggs]
\[mypy-emarg.*]
\[mypy-emarg.hatch]
-- Currently we don't treat an unstructured pattern like a.*.b as unused
-- if it matches another section (like a.x.b). This would be reasonable
-- to change. '
\[mypy-a.*.b]
\[mypy-a.*.c]
\[mypy-a.x.b]
[file foo.py]
[file quux.py]
[file spam/__init__.py]
[file spam/eggs.py]
[out]
Warning: unused section(s) in mypy.ini: [mypy-bar], [mypy-baz.*], [mypy-emarg.*], [mypy-emarg.hatch], [mypy-a.*.c], [mypy-a.x.b]
== Return code: 0
[case testConfigUnstructuredGlob]
# cmd: mypy emarg foo
[file mypy.ini]
\[mypy]
ignore_errors = true
\[mypy-*.lol]
ignore_errors = false
\[mypy-emarg.*]
ignore_errors = false
\[mypy-emarg.*.villip.*]
ignore_errors = true
\[mypy-emarg.hatch.villip.mankangulisk]
ignore_errors = false
[file emarg/__init__.py]
[file emarg/foo.py]
fail
[file emarg/villip.py]
fail
[file emarg/hatch/__init__.py]
[file emarg/hatch/villip/__init__.py]
[file emarg/hatch/villip/nus.py]
fail
[file emarg/hatch/villip/mankangulisk.py]
fail
[file foo/__init__.py]
[file foo/lol.py]
fail
[out]
foo/lol.py:1: error: Name 'fail' is not defined
emarg/foo.py:1: error: Name 'fail' is not defined
emarg/hatch/villip/mankangulisk.py:1: error: Name 'fail' is not defined
[case testPackageRootEmpty]
# cmd: mypy --package-root= a/b/c.py main.py
[file a/b/c.py]
[file main.py]
import a.b.c
[case testPackageRootNonEmpty]
# cmd: mypy --package-root=a/ a/b/c.py main.py
[file a/b/c.py]
[file main.py]
import b.c
[case testPackageRootMultiple1]
# cmd: mypy --package-root=. --package-root=a a/b/c.py d.py main.py
[file a/b/c.py]
[file d.py]
[file main.py]
import b.c
import d
[case testPackageRootMultiple2]
# cmd: mypy --package-root=a/ --package-root=./ a/b/c.py d.py main.py
[file a/b/c.py]
[file d.py]
[file main.py]
import b.c
import d
[case testCacheMap]
-- This just checks that a valid --cache-map triple is accepted.
-- (Errors are too verbose to check.)
# cmd: mypy a.py --no-sqlite-cache --cache-map a.py a.meta.json a.data.json
[file a.py]
[out]
[case testIniFiles]
# cmd: mypy
[file mypy.ini]
\[mypy]
files = a.py, b.py
[file a.py]
fail
[file b.py]
fail
[out]
b.py:1: error: Name 'fail' is not defined
a.py:1: error: Name 'fail' is not defined
[case testIniFilesGlobbing]
# cmd: mypy
[file mypy.ini]
\[mypy]
files = **/*.py
[file a/b.py]
fail
[file c.py]
fail
[out]
a/b.py:1: error: Name 'fail' is not defined
c.py:1: error: Name 'fail' is not defined
[case testIniFilesCmdlineOverridesConfig]
# cmd: mypy override.py
[file mypy.ini]
\[mypy]
files = config.py
[out]
mypy: can't read file 'override.py': No such file or directory
== Return code: 2
[case testErrorSummaryOnSuccess]
# cmd: mypy --error-summary good.py
[file good.py]
x = 2 + 2
[out]
Success: no issues found in 1 source file
== Return code: 0
[case testErrorSummaryOnFail]
# cmd: mypy --error-summary bad.py
[file bad.py]
42 + 'no'
[out]
bad.py:1: error: Unsupported operand types for + ("int" and "str")
Found 1 error in 1 file (checked 1 source file)
[case testErrorSummaryOnFailNotes]
# cmd: mypy --error-summary bad.py
[file bad.py]
from typing import List
x = [] # type: List[float]
y = [] # type: List[int]
x = y
[out]
bad.py:4: error: Incompatible types in assignment (expression has type "List[int]", variable has type "List[float]")
bad.py:4: note: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance
bad.py:4: note: Consider using "Sequence" instead, which is covariant
Found 1 error in 1 file (checked 1 source file)
[case testErrorSummaryOnFailTwoErrors]
# cmd: mypy --error-summary bad.py foo.py
[file bad.py]
42 + 'no'
42 + 'no'
[file foo.py]
[out]
bad.py:1: error: Unsupported operand types for + ("int" and "str")
bad.py:2: error: Unsupported operand types for + ("int" and "str")
Found 2 errors in 1 file (checked 2 source files)
[case testErrorSummaryOnFailTwoFiles]
# cmd: mypy --error-summary bad.py bad2.py
[file bad.py]
42 + 'no'
[file bad2.py]
42 + 'no'
[out]
bad2.py:1: error: Unsupported operand types for + ("int" and "str")
bad.py:1: error: Unsupported operand types for + ("int" and "str")
Found 2 errors in 2 files (checked 2 source files)
[case testErrorSummaryOnBadUsage]
# cmd: mypy --error-summary missing.py
[out]
mypy: can't read file 'missing.py': No such file or directory
== Return code: 2
[case testShowSourceCodeSnippetsWrappedFormatting]
# cmd: mypy --pretty --python-version=3.6 some_file.py
[file some_file.py]
from typing import Union
42 + 'no way'
class OneCustomClassName:
def some_interesting_method(self, arg: AnotherCustomClassDefinedBelow) -> AnotherCustomClassDefinedBelow:
...
class AnotherCustomClassDefinedBelow:
def another_even_more_interesting_method(self, arg: Union[int, str, float]) -> None:
self.very_important_attribute_with_long_name: OneCustomClassName = OneCustomClassName().some_interesting_method(arg)
[out]
some_file.py:3: error: Unsupported operand types for + ("int" and "str")
42 + 'no way'
^
some_file.py:11: error: Incompatible types in assignment (expression has type
"AnotherCustomClassDefinedBelow", variable has type "OneCustomClassName")
...t_attribute_with_long_name: OneCustomClassName = OneCustomClassName()....
^
some_file.py:11: error: Argument 1 to "some_interesting_method" of
"OneCustomClassName" has incompatible type "Union[int, str, float]"; expected
"AnotherCustomClassDefinedBelow"
...OneCustomClassName = OneCustomClassName().some_interesting_method(arg)
^
[case testShowSourceCodeSnippetsBlockingError]
# cmd: mypy --pretty --show-error-codes some_file.py
[file some_file.py]
it_looks_like_we_started_typing_something_but_then. = did_not_notice(an_extra_dot)
[out]
some_file.py:1: error: invalid syntax [syntax]
...ooks_like_we_started_typing_something_but_then. = did_not_notice(an_ex...
^
== Return code: 2
[case testSpecialTypeshedGenericNote]
# cmd: mypy --disallow-any-generics --python-version=3.6 test.py
[file test.py]
from os import PathLike
from queue import Queue
p: PathLike
q: Queue
[out]
test.py:4: error: Missing type parameters for generic type "_PathLike"
test.py:4: note: Subscripting classes that are not generic at runtime may require escaping, see https://mypy.readthedocs.io/en/latest/common_issues.html#not-generic-runtime
test.py:5: error: Missing type parameters for generic type "Queue"
test.py:5: note: Subscripting classes that are not generic at runtime may require escaping, see https://mypy.readthedocs.io/en/latest/common_issues.html#not-generic-runtime