Skip to content

Commit

Permalink
Support the metadata directory (as per PEP-517) for build_wheel (#4647)
Browse files Browse the repository at this point in the history
  • Loading branch information
abravalheri authored Sep 26, 2024
2 parents 3106af0 + fc08e7e commit 89d3e94
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 4 deletions.
1 change: 1 addition & 0 deletions newsfragments/1825.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Re-use pre-existing ``.dist-info`` dir when creating wheels via the build backend APIs (PEP 517) and the ``metadata_directory`` argument is passed -- by :user:`pelson`.
5 changes: 4 additions & 1 deletion setuptools/build_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,9 +417,12 @@ def build_wheel(
config_settings: _ConfigSettings = None,
metadata_directory: StrPath | None = None,
):
cmd = ['bdist_wheel']
if metadata_directory:
cmd.extend(['--dist-info-dir', metadata_directory])
with suppress_known_deprecation():
return self._build_with_temp_dir(
['bdist_wheel'],
cmd,
'.whl',
wheel_directory,
config_settings,
Expand Down
24 changes: 21 additions & 3 deletions setuptools/command/bdist_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,13 @@ class bdist_wheel(Command):
None,
"Python tag (cp32|cp33|cpNN) for abi3 wheel tag [default: false]",
),
(
"dist-info-dir=",
None,
"directory where a pre-generated dist-info can be found (e.g. as a "
"result of calling the PEP517 'prepare_metadata_for_build_wheel' "
"method)",
),
]

boolean_options = ["keep-temp", "skip-build", "relative", "universal"]
Expand All @@ -243,6 +250,7 @@ def initialize_options(self) -> None:
self.format = "zip"
self.keep_temp = False
self.dist_dir: str | None = None
self.dist_info_dir = None
self.egginfo_dir: str | None = None
self.root_is_pure: bool | None = None
self.skip_build = False
Expand All @@ -261,8 +269,9 @@ def finalize_options(self) -> None:
bdist_base = self.get_finalized_command("bdist").bdist_base
self.bdist_dir = os.path.join(bdist_base, "wheel")

egg_info = cast(egg_info_cls, self.distribution.get_command_obj("egg_info"))
egg_info.ensure_finalized() # needed for correct `wheel_dist_name`
if self.dist_info_dir is None:
egg_info = cast(egg_info_cls, self.distribution.get_command_obj("egg_info"))
egg_info.ensure_finalized() # needed for correct `wheel_dist_name`

self.data_dir = self.wheel_dist_name + ".data"
self.plat_name_supplied = bool(self.plat_name)
Expand Down Expand Up @@ -447,7 +456,16 @@ def run(self):
f"{safer_version(self.distribution.get_version())}.dist-info"
)
distinfo_dir = os.path.join(self.bdist_dir, distinfo_dirname)
self.egg2dist(self.egginfo_dir, distinfo_dir)
if self.dist_info_dir:
# Use the given dist-info directly.
log.debug(f"reusing {self.dist_info_dir}")
shutil.copytree(self.dist_info_dir, distinfo_dir)
# Egg info is still generated, so remove it now to avoid it getting
# copied into the wheel.
shutil.rmtree(self.egginfo_dir)
else:
# Convert the generated egg-info into dist-info.
self.egg2dist(self.egginfo_dir, distinfo_dir)

self.write_wheelfile(distinfo_dir)

Expand Down
25 changes: 25 additions & 0 deletions setuptools/tests/test_bdist_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -619,3 +619,28 @@ def _fake_import(name: str, *args, **kwargs):
monkeypatch.delitem(sys.modules, "setuptools.command.bdist_wheel")

import setuptools.command.bdist_wheel # noqa: F401


def test_dist_info_provided(dummy_dist, monkeypatch, tmp_path):
monkeypatch.chdir(dummy_dist)
distinfo = tmp_path / "dummy_dist.dist-info"

distinfo.mkdir()
(distinfo / "METADATA").write_text("name: helloworld", encoding="utf-8")

# We don't control the metadata. According to PEP-517, "The hook MAY also
# create other files inside this directory, and a build frontend MUST
# preserve".
(distinfo / "FOO").write_text("bar", encoding="utf-8")

bdist_wheel_cmd(bdist_dir=str(tmp_path), dist_info_dir=str(distinfo)).run()
expected = {
"dummy_dist-1.0.dist-info/FOO",
"dummy_dist-1.0.dist-info/RECORD",
}
with ZipFile("dist/dummy_dist-1.0-py3-none-any.whl") as wf:
files_found = set(wf.namelist())
# Check that all expected files are there.
assert expected - files_found == set()
# Make sure there is no accidental egg-info bleeding into the wheel.
assert not [path for path in files_found if 'egg-info' in str(path)]

0 comments on commit 89d3e94

Please sign in to comment.