Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
6 changes: 4 additions & 2 deletions mypy/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import sys
import traceback

from mypy.fscache import FileSystemCache
from mypy.main import main, process_options
from mypy.util import FancyFormatter

Expand All @@ -22,7 +23,8 @@ def console_entry() -> None:
os.dup2(devnull, sys.stdout.fileno())
sys.exit(2)
except KeyboardInterrupt:
_, options = process_options(args=sys.argv[1:])
# Setting fscache prevents bogus errors when --package-root is set.
_, options = process_options(args=sys.argv[1:], fscache=FileSystemCache())
if options.show_traceback:
sys.stdout.write(traceback.format_exc())
formatter = FancyFormatter(sys.stdout, sys.stderr, False)
Expand All @@ -36,7 +38,7 @@ def console_entry() -> None:
try:
import mypy.errors

_, options = process_options(args=sys.argv[1:])
_, options = process_options(args=sys.argv[1:], fscache=FileSystemCache())
mypy.errors.report_internal_error(e, None, 0, None, options)
except Exception:
pass
Expand Down
5 changes: 2 additions & 3 deletions mypy/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,7 @@ def parse_all(self, states: list[State], post_parse: bool = True) -> None:
if state.tree is not None:
# The file was already parsed.
continue
if not self.fscache.exists(state.xpath):
if not self.fscache.exists(state.xpath, real_only=True):
# New parser only supports parsing on-disk files.
sequential_states.append(state)
continue
Expand Down Expand Up @@ -1083,7 +1083,6 @@ def parse_parallel(self, sequential_states: list[State], parallel_states: list[S
elif state.source_hash is None:
# At least namespace packages may not have source.
state.get_source()
state.size_hint = os.path.getsize(state.xpath)
state.early_errors = list(self.errors.error_info_map.get(state.xpath, []))
state.semantic_analysis_pass1()
self.ast_cache[state.id] = (state.tree, state.early_errors, state.source_hash)
Expand Down Expand Up @@ -1271,7 +1270,7 @@ def parse_file(

Raise CompileError if there is a parse error.
"""
file_exists = self.fscache.exists(path)
file_exists = self.fscache.exists(path, real_only=True)
t0 = time.time()
if raw_data:
# If possible, deserialize from known binary data instead of parsing from scratch.
Expand Down
1 change: 1 addition & 0 deletions mypy/build_worker/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ def main(argv: list[str]) -> None:
raise

fscache = FileSystemCache()
fscache.set_package_root(options.package_root)
cached_read = fscache.read
errors = Errors(options, read_source=lambda path: read_py_file(path, cached_read))

Expand Down
9 changes: 7 additions & 2 deletions mypy/fscache.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,9 +253,14 @@ def isdir(self, path: str) -> bool:
return False
return stat.S_ISDIR(st.st_mode)

def exists(self, path: str) -> bool:
def exists(self, path: str, real_only: bool = False) -> bool:
st = self.stat_or_none(path)
return st is not None
if st is None:
return False
if real_only:
dirname, _ = os.path.split(path)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

os.path.dirname(path) may be faster, as it may construct one fewer substring (but haven't verified).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

OoC I checked and it is indeed ~20% faster.

return dirname not in self.fake_package_cache
return True

def read(self, path: str) -> bytes:
if path in self.read_cache:
Expand Down
8 changes: 8 additions & 0 deletions test-data/unit/cmdline.test
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,14 @@ import d
import b.c
import d

[case testPackageRootMultipleParallel]
# cmd: mypy --package-root=a/ --package-root=./ a/b/c.py d.py main.py --num-workers=2
[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.)
Expand Down
Loading