Publishing 2019 R1 content
[platform/upstream/dldt.git] / tools / accuracy_checker / pylint_checkers.py
1 """
2 Copyright (c) 2019 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 """
16
17 import astroid
18 from pylint.checkers import BaseChecker
19 from pylint.interfaces import IAstroidChecker, IRawChecker
20
21
22 class BackslashChecker(BaseChecker):
23     """
24     Checks for line continuations with '\' instead of using triple quoted string or parenthesis.
25     """
26
27     __implements__ = IRawChecker
28
29     name = 'backslash'
30     msgs = {
31         'W9901': (
32             'use of \\ for line continuation', 'backslash-line-continuation',
33             'Used when a \\ is used for a line continuation instead of using triple quoted string or parenthesis.'
34         ),
35     }
36     options = ()
37
38     def process_module(self, node):
39         with node.stream() as stream:
40             for (line_number, line) in enumerate(stream):
41                 if not line.decode().rstrip().endswith('\\'):
42                     continue
43
44                 self.add_message('backslash-line-continuation', line=line_number)
45
46
47 class AbsoluteImportsChecker(BaseChecker):
48     """
49     Check for absolute import from the same package.
50     """
51
52     __implements__ = IAstroidChecker
53
54     name = 'absolute-imports'
55     priority = -1
56     msgs = {
57         'W9902': (
58             'absolute import from same package', 'package-absolute-imports',
59             'Used when module of same package imported using absolute import'
60         )
61     }
62
63     def visit_importfrom(self, node):
64         node_package = self._node_package(node)
65         import_name = node.modname
66         if import_name.startswith(node_package):
67             self.add_message('package-absolute-imports', node=node)
68
69     @staticmethod
70     def _node_package(node):
71         return node.scope().name.split('.')[0]
72
73
74 class StringFormatChecker(BaseChecker):
75     """
76     Check for absolute import from the same package.
77     """
78
79     __implements__ = IAstroidChecker
80
81     name = 'string-format'
82     priority = -1
83     msgs = {
84         'W9903': (
85             'use of "%" for string formatting', 'deprecated-string-format',
86             '"%" operator is used for string formatting instead of str.format method'
87         )
88     }
89
90     def visit_binop(self, node):
91         if node.op != '%':
92             return
93
94         left = node.left
95         if not (isinstance(left, astroid.Const) and isinstance(left.value, str)):
96             return
97
98         self.add_message('deprecated-string-format', node=node)
99
100
101 class BadFunctionChecker(BaseChecker):
102     """
103     Check for absolute import from the same package.
104     """
105
106     __implements__ = IAstroidChecker
107
108     name = 'bad-function'
109     priority = -1
110     msgs = {'W9904': ('using prohibited function', 'bad-function-call', '')}
111
112     options = (
113         (
114             'bad-functions',
115             {
116                 'default': '',
117                 'help': 'List of prohibited functions',
118             },
119         ),
120     )
121
122     def visit_call(self, node):
123         bad_functions = set(f.strip() for f in self.config.bad_functions.split(','))
124         if self._function_name(node) in bad_functions:
125             self.add_message('bad-function-call', node=node)
126
127     @staticmethod
128     def _function_name(node):
129         func = node.func
130         if hasattr(func, 'attrname'):
131             return func.attrname
132         elif hasattr(func, 'name'):
133             return func.name
134
135
136 def register(linter):
137     """
138     Required method to auto register this checker.
139     """
140
141     linter.register_checker(BackslashChecker(linter))
142     linter.register_checker(AbsoluteImportsChecker(linter))
143     linter.register_checker(StringFormatChecker(linter))
144     linter.register_checker(BadFunctionChecker(linter))