Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Allowed use of types.ModuleType
  • Loading branch information
pkch committed Apr 2, 2017
commit 585ff8d47a477e14dee40bb9eeb07ba011d271d7
2 changes: 1 addition & 1 deletion mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def analyze_ref_expr(self, e: RefExpr, lvalue: bool = False) -> Type:
result = type_object_type(node, self.named_type)
elif isinstance(node, MypyFile):
# Reference to a module object.
result = self.named_type('builtins.module')
result = self.named_type('types.ModuleType')
elif isinstance(node, Decorator):
result = self.analyze_var_ref(node.var, e)
else:
Expand Down
2 changes: 1 addition & 1 deletion mypy/checkmember.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ def analyze_class_attribute_access(itype: Instance,

if isinstance(node.node, MypyFile):
# Reference to a module object.
return builtin_type('builtins.module')
return builtin_type('types.ModuleType')

if is_decorated:
# TODO: Return type of decorated function. This is quick hack to work around #998.
Expand Down
4 changes: 2 additions & 2 deletions test-data/unit/check-ignore.test
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import b # type: ignore
reveal_type(a.foo) # E: Revealed type is 'Any'
reveal_type(b.foo) # E: Revealed type is 'builtins.int'
a.bar()
b.bar() # E: "module" has no attribute "bar"
b.bar() # E: "ModuleType" has no attribute "bar"

[file b.py]
foo = 3
Expand Down Expand Up @@ -76,7 +76,7 @@ class B(A):
import m
m.x = object # type: ignore
m.f() # type: ignore
m.y # E: "module" has no attribute "y"
m.y # E: "ModuleType" has no attribute "y"
[file m.py]
[builtins fixtures/module.pyi]

Expand Down
6 changes: 3 additions & 3 deletions test-data/unit/check-incremental.test
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ const = 3
[stale mod3]
[builtins fixtures/module.pyi]
[out2]
tmp/mod1.py:3: error: "module" has no attribute "mod4"
tmp/mod1.py:3: error: "ModuleType" has no attribute "mod4"

[case testIncrementalLongBrokenCascade]
import mod1
Expand Down Expand Up @@ -335,7 +335,7 @@ const = 3
[stale mod6]
[builtins fixtures/module.pyi]
[out2]
tmp/mod1.py:3: error: "module" has no attribute "mod7"
tmp/mod1.py:3: error: "ModuleType" has no attribute "mod7"

[case testIncrementalNestedBrokenCascade]
import mod1
Expand All @@ -361,7 +361,7 @@ const = 3
[stale mod2.mod3]
[builtins fixtures/module.pyi]
[out2]
tmp/mod1.py:3: error: "module" has no attribute "mod4"
tmp/mod1.py:3: error: "ModuleType" has no attribute "mod4"

[case testIncrementalNestedBrokenCascadeWithType1]
import mod1, mod2.mod3.mod5
Expand Down
26 changes: 18 additions & 8 deletions test-data/unit/check-modules.test
Original file line number Diff line number Diff line change
Expand Up @@ -153,17 +153,18 @@ def f(c:str) -> None: pass
[case testInvalidOperationsOnModules]
import m
import typing

class A: pass
m() # E: "module" not callable
a = m # type: A # E: Incompatible types in assignment (expression has type "module", variable has type "A")
m + None # E: Unsupported left operand type for + ("module")
m() # E: "ModuleType" not callable
a = m # type: A # E: Incompatible types in assignment (expression has type "ModuleType", variable has type "A")
m + None # E: Unsupported left operand type for + ("ModuleType")
[file m.py]
[builtins fixtures/module.pyi]

[case testNameDefinedInDifferentModule]
import m, n
import typing
m.x # E: "module" has no attribute "x"
m.x # E: "ModuleType" has no attribute "x"
[file m.py]
y = object()
[file n.py]
Expand Down Expand Up @@ -329,7 +330,7 @@ import nonexistent
[out]
tmp/x.py:1: error: Cannot find module named 'nonexistent'
tmp/x.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:3: error: "module" has no attribute "z"
main:3: error: "ModuleType" has no attribute "z"

[case testUnknownModuleImportedWithinFunction]
def f():
Expand Down Expand Up @@ -647,7 +648,7 @@ def f(x: str) -> None: pass
if object():
import m
else:
m = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "module")
m = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "ModuleType")
[file m.py]
[builtins fixtures/module.pyi]
[out]
Expand Down Expand Up @@ -751,7 +752,7 @@ value = 3.2
[case testSubmoduleImportFromDoesNotAddParents]
from a import b
reveal_type(b.value) # E: Revealed type is 'builtins.str'
b.c.value # E: "module" has no attribute "c"
b.c.value # E: "ModuleType" has no attribute "c"
a.value # E: Name 'a' is not defined

[file a/__init__.py]
Expand Down Expand Up @@ -852,7 +853,7 @@ bar = parent.unrelated.ShouldNotLoad()
[builtins fixtures/module.pyi]
[out]
tmp/parent/child.py:8: error: Revealed type is 'parent.common.SomeClass'
tmp/parent/child.py:9: error: "module" has no attribute "unrelated"
tmp/parent/child.py:9: error: "ModuleType" has no attribute "unrelated"

[case testSubmoduleMixingImportFromAndImport2]
import parent.child
Expand Down Expand Up @@ -1406,3 +1407,12 @@ reveal_type(cb) # E: Revealed type is 'def (*Any, **Any) -> Any'
from typing import Callable, Any
AnyCallable = Callable[..., Any]
[out]

[case testRevealType]
import types
def f() -> types.ModuleType:
return types
reveal_type(f()) # E: Revealed type is 'types.ModuleType'
reveal_type(types) # E: Revealed type is 'types.ModuleType'

[builtins fixtures/module.pyi]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a \n character at the end of this line.

8 changes: 4 additions & 4 deletions test-data/unit/cmdline.test
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,8 @@ x += '' # Error reported here
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")
main.py:7: error: "ModuleType" has no attribute "y"
main.py:8: error: Unsupported operand types for + ("ModuleType" and "int")

[case testConfigFollowImportsSilent]
# cmd: mypy main.py
Expand All @@ -386,8 +386,8 @@ 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")
main.py:5: error: "ModuleType" has no attribute "y"
main.py:6: error: Unsupported operand types for + ("ModuleType" and "int")

[case testConfigFollowImportsSkip]
# cmd: mypy main.py
Expand Down
6 changes: 5 additions & 1 deletion test-data/unit/fixtures/async_await.pyi
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import typing

T = typing.TypeVar('T')
class list(typing.Generic[T], typing.Sequence[T]): pass

class object:
def __init__(self): pass
class type: pass
class function: pass
class int: pass
class str: pass
class dict: pass
class list: pass
class set: pass
class tuple: pass
class BaseException: pass
class StopIteration(BaseException): pass
class StopAsyncIteration(BaseException): pass
def iter(obj: typing.Any) -> typing.Any: pass
def next(obj: typing.Any) -> typing.Any: pass
class ellipsis: ...
11 changes: 6 additions & 5 deletions test-data/unit/fixtures/module.pyi
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
from typing import Any, Dict, Generic, TypeVar
from typing import Any, Dict, Generic, TypeVar, Sequence
from types import ModuleType

T = TypeVar('T')
S = TypeVar('S')

class list(Generic[T], Sequence[T]): pass

class object:
def __init__(self) -> None: pass
class module:
__name__ = ... # type: str
__file__ = ... # type: str
__dict__ = ... # type: Dict[str, Any]
class type: pass
class function: pass
class int: pass
class str: pass
class bool: pass
class tuple: pass
class dict(Generic[T, S]): pass
class ellipsis: pass

5 changes: 4 additions & 1 deletion test-data/unit/fixtures/module_all.pyi
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
from typing import Generic, Sequence, TypeVar
from types import ModuleType

_T = TypeVar('_T')

class object:
def __init__(self) -> None: pass
class module: pass
class type: pass
class function: pass
class int: pass
class str: pass
class bool: pass
class list(Generic[_T], Sequence[_T]):
def append(self, x: _T): pass
def extend(self, x: Sequence[_T]): pass
def __add__(self, rhs: Sequence[_T]) -> list[_T]: pass
class tuple: pass
class ellipsis: pass
32 changes: 31 additions & 1 deletion test-data/unit/lib-stub/types.pyi
Original file line number Diff line number Diff line change
@@ -1,4 +1,34 @@
from typing import TypeVar
from typing import TypeVar, Optional, List, Any, Generic, Sequence
T = TypeVar('T')

def coroutine(func: T) -> T:
return func

class bool: ...

class ModuleSpec:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to prune the contents of this file some? It looks like you just copied from typeshed -- but in order to avoid slowing down the tests we should really only include attributes that tests reference.

def __init__(self, name: str, loader: Optional['Loader'], *,
origin: str = None, loader_state: Any = None,
is_package: bool = None) -> None: ...
name = ... # type: str
loader = ... # type: Optional[Loader]
origin = ... # type: Optional[str]
submodule_search_locations = ... # type: Optional[List[str]]
loader_state = ... # type: Any
cached = ... # type: Optional[str]
parent = ... # type: Optional[str]
has_location = ... # type: bool

class Loader:
def load_module(self, fullname: str) -> ModuleType: ...
def module_repr(self, module: ModuleType) -> str: ...
def create_module(self, spec: ModuleSpec) -> Optional[ModuleType]: ...
def exec_module(self, module: ModuleType) -> None: ...

class ModuleType:
__name__ = ... # type: str
__file__ = ... # type: str
__loader__ = ... # type: Optional[Loader]
__package__ = ... # type: Optional[str]
__spec__ = ... # type: Optional[ModuleSpec]
def __init__(self, name: str, doc: Optional[str] = ...) -> None: ...
4 changes: 2 additions & 2 deletions test-data/unit/pythoneval.test
Original file line number Diff line number Diff line change
Expand Up @@ -1169,8 +1169,8 @@ collections.Deque()
typing.deque()

[out]
_testDequeWrongCase.py:4: error: "module" has no attribute "Deque"
_testDequeWrongCase.py:5: error: "module" has no attribute "deque"
_testDequeWrongCase.py:4: error: "ModuleType" has no attribute "Deque"
_testDequeWrongCase.py:5: error: "ModuleType" has no attribute "deque"

[case testDictUpdateInference]
from typing import Dict, Optional
Expand Down