Skip to content

Commit

Permalink
Fix custom typeshed dir handling by is_typeshed_file() (#13629)
Browse files Browse the repository at this point in the history
This was broken by #13155, fix is
straightforward, pass custom typeshed dir from options everywhere.

Co-authored-by: Ivan Levkivskyi <ilevkivskyi@dropbox.com>
  • Loading branch information
ilevkivskyi and Ivan Levkivskyi authored Sep 8, 2022
1 parent d8652b4 commit c0372cc
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 17 deletions.
12 changes: 3 additions & 9 deletions mypy/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -668,16 +668,10 @@ def __init__(
raise CompileError(
[f"Failed to find builtin module {module}, perhaps typeshed is broken?"]
)
if is_typeshed_file(path):
if is_typeshed_file(options.abs_custom_typeshed_dir, path) or is_stub_package_file(
path
):
continue
if is_stub_package_file(path):
continue
if options.custom_typeshed_dir is not None:
# Check if module lives under custom_typeshed_dir subtree
custom_typeshed_dir = os.path.abspath(options.custom_typeshed_dir)
path = os.path.abspath(path)
if os.path.commonpath((path, custom_typeshed_dir)) == custom_typeshed_dir:
continue

raise CompileError(
[
Expand Down
2 changes: 1 addition & 1 deletion mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ def __init__(
self.pass_num = 0
self.current_node_deferred = False
self.is_stub = tree.is_stub
self.is_typeshed_stub = is_typeshed_file(path)
self.is_typeshed_stub = is_typeshed_file(options.abs_custom_typeshed_dir, path)
self.inferred_attribute_types = None

# If True, process function definitions. If False, don't. This is used
Expand Down
10 changes: 8 additions & 2 deletions mypy/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,10 @@ def clear_errors_in_targets(self, path: str, targets: set[str]) -> None:
self.has_blockers.remove(path)

def generate_unused_ignore_errors(self, file: str) -> None:
if is_typeshed_file(file) or file in self.ignored_files:
if (
is_typeshed_file(self.options.abs_custom_typeshed_dir if self.options else None, file)
or file in self.ignored_files
):
return
ignored_lines = self.ignored_lines[file]
used_ignored_lines = self.used_ignored_lines[file]
Expand Down Expand Up @@ -658,7 +661,10 @@ def generate_unused_ignore_errors(self, file: str) -> None:
def generate_ignore_without_code_errors(
self, file: str, is_warning_unused_ignores: bool
) -> None:
if is_typeshed_file(file) or file in self.ignored_files:
if (
is_typeshed_file(self.options.abs_custom_typeshed_dir if self.options else None, file)
or file in self.ignored_files
):
return

used_ignored_lines = self.used_ignored_lines[file]
Expand Down
4 changes: 4 additions & 0 deletions mypy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,10 @@ def set_strict_flags() -> None:
# Enabling an error code always overrides disabling
options.disabled_error_codes -= options.enabled_error_codes

# Compute absolute path for custom typeshed (if present).
if options.custom_typeshed_dir is not None:
options.abs_custom_typeshed_dir = os.path.abspath(options.custom_typeshed_dir)

# Set build flags.
if special_opts.find_occurrences:
state.find_occurrences = special_opts.find_occurrences.split(".")
Expand Down
2 changes: 2 additions & 0 deletions mypy/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ def __init__(self) -> None:
self.platform = sys.platform
self.custom_typing_module: str | None = None
self.custom_typeshed_dir: str | None = None
# The abspath() version of the above, we compute it once as an optimization.
self.abs_custom_typeshed_dir: str | None = None
self.mypy_path: list[str] = []
self.report_dirs: dict[str, str] = {}
# Show errors in PEP 561 packages/site-packages modules
Expand Down
4 changes: 3 additions & 1 deletion mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,9 @@ def file_context(
self.cur_mod_id = file_node.fullname
with scope.module_scope(self.cur_mod_id):
self._is_stub_file = file_node.path.lower().endswith(".pyi")
self._is_typeshed_stub_file = is_typeshed_file(file_node.path)
self._is_typeshed_stub_file = is_typeshed_file(
options.abs_custom_typeshed_dir, file_node.path
)
self.globals = file_node.names
self.tvar_scope = TypeVarLikeScope()

Expand Down
12 changes: 10 additions & 2 deletions mypy/semanal_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,11 @@ def check_type_arguments(graph: Graph, scc: list[str], errors: Errors) -> None:
for module in scc:
state = graph[module]
assert state.tree
analyzer = TypeArgumentAnalyzer(errors, state.options, is_typeshed_file(state.path or ""))
analyzer = TypeArgumentAnalyzer(
errors,
state.options,
is_typeshed_file(state.options.abs_custom_typeshed_dir, state.path or ""),
)
with state.wrap_context():
with mypy.state.state.strict_optional_set(state.options.strict_optional):
state.tree.accept(analyzer)
Expand All @@ -381,7 +385,11 @@ def check_type_arguments_in_targets(
This mirrors the logic in check_type_arguments() except that we process only
some targets. This is used in fine grained incremental mode.
"""
analyzer = TypeArgumentAnalyzer(errors, state.options, is_typeshed_file(state.path or ""))
analyzer = TypeArgumentAnalyzer(
errors,
state.options,
is_typeshed_file(state.options.abs_custom_typeshed_dir, state.path or ""),
)
with state.wrap_context():
with mypy.state.state.strict_optional_set(state.options.strict_optional):
for target in targets:
Expand Down
5 changes: 3 additions & 2 deletions mypy/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -769,9 +769,10 @@ def format_error(
return self.style(msg, "red", bold=True)


def is_typeshed_file(file: str) -> bool:
def is_typeshed_file(typeshed_dir: str | None, file: str) -> bool:
typeshed_dir = typeshed_dir if typeshed_dir is not None else TYPESHED_DIR
try:
return os.path.commonpath((TYPESHED_DIR, os.path.abspath(file))) == TYPESHED_DIR
return os.path.commonpath((typeshed_dir, os.path.abspath(file))) == typeshed_dir
except ValueError: # Different drives on Windows
return False

Expand Down

0 comments on commit c0372cc

Please sign in to comment.