diff --git a/.travis.yml b/.travis.yml index ed757ed08300..98e12e3d76d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,7 +43,8 @@ env: - OPENBLAS_NUM_THREADS=1 - PANDAS= - NPROC=2 - - TEST_ARGS=--no-pep8 + - INSTALL_PEP8= + - RUN_PEP8= - NOSE_ARGS="-j $NPROC" - PYTEST_ARGS="-ra --maxfail=1 --timeout=300 --durations=25 --cov-report= --cov=lib -n $NPROC" - PYTHON_ARGS= @@ -61,9 +62,9 @@ matrix: - python: 3.5 env: BUILD_DOCS=true - python: 3.5 - env: USE_PYTEST=true PANDAS=pandas DELETE_FONT_CACHE=1 TEST_ARGS= + env: USE_PYTEST=true PANDAS=pandas DELETE_FONT_CACHE=1 - python: 3.6 - env: USE_PYTEST=true DELETE_FONT_CACHE=1 TEST_ARGS= + env: USE_PYTEST=true DELETE_FONT_CACHE=1 INSTALL_PEP8=pytest-pep8 RUN_PEP8=--pep8 - python: "nightly" env: PRE=--pre - os: osx @@ -113,14 +114,14 @@ install: pip install --upgrade setuptools - | # Install dependencies from pypi - pip install $PRE python-dateutil $NUMPY pyparsing!=2.1.6 $PANDAS pep8 cycler coveralls coverage $MOCK + pip install $PRE python-dateutil $NUMPY pyparsing!=2.1.6 $PANDAS cycler coveralls coverage $MOCK pip install $PRE -r doc-requirements.txt # Install nose from a build which has partial # support for python36 and suport for coverage output suppressing pip install git+https://github.com/jenshnielsen/nose.git@matplotlibnose # pytest-cov>=2.3.1 due to https://github.com/pytest-dev/pytest-cov/issues/124 - pip install $PRE pytest 'pytest-cov>=2.3.1' pytest-timeout pytest-xdist pytest-faulthandler + pip install $PRE pytest 'pytest-cov>=2.3.1' pytest-timeout pytest-xdist pytest-faulthandler $INSTALL_PEP8 # We manually install humor sans using the package from Ubuntu 14.10. Unfortunatly humor sans is not # availible in the Ubuntu version used by Travis but we can manually install the deb from a later @@ -154,13 +155,12 @@ script: if [[ $DELETE_FONT_CACHE == 1 ]]; then rm -rf ~/.cache/matplotlib fi - export MPL_REPO_DIR=$PWD # needed for pep8-conformance test of the examples if [[ $USE_PYTEST == false ]]; then - echo The following args are passed to nose $NOSE_ARGS + echo The following args are passed to nose $NOSE_ARGS $RUN_PEP8 if [[ $TRAVIS_OS_NAME == 'osx' ]]; then - python tests.py $NOSE_ARGS $TEST_ARGS + python tests.py $NOSE_ARGS $RUN_PEP8 else - gdb -return-child-result -batch -ex r -ex bt --args python $PYTHON_ARGS tests.py $NOSE_ARGS $TEST_ARGS + gdb -return-child-result -batch -ex r -ex bt --args python $PYTHON_ARGS tests.py $NOSE_ARGS $RUN_PEP8 fi else # Workaround for pytest-xdist flaky colletion order @@ -169,8 +169,8 @@ script: export PYTHONHASHSEED=$(shuf -i 1-4294967295 -n 1) echo PYTHONHASHSEED=$PYTHONHASHSEED - echo The following args are passed to pytest $PYTEST_ARGS - py.test $PYTEST_ARGS $TEST_ARGS + echo The following args are passed to pytest $PYTEST_ARGS $RUN_PEP8 + py.test $PYTEST_ARGS $RUN_PEP8 fi else cd doc diff --git a/appveyor.yml b/appveyor.yml index f4feb9a8605e..fb6a0c76d139 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,7 +14,6 @@ environment: CMD_IN_ENV: "cmd /E:ON /V:ON /C obvci_appveyor_python_build_env.cmd" # Workaround for https://github.com/conda/conda-build/issues/636 PYTHONIOENCODING: "UTF-8" - TEST_ARGS: --no-pep8 PYTEST_ARGS: -ra --timeout=300 --durations=25 #--cov-report= --cov=lib #-n %NUMBER_OF_PROCESSORS% USE_PYTEST: no #PYTHONHASHSEED: 0 # Workaround for pytest-xdist flaky colletion order @@ -137,8 +136,8 @@ test_script: - python -c "import matplotlib as m; m.use('tkagg'); import matplotlib.pyplot as plt; print(plt.get_backend())" # tests - if x%USE_PYTEST% == xyes echo The following args are passed to pytest %PYTEST_ARGS% - - if x%USE_PYTEST% == xyes py.test %PYTEST_ARGS% %TEST_ARGS% - - if x%USE_PYTEST% == xno python tests.py %TEST_ARGS% + - if x%USE_PYTEST% == xyes py.test %PYTEST_ARGS% + - if x%USE_PYTEST% == xno python tests.py # Generate a html for visual tests - python visual_tests.py diff --git a/lib/matplotlib/tests/test_coding_standards.py b/lib/matplotlib/tests/test_coding_standards.py deleted file mode 100644 index 3478e50454ae..000000000000 --- a/lib/matplotlib/tests/test_coding_standards.py +++ /dev/null @@ -1,286 +0,0 @@ -from __future__ import (absolute_import, division, print_function, - unicode_literals) - -from fnmatch import fnmatch -import os - -import pytest - -try: - import pep8 -except ImportError: - HAS_PEP8 = False -else: - HAS_PEP8 = pep8.__version__ > '1.4.5' - -import matplotlib - - -PEP8_ADDITIONAL_IGNORE = ['E111', - 'E114', - 'E115', - 'E116', - 'E121', - 'E122', - 'E123', - 'E124', - 'E125', - 'E126', - 'E127', - 'E128', - 'E129', - 'E131', - 'E265', - 'E266', - 'W503'] - -EXTRA_EXCLUDE_FILE = os.path.join(os.path.dirname(__file__), - '.pep8_test_exclude.txt') - - -if HAS_PEP8: - class StandardReportWithExclusions(pep8.StandardReport): - #: A class attribute to store the exception exclusion file patterns. - expected_bad_files = [] - - #: A class attribute to store the lines of failing tests. - _global_deferred_print = [] - - #: A class attribute to store patterns which have seen exceptions. - matched_exclusions = set() - - def get_file_results(self): - # If the file had no errors, return self.file_errors - # (which will be 0). - if not self._deferred_print: - return self.file_errors - - # Iterate over all of the patterns, to find a possible exclusion. - # If the filename is to be excluded, go ahead and remove the - # counts that self.error added. - for pattern in self.expected_bad_files: - if fnmatch(self.filename, pattern): - self.matched_exclusions.add(pattern) - # invert the error method's counters. - for _, _, code, _, _ in self._deferred_print: - self.counters[code] -= 1 - if self.counters[code] == 0: - self.counters.pop(code) - self.messages.pop(code) - self.file_errors -= 1 - self.total_errors -= 1 - return self.file_errors - - # mirror the content of StandardReport, only storing the output to - # file rather than printing. This could be a feature request for - # the PEP8 tool. - self._deferred_print.sort() - for line_number, offset, code, text, _ in self._deferred_print: - self._global_deferred_print.append( - self._fmt % {'path': self.filename, - 'row': self.line_offset + line_number, - 'col': offset + 1, 'code': code, - 'text': text}) - return self.file_errors - - -def assert_pep8_conformance(module=matplotlib, exclude_files=None, - extra_exclude_file=EXTRA_EXCLUDE_FILE, - pep8_additional_ignore=PEP8_ADDITIONAL_IGNORE, - dirname=None, expected_bad_files=None, - extra_exclude_directories=None): - """ - 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. - """ - __tracebackhide__ = True - - if not HAS_PEP8: - pytest.skip('The pep8 tool is required for this test') - - # to get a list of bad files, rather than the specific errors, add - # "reporter=pep8.FileReport" to the StyleGuide constructor. - pep8style = pep8.StyleGuide(quiet=False, - reporter=StandardReportWithExclusions) - reporter = pep8style.options.reporter - - if expected_bad_files is not None: - reporter.expected_bad_files = expected_bad_files - - # Extend the number of PEP8 guidelines which are not checked. - pep8style.options.ignore = (pep8style.options.ignore + - 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. - if exclude_files is not None: - pep8style.options.exclude.extend(exclude_files) - - # Allow users to add their own exclude list. - 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) - - if extra_exclude_directories: - pep8style.options.exclude.extend(extra_exclude_directories) - - if dirname is None: - dirname = os.path.dirname(module.__file__) - result = pep8style.check_files([dirname]) - if reporter is StandardReportWithExclusions: - msg = ("Found code syntax errors (and warnings):\n" - "{0}".format('\n'.join(reporter._global_deferred_print))) - else: - msg = "Found code syntax errors (and warnings)." - assert result.total_errors == 0, msg - - # If we've been using the exclusions reporter, check that we didn't - # exclude files unnecessarily. - if reporter is StandardReportWithExclusions: - unexpectedly_good = sorted(set(reporter.expected_bad_files) - - reporter.matched_exclusions) - - if unexpectedly_good: - raise ValueError('Some exclude patterns were unnecessary as the ' - 'files they pointed to either passed the PEP8 ' - 'tests or do not point to a file:\n ' - '{0}'.format('\n '.join(unexpectedly_good))) - - -def test_pep8_conformance_installed_files(): - __tracebackhide__ = True - - exclude_files = ['_image.py', - '_tri.py', - '_backend_agg.py', - '_tkagg.py', - 'ft2font.py', - '_cntr.py', - '_contour.py', - '_png.py', - '_path.py', - 'ttconv.py', - '_gtkagg.py', - '_backend_gdk.py', - 'pyparsing*', - '_qhull.py', - '_macosx.py'] - - expected_bad_files = ['_cm.py', - '_mathtext_data.py', - 'backend_bases.py', - 'font_manager.py', - 'fontconfig_pattern.py', - 'gridspec.py', - 'legend_handler.py', - 'mathtext.py', - 'patheffects.py', - 'pylab.py', - 'pyplot.py', - 'rcsetup.py', - 'stackplot.py', - 'texmanager.py', - 'transforms.py', - 'type1font.py', - 'testing/decorators.py', - 'testing/jpl_units/Duration.py', - 'testing/jpl_units/Epoch.py', - 'testing/jpl_units/EpochConverter.py', - 'testing/jpl_units/StrConverter.py', - 'testing/jpl_units/UnitDbl.py', - 'testing/jpl_units/UnitDblConverter.py', - 'testing/jpl_units/UnitDblFormatter.py', - 'testing/jpl_units/__init__.py', - 'tri/triinterpolate.py', - 'tests/test_axes.py', - 'tests/test_image.py', - 'tests/test_lines.py', - 'tests/test_mathtext.py', - 'tests/test_rcparams.py', - 'tests/test_tightlayout.py', - 'tests/test_triangulation.py', - 'backends/backend_agg.py', - 'backends/backend_cairo.py', - 'backends/backend_gdk.py', - 'backends/backend_gtk.py', - 'backends/backend_gtk3.py', - 'backends/backend_gtk3cairo.py', - 'backends/backend_gtkagg.py', - 'backends/backend_gtkcairo.py', - 'backends/backend_macosx.py', - 'backends/backend_pgf.py', - 'backends/backend_ps.py', - 'backends/backend_svg.py', - 'backends/backend_template.py', - 'backends/backend_tkagg.py', - 'backends/tkagg.py', - 'backends/windowing.py', - 'backends/qt_editor/formlayout.py', - 'sphinxext/mathmpl.py', - 'sphinxext/only_directives.py', - 'sphinxext/plot_directive.py', - 'projections/__init__.py', - 'projections/geo.py', - 'projections/polar.py'] - expected_bad_files = ['*/matplotlib/' + s for s in expected_bad_files] - assert_pep8_conformance(module=matplotlib, - exclude_files=exclude_files, - expected_bad_files=expected_bad_files) - - -def test_pep8_conformance_examples(): - mpldir = os.environ.get('MPL_REPO_DIR', None) - if mpldir is None: - # try and guess! - fp = os.getcwd() - while len(fp) > 2: - if os.path.isdir(os.path.join(fp, 'examples')): - mpldir = fp - break - fp, tail = os.path.split(fp) - - if mpldir is None: - pytest.xfail("can not find the examples, set env MPL_REPO_DIR to " - "point to the top-level path of the source tree") - - exdir = os.path.join(mpldir, 'examples') - blacklist = () - expected_bad_files = ['*/pylab_examples/table_demo.py', - '*/pylab_examples/tricontour_demo.py', - '*/pylab_examples/tripcolor_demo.py', - '*/pylab_examples/triplot_demo.py', - '*/shapes_and_collections/artist_reference.py', - '*/pyplots/align_ylabels.py', - '*/pyplots/annotate_transform.py', - '*/pyplots/pyplot_simple.py', - '*/pyplots/annotation_basic.py', - '*/pyplots/annotation_polar.py', - '*/pyplots/auto_subplots_adjust.py', - '*/pyplots/pyplot_two_subplots.py', - '*/pyplots/boxplot_demo.py', - '*/pyplots/tex_demo.py', - '*/pyplots/compound_path_demo.py', - '*/pyplots/text_commands.py', - '*/pyplots/text_layout.py', - '*/pyplots/fig_axes_customize_simple.py', - '*/pyplots/whats_new_1_subplot3d.py', - '*/pyplots/whats_new_98_4_fancy.py', - '*/pyplots/whats_new_98_4_fill_between.py', - '*/pyplots/whats_new_98_4_legend.py', - '*/pyplots/pyplot_annotate.py', - '*/pyplots/whats_new_99_axes_grid.py', - '*/pyplots/pyplot_formatstr.py', - '*/pyplots/pyplot_mathtext.py', - '*/pyplots/whats_new_99_spines.py'] - assert_pep8_conformance(dirname=exdir, - extra_exclude_directories=blacklist, - pep8_additional_ignore=PEP8_ADDITIONAL_IGNORE + - ['E116', 'E501', 'E402'], - expected_bad_files=expected_bad_files) diff --git a/pytest.ini b/pytest.ini index 44da53ce982d..7a50474fe7e3 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,2 +1,134 @@ [pytest] norecursedirs = .git build ci dist extern release tools unit venv +pep8ignore = + * E111 E114 E115 E116 E121 E122 E123 E124 E125 E126 E127 E128 E129 E131 E226 E240 E241 E242 E243 E244 E245 E246 E247 E248 E249 E265 E266 E704 W503 + + boilerplate.py E501 + setup.py E402 E501 + setupext.py E301 E302 E501 + setup_external_compile.py E302 E501 E711 + versioneer.py ALL # External file. + visual_tests.py E302 E501 + + matplotlib/backends/qt_editor/formlayout.py E301 E402 E501 + matplotlib/backends/backend_agg.py E225 E228 E231 E261 E301 E302 E303 E501 E701 + matplotlib/backends/backend_cairo.py E203 E211 E221 E231 E261 E272 E302 E303 E401 E402 E501 E701 E711 + matplotlib/backends/backend_gdk.py E202 E203 E211 E221 E225 E231 E261 E302 E303 E402 E501 E702 E711 + matplotlib/backends/backend_gtk.py E201 E202 E203 E211 E221 E222 E225 E231 E251 E261 E262 E301 E302 E303 E401 E402 E501 E701 E702 E703 + matplotlib/backends/backend_gtk3.py E201 E202 E203 E211 E221 E222 E225 E231 E251 E261 E262 E301 E302 E401 E402 E501 E701 + matplotlib/backends/backend_gtk3cairo.py E211 E302 E501 + matplotlib/backends/backend_gtkagg.py E211 E225 E231 E261 E302 E501 E701 + matplotlib/backends/backend_gtkcairo.py E211 E225 E231 E402 E701 + matplotlib/backends/backend_macosx.py E222 E225 E231 E261 E501 E701 E711 + matplotlib/backends/backend_pgf.py E261 E302 E303 E501 E731 + matplotlib/backends/backend_ps.py E202 E203 E225 E228 E231 E261 E262 E271 E301 E302 E303 E401 E402 E501 E701 + matplotlib/backends/backend_svg.py E203 E221 E225 E228 E231 E261 E302 E401 E501 + matplotlib/backends/backend_template.py E302 E303 E501 + matplotlib/backends/backend_tkagg.py E201 E202 E203 E222 E225 E231 E251 E271 E301 E302 E303 E401 E501 E701 W293 + matplotlib/backends/tkagg.py E231 E302 E701 + matplotlib/backends/windowing.py E301 E302 + matplotlib/backend_bases.py E225 E501 E712 + matplotlib/projections/__init__.py E302 + matplotlib/projections/geo.py E203 E221 E231 E261 E302 E402 E501 E502 + matplotlib/projections/polar.py E202 E203 E221 E231 E251 E301 E402 E501 + matplotlib/sphinxext/mathmpl.py E302 + matplotlib/sphinxext/only_directives.py E302 + matplotlib/sphinxext/plot_directive.py E261 E301 E302 E401 E402 E501 + matplotlib/testing/decorators.py E301 E303 E501 + matplotlib/testing/jpl_units/__init__.py E201 E202 E302 E501 + matplotlib/testing/jpl_units/Duration.py E201 E202 E302 + matplotlib/testing/jpl_units/Epoch.py E201 E202 E203 E302 E501 + matplotlib/testing/jpl_units/EpochConverter.py E201 E202 E251 E302 E711 + matplotlib/testing/jpl_units/StrConverter.py E201 E202 E221 E302 E303 + matplotlib/testing/jpl_units/UnitDbl.py E201 E202 E203 + matplotlib/testing/jpl_units/UnitDblConverter.py E201 E202 E203 E251 E302 E501 E711 + matplotlib/testing/jpl_units/UnitDblFormatter.py E201 E202 E251 E302 + matplotlib/tests/test_axes.py E101 E202 E225 E231 E261 E302 E303 E501 E712 W191 + matplotlib/tests/test_image.py E225 E231 E251 E302 E303 E501 E502 + matplotlib/tests/test_lines.py E231 E261 + matplotlib/tests/test_mathtext.py E261 E302 E501 + matplotlib/tests/test_rcparams.py E231 E501 + matplotlib/tests/test_tightlayout.py E302 + matplotlib/tests/test_triangulation.py E201 E302 + matplotlib/tri/triinterpolate.py E201 E221 + matplotlib/_cm.py E101 E202 E203 W191 + matplotlib/_mathtext_data.py E203 E231 E261 E501 + matplotlib/font_manager.py E201 E203 E221 E225 E228 E231 E251 E261 E262 E302 E402 E501 + matplotlib/fontconfig_pattern.py E201 E203 E221 E222 E225 E302 E401 E501 + matplotlib/gridspec.py E203 E222 E225 E231 E302 E303 E402 E501 + matplotlib/legend_handler.py E201 E301 E303 E501 + matplotlib/mathtext.py E201 E202 E203 E211 E221 E222 E225 E228 E231 E251 E261 E301 E302 E303 E401 E402 E501 + matplotlib/patheffects.py E231 + matplotlib/pylab.py E401 E402 E501 + matplotlib/pyplot.py E201 E202 E203 E221 E222 E225 E231 E251 E261 E302 E303 E501 E701 E713 + matplotlib/rcsetup.py E203 E225 E261 E302 E501 + matplotlib/stackplot.py E251 + matplotlib/texmanager.py E501 + matplotlib/transforms.py E201 E202 E203 E302 E501 + matplotlib/type1font.py E222 E501 E731 + + mpl_toolkits/axes_grid/axes_divider.py E501 + mpl_toolkits/axes_grid/axes_grid.py E225 E302 + mpl_toolkits/axes_grid/axes_rgb.py E302 E501 + mpl_toolkits/axes_grid/parasite_axes.py E501 + mpl_toolkits/axes_grid1/axes_divider.py E402 E501 + mpl_toolkits/axes_grid1/axes_grid.py E225 W391 + mpl_toolkits/axes_grid1/axes_rgb.py E231 E501 + mpl_toolkits/axes_grid1/axes_size.py E225 E261 E302 E303 E501 + mpl_toolkits/axes_grid1/colorbar.py E225 E231 E261 E262 E302 E303 E501 E701 + mpl_toolkits/axes_grid1/inset_locator.py E501 + mpl_toolkits/axes_grid1/mpl_axes.py E302 E303 E501 E502 + mpl_toolkits/axes_grid1/parasite_axes.py E225 E231 E302 E303 E402 E501 E502 + mpl_toolkits/axisartist/__init__.py E501 + mpl_toolkits/axisartist/angle_helper.py E201 E203 E221 E222 E225 E231 E251 E261 E262 E302 E303 E402 E501 E502 + mpl_toolkits/axisartist/axes_divider.py E501 + mpl_toolkits/axisartist/axes_grid.py E225 E302 + mpl_toolkits/axisartist/axes_rgb.py E302 E501 + mpl_toolkits/axisartist/axis_artist.py E201 E202 E221 E225 E228 E231 E251 E261 E262 E302 E303 E402 E501 E701 E702 E711 + mpl_toolkits/axisartist/axisline_style.py E231 E261 E262 E302 E303 + mpl_toolkits/axisartist/axislines.py E225 E231 E261 E262 E302 E303 E501 E502 E711 + mpl_toolkits/axisartist/clip_path.py E225 E228 E302 E303 E501 E502 + mpl_toolkits/axisartist/floating_axes.py E201 E225 E231 E261 E262 E271 E302 E303 E402 E501 + mpl_toolkits/axisartist/grid_finder.py E231 E261 E302 E303 E402 E501 E502 + mpl_toolkits/axisartist/grid_helper_curvelinear.py E221 E225 E231 E251 E261 E262 E271 E302 E303 E501 E502 + mpl_toolkits/axisartist/parasite_axes.py E501 + mpl_toolkits/mplot3d/art3d.py E203 E222 E225 E231 E501 E502 + mpl_toolkits/mplot3d/axes3d.py E203 E225 E231 E271 E303 E402 E501 E502 E701 + mpl_toolkits/mplot3d/axis3d.py E201 E202 E203 E222 E231 E302 E303 E501 E502 + mpl_toolkits/mplot3d/proj3d.py E231 E302 E303 + mpl_toolkits/tests/test_axes_grid1.py E201 E202 + mpl_toolkits/tests/test_mplot3d.py E231 E302 + mpl_toolkits/__init__.py E261 + mpl_toolkits/exceltools.py E201 E202 E225 E228 E302 E303 E501 E701 + mpl_toolkits/gtktools.py E221 E222 E225 E228 E231 E251 E261 E301 E302 E303 E401 E501 E701 + + doc/* ALL + + *examples/* E116 E501 E402 + *examples/pylab_examples/table_demo.py E201 + *examples/pylab_examples/tricontour_demo.py E201 + *examples/pylab_examples/tripcolor_demo.py E201 + *examples/pylab_examples/triplot_demo.py E201 + *examples/pyplots/align_ylabels.py E231 + *examples/pyplots/annotate_transform.py E228 E251 + *examples/pyplots/annotation_basic.py E231 + *examples/pyplots/annotation_polar.py E231 + *examples/pyplots/auto_subplots_adjust.py E231 E261 E302 W391 + *examples/pyplots/boxplot_demo.py E231 + *examples/pyplots/compound_path_demo.py E231 + *examples/pyplots/fig_axes_customize_simple.py E261 + *examples/pyplots/pyplot_annotate.py E231 + *examples/pyplots/pyplot_formatstr.py E231 + *examples/pyplots/pyplot_mathtext.py E231 + *examples/pyplots/pyplot_simple.py E231 + *examples/pyplots/pyplot_two_subplots.py E302 + *examples/pyplots/tex_demo.py E231 + *examples/pyplots/text_commands.py E231 + *examples/pyplots/text_layout.py E231 + *examples/pyplots/whats_new_1_subplot3d.py W391 + *examples/pyplots/whats_new_98_4_fancy.py E225 E261 E302 + *examples/pyplots/whats_new_98_4_fill_between.py E225 + *examples/pyplots/whats_new_98_4_legend.py E228 + *examples/pyplots/whats_new_99_axes_grid.py E225 E231 E302 E303 + *examples/pyplots/whats_new_99_spines.py E231 E261 + *examples/shapes_and_collections/artist_reference.py E203