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

#150 Refactoring. Implemented pluggable providers for type hinting. #187

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions rope/base/default_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ def set_prefs(prefs):
# after normal imports.
prefs['sort_imports_alphabetically'] = False

# Location of implementation of rope.base.oi.type_hinting.interfaces.ITypeHintingFactory
# In general case, you don't have to change this value, unless you're an rope expert.
# Change this value to inject you own implementations of interfaces
# listed in module rope.base.oi.type_hinting.providers.interfaces
# For example, you can add you own providers for Django Models, or disable the search
# type-hinting in a class hierarchy, etc.
prefs['type_hinting_factory'] = 'rope.base.oi.type_hinting.factory.default_type_hinting_factory'


def project_opened(project):
"""This function is called after opening the project"""
Expand Down
226 changes: 0 additions & 226 deletions rope/base/oi/docstrings.py

This file was deleted.

8 changes: 6 additions & 2 deletions rope/base/oi/soi.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import rope.base.pynames
import rope.base.pyobjects
from rope.base import evaluate, utils, arguments
from rope.base.oi.docstrings import hint_return, hint_param, hint_attr, hint_pep0484
from rope.base.oi.type_hinting.factory import get_type_hinting_factory


_ignore_inferred = utils.ignore_exception(
Expand All @@ -32,6 +32,7 @@ def infer_returned_object(pyfunction, args):
result = object_info.get_returned(pyfunction, args)
if result is not None:
return result
hint_return = get_type_hinting_factory(pyfunction.pycore.project).make_return_provider()
type_ = hint_return(pyfunction)
if type_ is not None:
return rope.base.pyobjects.PyObject(type_)
Expand Down Expand Up @@ -75,7 +76,8 @@ def infer_assigned_object(pyname):
elif result is not None:
return result

hinting_result = hint_pep0484(pyname)
hint_assignment = get_type_hinting_factory(pyname.module.pycore.project).make_assignment_provider()
hinting_result = hint_assignment(pyname)
if hinting_result is not None:
return hinting_result

Expand All @@ -97,6 +99,7 @@ def _infer_assigned_object_by_hint(pyname):
pyclass = pyobject.parent
else:
return
hint_attr = get_type_hinting_factory(pyname.module.pycore.project).make_attr_provider()
for name, attr in pyclass.get_attributes().items():
if attr is pyname:
type_ = hint_attr(pyclass, name)
Expand Down Expand Up @@ -147,6 +150,7 @@ def _infer_returned(pyobject, args):
def _parameter_objects(pyobject):
result = []
params = pyobject.get_param_names(special_args=False)
hint_param = get_type_hinting_factory(pyobject.pycore.project).make_param_provider()
for name in params:
type_ = hint_param(pyobject, name)
if type_ is not None:
Expand Down
Empty file.
58 changes: 58 additions & 0 deletions rope/base/oi/type_hinting/factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from rope.base.oi.type_hinting import interfaces
from rope.base.oi.type_hinting.providers import (
composite, inheritance, docstrings, numpydocstrings, pep0484_type_comments
)
from rope.base import utils


class TypeHintingFactory(interfaces.ITypeHintingFactory):

@utils.saveit
def make_param_provider(self):
providers = [
docstrings.ParamProvider(docstrings.DocstringParamParser()),
docstrings.ParamProvider(numpydocstrings.NumPyDocstringParamParser()),
]
return inheritance.ParamProvider(composite.ParamProvider(*providers))

@utils.saveit
def make_attr_provider(self):
providers = [
docstrings.AttrProvider(docstrings.DocstringParamParser()),
docstrings.AttrProvider(numpydocstrings.NumPyDocstringParamParser()),
]
return inheritance.AttrProvider(composite.AttrProvider(*providers))

@utils.saveit
def make_return_provider(self):
return inheritance.ReturnProvider(docstrings.ReturnProvider(docstrings.DocstringReturnParser()))

@utils.saveit
def make_assignment_provider(self):
return pep0484_type_comments.AssignmentProvider()

default_type_hinting_factory = TypeHintingFactory()


class TypeHintingFactoryAccessor(object):

def __call__(self, project):
"""
:type project: rope.base.project.Project
:rtype: rope.base.oi.type_hinting.interfaces.ITypeHintingFactory
"""
factory_location = project.get_prefs().get(
'type_hinting_factory',
'rope.base.oi.type_hinting.factory.default_type_hinting_factory'
)
return self._get_factory(factory_location)

@utils.cached(10)
def _get_factory(self, factory_location):
"""
:type factory_location: str
:rtype: rope.base.oi.type_hinting.interfaces.ITypeHintingFactory
"""
return utils.resolve(factory_location)

get_type_hinting_factory = TypeHintingFactoryAccessor()
21 changes: 21 additions & 0 deletions rope/base/oi/type_hinting/interfaces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class ITypeHintingFactory(object):

def make_param_provider(self):
"""
:rtype: rope.base.oi.type_hinting.providers.interfaces.IParamProvider
"""

def make_attr_provider(self):
"""
:rtype: rope.base.oi.type_hinting.providers.interfaces.IAttrProvider
"""

def make_return_provider(self):
"""
:rtype: rope.base.oi.type_hinting.providers.interfaces.IReturnProvider
"""

def make_assignment_provider(self):
"""
:rtype: rope.base.oi.type_hinting.providers.interfaces.IAssignmentProvider
"""
Empty file.
Loading