revert(pypi): use Python for marker eval and METADATA parsing (#2834)

Summary:
- Revert to using Python for marker evaluation during parsing of
  requirements (partial revert of #2692).
- Use Python to parse whl METADATA.
- Bugfix the new simpler algorithm and add a new unit test.

Fixes #2830

(cherry picked from commit 5b9d545220e5956e0686de91a14e6ded89df651a)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 92667a8..8b7c206 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -66,8 +66,6 @@
     * 3.12.9
     * 3.13.2
 * (pypi) Use `xcrun xcodebuild --showsdks` to find XCode root.
-* (pypi) The `bzlmod` extension will now generate smaller lock files for  when
-  using `experimental_index_url`.
 * (toolchains) Remove all but `3.8.20` versions of the Python `3.8` interpreter who has
   reached EOL. If users still need other versions of the `3.8` interpreter, please supply
   the URLs manually {bzl:obj}`python.toolchain` or {bzl:obj}`python_register_toolchains` calls.
@@ -83,13 +81,6 @@
   [PR #2746](https://github.com/bazel-contrib/rules_python/pull/2746).
 * (rules) {attr}`py_binary.srcs` and {attr}`py_test.srcs` is no longer mandatory when
   `main_module` is specified (for `--bootstrap_impl=script`)
-* (pypi) From now on the `Requires-Dist` from the wheel metadata is analysed in
-  the loading phase instead of repository rule phase giving better caching
-  performance when the target platforms are changed (e.g. target python
-  versions). This is preparatory work for stabilizing the cross-platform wheel
-  support. From now on the usage of `experimental_target_platforms` should be
-  avoided and the `requirements_by_platform` values should be instead used to
-  specify the target platforms for the given dependencies.
 
 [20250317]: https://github.com/astral-sh/python-build-standalone/releases/tag/20250317
 
diff --git a/python/private/pypi/evaluate_markers.bzl b/python/private/pypi/evaluate_markers.bzl
index f966aa3..1919335 100644
--- a/python/private/pypi/evaluate_markers.bzl
+++ b/python/private/pypi/evaluate_markers.bzl
@@ -14,10 +14,21 @@
 
 """A simple function that evaluates markers using a python interpreter."""
 
+load(":deps.bzl", "record_files")
 load(":pep508_env.bzl", "env")
 load(":pep508_evaluate.bzl", "evaluate")
 load(":pep508_platform.bzl", "platform_from_str")
 load(":pep508_requirement.bzl", "requirement")
+load(":pypi_repo_utils.bzl", "pypi_repo_utils")
+
+# Used as a default value in a rule to ensure we fetch the dependencies.
+SRCS = [
+    # When the version, or any of the files in `packaging` package changes,
+    # this file will change as well.
+    record_files["pypi__packaging"],
+    Label("//python/private/pypi/requirements_parser:resolve_target_platforms.py"),
+    Label("//python/private/pypi/whl_installer:platform.py"),
+]
 
 def evaluate_markers(requirements, python_version = None):
     """Return the list of supported platforms per requirements line.
@@ -37,3 +48,54 @@
                 ret.setdefault(req_string, []).append(platform)
 
     return ret
+
+def evaluate_markers_py(mrctx, *, requirements, python_interpreter, python_interpreter_target, srcs, logger = None):
+    """Return the list of supported platforms per requirements line.
+
+    Args:
+        mrctx: repository_ctx or module_ctx.
+        requirements: list[str] of the requirement file lines to evaluate.
+        python_interpreter: str, path to the python_interpreter to use to
+            evaluate the env markers in the given requirements files. It will
+            be only called if the requirements files have env markers. This
+            should be something that is in your PATH or an absolute path.
+        python_interpreter_target: Label, same as python_interpreter, but in a
+            label format.
+        srcs: list[Label], the value of SRCS passed from the `rctx` or `mctx` to this function.
+        logger: repo_utils.logger or None, a simple struct to log diagnostic
+            messages. Defaults to None.
+
+    Returns:
+        dict of string lists with target platforms
+    """
+    if not requirements:
+        return {}
+
+    in_file = mrctx.path("requirements_with_markers.in.json")
+    out_file = mrctx.path("requirements_with_markers.out.json")
+    mrctx.file(in_file, json.encode(requirements))
+
+    pypi_repo_utils.execute_checked(
+        mrctx,
+        op = "ResolveRequirementEnvMarkers({})".format(in_file),
+        python = pypi_repo_utils.resolve_python_interpreter(
+            mrctx,
+            python_interpreter = python_interpreter,
+            python_interpreter_target = python_interpreter_target,
+        ),
+        arguments = [
+            "-m",
+            "python.private.pypi.requirements_parser.resolve_target_platforms",
+            in_file,
+            out_file,
+        ],
+        srcs = srcs,
+        environment = {
+            "PYTHONPATH": [
+                Label("@pypi__packaging//:BUILD.bazel"),
+                Label("//:BUILD.bazel"),
+            ],
+        },
+        logger = logger,
+    )
+    return json.decode(mrctx.read(out_file))
diff --git a/python/private/pypi/extension.bzl b/python/private/pypi/extension.bzl
index e9eba68..647407f 100644
--- a/python/private/pypi/extension.bzl
+++ b/python/private/pypi/extension.bzl
@@ -24,7 +24,7 @@
 load("//python/private:semver.bzl", "semver")
 load("//python/private:version_label.bzl", "version_label")
 load(":attrs.bzl", "use_isolated")
-load(":evaluate_markers.bzl", "evaluate_markers")
+load(":evaluate_markers.bzl", "evaluate_markers_py", EVALUATE_MARKERS_SRCS = "SRCS")
 load(":hub_repository.bzl", "hub_repository", "whl_config_settings_to_json")
 load(":parse_requirements.bzl", "parse_requirements")
 load(":parse_whl_name.bzl", "parse_whl_name")
@@ -71,6 +71,7 @@
         whl_overrides,
         available_interpreters = INTERPRETER_LABELS,
         minor_mapping = MINOR_MAPPING,
+        evaluate_markers = evaluate_markers_py,
         get_index_urls = None):
     """create all of the whl repositories
 
@@ -85,6 +86,7 @@
             used during the `repository_rule` and must be always compatible with the host.
         minor_mapping: {type}`dict[str, str]` The dictionary needed to resolve the full
             python version used to parse package METADATA files.
+        evaluate_markers: the function used to evaluate the markers.
 
     Returns a {type}`struct` with the following attributes:
         whl_map: {type}`dict[str, list[struct]]` the output is keyed by the
@@ -172,7 +174,28 @@
         ),
         extra_pip_args = pip_attr.extra_pip_args,
         get_index_urls = get_index_urls,
-        evaluate_markers = evaluate_markers,
+        # NOTE @aignas 2024-08-02: , we will execute any interpreter that we find either
+        # in the PATH or if specified as a label. We will configure the env
+        # markers when evaluating the requirement lines based on the output
+        # from the `requirements_files_by_platform` which should have something
+        # similar to:
+        # {
+        #    "//:requirements.txt": ["cp311_linux_x86_64", ...]
+        # }
+        #
+        # We know the target python versions that we need to evaluate the
+        # markers for and thus we don't need to use multiple python interpreter
+        # instances to perform this manipulation. This function should be executed
+        # only once by the underlying code to minimize the overhead needed to
+        # spin up a Python interpreter.
+        evaluate_markers = lambda module_ctx, requirements: evaluate_markers(
+            module_ctx,
+            requirements = requirements,
+            python_interpreter = pip_attr.python_interpreter,
+            python_interpreter_target = python_interpreter_target,
+            srcs = pip_attr._evaluate_markers_srcs,
+            logger = logger,
+        ),
         logger = logger,
     )
 
@@ -193,6 +216,7 @@
             enable_implicit_namespace_pkgs = pip_attr.enable_implicit_namespace_pkgs,
             environment = pip_attr.environment,
             envsubst = pip_attr.envsubst,
+            experimental_target_platforms = pip_attr.experimental_target_platforms,
             group_deps = group_deps,
             group_name = group_name,
             pip_data_exclude = pip_attr.pip_data_exclude,
@@ -281,6 +305,13 @@
         args["urls"] = [distribution.url]
         args["sha256"] = distribution.sha256
         args["filename"] = distribution.filename
+        args["experimental_target_platforms"] = [
+            # Get rid of the version fot the target platforms because we are
+            # passing the interpreter any way. Ideally we should search of ways
+            # how to pass the target platforms through the hub repo.
+            p.partition("_")[2]
+            for p in requirement.target_platforms
+        ]
 
         # Pure python wheels or sdists may need to have a platform here
         target_platforms = None
@@ -777,6 +808,13 @@
 The labels are JSON config files describing the modifications.
 """,
         ),
+        "_evaluate_markers_srcs": attr.label_list(
+            default = EVALUATE_MARKERS_SRCS,
+            doc = """\
+The list of labels to use as SRCS for the marker evaluation code. This ensures that the
+code will be re-evaluated when any of files in the default changes.
+""",
+        ),
     }, **ATTRS)
     attrs.update(AUTH_ATTRS)
 
diff --git a/python/private/pypi/generate_whl_library_build_bazel.bzl b/python/private/pypi/generate_whl_library_build_bazel.bzl
index 7988aca..31c9d4d 100644
--- a/python/private/pypi/generate_whl_library_build_bazel.bzl
+++ b/python/private/pypi/generate_whl_library_build_bazel.bzl
@@ -21,11 +21,14 @@
     "copy_files": render.dict,
     "data": render.list,
     "data_exclude": render.list,
+    "dependencies": render.list,
+    "dependencies_by_platform": lambda x: render.dict(x, value_repr = render.list),
     "entry_points": render.dict,
     "extras": render.list,
     "group_deps": render.list,
     "requires_dist": render.list,
     "srcs_exclude": render.list,
+    "tags": render.list,
     "target_platforms": lambda x: render.list(x) if x else "target_platforms",
 }
 
@@ -37,7 +40,7 @@
 
 package(default_visibility = ["//visibility:public"])
 
-whl_library_targets_from_requires(
+{fn}(
 {kwargs}
 )
 """
@@ -59,17 +62,28 @@
         A complete BUILD file as a string
     """
 
+    fn = "whl_library_targets"
+    if kwargs.get("tags"):
+        # legacy path
+        unsupported_args = [
+            "requires",
+            "metadata_name",
+            "metadata_version",
+        ]
+    else:
+        fn = "{}_from_requires".format(fn)
+        unsupported_args = [
+            "dependencies",
+            "dependencies_by_platform",
+        ]
+
+    for arg in unsupported_args:
+        if kwargs.get(arg):
+            fail("BUG, unsupported arg: '{}'".format(arg))
+
     loads = [
-        """load("@rules_python//python/private/pypi:whl_library_targets.bzl", "whl_library_targets_from_requires")""",
+        """load("@rules_python//python/private/pypi:whl_library_targets.bzl", "{}")""".format(fn),
     ]
-    if not kwargs.setdefault("target_platforms", None):
-        dep_template = kwargs["dep_template"]
-        loads.append(
-            "load(\"{}\", \"{}\")".format(
-                dep_template.format(name = "", target = "config.bzl"),
-                "target_platforms",
-            ),
-        )
 
     additional_content = []
     if annotation:
@@ -87,6 +101,7 @@
         [
             _TEMPLATE.format(
                 loads = "\n".join(loads),
+                fn = fn,
                 kwargs = render.indent("\n".join([
                     "{} = {},".format(k, _RENDER.get(k, repr)(v))
                     for k, v in sorted(kwargs.items())
diff --git a/python/private/pypi/parse_requirements.bzl b/python/private/pypi/parse_requirements.bzl
index 1cbf094..5633328 100644
--- a/python/private/pypi/parse_requirements.bzl
+++ b/python/private/pypi/parse_requirements.bzl
@@ -80,7 +80,7 @@
 
         The second element is extra_pip_args should be passed to `whl_library`.
     """
-    evaluate_markers = evaluate_markers or (lambda _: {})
+    evaluate_markers = evaluate_markers or (lambda _ctx, _requirements: {})
     options = {}
     requirements = {}
     for file, plats in requirements_by_platform.items():
@@ -156,7 +156,7 @@
     # to do, we could use Python to parse the requirement lines and infer the
     # URL of the files to download things from. This should be important for
     # VCS package references.
-    env_marker_target_platforms = evaluate_markers(reqs_with_env_markers)
+    env_marker_target_platforms = evaluate_markers(ctx, reqs_with_env_markers)
     if logger:
         logger.debug(lambda: "Evaluated env markers from:\n{}\n\nTo:\n{}".format(
             reqs_with_env_markers,
diff --git a/python/private/pypi/pip_repository.bzl b/python/private/pypi/pip_repository.bzl
index b7ed165..8ca94f7 100644
--- a/python/private/pypi/pip_repository.bzl
+++ b/python/private/pypi/pip_repository.bzl
@@ -16,12 +16,11 @@
 
 load("@bazel_skylib//lib:sets.bzl", "sets")
 load("//python/private:normalize_name.bzl", "normalize_name")
-load("//python/private:repo_utils.bzl", "REPO_DEBUG_ENV_VAR", "repo_utils")
+load("//python/private:repo_utils.bzl", "REPO_DEBUG_ENV_VAR")
 load("//python/private:text_util.bzl", "render")
-load(":evaluate_markers.bzl", "evaluate_markers")
+load(":evaluate_markers.bzl", "evaluate_markers_py", EVALUATE_MARKERS_SRCS = "SRCS")
 load(":parse_requirements.bzl", "host_platform", "parse_requirements", "select_requirement")
 load(":pip_repository_attrs.bzl", "ATTRS")
-load(":pypi_repo_utils.bzl", "pypi_repo_utils")
 load(":render_pkg_aliases.bzl", "render_pkg_aliases")
 load(":requirements_files_by_platform.bzl", "requirements_files_by_platform")
 
@@ -71,27 +70,7 @@
 exports_files(["requirements.bzl"])
 """
 
-def _evaluate_markers(rctx, requirements, logger = None):
-    python_interpreter = _get_python_interpreter_attr(rctx)
-    stdout = pypi_repo_utils.execute_checked_stdout(
-        rctx,
-        op = "GetPythonVersionForMarkerEval",
-        python = python_interpreter,
-        arguments = [
-            # Run the interpreter in isolated mode, this options implies -E, -P and -s.
-            # Ensures environment variables are ignored that are set in userspace, such as PYTHONPATH,
-            # which may interfere with this invocation.
-            "-I",
-            "-c",
-            "import sys; print(f'{sys.version_info[0]}.{sys.version_info[1]}.{sys.version_info[2]}', end='')",
-        ],
-        srcs = [],
-        logger = logger,
-    )
-    return evaluate_markers(requirements, python_version = stdout)
-
 def _pip_repository_impl(rctx):
-    logger = repo_utils.logger(rctx)
     requirements_by_platform = parse_requirements(
         rctx,
         requirements_by_platform = requirements_files_by_platform(
@@ -103,7 +82,13 @@
             extra_pip_args = rctx.attr.extra_pip_args,
         ),
         extra_pip_args = rctx.attr.extra_pip_args,
-        evaluate_markers = lambda requirements: _evaluate_markers(rctx, requirements, logger),
+        evaluate_markers = lambda rctx, requirements: evaluate_markers_py(
+            rctx,
+            requirements = requirements,
+            python_interpreter = rctx.attr.python_interpreter,
+            python_interpreter_target = rctx.attr.python_interpreter_target,
+            srcs = rctx.attr._evaluate_markers_srcs,
+        ),
     )
     selected_requirements = {}
     options = None
@@ -249,6 +234,13 @@
         _template = attr.label(
             default = ":requirements.bzl.tmpl.workspace",
         ),
+        _evaluate_markers_srcs = attr.label_list(
+            default = EVALUATE_MARKERS_SRCS,
+            doc = """\
+The list of labels to use as SRCS for the marker evaluation code. This ensures that the
+code will be re-evaluated when any of files in the default changes.
+""",
+        ),
         **ATTRS
     ),
     doc = """Accepts a locked/compiled requirements file and installs the dependencies listed within.
diff --git a/python/private/pypi/whl_installer/wheel.py b/python/private/pypi/whl_installer/wheel.py
index fce706a..25003e6 100644
--- a/python/private/pypi/whl_installer/wheel.py
+++ b/python/private/pypi/whl_installer/wheel.py
@@ -62,7 +62,9 @@
         """
         self.name: str = Deps._normalize(name)
         self._platforms: Set[Platform] = platforms or set()
-        self._target_versions = {(p.minor_version, p.micro_version) for p in platforms or {}}
+        self._target_versions = {
+            (p.minor_version, p.micro_version) for p in platforms or {}
+        }
         if platforms and len(self._target_versions) > 1:
             # TODO @aignas 2024-06-23: enable this to be set via a CLI arg
             # for being more explicit.
@@ -94,8 +96,8 @@
         for req in reqs:
             reqs_by_name.setdefault(req.name, []).append(req)
 
-        for reqs in reqs_by_name.values():
-            self._add_req(reqs, want_extras)
+        for req_name, reqs in reqs_by_name.items():
+            self._add_req(req_name, reqs, want_extras)
 
     def _add(self, dep: str, platform: Optional[Platform]):
         dep = Deps._normalize(dep)
@@ -134,7 +136,7 @@
         return re.sub(r"[-_.]+", "_", name).lower()
 
     def _resolve_extras(
-        self, reqs: List[Requirement], extras: Optional[Set[str]]
+        self, reqs: List[Requirement], want_extras: Optional[Set[str]]
     ) -> Set[str]:
         """Resolve extras which are due to depending on self[some_other_extra].
 
@@ -156,7 +158,7 @@
         # extras The empty string in the set is just a way to make the handling
         # of no extras and a single extra easier and having a set of {"", "foo"}
         # is equivalent to having {"foo"}.
-        extras = extras or {""}
+        extras: Set[str] = want_extras or {""}
 
         self_reqs = []
         for req in reqs:
@@ -189,13 +191,18 @@
 
         return extras
 
-    def _add_req(self, reqs: List[Requirement], extras: Set[str]) -> None:
+    def _add_req(self, req_name, reqs: List[Requirement], extras: Set[str]) -> None:
         platforms_to_add = set()
         for req in reqs:
             if req.marker is None:
                 self._add(req.name, None)
                 return
 
+            if not self._platforms:
+                if any(req.marker.evaluate({"extra": extra}) for extra in extras):
+                    self._add(req.name, None)
+                    return
+
             for plat in self._platforms:
                 if plat in platforms_to_add:
                     # marker evaluation is more expensive than this check
@@ -211,18 +218,24 @@
                         added = True
                         break
 
+        if not self._platforms:
+            return
+
         if len(platforms_to_add) == len(self._platforms):
             # the dep is in all target platforms, let's just add it to the regular
             # list
-            self._add(req.name, None)
+            self._add(req_name, None)
             return
 
         for plat in platforms_to_add:
             if self._default_minor_version is not None:
-                self._add(req.name, plat)
+                self._add(req_name, plat)
 
-            if self._default_minor_version is None or plat.minor_version == self._default_minor_version:
-                self._add(req.name, Platform(os = plat.os, arch = plat.arch))
+            if (
+                self._default_minor_version is None
+                or plat.minor_version == self._default_minor_version
+            ):
+                self._add(req_name, Platform(os=plat.os, arch=plat.arch))
 
     def build(self) -> FrozenDeps:
         return FrozenDeps(
diff --git a/python/private/pypi/whl_library.bzl b/python/private/pypi/whl_library.bzl
index 630dc85..0c09f79 100644
--- a/python/private/pypi/whl_library.bzl
+++ b/python/private/pypi/whl_library.bzl
@@ -15,18 +15,16 @@
 ""
 
 load("//python/private:auth.bzl", "AUTH_ATTRS", "get_auth")
-load("//python/private:bzlmod_enabled.bzl", "BZLMOD_ENABLED")
 load("//python/private:envsubst.bzl", "envsubst")
 load("//python/private:is_standalone_interpreter.bzl", "is_standalone_interpreter")
 load("//python/private:repo_utils.bzl", "REPO_DEBUG_ENV_VAR", "repo_utils")
 load(":attrs.bzl", "ATTRS", "use_isolated")
 load(":deps.bzl", "all_repo_names", "record_files")
 load(":generate_whl_library_build_bazel.bzl", "generate_whl_library_build_bazel")
-load(":parse_requirements.bzl", "host_platform")
+load(":parse_whl_name.bzl", "parse_whl_name")
 load(":patch_whl.bzl", "patch_whl")
-load(":pep508_requirement.bzl", "requirement")
 load(":pypi_repo_utils.bzl", "pypi_repo_utils")
-load(":whl_metadata.bzl", "whl_metadata")
+load(":whl_target_platforms.bzl", "whl_target_platforms")
 
 _CPPFLAGS = "CPPFLAGS"
 _COMMAND_LINE_TOOLS_PATH_SLUG = "commandlinetools"
@@ -342,6 +340,21 @@
                 timeout = rctx.attr.timeout,
             )
 
+    target_platforms = rctx.attr.experimental_target_platforms or []
+    if target_platforms:
+        parsed_whl = parse_whl_name(whl_path.basename)
+
+        # NOTE @aignas 2023-12-04: if the wheel is a platform specific wheel, we
+        # only include deps for that target platform
+        if parsed_whl.platform_tag != "any":
+            target_platforms = [
+                p.target_platform
+                for p in whl_target_platforms(
+                    platform_tag = parsed_whl.platform_tag,
+                    abi_tag = parsed_whl.abi_tag.strip("tm"),
+                )
+            ]
+
     pypi_repo_utils.execute_checked(
         rctx,
         op = "whl_library.ExtractWheel({}, {})".format(rctx.attr.name, whl_path),
@@ -349,7 +362,7 @@
         arguments = args + [
             "--whl-file",
             whl_path,
-        ],
+        ] + ["--platform={}".format(p) for p in target_platforms],
         srcs = rctx.attr._python_srcs,
         environment = environment,
         quiet = rctx.attr.quiet,
@@ -384,45 +397,21 @@
         )
         entry_points[entry_point_without_py] = entry_point_script_name
 
-    if BZLMOD_ENABLED:
-        # The following attributes are unset on bzlmod and we pass data through
-        # the hub via load statements.
-        default_python_version = None
-        target_platforms = []
-    else:
-        # NOTE @aignas 2025-04-16: if BZLMOD_ENABLED, we should use
-        # DEFAULT_PYTHON_VERSION since platforms always come with the actual
-        # python version otherwise we should use the version of the interpreter
-        # here. In WORKSPACE `multi_pip_parse` is using an interpreter for each
-        # `pip_parse` invocation, so we will have the host target platform
-        # only. Even if somebody would change the code to support
-        # `experimental_target_platforms`, they would be for a single python
-        # version. Hence, using the `default_python_version` that we get from the
-        # interpreter is correct. Hence, we unset the argument if we are on bzlmod.
-        default_python_version = metadata["python_version"]
-        target_platforms = rctx.attr.experimental_target_platforms or [host_platform(rctx)]
-
-    metadata = whl_metadata(
-        install_dir = rctx.path("site-packages"),
-        read_fn = rctx.read,
-        logger = logger,
-    )
-
     build_file_contents = generate_whl_library_build_bazel(
         name = whl_path.basename,
-        metadata_name = metadata.name,
-        metadata_version = metadata.version,
-        requires_dist = metadata.requires_dist,
         dep_template = rctx.attr.dep_template or "@{}{{name}}//:{{target}}".format(rctx.attr.repo_prefix),
         entry_points = entry_points,
-        target_platforms = target_platforms,
-        default_python_version = default_python_version,
         # TODO @aignas 2025-04-14: load through the hub:
+        dependencies = metadata["deps"],
+        dependencies_by_platform = metadata["deps_by_platform"],
         annotation = None if not rctx.attr.annotation else struct(**json.decode(rctx.read(rctx.attr.annotation))),
         data_exclude = rctx.attr.pip_data_exclude,
-        extras = requirement(rctx.attr.requirement).extras,
         group_deps = rctx.attr.group_deps,
         group_name = rctx.attr.group_name,
+        tags = [
+            "pypi_name={}".format(metadata["name"]),
+            "pypi_version={}".format(metadata["version"]),
+        ],
     )
     rctx.file("BUILD.bazel", build_file_contents)
 
diff --git a/tests/pypi/extension/extension_tests.bzl b/tests/pypi/extension/extension_tests.bzl
index 5de3bb5..1cd6869 100644
--- a/tests/pypi/extension/extension_tests.bzl
+++ b/tests/pypi/extension/extension_tests.bzl
@@ -136,6 +136,7 @@
         parallel_download = False,
         experimental_index_url_overrides = {},
         simpleapi_skip = simpleapi_skip,
+        _evaluate_markers_srcs = [],
         **kwargs
     )
 
@@ -273,6 +274,14 @@
             "python_3_15_host": "unit_test_interpreter_target",
         },
         minor_mapping = {"3.15": "3.15.19"},
+        evaluate_markers = lambda _, requirements, **__: {
+            key: [
+                platform
+                for platform in platforms
+                if ("x86_64" in platform and "platform_machine ==" in key) or ("x86_64" not in platform and "platform_machine !=" in key)
+            ]
+            for key, platforms in requirements.items()
+        },
     )
 
     pypi.exposed_packages().contains_exactly({"pypi": ["torch"]})
@@ -397,6 +406,15 @@
         },
         minor_mapping = {"3.12": "3.12.19"},
         simpleapi_download = mocksimpleapi_download,
+        evaluate_markers = lambda _, requirements, **__: {
+            # todo once 2692 is merged, this is going to be easier to test.
+            key: [
+                platform
+                for platform in platforms
+                if ("x86_64" in platform and "platform_machine ==" in key) or ("x86_64" not in platform and "platform_machine !=" in key)
+            ]
+            for key, platforms in requirements.items()
+        },
     )
 
     pypi.exposed_packages().contains_exactly({"pypi": ["torch"]})
@@ -440,6 +458,11 @@
     pypi.whl_libraries().contains_exactly({
         "pypi_312_torch_cp312_cp312_linux_x86_64_8800deef": {
             "dep_template": "@pypi//{name}:{target}",
+            "experimental_target_platforms": [
+                "linux_x86_64",
+                "osx_x86_64",
+                "windows_x86_64",
+            ],
             "filename": "torch-2.4.1+cpu-cp312-cp312-linux_x86_64.whl",
             "python_interpreter_target": "unit_test_interpreter_target",
             "requirement": "torch==2.4.1+cpu",
@@ -448,6 +471,13 @@
         },
         "pypi_312_torch_cp312_cp312_manylinux_2_17_aarch64_36109432": {
             "dep_template": "@pypi//{name}:{target}",
+            "experimental_target_platforms": [
+                "linux_aarch64",
+                "linux_arm",
+                "linux_ppc",
+                "linux_s390x",
+                "osx_aarch64",
+            ],
             "filename": "torch-2.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
             "python_interpreter_target": "unit_test_interpreter_target",
             "requirement": "torch==2.4.1",
@@ -456,6 +486,11 @@
         },
         "pypi_312_torch_cp312_cp312_win_amd64_3a570e5c": {
             "dep_template": "@pypi//{name}:{target}",
+            "experimental_target_platforms": [
+                "linux_x86_64",
+                "osx_x86_64",
+                "windows_x86_64",
+            ],
             "filename": "torch-2.4.1+cpu-cp312-cp312-win_amd64.whl",
             "python_interpreter_target": "unit_test_interpreter_target",
             "requirement": "torch==2.4.1+cpu",
@@ -464,6 +499,13 @@
         },
         "pypi_312_torch_cp312_none_macosx_11_0_arm64_72b484d5": {
             "dep_template": "@pypi//{name}:{target}",
+            "experimental_target_platforms": [
+                "linux_aarch64",
+                "linux_arm",
+                "linux_ppc",
+                "linux_s390x",
+                "osx_aarch64",
+            ],
             "filename": "torch-2.4.1-cp312-none-macosx_11_0_arm64.whl",
             "python_interpreter_target": "unit_test_interpreter_target",
             "requirement": "torch==2.4.1",
@@ -751,6 +793,16 @@
     pypi.whl_libraries().contains_exactly({
         "pypi_315_any_name": {
             "dep_template": "@pypi//{name}:{target}",
+            "experimental_target_platforms": [
+                "linux_aarch64",
+                "linux_arm",
+                "linux_ppc",
+                "linux_s390x",
+                "linux_x86_64",
+                "osx_aarch64",
+                "osx_x86_64",
+                "windows_x86_64",
+            ],
             "extra_pip_args": ["--extra-args-for-sdist-building"],
             "filename": "any-name.tar.gz",
             "python_interpreter_target": "unit_test_interpreter_target",
@@ -760,6 +812,16 @@
         },
         "pypi_315_direct_without_sha_0_0_1_py3_none_any": {
             "dep_template": "@pypi//{name}:{target}",
+            "experimental_target_platforms": [
+                "linux_aarch64",
+                "linux_arm",
+                "linux_ppc",
+                "linux_s390x",
+                "linux_x86_64",
+                "osx_aarch64",
+                "osx_x86_64",
+                "windows_x86_64",
+            ],
             "filename": "direct_without_sha-0.0.1-py3-none-any.whl",
             "python_interpreter_target": "unit_test_interpreter_target",
             "requirement": "direct_without_sha==0.0.1 @ example-direct.org/direct_without_sha-0.0.1-py3-none-any.whl",
@@ -780,6 +842,16 @@
         },
         "pypi_315_simple_py3_none_any_deadb00f": {
             "dep_template": "@pypi//{name}:{target}",
+            "experimental_target_platforms": [
+                "linux_aarch64",
+                "linux_arm",
+                "linux_ppc",
+                "linux_s390x",
+                "linux_x86_64",
+                "osx_aarch64",
+                "osx_x86_64",
+                "windows_x86_64",
+            ],
             "filename": "simple-0.0.1-py3-none-any.whl",
             "python_interpreter_target": "unit_test_interpreter_target",
             "requirement": "simple==0.0.1",
@@ -788,6 +860,16 @@
         },
         "pypi_315_simple_sdist_deadbeef": {
             "dep_template": "@pypi//{name}:{target}",
+            "experimental_target_platforms": [
+                "linux_aarch64",
+                "linux_arm",
+                "linux_ppc",
+                "linux_s390x",
+                "linux_x86_64",
+                "osx_aarch64",
+                "osx_x86_64",
+                "windows_x86_64",
+            ],
             "extra_pip_args": ["--extra-args-for-sdist-building"],
             "filename": "simple-0.0.1.tar.gz",
             "python_interpreter_target": "unit_test_interpreter_target",
@@ -797,6 +879,16 @@
         },
         "pypi_315_some_pkg_py3_none_any_deadbaaf": {
             "dep_template": "@pypi//{name}:{target}",
+            "experimental_target_platforms": [
+                "linux_aarch64",
+                "linux_arm",
+                "linux_ppc",
+                "linux_s390x",
+                "linux_x86_64",
+                "osx_aarch64",
+                "osx_x86_64",
+                "windows_x86_64",
+            ],
             "filename": "some_pkg-0.0.1-py3-none-any.whl",
             "python_interpreter_target": "unit_test_interpreter_target",
             "requirement": "some_pkg==0.0.1 @ example-direct.org/some_pkg-0.0.1-py3-none-any.whl --hash=sha256:deadbaaf",
@@ -805,6 +897,16 @@
         },
         "pypi_315_some_py3_none_any_deadb33f": {
             "dep_template": "@pypi//{name}:{target}",
+            "experimental_target_platforms": [
+                "linux_aarch64",
+                "linux_arm",
+                "linux_ppc",
+                "linux_s390x",
+                "linux_x86_64",
+                "osx_aarch64",
+                "osx_x86_64",
+                "windows_x86_64",
+            ],
             "filename": "some-other-pkg-0.0.1-py3-none-any.whl",
             "python_interpreter_target": "unit_test_interpreter_target",
             "requirement": "some_other_pkg==0.0.1",
@@ -856,6 +958,14 @@
             "python_3_15_host": "unit_test_interpreter_target",
         },
         minor_mapping = {"3.15": "3.15.19"},
+        evaluate_markers = lambda _, requirements, **__: {
+            key: [
+                platform
+                for platform in platforms
+                if ("darwin" in key and "osx" in platform) or ("linux" in key and "linux" in platform)
+            ]
+            for key, platforms in requirements.items()
+        },
     )
 
     pypi.exposed_packages().contains_exactly({"pypi": []})
diff --git a/tests/pypi/generate_whl_library_build_bazel/generate_whl_library_build_bazel_tests.bzl b/tests/pypi/generate_whl_library_build_bazel/generate_whl_library_build_bazel_tests.bzl
index 7bd19b6..83be739 100644
--- a/tests/pypi/generate_whl_library_build_bazel/generate_whl_library_build_bazel_tests.bzl
+++ b/tests/pypi/generate_whl_library_build_bazel/generate_whl_library_build_bazel_tests.bzl
@@ -86,7 +86,6 @@
 def _test_all_with_loads(env):
     want = """\
 load("@rules_python//python/private/pypi:whl_library_targets.bzl", "whl_library_targets_from_requires")
-load("@pypi//:config.bzl", "target_platforms")
 
 package(default_visibility = ["//visibility:public"])
 
@@ -119,7 +118,6 @@
         "qux",
     ],
     srcs_exclude = ["srcs_exclude_all"],
-    target_platforms = target_platforms,
 )
 
 # SOMETHING SPECIAL AT THE END
diff --git a/tests/pypi/parse_requirements/parse_requirements_tests.bzl b/tests/pypi/parse_requirements/parse_requirements_tests.bzl
index c504821..723bb60 100644
--- a/tests/pypi/parse_requirements/parse_requirements_tests.bzl
+++ b/tests/pypi/parse_requirements/parse_requirements_tests.bzl
@@ -458,7 +458,7 @@
 _tests.append(_test_select_requirement_none_platform)
 
 def _test_env_marker_resolution(env):
-    def _mock_eval_markers(input):
+    def _mock_eval_markers(_, input):
         ret = {
             "foo[extra]==0.0.1 ;marker --hash=sha256:deadbeef": ["cp311_windows_x86_64"],
         }
diff --git a/tests/pypi/whl_installer/wheel_test.py b/tests/pypi/whl_installer/wheel_test.py
index 6921fe6..3599fd1 100644
--- a/tests/pypi/whl_installer/wheel_test.py
+++ b/tests/pypi/whl_installer/wheel_test.py
@@ -11,7 +11,7 @@
 
 class DepsTest(unittest.TestCase):
     def test_simple(self):
-        deps = wheel.Deps("foo", requires_dist=["bar"])
+        deps = wheel.Deps("foo", requires_dist=["bar", 'baz; extra=="foo"'])
 
         got = deps.build()