Skip to content

Commit 35ccbd1

Browse files
committed
Rewrite regression test
1 parent 72e2366 commit 35ccbd1

File tree

2 files changed

+48
-34
lines changed

2 files changed

+48
-34
lines changed

tests/functional/test_cli.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
"""Basic CLI functionality checks.
22
"""
3+
import subprocess
4+
import sys
5+
from pathlib import Path
36
from textwrap import dedent
47

58
import pytest
69

10+
from pip._internal.commands import commands_dict
711
from tests.lib import PipTestEnvironment
812

913

@@ -45,3 +49,47 @@ def test_entrypoints_work(entrypoint: str, script: PipTestEnvironment) -> None:
4549
result2 = script.run("fake_pip", "-V", allow_stderr_warning=True)
4650
assert result.stdout == result2.stdout
4751
assert "old script wrapper" in result2.stderr
52+
53+
54+
@pytest.mark.parametrize(
55+
"command",
56+
set(commands_dict).symmetric_difference(
57+
# Exclude commands that are expected to use the network.
58+
# TODO: uninstall and list should only import network modules as needed
59+
{"install", "uninstall", "download", "search", "index", "wheel", "list"}
60+
),
61+
)
62+
def test_no_network_imports(command: str, tmp_path: Path) -> None:
63+
"""
64+
Verify that commands that don't access the network do NOT import network code.
65+
66+
This helps to reduce the startup time of these commands.
67+
68+
Note: This won't catch lazy network imports, but it'll catch top-level
69+
network imports which were accidently added (which is the most likely way
70+
to regress anyway).
71+
"""
72+
file = Path(tmp_path, f"imported_modules_for_{command}")
73+
code = f"""
74+
import runpy
75+
import sys
76+
77+
sys.argv[1:] = [{command!r}, "--help"]
78+
79+
try:
80+
runpy.run_module("pip", alter_sys=True, run_name="__main__")
81+
finally:
82+
with open({str(file)!r}, "w") as f:
83+
print(*sys.modules.keys(), sep="\\n", file=f)
84+
"""
85+
subprocess.run(
86+
[sys.executable],
87+
input=code,
88+
encoding="utf-8",
89+
check=True,
90+
)
91+
imported = file.read_text().splitlines()
92+
assert not any("pip._internal.index" in mod for mod in imported)
93+
assert not any("pip._internal.network" in mod for mod in imported)
94+
assert not any("requests" in mod for mod in imported)
95+
assert not any("urllib3" in mod for mod in imported)

tests/unit/test_commands.py

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import subprocess
2-
import sys
31
from typing import Callable, List
42
from unittest import mock
53

@@ -122,35 +120,3 @@ def is_requirement_command(command: Command) -> bool:
122120
return isinstance(command, RequirementCommand)
123121

124122
check_commands(is_requirement_command, ["download", "install", "wheel"])
125-
126-
127-
@pytest.mark.parametrize(
128-
"command", ["cache", "check", "config", "freeze", "hash", "help", "inspect", "show"]
129-
)
130-
def test_no_network_imports(command: str) -> None:
131-
"""
132-
Verify that commands that don't access the network do NOT import network code.
133-
134-
This helps to reduce the startup time of these commands.
135-
136-
Note: This won't catch lazy network imports, but it'll catch top-level
137-
network imports which were accidently added (which is the most likely way
138-
to regress anyway).
139-
"""
140-
code = f"""
141-
import sys
142-
from pip._internal.commands import create_command
143-
144-
command = create_command("{command}")
145-
names = sorted(mod.__name__ for mod in sys.modules.values())
146-
for mod in names:
147-
print(mod)
148-
"""
149-
proc = subprocess.run(
150-
[sys.executable], encoding="utf-8", input=code, capture_output=True, check=True
151-
)
152-
imported = proc.stdout.splitlines()
153-
assert not any("pip._internal.index" in mod for mod in imported)
154-
assert not any("pip._internal.network" in mod for mod in imported)
155-
assert not any("requests" in mod for mod in imported)
156-
assert not any("urllib3" in mod for mod in imported)

0 commit comments

Comments
 (0)