Skip to content

Commit 9fb53fd

Browse files
authored
Merge pull request #4617 from abravalheri/issue-4612
Deprecate `bdist_wheel.universal`
2 parents cd3ba7d + 1f5f6be commit 9fb53fd

File tree

4 files changed

+41
-20
lines changed

4 files changed

+41
-20
lines changed

Diff for: newsfragments/4617.feature.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Deprecated ``bdist_wheel.universal`` configuration.

Diff for: setuptools/command/bdist_wheel.py

+16-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from wheel.wheelfile import WheelFile
2727

2828
from .. import Command, __version__
29+
from ..warnings import SetuptoolsDeprecationWarning
2930
from .egg_info import egg_info as egg_info_cls
3031

3132
from distutils import log
@@ -205,7 +206,7 @@ class bdist_wheel(Command):
205206
"g",
206207
"Group name used when creating a tar file [default: current group]",
207208
),
208-
("universal", None, "make a universal wheel [default: false]"),
209+
("universal", None, "*DEPRECATED* make a universal wheel [default: false]"),
209210
(
210211
"compression=",
211212
None,
@@ -278,13 +279,26 @@ def finalize_options(self) -> None:
278279

279280
# Support legacy [wheel] section for setting universal
280281
wheel = self.distribution.get_option_dict("wheel")
281-
if "universal" in wheel:
282+
if "universal" in wheel: # pragma: no cover
282283
# please don't define this in your global configs
283284
log.warn("The [wheel] section is deprecated. Use [bdist_wheel] instead.")
284285
val = wheel["universal"][1].strip()
285286
if val.lower() in ("1", "true", "yes"):
286287
self.universal = True
287288

289+
if self.universal:
290+
SetuptoolsDeprecationWarning.emit(
291+
"bdist_wheel.universal is deprecated",
292+
"""
293+
With Python 2.7 end-of-life, support for building universal wheels
294+
(i.e., wheels that support both Python 2 and Python 3)
295+
is being obviated.
296+
Please discontinue using this option, or if you still need it,
297+
file an issue with pypa/setuptools describing your use case.
298+
""",
299+
due_date=(2025, 8, 30), # Introduced in 2024-08-30
300+
)
301+
288302
if self.build_number is not None and not self.build_number[:1].isdigit():
289303
raise ValueError("Build tag (build-number) must start with a digit.")
290304

Diff for: setuptools/tests/test_bdist_wheel.py

+24-15
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
remove_readonly_exc,
2727
)
2828
from setuptools.dist import Distribution
29+
from setuptools.warnings import SetuptoolsDeprecationWarning
2930

3031
from distutils.core import run_setup
3132

@@ -123,7 +124,6 @@
123124
)
124125
"""
125126
),
126-
"setup.cfg": "[bdist_wheel]\nuniversal=1",
127127
"headersdist.py": "",
128128
"header.h": "",
129129
},
@@ -300,8 +300,8 @@ def license_paths(self):
300300

301301
def test_licenses_default(dummy_dist, monkeypatch, tmp_path):
302302
monkeypatch.chdir(dummy_dist)
303-
bdist_wheel_cmd(bdist_dir=str(tmp_path), universal=True).run()
304-
with ZipFile("dist/dummy_dist-1.0-py2.py3-none-any.whl") as wf:
303+
bdist_wheel_cmd(bdist_dir=str(tmp_path)).run()
304+
with ZipFile("dist/dummy_dist-1.0-py3-none-any.whl") as wf:
305305
license_files = {
306306
"dummy_dist-1.0.dist-info/" + fname for fname in DEFAULT_LICENSE_FILES
307307
}
@@ -314,9 +314,9 @@ def test_licenses_deprecated(dummy_dist, monkeypatch, tmp_path):
314314
)
315315
monkeypatch.chdir(dummy_dist)
316316

317-
bdist_wheel_cmd(bdist_dir=str(tmp_path), universal=True).run()
317+
bdist_wheel_cmd(bdist_dir=str(tmp_path)).run()
318318

319-
with ZipFile("dist/dummy_dist-1.0-py2.py3-none-any.whl") as wf:
319+
with ZipFile("dist/dummy_dist-1.0-py3-none-any.whl") as wf:
320320
license_files = {"dummy_dist-1.0.dist-info/DUMMYFILE"}
321321
assert set(wf.namelist()) == DEFAULT_FILES | license_files
322322

@@ -337,8 +337,8 @@ def test_licenses_deprecated(dummy_dist, monkeypatch, tmp_path):
337337
def test_licenses_override(dummy_dist, monkeypatch, tmp_path, config_file, config):
338338
dummy_dist.joinpath(config_file).write_text(config, encoding="utf-8")
339339
monkeypatch.chdir(dummy_dist)
340-
bdist_wheel_cmd(bdist_dir=str(tmp_path), universal=True).run()
341-
with ZipFile("dist/dummy_dist-1.0-py2.py3-none-any.whl") as wf:
340+
bdist_wheel_cmd(bdist_dir=str(tmp_path)).run()
341+
with ZipFile("dist/dummy_dist-1.0-py3-none-any.whl") as wf:
342342
license_files = {
343343
"dummy_dist-1.0.dist-info/" + fname for fname in {"DUMMYFILE", "LICENSE"}
344344
}
@@ -350,20 +350,29 @@ def test_licenses_disabled(dummy_dist, monkeypatch, tmp_path):
350350
"[metadata]\nlicense_files=\n", encoding="utf-8"
351351
)
352352
monkeypatch.chdir(dummy_dist)
353-
bdist_wheel_cmd(bdist_dir=str(tmp_path), universal=True).run()
354-
with ZipFile("dist/dummy_dist-1.0-py2.py3-none-any.whl") as wf:
353+
bdist_wheel_cmd(bdist_dir=str(tmp_path)).run()
354+
with ZipFile("dist/dummy_dist-1.0-py3-none-any.whl") as wf:
355355
assert set(wf.namelist()) == DEFAULT_FILES
356356

357357

358358
def test_build_number(dummy_dist, monkeypatch, tmp_path):
359359
monkeypatch.chdir(dummy_dist)
360-
bdist_wheel_cmd(bdist_dir=str(tmp_path), build_number="2", universal=True).run()
361-
with ZipFile("dist/dummy_dist-1.0-2-py2.py3-none-any.whl") as wf:
360+
bdist_wheel_cmd(bdist_dir=str(tmp_path), build_number="2").run()
361+
with ZipFile("dist/dummy_dist-1.0-2-py3-none-any.whl") as wf:
362362
filenames = set(wf.namelist())
363363
assert "dummy_dist-1.0.dist-info/RECORD" in filenames
364364
assert "dummy_dist-1.0.dist-info/METADATA" in filenames
365365

366366

367+
def test_universal_deprecated(dummy_dist, monkeypatch, tmp_path):
368+
monkeypatch.chdir(dummy_dist)
369+
with pytest.warns(SetuptoolsDeprecationWarning, match=".*universal is deprecated"):
370+
bdist_wheel_cmd(bdist_dir=str(tmp_path), universal=True).run()
371+
372+
# For now we still respect the option
373+
assert os.path.exists("dist/dummy_dist-1.0-py2.py3-none-any.whl")
374+
375+
367376
EXTENSION_EXAMPLE = """\
368377
#include <Python.h>
369378
@@ -431,8 +440,8 @@ def test_build_from_readonly_tree(dummy_dist, monkeypatch, tmp_path):
431440
)
432441
def test_compression(dummy_dist, monkeypatch, tmp_path, option, compress_type):
433442
monkeypatch.chdir(dummy_dist)
434-
bdist_wheel_cmd(bdist_dir=str(tmp_path), universal=True, compression=option).run()
435-
with ZipFile("dist/dummy_dist-1.0-py2.py3-none-any.whl") as wf:
443+
bdist_wheel_cmd(bdist_dir=str(tmp_path), compression=option).run()
444+
with ZipFile("dist/dummy_dist-1.0-py3-none-any.whl") as wf:
436445
filenames = set(wf.namelist())
437446
assert "dummy_dist-1.0.dist-info/RECORD" in filenames
438447
assert "dummy_dist-1.0.dist-info/METADATA" in filenames
@@ -451,8 +460,8 @@ def test_wheelfile_line_endings(wheel_paths):
451460
def test_unix_epoch_timestamps(dummy_dist, monkeypatch, tmp_path):
452461
monkeypatch.setenv("SOURCE_DATE_EPOCH", "0")
453462
monkeypatch.chdir(dummy_dist)
454-
bdist_wheel_cmd(bdist_dir=str(tmp_path), build_number="2a", universal=True).run()
455-
with ZipFile("dist/dummy_dist-1.0-2a-py2.py3-none-any.whl") as wf:
463+
bdist_wheel_cmd(bdist_dir=str(tmp_path), build_number="2a").run()
464+
with ZipFile("dist/dummy_dist-1.0-2a-py3-none-any.whl") as wf:
456465
for zinfo in wf.filelist:
457466
assert zinfo.date_time >= (1980, 1, 1, 0, 0, 0) # min epoch is used
458467

Diff for: setuptools/tests/test_build_meta.py

-3
Original file line numberDiff line numberDiff line change
@@ -358,9 +358,6 @@ def test_build_with_pyproject_config(self, tmpdir, setup_script):
358358
359359
[tool.distutils.sdist]
360360
formats = "gztar"
361-
362-
[tool.distutils.bdist_wheel]
363-
universal = true
364361
"""
365362
),
366363
"MANIFEST.in": DALS(

0 commit comments

Comments
 (0)