fix: Add linux_riscv64 to _pip_repository_impl (#3350)

Add `linux_riscv64` support for pulling pip dependencies. This is not
adding any hermetic toolchain support - user has to provide a working
toolchain.

Fix #2729

---------

Co-authored-by: Ignas Anikevicius <240938+aignas@users.noreply.github.com>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6cb5716..ad8f1c9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -113,6 +113,8 @@
   ([#3339](https://github.com/bazel-contrib/rules_python/issues/3339)).
 * (uv) {obj}`//python/uv:lock.bzl%lock` now works with a local platform
   runtime.
+* (pypi) `linux_riscv64` is added to the platforms list in `_pip_repository_impl`,
+  which fixes [a build issue for tensorflow on riscv64](https://github.com/bazel-contrib/rules_python/discussions/2729).
 * (toolchains) WORKSPACE builds now correctly register musl and freethreaded
   variants. Setting {obj}`--py_linux_libc=musl` and `--py_freethreaded=yes` now
   activate them, respectively.
diff --git a/python/private/pypi/pip_repository.bzl b/python/private/pypi/pip_repository.bzl
index e9a4c44..d635651 100644
--- a/python/private/pypi/pip_repository.bzl
+++ b/python/private/pypi/pip_repository.bzl
@@ -96,6 +96,7 @@
                 "linux_aarch64",
                 "linux_arm",
                 "linux_ppc",
+                "linux_riscv64",
                 "linux_s390x",
                 "linux_x86_64",
                 "osx_aarch64",
diff --git a/python/private/pypi/whl_installer/platform.py b/python/private/pypi/whl_installer/platform.py
index ff267fe..0757d86 100644
--- a/python/private/pypi/whl_installer/platform.py
+++ b/python/private/pypi/whl_installer/platform.py
@@ -45,6 +45,7 @@
     ppc64le = 5
     s390x = 6
     arm = 7
+    riscv64 = 8
     amd64 = x86_64
     arm64 = aarch64
     i386 = x86_32
@@ -269,6 +270,8 @@
             return "ppc"
         elif self.arch == Arch.ppc64le:
             return "ppc64le"
+        elif self.arch == Arch.riscv64:
+            return "riscv64"
         elif self.arch == Arch.s390x:
             return "s390x"
         else:
diff --git a/python/private/pypi/whl_target_platforms.bzl b/python/private/pypi/whl_target_platforms.bzl
index 6c3dd5d..28547c6 100644
--- a/python/private/pypi/whl_target_platforms.bzl
+++ b/python/private/pypi/whl_target_platforms.bzl
@@ -30,6 +30,7 @@
     "ppc": "ppc",
     "ppc64": "ppc",
     "ppc64le": "ppc64le",
+    "riscv64": "riscv64",
     "s390x": "s390x",
     "arm": "arm",
     "armv6l": "arm",
diff --git a/tests/pypi/whl_installer/platform_test.py b/tests/pypi/whl_installer/platform_test.py
index ad65650..0d944bb 100644
--- a/tests/pypi/whl_installer/platform_test.py
+++ b/tests/pypi/whl_installer/platform_test.py
@@ -38,17 +38,17 @@
 
     def test_can_get_all_for_py_version(self):
         cp39 = Platform.all(minor_version=9, micro_version=0)
-        self.assertEqual(21, len(cp39), f"Got {cp39}")
+        self.assertEqual(24, len(cp39), f"Got {cp39}")
         self.assertEqual(cp39, Platform.from_string("cp39.0_*"))
 
     def test_can_get_all_for_os(self):
         linuxes = Platform.all(OS.linux, minor_version=9)
-        self.assertEqual(7, len(linuxes))
+        self.assertEqual(8, len(linuxes))
         self.assertEqual(linuxes, Platform.from_string("cp39_linux_*"))
 
     def test_can_get_all_for_os_for_host_python(self):
         linuxes = Platform.all(OS.linux)
-        self.assertEqual(7, len(linuxes))
+        self.assertEqual(8, len(linuxes))
         self.assertEqual(linuxes, Platform.from_string("linux_*"))
 
     def test_platform_sort(self):
diff --git a/tests/pypi/whl_target_platforms/whl_target_platforms_tests.bzl b/tests/pypi/whl_target_platforms/whl_target_platforms_tests.bzl
index a976a0c..6bec26c 100644
--- a/tests/pypi/whl_target_platforms/whl_target_platforms_tests.bzl
+++ b/tests/pypi/whl_target_platforms/whl_target_platforms_tests.bzl
@@ -34,6 +34,9 @@
         "musllinux_1_1_ppc64le": [
             struct(os = "linux", cpu = "ppc64le", abi = None, target_platform = "linux_ppc64le", version = (1, 1)),
         ],
+        "musllinux_1_2_riscv64": [
+            struct(os = "linux", cpu = "riscv64", abi = None, target_platform = "linux_riscv64", version = (1, 2)),
+        ],
         "win_amd64": [
             struct(os = "windows", cpu = "x86_64", abi = None, target_platform = "windows_x86_64", version = (0, 0)),
         ],
@@ -66,6 +69,9 @@
         "musllinux_1_1_ppc64le": [
             struct(os = "linux", cpu = "ppc64le", abi = "cp311", target_platform = "cp311_linux_ppc64le", version = (1, 1)),
         ],
+        "musllinux_1_2_riscv64": [
+            struct(os = "linux", cpu = "riscv64", abi = "cp311", target_platform = "cp311_linux_riscv64", version = (1, 2)),
+        ],
         "win_amd64": [
             struct(os = "windows", cpu = "x86_64", abi = "cp311", target_platform = "cp311_windows_x86_64", version = (0, 0)),
         ],
@@ -103,6 +109,7 @@
         "manylinux_11_12_i686": 1,
         "manylinux_11_12_ppc64": 1,
         "manylinux_11_12_ppc64le": 1,
+        "manylinux_11_12_riscv64": 1,
         "manylinux_11_12_s390x": 1,
         "manylinux_11_12_x86_64": 1,
         "manylinux_1_2_aarch64": 1,
@@ -111,6 +118,7 @@
         "musllinux_11_12_armv7l": 1,
         "musllinux_11_12_i686": 1,
         "musllinux_11_12_ppc64le": 1,
+        "musllinux_11_12_riscv64": 1,
         "musllinux_11_12_s390x": 1,
         "musllinux_11_12_x86_64": 1,
         "win32": 1,