diff --git a/jedi/api/classes.py b/jedi/api/classes.py index fba9b5ad..ee741c33 100644 --- a/jedi/api/classes.py +++ b/jedi/api/classes.py @@ -27,7 +27,7 @@ from jedi.inference.compiled.mixed import MixedName from jedi.inference.names import ImportName, SubModuleName from jedi.inference.gradual.stub_value import StubModuleValue from jedi.inference.gradual.conversion import convert_names, convert_values -from jedi.inference.base_value import ValueSet +from jedi.inference.base_value import ValueSet, HasNoContext from jedi.api.keywords import KeywordName from jedi.api import completion_cache from jedi.api.helpers import filter_follow_imports @@ -37,13 +37,17 @@ def _sort_names_by_start_pos(names): return sorted(names, key=lambda s: s.start_pos or (0, 0)) -def defined_names(inference_state, context): +def defined_names(inference_state, value): """ List sub-definitions (e.g., methods in class). :type scope: Scope :rtype: list of Name """ + try: + context = value.as_context() + except HasNoContext: + return [] filter = next(context.get_filters()) names = [name for name in filter.values()] return [Name(inference_state, n) for n in _sort_names_by_start_pos(names)] @@ -759,7 +763,7 @@ class Name(BaseName): """ defs = self._name.infer() return sorted( - unite(defined_names(self._inference_state, d.as_context()) for d in defs), + unite(defined_names(self._inference_state, d) for d in defs), key=lambda s: s._name.start_pos or (0, 0) ) diff --git a/jedi/inference/base_value.py b/jedi/inference/base_value.py index e51e063c..31b72937 100644 --- a/jedi/inference/base_value.py +++ b/jedi/inference/base_value.py @@ -22,6 +22,10 @@ from jedi.cache import memoize_method sentinel = object() +class HasNoContext(Exception): + pass + + class HelperValueMixin: def get_root_context(self): value = self @@ -261,7 +265,7 @@ class Value(HelperValueMixin): return self.parent_context.is_stub() def _as_context(self): - raise NotImplementedError('Not all values need to be converted to contexts: %s', self) + raise HasNoContext @property def name(self): diff --git a/test/test_api/test_names.py b/test/test_api/test_names.py index d43a29bb..287a301e 100644 --- a/test/test_api/test_names.py +++ b/test/test_api/test_names.py @@ -189,3 +189,9 @@ def test_no_error(get_names): def test_is_side_effect(get_names, code, index, is_side_effect): names = get_names(code, references=True, all_scopes=True) assert names[index].is_side_effect() == is_side_effect + + +def test_no_defined_names(get_names): + definition, = get_names("x = (1, 2)") + + assert not definition.defined_names()