Skip to content

Commit aa27a3f

Browse files
Adds the "Requires-Python" metadata support. Fixes bazel-contrib#378 (bazel-contrib#379)
* Adds the "Requires-Python" metadata support. Fixes bazel-contrib#378 This adds support for allowing people to specify which versions of python a wheel should run on. This was added in PEP 440 * Move 'Requires-Python' to a conditional * Add python test to check metadata Co-authored-by: Alex Eagle <eagle@post.harvard.edu>
1 parent 993b066 commit aa27a3f

File tree

4 files changed

+44
-4
lines changed

4 files changed

+44
-4
lines changed

experimental/examples/wheel/BUILD

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,17 @@ py_wheel(
135135
],
136136
)
137137

138+
py_wheel(
139+
name = "python_requires_in_a_package",
140+
distribution = "example_python_requires_in_a_package",
141+
python_tag = "py3",
142+
python_requires = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*",
143+
version = "0.0.1",
144+
deps = [
145+
":example_pkg",
146+
],
147+
)
148+
138149
py_test(
139150
name = "wheel_test",
140151
srcs = ["wheel_test.py"],
@@ -145,5 +156,6 @@ py_test(
145156
":customized",
146157
":minimal_with_py_library",
147158
":minimal_with_py_package",
159+
":python_requires_in_a_package"
148160
],
149161
)

experimental/examples/wheel/wheel_test.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ def test_customized_wheel(self):
7070
'example_customized-0.0.1.dist-info/WHEEL')
7171
metadata_contents = zf.read(
7272
'example_customized-0.0.1.dist-info/METADATA')
73-
entry_point_contents = zf.read('example_customized-0.0.1.dist-info/entry_points.txt')
73+
entry_point_contents = zf.read(
74+
'example_customized-0.0.1.dist-info/entry_points.txt')
7475
# The entries are guaranteed to be sorted.
7576
self.assertEquals(record_contents, b"""\
7677
example_customized-0.0.1.dist-info/METADATA,sha256=TeeEmokHE2NWjkaMcVJuSAq4_AXUoIad2-SLuquRmbg,372
@@ -162,6 +163,24 @@ def test_custom_package_root_multi_prefix_reverse_order_wheel(self):
162163
'example_custom_package_root_multi_prefix_reverse_order-0.0.1.dist-info/METADATA',
163164
'example_custom_package_root_multi_prefix_reverse_order-0.0.1.dist-info/RECORD'])
164165

166+
def test_python_requires_wheel(self):
167+
filename = os.path.join(os.environ['TEST_SRCDIR'],
168+
'rules_python', 'experimental',
169+
'examples', 'wheel',
170+
'example_python_requires_in_a_package-0.0.1-py3-none-any.whl')
171+
with zipfile.ZipFile(filename) as zf:
172+
metadata_contents = zf.read(
173+
'example_python_requires_in_a_package-0.0.1.dist-info/METADATA')
174+
# The entries are guaranteed to be sorted.
175+
self.assertEquals(metadata_contents, b"""\
176+
Metadata-Version: 2.1
177+
Name: example_python_requires_in_a_package
178+
Version: 0.0.1
179+
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
180+
181+
UNKNOWN
182+
""")
183+
165184

166185
if __name__ == '__main__':
167186
unittest.main()

experimental/python/wheel.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ def _py_wheel_impl(ctx):
110110
args.add("--name", ctx.attr.distribution)
111111
args.add("--version", ctx.attr.version)
112112
args.add("--python_tag", ctx.attr.python_tag)
113+
args.add("--python_requires", ctx.attr.python_requires)
113114
args.add("--abi", ctx.attr.abi)
114115
args.add("--platform", ctx.attr.platform)
115116
args.add("--out", outfile.path)
@@ -249,6 +250,7 @@ _other_attrs = {
249250
"description_file": attr.label(allow_single_file = True),
250251
"homepage": attr.string(default = ""),
251252
"license": attr.string(default = ""),
253+
"python_requires": attr.string(default = ""),
252254
"strip_path_prefixes": attr.string_list(
253255
default = [],
254256
doc = "path prefixes to strip from files added to the generated package",

experimental/tools/wheelmaker.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ def add_wheelfile(self):
129129
wheel_contents += "Tag: %s\n" % tag
130130
self.add_string(self.distinfo_path('WHEEL'), wheel_contents)
131131

132-
def add_metadata(self, extra_headers, description, classifiers, requires,
133-
extra_requires):
132+
def add_metadata(self, extra_headers, description, classifiers, python_requires,
133+
requires, extra_requires):
134134
"""Write METADATA file to the distribution."""
135135
# https://www.python.org/dev/peps/pep-0566/
136136
# https://packaging.python.org/specifications/core-metadata/
@@ -141,6 +141,8 @@ def add_metadata(self, extra_headers, description, classifiers, requires,
141141
metadata.extend(extra_headers)
142142
for classifier in classifiers:
143143
metadata.append("Classifier: %s" % classifier)
144+
if python_requires:
145+
metadata.append("Requires-Python: %s" % python_requires)
144146
for requirement in requires:
145147
metadata.append("Requires-Dist: %s" % requirement)
146148

@@ -225,6 +227,8 @@ def main():
225227
wheel_group.add_argument('--classifier', action='append',
226228
help="Classifiers to embed in package metadata. "
227229
"Can be supplied multiple times")
230+
wheel_group.add_argument('--python_requires',
231+
help="Version of python that the wheel will work with")
228232
wheel_group.add_argument('--description_file',
229233
help="Path to the file with package description")
230234
wheel_group.add_argument('--entry_points_file',
@@ -302,17 +306,20 @@ def main():
302306
req, option = extra.rsplit(';', 1)
303307
extra_requires[option].append(req)
304308
classifiers = arguments.classifier or []
309+
python_requires = arguments.python_requires or ""
305310
requires = arguments.requires or []
306311
extra_headers = arguments.header or []
307312

308313
maker.add_metadata(extra_headers=extra_headers,
309314
description=description,
310315
classifiers=classifiers,
316+
python_requires=python_requires,
311317
requires=requires,
312318
extra_requires=extra_requires)
313319

314320
if arguments.entry_points_file:
315-
maker.add_file(maker.distinfo_path("entry_points.txt"), arguments.entry_points_file)
321+
maker.add_file(maker.distinfo_path(
322+
"entry_points.txt"), arguments.entry_points_file)
316323

317324
maker.add_recordfile()
318325

0 commit comments

Comments
 (0)