Fail if Python 2 values are specified (#887)

Fail for py2 python_version, srcs_version, and runtime values.

See https://github.com/bazelbuild/rules_python/issues/886
diff --git a/docs/python.md b/docs/python.md
index 1726ade..6682e48 100755
--- a/docs/python.md
+++ b/docs/python.md
@@ -55,84 +55,6 @@
 | <a id="py_import-srcs"></a>srcs |  The list of Python package files provided to Python targets that depend on this target. Note that currently only the .egg format is accepted. For .whl files, try the whl_library rule. We accept contributions to extend py_import to handle .whl.   | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | <code>[]</code> |
 
 
-<a id="py_runtime_pair"></a>
-
-## py_runtime_pair
-
-<pre>
-py_runtime_pair(<a href="#py_runtime_pair-name">name</a>, <a href="#py_runtime_pair-py2_runtime">py2_runtime</a>, <a href="#py_runtime_pair-py3_runtime">py3_runtime</a>)
-</pre>
-
-A toolchain rule for Python.
-
-This wraps up to two Python runtimes, one for Python 2 and one for Python 3.
-The rule consuming this toolchain will choose which runtime is appropriate.
-Either runtime may be omitted, in which case the resulting toolchain will be
-unusable for building Python code using that version.
-
-Usually the wrapped runtimes are declared using the `py_runtime` rule, but any
-rule returning a `PyRuntimeInfo` provider may be used.
-
-This rule returns a `platform_common.ToolchainInfo` provider with the following
-schema:
-
-```python
-platform_common.ToolchainInfo(
-    py2_runtime = &lt;PyRuntimeInfo or None&gt;,
-    py3_runtime = &lt;PyRuntimeInfo or None&gt;,
-)
-```
-
-Example usage:
-
-```python
-# In your BUILD file...
-
-load("@rules_python//python:defs.bzl", "py_runtime_pair")
-
-py_runtime(
-    name = "my_py2_runtime",
-    interpreter_path = "/system/python2",
-    python_version = "PY2",
-)
-
-py_runtime(
-    name = "my_py3_runtime",
-    interpreter_path = "/system/python3",
-    python_version = "PY3",
-)
-
-py_runtime_pair(
-    name = "my_py_runtime_pair",
-    py2_runtime = ":my_py2_runtime",
-    py3_runtime = ":my_py3_runtime",
-)
-
-toolchain(
-    name = "my_toolchain",
-    target_compatible_with = &lt;...&gt;,
-    toolchain = ":my_py_runtime_pair",
-    toolchain_type = "@rules_python//python:toolchain_type",
-)
-```
-
-```python
-# In your WORKSPACE...
-
-register_toolchains("//my_pkg:my_toolchain")
-```
-
-
-**ATTRIBUTES**
-
-
-| Name  | Description | Type | Mandatory | Default |
-| :------------- | :------------- | :------------- | :------------- | :------------- |
-| <a id="py_runtime_pair-name"></a>name |  A unique name for this target.   | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required |  |
-| <a id="py_runtime_pair-py2_runtime"></a>py2_runtime |  The runtime to use for Python 2 targets. Must have <code>python_version</code> set to <code>PY2</code>.   | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>None</code> |
-| <a id="py_runtime_pair-py3_runtime"></a>py3_runtime |  The runtime to use for Python 3 targets. Must have <code>python_version</code> set to <code>PY3</code>.   | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>None</code> |
-
-
 <a id="py_binary"></a>
 
 ## py_binary
@@ -187,6 +109,77 @@
 | <a id="py_runtime-attrs"></a>attrs |  Rule attributes   |  none |
 
 
+<a id="py_runtime_pair"></a>
+
+## py_runtime_pair
+
+<pre>
+py_runtime_pair(<a href="#py_runtime_pair-name">name</a>, <a href="#py_runtime_pair-py2_runtime">py2_runtime</a>, <a href="#py_runtime_pair-py3_runtime">py3_runtime</a>, <a href="#py_runtime_pair-attrs">attrs</a>)
+</pre>
+
+A toolchain rule for Python.
+
+This used to wrap up to two Python runtimes, one for Python 2 and one for Python 3.
+However, Python 2 is no longer supported, so it now only wraps a single Python 3
+runtime.
+
+Usually the wrapped runtimes are declared using the `py_runtime` rule, but any
+rule returning a `PyRuntimeInfo` provider may be used.
+
+This rule returns a `platform_common.ToolchainInfo` provider with the following
+schema:
+
+```python
+platform_common.ToolchainInfo(
+    py2_runtime = None,
+    py3_runtime = &lt;PyRuntimeInfo or None&gt;,
+)
+```
+
+Example usage:
+
+```python
+# In your BUILD file...
+
+load("@rules_python//python:defs.bzl", "py_runtime_pair")
+
+py_runtime(
+    name = "my_py3_runtime",
+    interpreter_path = "/system/python3",
+    python_version = "PY3",
+)
+
+py_runtime_pair(
+    name = "my_py_runtime_pair",
+    py3_runtime = ":my_py3_runtime",
+)
+
+toolchain(
+    name = "my_toolchain",
+    target_compatible_with = &lt;...&gt;,
+    toolchain = ":my_py_runtime_pair",
+    toolchain_type = "@rules_python//python:toolchain_type",
+)
+```
+
+```python
+# In your WORKSPACE...
+
+register_toolchains("//my_pkg:my_toolchain")
+```
+
+
+**PARAMETERS**
+
+
+| Name  | Description | Default Value |
+| :------------- | :------------- | :------------- |
+| <a id="py_runtime_pair-name"></a>name |  str, the name of the target   |  none |
+| <a id="py_runtime_pair-py2_runtime"></a>py2_runtime |  optional Label; must be unset or None; an error is raised otherwise.   |  <code>None</code> |
+| <a id="py_runtime_pair-py3_runtime"></a>py3_runtime |  Label; a target with <code>PyRuntimeInfo</code> for Python 3.   |  <code>None</code> |
+| <a id="py_runtime_pair-attrs"></a>attrs |  Extra attrs passed onto the native rule   |  none |
+
+
 <a id="py_test"></a>
 
 ## py_test
diff --git a/python/defs.bzl b/python/defs.bzl
index 88f28c5..7b60c65 100644
--- a/python/defs.bzl
+++ b/python/defs.bzl
@@ -17,7 +17,6 @@
 """
 
 load("@bazel_tools//tools/python:srcs_version.bzl", _find_requirements = "find_requirements")
-load("@bazel_tools//tools/python:toolchain.bzl", _py_runtime_pair = "py_runtime_pair")
 load(
     "//python/private:reexports.bzl",
     "internal_PyInfo",
@@ -25,6 +24,7 @@
     _py_binary = "py_binary",
     _py_library = "py_library",
     _py_runtime = "py_runtime",
+    _py_runtime_pair = "py_runtime_pair",
     _py_test = "py_test",
 )
 
diff --git a/python/private/reexports.bzl b/python/private/reexports.bzl
index 6ad9e0c..987187c 100644
--- a/python/private/reexports.bzl
+++ b/python/private/reexports.bzl
@@ -37,6 +37,8 @@
 the original name.
 """
 
+load("@bazel_tools//tools/python:toolchain.bzl", _py_runtime_pair = "py_runtime_pair")
+
 # The implementation of the macros and tagging mechanism follows the example
 # set by rules_cc and rules_java.
 
@@ -64,6 +66,8 @@
     Args:
       **attrs: Rule attributes
     """
+    if attrs.get("srcs_version") in ("PY2", "PY2ONLY"):
+        fail("Python 2 is no longer supported: https://github.com/bazelbuild/rules_python/issues/886")
 
     # buildifier: disable=native-python
     native.py_library(**_add_tags(attrs))
@@ -74,6 +78,10 @@
     Args:
       **attrs: Rule attributes
     """
+    if attrs.get("python_version") == "PY2":
+        fail("Python 2 is no longer supported: https://github.com/bazelbuild/rules_python/issues/886")
+    if attrs.get("srcs_version") in ("PY2", "PY2ONLY"):
+        fail("Python 2 is no longer supported: https://github.com/bazelbuild/rules_python/issues/886")
 
     # buildifier: disable=native-python
     native.py_binary(**_add_tags(attrs))
@@ -84,6 +92,10 @@
     Args:
       **attrs: Rule attributes
     """
+    if attrs.get("python_version") == "PY2":
+        fail("Python 2 is no longer supported: https://github.com/bazelbuild/rules_python/issues/886")
+    if attrs.get("srcs_version") in ("PY2", "PY2ONLY"):
+        fail("Python 2 is no longer supported: https://github.com/bazelbuild/rules_python/issues/886")
 
     # buildifier: disable=native-python
     native.py_test(**_add_tags(attrs))
@@ -94,6 +106,78 @@
     Args:
       **attrs: Rule attributes
     """
+    if attrs.get("python_version") == "PY2":
+        fail("Python 2 is no longer supported: see https://github.com/bazelbuild/rules_python/issues/886")
 
     # buildifier: disable=native-python
     native.py_runtime(**_add_tags(attrs))
+
+# NOTE: This doc is copy/pasted from the builtin py_runtime_pair rule so our
+# doc generator gives useful API docs.
+def py_runtime_pair(name, py2_runtime = None, py3_runtime = None, **attrs):
+    """A toolchain rule for Python.
+
+    This used to wrap up to two Python runtimes, one for Python 2 and one for Python 3.
+    However, Python 2 is no longer supported, so it now only wraps a single Python 3
+    runtime.
+
+    Usually the wrapped runtimes are declared using the `py_runtime` rule, but any
+    rule returning a `PyRuntimeInfo` provider may be used.
+
+    This rule returns a `platform_common.ToolchainInfo` provider with the following
+    schema:
+
+    ```python
+    platform_common.ToolchainInfo(
+        py2_runtime = None,
+        py3_runtime = <PyRuntimeInfo or None>,
+    )
+    ```
+
+    Example usage:
+
+    ```python
+    # In your BUILD file...
+
+    load("@rules_python//python:defs.bzl", "py_runtime_pair")
+
+    py_runtime(
+        name = "my_py3_runtime",
+        interpreter_path = "/system/python3",
+        python_version = "PY3",
+    )
+
+    py_runtime_pair(
+        name = "my_py_runtime_pair",
+        py3_runtime = ":my_py3_runtime",
+    )
+
+    toolchain(
+        name = "my_toolchain",
+        target_compatible_with = <...>,
+        toolchain = ":my_py_runtime_pair",
+        toolchain_type = "@rules_python//python:toolchain_type",
+    )
+    ```
+
+    ```python
+    # In your WORKSPACE...
+
+    register_toolchains("//my_pkg:my_toolchain")
+    ```
+
+    Args:
+        name: str, the name of the target
+        py2_runtime: optional Label; must be unset or None; an error is raised
+            otherwise.
+        py3_runtime: Label; a target with `PyRuntimeInfo` for Python 3.
+        **attrs: Extra attrs passed onto the native rule
+    """
+    if attrs.get("py2_runtime"):
+        fail("PYthon 2 is no longer supported: see https://github.com/bazelbuild/rules_python/issues/886")
+    _py_runtime_pair(
+        name = name,
+        py2_runtime = py2_runtime,
+        py3_runtime = py3_runtime,
+        **attrs
+    )