Closed rdbisme closed 4 years ago
I can't reproduce with almost the same configuration (macOS 10.14 and Python 3 from Homebrew). :YcmDebugInfo
returns the following:
Printing YouCompleteMe debug information...
-- Client logfile: /var/folders/zy/rsczmz7n72v4gqd2zg024p3h0000gn/T/ycm_qozbzj59.log
-- Server Python interpreter: /usr/local/opt/python/bin/python3.7
-- Server Python version: 3.7.3
-- Server has Clang support compiled in: True
-- Clang version: clang version 8.0.0 (tags/RELEASE_800/final)
-- No extra configuration file found
-- Python completer debug information:
-- Python interpreter: /usr/local/Cellar/python/3.7.3/bin/python3.7
-- Python path: ['/Users/micbou/.local/share/virtualenvs/myvirtualenv/lib/python37.zip', '/Users/micbou/.local/share/virtualenvs/myvirtualenv/li
b/python3.7', '/Users/micbou/.local/share/virtualenvs/myvirtualenv/lib/python3.7/lib-dynload', '/usr/local/Cellar/python/3.7.3/Frameworks/Python.f
ramework/Versions/3.7/lib/python3.7', '/Users/micbou/.local/share/virtualenvs/myvirtualenv/lib/python3.7/site-packages']
-- Python version: 3.7.3
-- Jedi version: 0.13.3
-- Parso version: 0.3.4
-- Server running at: http://127.0.0.1:50042
-- Server process ID: 24915
-- Server logfiles:
-- /var/folders/zy/rsczmz7n72v4gqd2zg024p3h0000gn/T/ycmd_50042_stdout_lg3qkgzb.log
-- /var/folders/zy/rsczmz7n72v4gqd2zg024p3h0000gn/T/ycmd_50042_stderr_x6vx7arr.log
after starting Vim in a virtual environment activated with Pew (pew new myvirtualenv
). I don't even have to set the g:ycm_python_binary_path
to 'python'
but it also works with that option.
So I am not sure why it doesn't work for you but maybe it's an issue with your version of Pew. Are you using the latest version?
$ pew version
1.2.0
Shouldn't this:
-- Python completer debug information:
-- Python interpreter: /usr/local/Cellar/python/3.7.3/bin/python3.7
Be the one from the virtualenv instead. I also tried directly sourcing the virtualenv activate
script instead of using pew... I'll try again with the new version and report back.
(In any case I'm also missing the right paths from the Python path)
Be the one from the virtualenv instead.
Yes, that's something I would expect but for some reason the interpreter path returned by Jedi depends on the Python it's running on:
$ /Users/micbou/.local/share/virtualenvs/myvirtualenv/bin/python -c "import jedi; print(jedi.create_environment('/Users/micbou/.local/share/virtualenvs/myvirtualenv/bin/python', safe=False).executable)"
/Users/micbou/.local/share/virtualenvs/myvirtualenv/bin/python
$ /usr/local/Cellar/python/3.7.3/bin/python3 -c "import jedi; print(jedi.create_environment('/Users/micbou/.local/share/virtualenvs/myvirtualenv/bin/python', safe=False).executable)"
/usr/local/Cellar/python/3.7.3/bin/python3
$ /usr/local/Frameworks/Python.framework/Versions/3.7/bin/python3 -c "import jedi; print(jedi.create_environment('/Users/micbou/.local/share/virtualenvs/myvirtualenv/bin/python', safe=False).executable)"
/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/bin/python3
$ /usr/bin/python -c "import jedi; print(jedi.create_environment('/Users/micbou/.local/share/virtualenvs/myvirtualenv/bin/python', safe=False).executable)"
/Users/micbou/.local/share/virtualenvs/myvirtualenv/bin/python
It's not the issue though because all of these paths actually point to the same Python (/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/bin/python3.7
). The important part is that the Python path
line in the output of :YcmDebugInfo
contains the virtualenv paths.
Could you run the command (replace the *****
)
PYTHONPATH=../parso python -c "import jedi; print(jedi.create_environment('/Users/*****/.envs/db-model-MCWC4LsT/bin/python', safe=False).get_sys_path())"
in the YouCompleteMe/third_party/ycmd/third_party/jedi_deps/jedi
folder and paste its output?
This works as expected.
['/Users/*****/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/jedi_deps/parso', '/Users/*****/.envs/db-model-MCWC4LsT/lib/python37.zip', '/Users/*****/.envs/db-model-MCWC4LsT/lib/python3.7', '/Users/*****/.envs/db-model-MCWC4LsT/lib/python3.7/lib-dynload', '/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7', '/Users/*****/.envs/db-model-MCWC4LsT/lib/python3.7/site-packages']
Also
PYTHONPATH=../parso python -c "import jedi; print(jedi.create_environment('/Users/*****/.envs/db-model-MCWC4LsT/bin/python', safe=False).executable)"
/Users/*****/.envs/db-model-MCWC4LsT/bin/python
The thing is that in the interactive virtualenv shell jedi
works as expected. It's inside ycmd
that I have problems...
The thing is that in the interactive virtualenv shell jedi works as expected.
Did you try outside the virtualenv? It should work as well.
PYTHONPATH=../parso python -c "import jedi; print(jedi.create_environment('/Users/****/.envs/db-model-MCWC4LsT/bin/python', safe=False).get_sys_path())"
['/Users/*****/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/jedi_deps/parso', '/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python37.zip', '/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7', '/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload', '/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages']
PYTHONPATH=../parso python -c "import jedi; print(jedi.create_environment('/Users/***/.envs/db-model-MCWC4LsT/bin/python', safe=False).executable)"
/opt/local/bin/python
This is what I get from running the same commands, but outside the virtualenv. So it gets the system python instead.
Ehi, any idea on how to solve here? :)
Hello, I'm still experiencing this issue... Is there anything I can do to help you out with the debug?
I'm trying to debug this. I delved a bit inside jedi create_environment
function. It creates an Environment
object with the correct python binary path (i.e. the one from the virtualenv
).
The problem arises when the instance of Environment
calls self._get_subprocess
. What self._get_subprocess
does is creating a customized subprocess.Popen
and so executing the virtualenv Python intepreter in a subprocess (Link).
What it does then, is sending the function _get_info
to the subprocess and it captures the output.
def _get_info():
return (
sys.executable,
sys.prefix,
sys.version_info[:3],
)
I tried to log a bit what's happening when the Subprocess is created, so I added few logging entries in the source code jedi/evaluate/compiled/subprocess/__init__.py
def _send(self, evaluator_id, function, args=(), kwargs={}):
if self.is_crashed:
raise InternalError("The subprocess %s has crashed." % self._executable)
if not is_py3:
# Python 2 compatibility
kwargs = {force_unicode(key): value for key, value in kwargs.items()}
data = evaluator_id, function, args, kwargs
import logging
LOGGER = logging.getLogger('ycmd')
LOGGER.info(data)
LOGGER.info(f'Process args: {self._process.args}')
try:
pickle_dump(data, self._process.stdin, self._pickle_protocol)
except (socket.error, IOError) as e:
# Once Python2 will be removed we can just use `BrokenPipeError`.
# Also, somehow in windows it returns EINVAL instead of EPIPE if
# the subprocess dies.
if e.errno not in (errno.EPIPE, errno.EINVAL):
# Not a broken pipe
raise
self._kill()
raise InternalError("The subprocess %s was killed. Maybe out of memory?"
% self._executable)
try:
is_exception, traceback, result = pickle_load(self._process.stdout)
import logging
LOGGER = logging.getLogger('ycmd')
LOGGER.info(result)
except EOFError as eof_error:
try:
stderr = self._process.stderr.read().decode('utf-8', 'replace')
except Exception as exc:
stderr = '<empty/not available (%r)>' % exc
self._kill()
_add_stderr_to_debug(self._stderr_queue)
raise InternalError(
"The subprocess %s has crashed (%r, stderr=%s)." % (
self._executable,
eof_error,
stderr,
))
_add_stderr_to_debug(self._stderr_queue)
if is_exception:
# Replace the attribute error message with a the traceback. It's
# way more informative.
result.args = (traceback,)
raise result
return result
def delete_evaluator(self, evaluator_id):
"""
Currently we are not deleting evalutors instantly. They only get
deleted once the subprocess is used again. It would probably a better
solution to move all of this into a thread. However, the memory usage
of a single evaluator shouldn't be that high.
"""
# With an argument - the evaluator gets deleted.
self._evaluator_deletion_queue.append(evaluator_id)
And this is what I get:
2019-07-23 15:42:52,543 - INFO - Received ready request
2019-07-23 15:42:52,606 - INFO - Received event notification
2019-07-23 15:42:52,607 - INFO - Received event notification
2019-07-23 15:42:52,607 - INFO - Adding buffer identifiers for file: /Users/rubendibattista/git/x/josiepy/josie/solver/solver.py
2019-07-23 15:42:52,655 - INFO - data: (None, <function _get_info at 0x10fc42320>, (), {})
2019-07-23 15:42:52,658 - INFO - Process args: ('/Users/rubendibattista/.envs/josiepy-B4k-0ZyT/bin/python', '/Users/rubendibattista/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/jedi_deps/jedi/jedi/evaluate/compiled/subprocess/__main__.py', '/Users/rubendibattista/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/jedi_deps/parso', '3.7.4')
2019-07-23 15:42:52,771 - INFO - ('/opt/local/bin/python', '/opt/local/Library/Frameworks/Python.framework/Versions/3.7', (3, 7, 4))
2019-07-23 15:42:52,771 - INFO - data: (None, <function get_sys_path at 0x10fd7f710>, (), {})
2019-07-23 15:42:52,772 - INFO - Process args: ('/Users/rubendibattista/.envs/josiepy-B4k-0ZyT/bin/python', '/Users/rubendibattista/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/jedi_deps/jedi/jedi/evaluate/compiled/subprocess/__main__.py', '/Users/rubendibattista/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/jedi_deps/parso', '3.7.4')
2019-07-23 15:42:52,772 - INFO - ['/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python37.zip', '/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7', '/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload', '/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages']
2019-07-23 15:42:52,814 - INFO - Received filetype completion available request
2019-07-23 15:42:54,463 - INFO - Received debug info request
So if we examine the args
passed to the Popen
, we see that in facts the provided interpreter is /Users/rubendibattista/.envs/josiepy-B4k-0ZyT/bin/python
. (according to Popen
documentation the first arg is the program to execute). Unfortunately the result is:
('/opt/local/bin/python', '/opt/local/Library/Frameworks/Python.framework/Versions/3.7', (3, 7, 4))
It seems to me that the jedi
subprocess, despite being run with the virtualenv python interpreter, executes instead the system python. I'm not very familiar with the jedi
internals and why this happens, but it looks to me that this is a bug.
seems to me that the jedi subprocess, despite being run with the virtualenv python interpreter, executes instead the system python. I'm not very familiar with the jedi internals and why this happens, but it looks to me that this is a bug.
Thanks for the detail, based on that I think this should be raised with Jedi not us.
not sure there's anything for YCM to change here.
Issue Prelude
Please complete these steps and check these boxes (by putting an
x
inside the brackets) before filing your issue:vim --version
.:YcmDebugInfo
.:YcmToggleLogs
command.install.py
(orcmake
/make
/ninja
) including its invocationThank you for adhering to this process! It ensures your issue is resolved quickly and that neither your nor our time is needlessly wasted.
Issue Details
When opening a python file within a virtualenv shell
YcmDebugInfo
shows the system interpreter instead of the virtualenv one. This seems to not happen on Linux (and Python 3.6).I chatted for few days on the Gitter to understand if it was my problem, but it seems related to the
jedi.create_environment
method, on macOS. The thing is that if I run the following code on an interactive shell within the virtualenv:I correctly get the intepreter inside the virtualenv.
Rewriting these lines like this:
I get the following output in the logs:
For whatever reason, inside
ycmd
the retrieved intepreter is the system one instead of the virtualenv oneMinimal
.vimrc
Then run
vim app.py
.Just run vim on a python file with the minimal
.vimrc
provided when inside a (Python 3.7?) virtualenv CheckYcmDebugInfo
The Python intepreter should have been the one in the virtualenv (
/Users/*****/.envs/db-model-MCWC4LsT/bin/python
)The Python interpreter is instead the system one
Diagnostic data
Output of
vim --version
Python 3.7
Output of
YcmDebugInfo
OS version, distribution, etc.
macOS Mojave 10.14.4