chore/fix!: remove incompatible whl packaging flags (#1569)
Remove incompatible `whl` packaging flags that had been flipped
in `0.27.0` release.
Also fixes a bug where the the build stamp values (e.g. build username)
were lowercased
when they shouldn't be.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2e8f898..d38a7a4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,8 +24,11 @@
### Changed
* **BREAKING** The deprecated `incompatible_generate_aliases` feature flags
- from `pip_parse` and `gazelle` got removed. They have been flipped to `True`
+ from `pip_parse` and `gazelle` got removed. They had been flipped to `True`
in 0.27.0 release.
+* **BREAKING** (wheel) The `incompatible_normalize_name` and
+ `incompatible_normalize_version` flags have been removed. They had been
+ flipped to `True` in 0.27.0 release.
### Fixed
@@ -34,6 +37,8 @@
platform-specific content in `MODULE.bazel.lock` files; Follow
[#1643](https://github.com/bazelbuild/rules_python/issues/1643) for removing
platform-specific content in `MODULE.bazel.lock` files.
+* (wheel) The stamp variables inside the distribution name are no longer
+ lower-cased when normalizing under PEP440 conventions.
### Added
diff --git a/examples/wheel/BUILD.bazel b/examples/wheel/BUILD.bazel
index ab4f3a3..5c138a2 100644
--- a/examples/wheel/BUILD.bazel
+++ b/examples/wheel/BUILD.bazel
@@ -54,8 +54,6 @@
testonly = True, # Set this to verify the generated .dist target doesn't break things
# Package data. We're building "example_minimal_library-0.0.1-py3-none-any.whl"
distribution = "example_minimal_library",
- incompatible_normalize_name = True,
- incompatible_normalize_version = True,
python_tag = "py3",
version = "0.0.1",
deps = [
@@ -78,8 +76,6 @@
testonly = True,
abi = "$(ABI)",
distribution = "example_minimal_library",
- incompatible_normalize_name = True,
- incompatible_normalize_version = True,
python_tag = "$(PYTHON_TAG)",
toolchains = ["//examples/wheel:make_variable_tags"],
version = "$(VERSION)",
@@ -99,8 +95,6 @@
name = "minimal_with_py_library_with_stamp",
# Package data. We're building "example_minimal_library-0.0.1-py3-none-any.whl"
distribution = "example_minimal_library{BUILD_USER}",
- incompatible_normalize_name = False,
- incompatible_normalize_version = False,
python_tag = "py3",
stamp = 1,
version = "0.1.{BUILD_TIMESTAMP}",
@@ -129,8 +123,6 @@
name = "minimal_with_py_package",
# Package data. We're building "example_minimal_package-0.0.1-py3-none-any.whl"
distribution = "example_minimal_package",
- incompatible_normalize_name = True,
- incompatible_normalize_version = True,
python_tag = "py3",
version = "0.0.1",
deps = [":example_pkg"],
@@ -164,8 +156,6 @@
"//examples/wheel:README.md": "README",
},
homepage = "www.example.com",
- incompatible_normalize_name = True,
- incompatible_normalize_version = True,
license = "Apache 2.0",
project_urls = {
"Bug Tracker": "www.example.com/issues",
@@ -187,8 +177,6 @@
entry_points = {
"console_scripts": ["main = foo.bar:baz"],
},
- incompatible_normalize_name = True,
- incompatible_normalize_version = True,
python_tag = "py3",
strip_path_prefixes = [
"examples",
@@ -203,8 +191,6 @@
name = "custom_package_root_multi_prefix",
# Package data. We're building "custom_custom_package_root_multi_prefix-0.0.1-py3-none-any.whl"
distribution = "example_custom_package_root_multi_prefix",
- incompatible_normalize_name = True,
- incompatible_normalize_version = True,
python_tag = "py3",
strip_path_prefixes = [
"examples/wheel/lib",
@@ -220,8 +206,6 @@
name = "custom_package_root_multi_prefix_reverse_order",
# Package data. We're building "custom_custom_package_root_multi_prefix_reverse_order-0.0.1-py3-none-any.whl"
distribution = "example_custom_package_root_multi_prefix_reverse_order",
- incompatible_normalize_name = True,
- incompatible_normalize_version = True,
python_tag = "py3",
strip_path_prefixes = [
"examples/wheel",
@@ -236,8 +220,6 @@
py_wheel(
name = "python_requires_in_a_package",
distribution = "example_python_requires_in_a_package",
- incompatible_normalize_name = True,
- incompatible_normalize_version = True,
python_requires = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*",
python_tag = "py3",
version = "0.0.1",
@@ -249,8 +231,6 @@
py_wheel(
name = "use_rule_with_dir_in_outs",
distribution = "use_rule_with_dir_in_outs",
- incompatible_normalize_name = True,
- incompatible_normalize_version = True,
python_tag = "py3",
version = "0.0.1",
deps = [
@@ -264,8 +244,6 @@
name = "python_abi3_binary_wheel",
abi = "abi3",
distribution = "example_python_abi3_binary_wheel",
- incompatible_normalize_name = True,
- incompatible_normalize_version = True,
# these platform strings must line up with test_python_abi3_binary_wheel() in wheel_test.py
platform = select({
":aarch64-apple-darwin": "macosx_11_0_arm64",
@@ -280,27 +258,12 @@
)
py_wheel(
- name = "legacy_filename_escaping",
- # Per https://www.python.org/dev/peps/pep-0427/#escaping-and-unicode
- # runs of non-alphanumeric, non-digit symbols should be replaced with a single underscore.
- # Unicode non-ascii letters should *not* be replaced with underscore.
- distribution = "file~~name-escaping",
- incompatible_normalize_name = False,
- incompatible_normalize_version = False,
- python_tag = "py3",
- version = "0.0.1-r7",
- deps = [":example_pkg"],
-)
-
-py_wheel(
name = "filename_escaping",
# Per https://packaging.python.org/en/latest/specifications/binary-distribution-format/#escaping-and-unicode
# runs of "-", "_" and "." should be replaced with a single underscore.
# Unicode non-ascii letters aren't allowed according to
# https://packaging.python.org/en/latest/specifications/name-normalization/.
distribution = "File--Name-Escaping",
- incompatible_normalize_name = True,
- incompatible_normalize_version = True,
python_tag = "py3",
version = "v0.0.1.RC1+ubuntu-r7",
deps = [":example_pkg"],
@@ -315,7 +278,6 @@
":custom_package_root_multi_prefix_reverse_order",
":customized",
":filename_escaping",
- ":legacy_filename_escaping",
":minimal_with_py_library",
":minimal_with_py_library_with_stamp",
":minimal_with_py_package",
diff --git a/examples/wheel/wheel_test.py b/examples/wheel/wheel_test.py
index 43fbe0c..03a9408 100644
--- a/examples/wheel/wheel_test.py
+++ b/examples/wheel/wheel_test.py
@@ -192,44 +192,6 @@
filename, "48eed93258bba0bb366c879b77917d947267d89e7e60005d1766d844fb909118"
)
- def test_legacy_filename_escaping(self):
- filename = self._get_path(
- "file_name_escaping-0.0.1_r7-py3-none-any.whl",
- )
- with zipfile.ZipFile(filename) as zf:
- self.assertAllEntriesHasReproducibleMetadata(zf)
- self.assertEqual(
- zf.namelist(),
- [
- "examples/wheel/lib/data.txt",
- "examples/wheel/lib/module_with_data.py",
- "examples/wheel/lib/simple_module.py",
- "examples/wheel/main.py",
- # PEP calls for replacing only in the archive filename.
- # Alas setuptools also escapes in the dist-info directory
- # name, so let's be compatible.
- "file_name_escaping-0.0.1_r7.dist-info/WHEEL",
- "file_name_escaping-0.0.1_r7.dist-info/METADATA",
- "file_name_escaping-0.0.1_r7.dist-info/RECORD",
- ],
- )
- metadata_contents = zf.read(
- "file_name_escaping-0.0.1_r7.dist-info/METADATA"
- )
- self.assertEqual(
- metadata_contents,
- b"""\
-Metadata-Version: 2.1
-Name: file~~name-escaping
-Version: 0.0.1-r7
-
-UNKNOWN
-""",
- )
- self.assertFileSha256Equal(
- filename, "ace5fab6458f8c3b4b50801b8e8214288bba786472e81547fced743a67531312"
- )
-
def test_filename_escaping(self):
filename = self._get_path(
"file_name_escaping-0.0.1rc1+ubuntu.r7-py3-none-any.whl",
@@ -450,15 +412,15 @@
def test_rule_expands_workspace_status_keys_in_wheel_metadata(self):
filename = self._get_path(
- "example_minimal_library_BUILD_USER_-0.1._BUILD_TIMESTAMP_-py3-none-any.whl"
+ "example_minimal_library{BUILD_USER}-0.1.{BUILD_TIMESTAMP}-py3-none-any.whl"
)
with zipfile.ZipFile(filename) as zf:
self.assertAllEntriesHasReproducibleMetadata(zf)
metadata_file = None
for f in zf.namelist():
- self.assertNotIn("_BUILD_TIMESTAMP_", f)
- self.assertNotIn("_BUILD_USER_", f)
+ self.assertNotIn("{BUILD_TIMESTAMP}", f)
+ self.assertNotIn("{BUILD_USER}", f)
if os.path.basename(f) == "METADATA":
metadata_file = f
self.assertIsNotNone(metadata_file)
diff --git a/python/private/py_wheel.bzl b/python/private/py_wheel.bzl
index f451389..bca8615 100644
--- a/python/private/py_wheel.bzl
+++ b/python/private/py_wheel.bzl
@@ -118,28 +118,7 @@
),
}
-_feature_flags = {
- "incompatible_normalize_name": attr.bool(
- default = True,
- doc = """\
-Normalize the package distribution name according to latest
-Python packaging standards.
-
-See https://packaging.python.org/en/latest/specifications/binary-distribution-format/#escaping-and-unicode
-and https://packaging.python.org/en/latest/specifications/name-normalization/.
-
-Apart from the valid names according to the above, we also accept
-'{' and '}', which may be used as placeholders for stamping.
-""",
- ),
- "incompatible_normalize_version": attr.bool(
- default = True,
- doc = "Normalize the package version according to PEP440 standard. " +
- "With this option set to True, if the user wants to pass any " +
- "stamp variables, they have to be enclosed in '{}', e.g. " +
- "'{BUILD_TIMESTAMP}'.",
- ),
-}
+_feature_flags = {}
_requirement_attrs = {
"extra_requires": attr.string_list_dict(
@@ -237,9 +216,16 @@
'{' and '}', which may be used as placeholders for stamping.
"""
escaped = ""
+ _inside_stamp_var = False
for character in name.elems():
- if character.isalnum() or character in ["{", "}"]:
- escaped += character.lower()
+ if character == "{":
+ _inside_stamp_var = True
+ escaped += character
+ elif character == "}":
+ _inside_stamp_var = False
+ escaped += character
+ elif character.isalnum():
+ escaped += character if _inside_stamp_var else character.lower()
elif character in ["-", "_", "."]:
if escaped == "":
fail(
@@ -297,23 +283,13 @@
python_tag = _replace_make_variables(ctx.attr.python_tag, ctx)
version = _replace_make_variables(ctx.attr.version, ctx)
- filename_segments = []
-
- if ctx.attr.incompatible_normalize_name:
- filename_segments.append(_escape_filename_distribution_name(ctx.attr.distribution))
- else:
- filename_segments.append(_escape_filename_segment(ctx.attr.distribution))
-
- if ctx.attr.incompatible_normalize_version:
- filename_segments.append(normalize_pep440(version))
- else:
- filename_segments.append(_escape_filename_segment(version))
-
- filename_segments.extend([
+ filename_segments = [
+ _escape_filename_distribution_name(ctx.attr.distribution),
+ normalize_pep440(version),
_escape_filename_segment(python_tag),
_escape_filename_segment(abi),
_escape_filename_segment(ctx.attr.platform),
- ])
+ ]
outfile = ctx.actions.declare_file("-".join(filename_segments) + ".whl")
@@ -344,10 +320,6 @@
args.add("--out", outfile)
args.add("--name_file", name_file)
args.add_all(ctx.attr.strip_path_prefixes, format_each = "--strip_path_prefix=%s")
- if not ctx.attr.incompatible_normalize_name:
- args.add("--noincompatible_normalize_name")
- if not ctx.attr.incompatible_normalize_version:
- args.add("--noincompatible_normalize_version")
# Pass workspace status files if stamping is enabled
if is_stamping_enabled(ctx.attr):
diff --git a/tools/wheelmaker.py b/tools/wheelmaker.py
index 3bfaba2..e2d0121 100644
--- a/tools/wheelmaker.py
+++ b/tools/wheelmaker.py
@@ -218,41 +218,24 @@
platform,
outfile=None,
strip_path_prefixes=None,
- incompatible_normalize_name=True,
- incompatible_normalize_version=True,
):
self._name = name
- self._version = version
+ self._version = normalize_pep440(version)
self._build_tag = build_tag
self._python_tag = python_tag
self._abi = abi
self._platform = platform
self._outfile = outfile
self._strip_path_prefixes = strip_path_prefixes
-
- if incompatible_normalize_version:
- self._version = normalize_pep440(self._version)
- self._escaped_version = self._version
- else:
- self._escaped_version = escape_filename_segment(self._version)
-
- if incompatible_normalize_name:
- escaped_name = escape_filename_distribution_name(self._name)
- self._distinfo_dir = (
- escaped_name + "-" + self._escaped_version + ".dist-info/"
- )
- self._wheelname_fragment_distribution_name = escaped_name
- else:
- # The legacy behavior escapes the distinfo dir but not the
- # wheel name. Enable incompatible_normalize_name to fix it.
- # https://github.com/bazelbuild/rules_python/issues/1132
- self._distinfo_dir = (
- escape_filename_segment(self._name)
- + "-"
- + self._escaped_version
- + ".dist-info/"
- )
- self._wheelname_fragment_distribution_name = self._name
+ self._wheelname_fragment_distribution_name = escape_filename_distribution_name(
+ self._name
+ )
+ self._distinfo_dir = (
+ self._wheelname_fragment_distribution_name
+ + "-"
+ + self._version
+ + ".dist-info/"
+ )
self._whlfile = None
@@ -308,12 +291,12 @@
wheel_contents += "Tag: %s\n" % tag
self._whlfile.add_string(self.distinfo_path("WHEEL"), wheel_contents)
- def add_metadata(self, metadata, name, description, version):
+ def add_metadata(self, metadata, name, description):
"""Write METADATA file to the distribution."""
# https://www.python.org/dev/peps/pep-0566/
# https://packaging.python.org/specifications/core-metadata/
metadata = re.sub("^Name: .*$", "Name: %s" % name, metadata, flags=re.MULTILINE)
- metadata += "Version: %s\n\n" % version
+ metadata += "Version: %s\n\n" % self._version
# setuptools seems to insert UNKNOWN as description when none is
# provided.
metadata += description if description else "UNKNOWN"
@@ -459,12 +442,6 @@
help="Pass in the stamp info file for stamping",
)
- feature_group = parser.add_argument_group("Feature flags")
- feature_group.add_argument("--noincompatible_normalize_name", action="store_true")
- feature_group.add_argument(
- "--noincompatible_normalize_version", action="store_true"
- )
-
return parser.parse_args(sys.argv[1:])
@@ -521,8 +498,6 @@
platform=arguments.platform,
outfile=arguments.out,
strip_path_prefixes=strip_prefixes,
- incompatible_normalize_name=not arguments.noincompatible_normalize_name,
- incompatible_normalize_version=not arguments.noincompatible_normalize_version,
) as maker:
for package_filename, real_filename in all_files:
maker.add_file(package_filename, real_filename)
@@ -539,15 +514,10 @@
with open(arguments.metadata_file, "rt", encoding="utf-8") as metadata_file:
metadata = metadata_file.read()
- if arguments.noincompatible_normalize_version:
- version_in_metadata = version
- else:
- version_in_metadata = normalize_pep440(version)
maker.add_metadata(
metadata=metadata,
name=name,
description=description,
- version=version_in_metadata,
)
if arguments.entry_points_file: