Skip to content

Commit f864903

Browse files
authored
Merge pull request #7175 from chrahunt/refactor/centralize-setuptools-args
Centralize setuptools args construction
2 parents c4009ec + 66c3e60 commit f864903

File tree

4 files changed

+182
-87
lines changed

4 files changed

+182
-87
lines changed

src/pip/_internal/operations/generate_metadata.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66

77
from pip._internal.exceptions import InstallationError
88
from pip._internal.utils.misc import ensure_dir
9-
from pip._internal.utils.setuptools_build import make_setuptools_shim_args
9+
from pip._internal.utils.setuptools_build import make_setuptools_egg_info_args
1010
from pip._internal.utils.subprocess import call_subprocess
1111
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
1212
from pip._internal.vcs import vcs
1313

1414
if MYPY_CHECK_RUNNING:
15-
from typing import Callable, List
15+
from typing import Callable, List, Optional
16+
1617
from pip._internal.req.req_install import InstallRequirement
1718

1819
logger = logging.getLogger(__name__)
@@ -99,27 +100,27 @@ def _generate_metadata_legacy(install_req):
99100
install_req.setup_py_path, req_details_str,
100101
)
101102

102-
# Compose arguments for subprocess call
103-
base_cmd = make_setuptools_shim_args(install_req.setup_py_path)
104-
if install_req.isolated:
105-
base_cmd += ["--no-user-cfg"]
106-
103+
egg_info_dir = None # type: Optional[str]
107104
# For non-editable installs, don't put the .egg-info files at the root,
108105
# to avoid confusion due to the source code being considered an installed
109106
# egg.
110-
egg_base_option = [] # type: List[str]
111107
if not install_req.editable:
112108
egg_info_dir = os.path.join(
113109
install_req.unpacked_source_directory, 'pip-egg-info',
114110
)
115-
egg_base_option = ['--egg-base', egg_info_dir]
116111

117112
# setuptools complains if the target directory does not exist.
118113
ensure_dir(egg_info_dir)
119114

115+
args = make_setuptools_egg_info_args(
116+
install_req.setup_py_path,
117+
egg_info_dir=egg_info_dir,
118+
no_user_config=install_req.isolated,
119+
)
120+
120121
with install_req.build_env:
121122
call_subprocess(
122-
base_cmd + ["egg_info"] + egg_base_option,
123+
args,
123124
cwd=install_req.unpacked_source_directory,
124125
command_desc='python setup.py egg_info',
125126
)

src/pip/_internal/req/req_install.py

Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@
4848
rmtree,
4949
)
5050
from pip._internal.utils.packaging import get_metadata
51-
from pip._internal.utils.setuptools_build import make_setuptools_shim_args
51+
from pip._internal.utils.setuptools_build import (
52+
make_setuptools_develop_args,
53+
make_setuptools_install_args,
54+
)
5255
from pip._internal.utils.subprocess import (
5356
call_subprocess,
5457
runner_with_spinner_message,
@@ -690,20 +693,18 @@ def install_editable(
690693
# type: (...) -> None
691694
logger.info('Running setup.py develop for %s', self.name)
692695

693-
if prefix:
694-
prefix_param = ['--prefix={}'.format(prefix)]
695-
install_options = list(install_options) + prefix_param
696-
base_cmd = make_setuptools_shim_args(
696+
args = make_setuptools_develop_args(
697697
self.setup_py_path,
698698
global_options=global_options,
699-
no_user_config=self.isolated
699+
install_options=install_options,
700+
no_user_config=self.isolated,
701+
prefix=prefix,
700702
)
703+
701704
with indent_log():
702705
with self.build_env:
703706
call_subprocess(
704-
base_cmd +
705-
['develop', '--no-deps'] +
706-
list(install_options),
707+
args,
707708
cwd=self.unpacked_source_directory,
708709
)
709710

@@ -880,18 +881,33 @@ def install(
880881
install_options = list(install_options) + \
881882
self.options.get('install_options', [])
882883

884+
header_dir = None # type: Optional[str]
885+
if running_under_virtualenv():
886+
py_ver_str = 'python' + sysconfig.get_python_version()
887+
header_dir = os.path.join(
888+
sys.prefix, 'include', 'site', py_ver_str, self.name
889+
)
890+
883891
with TempDirectory(kind="record") as temp_dir:
884892
record_filename = os.path.join(temp_dir.path, 'install-record.txt')
885-
install_args = self.get_install_args(
886-
global_options, record_filename, root, prefix, pycompile,
893+
install_args = make_setuptools_install_args(
894+
self.setup_py_path,
895+
global_options=global_options,
896+
install_options=install_options,
897+
record_filename=record_filename,
898+
root=root,
899+
prefix=prefix,
900+
header_dir=header_dir,
901+
no_user_config=self.isolated,
902+
pycompile=pycompile,
887903
)
888904

889905
runner = runner_with_spinner_message(
890906
"Running setup.py install for {}".format(self.name)
891907
)
892908
with indent_log(), self.build_env:
893909
runner(
894-
cmd=install_args + install_options,
910+
cmd=install_args,
895911
cwd=self.unpacked_source_directory,
896912
)
897913

@@ -935,39 +951,3 @@ def prepend_root(path):
935951
inst_files_path = os.path.join(egg_info_dir, 'installed-files.txt')
936952
with open(inst_files_path, 'w') as f:
937953
f.write('\n'.join(new_lines) + '\n')
938-
939-
def get_install_args(
940-
self,
941-
global_options, # type: Sequence[str]
942-
record_filename, # type: str
943-
root, # type: Optional[str]
944-
prefix, # type: Optional[str]
945-
pycompile # type: bool
946-
):
947-
# type: (...) -> List[str]
948-
install_args = make_setuptools_shim_args(
949-
self.setup_py_path,
950-
global_options=global_options,
951-
no_user_config=self.isolated,
952-
unbuffered_output=True
953-
)
954-
install_args += ['install', '--record', record_filename]
955-
install_args += ['--single-version-externally-managed']
956-
957-
if root is not None:
958-
install_args += ['--root', root]
959-
if prefix is not None:
960-
install_args += ['--prefix', prefix]
961-
962-
if pycompile:
963-
install_args += ["--compile"]
964-
else:
965-
install_args += ["--no-compile"]
966-
967-
if running_under_virtualenv():
968-
py_ver_str = 'python' + sysconfig.get_python_version()
969-
install_args += ['--install-headers',
970-
os.path.join(sys.prefix, 'include', 'site',
971-
py_ver_str, self.name)]
972-
973-
return install_args

src/pip/_internal/utils/setuptools_build.py

Lines changed: 128 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
44

55
if MYPY_CHECK_RUNNING:
6-
from typing import List, Sequence
6+
from typing import List, Optional, Sequence
77

88
# Shim to wrap setup.py invocation with setuptools
99
#
@@ -21,10 +21,10 @@
2121

2222

2323
def make_setuptools_shim_args(
24-
setup_py_path, # type: str
25-
global_options=None, # type: Sequence[str]
26-
no_user_config=False, # type: bool
27-
unbuffered_output=False # type: bool
24+
setup_py_path, # type: str
25+
global_options=None, # type: Sequence[str]
26+
no_user_config=False, # type: bool
27+
unbuffered_output=False # type: bool
2828
):
2929
# type: (...) -> List[str]
3030
"""
@@ -38,10 +38,129 @@ def make_setuptools_shim_args(
3838
"""
3939
args = [sys.executable]
4040
if unbuffered_output:
41-
args.append('-u')
42-
args.extend(['-c', _SETUPTOOLS_SHIM.format(setup_py_path)])
41+
args += ["-u"]
42+
args += ["-c", _SETUPTOOLS_SHIM.format(setup_py_path)]
4343
if global_options:
44-
args.extend(global_options)
44+
args += global_options
4545
if no_user_config:
46-
args.append('--no-user-cfg')
46+
args += ["--no-user-cfg"]
47+
return args
48+
49+
50+
def make_setuptools_bdist_wheel_args(
51+
setup_py_path, # type: str
52+
global_options, # type: Sequence[str]
53+
build_options, # type: Sequence[str]
54+
destination_dir, # type: str
55+
python_tag, # type: Optional[str]
56+
):
57+
# type: (...) -> List[str]
58+
# NOTE: Eventually, we'd want to also -S to the flags here, when we're
59+
# isolating. Currently, it breaks Python in virtualenvs, because it
60+
# relies on site.py to find parts of the standard library outside the
61+
# virtualenv.
62+
args = make_setuptools_shim_args(
63+
setup_py_path,
64+
global_options=global_options,
65+
unbuffered_output=True
66+
)
67+
args += ["bdist_wheel", "-d", destination_dir]
68+
args += build_options
69+
if python_tag is not None:
70+
args += ["--python-tag", python_tag]
71+
return args
72+
73+
74+
def make_setuptools_clean_args(
75+
setup_py_path, # type: str
76+
global_options, # type: Sequence[str]
77+
):
78+
# type: (...) -> List[str]
79+
args = make_setuptools_shim_args(
80+
setup_py_path,
81+
global_options=global_options,
82+
unbuffered_output=True
83+
)
84+
args += ["clean", "--all"]
85+
return args
86+
87+
88+
def make_setuptools_develop_args(
89+
setup_py_path, # type: str
90+
global_options, # type: Sequence[str]
91+
install_options, # type: Sequence[str]
92+
no_user_config, # type: bool
93+
prefix, # type: Optional[str]
94+
):
95+
# type: (...) -> List[str]
96+
args = make_setuptools_shim_args(
97+
setup_py_path,
98+
global_options=global_options,
99+
no_user_config=no_user_config,
100+
)
101+
102+
args += ["develop", "--no-deps"]
103+
104+
args += install_options
105+
106+
if prefix:
107+
args += ["--prefix", prefix]
108+
109+
return args
110+
111+
112+
def make_setuptools_egg_info_args(
113+
setup_py_path, # type: str
114+
egg_info_dir, # type: Optional[str]
115+
no_user_config, # type: bool
116+
):
117+
# type: (...) -> List[str]
118+
args = make_setuptools_shim_args(setup_py_path)
119+
if no_user_config:
120+
args += ["--no-user-cfg"]
121+
122+
args += ["egg_info"]
123+
124+
if egg_info_dir:
125+
args += ["--egg-base", egg_info_dir]
126+
127+
return args
128+
129+
130+
def make_setuptools_install_args(
131+
setup_py_path, # type: str
132+
global_options, # type: Sequence[str]
133+
install_options, # type: Sequence[str]
134+
record_filename, # type: str
135+
root, # type: Optional[str]
136+
prefix, # type: Optional[str]
137+
header_dir, # type: Optional[str]
138+
no_user_config, # type: bool
139+
pycompile # type: bool
140+
):
141+
# type: (...) -> List[str]
142+
args = make_setuptools_shim_args(
143+
setup_py_path,
144+
global_options=global_options,
145+
no_user_config=no_user_config,
146+
unbuffered_output=True
147+
)
148+
args += ["install", "--record", record_filename]
149+
args += ["--single-version-externally-managed"]
150+
151+
if root is not None:
152+
args += ["--root", root]
153+
if prefix is not None:
154+
args += ["--prefix", prefix]
155+
156+
if pycompile:
157+
args += ["--compile"]
158+
else:
159+
args += ["--no-compile"]
160+
161+
if header_dir:
162+
args += ["--install-headers", header_dir]
163+
164+
args += install_options
165+
47166
return args

src/pip/_internal/wheel.py

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@
3939
from pip._internal.utils.logging import indent_log
4040
from pip._internal.utils.marker_files import has_delete_marker_file
4141
from pip._internal.utils.misc import captured_stdout, ensure_dir, read_chunks
42-
from pip._internal.utils.setuptools_build import make_setuptools_shim_args
42+
from pip._internal.utils.setuptools_build import (
43+
make_setuptools_bdist_wheel_args,
44+
make_setuptools_clean_args,
45+
)
4346
from pip._internal.utils.subprocess import (
4447
LOG_DIVIDER,
4548
call_subprocess,
@@ -957,17 +960,6 @@ def _build_one_inside_env(self, req, output_dir, python_tag=None):
957960
self._clean_one(req)
958961
return None
959962

960-
def _base_setup_args(self, req):
961-
# NOTE: Eventually, we'd want to also -S to the flags here, when we're
962-
# isolating. Currently, it breaks Python in virtualenvs, because it
963-
# relies on site.py to find parts of the standard library outside the
964-
# virtualenv.
965-
return make_setuptools_shim_args(
966-
req.setup_py_path,
967-
global_options=self.global_options,
968-
unbuffered_output=True
969-
)
970-
971963
def _build_one_pep517(self, req, tempd, python_tag=None):
972964
"""Build one InstallRequirement using the PEP 517 build process.
973965
@@ -1012,16 +1004,17 @@ def _build_one_legacy(self, req, tempd, python_tag=None):
10121004
10131005
Returns path to wheel if successfully built. Otherwise, returns None.
10141006
"""
1015-
base_args = self._base_setup_args(req)
1007+
wheel_args = make_setuptools_bdist_wheel_args(
1008+
req.setup_py_path,
1009+
global_options=self.global_options,
1010+
build_options=self.build_options,
1011+
destination_dir=tempd,
1012+
python_tag=python_tag,
1013+
)
10161014

10171015
spin_message = 'Building wheel for %s (setup.py)' % (req.name,)
10181016
with open_spinner(spin_message) as spinner:
10191017
logger.debug('Destination directory: %s', tempd)
1020-
wheel_args = base_args + ['bdist_wheel', '-d', tempd] \
1021-
+ self.build_options
1022-
1023-
if python_tag is not None:
1024-
wheel_args += ["--python-tag", python_tag]
10251018

10261019
try:
10271020
output = call_subprocess(
@@ -1045,10 +1038,12 @@ def _build_one_legacy(self, req, tempd, python_tag=None):
10451038
return wheel_path
10461039

10471040
def _clean_one(self, req):
1048-
base_args = self._base_setup_args(req)
1041+
clean_args = make_setuptools_clean_args(
1042+
req.setup_py_path,
1043+
global_options=self.global_options,
1044+
)
10491045

10501046
logger.info('Running setup.py clean for %s', req.name)
1051-
clean_args = base_args + ['clean', '--all']
10521047
try:
10531048
call_subprocess(clean_args, cwd=req.source_dir)
10541049
return True

0 commit comments

Comments
 (0)