pynvim
pynvim copied to clipboard
Code is run not in __main__ module
Consider the following script:
python import sys; print sys.modules['__main__'].__dict__ is globals()
. In Vim this code prints True
, in NeoVim it prints False
. Using import __main__
can be (and is actually used in powerline) to put some variable into global environment without requiring to specify globals()
dictionary, so that code that user needs to run to use powerline is simply
python from powerline.vim import setup as powerline_setup
python powerline_setup()
python del powerline_setup
which is simple and easy.
I'm not sure what can be done, I've tried setting the main module in the compatibility module setup:
diff --git a/runtime/autoload/provider/script_host.py b/runtime/autoload/provider/script_host.py
index 1420831..dddded8 100644
--- a/runtime/autoload/provider/script_host.py
+++ b/runtime/autoload/provider/script_host.py
@@ -37,6 +37,7 @@ class ScriptHost(object):
neovim.DecodeHook(
encoding=nvim.options['encoding'].decode('ascii')))
sys.modules['vim'] = self.legacy_vim
+ sys.modules['__main__'] = self.legacy_vim
def setup(self, nvim):
"""Setup import hooks and global streams.
but it doesn't work as expected. Do you have any ideas on how to fix this?
@tarruda ?! vim
module and __main__
are completely different things. To create needed module you may follow two paths:
- Create
*.py
file insys.path
and import it. - Use
imp.new_module('__main__')
and assign it tosys.modules
directly.
I would highly suggest to use the second variant and do two things:
- Assign newly created module to
sys.modules
. - Use
__main__.__dict__
asglobals
argument toexec
andeval
.
You already do the second thing. But you are not doing the first which is why my script fails:
diff --git a/runtime/autoload/provider/script_host.py b/runtime/autoload/provider/script_host.py
index 1420831..0abb0ae 100644
--- a/runtime/autoload/provider/script_host.py
+++ b/runtime/autoload/provider/script_host.py
@@ -28,6 +28,7 @@ class ScriptHost(object):
self.setup(nvim)
# context where all code will run
self.module = imp.new_module('__main__')
+ sys.modules['__main__'] = self.module
nvim.script_context = self.module
# it seems some plugins assume 'sys' is already imported, so do it now
exec('import sys', self.module.__dict__)
By the way, imp.new_module
is deprecated since 3.4. Thus
diff --git a/runtime/autoload/provider/script_host.py b/runtime/autoload/provider/script_host.py
index 1420831..df3906e 100644
--- a/runtime/autoload/provider/script_host.py
+++ b/runtime/autoload/provider/script_host.py
@@ -4,6 +4,8 @@ import logging
import os
import sys
+from types import ModuleType
+
import neovim
__all__ = ('ScriptHost',)
@@ -27,7 +29,8 @@ class ScriptHost(object):
"""Initialize the legacy python-vim environment."""
self.setup(nvim)
# context where all code will run
- self.module = imp.new_module('__main__')
+ self.module = ModuleType('__main__')
+ sys.modules['__main__'] = self.module
nvim.script_context = self.module
# it seems some plugins assume 'sys' is already imported, so do it now
exec('import sys', self.module.__dict__)
This works at least starting from Python-2.6.
And the whole imp
thing is deprecated as well. But new replacements for find_module
and load_module
are not that compatible.