[gnome-builder: 1/4] change jedi patching so that it works for completion even if patching not possible
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder: 1/4] change jedi patching so that it works for completion even if patching not possible
- Date: Mon, 3 Feb 2020 18:05:19 +0000 (UTC)
commit 465d853cd006efc5a86109f28eece58466bce130
Author: Sagar Chalise <chalisesagar gmail com>
Date: Sun Jan 26 11:52:22 2020 +0545
change jedi patching so that it works for completion even if patching not possible
src/plugins/jedi/jedi_plugin.py | 241 +++++++++++++++++++++-------------------
1 file changed, 126 insertions(+), 115 deletions(-)
---
diff --git a/src/plugins/jedi/jedi_plugin.py b/src/plugins/jedi/jedi_plugin.py
index 119832e88..a01da9835 100644
--- a/src/plugins/jedi/jedi_plugin.py
+++ b/src/plugins/jedi/jedi_plugin.py
@@ -89,127 +89,136 @@ def return_error(task, error):
#print(repr(error))
task.return_error(GLib.Error(message=repr(error)))
-try:
- import jedi
- from jedi.evaluate.compiled import CompiledObject
- from jedi.evaluate.compiled import get_special_object
+def patch_jedi():
try:
- # 0.12
- from jedi.evaluate.compiled import create_from_name
- from jedi.evaluate.base_context import Context
- except ImportError:
- # Pre 0.12
- from jedi.evaluate.compiled import _create_from_name as create_from_name
- from jedi.evaluate.context import Context
- from jedi.evaluate.docstrings import _evaluate_for_statement_string
- from jedi.evaluate.imports import Importer
-
- class PatchedJediCompiledObject(CompiledObject):
- "A modified version of Jedi CompiledObject to work with GObject Introspection modules"
-
- def __init__(self, evaluator, obj, parent_context=None, faked_class=None):
- # we have to override __init__ to change super(CompiledObject, self)
- # to Context, in order to prevent an infinite recursion
- Context.__init__(self, evaluator, parent_context)
- self.obj = obj
- self.tree_node = faked_class
-
- def _cls(self):
- if self.obj.__class__ == IntrospectionModule:
- return self
- else:
- return super()._cls(self)
-
- @property
- def py__call__(self):
- def actual(params):
- # Parse the docstring to find the return type:
- ret_type = ''
- if '->' in self.obj.__doc__:
- ret_type = self.obj.__doc__.split('->')[1].strip()
- ret_type = ret_type.replace(' or None', '')
- if ret_type.startswith('iter:'):
- ret_type = ret_type[len('iter:'):] # we don't care if it's an iterator
-
- if hasattr(__builtins__, ret_type):
- # The function we're inspecting returns a builtin python type, that's easy
- # (see test/test_evaluate/test_compiled.py in the jedi source code for usage)
- builtins = get_special_object(self.evaluator, 'BUILTINS')
- builtin_obj = builtins.py__getattribute__(ret_type)
- obj = _create_from_name(self.evaluator, builtins, builtin_obj, "")
- return self.evaluator.execute(obj, params)
+ from jedi.evaluate.compiled import CompiledObject
+ from jedi.evaluate.compiled import get_special_object
+ try:
+ # 0.12
+ from jedi.evaluate.compiled import create_from_name
+ from jedi.evaluate.base_context import Context
+ except ImportError:
+ # Pre 0.12
+ from jedi.evaluate.compiled import _create_from_name as create_from_name
+ from jedi.evaluate.context import Context
+ from jedi.evaluate.docstrings import _evaluate_for_statement_string
+ from jedi.evaluate.imports import Importer
+
+ class PatchedJediCompiledObject(CompiledObject):
+ "A modified version of Jedi CompiledObject to work with GObject Introspection modules"
+
+ def __init__(self, evaluator, obj, parent_context=None, faked_class=None):
+ # we have to override __init__ to change super(CompiledObject, self)
+ # to Context, in order to prevent an infinite recursion
+ Context.__init__(self, evaluator, parent_context)
+ self.obj = obj
+ self.tree_node = faked_class
+
+ def _cls(self):
+ if self.obj.__class__ == IntrospectionModule:
+ return self
else:
- # The function we're inspecting returns a GObject type
- parent = self.parent_context.obj.__name__
- if parent.startswith('gi.repository'):
- parent = parent[len('gi.repository.'):]
- else:
- # a module with overrides, such as Gtk, behaves differently
- parent_module = self.parent_context.obj.__module__
- if parent_module.startswith('gi.overrides'):
- parent_module = parent_module[len('gi.overrides.'):]
- parent = '%s.%s' % (parent_module, parent)
-
- if ret_type.startswith(parent):
- # A pygobject type in the same module
- ret_type = ret_type[len(parent):]
+ return super()._cls(self)
+
+ @property
+ def py__call__(self):
+ def actual(params):
+ # Parse the docstring to find the return type:
+ ret_type = ''
+ if '->' in self.obj.__doc__:
+ ret_type = self.obj.__doc__.split('->')[1].strip()
+ ret_type = ret_type.replace(' or None', '')
+ if ret_type.startswith('iter:'):
+ ret_type = ret_type[len('iter:'):] # we don't care if it's an iterator
+
+ if hasattr(__builtins__, ret_type):
+ # The function we're inspecting returns a builtin python type, that's easy
+ # (see test/test_evaluate/test_compiled.py in the jedi source code for usage)
+ builtins = get_special_object(self.evaluator, 'BUILTINS')
+ builtin_obj = builtins.py__getattribute__(ret_type)
+ obj = _create_from_name(self.evaluator, builtins, builtin_obj, "")
+ return self.evaluator.execute(obj, params)
else:
- # A pygobject type in a different module
- return_type_parent = ret_type.split('.', 1)[0]
- ret_type = 'from gi.repository import %s\n%s' % (return_type_parent, ret_type)
- result = _evaluate_for_statement_string(self.parent_context, ret_type)
- return set(result)
- if type(self.obj) == FunctionInfo:
- return actual
- return super().py__call__
-
- # we need to override CompiledBoundMethod without changing it much,
- # just so it'll not get confused due to our overriden CompiledObject
- class PatchedCompiledBoundMethod(PatchedJediCompiledObject):
- def __init__(self, func):
- super().__init__(func.evaluator, func.obj, func.parent_context, func.tree_node)
-
- class PatchedJediImporter(Importer):
- "A modified version of Jedi Importer to work with GObject Introspection modules"
- def follow(self):
- module_list = super().follow()
- if not module_list:
- import_path = '.'.join([str(i) for i in self.import_path])
- if import_path.startswith('gi.repository'):
- try:
- module = gi_importer.load_module(import_path)
- module_list = [PatchedJediCompiledObject(self._evaluator, module)]
- except ImportError:
- pass
- return module_list
-
- try:
- # Pre 0.12 workaround
- # TODO: What needs to be fixed here for 0.12?
- original_jedi_get_module = jedi.evaluate.compiled.fake.get_module
- def patched_jedi_get_module(obj):
- "Work around a weird bug in jedi"
- try:
- return original_jedi_get_module(obj)
- except ImportError as e:
- if e.msg == "No module named 'gi._gobject._gobject'":
- return original_jedi_get_module('gi._gobject')
- jedi.evaluate.compiled.fake.get_module = patched_jedi_get_module
- except:
- pass
+ # The function we're inspecting returns a GObject type
+ parent = self.parent_context.obj.__name__
+ if parent.startswith('gi.repository'):
+ parent = parent[len('gi.repository.'):]
+ else:
+ # a module with overrides, such as Gtk, behaves differently
+ parent_module = self.parent_context.obj.__module__
+ if parent_module.startswith('gi.overrides'):
+ parent_module = parent_module[len('gi.overrides.'):]
+ parent = '%s.%s' % (parent_module, parent)
+
+ if ret_type.startswith(parent):
+ # A pygobject type in the same module
+ ret_type = ret_type[len(parent):]
+ else:
+ # A pygobject type in a different module
+ return_type_parent = ret_type.split('.', 1)[0]
+ ret_type = 'from gi.repository import %s\n%s' % (return_type_parent, ret_type)
+ result = _evaluate_for_statement_string(self.parent_context, ret_type)
+ return set(result)
+ if type(self.obj) == FunctionInfo:
+ return actual
+ return super().py__call__
+
+ # we need to override CompiledBoundMethod without changing it much,
+ # just so it'll not get confused due to our overriden CompiledObject
+ class PatchedCompiledBoundMethod(PatchedJediCompiledObject):
+ def __init__(self, func):
+ super().__init__(func.evaluator, func.obj, func.parent_context, func.tree_node)
+
+ class PatchedJediImporter(Importer):
+ "A modified version of Jedi Importer to work with GObject Introspection modules"
+ def follow(self):
+ module_list = super().follow()
+ if not module_list:
+ import_path = '.'.join([str(i) for i in self.import_path])
+ if import_path.startswith('gi.repository'):
+ try:
+ module = gi_importer.load_module(import_path)
+ module_list = [PatchedJediCompiledObject(self._evaluator, module)]
+ except ImportError:
+ pass
+ return module_list
+
+ try:
+ # Pre 0.12 workaround
+ # TODO: What needs to be fixed here for 0.12?
+ original_jedi_get_module = jedi.evaluate.compiled.fake.get_module
+ def patched_jedi_get_module(obj):
+ "Work around a weird bug in jedi"
+ try:
+ return original_jedi_get_module(obj)
+ except ImportError as e:
+ if e.msg == "No module named 'gi._gobject._gobject'":
+ return original_jedi_get_module('gi._gobject')
+ jedi.evaluate.compiled.fake.get_module = patched_jedi_get_module
+ except:
+ pass
+
+ jedi.evaluate.compiled.CompiledObject = PatchedJediCompiledObject
+ try:
+ jedi.evaluate.instance.CompiledBoundMethod = PatchedCompiledBoundMethod
+ except AttributeError:
+ jedi.evaluate.context.instance.CompiledBoundMethod = PatchedCompiledBoundMethod
+ jedi.evaluate.imports.Importer = PatchedJediImporter
+ return True
+ except ImportError as ex:
+ print("jedi patching not possible. GI completion may not work.")
+ print(ex)
+ return False
- jedi.evaluate.compiled.CompiledObject = PatchedJediCompiledObject
- try:
- jedi.evaluate.instance.CompiledBoundMethod = PatchedCompiledBoundMethod
- except AttributeError:
- jedi.evaluate.context.instance.CompiledBoundMethod = PatchedCompiledBoundMethod
- jedi.evaluate.imports.Importer = PatchedJediImporter
- HAS_JEDI = True
-except ImportError as ex:
+try:
+ import jedi
+except ImportError:
print("jedi not found, python auto-completion not possible.")
- print(ex)
+ IS_JEDI_PATCHED = False
HAS_JEDI = False
-
+else:
+ HAS_JEDI = True
+ IS_JEDI_PATCHED = patch_jedi()
GIR_PATH_LIST = []
def init_gir_path_list():
@@ -543,6 +552,8 @@ class JediCompletionRequest:
def get_gi_obj(info):
""" Get a GObject Introspection object from a jedi Completion, or None if the completion is not
GObject Introspection related """
+ if not IS_JEDI_PATCHED:
+ return None
if (type(info._module) == PatchedJediCompiledObject and
info._module.obj.__class__ == IntrospectionModule):
return next(info._name.infer()).obj
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]