Fix tests under Bazel 0.5.3+

Bazel now ignores the default_python_version and srcs_version
attributes, so we wrap bazel test invocations inside a wrapper script
that runs all tests under Python 2, and then runs all tests under
Python 3.
diff --git a/compiler/BUILD b/compiler/BUILD
index f7fca88..321b692 100644
--- a/compiler/BUILD
+++ b/compiler/BUILD
@@ -46,10 +46,9 @@
 )
 
 [py_test(
-    name = "%s_%s_test" % (src_name, version),
+    name = "%s_test" % (src_name,),
     size = "small",
     srcs = [src_name + "_test.py"],
-    default_python_version = version,
     main = src_name + "_test.py",
     srcs_version = "PY2AND3",
     deps = [
@@ -61,7 +60,4 @@
     "manifest_parser",
     "python_archive",
     "stored_resource",
-] for version in [
-    "PY2",
-    "PY3",
 ]]
diff --git a/run_tests.sh b/run_tests.sh
new file mode 100755
index 0000000..32698d0
--- /dev/null
+++ b/run_tests.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+# Copyright 2016 Google Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -euo pipefail
+
+PYTHON2=$(which python)
+if [ -z "${PYTHON2}" ]; then
+  PYTHON2=$(which python2)
+fi
+PYTHON3=$(which python3)
+
+# Make sure 'python' is actually Python 2.  Some distributions
+# incorrectly have 'python' as Python 3.
+#
+# See PEP 394: The "python" Command on Unix-Like Systems
+#   https://www.python.org/dev/peps/pep-0394/
+if [ -n "${PYTHON2}" ]; then
+  VERSION=$("${PYTHON2}" -V 2>&1)
+  if ! expr match "${VERSION}" "Python 2." >/dev/null ; then
+    PYTHON2=
+  fi
+fi
+
+# Must have at least one Python interpreter to test
+if [ -z "${PYTHON2}" -a -z "${PYTHON3}" ]; then
+  echo "ERROR: Could not find Python 2 or 3 interpreter on $PATH" 1>&2
+  exit 1
+fi
+
+# Run tests
+if [ -n "${PYTHON2}" ]; then
+  echo "Found Python 2 at ${PYTHON2}"
+  bazel test --define subpar_test_python_version=2 --python_path="${PYTHON2}" --test_output=errors //...
+fi
+
+if [ -n "${PYTHON3}" ]; then
+  echo "Found Python 3 at ${PYTHON3}"
+  bazel test --define subpar_test_python_version=3 --python_path="${PYTHON3}" --test_output=errors //...
+fi
diff --git a/runtime/BUILD b/runtime/BUILD
index 806c613..5f8edff 100644
--- a/runtime/BUILD
+++ b/runtime/BUILD
@@ -11,22 +11,9 @@
 )
 
 py_test(
-    name = "support_PY2_test",
+    name = "support_test",
     size = "small",
     srcs = ["support_test.py"],
-    default_python_version = "PY2",
-    main = "support_test.py",
-    srcs_version = "PY2AND3",
-    deps = [
-        ":support",
-    ],
-)
-
-py_test(
-    name = "support_PY3_test",
-    size = "small",
-    srcs = ["support_test.py"],
-    default_python_version = "PY3",
     main = "support_test.py",
     srcs_version = "PY2AND3",
     deps = [
diff --git a/tests/BUILD b/tests/BUILD
index be3a91a..37cc71b 100644
--- a/tests/BUILD
+++ b/tests/BUILD
@@ -12,6 +12,21 @@
 
 load("//:subpar.bzl", "par_binary")
 
+# Configurations
+config_setting(
+    name = "subpar_test_python_version_2",
+    define_values = {
+        "subpar_test_python_version": "2",
+    },
+)
+
+config_setting(
+    name = "subpar_test_python_version_3",
+    define_values = {
+        "subpar_test_python_version": "3",
+    },
+)
+
 # Utility targets
 sh_library(
     name = "test_harness",
@@ -19,22 +34,17 @@
 )
 
 # Targets used by tests below
-[par_binary(
-    name = "package_c/c_%s" % version,
+par_binary(
+    name = "package_c/c",
     srcs = ["package_c/c.py"],
-    default_python_version = version,
     main = "package_c/c.py",
     srcs_version = "PY2AND3",
-    deps = ["//tests/package_b:b_%s" % version],
-) for version in [
-    "PY2",
-    "PY3",
-]]
+    deps = ["//tests/package_b:b"],
+)
 
-[par_binary(
-    name = "package_d/d_%s" % version,
+par_binary(
+    name = "package_d/d",
     srcs = ["package_d/d.py"],
-    default_python_version = version,
     imports = [
         "package_b",
         "package_c",
@@ -42,112 +52,97 @@
     main = "package_d/d.py",
     srcs_version = "PY2AND3",
     deps = [
-        "//tests:package_c/c_%s" % version,
-        "//tests/package_b:b_%s" % version,
+        "//tests:package_c/c",
+        "//tests/package_b:b",
     ],
-) for version in [
-    "PY2",
-    "PY3",
-]]
+)
 
-[par_binary(
-    name = "package_e/e_%s" % version,
+par_binary(
+    name = "package_e/e",
     srcs = ["package_e/e.py"],
     data = [
         "@test_workspace//:data_file.txt",
     ],
-    default_python_version = version,
     main = "package_e/e.py",
     srcs_version = "PY2AND3",
     deps = [
         "@test_workspace//:package_external_lib/external_lib",
     ],
-) for version in [
-    "PY2",
-    "PY3",
-]]
-
-par_binary(
-    name = "package_f/f_PY2",
-    srcs = ["package_f/f_PY2.py"],
 )
 
 par_binary(
-    name = "package_f/f_PY3",
-    srcs = ["package_f/f_PY3.py"],
-    default_python_version = "PY3",
-    srcs_version = "PY2AND3",
+    name = "package_f/f",
+    srcs = select({
+        "subpar_test_python_version_3": ["package_f/f_PY3.py"],
+        "//conditions:default": ["package_f/f_PY2.py"],
+    }),
+    main = select({
+        "subpar_test_python_version_3": "package_f/f_PY3.py",
+        "//conditions:default": "package_f/f_PY2.py",
+    }),
 )
 
-[par_binary(
-    name = "package_g/g_%s" % version,
+par_binary(
+    name = "package_g/g",
     srcs = ["package_g/g.py"],
-    default_python_version = version,
     main = "package_g/g.py",
     srcs_version = "PY2AND3",
-) for version in [
-    "PY2",
-    "PY3",
-]]
+)
 
-[par_binary(
-    name = "package_shadow/main_%s" % version,
+par_binary(
+    name = "package_shadow/main",
     srcs = [
         "package_shadow/code/__init__.py",
         "package_shadow/code/shadowed.py",
         "package_shadow/main.py",
     ],
-    default_python_version = version,
     imports = ["package_shadow"],
     main = "package_shadow/main.py",
     srcs_version = "PY2AND3",
-) for version in [
-    "PY2",
-    "PY3",
-]]
+)
 
-[par_binary(
-    name = "package_import_roots/import_roots_%s" % version,
+par_binary(
+    name = "package_import_roots/import_roots",
     srcs = [
         "package_import_roots/import_roots.py",
     ],
-    default_python_version = version,
     imports = ["package_import_roots"],
     main = "package_import_roots/import_roots.py",
     srcs_version = "PY2AND3",
-) for version in [
-    "PY2",
-    "PY3",
-]]
+)
 
 # Test targets
 [(
     # Run test without .par file as a control
     sh_test(
-        name = "%s_%s_nopar_test" % (name, version),
+        name = "%s_nopar_test" % name,
         size = "small",
         srcs = ["test_harness.sh"],
         args = [
-            "tests%s_%s" % (path, version),
+            "tests%s" % path,
         ],
         data = [
-            "//tests%s_%s" % (label, version),
+            "//tests%s" % label,
         ],
     ),
     # Test .par file with harness
     sh_test(
-        name = "%s_%s_test" % (name, version),
+        name = "%s_test" % name,
         size = "small",
         srcs = ["test_harness.sh"],
         args = [
             "--par",
-            "tests%s_%s.par" % (path, version),
-            "tests%s_%s_filelist.txt" % (path, version),
-        ],
+            "tests%s.par" % path,
+        ] + select({
+            "subpar_test_python_version_3": ["tests%s_PY3_filelist.txt" % path],
+            "//conditions:default": ["tests%s_PY2_filelist.txt" % path],
+        }),
         data = [
-            "//tests%s_%s.par" % (label, version),
-            "//tests%s_%s_filelist.txt" % (label, version),
-        ],
+            "//tests%s.par" % label,
+        ] + select({
+            "subpar_test_python_version_3": ["//tests%s_PY3_filelist.txt" % label],
+            "//conditions:default": ["//tests%s_PY2_filelist.txt" % label],
+        }),
     ),
 ) for name, label, path in [
     ("basic", "/package_a:a", "/package_a/a"),
@@ -159,7 +154,4 @@
     ("main_boilerplate", ":package_g/g", "/package_g/g"),
     ("shadow", ":package_shadow/main", "/package_shadow/main"),
     ("import_roots", ":package_import_roots/import_roots", "/package_import_roots/import_roots"),
-] for version in [
-    "PY2",
-    "PY3",
 ]]
diff --git a/tests/package_a/BUILD b/tests/package_a/BUILD
index da526ba..cf077f4 100644
--- a/tests/package_a/BUILD
+++ b/tests/package_a/BUILD
@@ -9,8 +9,8 @@
     "a_PY3_filelist.txt",
 ])
 
-[par_binary(
-    name = "a_%s" % version,
+par_binary(
+    name = "a",
     srcs = [
         "a.py",
         "//:__init__.py",
@@ -18,13 +18,9 @@
         "//tests/package_a:__init__.py",
     ],
     data = ["a_dat.txt"],
-    default_python_version = version,
     main = "a.py",
     srcs_version = "PY2AND3",
-) for version in [
-    "PY2",
-    "PY3",
-]]
+)
 
 py_library(
     name = "a_lib",
diff --git a/tests/package_a/a_PY2_filelist.txt b/tests/package_a/a_PY2_filelist.txt
index 1976cd0..bdbf7a5 100644
--- a/tests/package_a/a_PY2_filelist.txt
+++ b/tests/package_a/a_PY2_filelist.txt
@@ -4,6 +4,6 @@
 subpar/runtime/support.py
 subpar/tests/__init__.py
 subpar/tests/package_a/__init__.py
+subpar/tests/package_a/a
 subpar/tests/package_a/a.py
-subpar/tests/package_a/a_PY2
 subpar/tests/package_a/a_dat.txt
diff --git a/tests/package_a/a_PY3_filelist.txt b/tests/package_a/a_PY3_filelist.txt
index 606238e..bdbf7a5 100644
--- a/tests/package_a/a_PY3_filelist.txt
+++ b/tests/package_a/a_PY3_filelist.txt
@@ -4,6 +4,6 @@
 subpar/runtime/support.py
 subpar/tests/__init__.py
 subpar/tests/package_a/__init__.py
+subpar/tests/package_a/a
 subpar/tests/package_a/a.py
-subpar/tests/package_a/a_PY3
 subpar/tests/package_a/a_dat.txt
diff --git a/tests/package_b/BUILD b/tests/package_b/BUILD
index ffe5433..af0d9da 100644
--- a/tests/package_b/BUILD
+++ b/tests/package_b/BUILD
@@ -9,8 +9,8 @@
     "b_PY3_filelist.txt",
 ])
 
-[par_binary(
-    name = "b_%s" % version,
+par_binary(
+    name = "b",
     srcs = [
         "b.py",
         "//:__init__.py",
@@ -18,14 +18,10 @@
         "//tests/package_b:__init__.py",
     ],
     data = ["b_dat.txt"],
-    default_python_version = version,
     main = "b.py",
     srcs_version = "PY2AND3",
     deps = [
-        "//tests/package_a:a_%s" % version,
+        "//tests/package_a:a",
         "//tests/package_a:a_lib",
     ],
-) for version in [
-    "PY2",
-    "PY3",
-]]
+)
diff --git a/tests/package_b/b_PY2_filelist.txt b/tests/package_b/b_PY2_filelist.txt
index f6b0955..9177503 100644
--- a/tests/package_b/b_PY2_filelist.txt
+++ b/tests/package_b/b_PY2_filelist.txt
@@ -4,12 +4,12 @@
 subpar/runtime/support.py
 subpar/tests/__init__.py
 subpar/tests/package_a/__init__.py
+subpar/tests/package_a/a
 subpar/tests/package_a/a.py
-subpar/tests/package_a/a_PY2
 subpar/tests/package_a/a_dat.txt
 subpar/tests/package_a/a_lib.py
 subpar/tests/package_a/a_lib_dat.txt
 subpar/tests/package_b/__init__.py
+subpar/tests/package_b/b
 subpar/tests/package_b/b.py
-subpar/tests/package_b/b_PY2
 subpar/tests/package_b/b_dat.txt
diff --git a/tests/package_b/b_PY3_filelist.txt b/tests/package_b/b_PY3_filelist.txt
index 7ace434..9177503 100644
--- a/tests/package_b/b_PY3_filelist.txt
+++ b/tests/package_b/b_PY3_filelist.txt
@@ -4,12 +4,12 @@
 subpar/runtime/support.py
 subpar/tests/__init__.py
 subpar/tests/package_a/__init__.py
+subpar/tests/package_a/a
 subpar/tests/package_a/a.py
-subpar/tests/package_a/a_PY3
 subpar/tests/package_a/a_dat.txt
 subpar/tests/package_a/a_lib.py
 subpar/tests/package_a/a_lib_dat.txt
 subpar/tests/package_b/__init__.py
+subpar/tests/package_b/b
 subpar/tests/package_b/b.py
-subpar/tests/package_b/b_PY3
 subpar/tests/package_b/b_dat.txt
diff --git a/tests/package_c/c_PY2_filelist.txt b/tests/package_c/c_PY2_filelist.txt
index 5506e91..361772f 100644
--- a/tests/package_c/c_PY2_filelist.txt
+++ b/tests/package_c/c_PY2_filelist.txt
@@ -4,15 +4,15 @@
 subpar/runtime/support.py
 subpar/tests/__init__.py
 subpar/tests/package_a/__init__.py
+subpar/tests/package_a/a
 subpar/tests/package_a/a.py
-subpar/tests/package_a/a_PY2
 subpar/tests/package_a/a_dat.txt
 subpar/tests/package_a/a_lib.py
 subpar/tests/package_a/a_lib_dat.txt
 subpar/tests/package_b/__init__.py
+subpar/tests/package_b/b
 subpar/tests/package_b/b.py
-subpar/tests/package_b/b_PY2
 subpar/tests/package_b/b_dat.txt
 subpar/tests/package_c/__init__.py
+subpar/tests/package_c/c
 subpar/tests/package_c/c.py
-subpar/tests/package_c/c_PY2
diff --git a/tests/package_c/c_PY3_filelist.txt b/tests/package_c/c_PY3_filelist.txt
index 507636e..361772f 100644
--- a/tests/package_c/c_PY3_filelist.txt
+++ b/tests/package_c/c_PY3_filelist.txt
@@ -4,15 +4,15 @@
 subpar/runtime/support.py
 subpar/tests/__init__.py
 subpar/tests/package_a/__init__.py
+subpar/tests/package_a/a
 subpar/tests/package_a/a.py
-subpar/tests/package_a/a_PY3
 subpar/tests/package_a/a_dat.txt
 subpar/tests/package_a/a_lib.py
 subpar/tests/package_a/a_lib_dat.txt
 subpar/tests/package_b/__init__.py
+subpar/tests/package_b/b
 subpar/tests/package_b/b.py
-subpar/tests/package_b/b_PY3
 subpar/tests/package_b/b_dat.txt
 subpar/tests/package_c/__init__.py
+subpar/tests/package_c/c
 subpar/tests/package_c/c.py
-subpar/tests/package_c/c_PY3
diff --git a/tests/package_d/d_PY2_filelist.txt b/tests/package_d/d_PY2_filelist.txt
index f38f57c..5e460e0 100644
--- a/tests/package_d/d_PY2_filelist.txt
+++ b/tests/package_d/d_PY2_filelist.txt
@@ -4,18 +4,18 @@
 subpar/runtime/support.py
 subpar/tests/__init__.py
 subpar/tests/package_a/__init__.py
+subpar/tests/package_a/a
 subpar/tests/package_a/a.py
-subpar/tests/package_a/a_PY2
 subpar/tests/package_a/a_dat.txt
 subpar/tests/package_a/a_lib.py
 subpar/tests/package_a/a_lib_dat.txt
 subpar/tests/package_b/__init__.py
+subpar/tests/package_b/b
 subpar/tests/package_b/b.py
-subpar/tests/package_b/b_PY2
 subpar/tests/package_b/b_dat.txt
 subpar/tests/package_c/__init__.py
+subpar/tests/package_c/c
 subpar/tests/package_c/c.py
-subpar/tests/package_c/c_PY2
 subpar/tests/package_d/__init__.py
+subpar/tests/package_d/d
 subpar/tests/package_d/d.py
-subpar/tests/package_d/d_PY2
diff --git a/tests/package_d/d_PY3_filelist.txt b/tests/package_d/d_PY3_filelist.txt
index b29dfff..5e460e0 100644
--- a/tests/package_d/d_PY3_filelist.txt
+++ b/tests/package_d/d_PY3_filelist.txt
@@ -4,18 +4,18 @@
 subpar/runtime/support.py
 subpar/tests/__init__.py
 subpar/tests/package_a/__init__.py
+subpar/tests/package_a/a
 subpar/tests/package_a/a.py
-subpar/tests/package_a/a_PY3
 subpar/tests/package_a/a_dat.txt
 subpar/tests/package_a/a_lib.py
 subpar/tests/package_a/a_lib_dat.txt
 subpar/tests/package_b/__init__.py
+subpar/tests/package_b/b
 subpar/tests/package_b/b.py
-subpar/tests/package_b/b_PY3
 subpar/tests/package_b/b_dat.txt
 subpar/tests/package_c/__init__.py
+subpar/tests/package_c/c
 subpar/tests/package_c/c.py
-subpar/tests/package_c/c_PY3
 subpar/tests/package_d/__init__.py
+subpar/tests/package_d/d
 subpar/tests/package_d/d.py
-subpar/tests/package_d/d_PY3
diff --git a/tests/package_e/e_PY2_filelist.txt b/tests/package_e/e_PY2_filelist.txt
index 9863899..efe9b18 100644
--- a/tests/package_e/e_PY2_filelist.txt
+++ b/tests/package_e/e_PY2_filelist.txt
@@ -5,8 +5,8 @@
 subpar/runtime/support.py
 subpar/tests/__init__.py
 subpar/tests/package_e/__init__.py
+subpar/tests/package_e/e
 subpar/tests/package_e/e.py
-subpar/tests/package_e/e_PY2
 test_workspace/__init__.py
 test_workspace/data_file.txt
 test_workspace/package_external_lib/__init__.py
diff --git a/tests/package_e/e_PY3_filelist.txt b/tests/package_e/e_PY3_filelist.txt
index e8920a1..efe9b18 100644
--- a/tests/package_e/e_PY3_filelist.txt
+++ b/tests/package_e/e_PY3_filelist.txt
@@ -5,8 +5,8 @@
 subpar/runtime/support.py
 subpar/tests/__init__.py
 subpar/tests/package_e/__init__.py
+subpar/tests/package_e/e
 subpar/tests/package_e/e.py
-subpar/tests/package_e/e_PY3
 test_workspace/__init__.py
 test_workspace/data_file.txt
 test_workspace/package_external_lib/__init__.py
diff --git a/tests/package_f/f_PY2_filelist.txt b/tests/package_f/f_PY2_filelist.txt
index 8b382cb..0d61e87 100644
--- a/tests/package_f/f_PY2_filelist.txt
+++ b/tests/package_f/f_PY2_filelist.txt
@@ -4,5 +4,5 @@
 subpar/runtime/support.py
 subpar/tests/__init__.py
 subpar/tests/package_f/__init__.py
-subpar/tests/package_f/f_PY2
+subpar/tests/package_f/f
 subpar/tests/package_f/f_PY2.py
diff --git a/tests/package_f/f_PY3_filelist.txt b/tests/package_f/f_PY3_filelist.txt
index b9ba660..428bc93 100644
--- a/tests/package_f/f_PY3_filelist.txt
+++ b/tests/package_f/f_PY3_filelist.txt
@@ -4,5 +4,5 @@
 subpar/runtime/support.py
 subpar/tests/__init__.py
 subpar/tests/package_f/__init__.py
-subpar/tests/package_f/f_PY3
+subpar/tests/package_f/f
 subpar/tests/package_f/f_PY3.py
diff --git a/tests/package_g/g_PY2_filelist.txt b/tests/package_g/g_PY2_filelist.txt
index d495021..b58fe85 100644
--- a/tests/package_g/g_PY2_filelist.txt
+++ b/tests/package_g/g_PY2_filelist.txt
@@ -4,5 +4,5 @@
 subpar/runtime/support.py
 subpar/tests/__init__.py
 subpar/tests/package_g/__init__.py
+subpar/tests/package_g/g
 subpar/tests/package_g/g.py
-subpar/tests/package_g/g_PY2
diff --git a/tests/package_g/g_PY3_filelist.txt b/tests/package_g/g_PY3_filelist.txt
index 028bf66..b58fe85 100644
--- a/tests/package_g/g_PY3_filelist.txt
+++ b/tests/package_g/g_PY3_filelist.txt
@@ -4,5 +4,5 @@
 subpar/runtime/support.py
 subpar/tests/__init__.py
 subpar/tests/package_g/__init__.py
+subpar/tests/package_g/g
 subpar/tests/package_g/g.py
-subpar/tests/package_g/g_PY3
diff --git a/tests/package_import_roots/import_roots_PY2_filelist.txt b/tests/package_import_roots/import_roots_PY2_filelist.txt
index 5b16980..3f1da51 100644
--- a/tests/package_import_roots/import_roots_PY2_filelist.txt
+++ b/tests/package_import_roots/import_roots_PY2_filelist.txt
@@ -4,5 +4,5 @@
 subpar/runtime/support.py
 subpar/tests/__init__.py
 subpar/tests/package_import_roots/__init__.py
+subpar/tests/package_import_roots/import_roots
 subpar/tests/package_import_roots/import_roots.py
-subpar/tests/package_import_roots/import_roots_PY2
diff --git a/tests/package_import_roots/import_roots_PY3_filelist.txt b/tests/package_import_roots/import_roots_PY3_filelist.txt
index 11a4fe7..3f1da51 100644
--- a/tests/package_import_roots/import_roots_PY3_filelist.txt
+++ b/tests/package_import_roots/import_roots_PY3_filelist.txt
@@ -4,5 +4,5 @@
 subpar/runtime/support.py
 subpar/tests/__init__.py
 subpar/tests/package_import_roots/__init__.py
+subpar/tests/package_import_roots/import_roots
 subpar/tests/package_import_roots/import_roots.py
-subpar/tests/package_import_roots/import_roots_PY3
diff --git a/tests/package_shadow/main_PY2_filelist.txt b/tests/package_shadow/main_PY2_filelist.txt
index 20331f8..1f622f1 100644
--- a/tests/package_shadow/main_PY2_filelist.txt
+++ b/tests/package_shadow/main_PY2_filelist.txt
@@ -6,5 +6,5 @@
 subpar/tests/package_shadow/__init__.py
 subpar/tests/package_shadow/code/__init__.py
 subpar/tests/package_shadow/code/shadowed.py
+subpar/tests/package_shadow/main
 subpar/tests/package_shadow/main.py
-subpar/tests/package_shadow/main_PY2
diff --git a/tests/package_shadow/main_PY3_filelist.txt b/tests/package_shadow/main_PY3_filelist.txt
index f1c6b97..1f622f1 100644
--- a/tests/package_shadow/main_PY3_filelist.txt
+++ b/tests/package_shadow/main_PY3_filelist.txt
@@ -6,5 +6,5 @@
 subpar/tests/package_shadow/__init__.py
 subpar/tests/package_shadow/code/__init__.py
 subpar/tests/package_shadow/code/shadowed.py
+subpar/tests/package_shadow/main
 subpar/tests/package_shadow/main.py
-subpar/tests/package_shadow/main_PY3