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/README.md b/README.md
index d880b0a..b553e09 100644
--- a/README.md
+++ b/README.md
@@ -83,6 +83,11 @@
 is still used to 'bootstrap' Python targets (see https://github.com/bazelbuild/rules_python/issues/691).
 You may also find some quirks while using this toolchain. Please refer to [python-build-standalone documentation's _Quirks_ section](https://python-build-standalone.readthedocs.io/en/latest/quirks.html) for details.
 
+### Toolchain usage in other rules
+
+Python toolchains can be utilised in other bazel rules, such as `genrule()`, by adding the `toolchains=["@rules_python//python:current_py_toolchain"]` attribute. The path to the python interpreter can be obtained by using the `$(PYTHON2)` and `$(PYTHON3)` ["Make" Variables](https://bazel.build/reference/be/make-variables). See the [`test_current_py_toolchain`](tests/load_from_macro/BUILD) target for an example.
+
+
 ### "Hello World"
 
 Once you've imported the rule set into your `WORKSPACE` using any of these
diff --git a/docs/python.md b/docs/python.md
index 2b57d25..bd14b82 100755
--- a/docs/python.md
+++ b/docs/python.md
@@ -1,5 +1,28 @@
 <!-- Generated with Stardoc: http://skydoc.bazel.build -->
 
+<a name="#current_py_toolchain"></a>
+
+## current_py_toolchain
+
+<pre>
+current_py_toolchain(<a href="#current_py_toolchain-name">name</a>)
+</pre>
+
+
+    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.
+    
+
+**ATTRIBUTES**
+
+
+| Name  | Description | Type | Mandatory | Default |
+| :-------------: | :-------------: | :-------------: | :-------------: | :-------------: |
+| name |  A unique name for this target.   | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required |  |
+
+
 <a name="#py_import"></a>
 
 ## py_import
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.
 
diff --git a/tests/load_from_macro/BUILD b/tests/load_from_macro/BUILD
index 8b5048a..00d7bf9 100644
--- a/tests/load_from_macro/BUILD
+++ b/tests/load_from_macro/BUILD
@@ -24,3 +24,11 @@
     # Allow a test to verify an "outside package" doesn't get included
     visibility = ["//examples/wheel:__pkg__"],
 )
+
+genrule(
+    name = "test_current_py_toolchain",
+    srcs = [],
+    outs = ["out.txt"],
+    cmd = "$(PYTHON3) --version > $(location out.txt)",
+    toolchains = ["//python:current_py_toolchain"],
+)