Skip to content

Commit 09676c9

Browse files
authored
Don't crash if module shadows special library module such as "typing" (#8405)
Special cases a small set of modules so that they must be defined in typeshed, as otherwise it's likely that mypy can crash, as it assumes that various things are defined in very specific ways in these modules. Fixes #1876.
1 parent cdf943a commit 09676c9

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

mypy/build.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
from mypy.errors import Errors, CompileError, ErrorInfo, report_internal_error
3737
from mypy.util import (
3838
DecodeError, decode_python_encoding, is_sub_path, get_mypy_comments, module_prefix,
39-
read_py_file, hash_digest,
39+
read_py_file, hash_digest, is_typeshed_file
4040
)
4141
if TYPE_CHECKING:
4242
from mypy.report import Reports # Avoid unconditional slow import
@@ -66,6 +66,18 @@
6666
# that it's easy to enable this when running tests.
6767
DEBUG_FINE_GRAINED = False # type: Final
6868

69+
# These modules are special and should always come from typeshed.
70+
CORE_BUILTIN_MODULES = {
71+
'builtins',
72+
'typing',
73+
'types',
74+
'typing_extensions',
75+
'mypy_extensions',
76+
'_importlib_modulespec',
77+
'sys',
78+
'abc',
79+
}
80+
6981

7082
Graph = Dict[str, 'State']
7183

@@ -2390,6 +2402,14 @@ def find_module_and_diagnose(manager: BuildManager,
23902402
if is_sub_path(path, dir):
23912403
# Silence errors in site-package dirs and typeshed
23922404
follow_imports = 'silent'
2405+
if (id in CORE_BUILTIN_MODULES
2406+
and not is_typeshed_file(path)
2407+
and not options.use_builtins_fixtures
2408+
and not options.custom_typeshed_dir):
2409+
raise CompileError([
2410+
'mypy: "%s" shadows library module "%s"' % (path, id),
2411+
'note: A user-defined top-level module with name "%s" is not supported' % id
2412+
])
23932413
return (path, follow_imports)
23942414
else:
23952415
# Could not find a module. Typically the reason is a

mypy/test/testpythoneval.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ def test_python_evaluation(testcase: DataDrivenTestCase, cache_dir: str) -> None
8888
if line.startswith(test_temp_dir + os.sep):
8989
output.append(line[len(test_temp_dir + os.sep):].rstrip("\r\n"))
9090
else:
91+
# Normalize paths so that the output is the same on Windows and Linux/macOS.
92+
line = line.replace(test_temp_dir + os.sep, test_temp_dir + '/')
9193
output.append(line.rstrip("\r\n"))
9294
if returncode == 0:
9395
# Execute the program.

test-data/unit/pythoneval.test

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,3 +1501,12 @@ from typing import List
15011501
async def foo() -> None:
15021502
f = [] # type: List[Future[None]]
15031503
await wait(f)
1504+
1505+
[case testShadowTypingModule]
1506+
1 + ''
1507+
[file typing.py]
1508+
x = 0
1509+
1 + ''
1510+
[out]
1511+
mypy: "tmp/typing.py" shadows library module "typing"
1512+
note: A user-defined top-level module with name "typing" is not supported

0 commit comments

Comments
 (0)