diff --git a/jedi/evaluate/context/module.py b/jedi/evaluate/context/module.py index 9a57867a..248cf322 100644 --- a/jedi/evaluate/context/module.py +++ b/jedi/evaluate/context/module.py @@ -9,6 +9,8 @@ from jedi.evaluate import compiled from jedi.evaluate.base_context import TreeContext from jedi.evaluate.names import SubModuleName from jedi.evaluate.helpers import contexts_from_qualified_names +from jedi.evaluate.compiled import create_simple_object +from jedi.evaluate.base_context import ContextSet class _ModuleAttributeName(AbstractNameDefinition): @@ -17,11 +19,16 @@ class _ModuleAttributeName(AbstractNameDefinition): """ api_type = u'instance' - def __init__(self, parent_module, string_name): + def __init__(self, parent_module, string_name, string_value=None): self.parent_context = parent_module self.string_name = string_name + self._string_value = string_value def infer(self): + if self._string_value is not None: + return ContextSet([ + create_simple_object(self.parent_context.evaluator, self._string_value) + ]) return compiled.get_string_context_set(self.parent_context.evaluator) @@ -132,9 +139,13 @@ class ModuleMixin(SubModuleDictMixin): @evaluator_method_cache() def _module_attributes_dict(self): - names = ['__file__', '__package__', '__doc__', '__name__'] + names = ['__package__', '__doc__', '__name__'] # All the additional module attributes are strings. - return dict((n, _ModuleAttributeName(self, n)) for n in names) + dct = dict((n, _ModuleAttributeName(self, n)) for n in names) + file = self.py__file__() + if file is not None: + dct['__file__'] = _ModuleAttributeName(self, '__file__', file) + return dct def iter_star_filters(self, search_global=False): for star_module in self.star_imports(): diff --git a/jedi/evaluate/filters.py b/jedi/evaluate/filters.py index be77631c..b59501f6 100644 --- a/jedi/evaluate/filters.py +++ b/jedi/evaluate/filters.py @@ -409,5 +409,4 @@ def get_global_filters(evaluator, context, until_position, origin_scope): context = context.parent_context # Add builtins to the global scope. - for filter in evaluator.builtins_module.get_filters(): - yield filter + yield next(evaluator.builtins_module.get_filters()) diff --git a/test/test_evaluate/test_context.py b/test/test_evaluate/test_context.py index bc301c09..27d83509 100644 --- a/test/test_evaluate/test_context.py +++ b/test/test_evaluate/test_context.py @@ -5,3 +5,14 @@ def test_module_attributes(Script): assert def_.column is None str_, = def_.infer() assert str_.name == 'str' + + +def test_module__file__(Script, environment): + assert not Script('__file__').goto_definitions() + def_, = Script('__file__', path='example.py').goto_definitions() + value = def_._name._context.get_safe_value() + assert value.endswith('example.py') + + def_, = Script('import antigravity; antigravity.__file__').goto_definitions() + value = def_._name._context.get_safe_value() + assert value.endswith('.py')