Skip to content

Don't crash if module shadows special library module such as "typing" #8405

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
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
22 changes: 21 additions & 1 deletion mypy/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
from mypy.errors import Errors, CompileError, ErrorInfo, report_internal_error
from mypy.util import (
DecodeError, decode_python_encoding, is_sub_path, get_mypy_comments, module_prefix,
read_py_file, hash_digest,
read_py_file, hash_digest, is_typeshed_file
)
if TYPE_CHECKING:
from mypy.report import Reports # Avoid unconditional slow import
Expand Down Expand Up @@ -66,6 +66,18 @@
# that it's easy to enable this when running tests.
DEBUG_FINE_GRAINED = False # type: Final

# These modules are special and should always come from typeshed.
CORE_BUILTIN_MODULES = {
'builtins',
'typing',
'types',
'typing_extensions',
'mypy_extensions',
'_importlib_modulespec',
'sys',
'abc',
}


Graph = Dict[str, 'State']

Expand Down Expand Up @@ -2390,6 +2402,14 @@ def find_module_and_diagnose(manager: BuildManager,
if is_sub_path(path, dir):
# Silence errors in site-package dirs and typeshed
follow_imports = 'silent'
if (id in CORE_BUILTIN_MODULES
and not is_typeshed_file(path)
and not options.use_builtins_fixtures
and not options.custom_typeshed_dir):
raise CompileError([
'mypy: "%s" shadows library module "%s"' % (path, id),
'note: A user-defined top-level module with name "%s" is not supported' % id
])
return (path, follow_imports)
else:
# Could not find a module. Typically the reason is a
Expand Down
2 changes: 2 additions & 0 deletions mypy/test/testpythoneval.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ def test_python_evaluation(testcase: DataDrivenTestCase, cache_dir: str) -> None
if line.startswith(test_temp_dir + os.sep):
output.append(line[len(test_temp_dir + os.sep):].rstrip("\r\n"))
else:
# Normalize paths so that the output is the same on Windows and Linux/macOS.
line = line.replace(test_temp_dir + os.sep, test_temp_dir + '/')
output.append(line.rstrip("\r\n"))
if returncode == 0:
# Execute the program.
Expand Down
9 changes: 9 additions & 0 deletions test-data/unit/pythoneval.test
Original file line number Diff line number Diff line change
Expand Up @@ -1501,3 +1501,12 @@ from typing import List
async def foo() -> None:
f = [] # type: List[Future[None]]
await wait(f)

[case testShadowTypingModule]
1 + ''
[file typing.py]
x = 0
1 + ''
[out]
mypy: "tmp/typing.py" shadows library module "typing"
note: A user-defined top-level module with name "typing" is not supported