Merge ~juergh/+git/annotations-tools:wip/lint into ~arighi/+git/annotations-tools:master

Proposed by Juerg Haefliger
Status: Merged
Approved by: Andrea Righi
Approved revision: 333af0f6ea0a395cf7e4a88c186d3fe34fdce6b3
Merged at revision: 333af0f6ea0a395cf7e4a88c186d3fe34fdce6b3
Proposed branch: ~juergh/+git/annotations-tools:wip/lint
Merge into: ~arighi/+git/annotations-tools:master
Diff against target: 288 lines (+86/-39)
4 files modified
Makefile (+7/-2)
annotations (+9/-7)
kconfig/annotations.py (+40/-30)
setup.cfg (+30/-0)
Reviewer Review Type Date Requested Status
Andrea Righi Pending
Review via email: mp+437164@code.launchpad.net

Commit message

Add pylint checks and fixes.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/Makefile b/Makefile
2index 68a710b..317440a 100644
3--- a/Makefile
4+++ b/Makefile
5@@ -1,6 +1,11 @@
6-.PHONY: all lint
7+.PHONY: all lint flake8 pylint
8
9 all: lint
10
11-lint:
12+lint: flake8 pylint
13+
14+flake8:
15 flake8 annotations .
16+
17+pylint:
18+ pylint annotations kconfig
19diff --git a/annotations b/annotations
20index 7e7ff5e..ea6bc9b 100755
21--- a/annotations
22+++ b/annotations
23@@ -8,9 +8,10 @@ sys.dont_write_bytecode = True
24 import os
25 import argparse
26 import json
27-from kconfig.annotations import Annotation, KConfig
28 from signal import signal, SIGPIPE, SIG_DFL
29
30+from kconfig.annotations import Annotation, KConfig
31+
32 VERSION = '0.1'
33
34 SKIP_CONFIGS = (
35@@ -76,7 +77,7 @@ _ARGPARSER = make_parser()
36 def arg_fail(message):
37 print(message)
38 _ARGPARSER.print_usage()
39- exit(1)
40+ sys.exit(1)
41
42
43 def print_result(config, res):
44@@ -96,7 +97,8 @@ def do_query(args):
45 def do_autocomplete(args):
46 a = Annotation(args.file)
47 res = (c.removeprefix('CONFIG_') for c in a.search_config())
48- print('complete -W "{}" annotations'.format(' '.join(res)))
49+ res_str = ' '.join(res)
50+ print(f'complete -W "{res_str}" annotations')
51
52
53 def do_source(args):
54@@ -104,7 +106,7 @@ def do_source(args):
55 arg_fail('error: --source requires --config')
56 if not os.path.exists('tags'):
57 print('tags not found in the current directory, try: `make tags`')
58- exit(1)
59+ sys.exit(1)
60 os.system(f'vim -t {args.config}')
61
62
63@@ -221,7 +223,7 @@ def do_check(args):
64 total += 1
65
66 print(f"check-config: {good}/{total} checks passed -- exit {ret}")
67- exit(ret)
68+ sys.exit(ret)
69
70
71 def autodetect_annotations(args):
72@@ -230,9 +232,9 @@ def autodetect_annotations(args):
73 # If --file/-f isn't specified try to automatically determine the right
74 # location of the annotations file looking at debian/debian.env.
75 try:
76- with open('debian/debian.env', 'rt') as fd:
77+ with open('debian/debian.env', 'rt', encoding='utf-8') as fd:
78 args.file = fd.read().rstrip().split('=')[1] + '/config/annotations'
79- except Exception:
80+ except (FileNotFoundError, IndexError):
81 arg_fail('error: could not determine DEBDIR, try using: --file/-f')
82
83
84diff --git a/kconfig/annotations.py b/kconfig/annotations.py
85index 19fb544..a1ad282 100644
86--- a/kconfig/annotations.py
87+++ b/kconfig/annotations.py
88@@ -7,21 +7,26 @@ import json
89 import re
90 import shutil
91 import tempfile
92+
93+from abc import abstractmethod
94 from ast import literal_eval
95 from os.path import dirname, abspath
96
97
98-class Config(object):
99- def __init__(self, fname: str, arch: str = None, flavour: str = None):
100+class Config():
101+ def __init__(self, fname):
102 """
103 Basic configuration file object
104 """
105 self.fname = fname
106+ self.config = {}
107+
108 raw_data = self._load(fname)
109 self._parse(raw_data)
110
111- def _load(self, fname: str) -> str:
112- with open(fname, 'rt') as fd:
113+ @staticmethod
114+ def _load(fname: str) -> str:
115+ with open(fname, 'rt', encoding='utf-8') as fd:
116 data = fd.read()
117 return data.rstrip()
118
119@@ -29,13 +34,17 @@ class Config(object):
120 """ Return a JSON representation of the config """
121 return json.dumps(self.config, indent=4)
122
123+ @abstractmethod
124+ def _parse(self, data: str):
125+ pass
126+
127
128 class KConfig(Config):
129 """
130 Parse a .config file, individual config options can be accessed via
131 .config[<CONFIG_OPTION>]
132 """
133- def _parse(self, data: str) -> dict:
134+ def _parse(self, data: str):
135 self.config = {}
136 for line in data.splitlines():
137 m = re.match(r'^# (CONFIG_.*) is not set$', line)
138@@ -107,17 +116,17 @@ class Annotation(Config):
139 raise Exception('syntax error')
140 self.config[conf] = entry
141 except Exception as e:
142- raise Exception(str(e) + f', line = {line}')
143+ raise Exception(str(e) + f', line = {line}') from e
144 continue
145
146 # Invalid line
147 raise Exception(f'invalid line: {line}')
148
149- """
150- Parse main annotations file, individual config options can be accessed via
151- self.config[<CONFIG_OPTION>]
152- """
153- def _parse(self, data: str) -> dict:
154+ def _parse(self, data: str):
155+ """
156+ Parse main annotations file, individual config options can be accessed
157+ via self.config[<CONFIG_OPTION>]
158+ """
159 self.config = {}
160 self.arch = []
161 self.flavour = []
162@@ -138,7 +147,7 @@ class Annotation(Config):
163 self.flavour = list(m.group(1).split(' '))
164 m = re.match(r'^# FLAVOUR_DEP: (.*)', line)
165 if m:
166- self.flavour_dep = eval(m.group(1))
167+ self.flavour_dep = literal_eval(m.group(1))
168 self.header += line + "\n"
169 else:
170 break
171@@ -183,12 +192,12 @@ class Annotation(Config):
172 flavour = arch
173 self.config[config]['policy'][flavour] = value
174 else:
175- for arch in self.arch:
176- self.config[config]['policy'][arch] = value
177+ for a in self.arch:
178+ self.config[config]['policy'][a] = value
179 if note is not None:
180 self.config[config]['note'] = "'" + note.replace("'", '') + "'"
181
182- def update(self, c: KConfig, arch: str, flavour: str = None, configs: list = []):
183+ def update(self, c: KConfig, arch: str, flavour: str = None, configs: list = None):
184 """ Merge configs from a Kconfig object into Annotation object """
185
186 # Determine if we need to import all configs or a single config
187@@ -260,7 +269,7 @@ class Annotation(Config):
188 for flavour in arch_flavours:
189 if flavour not in self.config[conf]['policy']:
190 break
191- elif value is None:
192+ if value is None:
193 value = self.config[conf]['policy'][flavour]
194 elif value != self.config[conf]['policy'][flavour]:
195 break
196@@ -282,7 +291,8 @@ class Annotation(Config):
197 if not self.config[conf]['policy']:
198 del self.config[conf]
199
200- def _sorted(self, config):
201+ @staticmethod
202+ def _sorted(config):
203 """ Sort configs alphabetically but return configs with a note first """
204 w_note = []
205 wo_note = []
206@@ -362,31 +372,31 @@ class Annotation(Config):
207 if config is None and arch is None:
208 # Get all config options for all architectures
209 return self.config
210- elif config is None and arch is not None:
211+ if config is None and arch is not None:
212 # Get config options of a specific architecture
213 ret = {}
214- for c in self.config:
215- if 'policy' not in self.config[c]:
216+ for c, val in self.config.items():
217+ if 'policy' not in val:
218 continue
219- if flavour in self.config[c]['policy']:
220- ret[c] = self.config[c]['policy'][flavour]
221- elif generic != flavour and generic in self.config[c]['policy']:
222- ret[c] = self.config[c]['policy'][generic]
223- elif arch in self.config[c]['policy']:
224- ret[c] = self.config[c]['policy'][arch]
225+ if flavour in val['policy']:
226+ ret[c] = val['policy'][flavour]
227+ elif generic != flavour and generic in val['policy']:
228+ ret[c] = val['policy'][generic]
229+ elif arch in val['policy']:
230+ ret[c] = val['policy'][arch]
231 return ret
232- elif config is not None and arch is None:
233+ if config is not None and arch is None:
234 # Get a specific config option for all architectures
235 return self.config[config] if config in self.config else None
236- elif config is not None and arch is not None:
237+ if config is not None and arch is not None:
238 # Get a specific config option for a specific architecture
239 if config in self.config:
240 if 'policy' in self.config[config]:
241 if flavour in self.config[config]['policy']:
242 return {config: self.config[config]['policy'][flavour]}
243- elif generic != flavour and generic in self.config[config]['policy']:
244+ if generic != flavour and generic in self.config[config]['policy']:
245 return {config: self.config[config]['policy'][generic]}
246- elif arch in self.config[config]['policy']:
247+ if arch in self.config[config]['policy']:
248 return {config: self.config[config]['policy'][arch]}
249 return None
250
251diff --git a/setup.cfg b/setup.cfg
252index 6fff888..00a726a 100644
253--- a/setup.cfg
254+++ b/setup.cfg
255@@ -3,3 +3,33 @@ max_line_length = 120
256 per-file-ignores =
257 # E402 module level import not at top of file
258 annotations: E402
259+
260+
261+[pylint.FORMAT]
262+max-line-length = 120
263+
264+[pylint]
265+# These are the default disables but for some reason we seem to loose them
266+# due to the above statement (huh?). So redefine them.
267+disable = invalid-name,
268+ missing-module-docstring,
269+ missing-class-docstring,
270+ missing-function-docstring,
271+ wrong-import-position,
272+ raw-checker-failed,
273+ bad-inline-option,
274+ locally-disabled,
275+ file-ignored,
276+ suppressed-message,
277+ useless-suppression,
278+ deprecated-pragma,
279+ use-symbolic-message-instead,
280+ too-many-instance-attributes,
281+ too-many-arguments,
282+ too-many-locals,
283+ too-many-statements,
284+ redefined-outer-name,
285+ # End of default disables
286+ too-many-branches,
287+ too-many-return-statements,
288+ too-few-public-methods

Subscribers

People subscribed via source and target branches

to all changes: