Improved Python 3 support

In order to better support building Chromium with Python 3 on Windows it
is helpful if --script-executable=c:\src\depot_tools\python3.bat will
translate python3.bat to the appropriate python.exe path. This is mostly
just a matter of calling PythonBatToExe from FillPythonPath, but it was
also necessary to update PythonBatToExe to make it's Python print
statement be Python 3 compatible.

This change also means that if python.bat is found in the path during
normal initialization and points to Python 3 then this will succeed
instead of printing a cryptic error message.

Change-Id: I7339034c6c8e817a386ca19f57f64401a3d49b2c
Commit-Queue: Brett Wilson <>
Reviewed-by: Brett Wilson <>
diff --git a/src/gn/ b/src/gn/
index 1535276..081bc7e 100644
--- a/src/gn/
+++ b/src/gn/
@@ -265,7 +265,7 @@
   // two quotes at the end.
   std::u16string command = u"cmd.exe /c \"\"";
-  command.append(u"\" -c \"import sys; print sys.executable\"\"");
+  command.append(u"\" -c \"import sys; print(sys.executable)\"\"");
   std::string python_path;
   std::string std_err;
@@ -727,8 +727,12 @@
   ScopedTrace setup_trace(TraceItem::TRACE_SETUP, "Fill Python Path");
   const Value* value = dotfile_scope_.GetValue("script_executable", true);
   if (cmdline.HasSwitch(switches::kScriptExecutable)) {
-    build_settings_.set_python_path(
-        cmdline.GetSwitchValuePath(switches::kScriptExecutable));
+    auto script_executable = cmdline.GetSwitchValuePath(switches::kScriptExecutable);
+#if defined(OS_WIN)
+    if (script_executable.FinalExtension() == u".bat")
+      script_executable = PythonBatToExe(script_executable);
+    build_settings_.set_python_path(script_executable);
   } else if (value) {
     if (!value->VerifyTypeIs(Value::STRING, err)) {
       return false;