Allow python location to be selected.

Summary:
Now `PATH_TO_PYTHON_INTERP` is no longer used. Path to python interpreter is loaded from `.buckconfig`.
Now `buck project` works on Windows. Before this revision python interpreter is hard-coded in Project.java.

Test Plan: Unit tests. Run `buck project` on Windows.
diff --git a/bin/buck.cmd b/bin/buck.cmd
index 27968da..f8d87de 100644
--- a/bin/buck.cmd
+++ b/bin/buck.cmd
@@ -69,6 +69,9 @@
   )
 )
 
+:: Path to Python interpreter will be tried to find. If not found, Jython will be used.
+set PYTHON_INTERP_FALLBACK=%BUCK_BIN_DIRECTORY%\jython.cmd
+
 set RELATIVE_PATH_TO_BUCK_PY=src/com/facebook/buck/parser/buck.py
 set PATH_TO_BUCK_PY=%BUCK_DIRECTORY%\%RELATIVE_PATH_TO_BUCK_PY%
 
@@ -80,7 +83,7 @@
 -Dbuck.abi_processor_classes=%BUCK_DIRECTORY%\build\abi_processor\classes ^
 -Dbuck.path_to_emma_jar=%BUCK_DIRECTORY%\third-party\java\emma-2.0.5312\out\emma-2.0.5312.jar ^
 -Dbuck.test_util_no_tests_dir=true ^
--Dbuck.path_to_python_interp=%PYTHON_INTERP% ^
+-Dbuck.path_to_python_interp=%PYTHON_INTERP_FALLBACK% ^
 -Dbuck.path_to_buck_py=%PATH_TO_BUCK_PY% ^
 -Dbuck.path_to_intellij_py=%BUCK_DIRECTORY%\src\com\facebook\buck\command\intellij.py ^
 -Dbuck.git_commit=%BUCK_CURRENT_VERSION% ^
diff --git a/bin/buck_common b/bin/buck_common
index d96e84b..cf4847a 100755
--- a/bin/buck_common
+++ b/bin/buck_common
@@ -133,14 +133,8 @@
 popd > /dev/null
 popd > /dev/null
 
-# Determine which python interpreter to use for buck.  Currently python
-# is elected as the very-nearly-hardcoded default for temporary
-# performance relief.  To override for debug/testing purposes, use:
-#   DEBUG_BUCK_PYTHON=path/to/buck/bin/jython buck build //apps/myapp:app
-# TODO: This should be fixed with proper global configuration and
-# autodetection.
-DEFAULT_PYTHON_INTERP=python
-PYTHON_INTERP=${DEBUG_BUCK_PYTHON-$DEFAULT_PYTHON_INTERP}
+# Path to Python interpreter will be tried to find. If not found, Jython will be used.
+PYTHON_INTERP_FALLBACK=${BUCK_DIRECTORY}/bin/jython
 
 # Note that if $RELATIVE_PATH_TO_BUCK_PY changes, then the default value of
 # com.facebook.buck.json.BuildFileToJsonParser#PATH_TO_BUCK_PY 
@@ -186,7 +180,7 @@
 -Dbuck.abi_processor_classes=${BUCK_DIRECTORY}/build/abi_processor/classes \
 -Dbuck.path_to_emma_jar=${BUCK_DIRECTORY}/third-party/java/emma-2.0.5312/out/emma-2.0.5312.jar \
 -Dbuck.test_util_no_tests_dir=true \
--Dbuck.path_to_python_interp=${PYTHON_INTERP} \
+-Dbuck.path_to_python_interp=${PYTHON_INTERP_FALLBACK} \
 -Dbuck.path_to_buck_py=${PATH_TO_BUCK_PY} \
 -Dbuck.path_to_intellij_py=${BUCK_DIRECTORY}/src/com/facebook/buck/command/intellij.py \
 -Dbuck.git_commit=${BUCK_CURRENT_VERSION} \
diff --git a/src/com/facebook/buck/cli/AuditRulesCommand.java b/src/com/facebook/buck/cli/AuditRulesCommand.java
index bd81c50..dc370f5 100644
--- a/src/com/facebook/buck/cli/AuditRulesCommand.java
+++ b/src/com/facebook/buck/cli/AuditRulesCommand.java
@@ -87,7 +87,8 @@
   int runCommandWithOptions(AuditRulesOptions options) throws IOException {
     ProjectFilesystem projectFilesystem = getProjectFilesystem();
     ProjectBuildFileParser parser = new ProjectBuildFileParser(projectFilesystem,
-        options.getBuckConfig().getDefaultIncludes());
+        options.getBuckConfig().getDefaultIncludes(),
+        options.getBuckConfig().getPythonInterpreter());
     PrintStream out = console.getStdOut();
     for (String pathToBuildFile : options.getArguments()) {
       // Print a comment with the path to the build file.
diff --git a/src/com/facebook/buck/cli/BuckConfig.java b/src/com/facebook/buck/cli/BuckConfig.java
index 9550fe2..20e28c7 100644
--- a/src/com/facebook/buck/cli/BuckConfig.java
+++ b/src/com/facebook/buck/cli/BuckConfig.java
@@ -565,4 +565,46 @@
   public int hashCode() {
     return Objects.hashCode(sectionsToEntries);
   }
+
+  private String[] getEnv(String propertyName, String separator) {
+    String value = System.getenv(propertyName);
+    if (value == null) {
+      value = "";
+    }
+    return value.split(separator);
+  }
+
+  /**
+   * Returns the path to python interpreter. Firstly, it queries "python" under "tools" section
+   * defined in .buckconfig. If not found or invalid, it will try to find python under PATH.
+   * @return The found python interpreter.
+   */
+  public String getPythonInterpreter() {
+    String interpreter = getValue("tools", "python").or("python");
+    // Try finding interpreter with file name directly.
+    File executable = new File(interpreter);
+    if (executable.canExecute()) {
+      return executable.getAbsolutePath();
+    }
+
+    // Try to prepend path
+    // For windows, executables have certain extension names, i.e. .exe, .bat, .cmd, etc, which are
+    // defined in %PATHEXT%
+    String[] paths = getEnv("PATH", File.pathSeparator);
+    String[] pathExts = getEnv("PATHEXT", File.pathSeparator);
+    for (String path : paths) {
+      for (String pathExt : pathExts) {
+        executable = new File(path, interpreter + pathExt);
+        if (executable.canExecute()) {
+          return executable.getAbsolutePath();
+        }
+      }
+    }
+
+    // Use Jython as a fallback
+    interpreter = System.getProperty("buck.path_to_python_interp", "bin/jython");
+    executable = new File(interpreter);
+    assert(executable.canExecute());
+    return interpreter;
+  }
 }
diff --git a/src/com/facebook/buck/cli/CommandRunnerParams.java b/src/com/facebook/buck/cli/CommandRunnerParams.java
index ae5e578..c8f2c07 100644
--- a/src/com/facebook/buck/cli/CommandRunnerParams.java
+++ b/src/com/facebook/buck/cli/CommandRunnerParams.java
@@ -44,13 +44,14 @@
       ProjectFilesystem projectFilesystem,
       KnownBuildRuleTypes buildRuleTypes,
       ArtifactCache artifactCache,
-      BuckEventBus eventBus) {
+      BuckEventBus eventBus,
+      String pythonInterpreter) {
     this(console,
         projectFilesystem,
         buildRuleTypes,
         artifactCache,
         eventBus,
-        new Parser(projectFilesystem, buildRuleTypes, console));
+        new Parser(projectFilesystem, buildRuleTypes, console, pythonInterpreter));
   }
 
   public CommandRunnerParams(
diff --git a/src/com/facebook/buck/cli/Main.java b/src/com/facebook/buck/cli/Main.java
index f673c14..d6018c1 100644
--- a/src/com/facebook/buck/cli/Main.java
+++ b/src/com/facebook/buck/cli/Main.java
@@ -92,7 +92,10 @@
                   BuckConfig config,
                   Console console) throws IOException {
       this.config = config;
-      this.parser = new Parser(projectFilesystem, new KnownBuildRuleTypes(), console);
+      this.parser = new Parser(projectFilesystem,
+          new KnownBuildRuleTypes(),
+          console,
+          config.getPythonInterpreter());
       this.fileEventBus = new EventBus("file-change-events");
       this.filesystemWatcher = new ProjectFilesystemWatcher(
           projectFilesystem,
@@ -218,7 +221,10 @@
       daemon.watchFileSystem();
       parser = daemon.getParser();
     } else {
-      parser = new Parser(projectFilesystem, knownBuildRuleTypes, console);
+      parser = new Parser(projectFilesystem,
+          knownBuildRuleTypes,
+          console,
+          config.getPythonInterpreter());
     }
 
     Clock clock = new DefaultClock();
diff --git a/src/com/facebook/buck/cli/ProjectCommand.java b/src/com/facebook/buck/cli/ProjectCommand.java
index 1943d2c..1082fd3 100644
--- a/src/com/facebook/buck/cli/ProjectCommand.java
+++ b/src/com/facebook/buck/cli/ProjectCommand.java
@@ -81,7 +81,8 @@
         executionContext,
         getProjectFilesystem(),
         options.getPathToDefaultAndroidManifest(),
-        options.getPathToPostProcessScript());
+        options.getPathToPostProcessScript(),
+        options.getBuckConfig().getPythonInterpreter());
 
     File tempFile = new File(Files.createTempDir(), "project.json");
     int exitCode;
diff --git a/src/com/facebook/buck/command/Project.java b/src/com/facebook/buck/command/Project.java
index 8118184..79dd9c0 100644
--- a/src/com/facebook/buck/command/Project.java
+++ b/src/com/facebook/buck/command/Project.java
@@ -129,6 +129,7 @@
   private final Optional<String> pathToDefaultAndroidManifest;
   private final Optional<String> pathToPostProcessScript;
   private final Set<PrebuiltJarRule> libraryJars;
+  private final String pythonInterpreter;
 
   public Project(PartialGraph partialGraph,
       Map<String, String> basePathToAliasMap,
@@ -136,7 +137,8 @@
       ExecutionContext executionContext,
       ProjectFilesystem projectFilesystem,
       Optional<String> pathToDefaultAndroidManifest,
-      Optional<String> pathToPostProcessScript) {
+      Optional<String> pathToPostProcessScript,
+      String pythonInterpreter) {
     this.partialGraph = Preconditions.checkNotNull(partialGraph);
     this.buildFileTree = new BuildFileTree(partialGraph.getTargets());
     this.basePathToAliasMap = ImmutableMap.copyOf(basePathToAliasMap);
@@ -146,6 +148,7 @@
     this.pathToDefaultAndroidManifest = Preconditions.checkNotNull(pathToDefaultAndroidManifest);
     this.pathToPostProcessScript = Preconditions.checkNotNull(pathToPostProcessScript);
     this.libraryJars = Sets.newHashSet();
+    this.pythonInterpreter = Preconditions.checkNotNull(pythonInterpreter);
   }
 
   public int createIntellijProject(File jsonTempFile,
@@ -910,7 +913,7 @@
 
   private ExitCodeAndStdOut processJsonConfig(File jsonTempFile) throws IOException {
     final ImmutableList<String> args = ImmutableList.of(
-        "python", PATH_TO_INTELLIJ_PY, jsonTempFile.getAbsolutePath());
+        pythonInterpreter, PATH_TO_INTELLIJ_PY, jsonTempFile.getAbsolutePath());
 
     ShellStep command = new ShellStep() {
 
diff --git a/src/com/facebook/buck/json/DefaultProjectBuildFileParserFactory.java b/src/com/facebook/buck/json/DefaultProjectBuildFileParserFactory.java
index 7429e50..8a1ec9d 100644
--- a/src/com/facebook/buck/json/DefaultProjectBuildFileParserFactory.java
+++ b/src/com/facebook/buck/json/DefaultProjectBuildFileParserFactory.java
@@ -21,13 +21,16 @@
 
 public class DefaultProjectBuildFileParserFactory implements ProjectBuildFileParserFactory {
   private final ProjectFilesystem projectFilesystem;
+  private final String pythonInterpreter;
 
-  public DefaultProjectBuildFileParserFactory(ProjectFilesystem projectFilesystem) {
+  public DefaultProjectBuildFileParserFactory(ProjectFilesystem projectFilesystem,
+                                              String pythonInterpreter) {
     this.projectFilesystem = Preconditions.checkNotNull(projectFilesystem);
+    this.pythonInterpreter = Preconditions.checkNotNull(pythonInterpreter);
   }
 
   @Override
   public ProjectBuildFileParser createParser(Iterable<String> commonIncludes) {
-    return new ProjectBuildFileParser(projectFilesystem, commonIncludes);
+    return new ProjectBuildFileParser(projectFilesystem, commonIncludes, pythonInterpreter);
   }
 }
diff --git a/src/com/facebook/buck/json/ProjectBuildFileParser.java b/src/com/facebook/buck/json/ProjectBuildFileParser.java
index 49e3201..a7f94af 100644
--- a/src/com/facebook/buck/json/ProjectBuildFileParser.java
+++ b/src/com/facebook/buck/json/ProjectBuildFileParser.java
@@ -41,27 +41,6 @@
  * parsing phase and must be closed afterward to free up resources.
  */
 public class ProjectBuildFileParser implements AutoCloseable {
-
-  /**
-   * Path to the Python interpreter to use.  Hardcoding the default of python for
-   * now which causes all integration tests of buck itself to fallback (which do not
-   * invoke via {@code bin/buck_common} and therefore do not have this property set).
-   * This should be addressed by offering a proper strategy for selecting the correct
-   * interpreter for the system involving auto-detection and/or global buck configuration.
-   * Additionally, there must be a strategy by which this value can be adjusted for integration
-   * tests so that they can verify both the python and jython environments remain
-   * functional.
-   * <p>
-   * Note there is a serious gotcha by using bin/jython here for buck integration tests today.
-   * This is because Jython's startup time is incredibly slow (2-3s), multiplied n times
-   * for each test.  The fix may well involve reviving Jython integrated directly into
-   * buck but this has to be done very cafefully as to not add performance regressions for
-   * users who do not take the jython code path.
-   * <p>
-   */
-  private static final String PATH_TO_PYTHON_INTERP =
-      System.getProperty("buck.path_to_python_interp", "python");
-
   /** Path to the buck.py script that is used to evaluate a build file. */
   private static final String PATH_TO_BUCK_PY = System.getProperty("buck.path_to_buck_py",
       "src/com/facebook/buck/parser/buck.py");
@@ -74,6 +53,7 @@
   private final File projectRoot;
   private final ImmutableSet<String> ignorePaths;
   private final ImmutableList<String> commonIncludes;
+  private final String pythonInterpreter;
 
   private boolean isServerMode;
 
@@ -82,10 +62,12 @@
 
   public ProjectBuildFileParser(
       ProjectFilesystem projectFilesystem,
-      Iterable<String> commonIncludes) {
+      Iterable<String> commonIncludes,
+      String pythonInterpreter) {
     this.projectRoot = projectFilesystem.getProjectRoot();
     this.ignorePaths = projectFilesystem.getIgnorePaths();
     this.commonIncludes = ImmutableList.copyOf(commonIncludes);
+    this.pythonInterpreter = Preconditions.checkNotNull(pythonInterpreter);
 
     // Default to server mode unless explicitly unset internally.
     setServerMode(true);
@@ -151,7 +133,7 @@
     // Invoking buck.py and read JSON-formatted build rules from its stdout.
     ImmutableList.Builder<String> argBuilder = ImmutableList.builder();
 
-    argBuilder.add(PATH_TO_PYTHON_INTERP);
+    argBuilder.add(pythonInterpreter);
 
     // Ask python to unbuffer stdout so that we can coordinate based on the output as it is
     // produced.
diff --git a/src/com/facebook/buck/parser/Parser.java b/src/com/facebook/buck/parser/Parser.java
index d00efb2..b3bc987 100644
--- a/src/com/facebook/buck/parser/Parser.java
+++ b/src/com/facebook/buck/parser/Parser.java
@@ -131,7 +131,8 @@
 
   public Parser(final ProjectFilesystem projectFilesystem,
       KnownBuildRuleTypes buildRuleTypes,
-      Console console) {
+      Console console,
+      String pythonInterpreter) {
     this(projectFilesystem,
         buildRuleTypes,
         console,
@@ -144,7 +145,7 @@
         },
         new BuildTargetParser(projectFilesystem),
          /* knownBuildTargets */ Maps.<BuildTarget, BuildRuleBuilder<?>>newHashMap(),
-        new DefaultProjectBuildFileParserFactory(projectFilesystem));
+        new DefaultProjectBuildFileParserFactory(projectFilesystem, pythonInterpreter));
   }
 
   /**
diff --git a/test/com/facebook/buck/cli/AuditClasspathCommandTest.java b/test/com/facebook/buck/cli/AuditClasspathCommandTest.java
index 8715123..80e545c 100644
--- a/test/com/facebook/buck/cli/AuditClasspathCommandTest.java
+++ b/test/com/facebook/buck/cli/AuditClasspathCommandTest.java
@@ -36,6 +36,7 @@
 import com.facebook.buck.rules.NoopArtifactCache;
 import com.facebook.buck.testutil.RuleMap;
 import com.facebook.buck.testutil.TestConsole;
+import com.facebook.buck.testutil.BuckTestConstant;
 import com.facebook.buck.util.ProjectFilesystem;
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
@@ -71,7 +72,8 @@
         projectFilesystem,
         buildRuleTypes,
         artifactCache,
-        eventBus));
+        eventBus,
+        BuckTestConstant.PYTHON_INTERPRETER));
   }
 
   private PartialGraph createGraphFromBuildRules(BuildRuleResolver ruleResolver,
diff --git a/test/com/facebook/buck/cli/AuditOwnerCommandTest.java b/test/com/facebook/buck/cli/AuditOwnerCommandTest.java
index 15b9b76..7dcd8ae 100644
--- a/test/com/facebook/buck/cli/AuditOwnerCommandTest.java
+++ b/test/com/facebook/buck/cli/AuditOwnerCommandTest.java
@@ -245,7 +245,8 @@
         filesystem,
         buildRuleTypes,
         artifactCache,
-        eventBus));
+        eventBus,
+        buckConfig.getPythonInterpreter()));
   }
 
   @Test
diff --git a/test/com/facebook/buck/cli/InstallCommandTest.java b/test/com/facebook/buck/cli/InstallCommandTest.java
index 3bfe486..7575192 100644
--- a/test/com/facebook/buck/cli/InstallCommandTest.java
+++ b/test/com/facebook/buck/cli/InstallCommandTest.java
@@ -31,6 +31,7 @@
 import com.facebook.buck.rules.KnownBuildRuleTypes;
 import com.facebook.buck.rules.NoopArtifactCache;
 import com.facebook.buck.testutil.TestConsole;
+import com.facebook.buck.testutil.BuckTestConstant;
 import com.facebook.buck.util.Console;
 import com.facebook.buck.util.ProjectFilesystem;
 
@@ -93,7 +94,8 @@
         filesystem,
         buildRuleTypes,
         artifactCache,
-        eventBus));
+        eventBus,
+        BuckTestConstant.PYTHON_INTERPRETER));
   }
 
   /**
diff --git a/test/com/facebook/buck/cli/ProjectCommandTest.java b/test/com/facebook/buck/cli/ProjectCommandTest.java
index 1fb7871..cde735d 100644
--- a/test/com/facebook/buck/cli/ProjectCommandTest.java
+++ b/test/com/facebook/buck/cli/ProjectCommandTest.java
@@ -43,6 +43,7 @@
 import com.facebook.buck.rules.ProjectConfigRule;
 import com.facebook.buck.testutil.MoreAsserts;
 import com.facebook.buck.testutil.TestConsole;
+import com.facebook.buck.testutil.BuckTestConstant;
 import com.facebook.buck.util.ProcessExecutor;
 import com.facebook.buck.util.ProjectFilesystem;
 import com.google.common.base.Function;
@@ -170,7 +171,8 @@
           new ProjectFilesystem(new File(".")),
           new KnownBuildRuleTypes(),
           artifactCache,
-          new BuckEventBus()));
+          new BuckEventBus(),
+          BuckTestConstant.PYTHON_INTERPRETER));
     }
 
     @Override
diff --git a/test/com/facebook/buck/cli/TargetsCommandTest.java b/test/com/facebook/buck/cli/TargetsCommandTest.java
index 3e4683b..0d01502 100644
--- a/test/com/facebook/buck/cli/TargetsCommandTest.java
+++ b/test/com/facebook/buck/cli/TargetsCommandTest.java
@@ -48,6 +48,7 @@
 import com.facebook.buck.testutil.RuleMap;
 import com.facebook.buck.testutil.TestConsole;
 import com.facebook.buck.util.BuckConstant;
+import com.facebook.buck.testutil.BuckTestConstant;
 import com.facebook.buck.util.ProjectFilesystem;
 import com.fasterxml.jackson.core.JsonFactory;
 import com.fasterxml.jackson.core.JsonParser.Feature;
@@ -122,7 +123,8 @@
             projectFilesystem,
             buildRuleTypes,
             artifactCache,
-            eventBus));
+            eventBus,
+            BuckTestConstant.PYTHON_INTERPRETER));
   }
 
   @Test
diff --git a/test/com/facebook/buck/command/ProjectTest.java b/test/com/facebook/buck/command/ProjectTest.java
index 0c1c64b..0ac6aa1 100644
--- a/test/com/facebook/buck/command/ProjectTest.java
+++ b/test/com/facebook/buck/command/ProjectTest.java
@@ -45,6 +45,7 @@
 import com.facebook.buck.rules.ProjectConfigRule;
 import com.facebook.buck.step.ExecutionContext;
 import com.facebook.buck.testutil.RuleMap;
+import com.facebook.buck.testutil.BuckTestConstant;
 import com.facebook.buck.util.HumanReadableException;
 import com.facebook.buck.util.ProjectFilesystem;
 import com.google.common.base.Function;
@@ -728,7 +729,8 @@
         executionContext,
         projectFilesystem,
         /* pathToDefaultAndroidManifest */ Optional.<String>absent(),
-        /* pathToPostProcessScript */ Optional.<String>absent());
+        /* pathToPostProcessScript */ Optional.<String>absent(),
+        BuckTestConstant.PYTHON_INTERPRETER);
 
     // Execute Project's business logic.
     EasyMock.replay(executionContext, projectFilesystem);
diff --git a/test/com/facebook/buck/parser/ParserTest.java b/test/com/facebook/buck/parser/ParserTest.java
index 8852a8c..c93b506 100644
--- a/test/com/facebook/buck/parser/ParserTest.java
+++ b/test/com/facebook/buck/parser/ParserTest.java
@@ -46,6 +46,7 @@
 import com.facebook.buck.rules.KnownBuildRuleTypes;
 import com.facebook.buck.testutil.TestConsole;
 import com.facebook.buck.util.BuckConstant;
+import com.facebook.buck.testutil.BuckTestConstant;
 import com.facebook.buck.util.HumanReadableException;
 import com.facebook.buck.util.ProjectFilesystem;
 import com.google.common.base.Charsets;
@@ -106,7 +107,7 @@
 
     buildRuleTypes = new KnownBuildRuleTypes();
     DefaultProjectBuildFileParserFactory testBuildFileParserFactory =
-        new DefaultProjectBuildFileParserFactory(filesystem);
+        new DefaultProjectBuildFileParserFactory(filesystem, BuckTestConstant.PYTHON_INTERPRETER);
     testParser = createParser(emptyBuildTargets(), testBuildFileParserFactory);
   }
 
@@ -167,7 +168,8 @@
     Parser parser = new Parser(
         new ProjectFilesystem(new File(".")),
         new KnownBuildRuleTypes(),
-        new TestConsole());
+        new TestConsole(),
+        BuckTestConstant.PYTHON_INTERPRETER);
 
     parser.parseRawRulesInternal(ruleObjects, null);
     RawRulePredicate predicate = alwaysTrue();
@@ -441,7 +443,7 @@
 
     Parser parser = createParser(buildFileTreeSupplier,
         emptyBuildTargets(),
-        new DefaultProjectBuildFileParserFactory(filesystem),
+        new DefaultProjectBuildFileParserFactory(filesystem, BuckTestConstant.PYTHON_INTERPRETER),
         new BuildTargetParser(filesystem));
 
     parser.filterAllTargetsInProject(filesystem, Lists.<String>newArrayList(), alwaysTrue());
@@ -468,7 +470,7 @@
 
     Parser parser = createParser(buildFileTreeSupplier,
         emptyBuildTargets(),
-        new DefaultProjectBuildFileParserFactory(filesystem),
+        new DefaultProjectBuildFileParserFactory(filesystem, BuckTestConstant.PYTHON_INTERPRETER),
         new BuildTargetParser(filesystem));
 
     parser.filterAllTargetsInProject(filesystem, Lists.<String>newArrayList(), alwaysTrue());
@@ -495,7 +497,7 @@
 
     Parser parser = createParser(buildFileTreeSupplier,
         emptyBuildTargets(),
-        new DefaultProjectBuildFileParserFactory(filesystem),
+        new DefaultProjectBuildFileParserFactory(filesystem, BuckTestConstant.PYTHON_INTERPRETER),
         new BuildTargetParser(filesystem));
 
     parser.filterAllTargetsInProject(filesystem, Lists.<String>newArrayList(), alwaysTrue());
@@ -523,7 +525,7 @@
 
     Parser parser = createParser(buildFileTreeSupplier,
         emptyBuildTargets(),
-        new DefaultProjectBuildFileParserFactory(filesystem),
+        new DefaultProjectBuildFileParserFactory(filesystem, BuckTestConstant.PYTHON_INTERPRETER),
         new BuildTargetParser(filesystem));
 
     parser.filterAllTargetsInProject(filesystem, Lists.<String>newArrayList(), alwaysTrue());
@@ -549,7 +551,7 @@
 
     Parser parser = createParser(buildFileTreeSupplier,
         emptyBuildTargets(),
-        new DefaultProjectBuildFileParserFactory(filesystem),
+        new DefaultProjectBuildFileParserFactory(filesystem, BuckTestConstant.PYTHON_INTERPRETER),
         new BuildTargetParser(filesystem));
 
     WatchEvent<Path> event = createMock(WatchEvent.class);
@@ -782,7 +784,7 @@
 
     private class TestProjectBuildFileParser extends ProjectBuildFileParser {
       public TestProjectBuildFileParser() {
-        super(projectFilesystem, ImmutableList.<String>of());
+        super(projectFilesystem, ImmutableList.<String>of(), "python");
       }
 
       @Override
diff --git a/test/com/facebook/buck/testutil/BuckTestConstant.java b/test/com/facebook/buck/testutil/BuckTestConstant.java
new file mode 100644
index 0000000..733895d
--- /dev/null
+++ b/test/com/facebook/buck/testutil/BuckTestConstant.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.
+ */
+
+package com.facebook.buck.testutil;
+
+
+public class BuckTestConstant {
+
+  /**
+   * Path to python interpreter for testing.
+   */
+  public static final String PYTHON_INTERPRETER = "python";
+
+  private BuckTestConstant() {}
+}