Remove classes from plugins and use decorators instead

This commit is contained in:
Dave Halter
2019-07-16 10:23:19 +02:00
parent 60415033b4
commit 8329e2e969
5 changed files with 69 additions and 94 deletions

View File

@@ -121,7 +121,7 @@ class Evaluator(object):
# Plugin API
from jedi.plugins import plugin_manager
plugin_callbacks = plugin_manager.get_callbacks(self)
plugin_callbacks = plugin_manager.get_callbacks()
self.execute = plugin_callbacks.decorate('execute', callback=_execute)
self._import_module = partial(
plugin_callbacks.decorate(

View File

@@ -1,5 +1,5 @@
from jedi.plugins.stdlib import StdlibPlugin
from jedi.plugins.flask import FlaskPlugin
from jedi.plugins import stdlib
from jedi.plugins import flask
class _PluginManager(object):
@@ -12,12 +12,12 @@ class _PluginManager(object):
"""
self._registered_plugins.append(plugin_class)
def _build_chain(self, evaluator):
def _build_chain(self):
for plugin_class in self._registered_plugin_classes:
yield plugin_class(evaluator)
yield plugin_class
def get_callbacks(self, evaluator):
return _PluginCallbacks(self._build_chain(evaluator))
def get_callbacks(self):
return _PluginCallbacks(self._build_chain())
class _PluginCallbacks(object):
@@ -27,11 +27,13 @@ class _PluginCallbacks(object):
def decorate(self, name, callback):
for plugin in reversed(self._plugins):
# Need to reverse so the first plugin is run first.
callback = getattr(plugin, name)(callback)
try:
func = getattr(plugin, name)
except AttributeError:
pass
else:
callback = func(callback)
return callback
plugin_manager = _PluginManager([
StdlibPlugin,
FlaskPlugin,
])
plugin_manager = _PluginManager([stdlib, flask])

View File

@@ -1,21 +0,0 @@
class BasePlugin(object):
"""
Plugins are created each time an evaluator is created.
"""
def __init__(self, evaluator):
# In __init__ you can do some caching.
self._evaluator = evaluator
def execute(self, callback):
"""
Decorates the execute(context, arguments) function.
"""
return callback
def import_module(self, callback):
"""
Decorates the
import_module(evaluator, import_path, sys_path, add_error_callback)
function.
"""
return callback

View File

@@ -1,25 +1,21 @@
from jedi.plugins.base import BasePlugin
class FlaskPlugin(BasePlugin):
def import_module(self, callback):
"""
Handle "magic" Flask extension imports:
``flask.ext.foo`` is really ``flask_foo`` or ``flaskext.foo``.
"""
def wrapper(evaluator, import_names, module_context, *args, **kwargs):
if len(import_names) == 3 and import_names[:2] == ('flask', 'ext'):
# New style.
ipath = (u'flask_' + import_names[2]),
context_set = callback(evaluator, ipath, None, *args, **kwargs)
if context_set:
return context_set
context_set = callback(evaluator, (u'flaskext',), None, *args, **kwargs)
return callback(
evaluator,
(u'flaskext', import_names[2]),
next(iter(context_set)),
*args, **kwargs
)
return callback(evaluator, import_names, module_context, *args, **kwargs)
return wrapper
def import_module(callback):
"""
Handle "magic" Flask extension imports:
``flask.ext.foo`` is really ``flask_foo`` or ``flaskext.foo``.
"""
def wrapper(evaluator, import_names, module_context, *args, **kwargs):
if len(import_names) == 3 and import_names[:2] == ('flask', 'ext'):
# New style.
ipath = (u'flask_' + import_names[2]),
context_set = callback(evaluator, ipath, None, *args, **kwargs)
if context_set:
return context_set
context_set = callback(evaluator, (u'flaskext',), None, *args, **kwargs)
return callback(
evaluator,
(u'flaskext', import_names[2]),
next(iter(context_set)),
*args, **kwargs
)
return callback(evaluator, import_names, module_context, *args, **kwargs)
return wrapper

View File

@@ -12,7 +12,6 @@ compiled module that returns the types for C-builtins.
import parso
from jedi._compatibility import force_unicode
from jedi.plugins.base import BasePlugin
from jedi import debug
from jedi.evaluate.helpers import get_str_or_none
from jedi.evaluate.arguments import ValuesArguments, \
@@ -98,45 +97,44 @@ _NAMEDTUPLE_FIELD_TEMPLATE = '''\
'''
class StdlibPlugin(BasePlugin):
def execute(self, callback):
def wrapper(context, arguments):
def execute(callback):
def wrapper(context, arguments):
try:
obj_name = context.name.string_name
except AttributeError:
pass
else:
if context.parent_context == context.evaluator.builtins_module:
module_name = 'builtins'
elif context.parent_context is not None and context.parent_context.is_module():
module_name = context.parent_context.py__name__()
else:
return callback(context, arguments=arguments)
if isinstance(context, BoundMethod):
if module_name == 'builtins':
if context.py__name__() == '__get__':
if context.class_context.py__name__() == 'property':
return builtins_property(
context,
arguments=arguments
)
elif context.py__name__() in ('deleter', 'getter', 'setter'):
if context.class_context.py__name__() == 'property':
return ContextSet([context.instance])
return callback(context, arguments=arguments)
# for now we just support builtin functions.
try:
obj_name = context.name.string_name
except AttributeError:
func = _implemented[module_name][obj_name]
except KeyError:
pass
else:
if context.parent_context == self._evaluator.builtins_module:
module_name = 'builtins'
elif context.parent_context is not None and context.parent_context.is_module():
module_name = context.parent_context.py__name__()
else:
return callback(context, arguments=arguments)
return func(context, arguments=arguments)
return callback(context, arguments=arguments)
if isinstance(context, BoundMethod):
if module_name == 'builtins':
if context.py__name__() == '__get__':
if context.class_context.py__name__() == 'property':
return builtins_property(
context,
arguments=arguments
)
elif context.py__name__() in ('deleter', 'getter', 'setter'):
if context.class_context.py__name__() == 'property':
return ContextSet([context.instance])
return callback(context, arguments=arguments)
# for now we just support builtin functions.
try:
func = _implemented[module_name][obj_name]
except KeyError:
pass
else:
return func(context, arguments=arguments)
return callback(context, arguments=arguments)
return wrapper
return wrapper
def _follow_param(evaluator, arguments, index):