Skip to content

Commit d7553fe

Browse files
authored
Fix search paths for -p (python#9387)
`-p` is similar to `-m` except that it will recursively typecheck submodules. Unfortunately the early module walk was being done with search paths that did not benefit from site_packages for the selected python executable, which resulted in some packages being typechecked fine with `-m`, but rejected as `not found` by `-p`. Fixes python#9386
1 parent ec76cca commit d7553fe

File tree

4 files changed

+30
-15
lines changed

4 files changed

+30
-15
lines changed

mypy/main.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414
from mypy import defaults
1515
from mypy import state
1616
from mypy import util
17-
from mypy.modulefinder import BuildSource, FindModuleCache, mypy_path, SearchPaths
17+
from mypy.modulefinder import (
18+
BuildSource, FindModuleCache, SearchPaths,
19+
get_site_packages_dirs, mypy_path,
20+
)
1821
from mypy.find_sources import create_source_list, InvalidSourceList
1922
from mypy.fscache import FileSystemCache
2023
from mypy.errors import CompileError
@@ -921,7 +924,11 @@ def set_strict_flags() -> None:
921924
# Set target.
922925
if special_opts.modules + special_opts.packages:
923926
options.build_type = BuildType.MODULE
924-
search_paths = SearchPaths((os.getcwd(),), tuple(mypy_path() + options.mypy_path), (), ())
927+
egg_dirs, site_packages = get_site_packages_dirs(options.python_executable)
928+
search_paths = SearchPaths((os.getcwd(),),
929+
tuple(mypy_path() + options.mypy_path),
930+
tuple(egg_dirs + site_packages),
931+
())
925932
targets = []
926933
# TODO: use the same cache that the BuildManager will
927934
cache = FindModuleCache(search_paths, fscache, options, special_opts.packages)

mypy/modulefinder.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -473,14 +473,16 @@ def default_lib_path(data_dir: str,
473473

474474

475475
@functools.lru_cache(maxsize=None)
476-
def get_site_packages_dirs(python_executable: str) -> Tuple[List[str], List[str]]:
476+
def get_site_packages_dirs(python_executable: Optional[str]) -> Tuple[List[str], List[str]]:
477477
"""Find package directories for given python.
478478
479479
This runs a subprocess call, which generates a list of the egg directories, and the site
480480
package directories. To avoid repeatedly calling a subprocess (which can be slow!) we
481481
lru_cache the results."""
482482

483-
if python_executable == sys.executable:
483+
if python_executable is None:
484+
return [], []
485+
elif python_executable == sys.executable:
484486
# Use running Python's package dirs
485487
site_packages = sitepkgs.getsitepackages()
486488
else:
@@ -598,11 +600,7 @@ def compute_search_paths(sources: List[BuildSource],
598600
if alt_lib_path:
599601
mypypath.insert(0, alt_lib_path)
600602

601-
if options.python_executable is None:
602-
egg_dirs = [] # type: List[str]
603-
site_packages = [] # type: List[str]
604-
else:
605-
egg_dirs, site_packages = get_site_packages_dirs(options.python_executable)
603+
egg_dirs, site_packages = get_site_packages_dirs(options.python_executable)
606604
for site_dir in site_packages:
607605
assert site_dir not in lib_path
608606
if (site_dir in mypypath or

mypy/test/testpep561.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,15 @@ def test_pep561(testcase: DataDrivenTestCase) -> None:
120120
old_dir = os.getcwd()
121121
os.chdir(venv_dir)
122122
try:
123-
program = testcase.name + '.py'
124-
with open(program, 'w', encoding='utf-8') as f:
125-
for s in testcase.input:
126-
f.write('{}\n'.format(s))
127-
cmd_line = mypy_args + [program, '--no-incremental', '--no-error-summary']
123+
cmd_line = list(mypy_args)
124+
has_program = not ('-p' in cmd_line or '--package' in cmd_line)
125+
if has_program:
126+
program = testcase.name + '.py'
127+
with open(program, 'w', encoding='utf-8') as f:
128+
for s in testcase.input:
129+
f.write('{}\n'.format(s))
130+
cmd_line.append(program)
131+
cmd_line.extend(['--no-incremental', '--no-error-summary'])
128132
if python_executable != sys.executable:
129133
cmd_line.append('--python-executable={}'.format(python_executable))
130134
if testcase.files != []:
@@ -135,7 +139,8 @@ def test_pep561(testcase: DataDrivenTestCase) -> None:
135139
output = []
136140
# Type check the module
137141
out, err, returncode = mypy.api.run(cmd_line)
138-
os.remove(program)
142+
if has_program:
143+
os.remove(program)
139144
# split lines, remove newlines, and remove directory of test case
140145
for line in (out + err).splitlines():
141146
if line.startswith(test_temp_dir + os.sep):

test-data/unit/pep561.test

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ reveal_type(a)
2020
[out]
2121
testTypedPkgSimple.py:5: note: Revealed type is 'builtins.tuple[builtins.str]'
2222

23+
[case testTypedPkgSimplePackageSearchPath]
24+
# pkgs: typedpkg
25+
# flags: -p typedpkg.pkg
26+
[out]
27+
2328
[case testTypedPkg_config_nositepackages]
2429
# pkgs: typedpkg
2530
from typedpkg.sample import ex

0 commit comments

Comments
 (0)