Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly change the working directory in python #296

Merged
merged 1 commit into from Apr 13, 2018

Conversation

Leandros
Copy link
Contributor

This is implementing #295 and neovim/neovim#3636.

@justinmk
Copy link
Member

Thanks! Can you add a test?

@Leandros
Copy link
Contributor Author

@justinmk Sure, I've had a test written anyway.

@@ -65,7 +65,9 @@ def setup(self, nvim):
sys.stderr = RedirectStream(lambda data: nvim.err_write(data))
# Setup the DirChanged listener
cid = nvim.channel_id
nvim.command('au DirChanged * call rpcrequest(%d, "python_chdir", v:event)' % cid)
cmd = 'au DirChanged * call rpcrequest(%d, "python_chdir", v:event)' \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use autocmd instead of au, which makes it easier go grep for when searching for autocmd-related things.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

@Leandros
Copy link
Contributor Author

Alright, all tests ran through. Fixed the last linter warning.

@@ -63,6 +63,12 @@ def setup(self, nvim):
self.saved_stderr = sys.stderr
sys.stdout = RedirectStream(lambda data: nvim.out_write(data))
sys.stderr = RedirectStream(lambda data: nvim.err_write(data))
# Setup the DirChanged listener
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm maybe we can use the host autocmd infrastructure here. (We need to add a flag to not start the host for the autocmd, but that would be useable in general)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually that would require a bit bigger refactor than I thought, so let's keep this as is for now (and maybe revisit at UpdateRemotePlugins refactor)

@mhinz
Copy link
Member

mhinz commented Jan 19, 2018

@bfredl

What is happening here? https://travis-ci.org/neovim/python-client/jobs/330770820#L512

I get this locally as well. Sometimes.

Error detected while processing function provider#python3#Call:
line   18:
no request handler registered for "python_execute"

It starts happening at a8a98b8. This culprit seems to be this line:

nvim.command('au DirChanged * call rpcrequest(%d, "python_chdir", v:event)' % cid)

@bfredl
Copy link
Member

bfredl commented Jan 19, 2018

you mean you don't see it on master?

@@ -63,6 +63,12 @@ def setup(self, nvim):
self.saved_stderr = sys.stderr
sys.stdout = RedirectStream(lambda data: nvim.out_write(data))
sys.stderr = RedirectStream(lambda data: nvim.err_write(data))
# Setup the DirChanged listener
cid = nvim.channel_id
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unnecessary temporary

# Setup the DirChanged listener
cid = nvim.channel_id
cmd = 'autocmd DirChanged *' \
+ ' call rpcrequest(%d, "python_chdir", v:event)' \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also we prefer to use new-style .format()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I, too, prefer .format(). I simply followed what I've seen being used before. Will change it.

@mhinz
Copy link
Member

mhinz commented Jan 19, 2018

Yup. I just do:

$ git checkout a8a98b8
$ nvim
:python3 import os

Commenting out the following line makes it work again:

nvim.command('au DirChanged * call rpcrequest(%d, "python_chdir", v:event)' % cid)

@mhinz
Copy link
Member

mhinz commented Jan 19, 2018

Any nvim.command() in setup() will lead to that error.

@bfredl
Copy link
Member

bfredl commented Jan 19, 2018

Hmm, maybe it shouldn't be done in __init__. I generally recommend against doing any RPC there, but I don't see the specific problem right here. Maybe the issue is that it is un-synchorized in general, using nvim.command(...,async=True) might fix it even if its not pretty either.

@mhinz
Copy link
Member

mhinz commented Jan 19, 2018

Yup, nvim.command(..., async=True) fixes it for me.

@bfredl
Copy link
Member

bfredl commented Jan 19, 2018

It is a bit racy, if a vim script does

py3 import blah # first call, so starts the host
cd mydir

the cd might come before the async registration. One can of course also invoke it in the async command to be sure in this case, but generally we want some mechanism for "run this vimL code right when the host starts".

@Leandros
Copy link
Contributor Author

Leandros commented Jan 19, 2018

@mhinz Hmm. That is interesting. I'm using it already, and couldn't see any errors. Which nvim version are you using?

NVIM v0.2.2
Build type: Release
LuaJIT 2.1.0-beta3
Compilation: /usr/local/Homebrew/Library/Homebrew/shims/super/clang -Wconversion -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DNDEBUG -DMIN_LOG_LEVEL=3 -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fdiagnostics-color=auto -DINCLUDE_GENERATED_DECLARATIONS -I/tmp/neovim-20171118-53412-9ielcr/neovim-0.2.2/build/config -I/tmp/neovim-20171118-53412-9ielcr/neovim-0.2.2/src -I/usr/local/include -I/usr/local/include -I/usr/local/include -I/usr/local/include -I/usr/local/include -I/usr/local/include -I/usr/local/opt/gettext/include -I/usr/include -I/tmp/neovim-20171118-53412-9ielcr/neovim-0.2.2/build/src/nvim/auto -I/tmp/neovim-20171118-53412-9ielcr/neovim-0.2.2/build/include
Compiled by brew@Sierra-2.local

Features: +acl +iconv +jemalloc +tui
See ":help feature-compile"

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/usr/local/Cellar/neovim/0.2.2/share/nvim"

Run :checkhealth for more info

@mhinz
Copy link
Member

mhinz commented Jan 19, 2018

@Leandros

Hm, you're right. I can only reproduce it with master and this repo is using nightlies during CI tests.

I can't reproduce it with the 0.2.2 release.

I'll bisect nvim later.

@mhinz
Copy link
Member

mhinz commented Jan 20, 2018

@bfredl

This issue starts happening after neovim/neovim@1ebc96fe1.

@bfredl
Copy link
Member

bfredl commented Jan 20, 2018

Yes, it changes processing of RPC job messages, but not more than to how they were before RPC jobs gained stderr support neovim/neovim#4723 (and to how RPC sockets always have worked), so they are less "forgiving" to potentially racy patterns.

Synchronous initialization should be initiated by one party only. In the case of plugin hosts, this is already nvim, by using one of poll, specs or in the case of script_host by calling one of the script methods directly.

@@ -44,6 +44,14 @@ def __init__(self, nvim):
exec('import sys', self.module.__dict__)
self.legacy_vim = LegacyVim.from_nvim(nvim)
sys.modules['vim'] = self.legacy_vim
# Since the 'DirChanged' autocmd is established asynchronously, import
# os manually already, to prevent a potential race condition
exec('import os', self.module.__dict__)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed? The autocmd handler method is executed in the context of script_host.py which already has the import.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to work-around the race you described, by importing os before, so that Vim can see the current working directory without creating a race.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the race has nothing to do with import os. Quick fix would rather be to do
nvim.command('call rpcrequest({}, "python_chdir", {"cwd": getcwd()}', async=True) after registering the autocmd

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The quickfix doesn't seem to work, at least for me, it results in a python error from my plugins.
screen shot 2018-01-24 at 10 11 03

@Leandros
Copy link
Contributor Author

@bfredl What's your suggestion of implementing this? It's definitely required, we need to watch for the DirChange somehow. I've just looked at the ruby plugin, and found they're doing it quite similar.

@bfredl
Copy link
Member

bfredl commented Jan 22, 2018

Lets use the current solution for now (with the fix I just posted), until we improve host autocmd registration.

justinmk pushed a commit to Leandros/python-client that referenced this pull request Apr 12, 2018
@justinmk
Copy link
Member

nvim.command('call rpcrequest({}, "python_chdir", {"cwd": getcwd()}', async=True)

seems to be a chicken-egg problem, instead I went with this:

os.chdir(nvim.eval('getcwd()', async=False))

Pushed an update to @Leandros branch, will merge after CI.

justinmk pushed a commit to Leandros/python-client that referenced this pull request Apr 12, 2018
bfredl added a commit that referenced this pull request Apr 29, 2018
This release adds support for Python 3.7 which now is in beta. `async`
is a keyword in python3.7, and it should be replaced with `async_` when
used as a keyword argument to API methods. `async` is still supported
with python 2.7 and 3.6 for the moment, but considered deprecated.

Also, integration with the in-process lua interpreter in Nvim is now supported.

Changes since 0.2.4:

* debcde0 clean up remote object implementation (#313)
* e880fe7 Guidelines for local plugin development (#317)
* 1ab98e8 Update the working directory on DirChanged for legacy plugins (#296)
* d53415d Fix SyntaxError in py3.7: use `async_` instead of `async` (#274)
* b65f62d Use `pytest` as `nosetests` are not longer maintained (#266)
* d9aed96 Support using lua functions. `buf.update_higlights` as an internal example (#325)
@blueyed
Copy link
Contributor

blueyed commented Apr 30, 2018

This appears to cause problems with initial use of :py3 for me: #337.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants