Coverage for C:\Repos\ekr-pylint\pylint\interfaces.py: 73%

45 statements  

« prev     ^ index     » next       coverage.py v6.4, created at 2022-05-24 10:21 -0500

1# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html 

2# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE 

3# Copyright (c) https://github.com/PyCQA/pylint/blob/main/CONTRIBUTORS.txt 

4 

5"""Interfaces for Pylint objects.""" 

6 

7from __future__ import annotations 

8 

9import warnings 

10from collections import namedtuple 

11from tokenize import TokenInfo 

12from typing import TYPE_CHECKING 

13 

14from astroid import nodes 

15 

16if TYPE_CHECKING: 

17 from pylint.checkers import BaseChecker 

18 from pylint.message import Message 

19 from pylint.reporters.ureports.nodes import Section 

20 

21__all__ = ( 

22 "IRawChecker", 

23 "IAstroidChecker", 

24 "ITokenChecker", 

25 "IReporter", 

26 "IChecker", 

27 "HIGH", 

28 "CONTROL_FLOW", 

29 "INFERENCE", 

30 "INFERENCE_FAILURE", 

31 "UNDEFINED", 

32 "CONFIDENCE_LEVELS", 

33 "CONFIDENCE_LEVEL_NAMES", 

34) 

35 

36Confidence = namedtuple("Confidence", ["name", "description"]) 

37# Warning Certainties 

38HIGH = Confidence("HIGH", "Warning that is not based on inference result.") 

39CONTROL_FLOW = Confidence( 

40 "CONTROL_FLOW", "Warning based on assumptions about control flow." 

41) 

42INFERENCE = Confidence("INFERENCE", "Warning based on inference result.") 

43INFERENCE_FAILURE = Confidence( 

44 "INFERENCE_FAILURE", "Warning based on inference with failures." 

45) 

46UNDEFINED = Confidence("UNDEFINED", "Warning without any associated confidence level.") 

47 

48CONFIDENCE_LEVELS = [HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, UNDEFINED] 

49CONFIDENCE_LEVEL_NAMES = [i.name for i in CONFIDENCE_LEVELS] 

50 

51 

52class Interface: 

53 """Base class for interfaces.""" 

54 

55 def __init__(self) -> None: 

56 warnings.warn( 

57 "Interface and all of its subclasses have been deprecated " 

58 "and will be removed in pylint 3.0.", 

59 DeprecationWarning, 

60 ) 

61 

62 @classmethod 

63 def is_implemented_by( 

64 cls: type[Interface] | tuple[type[Interface], ...], instance: BaseChecker 

65 ) -> bool: 

66 with warnings.catch_warnings(): 

67 warnings.filterwarnings("ignore", category=DeprecationWarning) 

68 return implements(instance, cls) 

69 

70 

71def implements( 

72 obj: BaseChecker, 

73 interface: type[Interface] | tuple[type[Interface], ...], 

74) -> bool: 

75 """Does the given object (maybe an instance or class) implement the interface.""" 

76 # TODO: 3.0: Remove deprecated function 

77 warnings.warn( 

78 "implements has been deprecated in favour of using basic " 

79 "inheritance patterns without using __implements__.", 

80 DeprecationWarning, 

81 ) 

82 implements_ = getattr(obj, "__implements__", ()) 

83 if not isinstance(implements_, (list, tuple)): 

84 implements_ = (implements_,) 

85 return any(issubclass(i, interface) for i in implements_) 

86 

87 

88class IChecker(Interface): 

89 """Base interface, to be used only for sub interfaces definition.""" 

90 

91 def open(self) -> None: 

92 """Called before visiting project (i.e. set of modules).""" 

93 

94 def close(self) -> None: 

95 """Called after visiting project (i.e. set of modules).""" 

96 

97 

98class IRawChecker(IChecker): 

99 """Interface for checker which need to parse the raw file.""" 

100 

101 def process_module(self, node: nodes.Module) -> None: 

102 """Process a module. 

103 

104 The module's content is accessible via ``astroid.stream`` 

105 """ 

106 

107 

108class ITokenChecker(IChecker): 

109 """Interface for checkers that need access to the token list.""" 

110 

111 def process_tokens(self, tokens: list[TokenInfo]) -> None: 

112 """Process a module. 

113 

114 Tokens is a list of all source code tokens in the file. 

115 """ 

116 

117 

118class IAstroidChecker(IChecker): 

119 """Interface for checker which prefers receive events according to 

120 statement type. 

121 """ 

122 

123 

124class IReporter(Interface): 

125 """Reporter collect messages and display results encapsulated in a layout.""" 

126 

127 def handle_message(self, msg: Message) -> None: 

128 """Handle the given message object.""" 

129 

130 def display_reports(self, layout: Section) -> None: 

131 """Display results encapsulated in the layout tree."""