Provide current_py_toolchain (#731)

This commit introduces the current_py_toolchain rule, exposing the
PYTHON2 and PYTHON3 "make" variables in bazel rules, analagous to
@bazel_tools//tools/cpp:current_cc_toolchain.

See
https://docs.bazel.build/versions/main/be/make-variables.html#custom_variables

Co-authored-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com>
diff --git a/python/BUILD b/python/BUILD
index 05cc9d1..ce19653 100644
--- a/python/BUILD
+++ b/python/BUILD
@@ -24,6 +24,8 @@
 that @rules_python//python is only concerned with the core rules.
 """
 
+load(":defs.bzl", "current_py_toolchain")
+
 package(default_visibility = ["//visibility:public"])
 
 licenses(["notice"])  # Apache 2.0
@@ -138,3 +140,7 @@
     "packaging.bzl",
     "pip.bzl",
 ])
+
+current_py_toolchain(
+    name = "current_py_toolchain",
+)
diff --git a/python/defs.bzl b/python/defs.bzl
index 39c26eb..f3a74eb 100644
--- a/python/defs.bzl
+++ b/python/defs.bzl
@@ -41,6 +41,49 @@
         attrs["tags"] = [_MIGRATION_TAG]
     return attrs
 
+def _current_py_toolchain_impl(ctx):
+    toolchain = ctx.toolchains[ctx.attr._toolchain]
+
+    direct = []
+    transitive = []
+    vars = {}
+
+    if toolchain.py3_runtime and toolchain.py3_runtime.interpreter:
+        direct.append(toolchain.py3_runtime.interpreter)
+        transitive.append(toolchain.py3_runtime.files)
+        vars["PYTHON3"] = toolchain.py3_runtime.interpreter.path
+
+    if toolchain.py2_runtime and toolchain.py2_runtime.interpreter:
+        direct.append(toolchain.py2_runtime.interpreter)
+        transitive.append(toolchain.py2_runtime.files)
+        vars["PYTHON2"] = toolchain.py2_runtime.interpreter.path
+
+    files = depset(direct, transitive = transitive)
+    return [
+        toolchain,
+        platform_common.TemplateVariableInfo(vars),
+        DefaultInfo(
+            runfiles = ctx.runfiles(transitive_files = files),
+            files = files,
+        ),
+    ]
+
+current_py_toolchain = rule(
+    doc = """
+    This rule exists so that the current python toolchain can be used in the `toolchains` attribute of
+    other rules, such as genrule. It allows exposing a python toolchain after toolchain resolution has
+    happened, to a rule which expects a concrete implementation of a toolchain, rather than a
+    toolchain_type which could be resolved to that toolchain.
+    """,
+    implementation = _current_py_toolchain_impl,
+    attrs = {
+        "_toolchain": attr.string(default = str(Label("@bazel_tools//tools/python:toolchain_type"))),
+    },
+    toolchains = [
+        str(Label("@bazel_tools//tools/python:toolchain_type")),
+    ],
+)
+
 def py_library(**attrs):
     """See the Bazel core [py_library](https://docs.bazel.build/versions/master/be/python.html#py_library) documentation.