Get matplotlib working with upstream Python

This patch adds support for using matplotlib plus its Gtk backend with
`--config=k8_upstream_python`. Unfortunately, the Tk backend doesn't
work because of how Python is packaged. See the following issue for
more information:
https://github.com/matplotlib/matplotlib/issues/23074

Separately, we need to patch pygobject and matplotlib for various
hermeticity reasons. To accomplish this, I've added patching support
for wheels downloaded via rules_python. I should have set it up to use
annotations (the same mechanism we use for injecting deps), but it was
a little cumbersome. Annotations are not set up for using in arguments
to repository rules. I instead opted for a separate JSON file. You can
find it at `tools/python/patches.json`.

You can try the two new example programs:

    $ bazel run --config=k8_upstream_python //build_tests:matplotlib_example
    $ bazel run --config=k8_upstream_python //build_tests:pygobject_example

Signed-off-by: Philipp Schrader <philipp.schrader@gmail.com>
Change-Id: I3c4e8648a8012aa23dedd53610e82d590d1c409d
diff --git a/tools/python/package_annotations.bzl b/tools/python/package_annotations.bzl
new file mode 100644
index 0000000..b359d72
--- /dev/null
+++ b/tools/python/package_annotations.bzl
@@ -0,0 +1,12 @@
+load("@rules_python//python:pip.bzl", "package_annotation")
+
+ANNOTATIONS = {
+    "matplotlib": package_annotation(
+        data = ["@gtk_runtime//:gtk_runtime"],
+        deps = ["@bazel_tools//tools/python/runfiles"],
+    ),
+    "pygobject": package_annotation(
+        data = ["@gtk_runtime//:gtk_runtime"],
+        deps = ["@bazel_tools//tools/python/runfiles"],
+    ),
+}
diff --git a/tools/python/patches.json b/tools/python/patches.json
new file mode 100644
index 0000000..bfda933
--- /dev/null
+++ b/tools/python/patches.json
@@ -0,0 +1,14 @@
+{
+    "matplotlib": {
+        "patches": [
+            "//third_party:python/matplotlib/init.patch"
+        ],
+        "patch_args": ["-p1"]
+    },
+    "pygobject": {
+        "patches": [
+            "//third_party:python/pygobject/init.patch"
+        ],
+        "patch_args": ["-p1"]
+    }
+}
diff --git a/tools/python/runtime_binary.sh b/tools/python/runtime_binary.sh
index 1a4b3dc..6dc34c1 100755
--- a/tools/python/runtime_binary.sh
+++ b/tools/python/runtime_binary.sh
@@ -23,7 +23,11 @@
 for path in ${PYTHONPATH//:/ }; do
   if [[ "$path" == *.runfiles/python3_9_x86_64-unknown-linux-gnu ]]; then
     PYTHON_BIN="$path"/bin/python3
-    export LD_LIBRARY_PATH="$path"/lib
+    LD_LIBRARY_PATH=":${path}/lib"
+    LD_LIBRARY_PATH+=":${path}/../gtk_runtime/lib/x86_64-linux-gnu"
+    LD_LIBRARY_PATH+=":${path}/../gtk_runtime/usr/lib/x86_64-linux-gnu"
+    LD_LIBRARY_PATH+=":${path}/../gtk_runtime/usr/lib"
+    export LD_LIBRARY_PATH
     break
   elif [[ "$path" == *.runfiles/python_repo ]]; then
     PYTHON_BIN="$path"/usr/bin/python3