Skip to content

Commit d1cb803

Browse files
committed
Merge pull request matplotlib#2486 from megies/reusable_pep8_testroutine
Make pep8 test routine reusable for other projects (work in progress).
2 parents 926bddc + af6c607 commit d1cb803

File tree

1 file changed

+148
-141
lines changed

1 file changed

+148
-141
lines changed

Diff for: lib/matplotlib/tests/test_coding_standards.py

+148-141
Original file line numberDiff line numberDiff line change
@@ -17,119 +17,135 @@
1717
else:
1818
HAS_PEP8 = pep8.__version__ > '1.4.5'
1919

20-
# Temporarily disabling test
21-
HAS_PEP8 = False
22-
2320
import matplotlib
2421

2522

23+
EXTRA_EXCLUDE_FILE = os.path.join(os.path.dirname(__file__),
24+
'.pep8_test_exclude.txt')
25+
EXCLUDE_FILES = ['_delaunay.py',
26+
'_image.py',
27+
'_tri.py',
28+
'_backend_agg.py',
29+
'_tkagg.py',
30+
'ft2font.py',
31+
'_cntr.py',
32+
'_png.py',
33+
'_path.py',
34+
'ttconv.py',
35+
'_gtkagg.py',
36+
'_backend_gdk.py',
37+
'pyparsing*']
38+
PEP8_ADDITIONAL_IGNORE = ('E121', 'E122', 'E123', 'E124', 'E125',
39+
'E126', 'E127', 'E128')
40+
EXPECTED_BAD_FILES = ['*/matplotlib/__init__.py',
41+
'*/matplotlib/_cm.py',
42+
'*/matplotlib/_mathtext_data.py',
43+
'*/matplotlib/_pylab_helpers.py',
44+
'*/matplotlib/afm.py',
45+
'*/matplotlib/artist.py',
46+
'*/matplotlib/axes.py',
47+
'*/matplotlib/axis.py',
48+
'*/matplotlib/backend_bases.py',
49+
'*/matplotlib/bezier.py',
50+
'*/matplotlib/cbook.py',
51+
'*/matplotlib/collections.py',
52+
'*/matplotlib/docstring.py',
53+
'*/matplotlib/dviread.py',
54+
'*/matplotlib/finance.py',
55+
'*/matplotlib/font_manager.py',
56+
'*/matplotlib/fontconfig_pattern.py',
57+
'*/matplotlib/gridspec.py',
58+
'*/matplotlib/legend.py',
59+
'*/matplotlib/legend_handler.py',
60+
'*/matplotlib/mathtext.py',
61+
'*/matplotlib/mlab.py',
62+
'*/matplotlib/path.py',
63+
'*/matplotlib/patheffects.py',
64+
'*/matplotlib/pylab.py',
65+
'*/matplotlib/pyplot.py',
66+
'*/matplotlib/rcsetup.py',
67+
'*/matplotlib/stackplot.py',
68+
'*/matplotlib/texmanager.py',
69+
'*/matplotlib/text.py',
70+
'*/matplotlib/transforms.py',
71+
'*/matplotlib/type1font.py',
72+
'*/matplotlib/widgets.py',
73+
'*/matplotlib/testing/compare.py',
74+
'*/matplotlib/testing/decorators.py',
75+
'*/matplotlib/testing/image_util.py',
76+
'*/matplotlib/testing/noseclasses.py',
77+
'*/matplotlib/testing/jpl_units/Duration.py',
78+
'*/matplotlib/testing/jpl_units/Epoch.py',
79+
'*/matplotlib/testing/jpl_units/EpochConverter.py',
80+
'*/matplotlib/testing/jpl_units/StrConverter.py',
81+
'*/matplotlib/testing/jpl_units/UnitDbl.py',
82+
'*/matplotlib/testing/jpl_units/UnitDblConverter.py',
83+
'*/matplotlib/testing/jpl_units/UnitDblFormatter.py',
84+
'*/matplotlib/testing/jpl_units/__init__.py',
85+
'*/matplotlib/tri/tricontour.py',
86+
'*/matplotlib/tri/triinterpolate.py',
87+
'*/matplotlib/tri/tripcolor.py',
88+
'*/matplotlib/tri/triplot.py',
89+
'*/matplotlib/tests/test_axes.py',
90+
'*/matplotlib/tests/test_bbox_tight.py',
91+
'*/matplotlib/tests/test_dates.py',
92+
'*/matplotlib/tests/test_delaunay.py',
93+
'*/matplotlib/tests/test_dviread.py',
94+
'*/matplotlib/tests/test_image.py',
95+
'*/matplotlib/tests/test_legend.py',
96+
'*/matplotlib/tests/test_lines.py',
97+
'*/matplotlib/tests/test_mathtext.py',
98+
'*/matplotlib/tests/test_rcparams.py',
99+
'*/matplotlib/tests/test_simplification.py',
100+
'*/matplotlib/tests/test_spines.py',
101+
'*/matplotlib/tests/test_streamplot.py',
102+
'*/matplotlib/tests/test_subplots.py',
103+
'*/matplotlib/tests/test_text.py',
104+
'*/matplotlib/tests/test_tightlayout.py',
105+
'*/matplotlib/tests/test_transforms.py',
106+
'*/matplotlib/tests/test_triangulation.py',
107+
'*/matplotlib/compat/subprocess.py',
108+
'*/matplotlib/backends/__init__.py',
109+
'*/matplotlib/backends/backend_agg.py',
110+
'*/matplotlib/backends/backend_cairo.py',
111+
'*/matplotlib/backends/backend_cocoaagg.py',
112+
'*/matplotlib/backends/backend_gdk.py',
113+
'*/matplotlib/backends/backend_gtk.py',
114+
'*/matplotlib/backends/backend_gtk3.py',
115+
'*/matplotlib/backends/backend_gtk3cairo.py',
116+
'*/matplotlib/backends/backend_gtkagg.py',
117+
'*/matplotlib/backends/backend_gtkcairo.py',
118+
'*/matplotlib/backends/backend_macosx.py',
119+
'*/matplotlib/backends/backend_mixed.py',
120+
'*/matplotlib/backends/backend_pdf.py',
121+
'*/matplotlib/backends/backend_pgf.py',
122+
'*/matplotlib/backends/backend_ps.py',
123+
'*/matplotlib/backends/backend_svg.py',
124+
'*/matplotlib/backends/backend_template.py',
125+
'*/matplotlib/backends/backend_tkagg.py',
126+
'*/matplotlib/backends/backend_webagg.py',
127+
'*/matplotlib/backends/backend_wx.py',
128+
'*/matplotlib/backends/backend_wxagg.py',
129+
'*/matplotlib/backends/qt4_compat.py',
130+
'*/matplotlib/backends/tkagg.py',
131+
'*/matplotlib/backends/windowing.py',
132+
'*/matplotlib/backends/qt4_editor/figureoptions.py',
133+
'*/matplotlib/backends/qt4_editor/formlayout.py',
134+
'*/matplotlib/sphinxext/__init__.py',
135+
'*/matplotlib/sphinxext/ipython_console_highlighting.py',
136+
'*/matplotlib/sphinxext/ipython_directive.py',
137+
'*/matplotlib/sphinxext/mathmpl.py',
138+
'*/matplotlib/sphinxext/only_directives.py',
139+
'*/matplotlib/sphinxext/plot_directive.py',
140+
'*/matplotlib/projections/__init__.py',
141+
'*/matplotlib/projections/geo.py',
142+
'*/matplotlib/projections/polar.py']
143+
144+
26145
if HAS_PEP8:
27146
class StandardReportWithExclusions(pep8.StandardReport):
28147
#; A class attribute to store the exception exclusion file patterns.
29-
expected_bad_files = [
30-
'*/matplotlib/__init__.py',
31-
'*/matplotlib/_cm.py',
32-
'*/matplotlib/_mathtext_data.py',
33-
'*/matplotlib/_pylab_helpers.py',
34-
'*/matplotlib/afm.py',
35-
'*/matplotlib/artist.py',
36-
'*/matplotlib/axes.py',
37-
'*/matplotlib/axis.py',
38-
'*/matplotlib/backend_bases.py',
39-
'*/matplotlib/bezier.py',
40-
'*/matplotlib/cbook.py',
41-
'*/matplotlib/collections.py',
42-
'*/matplotlib/docstring.py',
43-
'*/matplotlib/dviread.py',
44-
'*/matplotlib/finance.py',
45-
'*/matplotlib/font_manager.py',
46-
'*/matplotlib/fontconfig_pattern.py',
47-
'*/matplotlib/gridspec.py',
48-
'*/matplotlib/legend.py',
49-
'*/matplotlib/legend_handler.py',
50-
'*/matplotlib/mathtext.py',
51-
'*/matplotlib/mlab.py',
52-
'*/matplotlib/path.py',
53-
'*/matplotlib/patheffects.py',
54-
'*/matplotlib/pylab.py',
55-
'*/matplotlib/pyplot.py',
56-
'*/matplotlib/rcsetup.py',
57-
'*/matplotlib/stackplot.py',
58-
'*/matplotlib/texmanager.py',
59-
'*/matplotlib/text.py',
60-
'*/matplotlib/transforms.py',
61-
'*/matplotlib/type1font.py',
62-
'*/matplotlib/widgets.py',
63-
'*/matplotlib/testing/compare.py',
64-
'*/matplotlib/testing/decorators.py',
65-
'*/matplotlib/testing/image_util.py',
66-
'*/matplotlib/testing/noseclasses.py',
67-
'*/matplotlib/testing/jpl_units/Duration.py',
68-
'*/matplotlib/testing/jpl_units/Epoch.py',
69-
'*/matplotlib/testing/jpl_units/EpochConverter.py',
70-
'*/matplotlib/testing/jpl_units/StrConverter.py',
71-
'*/matplotlib/testing/jpl_units/UnitDbl.py',
72-
'*/matplotlib/testing/jpl_units/UnitDblConverter.py',
73-
'*/matplotlib/testing/jpl_units/UnitDblFormatter.py',
74-
'*/matplotlib/testing/jpl_units/__init__.py',
75-
'*/matplotlib/tri/tricontour.py',
76-
'*/matplotlib/tri/triinterpolate.py',
77-
'*/matplotlib/tri/tripcolor.py',
78-
'*/matplotlib/tri/triplot.py',
79-
'*/matplotlib/tests/test_axes.py',
80-
'*/matplotlib/tests/test_bbox_tight.py',
81-
'*/matplotlib/tests/test_dates.py',
82-
'*/matplotlib/tests/test_delaunay.py',
83-
'*/matplotlib/tests/test_dviread.py',
84-
'*/matplotlib/tests/test_image.py',
85-
'*/matplotlib/tests/test_legend.py',
86-
'*/matplotlib/tests/test_lines.py',
87-
'*/matplotlib/tests/test_mathtext.py',
88-
'*/matplotlib/tests/test_rcparams.py',
89-
'*/matplotlib/tests/test_simplification.py',
90-
'*/matplotlib/tests/test_spines.py',
91-
'*/matplotlib/tests/test_streamplot.py',
92-
'*/matplotlib/tests/test_subplots.py',
93-
'*/matplotlib/tests/test_text.py',
94-
'*/matplotlib/tests/test_tightlayout.py',
95-
'*/matplotlib/tests/test_transforms.py',
96-
'*/matplotlib/tests/test_triangulation.py',
97-
'*/matplotlib/compat/subprocess.py',
98-
'*/matplotlib/backends/__init__.py',
99-
'*/matplotlib/backends/backend_agg.py',
100-
'*/matplotlib/backends/backend_cairo.py',
101-
'*/matplotlib/backends/backend_cocoaagg.py',
102-
'*/matplotlib/backends/backend_gdk.py',
103-
'*/matplotlib/backends/backend_gtk.py',
104-
'*/matplotlib/backends/backend_gtk3.py',
105-
'*/matplotlib/backends/backend_gtk3cairo.py',
106-
'*/matplotlib/backends/backend_gtkagg.py',
107-
'*/matplotlib/backends/backend_gtkcairo.py',
108-
'*/matplotlib/backends/backend_macosx.py',
109-
'*/matplotlib/backends/backend_mixed.py',
110-
'*/matplotlib/backends/backend_pdf.py',
111-
'*/matplotlib/backends/backend_pgf.py',
112-
'*/matplotlib/backends/backend_ps.py',
113-
'*/matplotlib/backends/backend_svg.py',
114-
'*/matplotlib/backends/backend_template.py',
115-
'*/matplotlib/backends/backend_tkagg.py',
116-
'*/matplotlib/backends/backend_webagg.py',
117-
'*/matplotlib/backends/backend_wx.py',
118-
'*/matplotlib/backends/backend_wxagg.py',
119-
'*/matplotlib/backends/qt4_compat.py',
120-
'*/matplotlib/backends/tkagg.py',
121-
'*/matplotlib/backends/windowing.py',
122-
'*/matplotlib/backends/qt4_editor/figureoptions.py',
123-
'*/matplotlib/backends/qt4_editor/formlayout.py',
124-
'*/matplotlib/sphinxext/__init__.py',
125-
'*/matplotlib/sphinxext/ipython_console_highlighting.py',
126-
'*/matplotlib/sphinxext/ipython_directive.py',
127-
'*/matplotlib/sphinxext/mathmpl.py',
128-
'*/matplotlib/sphinxext/only_directives.py',
129-
'*/matplotlib/sphinxext/plot_directive.py',
130-
'*/matplotlib/projections/__init__.py',
131-
'*/matplotlib/projections/geo.py',
132-
'*/matplotlib/projections/polar.py']
148+
expected_bad_files = EXPECTED_BAD_FILES
133149

134150
#: A class attribute to store the lines of failing tests.
135151
_global_deferred_print = []
@@ -172,14 +188,18 @@ def get_file_results(self):
172188
return self.file_errors
173189

174190

175-
def test_pep8_conformance():
176-
# Tests the matplotlib codebase against the "pep8" tool.
177-
#
178-
# Users can add their own excluded files (should files exist in the
179-
# local directory which is not in the repository) by adding a
180-
# ".pep8_test_exclude.txt" file in the same directory as this test.
181-
# The file should be a line separated list of filenames/directories
182-
# as can be passed to the "pep8" tool's exclude list.
191+
def assert_pep8_conformance(module=matplotlib, exclude_files=EXCLUDE_FILES,
192+
extra_exclude_file=EXTRA_EXCLUDE_FILE,
193+
pep8_additional_ignore=PEP8_ADDITIONAL_IGNORE):
194+
"""
195+
Tests the matplotlib codebase against the "pep8" tool.
196+
197+
Users can add their own excluded files (should files exist in the
198+
local directory which is not in the repository) by adding a
199+
".pep8_test_exclude.txt" file in the same directory as this test.
200+
The file should be a line separated list of filenames/directories
201+
as can be passed to the "pep8" tool's exclude list.
202+
"""
183203

184204
if not HAS_PEP8:
185205
raise SkipTest('The pep8 tool is required for this test')
@@ -192,44 +212,26 @@ def test_pep8_conformance():
192212

193213
# Extend the number of PEP8 guidelines which are not checked.
194214
pep8style.options.ignore = (pep8style.options.ignore +
195-
('E121', 'E122', 'E123', 'E124', 'E125',
196-
'E126', 'E127', 'E128'))
215+
tuple(pep8_additional_ignore))
197216

198217
# Support for egg shared object wrappers, which are not PEP8 compliant,
199218
# nor part of the matplotlib repository.
200219
# DO NOT ADD FILES *IN* THE REPOSITORY TO THIS LIST.
201-
pep8style.options.exclude.extend(
202-
['_delaunay.py',
203-
'_image.py',
204-
'_tri.py',
205-
'_backend_agg.py',
206-
'_tkagg.py',
207-
'ft2font.py',
208-
'_cntr.py',
209-
'_png.py',
210-
'_path.py',
211-
'ttconv.py',
212-
'_gtkagg.py',
213-
'_backend_gdk.py',
214-
'pyparsing*'])
220+
pep8style.options.exclude.extend(exclude_files)
215221

216222
# Allow users to add their own exclude list.
217-
extra_exclude_file = os.path.join(os.path.dirname(__file__),
218-
'.pep8_test_exclude.txt')
219-
if os.path.exists(extra_exclude_file):
223+
if extra_exclude_file is not None and os.path.exists(extra_exclude_file):
220224
with open(extra_exclude_file, 'r') as fh:
221225
extra_exclude = [line.strip() for line in fh if line.strip()]
222226
pep8style.options.exclude.extend(extra_exclude)
223227

224-
result = pep8style.check_files([os.path.dirname(matplotlib.__file__)])
228+
result = pep8style.check_files([os.path.dirname(module.__file__)])
225229
if reporter is StandardReportWithExclusions:
226-
assert_equal(result.total_errors, 0,
227-
("Found code syntax errors (and warnings):\n"
228-
"{0}".format(
229-
'\n'.join(reporter._global_deferred_print))))
230+
msg = ("Found code syntax errors (and warnings):\n"
231+
"{0}".format('\n'.join(reporter._global_deferred_print)))
230232
else:
231-
assert_equal(result.total_errors, 0, "Found code syntax "
232-
"errors (and warnings).")
233+
msg = "Found code syntax errors (and warnings)."
234+
assert_equal(result.total_errors, 0, msg)
233235

234236
# If we've been using the exclusions reporter, check that we didn't
235237
# exclude files unnecessarily.
@@ -244,6 +246,11 @@ def test_pep8_conformance():
244246
'{}'.format('\n '.join(unexpectedly_good)))
245247

246248

249+
## Temporarily disabling test
250+
#def test_pep8_conformance():
251+
# assert_pep8_conformance()
252+
253+
247254
if __name__ == '__main__':
248255
import nose
249256
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)

0 commit comments

Comments
 (0)