Skip to content

Commit

Permalink
MAINT: Adding spellcheck and rst to pre-commit hooks and add Bugbear …
Browse files Browse the repository at this point in the history
…as Ruff setting (#689)
  • Loading branch information
hoxbro authored Nov 21, 2023
1 parent a7a73b2 commit 0201068
Show file tree
Hide file tree
Showing 15 changed files with 85 additions and 62 deletions.
13 changes: 11 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ repos:
- id: check-json
- id: detect-private-key
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.3
rev: v0.1.6
hooks:
- id: ruff
args: [geoviews]
files: geoviews/
- repo: https://github.com/hoxbro/clean_notebook
rev: v0.1.13
Expand All @@ -35,3 +34,13 @@ repos:
- id: codespell
additional_dependencies:
- tomli
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.10.0
hooks:
- id: rst-backticks
- id: rst-directive-colons
- id: rst-inline-touching-normal
- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.9.0.6
hooks:
- id: shellcheck
8 changes: 4 additions & 4 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ notebook::
cd geoviews-examples
jupyter notebook

(Here `geoviews examples` is a shorthand for `geoviews copy-examples
(Here ``geoviews examples`` is a shorthand for ``geoviews copy-examples
--path geoviews-examples && geoviews fetch-data --path
geoviews-examples`.)
geoviews-examples``.)

In the classic Jupyter notebook environment and JupyterLab, first make
sure to load the ``gv.extension()``. For versions of
Expand All @@ -59,8 +59,8 @@ Once you have installed JupyterLab and the extension launch it with::
jupyter-lab

If you want to try out the latest features between releases, you can
get the latest dev release by specifying `-c pyviz/label/dev` in place
of `-c pyviz`.
get the latest dev release by specifying ``-c pyviz/label/dev`` in place
of ``-c pyviz``.

Additional dependencies
=======================
Expand Down
6 changes: 3 additions & 3 deletions doc/releases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ instead. The ``Wikipedia`` tile source will be removed in version
``rioxarray.open_rasterio`` to load GeoTIFFs into a
``xarray.DataArray``.

Note, this release has a minor breaking change where `gv.feature.states`
defaults to `fill_color=None` so the fill color is transparent.
Note, this release has a minor breaking change where ``gv.feature.states``
defaults to ``fill_color=None`` so the fill color is transparent.

Enhancements:

Expand Down Expand Up @@ -358,7 +358,7 @@ Features:
* Added geographic projection awareness to ``hv.annotate`` function (`#377 <https://github.com/holoviz/geoviews/pull/377>`_, `#419 <https://github.com/holoviz/geoviews/pull/419>`_)
* Rewrote geometry interfaces such as geopandas to conform to new HoloViews geometry protocol (`#407 <https://github.com/holoviz/geoviews/pull/407>`_)
* Implement consistent .geom method on geometry types (e.g. Path, Polygons, Points) (`#424 <https://github.com/holoviz/geoviews/pull/424>`_)
* Add new `Rectangles` and `Segments` elements (`#377 <https://github.com/holoviz/geoviews/pull/377>`_)
* Add new ``Rectangles`` and ``Segments`` elements (`#377 <https://github.com/holoviz/geoviews/pull/377>`_)

Bug fixes:

Expand Down
4 changes: 3 additions & 1 deletion geoviews/data/geom_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,9 @@ def iloc(cls, dataset, index):
return data

@classmethod
def sample(cls, dataset, samples=[]):
def sample(cls, dataset, samples=None):
if samples is None:
samples = []
raise NotImplementedError('sampling operation not implemented for geometries.')

@classmethod
Expand Down
18 changes: 12 additions & 6 deletions geoviews/data/geopandas.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def geo_column(cls, data):
except AttributeError:
if len(data):
raise ValueError('No geometry column found in geopandas.DataFrame, '
'use the PandasInterface instead.')
'use the PandasInterface instead.') from None
return None

@classmethod
Expand Down Expand Up @@ -314,12 +314,16 @@ def reindex(cls, dataset, kdims=None, vdims=None):
return dataset.data

@classmethod
def sample(cls, columns, samples=[]):
def sample(cls, columns, samples=None):
if samples is None:
samples = []
raise NotImplementedError


@classmethod
def sort(cls, dataset, by=[], reverse=False):
def sort(cls, dataset, by=None, reverse=False):
if by is None:
by = []
geo_dims = cls.geom_dims(dataset)
if any(d in geo_dims for d in by):
raise DataError("SpatialPandasInterface does not allow sorting "
Expand Down Expand Up @@ -398,7 +402,7 @@ def values(cls, dataset, dimension, expanded=True, flat=True, compute=True, keep
ds = dataset.clone(dict_data, datatype=['geom_dictionary'])
values = []
geom_type = data.geom_type.iloc[0]
for i, row in data.iterrows():
for _i, row in data.iterrows():
ds.data = row.to_dict()
if new_geo_col_name != default_geo_name:
ds.data[new_geo_col_name] = ds.data.pop(default_geo_name)
Expand Down Expand Up @@ -496,7 +500,7 @@ def split(cls, dataset, start, end, datatype, **kwargs):
d.update({vd.name: row[vd.name] for vd in dataset.vdims})
geom_type = cls.geom_type(dataset)
ds = dataset.clone([d], datatype=['multitabular'])
for i, row in dataset.data.iterrows():
for _i, row in dataset.data.iterrows():
if datatype == 'geom':
objs.append(row[col])
continue
Expand Down Expand Up @@ -544,7 +548,7 @@ def get_geom_type(geom):
return 'Polygon'


def to_geopandas(data, xdim, ydim, columns=[], geom='point'):
def to_geopandas(data, xdim, ydim, columns=None, geom='point'):
"""Converts list of dictionary format geometries to spatialpandas line geometries.
Args:
Expand All @@ -560,6 +564,8 @@ def to_geopandas(data, xdim, ydim, columns=[], geom='point'):
from shapely.geometry import (
Point, LineString, Polygon, MultiPoint, MultiPolygon, MultiLineString
)
if columns is None:
columns = []
poly = any('holes' in d for d in data) or geom == 'Polygon'
if poly:
single_type, multi_type = Polygon, MultiPolygon
Expand Down
8 changes: 6 additions & 2 deletions geoviews/data/iris.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,10 +356,12 @@ def length(cls, dataset):


@classmethod
def sort(cls, columns, by=[], reverse=False):
def sort(cls, columns, by=None, reverse=False):
"""
Cubes are assumed to be sorted by default.
"""
if by is None:
by = []
return columns


Expand All @@ -372,10 +374,12 @@ def aggregate(cls, columns, kdims, function, **kwargs):


@classmethod
def sample(cls, dataset, samples=[]):
def sample(cls, dataset, samples=None):
"""
Sampling currently not implemented.
"""
if samples is None:
samples = []
raise NotImplementedError


Expand Down
6 changes: 4 additions & 2 deletions geoviews/element/geo.py
Original file line number Diff line number Diff line change
Expand Up @@ -928,7 +928,7 @@ def from_shapefile(cls, shapefile, *args, **kwargs):

@classmethod
def from_records(cls, records, dataset=None, on=None, value=None,
index=[], drop_missing=False, element=None, **kwargs):
index=None, drop_missing=False, element=None, **kwargs):
"""
Load data from a collection of `cartopy.io.shapereader.Record`
objects and optionally merge it with a dataset to assign
Expand Down Expand Up @@ -965,6 +965,8 @@ def from_records(cls, records, dataset=None, on=None, value=None,
shapes: Polygons or Path object
A Polygons or Path object containing the geometries
"""
if index is None:
index = []
if dataset is not None and not on:
raise ValueError('To merge dataset with shapes mapping '
'must define attribute(s) to merge on.')
Expand Down Expand Up @@ -1002,7 +1004,7 @@ def from_records(cls, records, dataset=None, on=None, value=None,
vdims = []

data = []
for i, rec in enumerate(records):
for rec in records:
geom = {}
if dataset:
selection = {dim: rec.attributes.get(attr, None)
Expand Down
2 changes: 1 addition & 1 deletion geoviews/operation/regrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def _get_regridder(self, element):
try:
import xesmf as xe
except ImportError:
raise ImportError("xESMF library required for weighted regridding.")
raise ImportError("xESMF library required for weighted regridding.") from None
x, y = element.kdims
if self.p.target:
tx, ty = self.p.target.kdims[:2]
Expand Down
6 changes: 4 additions & 2 deletions geoviews/plotting/bokeh/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ def __init__(self, element, **params):
)

def _axis_properties(self, axis, key, plot, dimension=None,
ax_mapping={'x': 0, 'y': 1}):
ax_mapping=None):
if ax_mapping is None:
ax_mapping = {'x': 0, 'y': 1}
axis_props = super()._axis_properties(axis, key, plot,
dimension, ax_mapping)
proj = self.projection
Expand Down Expand Up @@ -115,7 +117,7 @@ def initialize_plot(self, ranges=None, plot=None, plots=None, source=None):

def _postprocess_hover(self, renderer, source):
super()._postprocess_hover(renderer, source)
hover = getattr(self.handles["plot"], "hover")
hover = self.handles["plot"].hover
hover = hover[0] if hover else None
if (not self.geographic or hover is None or
isinstance(hover.tooltips, str) or self.projection is not GOOGLE_MERCATOR
Expand Down
12 changes: 10 additions & 2 deletions geoviews/streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ class PolyVertexEdit(PolyEdit):
A dictionary specifying the style options for the intermediate nodes.
"""

def __init__(self, node_style={}, feature_style={}, **params):
def __init__(self, node_style=None, feature_style=None, **params):
if feature_style is None:
feature_style = {}
if node_style is None:
node_style = {}
self.node_style = node_style
self.feature_style = feature_style
super().__init__(**params)
Expand All @@ -35,7 +39,11 @@ class PolyVertexDraw(PolyDraw):
A dictionary specifying the style options for the intermediate nodes.
"""

def __init__(self, node_style={}, feature_style={}, **params):
def __init__(self, node_style=None, feature_style=None, **params):
if feature_style is None:
feature_style = {}
if node_style is None:
node_style = {}
self.node_style = node_style
self.feature_style = feature_style
super().__init__(**params)
2 changes: 1 addition & 1 deletion geoviews/tests/data/test_iris.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from iris.tests.stock import lat_lon_cube
from iris.exceptions import MergeError
except ImportError:
raise SkipTest("Could not import iris, skipping IrisInterface tests.")
raise SkipTest("Could not import iris, skipping IrisInterface tests.") from None

from holoviews.core.data import Dataset, concat
from geoviews.data.iris import coord_to_dimension
Expand Down
2 changes: 1 addition & 1 deletion geoviews/tests/test_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
try:
from iris.tests.stock import lat_lon_cube
except ImportError:
raise unittest.SkipTest("iris not available")
raise unittest.SkipTest("iris not available") from None

from holoviews.core import HoloMap
from holoviews.element import Curve
Expand Down
25 changes: 15 additions & 10 deletions geoviews/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,14 @@ def project_extents(extents, src_proj, dest_proj, tol=1e-6):
geom_in_src_proj = geom_clipped_to_dest_proj
try:
geom_in_crs = dest_proj.project_geometry(geom_in_src_proj, src_proj)
except ValueError:
except ValueError as e:
src_name =type(src_proj).__name__
dest_name =type(dest_proj).__name__
raise ValueError(
f'Could not project data from {src_name} projection '
f'to {dest_name} projection. Ensure the coordinate '
'reference system (crs) matches your data and the kdims.'
)
) from e
else:
geom_in_crs = boundary_poly.intersection(domain_in_src_proj)
return geom_in_crs.bounds
Expand Down Expand Up @@ -139,12 +139,14 @@ def zoom(mapPx, worldPx, fraction):
return int(zoom) if np.isfinite(zoom) else 0


def geom_dict_to_array_dict(geom_dict, coord_names=['Longitude', 'Latitude']):
def geom_dict_to_array_dict(geom_dict, coord_names=None):
"""
Converts a dictionary containing an geometry key to a dictionary
of x- and y-coordinate arrays and if present a list-of-lists of
hole array.
"""
if coord_names is None:
coord_names = ["Longitude", "Latitude"]
x, y = coord_names
geom = geom_dict['geometry']
new_dict = {k: v for k, v in geom_dict.items() if k != 'geometry'}
Expand Down Expand Up @@ -266,19 +268,19 @@ def polygons_to_geom_dicts(polygons, skip_invalid=True):
return polys


def path_to_geom_dicts(path, skip_invalid=True):
def path_to_geom_dicts(fullpath, skip_invalid=True):
"""
Converts a Path element into a list of geometry dictionaries,
preserving all value dimensions.
"""
geoms = unpack_geoms(path)
geoms = unpack_geoms(fullpath)
if geoms is not None:
return geoms

geoms = []
invalid = False
xdim, ydim = path.kdims
for i, path in enumerate(path.split(datatype='columns')):
xdim, ydim = fullpath.kdims
for path in fullpath.split(datatype='columns'):
array = np.column_stack([path.pop(xdim.name), path.pop(ydim.name)])
splits = np.where(np.isnan(array[:, :2].astype('float')).sum(axis=1))[0]
arrays = np.split(array, splits+1) if len(splits) else [array]
Expand Down Expand Up @@ -581,7 +583,7 @@ def process_crs(crs):
import cartopy.crs as ccrs
import pyproj
except ImportError:
raise ImportError('Geographic projection support requires pyproj and cartopy.')
raise ImportError('Geographic projection support requires pyproj and cartopy.') from None

if crs is None:
return ccrs.PlateCarree()
Expand Down Expand Up @@ -641,7 +643,7 @@ def load_tiff(filename, crs=None, apply_transform=False, nan_nodata=False, **kwa
try:
import xarray as xr
except ImportError:
raise ImportError('Loading tiffs requires xarray to be installed')
raise ImportError('Loading tiffs requires xarray to be installed') from None
try:
with warnings.catch_warnings():
warnings.filterwarnings('ignore')
Expand Down Expand Up @@ -751,7 +753,7 @@ def from_xarray(da, crs=None, apply_transform=False, nan_nodata=False, **kwargs)
return el


def get_tile_rgb(tile_source, bbox, zoom_level, bbox_crs=ccrs.PlateCarree()):
def get_tile_rgb(tile_source, bbox, zoom_level, bbox_crs=None):
"""
Returns an RGB element given a tile_source, bounding box and zoom level.
Expand All @@ -773,6 +775,9 @@ def get_tile_rgb(tile_source, bbox, zoom_level, bbox_crs=ccrs.PlateCarree()):
"""

from .element import RGB, WMTS
if bbox_crs is None:
bbox_crs = ccrs.PlateCarree()

if isinstance(tile_source, (WMTS, Tiles)):
tile_source = tile_source.data

Expand Down
Loading

0 comments on commit 0201068

Please sign in to comment.