recipe: use python3 only

This follows http://go/luci/migrations/recipe_py3

Bug: chromium:1393261
Change-Id: Ia8dfe6931c7ac93deab4772462338b599d22c2d2
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/14900
Commit-Queue: Takuto Ikuta <tikuta@google.com>
Reviewed-by: Petr Hosek <phosek@google.com>
diff --git a/infra/README.recipes.md b/infra/README.recipes.md
index 731d098..0196775 100644
--- a/infra/README.recipes.md
+++ b/infra/README.recipes.md
@@ -16,7 +16,7 @@
 
 ### *recipe_modules* / [macos\_sdk](/infra/recipe_modules/macos_sdk)
 
-[DEPS](/infra/recipe_modules/macos_sdk/__init__.py#7): [recipe\_engine/cipd][recipe_engine/recipe_modules/cipd], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/step][recipe_engine/recipe_modules/step]
+[DEPS](/infra/recipe_modules/macos_sdk/__init__.py#5): [recipe\_engine/cipd][recipe_engine/recipe_modules/cipd], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/step][recipe_engine/recipe_modules/step]
 
 PYTHON_VERSION_COMPATIBILITY: PY3
 
@@ -66,7 +66,7 @@
 &emsp; **@property**<br>&mdash; **def [sdk\_dir](/infra/recipe_modules/macos_sdk/api.py#25)(self):**
 ### *recipe_modules* / [target](/infra/recipe_modules/target)
 
-[DEPS](/infra/recipe_modules/target/__init__.py#7): [recipe\_engine/platform][recipe_engine/recipe_modules/platform]
+[DEPS](/infra/recipe_modules/target/__init__.py#5): [recipe\_engine/platform][recipe_engine/recipe_modules/platform]
 
 PYTHON_VERSION_COMPATIBILITY: PY3
 
@@ -75,7 +75,7 @@
 &emsp; **@property**<br>&mdash; **def [host](/infra/recipe_modules/target/api.py#87)(self):**
 ### *recipe_modules* / [windows\_sdk](/infra/recipe_modules/windows_sdk)
 
-[DEPS](/infra/recipe_modules/windows_sdk/__init__.py#7): [recipe\_engine/cipd][recipe_engine/recipe_modules/cipd], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/step][recipe_engine/recipe_modules/step]
+[DEPS](/infra/recipe_modules/windows_sdk/__init__.py#5): [recipe\_engine/cipd][recipe_engine/recipe_modules/cipd], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/step][recipe_engine/recipe_modules/step]
 
 PYTHON_VERSION_COMPATIBILITY: PY3
 
@@ -95,45 +95,44 @@
 
 ### *recipes* / [gn](/infra/recipes/gn.py)
 
-[DEPS](/infra/recipes/gn.py#10): [macos\_sdk](#recipe_modules-macos_sdk), [target](#recipe_modules-target), [windows\_sdk](#recipe_modules-windows_sdk), [recipe\_engine/buildbucket][recipe_engine/recipe_modules/buildbucket], [recipe\_engine/cas][recipe_engine/recipe_modules/cas], [recipe\_engine/cipd][recipe_engine/recipe_modules/cipd], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step]
+[DEPS](/infra/recipes/gn.py#8): [macos\_sdk](#recipe_modules-macos_sdk), [target](#recipe_modules-target), [windows\_sdk](#recipe_modules-windows_sdk), [recipe\_engine/buildbucket][recipe_engine/recipe_modules/buildbucket], [recipe\_engine/cas][recipe_engine/recipe_modules/cas], [recipe\_engine/cipd][recipe_engine/recipe_modules/cipd], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step]
 
 PYTHON_VERSION_COMPATIBILITY: PY3
 
 Recipe for building GN.
 
-&mdash; **def [RunSteps](/infra/recipes/gn.py#106)(api, repository):**
+&mdash; **def [RunSteps](/infra/recipes/gn.py#103)(api, repository):**
 ### *recipes* / [macos\_sdk:examples/full](/infra/recipe_modules/macos_sdk/examples/full.py)
 
-[DEPS](/infra/recipe_modules/macos_sdk/examples/full.py#7): [macos\_sdk](#recipe_modules-macos_sdk), [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step]
+[DEPS](/infra/recipe_modules/macos_sdk/examples/full.py#5): [macos\_sdk](#recipe_modules-macos_sdk), [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step]
 
 PYTHON_VERSION_COMPATIBILITY: PY3
 
-&mdash; **def [RunSteps](/infra/recipe_modules/macos_sdk/examples/full.py#15)(api):**
+&mdash; **def [RunSteps](/infra/recipe_modules/macos_sdk/examples/full.py#13)(api):**
 ### *recipes* / [target:examples/full](/infra/recipe_modules/target/examples/full.py)
 
-[DEPS](/infra/recipe_modules/target/examples/full.py#7): [target](#recipe_modules-target), [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step]
+[DEPS](/infra/recipe_modules/target/examples/full.py#5): [target](#recipe_modules-target), [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step]
 
 PYTHON_VERSION_COMPATIBILITY: PY3
 
-&mdash; **def [RunSteps](/infra/recipe_modules/target/examples/full.py#15)(api):**
+&mdash; **def [RunSteps](/infra/recipe_modules/target/examples/full.py#13)(api):**
 ### *recipes* / [windows\_sdk:examples/full](/infra/recipe_modules/windows_sdk/examples/full.py)
 
-[DEPS](/infra/recipe_modules/windows_sdk/examples/full.py#7): [windows\_sdk](#recipe_modules-windows_sdk), [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step]
+[DEPS](/infra/recipe_modules/windows_sdk/examples/full.py#5): [windows\_sdk](#recipe_modules-windows_sdk), [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step]
 
 PYTHON_VERSION_COMPATIBILITY: PY3
 
-&mdash; **def [RunSteps](/infra/recipe_modules/windows_sdk/examples/full.py#15)(api):**
+&mdash; **def [RunSteps](/infra/recipe_modules/windows_sdk/examples/full.py#13)(api):**
 
-[recipe_engine/recipe_modules/buildbucket]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/1b1ecd03e0b00399784c43add1465f685b6d1ab9/README.recipes.md#recipe_modules-buildbucket
-[recipe_engine/recipe_modules/cas]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/1b1ecd03e0b00399784c43add1465f685b6d1ab9/README.recipes.md#recipe_modules-cas
-[recipe_engine/recipe_modules/cipd]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/1b1ecd03e0b00399784c43add1465f685b6d1ab9/README.recipes.md#recipe_modules-cipd
-[recipe_engine/recipe_modules/context]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/1b1ecd03e0b00399784c43add1465f685b6d1ab9/README.recipes.md#recipe_modules-context
-[recipe_engine/recipe_modules/file]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/1b1ecd03e0b00399784c43add1465f685b6d1ab9/README.recipes.md#recipe_modules-file
-[recipe_engine/recipe_modules/json]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/1b1ecd03e0b00399784c43add1465f685b6d1ab9/README.recipes.md#recipe_modules-json
-[recipe_engine/recipe_modules/path]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/1b1ecd03e0b00399784c43add1465f685b6d1ab9/README.recipes.md#recipe_modules-path
-[recipe_engine/recipe_modules/platform]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/1b1ecd03e0b00399784c43add1465f685b6d1ab9/README.recipes.md#recipe_modules-platform
-[recipe_engine/recipe_modules/properties]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/1b1ecd03e0b00399784c43add1465f685b6d1ab9/README.recipes.md#recipe_modules-properties
-[recipe_engine/recipe_modules/python]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/1b1ecd03e0b00399784c43add1465f685b6d1ab9/README.recipes.md#recipe_modules-python
-[recipe_engine/recipe_modules/raw_io]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/1b1ecd03e0b00399784c43add1465f685b6d1ab9/README.recipes.md#recipe_modules-raw_io
-[recipe_engine/recipe_modules/step]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/1b1ecd03e0b00399784c43add1465f685b6d1ab9/README.recipes.md#recipe_modules-step
-[recipe_engine/wkt/RecipeApi]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/1b1ecd03e0b00399784c43add1465f685b6d1ab9/recipe_engine/recipe_api.py#883
+[recipe_engine/recipe_modules/buildbucket]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/ff5ce51ceaaa7a62275bb766831a3ce1e88de37d/README.recipes.md#recipe_modules-buildbucket
+[recipe_engine/recipe_modules/cas]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/ff5ce51ceaaa7a62275bb766831a3ce1e88de37d/README.recipes.md#recipe_modules-cas
+[recipe_engine/recipe_modules/cipd]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/ff5ce51ceaaa7a62275bb766831a3ce1e88de37d/README.recipes.md#recipe_modules-cipd
+[recipe_engine/recipe_modules/context]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/ff5ce51ceaaa7a62275bb766831a3ce1e88de37d/README.recipes.md#recipe_modules-context
+[recipe_engine/recipe_modules/file]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/ff5ce51ceaaa7a62275bb766831a3ce1e88de37d/README.recipes.md#recipe_modules-file
+[recipe_engine/recipe_modules/json]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/ff5ce51ceaaa7a62275bb766831a3ce1e88de37d/README.recipes.md#recipe_modules-json
+[recipe_engine/recipe_modules/path]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/ff5ce51ceaaa7a62275bb766831a3ce1e88de37d/README.recipes.md#recipe_modules-path
+[recipe_engine/recipe_modules/platform]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/ff5ce51ceaaa7a62275bb766831a3ce1e88de37d/README.recipes.md#recipe_modules-platform
+[recipe_engine/recipe_modules/properties]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/ff5ce51ceaaa7a62275bb766831a3ce1e88de37d/README.recipes.md#recipe_modules-properties
+[recipe_engine/recipe_modules/raw_io]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/ff5ce51ceaaa7a62275bb766831a3ce1e88de37d/README.recipes.md#recipe_modules-raw_io
+[recipe_engine/recipe_modules/step]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/ff5ce51ceaaa7a62275bb766831a3ce1e88de37d/README.recipes.md#recipe_modules-step
+[recipe_engine/wkt/RecipeApi]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/ff5ce51ceaaa7a62275bb766831a3ce1e88de37d/recipe_engine/recipe_api.py#886
diff --git a/infra/config/recipes.cfg b/infra/config/recipes.cfg
index 39bf9ac..da25624 100644
--- a/infra/config/recipes.cfg
+++ b/infra/config/recipes.cfg
@@ -3,10 +3,11 @@
   "deps": {
     "recipe_engine": {
       "branch": "refs/heads/main",
-      "revision": "e662254992ccd69a1089660b5de6048fe1811550",
+      "revision": "ff5ce51ceaaa7a62275bb766831a3ce1e88de37d",
       "url": "https://chromium.googlesource.com/infra/luci/recipes-py"
     }
   },
   "project_id": "gn",
+  "py3_only": true,
   "recipes_path": "infra"
 }
diff --git a/infra/recipe_modules/macos_sdk/__init__.py b/infra/recipe_modules/macos_sdk/__init__.py
index 44a4456..56b6a94 100644
--- a/infra/recipe_modules/macos_sdk/__init__.py
+++ b/infra/recipe_modules/macos_sdk/__init__.py
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-PYTHON_VERSION_COMPATIBILITY = 'PY3'
-
 DEPS = [
     'recipe_engine/cipd',
     'recipe_engine/context',
diff --git a/infra/recipe_modules/macos_sdk/examples/full.py b/infra/recipe_modules/macos_sdk/examples/full.py
index 29014fc..a3348ab 100644
--- a/infra/recipe_modules/macos_sdk/examples/full.py
+++ b/infra/recipe_modules/macos_sdk/examples/full.py
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-PYTHON_VERSION_COMPATIBILITY = 'PY3'
-
 DEPS = [
     'macos_sdk',
     'recipe_engine/platform',
diff --git a/infra/recipe_modules/target/__init__.py b/infra/recipe_modules/target/__init__.py
index e85b812..1239fd2 100644
--- a/infra/recipe_modules/target/__init__.py
+++ b/infra/recipe_modules/target/__init__.py
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-PYTHON_VERSION_COMPATIBILITY = 'PY3'
-
 DEPS = [
     'recipe_engine/platform',
 ]
diff --git a/infra/recipe_modules/target/examples/full.py b/infra/recipe_modules/target/examples/full.py
index 68af2ec..c47c86a 100644
--- a/infra/recipe_modules/target/examples/full.py
+++ b/infra/recipe_modules/target/examples/full.py
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-PYTHON_VERSION_COMPATIBILITY = 'PY3'
-
 DEPS = [
     'target',
     'recipe_engine/platform',
diff --git a/infra/recipe_modules/windows_sdk/__init__.py b/infra/recipe_modules/windows_sdk/__init__.py
index 031697b..83323a8 100644
--- a/infra/recipe_modules/windows_sdk/__init__.py
+++ b/infra/recipe_modules/windows_sdk/__init__.py
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-PYTHON_VERSION_COMPATIBILITY = 'PY3'
-
 DEPS = [
     'recipe_engine/cipd',
     'recipe_engine/context',
diff --git a/infra/recipe_modules/windows_sdk/examples/full.expected/win.json b/infra/recipe_modules/windows_sdk/examples/full.expected/win.json
index f6c937f..f45cd83 100644
--- a/infra/recipe_modules/windows_sdk/examples/full.expected/win.json
+++ b/infra/recipe_modules/windows_sdk/examples/full.expected/win.json
@@ -30,9 +30,9 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
-      "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
+      "RECIPE_MODULE[recipe_engine::json]\\resources\\read.py",
       "[CACHE]\\windows_sdk\\win_sdk\\bin\\SetEnv.x64.json",
       "/path/to/tmp/json"
     ],
diff --git a/infra/recipe_modules/windows_sdk/examples/full.py b/infra/recipe_modules/windows_sdk/examples/full.py
index 687f2e7..902c491 100644
--- a/infra/recipe_modules/windows_sdk/examples/full.py
+++ b/infra/recipe_modules/windows_sdk/examples/full.py
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-PYTHON_VERSION_COMPATIBILITY = 'PY3'
-
 DEPS = [
     'windows_sdk',
     'recipe_engine/platform',
diff --git a/infra/recipes.py b/infra/recipes.py
index 81b0bc6..7c534c2 100755
--- a/infra/recipes.py
+++ b/infra/recipes.py
@@ -70,9 +70,12 @@
     recipes_path (str) - native path to where the recipes live inside of the
       current repo (i.e. the folder containing `recipes/` and/or
       `recipe_modules`)
+    py3_only (bool) - True if this repo has been marked as ONLY supporting
+      python3.
   """
   with open(recipes_cfg_path, 'r') as fh:
     pb = json.load(fh)
+  py3_only = pb.get('py3_only', False)
 
   try:
     if pb['api_version'] != 2:
@@ -85,7 +88,7 @@
     if not repo_name:
       repo_name = pb['project_id']
     if repo_name == 'recipe_engine':
-      return None, pb.get('recipes_path', '')
+      return None, pb.get('recipes_path', ''), py3_only
 
     engine = pb['deps']['recipe_engine']
 
@@ -104,7 +107,7 @@
 
     recipes_path = os.path.join(repo_root,
                                 recipes_path.replace('/', os.path.sep))
-    return EngineDep(**engine), recipes_path
+    return EngineDep(**engine), recipes_path, py3_only
   except KeyError as ex:
     raise MalformedRecipesCfg(str(ex), recipes_cfg_path)
 
@@ -113,11 +116,8 @@
 
 _BAT = '.bat' if IS_WIN else ''
 GIT = 'git' + _BAT
-VPYTHON = ('vpython' +
-           ('3' if os.getenv('RECIPES_USE_PY3') == 'true' else '') +
-           _BAT)
 CIPD = 'cipd' + _BAT
-REQUIRED_BINARIES = {GIT, VPYTHON, CIPD}
+REQUIRED_BINARIES = {GIT, CIPD}
 
 
 def _is_executable(path):
@@ -169,10 +169,14 @@
 
 
 def checkout_engine(engine_path, repo_root, recipes_cfg_path):
-  dep, recipes_path = parse(repo_root, recipes_cfg_path)
+  """Checks out the recipe_engine repo pinned in recipes.cfg.
+
+  Returns the path to the recipe engine repo and the py3_only boolean.
+  """
+  dep, recipes_path, py3_only = parse(repo_root, recipes_cfg_path)
   if dep is None:
     # we're running from the engine repo already!
-    return os.path.join(repo_root, recipes_path)
+    return os.path.join(repo_root, recipes_path), py3_only
 
   url = dep.url
 
@@ -217,7 +221,7 @@
     # or things will get squirrely.
     _git_check_call(['clean', '-qxf'], cwd=engine_path)
 
-  return engine_path
+  return engine_path, py3_only
 
 
 def main():
@@ -243,11 +247,16 @@
     repo_root = os.path.abspath(repo_root).decode()
     recipes_cfg_path = os.path.join(repo_root, 'infra', 'config', 'recipes.cfg')
     args = ['--package', recipes_cfg_path] + args
-  engine_path = checkout_engine(engine_override, repo_root, recipes_cfg_path)
+  engine_path, py3_only = checkout_engine(engine_override, repo_root, recipes_cfg_path)
 
-  argv = (
-      [VPYTHON, '-u',
-       os.path.join(engine_path, 'recipe_engine', 'main.py')] + args)
+  using_py3 = py3_only or os.getenv('RECIPES_USE_PY3') == 'true'
+  vpython = ('vpython' + ('3' if using_py3 else '') + _BAT)
+  if not _is_on_path(vpython):
+    return 'Required binary is not found on PATH: %s' % vpython
+
+  argv = ([
+    vpython, '-u', os.path.join(engine_path, 'recipe_engine', 'main.py'),
+  ] + args)
 
   if IS_WIN:
     # No real 'exec' on windows; set these signals to ignore so that they
diff --git a/infra/recipes/gn.expected/ci_linux.json b/infra/recipes/gn.expected/ci_linux.json
index a7001a6..5c09522 100644
--- a/infra/recipes/gn.expected/ci_linux.json
+++ b/infra/recipes/gn.expected/ci_linux.json
@@ -236,7 +236,7 @@
   },
   {
     "cmd": [
-      "vpython",
+      "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
       "--json-output",
@@ -267,7 +267,7 @@
   },
   {
     "cmd": [
-      "vpython",
+      "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
       "--json-output",
@@ -305,7 +305,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/rpmalloc/configure.py",
       "-c",
@@ -378,7 +378,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/rpmalloc/configure.py",
       "-c",
@@ -455,7 +455,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "-d"
@@ -558,7 +558,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "--use-lto",
@@ -711,7 +711,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "--use-lto",
diff --git a/infra/recipes/gn.expected/ci_mac.json b/infra/recipes/gn.expected/ci_mac.json
index 26af61d..66274f8 100644
--- a/infra/recipes/gn.expected/ci_mac.json
+++ b/infra/recipes/gn.expected/ci_mac.json
@@ -305,7 +305,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "-d"
@@ -462,7 +462,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "--use-lto",
@@ -668,7 +668,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "--use-lto",
diff --git a/infra/recipes/gn.expected/ci_win.json b/infra/recipes/gn.expected/ci_win.json
index e1a74d6..11534b5 100644
--- a/infra/recipes/gn.expected/ci_win.json
+++ b/infra/recipes/gn.expected/ci_win.json
@@ -188,9 +188,9 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
-      "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
+      "RECIPE_MODULE[recipe_engine::json]\\resources\\read.py",
       "[CACHE]\\windows_sdk\\win_sdk\\bin\\SetEnv.x64.json",
       "/path/to/tmp/json"
     ],
@@ -243,7 +243,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]\\gn\\build\\gen.py",
       "-d"
@@ -349,7 +349,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]\\gn\\build\\gen.py",
       "--use-lto",
diff --git a/infra/recipes/gn.expected/cipd_exists.json b/infra/recipes/gn.expected/cipd_exists.json
index 6094333..c2a1553 100644
--- a/infra/recipes/gn.expected/cipd_exists.json
+++ b/infra/recipes/gn.expected/cipd_exists.json
@@ -236,7 +236,7 @@
   },
   {
     "cmd": [
-      "vpython",
+      "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
       "--json-output",
@@ -267,7 +267,7 @@
   },
   {
     "cmd": [
-      "vpython",
+      "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
       "--json-output",
@@ -305,7 +305,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/rpmalloc/configure.py",
       "-c",
@@ -378,7 +378,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/rpmalloc/configure.py",
       "-c",
@@ -455,7 +455,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "-d"
@@ -558,7 +558,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "--use-lto",
@@ -762,7 +762,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "--use-lto",
diff --git a/infra/recipes/gn.expected/cipd_register.json b/infra/recipes/gn.expected/cipd_register.json
index 9420990..b877dc1 100644
--- a/infra/recipes/gn.expected/cipd_register.json
+++ b/infra/recipes/gn.expected/cipd_register.json
@@ -236,7 +236,7 @@
   },
   {
     "cmd": [
-      "vpython",
+      "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
       "--json-output",
@@ -267,7 +267,7 @@
   },
   {
     "cmd": [
-      "vpython",
+      "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
       "--json-output",
@@ -305,7 +305,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/rpmalloc/configure.py",
       "-c",
@@ -378,7 +378,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/rpmalloc/configure.py",
       "-c",
@@ -455,7 +455,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "-d"
@@ -558,7 +558,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "--use-lto",
@@ -797,7 +797,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "--use-lto",
diff --git a/infra/recipes/gn.expected/cq_linux.json b/infra/recipes/gn.expected/cq_linux.json
index 9f6943e..9bbd7d3 100644
--- a/infra/recipes/gn.expected/cq_linux.json
+++ b/infra/recipes/gn.expected/cq_linux.json
@@ -287,7 +287,7 @@
   },
   {
     "cmd": [
-      "vpython",
+      "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
       "--json-output",
@@ -318,7 +318,7 @@
   },
   {
     "cmd": [
-      "vpython",
+      "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
       "--json-output",
@@ -356,7 +356,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/rpmalloc/configure.py",
       "-c",
@@ -429,7 +429,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/rpmalloc/configure.py",
       "-c",
@@ -506,7 +506,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "-d"
@@ -609,7 +609,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "--use-lto",
@@ -710,7 +710,7 @@
   },
   {
     "cmd": [
-      "vpython",
+      "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
       "--json-output",
@@ -756,7 +756,7 @@
   },
   {
     "cmd": [
-      "vpython",
+      "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
       "--json-output",
@@ -889,7 +889,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "--use-lto",
diff --git a/infra/recipes/gn.expected/cq_mac.json b/infra/recipes/gn.expected/cq_mac.json
index f9d745e..cc3ec5f 100644
--- a/infra/recipes/gn.expected/cq_mac.json
+++ b/infra/recipes/gn.expected/cq_mac.json
@@ -356,7 +356,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "-d"
@@ -513,7 +513,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "--use-lto",
@@ -613,7 +613,7 @@
   },
   {
     "cmd": [
-      "vpython",
+      "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
       "--json-output",
@@ -659,7 +659,7 @@
   },
   {
     "cmd": [
-      "vpython",
+      "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
       "--json-output",
@@ -846,7 +846,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]/gn/build/gen.py",
       "--use-lto",
diff --git a/infra/recipes/gn.expected/cq_win.json b/infra/recipes/gn.expected/cq_win.json
index e1f742b..792e0e9 100644
--- a/infra/recipes/gn.expected/cq_win.json
+++ b/infra/recipes/gn.expected/cq_win.json
@@ -239,9 +239,9 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
-      "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
+      "RECIPE_MODULE[recipe_engine::json]\\resources\\read.py",
       "[CACHE]\\windows_sdk\\win_sdk\\bin\\SetEnv.x64.json",
       "/path/to/tmp/json"
     ],
@@ -294,7 +294,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]\\gn\\build\\gen.py",
       "-d"
@@ -400,7 +400,7 @@
   },
   {
     "cmd": [
-      "python",
+      "python3",
       "-u",
       "[START_DIR]\\gn\\build\\gen.py",
       "--use-lto",
@@ -503,7 +503,7 @@
   },
   {
     "cmd": [
-      "vpython",
+      "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]\\resources\\fileutil.py",
       "--json-output",
@@ -550,7 +550,7 @@
   },
   {
     "cmd": [
-      "vpython",
+      "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]\\resources\\fileutil.py",
       "--json-output",
diff --git a/infra/recipes/gn.py b/infra/recipes/gn.py
index 011d4b0..a4277dc 100644
--- a/infra/recipes/gn.py
+++ b/infra/recipes/gn.py
@@ -5,8 +5,6 @@
 
 from recipe_engine.recipe_api import Property
 
-PYTHON_VERSION_COMPATIBILITY = 'PY3'
-
 DEPS = [
     'recipe_engine/buildbucket',
     'recipe_engine/cas',
@@ -17,7 +15,6 @@
     'recipe_engine/path',
     'recipe_engine/platform',
     'recipe_engine/properties',
-    'recipe_engine/python',
     'recipe_engine/raw_io',
     'recipe_engine/step',
     'target',
@@ -226,10 +223,10 @@
                                              cipd_dir)
           with api.step.nest('build rpmalloc-' + platform), api.context(
               env=env, cwd=rpmalloc_src_dir):
-            api.python(
+            api.step(
                 'configure',
-                rpmalloc_src_dir.join('configure.py'),
-                args=['-c', 'release', '-a', rpmalloc_arch, '--lto'])
+                ['python3', '-u', rpmalloc_src_dir.join('configure.py')] +
+                ['-c', 'release', '-a', rpmalloc_arch, '--lto'])
 
             # NOTE: Only build the static library.
             rpmalloc_static_lib = api.path.join('lib', rpmalloc_os, 'release',
@@ -252,7 +249,8 @@
                   '--link-lib=%s' % rpmalloc_static_libs[target.platform]
               ]
 
-            api.python('generate', src_dir.join('build', 'gen.py'), args=args)
+            api.step('generate',
+                     ['python3', '-u', src_dir.join('build', 'gen.py')] + args)
 
             # Windows requires the environment modifications when building too.
             api.step('build',