1 from pathlib import Path 2 from typing import Optional 3 4 from jedi.inference.cache import inference_state_method_cache 5 from jedi.inference.filters import DictFilter 6 from jedi.inference.names import ValueNameMixin, AbstractNameDefinition 7 from jedi.inference.base_value import Value 8 from jedi.inference.value.module import SubModuleDictMixin 9 from jedi.inference.context import NamespaceContext 10 11 12 class ImplicitNSName(ValueNameMixin, AbstractNameDefinition): 13 """ 14 Accessing names for implicit namespace packages should infer to nothing. 15 This object will prevent Jedi from raising exceptions 16 """ 17 def __init__(self, implicit_ns_value, string_name): 18 self._value = implicit_ns_value 19 self.string_name = string_name 20 21 22 class ImplicitNamespaceValue(Value, SubModuleDictMixin): 23 """ 24 Provides support for implicit namespace packages 25 """ 26 api_type = 'namespace' 27 parent_context = None 28 29 def __init__(self, inference_state, string_names, paths): 30 super().__init__(inference_state, parent_context=None) 31 self.inference_state = inference_state 32 self.string_names = string_names 33 self._paths = paths 34 35 def get_filters(self, origin_scope=None): 36 yield DictFilter(self.sub_modules_dict()) 37 38 def get_qualified_names(self): 39 return () 40 41 @property # type: ignore[misc] 42 @inference_state_method_cache() 43 def name(self): 44 string_name = self.py__package__()[-1] 45 return ImplicitNSName(self, string_name) 46 47 def py__file__(self) -> Optional[Path]: 48 return None 49 50 def py__package__(self): 51 """Return the fullname 52 """ 53 return self.string_names 54 55 def py__path__(self): 56 return self._paths 57 58 def py__name__(self): 59 return '.'.join(self.string_names) 60 61 def is_namespace(self): 62 return True 63 64 def is_stub(self): 65 return False 66 67 def is_package(self): 68 return True 69 70 def as_context(self): 71 return NamespaceContext(self) 72 73 def __repr__(self): 74 return '<%s: %s>' % (self.__class__.__name__, self.py__name__()) 75