1 """ 2 TODO Some parts of this module are still not well documented. 3 """ 4 5 from jedi.inference import compiled 6 from jedi.inference.base_value import ValueSet 7 from jedi.inference.filters import ParserTreeFilter, MergedFilter 8 from jedi.inference.names import TreeNameDefinition 9 from jedi.inference.compiled import mixed 10 from jedi.inference.compiled.access import create_access_path 11 from jedi.inference.context import ModuleContext 12 13 14 def _create(inference_state, obj): 15 return compiled.create_from_access_path( 16 inference_state, create_access_path(inference_state, obj) 17 ) 18 19 20 class NamespaceObject: 21 def __init__(self, dct): 22 self.__dict__ = dct 23 24 25 class MixedTreeName(TreeNameDefinition): 26 def infer(self): 27 """ 28 In IPython notebook it is typical that some parts of the code that is 29 provided was already executed. In that case if something is not properly 30 inferred, it should still infer from the variables it already knows. 31 """ 32 inferred = super().infer() 33 if not inferred: 34 for compiled_value in self.parent_context.mixed_values: 35 for f in compiled_value.get_filters(): 36 values = ValueSet.from_sets( 37 n.infer() for n in f.get(self.string_name) 38 ) 39 if values: 40 return values 41 return inferred 42 43 44 class MixedParserTreeFilter(ParserTreeFilter): 45 name_class = MixedTreeName 46 47 48 class MixedModuleContext(ModuleContext): 49 def __init__(self, tree_module_value, namespaces): 50 super().__init__(tree_module_value) 51 self.mixed_values = [ 52 self._get_mixed_object( 53 _create(self.inference_state, NamespaceObject(n)) 54 ) for n in namespaces 55 ] 56 57 def _get_mixed_object(self, compiled_value): 58 return mixed.MixedObject( 59 compiled_value=compiled_value, 60 tree_value=self._value 61 ) 62 63 def get_filters(self, until_position=None, origin_scope=None): 64 yield MergedFilter( 65 MixedParserTreeFilter( 66 parent_context=self, 67 until_position=until_position, 68 origin_scope=origin_scope 69 ), 70 self.get_global_filter(), 71 ) 72 73 for mixed_object in self.mixed_values: 74 yield from mixed_object.get_filters(until_position, origin_scope) 75