Merge ~powersj/cloud-init:enable-pylint into cloud-init:master

Proposed by Joshua Powers
Status: Merged
Merged at revision: 35cf3415f9748c880db4d3c004f3410c3aa2cab2
Proposed branch: ~powersj/cloud-init:enable-pylint
Merge into: cloud-init:master
Diff against target: 160 lines (+56/-9)
7 files modified
.pylintrc (+39/-0)
cloudinit/net/network_state.py (+3/-2)
cloudinit/sources/DataSourceAltCloud.py (+1/-2)
cloudinit/sources/DataSourceOpenNebula.py (+2/-2)
cloudinit/sources/__init__.py (+1/-1)
cloudinit/url_helper.py (+1/-1)
tox.ini (+9/-1)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Approve
cloud-init Commiters Pending
Review via email: mp+320560@code.launchpad.net

Commit message

test: enable pylint support in tox

Description of the change

Why enable pylint?
pylint has the ability to catch errors that pyflakes/flake8 simply wont. pylint sets the bar higher for what can get accepted in terms of quality.

This set of commits enables pylint to run without errors. This does not add it to the list of tests when running tox as I think that is something up for discussion. Please review the configuration and the changes to the code.

There are a number of legit errors that I have updated the code to avoid those errors. However, there are two places where a variable was changes from being instantiated as None to {}. This is due to pylint stating how a None object cannot be check for in (e.g. 'my_key' in variable, if variable is None). I really, really do not want to be breaking some existing infrastructure.

pylint output:
https://paste.ubuntu.com/24224371/

tox clean:
https://paste.ubuntu.com/24224366/

Integration test using Xenial:
https://paste.ubuntu.com/24224456/

To post a comment you must log in.
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)

There was an error fetching revisions from git servers. Please try again in a few minutes. If the problem persists, contact Launchpad support.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.pylintrc b/.pylintrc
2new file mode 100644
3index 0000000..783c1bb
4--- /dev/null
5+++ b/.pylintrc
6@@ -0,0 +1,39 @@
7+[MASTER]
8+
9+# --go-faster, use multiple processes to speed up Pylint
10+jobs=4
11+
12+
13+[MESSAGES CONTROL]
14+
15+# Errors only
16+disable=C, F, I, R, W
17+
18+
19+[REPORTS]
20+
21+# Set the output format. Available formats are text, parseable, colorized, msvs
22+output-format=colorized
23+
24+# Just the errors please, no full report
25+reports=no
26+
27+
28+[TYPECHECK]
29+
30+# List of module names for which member attributes should not be checked
31+# (useful for modules/projects where namespaces are manipulated during runtime
32+# and thus existing member attributes cannot be deduced by static analysis. It
33+# supports qualified module names, as well as Unix pattern matching.
34+ignored-modules=six.moves,pkg_resources
35+
36+# List of class names for which member attributes should not be checked (useful
37+# for classes with dynamically set attributes). This supports the use of
38+# qualified names.
39+ignored-classes=optparse.Values,thread._local,_thread._local,Renderer
40+
41+# List of members which are set dynamically and missed by pylint inference
42+# system, and so shouldn't trigger E1101 when accessed. Python regular
43+# expressions are accepted.
44+generated-members=types,http.client,command_handlers
45+
46diff --git a/cloudinit/net/network_state.py b/cloudinit/net/network_state.py
47index 701aaa4..692b600 100644
48--- a/cloudinit/net/network_state.py
49+++ b/cloudinit/net/network_state.py
50@@ -214,7 +214,7 @@ class NetworkStateInterpreter(object):
51 return util.yaml_dumps(self._network_state)
52
53 def as_dict(self):
54- return {'version': self.version, 'config': self.config}
55+ return {'version': self._version, 'config': self._config}
56
57 def get_network_state(self):
58 ns = self.network_state
59@@ -611,7 +611,8 @@ class NetworkStateInterpreter(object):
60 self.handle_vlan(vlan_cmd)
61
62 def handle_wifis(self, command):
63- raise NotImplemented('NetworkState V2: Skipping wifi configuration')
64+ raise NotImplementedError("NetworkState V2: "
65+ "Skipping wifi configuration")
66
67 def _v2_common(self, cfg):
68 LOG.debug('v2_common: handling config:\n%s', cfg)
69diff --git a/cloudinit/sources/DataSourceAltCloud.py b/cloudinit/sources/DataSourceAltCloud.py
70index c2b0eac..8528fa1 100644
71--- a/cloudinit/sources/DataSourceAltCloud.py
72+++ b/cloudinit/sources/DataSourceAltCloud.py
73@@ -201,8 +201,7 @@ class DataSourceAltCloud(sources.DataSource):
74 util.logexc(LOG, 'Failed command: %s\n%s', ' '.join(cmd), _err)
75 return False
76 except OSError as _err:
77- util.logexc(LOG, 'Failed command: %s\n%s', ' '.join(cmd),
78- _err.message)
79+ util.logexc(LOG, 'Failed command: %s\n%s', ' '.join(cmd), _err)
80 return False
81
82 try:
83diff --git a/cloudinit/sources/DataSourceOpenNebula.py b/cloudinit/sources/DataSourceOpenNebula.py
84index 1f1baf4..cd75e6e 100644
85--- a/cloudinit/sources/DataSourceOpenNebula.py
86+++ b/cloudinit/sources/DataSourceOpenNebula.py
87@@ -286,12 +286,12 @@ def parse_shell_config(content, keylist=None, bash=None, asuser=None,
88 output = output[0:-1] # remove trailing null
89
90 # go through output. First _start_ is for 'preset', second for 'target'.
91- # Add to target only things were changed and not in volitile
92+ # Add to ret only things were changed and not in excluded.
93 for line in output.split("\x00"):
94 try:
95 (key, val) = line.split("=", 1)
96 if target is preset:
97- target[key] = val
98+ preset[key] = val
99 elif (key not in excluded and
100 (key in keylist_in or preset.get(key) != val)):
101 ret[key] = val
102diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
103index 1829450..5c99437 100644
104--- a/cloudinit/sources/__init__.py
105+++ b/cloudinit/sources/__init__.py
106@@ -50,7 +50,7 @@ class DataSource(object):
107 self.distro = distro
108 self.paths = paths
109 self.userdata = None
110- self.metadata = None
111+ self.metadata = {}
112 self.userdata_raw = None
113 self.vendordata = None
114 self.vendordata_raw = None
115diff --git a/cloudinit/url_helper.py b/cloudinit/url_helper.py
116index 312b046..2f6a158 100644
117--- a/cloudinit/url_helper.py
118+++ b/cloudinit/url_helper.py
119@@ -45,7 +45,7 @@ try:
120 from distutils.version import LooseVersion
121 import pkg_resources
122 _REQ = pkg_resources.get_distribution('requests')
123- _REQ_VER = LooseVersion(_REQ.version)
124+ _REQ_VER = LooseVersion(_REQ.version) # pylint: disable=no-member
125 if _REQ_VER >= LooseVersion('0.8.8'):
126 SSL_ENABLED = True
127 if _REQ_VER >= LooseVersion('0.7.0') and _REQ_VER < LooseVersion('1.0.0'):
128diff --git a/tox.ini b/tox.ini
129index f016f20..bf9046a 100644
130--- a/tox.ini
131+++ b/tox.ini
132@@ -1,5 +1,5 @@
133 [tox]
134-envlist = py27, py3, flake8, xenial
135+envlist = py27, py3, flake8, xenial, pylint
136 recreate = True
137
138 [testenv]
139@@ -17,6 +17,10 @@ commands = {envpython} -m flake8 {posargs:cloudinit/ tests/ tools/}
140 setenv =
141 LC_ALL = en_US.utf-8
142
143+[testenv:pylint]
144+deps = pylint==1.6.5
145+commands = {envpython} -m pylint {posargs:cloudinit}
146+
147 [testenv:py3]
148 basepython = python3
149 commands = {envpython} -m nose {posargs:--with-coverage \
150@@ -88,6 +92,10 @@ deps = pycodestyle
151 commands = {envpython} -m pyflakes {posargs:cloudinit/ tests/ tools/}
152 deps = pyflakes
153
154+[testenv:tip-pylint]
155+commands = {envpython} -m pylint {posargs:cloudinit}
156+deps = pylint
157+
158 [testenv:citest]
159 basepython = python3
160 commands = {envpython} -m tests.cloud_tests {posargs}

Subscribers

People subscribed via source and target branches