Browse Source

Check Python interpreter pathname

Rename CheckPythonVersion to IsPythonVersionCorrect.
In embedders, sys.executable may contain a Vim path instead of a Python
one. To avoid starting a Vim instance in this case, we check that given
path ends with a Python 2.6 or 2.7 name using a regex.
Add tests for this regex.
micbou 9 years ago
parent
commit
a80846e35d
2 changed files with 59 additions and 4 deletions
  1. 14 4
      python/ycm/paths.py
  2. 45 0
      python/ycm/tests/paths_test.py

+ 14 - 4
python/ycm/paths.py

@@ -21,11 +21,13 @@ import os
 import sys
 import vim
 import functools
+import re
 from ycmd import utils
 
 DIR_OF_CURRENT_SCRIPT = os.path.dirname( os.path.abspath( __file__ ) )
 
 WIN_PYTHON_PATH = os.path.join( sys.exec_prefix, 'python.exe' )
+PYTHON_BINARY_REGEX = re.compile( r'python(2(\.[67])?)?(.exe)?$' )
 
 
 def Memoize( obj ):
@@ -45,7 +47,7 @@ def PathToPythonInterpreter():
   python_interpreter = vim.eval( 'g:ycm_path_to_python_interpreter' )
 
   if python_interpreter:
-    if not CheckPythonVersion( python_interpreter ):
+    if not IsPythonVersionCorrect( python_interpreter ):
       raise RuntimeError( "Path in 'g:ycm_path_to_python_interpreter' option "
                           "does not point to a valid Python 2.6 or 2.7." )
 
@@ -58,7 +60,7 @@ def PathToPythonInterpreter():
   python_interpreter = ( WIN_PYTHON_PATH if utils.OnWindows() else
                          sys.executable )
 
-  if not CheckPythonVersion( python_interpreter ):
+  if not IsPythonVersionCorrect( python_interpreter ):
     raise RuntimeError( "Cannot find Python 2.6 or 2.7. You can set its path "
                         "using the 'g:ycm_path_to_python_interpreter' "
                         "option." )
@@ -66,9 +68,17 @@ def PathToPythonInterpreter():
   return python_interpreter
 
 
-def CheckPythonVersion( python_interpreter ):
+def EndsWithPython( path ):
+  """Check if given path ends with a python 2.6 or 2.7 name."""
+  return PYTHON_BINARY_REGEX.search( path ) is not None
+
+
+def IsPythonVersionCorrect( path ):
   """Check if given path is the Python interpreter version 2.6 or 2.7."""
-  command = [ python_interpreter,
+  if not EndsWithPython( path ):
+    return False
+
+  command = [ path,
               '-c',
               "import sys;"
               "major, minor = sys.version_info[ :2 ];"

+ 45 - 0
python/ycm/tests/paths_test.py

@@ -0,0 +1,45 @@
+#
+# Copyright (C) 2016 YouCompleteMe contributors
+#
+# This file is part of YouCompleteMe.
+#
+# YouCompleteMe is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# YouCompleteMe is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with YouCompleteMe.  If not, see <http://www.gnu.org/licenses/>.
+
+from ycm.test_utils import MockVimModule
+MockVimModule()
+
+from nose.tools import ok_
+from ycm.paths import EndsWithPython
+
+
+def EndsWithPython_PythonPaths_test():
+  python_paths = [
+    'python',
+    '/usr/bin/python2.6',
+    '/home/user/.pyenv/shims/python2.7',
+    r'C:\aPython26\python.exe'
+  ]
+
+  for path in python_paths:
+    ok_( EndsWithPython( path ) )
+
+
+def EndsWithPython_NotPythonPaths_test():
+  not_python_paths = [
+    '/opt/local/bin/vim',
+    r'C:\Program Files\Vim\vim74\gvim.exe'
+  ]
+
+  for path in not_python_paths:
+    ok_( not EndsWithPython( path ) )