Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/jedi/inference/gradual/stub_value.py: 39%

67 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-04-20 06:09 +0000

1from jedi.inference.base_value import ValueWrapper 

2from jedi.inference.value.module import ModuleValue 

3from jedi.inference.filters import ParserTreeFilter 

4from jedi.inference.names import StubName, StubModuleName 

5from jedi.inference.gradual.typing import TypingModuleFilterWrapper 

6from jedi.inference.context import ModuleContext 

7 

8 

9class StubModuleValue(ModuleValue): 

10 _module_name_class = StubModuleName 

11 

12 def __init__(self, non_stub_value_set, *args, **kwargs): 

13 super().__init__(*args, **kwargs) 

14 self.non_stub_value_set = non_stub_value_set 

15 

16 def is_stub(self): 

17 return True 

18 

19 def sub_modules_dict(self): 

20 """ 

21 We have to overwrite this, because it's possible to have stubs that 

22 don't have code for all the child modules. At the time of writing this 

23 there are for example no stubs for `json.tool`. 

24 """ 

25 names = {} 

26 for value in self.non_stub_value_set: 

27 try: 

28 method = value.sub_modules_dict 

29 except AttributeError: 

30 pass 

31 else: 

32 names.update(method()) 

33 names.update(super().sub_modules_dict()) 

34 return names 

35 

36 def _get_stub_filters(self, origin_scope): 

37 return [StubFilter( 

38 parent_context=self.as_context(), 

39 origin_scope=origin_scope 

40 )] + list(self.iter_star_filters()) 

41 

42 def get_filters(self, origin_scope=None): 

43 filters = super().get_filters(origin_scope) 

44 next(filters, None) # Ignore the first filter and replace it with our own 

45 stub_filters = self._get_stub_filters(origin_scope=origin_scope) 

46 yield from stub_filters 

47 yield from filters 

48 

49 def _as_context(self): 

50 return StubModuleContext(self) 

51 

52 

53class StubModuleContext(ModuleContext): 

54 def get_filters(self, until_position=None, origin_scope=None): 

55 # Make sure to ignore the position, because positions are not relevant 

56 # for stubs. 

57 return super().get_filters(origin_scope=origin_scope) 

58 

59 

60class TypingModuleWrapper(StubModuleValue): 

61 def get_filters(self, *args, **kwargs): 

62 filters = super().get_filters(*args, **kwargs) 

63 f = next(filters, None) 

64 assert f is not None 

65 yield TypingModuleFilterWrapper(f) 

66 yield from filters 

67 

68 def _as_context(self): 

69 return TypingModuleContext(self) 

70 

71 

72class TypingModuleContext(ModuleContext): 

73 def get_filters(self, *args, **kwargs): 

74 filters = super().get_filters(*args, **kwargs) 

75 yield TypingModuleFilterWrapper(next(filters, None)) 

76 yield from filters 

77 

78 

79class StubFilter(ParserTreeFilter): 

80 name_class = StubName 

81 

82 def _is_name_reachable(self, name): 

83 if not super()._is_name_reachable(name): 

84 return False 

85 

86 # Imports in stub files are only public if they have an "as" 

87 # export. 

88 definition = name.get_definition() 

89 if definition is None: 

90 return False 

91 if definition.type in ('import_from', 'import_name'): 

92 if name.parent.type not in ('import_as_name', 'dotted_as_name'): 

93 return False 

94 n = name.value 

95 # TODO rewrite direct return 

96 if n.startswith('_') and not (n.startswith('__') and n.endswith('__')): 

97 return False 

98 return True 

99 

100 

101class VersionInfo(ValueWrapper): 

102 pass