Skip to content

Commit

Permalink
enforce all ruff rules (#531)
Browse files Browse the repository at this point in the history
  • Loading branch information
bjlittle authored Nov 22, 2023
1 parent ccd935f commit 3e79bf1
Show file tree
Hide file tree
Showing 84 changed files with 502 additions and 436 deletions.
45 changes: 45 additions & 0 deletions .ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
extend = "pyproject.toml"

lint.ignore = [
# NOTE: To find a rule code to fix, run:
# ruff --select="ALL" --statistics src/geovista/<subpackage>

# flake8-boolean-trap (FBT)
# NOTE: A good thing to fix, but changes API.
"FBT001", # boolean-positional-arg-in-function-definition.
"FBT002", # boolean-default-value-in-function-definition.
"FBT003", # boolean-positional-value-in-function-call.

# Pylint (PL)
"PLR0912", # Too many branches.
"PLR0913", # Too many arguments in function definition.
"PLR0915", # Too many statements.
"PLR2004", # Magic value used in comparison, consider replacing with a constant.
"PLW0603", # Using the global statement to update is discouraged.

# flake8-self (SLF)
"SLF001", # Private member accessed.

# flake8-todos (TD)
"TD003", # Missing issue link on the line following this TODO.
]

[lint.extend-per-file-ignores]
"conftest.py" = [
# flake8-annotations (ANN)
"ANN001", # Missing type annotation for function argument.
"ANN201", # Missing return type annotation for public function.
]
"src/geovista/geoplotter.py" = [
# flake8-annotations (ANN)
"ANN401", # Dynamically typed expressions (typing.Any).
]
"test_*.py" = [
# flake8-annotations (ANN)
"ANN001", # Missing type annotation for function argument.
"ANN201", # Missing return type annotation for public funciton.
]
"test_slice_lines.py" = [
# eradicate (ERA)
"ERA001", # Found commented-out code.
]
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ include .gitattributes
exclude .gitignore
exclude .pre-commit-config.yaml
exclude .readthedocs.yml
exclude .ruff.toml
include *.md
include CITATION.cff
exclude codecov.yml
Expand Down
56 changes: 43 additions & 13 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,38 @@ target-version = "py310"

[tool.ruff.lint]
ignore = [
"D105", # pydocstyle: undocumented-magic-method
# NOTE: Non-permanent exclusions should be added to ".ruff.toml".

# flake8-annotations (ANN)
"ANN101", # Missing type annotation for 'self' in method.
"ANN102", # Missing type annotation for 'cls' in classmethod.

# flake8-commas (COM)
"COM812", # Trailing comma missing.
"COM819", # Trailing comma prohibited.

# pydocstyle (D)
"D105", # Missing docstring in magic method.

# flake8-fixme (FIX)
"FIX002", # Line contains TODO, consider resolving the issue.

# pep8-naming
"N806", # Variable name in function should be lowercase.
"N999", # Invalid module name.

# pandas-vet (PD)
"PD",

# Ruff-specific rules (RUF)
"RUF005", # Consider {expression} instead of concatenation.

# flake8-bandit (S)
"S101", # Use of assert detected.
]
preview = false
select = [
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"I", # isort
"E", # pycodestyle
"W",
"D", # pydocstyle
"F", # pyflakes
"UP", # pyupgrade
"ALL",
]


Expand All @@ -136,13 +157,22 @@ required-imports = ["from __future__ import annotations"]


[tool.ruff.lint.mccabe]
max-complexity = 22
max-complexity = 26


[tool.ruff.lint.per-file-ignores]
"src/geovista/examples/earthquakes.py" = ["E501"]
"src/geovista/examples/earthquakes_wink1.py" = ["E501"]
"src/geovista/report.py" = ["E722"]
"src/geovista/cli.py" = [
"T201", # flake8-print: print found.
]
"src/geovista/examples/*.py" = [
"TCH002", # flake8-type-checking: Move 3rd-party import into a type checking block.
]
"src/geovista/examples/earthquakes.py" = [
"E501", # pycodestyle: Line too long.
]
"src/geovista/examples/earthquakes_wink1.py" = [
"E501", # pycodestyle: Line too long.
]


[tool.ruff.lint.pydocstyle]
Expand Down
Empty file modified setup.py
100644 → 100755
Empty file.
12 changes: 6 additions & 6 deletions src/geovista/bridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
"""
from __future__ import annotations

from typing import TYPE_CHECKING
import warnings

import numpy as np
from numpy import ma
from numpy.typing import ArrayLike
from pyproj import CRS
import pyvista as pv

Expand All @@ -32,6 +32,9 @@
from .crs import WGS84, CRSLike, to_wkt
from .transform import transform_points

if TYPE_CHECKING:
from numpy.typing import ArrayLike

__all__ = ["Transform"]

# type aliases
Expand Down Expand Up @@ -217,9 +220,7 @@ def _create_connectivity_m1n1(shape: Shape) -> np.ndarray:
nodes_c2 = np.ravel(idxs[:-1, 1:]).reshape(-1, 1)
nodes_c3 = np.ravel(idxs[:-1, :-1]).reshape(-1, 1)

connectivity = np.hstack([nodes_c0, nodes_c1, nodes_c2, nodes_c3])

return connectivity
return np.hstack([nodes_c0, nodes_c1, nodes_c2, nodes_c3])

@staticmethod
def _create_connectivity_mn4(shape: Shape) -> np.ndarray:
Expand Down Expand Up @@ -258,9 +259,8 @@ def _create_connectivity_mn4(shape: Shape) -> np.ndarray:

# we know that we can only be dealing with a quad mesh
npts = np.prod(shape) * 4
connectivity = np.arange(npts, dtype=np.uint32).reshape(-1, 4)

return connectivity
return np.arange(npts, dtype=np.uint32).reshape(-1, 4)

@staticmethod
def _verify_2d(xs: ArrayLike, ys: ArrayLike) -> None:
Expand Down
4 changes: 2 additions & 2 deletions src/geovista/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ def fetch_coastlines(resolution: str | None = None) -> pv.PolyData:
fname = f"ne_coastlines_{resolution}.vtk"
processor = pooch.Decompress(method="auto", name=fname)
resource = CACHE.fetch(f"natural_earth/physical/{fname}.bz2", processor=processor)
mesh = pv.read(resource)
return mesh

return pv.read(resource)


def natural_earth_1(location: bool | None = False) -> TextureLike:
Expand Down
6 changes: 3 additions & 3 deletions src/geovista/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ def download(
previous_path = CACHE.path
CACHE.path = output

def collect(prefix):
def collect(prefix: str) -> list[str]:
return list(filter(lambda item: item.startswith(prefix), fnames))

if pull:
Expand Down Expand Up @@ -380,7 +380,7 @@ def collect(prefix):
is_flag=True,
help="Enable example diagnostics.",
)
def examples(run_all, show, run, verbose):
def examples(run_all: bool, show: bool, run: bool, verbose: bool) -> None:
"""Execute a geovista example script."""
# account for the initial "all" option
n_scripts = len(SCRIPTS) - 1
Expand Down Expand Up @@ -436,7 +436,7 @@ def examples(run_all, show, run, verbose):
is_flag=True,
help="Add a base layer",
)
def plot(fname, axes, base) -> None:
def plot(fname: str, axes: bool, base: bool) -> None:
"""Load and render a VTK mesh."""
mesh = pv.read(fname)
plotter = GeoPlotter()
Expand Down
61 changes: 31 additions & 30 deletions src/geovista/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@
from collections.abc import Iterable
from enum import Enum
import sys
from typing import Any
from typing import TYPE_CHECKING

import numpy as np
from numpy import ma
from numpy.typing import ArrayLike
import pyvista as pv
from pyvista import _vtk
from pyvista.core.filters import _get_output
from vtk import vtkLogger, vtkObject

if TYPE_CHECKING:
from numpy.typing import ArrayLike

__all__ = [
"BASE",
"CENTRAL_MERIDIAN",
Expand Down Expand Up @@ -60,9 +62,7 @@
"wrap",
]

#
# TODO: support richer default management
#
# TODO @bjlittle: support richer default management

#: Default base for wrapped longitude half-open interval, in degrees.
BASE: float = -180.0
Expand Down Expand Up @@ -214,11 +214,11 @@ def __str__(self) -> str:
.. versionadded:: 0.3.0
"""
# TODO: remove when minimum supported python version is 3.11
# TODO @bjlittle: Remove when minimum supported python version is 3.11.
return f"{self.name.lower()}"


# TODO: use StrEnum and auto when minimum supported python version is 3.11
# TODO @bjlittle: Use StrEnum and auto when minimum supported python version is 3.11.
class Preference(_MixinStrEnum, Enum):
"""Enumeration of common mesh geometry preferences.
Expand Down Expand Up @@ -257,7 +257,7 @@ def active_kernel() -> bool:
return result


def cast_UnstructuredGrid_to_PolyData(
def cast_UnstructuredGrid_to_PolyData( # noqa: N802
mesh: pv.UnstructuredGrid,
clean: bool | None = False,
) -> pv.PolyData:
Expand Down Expand Up @@ -405,22 +405,27 @@ def from_cartesian(

zlevel = np.zeros_like(lons)

if cloud:
if GV_FIELD_RADIUS in mesh.field_data and GV_FIELD_ZSCALE in mesh.field_data:
# field data injected by geovista.bridge.Transform.from_points
base = mesh[GV_FIELD_RADIUS][0]
zscale = mesh[GV_FIELD_ZSCALE][0]
zlevel = (radius - base) / (base * zscale)
if (
cloud
and GV_FIELD_RADIUS in mesh.field_data
and GV_FIELD_ZSCALE in mesh.field_data
):
# field data injected by geovista.bridge.Transform.from_points
base = mesh[GV_FIELD_RADIUS][0]
zscale = mesh[GV_FIELD_ZSCALE][0]
zlevel = (radius - base) / (base * zscale)

data = [lons, lats, zlevel]

# XXX: manage pole longitudes. an alternative future scheme could be more
# generic and inclusive, but this approach tackles the main use case for now
# TODO: refactor this into a separate function
# TODO @bjlittle: Manage pole longitudes. an alternative future scheme could be
# more generic and inclusive, but this approach tackles the main
# use case for now.

# TODO @bjlittle: Refactor this into a separate function.
pole_pids = np.where(np.isclose(np.abs(lats), 90))[0]
if pole_pids.size:
# enforce a common longitude for pole singularities
# TODO: review this strategy
# TODO @bjlittle: Review this strategy.
lons[pole_pids] = 0

if (
Expand All @@ -437,7 +442,7 @@ def from_cartesian(
pole_cids = np.unique(pole_submesh["vtkOriginalCellIds"])
for cid in pole_cids:
# get the pids (point-indices) of the polar cell points
# XXX: pyvista 0.38.0: cell_point_ids(cid) -> get_cell(cid).point_ids
# NOTE: pyvista 0.38.0: cell_point_ids(cid) -> get_cell(cid).point_ids
cell_pids = np.array(mesh.get_cell(cid).point_ids)
# unfold polar quad-cells
if len(cell_pids) == 4:
Expand Down Expand Up @@ -478,7 +483,7 @@ def from_cartesian(
seam_mask = np.isclose(np.abs(seam_lons), 180)
lons[seam_ids[seam_mask]] = 180
elif mesh.n_lines:
# TODO: unify closed interval strategies for lines and cells
# TODO @bjlittle: Unify closed interval strategies for lines and cells.
poi_mask = np.isclose(np.abs(lons), 180)

if np.any(poi_mask):
Expand All @@ -498,9 +503,7 @@ def from_cartesian(

lons[pids] = 180

result = np.vstack(data).T if stacked else np.array(data)

return result
return np.vstack(data).T if stacked else np.array(data)


def nan_mask(data: ArrayLike) -> np.ndarray:
Expand Down Expand Up @@ -555,7 +558,7 @@ def point_cloud(mesh: pv.PolyData) -> bool:


def sanitize_data(
*meshes: Any,
*meshes: Iterable[pv.PolyData],
) -> None:
"""Purge standard VTK helper cell and point data index arrays.
Expand Down Expand Up @@ -691,9 +694,8 @@ def to_cartesian(
y = np.ravel(radius * np.sin(y_rad) * np.sin(x_rad))
z = np.ravel(radius * np.cos(y_rad))
xyz = [x, y, z]
xyz = np.vstack(xyz).T if stacked else np.array(xyz)

return xyz
return np.vstack(xyz).T if stacked else np.array(xyz)


def to_lonlat(
Expand Down Expand Up @@ -817,8 +819,8 @@ def to_lonlats(
lons = wrap(lons, base=base, period=period, rtol=rtol, atol=atol)

z_radius = points[:, 2] / radius
# XXX: defensive clobber of values outside arcsin domain [-1, 1]
# which is the result of floating point inaccuracies at the extremes
# NOTE: defensive clobber of values outside arcsin domain [-1, 1]
# which is the result of floating point inaccuracies at the extremes
if indices := np.where(z_radius > 1):
z_radius[indices] = 1.0
if indices := np.where(z_radius < -1):
Expand All @@ -828,9 +830,8 @@ def to_lonlats(
lats = np.degrees(lats)

data = [lons, lats]
result = np.vstack(data).T if stacked else np.array(data)

return result
return np.vstack(data).T if stacked else np.array(data)


def triangulated(surface: pv.PolyData) -> bool:
Expand Down
Loading

0 comments on commit 3e79bf1

Please sign in to comment.