Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make pep8 test routine reusable for other projects #2486

Merged
merged 2 commits into from Oct 3, 2013
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
289 changes: 148 additions & 141 deletions lib/matplotlib/tests/test_coding_standards.py
Expand Up @@ -17,119 +17,135 @@
else:
HAS_PEP8 = pep8.__version__ > '1.4.5'

# Temporarily disabling test
HAS_PEP8 = False

import matplotlib


EXTRA_EXCLUDE_FILE = os.path.join(os.path.dirname(__file__),
'.pep8_test_exclude.txt')
EXCLUDE_FILES = ['_delaunay.py',
'_image.py',
'_tri.py',
'_backend_agg.py',
'_tkagg.py',
'ft2font.py',
'_cntr.py',
'_png.py',
'_path.py',
'ttconv.py',
'_gtkagg.py',
'_backend_gdk.py',
'pyparsing*']
PEP8_ADDITIONAL_IGNORE = ('E121', 'E122', 'E123', 'E124', 'E125',
'E126', 'E127', 'E128')
EXPECTED_BAD_FILES = ['*/matplotlib/__init__.py',
'*/matplotlib/_cm.py',
'*/matplotlib/_mathtext_data.py',
'*/matplotlib/_pylab_helpers.py',
'*/matplotlib/afm.py',
'*/matplotlib/artist.py',
'*/matplotlib/axes.py',
'*/matplotlib/axis.py',
'*/matplotlib/backend_bases.py',
'*/matplotlib/bezier.py',
'*/matplotlib/cbook.py',
'*/matplotlib/collections.py',
'*/matplotlib/docstring.py',
'*/matplotlib/dviread.py',
'*/matplotlib/finance.py',
'*/matplotlib/font_manager.py',
'*/matplotlib/fontconfig_pattern.py',
'*/matplotlib/gridspec.py',
'*/matplotlib/legend.py',
'*/matplotlib/legend_handler.py',
'*/matplotlib/mathtext.py',
'*/matplotlib/mlab.py',
'*/matplotlib/path.py',
'*/matplotlib/patheffects.py',
'*/matplotlib/pylab.py',
'*/matplotlib/pyplot.py',
'*/matplotlib/rcsetup.py',
'*/matplotlib/stackplot.py',
'*/matplotlib/texmanager.py',
'*/matplotlib/text.py',
'*/matplotlib/transforms.py',
'*/matplotlib/type1font.py',
'*/matplotlib/widgets.py',
'*/matplotlib/testing/compare.py',
'*/matplotlib/testing/decorators.py',
'*/matplotlib/testing/image_util.py',
'*/matplotlib/testing/noseclasses.py',
'*/matplotlib/testing/jpl_units/Duration.py',
'*/matplotlib/testing/jpl_units/Epoch.py',
'*/matplotlib/testing/jpl_units/EpochConverter.py',
'*/matplotlib/testing/jpl_units/StrConverter.py',
'*/matplotlib/testing/jpl_units/UnitDbl.py',
'*/matplotlib/testing/jpl_units/UnitDblConverter.py',
'*/matplotlib/testing/jpl_units/UnitDblFormatter.py',
'*/matplotlib/testing/jpl_units/__init__.py',
'*/matplotlib/tri/tricontour.py',
'*/matplotlib/tri/triinterpolate.py',
'*/matplotlib/tri/tripcolor.py',
'*/matplotlib/tri/triplot.py',
'*/matplotlib/tests/test_axes.py',
'*/matplotlib/tests/test_bbox_tight.py',
'*/matplotlib/tests/test_dates.py',
'*/matplotlib/tests/test_delaunay.py',
'*/matplotlib/tests/test_dviread.py',
'*/matplotlib/tests/test_image.py',
'*/matplotlib/tests/test_legend.py',
'*/matplotlib/tests/test_lines.py',
'*/matplotlib/tests/test_mathtext.py',
'*/matplotlib/tests/test_rcparams.py',
'*/matplotlib/tests/test_simplification.py',
'*/matplotlib/tests/test_spines.py',
'*/matplotlib/tests/test_streamplot.py',
'*/matplotlib/tests/test_subplots.py',
'*/matplotlib/tests/test_text.py',
'*/matplotlib/tests/test_tightlayout.py',
'*/matplotlib/tests/test_transforms.py',
'*/matplotlib/tests/test_triangulation.py',
'*/matplotlib/compat/subprocess.py',
'*/matplotlib/backends/__init__.py',
'*/matplotlib/backends/backend_agg.py',
'*/matplotlib/backends/backend_cairo.py',
'*/matplotlib/backends/backend_cocoaagg.py',
'*/matplotlib/backends/backend_gdk.py',
'*/matplotlib/backends/backend_gtk.py',
'*/matplotlib/backends/backend_gtk3.py',
'*/matplotlib/backends/backend_gtk3cairo.py',
'*/matplotlib/backends/backend_gtkagg.py',
'*/matplotlib/backends/backend_gtkcairo.py',
'*/matplotlib/backends/backend_macosx.py',
'*/matplotlib/backends/backend_mixed.py',
'*/matplotlib/backends/backend_pdf.py',
'*/matplotlib/backends/backend_pgf.py',
'*/matplotlib/backends/backend_ps.py',
'*/matplotlib/backends/backend_svg.py',
'*/matplotlib/backends/backend_template.py',
'*/matplotlib/backends/backend_tkagg.py',
'*/matplotlib/backends/backend_webagg.py',
'*/matplotlib/backends/backend_wx.py',
'*/matplotlib/backends/backend_wxagg.py',
'*/matplotlib/backends/qt4_compat.py',
'*/matplotlib/backends/tkagg.py',
'*/matplotlib/backends/windowing.py',
'*/matplotlib/backends/qt4_editor/figureoptions.py',
'*/matplotlib/backends/qt4_editor/formlayout.py',
'*/matplotlib/sphinxext/__init__.py',
'*/matplotlib/sphinxext/ipython_console_highlighting.py',
'*/matplotlib/sphinxext/ipython_directive.py',
'*/matplotlib/sphinxext/mathmpl.py',
'*/matplotlib/sphinxext/only_directives.py',
'*/matplotlib/sphinxext/plot_directive.py',
'*/matplotlib/projections/__init__.py',
'*/matplotlib/projections/geo.py',
'*/matplotlib/projections/polar.py']


if HAS_PEP8:
class StandardReportWithExclusions(pep8.StandardReport):
#; A class attribute to store the exception exclusion file patterns.
expected_bad_files = [
'*/matplotlib/__init__.py',
'*/matplotlib/_cm.py',
'*/matplotlib/_mathtext_data.py',
'*/matplotlib/_pylab_helpers.py',
'*/matplotlib/afm.py',
'*/matplotlib/artist.py',
'*/matplotlib/axes.py',
'*/matplotlib/axis.py',
'*/matplotlib/backend_bases.py',
'*/matplotlib/bezier.py',
'*/matplotlib/cbook.py',
'*/matplotlib/collections.py',
'*/matplotlib/docstring.py',
'*/matplotlib/dviread.py',
'*/matplotlib/finance.py',
'*/matplotlib/font_manager.py',
'*/matplotlib/fontconfig_pattern.py',
'*/matplotlib/gridspec.py',
'*/matplotlib/legend.py',
'*/matplotlib/legend_handler.py',
'*/matplotlib/mathtext.py',
'*/matplotlib/mlab.py',
'*/matplotlib/path.py',
'*/matplotlib/patheffects.py',
'*/matplotlib/pylab.py',
'*/matplotlib/pyplot.py',
'*/matplotlib/rcsetup.py',
'*/matplotlib/stackplot.py',
'*/matplotlib/texmanager.py',
'*/matplotlib/text.py',
'*/matplotlib/transforms.py',
'*/matplotlib/type1font.py',
'*/matplotlib/widgets.py',
'*/matplotlib/testing/compare.py',
'*/matplotlib/testing/decorators.py',
'*/matplotlib/testing/image_util.py',
'*/matplotlib/testing/noseclasses.py',
'*/matplotlib/testing/jpl_units/Duration.py',
'*/matplotlib/testing/jpl_units/Epoch.py',
'*/matplotlib/testing/jpl_units/EpochConverter.py',
'*/matplotlib/testing/jpl_units/StrConverter.py',
'*/matplotlib/testing/jpl_units/UnitDbl.py',
'*/matplotlib/testing/jpl_units/UnitDblConverter.py',
'*/matplotlib/testing/jpl_units/UnitDblFormatter.py',
'*/matplotlib/testing/jpl_units/__init__.py',
'*/matplotlib/tri/tricontour.py',
'*/matplotlib/tri/triinterpolate.py',
'*/matplotlib/tri/tripcolor.py',
'*/matplotlib/tri/triplot.py',
'*/matplotlib/tests/test_axes.py',
'*/matplotlib/tests/test_bbox_tight.py',
'*/matplotlib/tests/test_dates.py',
'*/matplotlib/tests/test_delaunay.py',
'*/matplotlib/tests/test_dviread.py',
'*/matplotlib/tests/test_image.py',
'*/matplotlib/tests/test_legend.py',
'*/matplotlib/tests/test_lines.py',
'*/matplotlib/tests/test_mathtext.py',
'*/matplotlib/tests/test_rcparams.py',
'*/matplotlib/tests/test_simplification.py',
'*/matplotlib/tests/test_spines.py',
'*/matplotlib/tests/test_streamplot.py',
'*/matplotlib/tests/test_subplots.py',
'*/matplotlib/tests/test_text.py',
'*/matplotlib/tests/test_tightlayout.py',
'*/matplotlib/tests/test_transforms.py',
'*/matplotlib/tests/test_triangulation.py',
'*/matplotlib/compat/subprocess.py',
'*/matplotlib/backends/__init__.py',
'*/matplotlib/backends/backend_agg.py',
'*/matplotlib/backends/backend_cairo.py',
'*/matplotlib/backends/backend_cocoaagg.py',
'*/matplotlib/backends/backend_gdk.py',
'*/matplotlib/backends/backend_gtk.py',
'*/matplotlib/backends/backend_gtk3.py',
'*/matplotlib/backends/backend_gtk3cairo.py',
'*/matplotlib/backends/backend_gtkagg.py',
'*/matplotlib/backends/backend_gtkcairo.py',
'*/matplotlib/backends/backend_macosx.py',
'*/matplotlib/backends/backend_mixed.py',
'*/matplotlib/backends/backend_pdf.py',
'*/matplotlib/backends/backend_pgf.py',
'*/matplotlib/backends/backend_ps.py',
'*/matplotlib/backends/backend_svg.py',
'*/matplotlib/backends/backend_template.py',
'*/matplotlib/backends/backend_tkagg.py',
'*/matplotlib/backends/backend_webagg.py',
'*/matplotlib/backends/backend_wx.py',
'*/matplotlib/backends/backend_wxagg.py',
'*/matplotlib/backends/qt4_compat.py',
'*/matplotlib/backends/tkagg.py',
'*/matplotlib/backends/windowing.py',
'*/matplotlib/backends/qt4_editor/figureoptions.py',
'*/matplotlib/backends/qt4_editor/formlayout.py',
'*/matplotlib/sphinxext/__init__.py',
'*/matplotlib/sphinxext/ipython_console_highlighting.py',
'*/matplotlib/sphinxext/ipython_directive.py',
'*/matplotlib/sphinxext/mathmpl.py',
'*/matplotlib/sphinxext/only_directives.py',
'*/matplotlib/sphinxext/plot_directive.py',
'*/matplotlib/projections/__init__.py',
'*/matplotlib/projections/geo.py',
'*/matplotlib/projections/polar.py']
expected_bad_files = EXPECTED_BAD_FILES

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


def test_pep8_conformance():
# Tests the matplotlib codebase against the "pep8" tool.
#
# Users can add their own excluded files (should files exist in the
# local directory which is not in the repository) by adding a
# ".pep8_test_exclude.txt" file in the same directory as this test.
# The file should be a line separated list of filenames/directories
# as can be passed to the "pep8" tool's exclude list.
def assert_pep8_conformance(module=matplotlib, exclude_files=EXCLUDE_FILES,
extra_exclude_file=EXTRA_EXCLUDE_FILE,
pep8_additional_ignore=PEP8_ADDITIONAL_IGNORE):
"""
Tests the matplotlib codebase against the "pep8" tool.

Users can add their own excluded files (should files exist in the
local directory which is not in the repository) by adding a
".pep8_test_exclude.txt" file in the same directory as this test.
The file should be a line separated list of filenames/directories
as can be passed to the "pep8" tool's exclude list.
"""

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

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

# Support for egg shared object wrappers, which are not PEP8 compliant,
# nor part of the matplotlib repository.
# DO NOT ADD FILES *IN* THE REPOSITORY TO THIS LIST.
pep8style.options.exclude.extend(
['_delaunay.py',
'_image.py',
'_tri.py',
'_backend_agg.py',
'_tkagg.py',
'ft2font.py',
'_cntr.py',
'_png.py',
'_path.py',
'ttconv.py',
'_gtkagg.py',
'_backend_gdk.py',
'pyparsing*'])
pep8style.options.exclude.extend(exclude_files)

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

result = pep8style.check_files([os.path.dirname(matplotlib.__file__)])
result = pep8style.check_files([os.path.dirname(module.__file__)])
if reporter is StandardReportWithExclusions:
assert_equal(result.total_errors, 0,
("Found code syntax errors (and warnings):\n"
"{0}".format(
'\n'.join(reporter._global_deferred_print))))
msg = ("Found code syntax errors (and warnings):\n"
"{0}".format('\n'.join(reporter._global_deferred_print)))
else:
assert_equal(result.total_errors, 0, "Found code syntax "
"errors (and warnings).")
msg = "Found code syntax errors (and warnings)."
assert_equal(result.total_errors, 0, msg)

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


## Temporarily disabling test
#def test_pep8_conformance():
# assert_pep8_conformance()


if __name__ == '__main__':
import nose
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)