Skip to content

Commit fa4c408

Browse files
pstradomskif0rmiga
andauthored
Move construction of the METADATA file from wheelmaker to .bzl (bazel-contrib#844)
* Move construction of the METADATA file (except for appending description) from wheelmaker to .bzl to avoid passing possibly unicode data on the commandline, which causes issues on windows an RBE due to UTF-16 vs UTF-8 confusion. Also fix some wrong attribute descriptions. * Regenerated docs. Buildifier fixes. * Another missing docs update. * Fix tests: all platforms should produce identical wheels. Co-authored-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com>
1 parent 2aeff3b commit fa4c408

4 files changed

Lines changed: 69 additions & 197 deletions

File tree

docs/packaging.md

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/wheel/wheel_test.py

Lines changed: 10 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -94,40 +94,11 @@ def test_customized_wheel(self):
9494
entry_point_contents = zf.read(
9595
"example_customized-0.0.1.dist-info/entry_points.txt"
9696
)
97-
# The entries are guaranteed to be sorted.
98-
if platform.system() == "Windows":
99-
self.assertEqual(
100-
record_contents,
101-
b"""\
102-
example_customized-0.0.1.dist-info/METADATA,sha256=pzE96o3Sp63TDzxAZgl0F42EFevm8x15vpDLqDVp_EQ,378
103-
example_customized-0.0.1.dist-info/NOTICE,sha256=Xpdw-FXET1IRgZ_wTkx1YQfo1-alET0FVf6V1LXO4js,76
104-
example_customized-0.0.1.dist-info/README,sha256=WmOFwZ3Jga1bHG3JiGRsUheb4UbLffUxyTdHczS27-o,40
105-
example_customized-0.0.1.dist-info/RECORD,,
106-
example_customized-0.0.1.dist-info/WHEEL,sha256=sobxWSyDDkdg_rinUth-jxhXHqoNqlmNMJY3aTZn2Us,91
107-
example_customized-0.0.1.dist-info/entry_points.txt,sha256=pqzpbQ8MMorrJ3Jp0ntmpZcuvfByyqzMXXi2UujuXD0,137
108-
examples/wheel/lib/data.txt,sha256=9vJKEdfLu8bZRArKLroPZJh1XKkK3qFMXiM79MBL2Sg,12
109-
examples/wheel/lib/module_with_data.py,sha256=8s0Khhcqz3yVsBKv2IB5u4l4TMKh7-c_V6p65WVHPms,637
110-
examples/wheel/lib/simple_module.py,sha256=z2hwciab_XPNIBNH8B1Q5fYgnJvQTeYf0ZQJpY8yLLY,637
111-
examples/wheel/main.py,sha256=sgg5iWN_9inYBjm6_Zw27hYdmo-l24fA-2rfphT-IlY,909
112-
""",
113-
)
114-
else:
115-
# TODO: The non-ascii characters in the METADATA file are interpreted differently on the
116-
# ubuntu16_rbe hosts in comparison to other unix platforms. This should not be the case
117-
# and the code should be updated to account for this.
118-
rbe_expected_contents = b"""\
119-
example_customized-0.0.1.dist-info/METADATA,sha256=pzE96o3Sp63TDzxAZgl0F42EFevm8x15vpDLqDVp_EQ,378
120-
example_customized-0.0.1.dist-info/NOTICE,sha256=Xpdw-FXET1IRgZ_wTkx1YQfo1-alET0FVf6V1LXO4js,76
121-
example_customized-0.0.1.dist-info/README,sha256=WmOFwZ3Jga1bHG3JiGRsUheb4UbLffUxyTdHczS27-o,40
122-
example_customized-0.0.1.dist-info/RECORD,,
123-
example_customized-0.0.1.dist-info/WHEEL,sha256=sobxWSyDDkdg_rinUth-jxhXHqoNqlmNMJY3aTZn2Us,91
124-
example_customized-0.0.1.dist-info/entry_points.txt,sha256=pqzpbQ8MMorrJ3Jp0ntmpZcuvfByyqzMXXi2UujuXD0,137
125-
examples/wheel/lib/data.txt,sha256=9vJKEdfLu8bZRArKLroPZJh1XKkK3qFMXiM79MBL2Sg,12
126-
examples/wheel/lib/module_with_data.py,sha256=8s0Khhcqz3yVsBKv2IB5u4l4TMKh7-c_V6p65WVHPms,637
127-
examples/wheel/lib/simple_module.py,sha256=z2hwciab_XPNIBNH8B1Q5fYgnJvQTeYf0ZQJpY8yLLY,637
128-
examples/wheel/main.py,sha256=sgg5iWN_9inYBjm6_Zw27hYdmo-l24fA-2rfphT-IlY,909
129-
"""
130-
unix_expected_contents = b"""\
97+
98+
self.assertEqual(
99+
record_contents,
100+
# The entries are guaranteed to be sorted.
101+
b"""\
131102
example_customized-0.0.1.dist-info/METADATA,sha256=TeeEmokHE2NWjkaMcVJuSAq4_AXUoIad2-SLuquRmbg,372
132103
example_customized-0.0.1.dist-info/NOTICE,sha256=Xpdw-FXET1IRgZ_wTkx1YQfo1-alET0FVf6V1LXO4js,76
133104
example_customized-0.0.1.dist-info/README,sha256=WmOFwZ3Jga1bHG3JiGRsUheb4UbLffUxyTdHczS27-o,40
@@ -138,15 +109,7 @@ def test_customized_wheel(self):
138109
examples/wheel/lib/module_with_data.py,sha256=8s0Khhcqz3yVsBKv2IB5u4l4TMKh7-c_V6p65WVHPms,637
139110
examples/wheel/lib/simple_module.py,sha256=z2hwciab_XPNIBNH8B1Q5fYgnJvQTeYf0ZQJpY8yLLY,637
140111
examples/wheel/main.py,sha256=sgg5iWN_9inYBjm6_Zw27hYdmo-l24fA-2rfphT-IlY,909
141-
"""
142-
self.assertIn(
143-
record_contents,
144-
[
145-
rbe_expected_contents,
146-
unix_expected_contents,
147-
],
148-
)
149-
112+
""")
150113
self.assertEqual(
151114
wheel_contents,
152115
b"""\
@@ -156,44 +119,9 @@ def test_customized_wheel(self):
156119
Tag: py3-none-any
157120
""",
158121
)
159-
if platform.system() == "Windows":
160-
self.assertEqual(
161-
metadata_contents,
162-
b"""\
163-
Metadata-Version: 2.1
164-
Name: example_customized
165-
Version: 0.0.1
166-
Author: Example Author with non-ascii characters: \xc3\x85\xc2\xbc\xc3\x83\xc2\xb3\xc3\x85\xc2\x82w
167-
Author-email: example@example.com
168-
Home-page: www.example.com
169-
License: Apache 2.0
170-
Classifier: License :: OSI Approved :: Apache Software License
171-
Classifier: Intended Audience :: Developers
172-
Requires-Dist: pytest
173-
174-
This is a sample description of a wheel.
175-
""",
176-
)
177-
else:
178-
# TODO: The non-ascii characters in the METADATA file are interpreted differently on the
179-
# ubuntu16_rbe hosts in comparison to other unix platforms. This should not be the case
180-
# and the code should be updated to account for this.
181-
rbe_expected_contents = b"""\
182-
Metadata-Version: 2.1
183-
Name: example_customized
184-
Version: 0.0.1
185-
Author: Example Author with non-ascii characters: \xc3\x85\xc2\xbc\xc3\x83\xc2\xb3\xc3\x85\xc2\x82w
186-
Author-email: example@example.com
187-
Home-page: www.example.com
188-
License: Apache 2.0
189-
Classifier: License :: OSI Approved :: Apache Software License
190-
Classifier: Intended Audience :: Developers
191-
Requires-Dist: pytest
192-
193-
This is a sample description of a wheel.
194-
"""
195-
196-
unix_expected_contents = b"""\
122+
self.assertEqual(
123+
metadata_contents,
124+
b"""\
197125
Metadata-Version: 2.1
198126
Name: example_customized
199127
Version: 0.0.1
@@ -206,14 +134,7 @@ def test_customized_wheel(self):
206134
Requires-Dist: pytest
207135
208136
This is a sample description of a wheel.
209-
"""
210-
self.assertIn(
211-
metadata_contents,
212-
[
213-
rbe_expected_contents,
214-
unix_expected_contents,
215-
],
216-
)
137+
""")
217138
self.assertEqual(
218139
entry_point_contents,
219140
b"""\

python/packaging.bzl

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ def _py_wheel_impl(ctx):
153153
args.add("--name", ctx.attr.distribution)
154154
args.add("--version", version)
155155
args.add("--python_tag", ctx.attr.python_tag)
156-
args.add("--python_requires", ctx.attr.python_requires)
157156
args.add("--abi", ctx.attr.abi)
158157
args.add("--platform", ctx.attr.platform)
159158
args.add("--out", outfile)
@@ -168,28 +167,42 @@ def _py_wheel_impl(ctx):
168167

169168
args.add("--input_file_list", packageinputfile)
170169

171-
extra_headers = []
170+
# Note: Description file is not embedded into metadata.txt yet,
171+
# it will be done later by wheelmaker script.
172+
metadata_file = ctx.actions.declare_file(ctx.attr.name + ".metadata.txt")
173+
metadata_contents = ["Metadata-Version: 2.1"]
174+
metadata_contents.append("Name: %s" % ctx.attr.distribution)
175+
metadata_contents.append("Version: %s" % version)
176+
172177
if ctx.attr.author:
173-
extra_headers.append("Author: %s" % ctx.attr.author)
178+
metadata_contents.append("Author: %s" % ctx.attr.author)
174179
if ctx.attr.author_email:
175-
extra_headers.append("Author-email: %s" % ctx.attr.author_email)
180+
metadata_contents.append("Author-email: %s" % ctx.attr.author_email)
176181
if ctx.attr.homepage:
177-
extra_headers.append("Home-page: %s" % ctx.attr.homepage)
182+
metadata_contents.append("Home-page: %s" % ctx.attr.homepage)
178183
if ctx.attr.license:
179-
extra_headers.append("License: %s" % ctx.attr.license)
180-
181-
for h in extra_headers:
182-
args.add("--header", h)
184+
metadata_contents.append("License: %s" % ctx.attr.license)
183185

184186
for c in ctx.attr.classifiers:
185-
args.add("--classifier", c)
186-
187-
for r in ctx.attr.requires:
188-
args.add("--requires", r)
189-
190-
for option, requirements in ctx.attr.extra_requires.items():
191-
for r in requirements:
192-
args.add("--extra_requires", r + ";" + option)
187+
metadata_contents.append("Classifier: %s" % c)
188+
189+
if ctx.attr.python_requires:
190+
metadata_contents.append("Requires-Python: %s" % ctx.attr.python_requires)
191+
for requirement in ctx.attr.requires:
192+
metadata_contents.append("Requires-Dist: %s" % requirement)
193+
194+
for option, option_requirements in sorted(ctx.attr.extra_requires.items()):
195+
metadata_contents.append("Provides-Extra: %s" % option)
196+
for requirement in option_requirements:
197+
metadata_contents.append(
198+
"Requires-Dist: %s; extra == '%s'" % (requirement, option),
199+
)
200+
ctx.actions.write(
201+
output = metadata_file,
202+
content = "\n".join(metadata_contents) + "\n",
203+
)
204+
other_inputs.append(metadata_file)
205+
args.add("--metadata_file", metadata_file)
193206

194207
# Merge console_scripts into entry_points.
195208
entrypoints = dict(ctx.attr.entry_points) # Copy so we can mutate it
@@ -334,7 +347,9 @@ _requirement_attrs = {
334347
doc = "List of optional requirements for this package",
335348
),
336349
"requires": attr.string_list(
337-
doc = "List of requirements for this package",
350+
doc = ("List of requirements for this package. See the section on " +
351+
"[Declaring required dependency](https://setuptools.readthedocs.io/en/latest/userguide/dependency_management.html#declaring-dependencies) " +
352+
"for details and examples of the format of this argument."),
338353
),
339354
}
340355

@@ -366,7 +381,7 @@ _other_attrs = {
366381
doc = "A list of strings describing the categories for the package. For valid classifiers see https://pypi.org/classifiers",
367382
),
368383
"description_file": attr.label(
369-
doc = "A file containing text describing the package in a single line.",
384+
doc = "A file containing text describing the package.",
370385
allow_single_file = True,
371386
),
372387
"extra_distinfo_files": attr.label_keyed_string_dict(
@@ -383,10 +398,7 @@ _other_attrs = {
383398
),
384399
"python_requires": attr.string(
385400
doc = (
386-
"A string specifying what other distributions need to be installed " +
387-
"when this one is. See the section on " +
388-
"[Declaring required dependency](https://setuptools.readthedocs.io/en/latest/userguide/dependency_management.html#declaring-dependencies) " +
389-
"for details and examples of the format of this argument."
401+
"Python versions required by this distribution, e.g. '>=3.5,<3.7'"
390402
),
391403
default = "",
392404
),

0 commit comments

Comments
 (0)