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

Replace flake8 with flakeheaven #1847

Merged
merged 14 commits into from
Aug 19, 2022
Merged

Replace flake8 with flakeheaven #1847

merged 14 commits into from
Aug 19, 2022

Conversation

weiji14
Copy link
Member

@weiji14 weiji14 commented Mar 26, 2022

Description of proposed changes

So that we can remove the setup.cfg file and have everything in pyproject.toml! Flakeheaven (https://github.com/flakeheaven/flakeheaven) is a flake8 wrapper/fork that is supports configuration in pyproject.toml.

For reference, these flake8 settings were originally added in #186 and #384.

[flake8]
ignore = E203, E266, E501, W503, F401, E741
max-line-length = 88
#max-complexity = 10
max-doc-length = 79

Addresses #1836.

Reminders

  • Run make format and make check to make sure the code follows the style guide.
  • Add tests for new features or tests that would have caught the bug that you're fixing.
  • Add new public functions/methods/classes to doc/api/index.rst.
  • Write detailed docstrings for all functions/methods.
  • If wrapping a new module, open a 'Wrap new GMT module' issue and submit reasonably-sized PRs.
  • If adding new functionality, add an example to docstrings or tutorials.

Slash Commands

You can write slash commands (/command) in the first line of a comment to perform
specific operations. Supported slash commands are:

  • /format: automatically format and lint the code
  • /test-gmt-dev: run full tests on the latest GMT development version

So that we can remove the setup.cfg file and have everything in pyproject.toml!
Temporarily installing flakeheaven using pip until conda-forge package is ready.
@weiji14 weiji14 added the maintenance Boring but important stuff for the core devs label Mar 26, 2022
@weiji14 weiji14 added this to the 0.6.1 milestone Mar 26, 2022
@weiji14 weiji14 self-assigned this Mar 26, 2022
Makefile Outdated
@@ -64,7 +64,7 @@ check:
docformatter --check $(DOCFORMATTER_OPTIONS) $(DOCFORMATTER_FILES)
black --check $(BLACK_FILES)
blackdoc --check $(BLACKDOC_OPTIONS) $(BLACK_FILES)
flake8 $(FLAKE8_FILES)
flakeheaven lint $(FLAKEHEAVEN_FILES)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can someone try and test this properly? I'm struggling to find a way to get this to fail for some reason, so need to check that it's actually doing something 😅

Copy link
Member Author

@weiji14 weiji14 May 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I installed a fresh conda virtual environment using the environment.yml in this branch and tried a simple command like flakeheaven lint --max-doc-length 9 pygmt/src/basemap.py which should fail, but no error was thrown. My guess is there's something broken in flakeheaven.

Edit: Seems to be fixed in flakeheaven=2.0.0 🎉

environment.yml Show resolved Hide resolved
@weiji14 weiji14 changed the title WIP Replace flake8 with flakeheaven Replace flake8 with flakeheaven May 10, 2022
pyproject.toml Outdated Show resolved Hide resolved
@seisman seisman modified the milestones: 0.7.0, 0.8.0 Jun 19, 2022
pyproject.toml Outdated
@@ -9,6 +9,12 @@ fallback_version = "999.999.999+unknown"
[tool.coverage.run]
omit = ["*/tests/*", "*pygmt/__init__.py"]

[tool.flakeheaven]
ignore = ["E203", "E266", "E501", "W503", "F401", "E741"]
Copy link
Member Author

@weiji14 weiji14 Jul 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the ignore list is not being respected by flakeheaven. Here's the Style Checks failures from https://github.com/GenericMappingTools/pygmt/runs/7275373864?check_suite_focus=true#step:5:18

FLAKEHEAVEN_CACHE_TIMEOUT=0 flakeheaven lint pygmt setup.py doc/conf.py examples
pygmt/__init__.py:25:1: F401'pygmt.datasets' imported but unused [pyflakes]
frompygmtimport datasets
  ^
pygmt/__init__.py:26:1: F401'pygmt.accessors.GMTDataArrayAccessor' imported but unused [pyflakes]
frompygmt.accessorsimport GMTDataArrayAccessor
  ^
pygmt/__init__.py:27:1: F401'pygmt.figure.Figure' imported but unused [pyflakes]
frompygmt.figureimport Figure, set_display
  ^
pygmt/__init__.py:27:1: F401'pygmt.figure.set_display' imported but unused [pyflakes]
frompygmt.figureimport Figure, set_display
  ^
pygmt/__init__.py:28:1: F401'pygmt.io.load_dataarray' imported but unused [pyflakes]
frompygmt.ioimport load_dataarray
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.binstats' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.blockmean' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.blockmedian' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.blockmode' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.config' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.dimfilter' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.filter1d' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.grd2cpt' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.grd2xyz' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.grdclip' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.grdcut' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.grdfill' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.grdfilter' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.grdgradient' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.grdhisteq' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.grdinfo' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.grdlandmask' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.grdproject' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.grdsample' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.grdtrack' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.grdvolume' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.info' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.makecpt' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.nearneighbor' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.project' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.select' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.sph2grd' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.sphdistance' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.sphinterpolate' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.surface' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.triangulate' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.which' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.x2sys_cross' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.x2sys_init' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/__init__.py:31:1: F401'pygmt.src.xyz2grd' imported but unused [pyflakes]
frompygmt.srcimport (
  ^
pygmt/datasets/samples.py:36:89: E501 line too long (96 > 88 characters) [pycodestyle]
"notre_dame_topography": "Table 5.11 in Davis: Statistics and Data Analysis in Geology",
                                                                                  ^
pygmt/datasets/__init__.py:5:1: F401'pygmt.datasets.earth_age.load_earth_age' imported but unused [pyflakes]
frompygmt.datasets.earth_ageimport load_earth_age
  ^
pygmt/datasets/__init__.py:6:1: F401'pygmt.datasets.earth_relief.load_earth_relief' imported but unused [pyflakes]
frompygmt.datasets.earth_reliefimport load_earth_relief
  ^
pygmt/datasets/__init__.py:7:1: F401'pygmt.datasets.samples.list_sample_data' imported but unused [pyflakes]
frompygmt.datasets.samplesimport (
  ^
pygmt/datasets/__init__.py:7:1: F401'pygmt.datasets.samples.load_fractures_compilation' imported but unused [pyflakes]
frompygmt.datasets.samplesimport (
  ^
pygmt/datasets/__init__.py:7:1: F401'pygmt.datasets.samples.load_hotspots' imported but unused [pyflakes]
frompygmt.datasets.samplesimport (
  ^
pygmt/datasets/__init__.py:7:1: F401'pygmt.datasets.samples.load_japan_quakes' imported but unused [pyflakes]
frompygmt.datasets.samplesimport (
  ^
pygmt/datasets/__init__.py:7:1: F401'pygmt.datasets.samples.load_mars_shape' imported but unused [pyflakes]
frompygmt.datasets.samplesimport (
  ^
pygmt/datasets/__init__.py:7:1: F401'pygmt.datasets.samples.load_ocean_ridge_points' imported but unused [pyflakes]
frompygmt.datasets.samplesimport (
  ^
pygmt/datasets/__init__.py:7:1: F401'pygmt.datasets.samples.load_sample_bathymetry' imported but unused [pyflakes]
frompygmt.datasets.samplesimport (
  ^
pygmt/datasets/__init__.py:7:1: F401'pygmt.datasets.samples.load_sample_data' imported but unused [pyflakes]
frompygmt.datasets.samplesimport (
  ^
pygmt/datasets/__init__.py:7:1: F401'pygmt.datasets.samples.load_usgs_quakes' imported but unused [pyflakes]
frompygmt.datasets.samplesimport (
  ^
pygmt/src/nearneighbor.py:60:89: E501 line too long (100 > 88 characters) [pycodestyle]
r"""
    Grid table data using a "Nearest neighbor" algorithm
    **nearneighbor** reads arbitrarily located (*x,y,z*\ [,\ *w*]) triples
    [quadruplets] and uses a nearest neighbor algorithm to assign a weighted
    average value to each node that has one or more data points within a search
    radius centered on the node with adequate coverage across a subset of the
    chosen sectors. The node value is computed as a weighted mean of the
    nearest point from each sector inside the search radius. The weighting
    function and the averaging used is given by:
    .. math::
        w(r_i) = \frac{{w_i}}{{1 + d(r_i) ^ 2}},
        \quad d(r) = \frac {{3r}}{{R}},
        \quad \bar{{z}} = \frac{{\sum_i^n w(r_i) z_i}}{{\sum_i^n w(r_i)}}
    where :math:`n` is the number of data points that satisfy the selection
    criteria and :math:`r_i` is the distance from the node to the *i*'th data
    point. If no data weights are supplied then :math:`w_i = 1`.
    .. figure:: https://docs.generic-mapping-tools.org/dev/_images/GMT_nearneighbor.png # noqa: W505
       :width: 300 px
       :align: center
       Search geometry includes the search radius (R) which limits the points
       considered and the number of sectors (here 4), which restricts how
       points inside the search radius contribute to the value at the node.
       Only the closest point in each sector (red circles) contribute to the
       weighted estimate.
    Takes a matrix, xyz triples, or a file name as input.
    Must provide either ``data`` or ``x``, ``y``, and ``z``.
    Full option list at :gmt-docs:`nearneighbor.html`
    {aliases}
    Parameters
    ----------
    data : str or {table-like}
        Pass in (x, y, z) or (longitude, latitude, elevation) values by
        providing a file name to an ASCII data table, a 2D
        {table-classes}.
    x/y/z : 1d arrays
        Arrays of x and y coordinates and values z of the data points.
    {I}
    {R}
    search_radius : str
        Sets the search radius that determines which data points are considered
        close to a node.
    outgrid : str
        Optional. The file name for the output netcdf file with extension .nc
        to store the grid in.
    empty : str
        Optional. Set the value assigned to empty nodes. Defaults to NaN.
    sectors : str
        *sectors*\ [**+m**\ *min_sectors*]\|\ **n**.
        Optional. The circular search area centered on each node is divided
        into *sectors* sectors. Average values will only be computed if there
        is *at least* one value inside each of at least *min_sectors* of the
        sectors for a given node. Nodes that fail this test are assigned the
        value NaN (but see ``empty``). If **+m** is omitted then *min_sectors*
        is set to be at least 50% of *sectors* (i.e., rounded up to next
        integer) [Default is a quadrant search with 100% coverage, i.e.,
        *sectors* = *min_sectors* = 4]. Note that only the nearest value per
        sector enters into the averaging; the more distant points are ignored.
        Alternatively, use ``sectors="n"`` to call GDAL's nearest neighbor
        algorithm instead.
    {V}
    {a}
    {b}
    {d}
    {e}
    {f}
    {g}
    {h}
    {i}
    {r}
    {w}
    Returns
    -------
    ret: xarray.DataArray or None
        Return type depends on whether the ``outgrid`` parameter is set:
        - :class:`xarray.DataArray`: if ``outgrid`` is not set
        - None if ``outgrid`` is set (grid output will be stored in file set by
          ``outgrid``)
    Example
    -------
    >>> import pygmt
    >>> # Load a sample dataset of bathymetric x, y, and z values
    >>> data = pygmt.datasets.load_sample_data(name="bathymetry")
    >>> # Create a new grid with 5 arc-minute spacing in the designated region
    >>> # Set search_radius to only consider points within 10 arc-minute of a node
    >>> output = pygmt.nearneighbor(
    ...     data=data,
    ...     spacing="5m",
    ...     region=[245, 255, 20, 30],
    ...     search_radius="10m",
    ... )
    """
                                                                                      ^
pygmt/src/meca.py:266:89: E501 line too long (91 > 88 characters) [pycodestyle]
  msg = "Column names in pd.DataFrame 'spec' do not match known conventions."
                                                                          ^
pygmt/src/text.py:192:13: W503 line break before binary operator [pycodestyle]
or angle isnotNone
  ^
pygmt/src/text.py:193:13: W503 line break before binary operator [pycodestyle]
or font isnotNone
  ^
pygmt/src/text.py:194:13: W503 line break before binary operator [pycodestyle]
or justify isnotNone
  ^
pygmt/src/plot3d.py:225:89: E501 line too long (93 > 88 characters) [pycodestyle]
f"Can't use arrays for {plot3d.aliases[flag]} if data is matrix or file."
                                                                      ^
pygmt/src/plot3d.py:193:9: W503 line break before binary operator [pycodestyle]
and kind == "geojson"
  ^
pygmt/src/plot3d.py:194:9: W503 line break before binary operator [pycodestyle]
and data.geom_type.isin(["Point", "MultiPoint"]).all()
  ^
pygmt/src/__init__.py:6:1: F401'pygmt.src.basemap.basemap' imported but unused [pyflakes]
frompygmt.src.basemapimport basemap
  ^
pygmt/src/__init__.py:7:1: F401'pygmt.src.binstats.binstats' imported but unused [pyflakes]
frompygmt.src.binstatsimport binstats
  ^
pygmt/src/__init__.py:8:1: F401'pygmt.src.blockm.blockmean' imported but unused [pyflakes]
frompygmt.src.blockmimport blockmean, blockmedian, blockmode
  ^
pygmt/src/__init__.py:8:1: F401'pygmt.src.blockm.blockmedian' imported but unused [pyflakes]
frompygmt.src.blockmimport blockmean, blockmedian, blockmode
  ^
pygmt/src/__init__.py:8:1: F401'pygmt.src.blockm.blockmode' imported but unused [pyflakes]
frompygmt.src.blockmimport blockmean, blockmedian, blockmode
  ^
pygmt/src/__init__.py:9:1: F401'pygmt.src.coast.coast' imported but unused [pyflakes]
frompygmt.src.coastimport coast
  ^
pygmt/src/__init__.py:10:1: F401'pygmt.src.colorbar.colorbar' imported but unused [pyflakes]
frompygmt.src.colorbarimport colorbar
  ^
pygmt/src/__init__.py:11:1: F401'pygmt.src.config.config' imported but unused [pyflakes]
frompygmt.src.configimport config
  ^
pygmt/src/__init__.py:12:1: F401'pygmt.src.contour.contour' imported but unused [pyflakes]
frompygmt.src.contourimport contour
  ^
pygmt/src/__init__.py:13:1: F401'pygmt.src.dimfilter.dimfilter' imported but unused [pyflakes]
frompygmt.src.dimfilterimport dimfilter
  ^
pygmt/src/__init__.py:14:1: F401'pygmt.src.filter1d.filter1d' imported but unused [pyflakes]
frompygmt.src.filter1dimport filter1d
  ^
pygmt/src/__init__.py:15:1: F401'pygmt.src.grd2cpt.grd2cpt' imported but unused [pyflakes]
frompygmt.src.grd2cptimport grd2cpt
  ^
pygmt/src/__init__.py:16:1: F401'pygmt.src.grd2xyz.grd2xyz' imported but unused [pyflakes]
frompygmt.src.grd2xyzimport grd2xyz
  ^
pygmt/src/__init__.py:17:1: F401'pygmt.src.grdclip.grdclip' imported but unused [pyflakes]
frompygmt.src.grdclipimport grdclip
  ^
pygmt/src/__init__.py:18:1: F401'pygmt.src.grdcontour.grdcontour' imported but unused [pyflakes]
frompygmt.src.grdcontourimport grdcontour
  ^
pygmt/src/__init__.py:19:1: F401'pygmt.src.grdcut.grdcut' imported but unused [pyflakes]
frompygmt.src.grdcutimport grdcut
  ^
pygmt/src/__init__.py:20:1: F401'pygmt.src.grdfill.grdfill' imported but unused [pyflakes]
frompygmt.src.grdfillimport grdfill
  ^
pygmt/src/__init__.py:21:1: F401'pygmt.src.grdfilter.grdfilter' imported but unused [pyflakes]
frompygmt.src.grdfilterimport grdfilter
  ^
pygmt/src/__init__.py:22:1: F401'pygmt.src.grdgradient.grdgradient' imported but unused [pyflakes]
frompygmt.src.grdgradientimport grdgradient
  ^
pygmt/src/__init__.py:23:1: F401'pygmt.src.grdhisteq.grdhisteq' imported but unused [pyflakes]
frompygmt.src.grdhisteqimport grdhisteq
  ^
pygmt/src/__init__.py:24:1: F401'pygmt.src.grdimage.grdimage' imported but unused [pyflakes]
frompygmt.src.grdimageimport grdimage
  ^
pygmt/src/__init__.py:25:1: F401'pygmt.src.grdinfo.grdinfo' imported but unused [pyflakes]
frompygmt.src.grdinfoimport grdinfo
  ^
pygmt/src/__init__.py:26:1: F401'pygmt.src.grdlandmask.grdlandmask' imported but unused [pyflakes]
frompygmt.src.grdlandmaskimport grdlandmask
  ^
pygmt/src/__init__.py:27:1: F401'pygmt.src.grdproject.grdproject' imported but unused [pyflakes]
frompygmt.src.grdprojectimport grdproject
  ^
pygmt/src/__init__.py:28:1: F401'pygmt.src.grdsample.grdsample' imported but unused [pyflakes]
frompygmt.src.grdsampleimport grdsample
  ^
pygmt/src/__init__.py:29:1: F401'pygmt.src.grdtrack.grdtrack' imported but unused [pyflakes]
frompygmt.src.grdtrackimport grdtrack
  ^
pygmt/src/__init__.py:30:1: F401'pygmt.src.grdview.grdview' imported but unused [pyflakes]
frompygmt.src.grdviewimport grdview
  ^
pygmt/src/__init__.py:31:1: F401'pygmt.src.grdvolume.grdvolume' imported but unused [pyflakes]
frompygmt.src.grdvolumeimport grdvolume
  ^
pygmt/src/__init__.py:32:1: F401'pygmt.src.histogram.histogram' imported but unused [pyflakes]
frompygmt.src.histogramimport histogram
  ^
pygmt/src/__init__.py:33:1: F401'pygmt.src.image.image' imported but unused [pyflakes]
frompygmt.src.imageimport image
  ^
pygmt/src/__init__.py:34:1: F401'pygmt.src.info.info' imported but unused [pyflakes]
frompygmt.src.infoimport info
  ^
pygmt/src/__init__.py:35:1: F401'pygmt.src.inset.inset' imported but unused [pyflakes]
frompygmt.src.insetimport inset
  ^
pygmt/src/__init__.py:36:1: F401'pygmt.src.legend.legend' imported but unused [pyflakes]
frompygmt.src.legendimport legend
  ^
pygmt/src/__init__.py:37:1: F401'pygmt.src.logo.logo' imported but unused [pyflakes]
frompygmt.src.logoimport logo
  ^
pygmt/src/__init__.py:38:1: F401'pygmt.src.makecpt.makecpt' imported but unused [pyflakes]
frompygmt.src.makecptimport makecpt
  ^
pygmt/src/__init__.py:39:1: F401'pygmt.src.meca.meca' imported but unused [pyflakes]
frompygmt.src.mecaimport meca
  ^
pygmt/src/__init__.py:40:1: F401'pygmt.src.nearneighbor.nearneighbor' imported but unused [pyflakes]
frompygmt.src.nearneighborimport nearneighbor
  ^
pygmt/src/__init__.py:41:1: F401'pygmt.src.plot.plot' imported but unused [pyflakes]
frompygmt.src.plotimport plot
  ^
pygmt/src/__init__.py:42:1: F401'pygmt.src.plot3d.plot3d' imported but unused [pyflakes]
frompygmt.src.plot3dimport plot3d
  ^
pygmt/src/__init__.py:43:1: F401'pygmt.src.project.project' imported but unused [pyflakes]
frompygmt.src.projectimport project
  ^
pygmt/src/__init__.py:44:1: F401'pygmt.src.rose.rose' imported but unused [pyflakes]
frompygmt.src.roseimport rose
  ^
pygmt/src/__init__.py:45:1: F401'pygmt.src.select.select' imported but unused [pyflakes]
frompygmt.src.selectimport select
  ^
pygmt/src/__init__.py:46:1: F401'pygmt.src.solar.solar' imported but unused [pyflakes]
frompygmt.src.solarimport solar
  ^
pygmt/src/__init__.py:47:1: F401'pygmt.src.sph2grd.sph2grd' imported but unused [pyflakes]
frompygmt.src.sph2grdimport sph2grd
  ^
pygmt/src/__init__.py:48:1: F401'pygmt.src.sphdistance.sphdistance' imported but unused [pyflakes]
frompygmt.src.sphdistanceimport sphdistance
  ^
pygmt/src/__init__.py:49:1: F401'pygmt.src.sphinterpolate.sphinterpolate' imported but unused [pyflakes]
frompygmt.src.sphinterpolateimport sphinterpolate
  ^
pygmt/src/__init__.py:50:1: F401'pygmt.src.subplot.set_panel' imported but unused [pyflakes]
frompygmt.src.subplotimport set_panel, subplot
  ^
pygmt/src/__init__.py:50:1: F401'pygmt.src.subplot.subplot' imported but unused [pyflakes]
frompygmt.src.subplotimport set_panel, subplot
  ^
pygmt/src/__init__.py:51:1: F401'pygmt.src.surface.surface' imported but unused [pyflakes]
frompygmt.src.surfaceimport surface
  ^
pygmt/src/__init__.py:52:1: F401'pygmt.src.text.text_ as text' imported but unused [pyflakes]
frompygmt.src.textimport text_ as text  # "text" is an argument within "text_"
  ^
pygmt/src/__init__.py:53:1: F401'pygmt.src.triangulate.triangulate' imported but unused [pyflakes]
frompygmt.src.triangulateimport triangulate
  ^
pygmt/src/__init__.py:54:1: F401'pygmt.src.velo.velo' imported but unused [pyflakes]
frompygmt.src.veloimport velo
  ^
pygmt/src/__init__.py:55:1: F401'pygmt.src.which.which' imported but unused [pyflakes]
frompygmt.src.whichimport which
  ^
pygmt/src/__init__.py:56:1: F401'pygmt.src.wiggle.wiggle' imported but unused [pyflakes]
frompygmt.src.wiggleimport wiggle
  ^
pygmt/src/__init__.py:57:1: F401'pygmt.src.x2sys_cross.x2sys_cross' imported but unused [pyflakes]
frompygmt.src.x2sys_crossimport x2sys_cross
  ^
pygmt/src/__init__.py:58:1: F401'pygmt.src.x2sys_init.x2sys_init' imported but unused [pyflakes]
frompygmt.src.x2sys_initimport x2sys_init
  ^
pygmt/src/__init__.py:59:1: F401'pygmt.src.xyz2grd.xyz2grd' imported but unused [pyflakes]
frompygmt.src.xyz2grdimport xyz2grd
  ^
pygmt/src/plot.py:255:89: E501 line too long (91 > 88 characters) [pycodestyle]
f"Can't use arrays for {plot.aliases[flag]} if data is matrix or file."
                                                                      ^
pygmt/src/plot.py:223:9: W503 line break before binary operator [pycodestyle]
and kind == "geojson"
  ^
pygmt/src/plot.py:224:9: W503 line break before binary operator [pycodestyle]
and data.geom_type.isin(["Point", "MultiPoint"]).all()
  ^
pygmt/tests/test_grdfill.py:91:89: E501 line too long (95 > 88 characters) [pycodestyle]
  reason="Upstream bug/crash fixed in https://github.com/GenericMappingTools/gmt/pull/6418.",
                                                                                      ^
pygmt/clib/session.py:507:89: E501 line too long (93 > 88 characters) [pycodestyle]
f"Module '{module}' failed with status code {status}:\n{self._error_message}"
                                                                          ^
pygmt/clib/session.py:652:89: E501 line too long (94 > 88 characters) [pycodestyle]
f"Only one modifier is allowed in constants, {nmodifiers} given: '{constant}'"
                                                                          ^
pygmt/clib/session.py:669:89: E501 line too long (97 > 88 characters) [pycodestyle]
f"Invalid constant modifier '{parts[1]}'. Must be one of {str(valid_modifiers)}."
                                                                          ^
pygmt/clib/session.py:657:17: W503 line break before binary operator [pycodestyle]
  + f"given: '{constant}'"
  ^
pygmt/clib/session.py:665:13: W503 line break before binary operator [pycodestyle]
and valid_modifiers isnotNone
  ^
pygmt/clib/session.py:666:13: W503 line break before binary operator [pycodestyle]
and parts[1] notin valid_modifiers
  ^
pygmt/clib/__init__.py:8:1: F401'pygmt.clib.session.Session' imported but unused [pyflakes]
frompygmt.clib.sessionimport Session
  ^
pygmt/helpers/utils.py:86:13: W503 line break before binary operator [pycodestyle]
orlen(getattr(data, "data_vars", (0, 1, 2))) < 3# xr.Dataset
  ^
pygmt/helpers/decorators.py:284:89: E501 line too long (98 > 88 characters) [pycodestyle]
"n": r"""
        interpolation : str
            [**b**\|\ **c**\|\ **l**\|\ **n**][**+a**][**+b**\ *BC*][**+c**][**+t**\ *threshold*].
            Select interpolation mode for grids. You can select the type of
            spline used:
            - **b** for B-spline
            - **c** for bicubic [Default]
            - **l** for bilinear
            - **n** for nearest-neighbor""",
                                                                                      ^
pygmt/helpers/decorators.py:798:89: E501 line too long (94 > 88 characters) [pycodestyle]
f"The '{oldname}' parameter has been deprecated since {deprecate_version}"
                                                                      ^
pygmt/helpers/__init__.py:4:1: F401'pygmt.helpers.decorators.deprecate_parameter' imported but unused [pyflakes]
frompygmt.helpers.decoratorsimport (
  ^
pygmt/helpers/__init__.py:4:1: F401'pygmt.helpers.decorators.fmt_docstring' imported but unused [pyflakes]
frompygmt.helpers.decoratorsimport (
  ^
pygmt/helpers/__init__.py:4:1: F401'pygmt.helpers.decorators.kwargs_to_strings' imported but unused [pyflakes]
frompygmt.helpers.decoratorsimport (
  ^
pygmt/helpers/__init__.py:4:1: F401'pygmt.helpers.decorators.use_alias' imported but unused [pyflakes]
frompygmt.helpers.decoratorsimport (
  ^
pygmt/helpers/__init__.py:10:1: F401'pygmt.helpers.tempfile.GMTTempFile' imported but unused [pyflakes]
frompygmt.helpers.tempfileimport GMTTempFile, tempfile_from_geojson, unique_name
  ^
pygmt/helpers/__init__.py:10:1: F401'pygmt.helpers.tempfile.tempfile_from_geojson' imported but unused [pyflakes]
frompygmt.helpers.tempfileimport GMTTempFile, tempfile_from_geojson, unique_name
  ^
pygmt/helpers/__init__.py:10:1: F401'pygmt.helpers.tempfile.unique_name' imported but unused [pyflakes]
frompygmt.helpers.tempfileimport GMTTempFile, tempfile_from_geojson, unique_name
  ^
pygmt/helpers/__init__.py:11:1: F401'pygmt.helpers.utils.args_in_kwargs' imported but unused [pyflakes]
frompygmt.helpers.utilsimport (
  ^
pygmt/helpers/__init__.py:11:1: F401'pygmt.helpers.utils.build_arg_string' imported but unused [pyflakes]
frompygmt.helpers.utilsimport (
  ^
pygmt/helpers/__init__.py:11:1: F401'pygmt.helpers.utils.data_kind' imported but unused [pyflakes]
frompygmt.helpers.utilsimport (
  ^
pygmt/helpers/__init__.py:11:1: F401'pygmt.helpers.utils.dummy_context' imported but unused [pyflakes]
frompygmt.helpers.utilsimport (
  ^
pygmt/helpers/__init__.py:11:1: F401'pygmt.helpers.utils.is_nonstr_iter' imported but unused [pyflakes]
frompygmt.helpers.utilsimport (
  ^
pygmt/helpers/__init__.py:11:1: F401'pygmt.helpers.utils.launch_external_viewer' imported but unused [pyflakes]
frompygmt.helpers.utilsimport (
  ^
examples/gallery/embellishments/colorbar.py:29:1: E266 too many leading '#' for block comment [pycodestyle]
## Create a colorbar designed for seismic tomography - roma
  ^
examples/gallery/embellishments/colorbar.py:33:1: E266 too many leading '#' for block comment [pycodestyle]
## Create a colorbar showing the scientific rainbow - batlow
  ^
examples/gallery/embellishments/colorbar.py:44:1: E266 too many leading '#' for block comment [pycodestyle]
## Create a colorbar suitable for surface topography - oleron
  ^
examples/gallery/3d_plots/grdview_surface.py:27:9: W503 line break before binary operator [pycodestyle]
  - np.exp(0.5 * (np.cos(2 * np.pi * x) + np.cos(2 * np.pi * y)))
  ^
examples/gallery/3d_plots/grdview_surface.py:28:9: W503 line break before binary operator [pycodestyle]
  + np.exp(1)
  ^
examples/gallery/3d_plots/grdview_surface.py:29:9: W503 line break before binary operator [pycodestyle]
  + 20
  ^
examples/gallery/3d_plots/scatter3d.py:82:89: E501 line too long (93 > 88 characters) [pycodestyle]
'WsNeZ3+t"Iris flower data set"',  # z axis label positioned on 3rd corner, add title
                                                                                  ^
make: *** [Makefile:67: check] Error 1
Error: Process completed with exit code 2.

May need to read into flakeheaven/flakeheaven#83 and see how the exception list is handled in flakeheaven compared to flake8 before.

Edit: fixed in 30a9267, see also #1847 (comment)

Copy link
Member Author

@weiji14 weiji14 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still a few rough edges due to missing features/bugs in flakeheaven, but I think it's ready for review!

pyproject.toml Outdated
Comment on lines 17 to 19
[tool.flakeheaven.plugins]
pycodestyle = ["+*", "-E266", "-E501", "-W503"]
pyflakes = ["+*", "-F401"]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like flakeheaven exceptions need to be handled here (see https://flakeheaven.readthedocs.io/en/latest/config.html#ignored-options).

For reference, original list from setup.cfg was E203, E266, E501, W503, F401, E741. The removed exceptions are E203 W503.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • E203: Whitespace before ':'
  • E266: Too many leading '#' for block comment
  • E501: Line too long (82 > 79 characters)
  • W503: Line break occurred before a binary operator
  • F401: Module imported but unused
  • E741: Do not use variables named 'I', 'O', or 'l'

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm OK with removing E203 and E741.

  1. Perhaps we can also remove E266. The only file that violate this rule is examples/gallery/embellishments/colorbar.py
  2. For F401, I don't think it's a good idea to ignore all "imported-but-unused" modules. Instead, we should only ignore the rules in specific files (e.g., **/__init__.py). This can be done by using flakeheaven's exceptions settings (https://flakeheaven.readthedocs.io/en/latest/config.html#example).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, removed E266 in 6822d87 and made F401 specific to **/__init__.py files only in 7dd65fa!

@@ -64,7 +64,7 @@ check:
docformatter --check $(DOCFORMATTER_OPTIONS) $(DOCFORMATTER_FILES)
black --check $(BLACK_FILES)
blackdoc --check $(BLACKDOC_OPTIONS) $(BLACK_FILES)
flake8 $(FLAKE8_FILES)
FLAKEHEAVEN_CACHE_TIMEOUT=0 flakeheaven lint $(FLAKEHEAVEN_FILES)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The FLAKEHEAVEN_CACHE_TIMEOUT cache invalidation flag might not be needed once flakeheaven/flakeheaven#87 is merged into flakeheaven and a new release is made.

@weiji14 weiji14 marked this pull request as ready for review July 11, 2022 03:37
environment.yml Outdated Show resolved Hide resolved
@seisman seisman added the needs review This PR has higher priority and needs review. label Jul 11, 2022
weiji14 and others added 5 commits August 18, 2022 08:43
Includes a fix that forwards max_line_length to pylint plugin.

Co-Authored-By: Dongdong Tian <[email protected]>
Removed some double ## in colorbar gallery example to allow this check to pass.
@seisman seisman added final review call This PR requires final review and approval from a second reviewer and removed needs review This PR has higher priority and needs review. labels Aug 18, 2022
@seisman seisman merged commit f263b13 into main Aug 19, 2022
@seisman seisman deleted the flake8-to-flakeheaven branch August 19, 2022 12:39
@seisman seisman removed the final review call This PR requires final review and approval from a second reviewer label Aug 19, 2022
sixy6e pushed a commit to sixy6e/pygmt that referenced this pull request Dec 21, 2022
* Replace flake8 with flakeheaven
* Install flakeheaven from conda-forge instead of pypi
* Invalidate flakeheaven cache
* Ignore pycodestyle and pyflakes errors in flakeheaven plugins section
* Pin minimum flakeheaven version to 3.0.0
* Enforce pycodestyle E266 Too many leading '#' for block comment
* Ignore pyflakes F401 'Module imported but unused' for __init__.py only

Co-Authored-By: Dongdong Tian <[email protected]>
@seisman seisman mentioned this pull request Dec 31, 2022
7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
maintenance Boring but important stuff for the core devs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants