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: