Skip to content

Commit

Permalink
Enable Bugbear 904 - Within an except clause, raise exceptions with…
Browse files Browse the repository at this point in the history
… `from err` or `from None` (#5992)
  • Loading branch information
hoxbro authored Nov 21, 2023
1 parent ba29c24 commit 6cd8a4e
Show file tree
Hide file tree
Showing 24 changed files with 50 additions and 50 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ repos:
- id: rst-directive-colons
- id: rst-inline-touching-normal
- repo: https://github.com/shellcheck-py/shellcheck-py
rev: "v0.9.0.6"
rev: v0.9.0.6
hooks:
- id: shellcheck
2 changes: 1 addition & 1 deletion holoviews/core/dimension.py
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,7 @@ def get_dimension_index(self, dimension):
dimensions = self.kdims+self.vdims
return next(i for i, d in enumerate(dimensions) if d == dim)
except StopIteration:
raise Exception(f"Dimension {dim} not found in {self.__class__.__name__}.")
raise Exception(f"Dimension {dim} not found in {self.__class__.__name__}.") from None


def get_dimension_type(self, dim):
Expand Down
8 changes: 4 additions & 4 deletions holoviews/core/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -634,8 +634,8 @@ def parse_fields(cls, formatter):
try:
parse = list(string.Formatter().parse(formatter))
return {f for f in list(zip(*parse))[1] if f is not None}
except Exception:
raise SyntaxError(f"Could not parse formatter {formatter!r}")
except Exception as e:
raise SyntaxError(f"Could not parse formatter {formatter!r}") from e

def __init__(self, **params):
super().__init__(**params)
Expand Down Expand Up @@ -673,8 +673,8 @@ def _validate_formatters(self):
raise Exception(f"Valid export fields are: {','.join(sorted(self.efields))}")
try:
time.strftime(self.timestamp_format, tuple(time.localtime()))
except Exception:
raise Exception("Timestamp format invalid")
except Exception as e:
raise Exception("Timestamp format invalid") from e


def add(self, obj=None, filename=None, data=None, info=None, **kwargs):
Expand Down
4 changes: 2 additions & 2 deletions holoviews/core/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def cleanup_custom_options(id, weakref=None):
f"Cleanup of custom options tree with id '{id}' failed "
f"with the following exception: {e}, an unreferenced "
"orphan tree may persist in memory."
)
) from e


def lookup_options(obj, group, backend):
Expand Down Expand Up @@ -660,7 +660,7 @@ def _merge_options(self, identifier, group_name, options):
raise OptionError(e.invalid_keyword,
e.allowed_keywords,
group_name=group_name,
path = self.path)
path = self.path) from e

def __getitem__(self, item):
if item in self.groups:
Expand Down
18 changes: 9 additions & 9 deletions holoviews/element/comparison.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,8 @@ def compare_lists(cls, l1, l2, msg=None):
cls.assertEqual(len(l1), len(l2))
for v1, v2 in zip(l1, l2):
cls.assertEqual(v1, v2)
except AssertionError:
raise AssertionError(msg or f'{l1!r} != {l2!r}')
except AssertionError as e:
raise AssertionError(msg or f'{l1!r} != {l2!r}') from e


@classmethod
Expand All @@ -251,8 +251,8 @@ def compare_tuples(cls, t1, t2, msg=None):
cls.assertEqual(len(t1), len(t2))
for i1, i2 in zip(t1, t2):
cls.assertEqual(i1, i2)
except AssertionError:
raise AssertionError(msg or f'{t1!r} != {t2!r}')
except AssertionError as e:
raise AssertionError(msg or f'{t1!r} != {t2!r}') from e


#=====================#
Expand All @@ -275,7 +275,7 @@ def compare_arrays(cls, arr1, arr2, msg='Arrays'):
try:
cls.assert_array_almost_equal_fn(arr1, arr2)
except AssertionError as e:
raise cls.failureException(msg + str(e)[11:])
raise cls.failureException(msg + str(e)[11:]) from e

@classmethod
def bounds_check(cls, el1, el2, msg=None):
Expand All @@ -288,8 +288,8 @@ def bounds_check(cls, el1, el2, msg=None):
if isinstance(v2, datetime_types):
v2 = dt_to_int(v2)
cls.assert_array_almost_equal_fn(v1, v2)
except AssertionError:
raise cls.failureException(f"BoundingBoxes are mismatched: {el1.bounds.lbrt()} != {el2.bounds.lbrt()}.")
except AssertionError as e:
raise cls.failureException(f"BoundingBoxes are mismatched: {el1.bounds.lbrt()} != {el2.bounds.lbrt()}.") from e


#=======================================#
Expand Down Expand Up @@ -321,7 +321,7 @@ def compare_dimensions(cls, dim1, dim2, msg=None):
cls.assertEqual(dim1_params[k], dim2_params[k], msg=None)
except AssertionError as e:
msg = f'Dimension parameter {k!r} mismatched: '
raise cls.failureException(f"{msg}{e!s}")
raise cls.failureException(f"{msg}{e!s}") from e

@classmethod
def compare_labelled_data(cls, obj1, obj2, msg=None):
Expand Down Expand Up @@ -712,7 +712,7 @@ def compare_dataframe(cls, df1, df2, msg='DFrame'):
try:
assert_frame_equal(df1, df2)
except AssertionError as e:
raise cls.failureException(msg+': '+str(e))
raise cls.failureException(f'{msg}: {e}') from e

#============#
# Statistics #
Expand Down
6 changes: 3 additions & 3 deletions holoviews/element/graphs.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,11 +528,11 @@ def __init__(self, data, kdims=None, vdims=None, **params):
points = self.point_type(nodes)
ds = Dataset(points).add_dimension('index', 2, np.arange(len(points)))
nodes = self.node_type(ds)
except Exception:
except Exception as e:
raise ValueError(
"Nodes argument could not be interpreted, expected "
"data with two or three columns representing the "
"x/y positions and optionally the node indices.")
"x/y positions and optionally the node indices.") from e
if edgepaths is not None and not isinstance(edgepaths, self.edge_type):
edgepaths = self.edge_type(edgepaths)

Expand All @@ -549,7 +549,7 @@ def from_vertices(cls, data):
from scipy.spatial import Delaunay
except ImportError:
raise ImportError("Generating triangles from points requires "
"SciPy to be installed.")
"SciPy to be installed.") from None
if not isinstance(data, Points):
data = Points(data)
if not len(data):
Expand Down
2 changes: 1 addition & 1 deletion holoviews/element/raster.py
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ def load_image(cls, filename, height=1, array=False, bounds=None, bare=False, **
try:
from PIL import Image
except ImportError:
raise ImportError("RGB.load_image requires PIL (or Pillow).")
raise ImportError("RGB.load_image requires PIL (or Pillow).") from None

with open(filename, 'rb') as f:
data = np.array(Image.open(f))
Expand Down
8 changes: 4 additions & 4 deletions holoviews/element/selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def spatial_select_gridded(xvals, yvals, geometry):
from ..operation.datashader import rasterize
except ImportError:
raise ImportError("Lasso selection on gridded data requires "
"datashader to be available.")
"datashader to be available.") from None
xs, ys = xvals[0], yvals[:, 0]
target = Image((xs, ys, np.empty(ys.shape+xs.shape)))
poly = Polygons([geometry])
Expand Down Expand Up @@ -132,7 +132,7 @@ def spatial_select_columnar(xvals, yvals, geometry):
geom_mask = np.array([poly.contains(p) for p in points])
except ImportError:
raise ImportError("Lasso selection on tabular data requires "
"either spatialpandas or shapely to be available.")
"either spatialpandas or shapely to be available.") from None
if isinstance(xvals, pd.Series):
sel_mask[sel_mask.index[np.where(sel_mask)[0]]] = geom_mask
else:
Expand All @@ -155,7 +155,7 @@ def spatial_geom_select(x0vals, y0vals, x1vals, y1vals, geometry):
return np.array([poly.contains(p) for p in boxes])
except ImportError:
raise ImportError("Lasso selection on geometry data requires "
"shapely to be available.")
"shapely to be available.") from None

def spatial_poly_select(xvals, yvals, geometry):
try:
Expand All @@ -165,7 +165,7 @@ def spatial_poly_select(xvals, yvals, geometry):
return np.array([poly.contains(p) for p in boxes])
except ImportError:
raise ImportError("Lasso selection on geometry data requires "
"shapely to be available.")
"shapely to be available.") from None

def spatial_bounds_select(xvals, yvals, bounds):
x0, y0, x1, y1 = bounds
Expand Down
4 changes: 2 additions & 2 deletions holoviews/ipython/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ def setUp(self):
self.ip = IPython.InteractiveShell()
if self.ip is None:
raise TypeError()
except Exception:
raise SkipTest("IPython could not be started")
except Exception as e:
raise SkipTest("IPython could not be started") from e

self.addTypeEqualityFunc(HTML, self.skip_comparison)
self.addTypeEqualityFunc(SVG, self.skip_comparison)
Expand Down
4 changes: 2 additions & 2 deletions holoviews/operation/datashader.py
Original file line number Diff line number Diff line change
Expand Up @@ -1570,9 +1570,9 @@ def _process(self, overlay, key=None):

try:
imgs = xr.align(*imgs, join='exact')
except ValueError:
except ValueError as e:
raise ValueError('RGB inputs to the stack operation could not be aligned; '
'ensure they share the same grid sampling.')
'ensure they share the same grid sampling.') from e

stacked = tf.stack(*imgs, how=self.p.compositor)
arr = shade.uint32_to_uint8(stacked.data)[::-1]
Expand Down
2 changes: 1 addition & 1 deletion holoviews/operation/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ def _process(self, element, key=None):
contour_generator,
)
except ImportError:
raise ImportError("contours operation requires contourpy.")
raise ImportError("contours operation requires contourpy.") from None

xs = element.dimension_values(0, True, flat=False)
ys = element.dimension_values(1, True, flat=False)
Expand Down
2 changes: 1 addition & 1 deletion holoviews/operation/normalization.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def get_ranges(self, element, key):
index = keys.index(key)
specs = ranges[index]
except Exception:
raise KeyError("Could not match element key to defined keys")
raise KeyError("Could not match element key to defined keys") from None
else:
raise ValueError("Key list length must match length of supplied ranges")

Expand Down
4 changes: 2 additions & 2 deletions holoviews/operation/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def _process(self, element, key=None):
from scipy import stats
from scipy.linalg import LinAlgError
except ImportError:
raise ImportError(f'{type(self).__name__} operation requires SciPy to be installed.')
raise ImportError(f'{type(self).__name__} operation requires SciPy to be installed.') from None

params = {}
if isinstance(element, Distribution):
Expand Down Expand Up @@ -172,7 +172,7 @@ def _process(self, element, key=None):
try:
from scipy import stats
except ImportError:
raise ImportError(f'{type(self).__name__} operation requires SciPy to be installed.')
raise ImportError(f'{type(self).__name__} operation requires SciPy to be installed.') from None

if len(element.dimensions()) < 2:
raise ValueError("bivariate_kde can only be computed on elements "
Expand Down
4 changes: 2 additions & 2 deletions holoviews/plotting/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,9 @@ def get_plot_class(self, obj):
def __setattr__(self, label, value):
try:
return super().__setattr__(label, value)
except Exception:
except Exception as e:
raise Exception("Please set class parameters directly on classes %s"
% ', '.join(str(cls) for cls in self.__dict__['plot_classes'].values()))
% ', '.join(str(cls) for cls in self.__dict__['plot_classes'].values())) from e

def params(self):
return self.plot_options
Expand Down
2 changes: 1 addition & 1 deletion holoviews/plotting/plotly/chart3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def get_data(self, element, ranges, style, **kwargs):
try:
from scipy.spatial import Delaunay
except ImportError:
raise SkipRendering("SciPy not available, cannot plot TriSurface")
raise SkipRendering("SciPy not available, cannot plot TriSurface") from None
x, y, z = (element.dimension_values(i) for i in range(3))
points2D = np.vstack([x, y]).T
tri = Delaunay(points2D)
Expand Down
2 changes: 1 addition & 1 deletion holoviews/plotting/plotly/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def get_data(self, element, ranges, style, is_geo=False, **kwargs):
import PIL.Image
except ImportError:
raise VersionError("""\
Rendering RGB elements with the plotly backend requires the Pillow package""")
Rendering RGB elements with the plotly backend requires the Pillow package""") from None

img = np.flip(
np.dstack([element.dimension_values(d, flat=False)
Expand Down
2 changes: 1 addition & 1 deletion holoviews/plotting/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ class needed to render it with the current renderer.
try:
plotclass = Store.registry[cls.backend][element_type]
except KeyError:
raise SkipRendering(f"No plotting class for {element_type.__name__} found.")
raise SkipRendering(f"No plotting class for {element_type.__name__} found.") from None
return plotclass

@classmethod
Expand Down
4 changes: 2 additions & 2 deletions holoviews/plotting/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ def collate(obj):
collated_layout = Layout(el.collate())
expanded.extend(collated_layout.values())
return Layout(expanded)
except Exception:
raise Exception(undisplayable_info(obj))
except Exception as e:
raise Exception(undisplayable_info(obj)) from e
else:
raise Exception(undisplayable_info(obj))

Expand Down
4 changes: 2 additions & 2 deletions holoviews/selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,10 +520,10 @@ def _select(element, selection_expr, cache=None):
except KeyError as e:
key_error = str(e).replace('"', '').replace('.', '')
raise CallbackError("linked_selection aborted because it could not "
f"display selection for all elements: {key_error} on '{element!r}'.")
f"display selection for all elements: {key_error} on '{element!r}'.") from e
except Exception as e:
raise CallbackError("linked_selection aborted because it could not "
"display selection for all elements: %s." % e)
"display selection for all elements: %s." % e) from e
ds_cache[selection_expr] = mask
else:
selection = element
Expand Down
6 changes: 3 additions & 3 deletions holoviews/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ def _expand_options(cls, options, backend=None):
try:
backend_options = Store.options(backend=backend or current_backend)
except KeyError as e:
raise Exception(f'The {e} backend is not loaded. Please load the backend using hv.extension.')
raise Exception(f'The {e} backend is not loaded. Please load the backend using hv.extension.') from None
expanded = {}
if isinstance(options, list):
options = merge_options_to_dict(options)
Expand Down Expand Up @@ -645,10 +645,10 @@ def renderer(name):
if prev_backend:
Store.set_current_backend(prev_backend)
return Store.renderers[name]
except ImportError:
except ImportError as e:
msg = ('Could not find a {name!r} renderer, available renderers are: {available}.')
available = ', '.join(repr(k) for k in Store.renderers)
raise ImportError(msg.format(name=name, available=available))
raise ImportError(msg.format(name=name, available=available)) from e


class extension(_pyviz_extension):
Expand Down
2 changes: 1 addition & 1 deletion holoviews/util/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def todict(cls, parseresult, mode='parens', ns=None):
dict(cls.namespace, **ns)))
except Exception:
if cls.abort_on_eval_failure:
raise SyntaxError(f"Could not evaluate keyword: {keyword!r}")
raise SyntaxError(f"Could not evaluate keyword: {keyword!r}") from None
msg = "Ignoring keyword pair that fails to evaluate: '%s'"
parsewarning.warning(msg % keyword)

Expand Down
4 changes: 2 additions & 2 deletions holoviews/util/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def extract_keywords(cls, line, items):
try:
items.update(eval(f'dict({keyword})'))
except Exception:
raise SyntaxError(f"Could not evaluate keyword: {keyword}")
raise SyntaxError(f"Could not evaluate keyword: {keyword}") from None
return items


Expand Down Expand Up @@ -321,7 +321,7 @@ def output(cls, line=None, cell=None, cell_runner=None,
raise ValueError(f"The selected plotting extension {backend!r} "
"has not been loaded, ensure you load it "
f"with hv.extension({backend!r}) before using "
"hv.output.")
"hv.output.") from e
print(f'Error: {e}')
if help_prompt:
print(help_prompt)
Expand Down
2 changes: 1 addition & 1 deletion holoviews/util/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -930,7 +930,7 @@ def __init__(self, obj, *args, **kwargs):
import xarray as xr
except ImportError:
raise ImportError("XArray could not be imported, dim().xr "
"requires the xarray to be available.")
"requires the xarray to be available.") from None
super().__init__(obj, *args, **kwargs)
self._ns = xr.DataArray

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ select = [
]

ignore = [
"B904", # Within an `except` clause, raise exceptions with from err or None
"E402", # Module level import not at top of file
"E501", # Line too long
"E701", # Multiple statements on one line
Expand All @@ -99,6 +98,7 @@ unfixable = [
"holoviews/tests/*" = [
"RUF001", "RUF002", "RUF003", # Ambiguous unicode character
"NPY002", # Replace legacy `np.random.rand` call with Generator
"B904", # Within an `except` clause, raise exceptions with from err or None
]

[tool.ruff.lint.isort]
Expand Down

0 comments on commit 6cd8a4e

Please sign in to comment.