Skip to content

Commit 2f77339

Browse files
committed
Support passing dist-info-dir to bdist_wheel, enabling setuptools to handle prepare_metadata_for_build_wheel correctly as per PEP-517. Closes #611
1 parent 0a4f40e commit 2f77339

File tree

2 files changed

+43
-3
lines changed

2 files changed

+43
-3
lines changed

src/wheel/bdist_wheel.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,12 @@ class bdist_wheel(Command):
219219
None,
220220
"Python tag (cp32|cp33|cpNN) for abi3 wheel tag" " (default: false)",
221221
),
222+
(
223+
"dist-info-dir=",
224+
None,
225+
"directory where a pre-generated dist-info can be found (e.g. as a "
226+
"result of calling the PEP517 'prepare_metadata_for_build_wheel' "
227+
"method)"),
222228
]
223229

224230
boolean_options = ["keep-temp", "skip-build", "relative", "universal"]
@@ -231,6 +237,7 @@ def initialize_options(self):
231237
self.format = "zip"
232238
self.keep_temp = False
233239
self.dist_dir = None
240+
self.dist_info_dir = None
234241
self.egginfo_dir = None
235242
self.root_is_pure = None
236243
self.skip_build = None
@@ -249,8 +256,9 @@ def finalize_options(self):
249256
bdist_base = self.get_finalized_command("bdist").bdist_base
250257
self.bdist_dir = os.path.join(bdist_base, "wheel")
251258

252-
egg_info = self.distribution.get_command_obj("egg_info")
253-
egg_info.ensure_finalized() # needed for correct `wheel_dist_name`
259+
if self.dist_info_dir is None:
260+
egg_info = self.distribution.get_command_obj("egg_info")
261+
egg_info.ensure_finalized() # needed for correct `wheel_dist_name`
254262

255263
self.data_dir = self.wheel_dist_name + ".data"
256264
self.plat_name_supplied = self.plat_name is not None
@@ -412,12 +420,21 @@ def run(self):
412420
)
413421

414422
self.set_undefined_options("install_egg_info", ("target", "egginfo_dir"))
423+
415424
distinfo_dirname = (
416425
f"{safer_name(self.distribution.get_name())}-"
417426
f"{safer_version(self.distribution.get_version())}.dist-info"
418427
)
419428
distinfo_dir = os.path.join(self.bdist_dir, distinfo_dirname)
420-
self.egg2dist(self.egginfo_dir, distinfo_dir)
429+
if self.dist_info_dir:
430+
# Use the given dist-info directly.
431+
shutil.copytree(self.dist_info_dir, distinfo_dir)
432+
# Egg info is still generated, so remove it now to avoid it getting
433+
# copied into the wheel.
434+
shutil.rmtree(self.egginfo_dir)
435+
else:
436+
# Convert the generated egg-info into dist-info.
437+
self.egg2dist(self.egginfo_dir, distinfo_dir)
421438

422439
self.write_wheelfile(distinfo_dir)
423440

tests/test_bdist_wheel.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,29 @@ def license_paths(self):
123123
assert "UTF-8 描述 説明" in metadata
124124

125125

126+
def test_dist_info_provided(dummy_dist, monkeypatch, tmp_path):
127+
monkeypatch.chdir(dummy_dist)
128+
distinfo = tmp_path / "dummy_dist.dist-info"
129+
distinfo.mkdir()
130+
(distinfo / 'METADATA').write_text("name: helloworld", encoding="utf-8")
131+
132+
# We don't control the metadata. According to PEP-517, "The hook MAY also
133+
# create other files inside this directory, and a build frontend MUST
134+
# preserve".
135+
(distinfo / 'FOO').write_text("bar", encoding="utf-8")
136+
subprocess.check_call(
137+
[
138+
sys.executable, "setup.py", "bdist_wheel",
139+
"-b", str(tmp_path), "--universal",
140+
"--dist-info-dir", str(distinfo),
141+
],
142+
)
143+
with WheelFile("dist/dummy_dist-1.0-py2.py3-none-any.whl") as wf:
144+
with wf.open("dummy_dist-1.0.dist-info/METADATA") as fh:
145+
assert fh.read() == b'name: helloworld'
146+
assert 'dummy_dist-1.0.dist-info/FOO' in list(wf.namelist())
147+
148+
126149
def test_licenses_default(dummy_dist, monkeypatch, tmp_path):
127150
monkeypatch.chdir(dummy_dist)
128151
subprocess.check_call(

0 commit comments

Comments
 (0)