Make matplotlibcpp work with upstream Python

This patch doesn't work on its own because the users of matplotlibcpp
often still depend on "debian_bundled_python" packages. If you want to
test locally, run with Ic7a8ba6110516aa2446ad2ad4e2495fab62d824c.

I can't get the version from master working. I'm assuming that's
because it refers to Python 3.5 instead of our current Python 3.9.
Regardless, you can see the plots with the new setup like so:

    $ bazel run //frc971/control_loops/drivetrain:line_follow_drivetrain_test -- --plot --gtest_filter=LineFollowDrivetrainTest.BasicGoalThetaCheck

(Note that you need `--config=k8_upstream_python` if running without
Ic7a8ba6110516aa2446ad2ad4e2495fab62d824c.)

The above command displays the two plots, but then crashes after the
plots are closed. I'm really not sure what's going on there. It works
without issues, however, when run roughly like so:

    $ $ (cd bazel-bin/frc971/control_loops/drivetrain/line_follow_drivetrain_test.runfiles/org_frc971/ && RUNFILES_DIR=$(pwd)/../ ../../line_follow_drivetrain_test --plot --gtest_filter=LineFollowDrivetrainTest.BasicGoalThetaCheck)

Signed-off-by: Philipp Schrader <philipp.schrader@gmail.com>
Change-Id: I2514a3831f18a7bec3a6d458965e94eb5d19e5fc
diff --git a/third_party/python/defs.bzl b/third_party/python/defs.bzl
new file mode 100644
index 0000000..f49d0ba
--- /dev/null
+++ b/third_party/python/defs.bzl
@@ -0,0 +1,34 @@
+def _extract_numpy_headers_impl(ctx):
+    files = ctx.attr.numpy[DefaultInfo].default_runfiles.files.to_list()
+    prefix = ctx.attr.header_prefix
+
+    hdrs = []
+    for file in files:
+        _, partition, include_file = file.path.partition("/numpy/core/include/numpy/")
+        if partition:
+            hdr = ctx.actions.declare_file("%s/numpy/%s" % (prefix, include_file))
+            ctx.actions.run(
+                inputs = [file],
+                outputs = [hdr],
+                executable = "cp",
+                arguments = [file.path, hdr.path],
+            )
+            hdrs.append(hdr)
+
+    return [DefaultInfo(files=depset(hdrs))]
+
+extract_numpy_headers = rule(
+    implementation = _extract_numpy_headers_impl,
+    doc = "Extracts the numpy headers from the corresponding py_library target.",
+    attrs = {
+        "numpy": attr.label(
+            mandatory = True,
+            providers = [PyInfo],
+            doc = "The label for the numpy py_library target.",
+        ),
+        "header_prefix": attr.string(
+            mandatory = True,
+            doc = "The directory to copy the headers into.",
+        ),
+    },
+)