From 212a2b7f2b65cafd247795161dc2432cf7a7d288 Mon Sep 17 00:00:00 2001 From: Jim Pivarski Date: Fri, 12 Oct 2018 11:46:23 -0500 Subject: [PATCH] consistent use of exception types --- awkward/array/base.py | 14 ++++++++------ awkward/array/chunked.py | 10 ++++++---- awkward/array/indexed.py | 8 +++++--- awkward/array/jagged.py | 34 +++++++++++++++++----------------- awkward/array/masked.py | 8 ++++---- awkward/array/table.py | 2 +- awkward/array/union.py | 6 +++++- awkward/array/virtual.py | 2 +- awkward/version.py | 2 +- 9 files changed, 48 insertions(+), 38 deletions(-) diff --git a/awkward/array/base.py b/awkward/array/base.py index 7f12de08..52a53eaa 100644 --- a/awkward/array/base.py +++ b/awkward/array/base.py @@ -34,7 +34,9 @@ class AwkwardArray(awkward.util.NDArrayOperatorsMixin): def __array__(self, *args, **kwargs): - raise Exception("{0} {1}".format(args, kwargs)) + # hitting this function is usually undesirable; uncomment to search for performance bugs + # raise Exception("{0} {1}".format(args, kwargs)) + return awkward.util.numpy.array(self, *args, **kwargs) def __iter__(self): for i in range(len(self)): @@ -55,11 +57,11 @@ def _try_tolist(self, x): except AttributeError: return x - # def __getattr__(self, where): - # if awkward.util.is_intstring(where): - # return self[where[1:]] - # else: - # raise AttributeError("'{0}' object has no attribute '{1}'".format(self.__class__.__name__, where)) + def __getattr__(self, where): + if awkward.util.is_intstring(where): + return self[where[1:]] + else: + raise AttributeError("'{0}' object has no attribute '{1}'".format(self.__class__.__name__, where)) def __bool__(self): raise ValueError("The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()") diff --git a/awkward/array/chunked.py b/awkward/array/chunked.py index e243b344..7ab70eb6 100644 --- a/awkward/array/chunked.py +++ b/awkward/array/chunked.py @@ -122,13 +122,13 @@ def knowcounts(self, until=None): if until is None: until = len(self._chunks) if not 0 <= until <= len(self._chunks): - raise IndexError("cannot knowcounts until chunkid {0} with {1} chunks".format(until, len(self._chunks))) + raise ValueError("cannot knowcounts until chunkid {0} with {1} chunks".format(until, len(self._chunks))) for i in range(len(self._counts), until): self._counts.append(len(self._chunks[i])) def knowtype(self, at): if not 0 <= at < len(self._chunks): - raise IndexError("cannot knowtype at chunkid {0} with {1} chunks".format(at, len(self._chunks))) + raise ValueError("cannot knowtype at chunkid {0} with {1} chunks".format(at, len(self._chunks))) tpe = awkward.type.fromarray(self._chunks[at]) if tpe.takes == 0: self._types[at] = () @@ -645,8 +645,10 @@ def chunkshape(self, value): try: for x in value: assert isinstance(x, awkward.util.integer) and value > 0 - except (TypeError, AssertionError): - raise TypeError("chunkshape must be a positive integer or tuple of positive integers") + except TypeError: + raise TypeError("chunkshape must be an integer or a tuple of integers") + except AssertionError: + raise ValueError("chunkshape must be a positive integer or tuple of positive integers") else: self._chunkshape = tuple(value) diff --git a/awkward/array/indexed.py b/awkward/array/indexed.py index 1ec104ea..eb5387a0 100644 --- a/awkward/array/indexed.py +++ b/awkward/array/indexed.py @@ -410,8 +410,10 @@ def length(self): @length.setter def length(self, value): - if not isinstance(value, awkward.util.integer) or value < 0: - raise TypeError("length must be a non-negative integer") + if not isinstance(value, awkward.util.integer): + raise TypeError("length must be an integer") + if value < 0: + raise ValueError("length must be a non-negative integer") self._length = value @property @@ -424,7 +426,7 @@ def index(self, value): if not issubclass(value.dtype.type, awkward.util.numpy.integer): raise TypeError("index must have integer dtype") if len(value.shape) != 1: - raise TypeError("index must be one-dimensional") + raise ValueError("index must be one-dimensional") if (value < 0).any(): raise ValueError("index must be a non-negative array") if len(value) > 0 and not (value[1:] >= value[:-1]).all(): diff --git a/awkward/array/jagged.py b/awkward/array/jagged.py index 30c262f7..8f672043 100644 --- a/awkward/array/jagged.py +++ b/awkward/array/jagged.py @@ -223,7 +223,7 @@ def starts(self, value): if not issubclass(value.dtype.type, awkward.util.numpy.integer): raise TypeError("starts must have integer dtype") if len(value.shape) == 0: - raise TypeError("starts must have at least one dimension") + raise ValueError("starts must have at least one dimension") if (value < 0).any(): raise ValueError("starts must be a non-negative array") self._starts = value @@ -240,7 +240,7 @@ def stops(self, value): if not issubclass(value.dtype.type, awkward.util.numpy.integer): raise TypeError("stops must have integer dtype") if len(value.shape) == 0: - raise TypeError("stops must have at least one dimension") + raise ValueError("stops must have at least one dimension") if (value < 0).any(): raise ValueError("stops must be a non-negative array") self._stops = value @@ -294,7 +294,7 @@ def counts(self, value): if not issubclass(value.dtype.type, awkward.util.numpy.integer): raise TypeError("counts must have integer dtype") if len(value.shape) == 0: - raise TypeError("counts must have at least one dimension") + raise ValueError("counts must have at least one dimension") if (value < 0).any(): raise ValueError("counts must be a non-negative array") offsets = counts2offsets(value.reshape(-1)) @@ -321,7 +321,7 @@ def parents(self, value): if not issubclass(value.dtype.type, awkward.util.numpy.integer): raise TypeError("parents must have integer dtype") if len(value.shape) == 0: - raise TypeError("parents must have at least one dimension") + raise ValueError("parents must have at least one dimension") self._starts, self._stops = parents2startsstops(value) self._offsets, self._counts = None, None self._parents = value @@ -510,26 +510,26 @@ def _tojagged(self, starts=None, stops=None, copy=True): elif stops is None: starts = awkward.util.toarray(starts, awkward.util.INDEXTYPE) if len(self) != len(starts): - raise IndexError("cannot fit JaggedArray of length {0} into starts of length {1}".format(len(self), len(starts))) + raise ValueError("cannot fit JaggedArray of length {0} into starts of length {1}".format(len(self), len(starts))) stops = starts + self.counts if (stops[:-1] > starts[1:]).any(): - raise IndexError("cannot fit contents of JaggedArray into the given starts array") + raise ValueError("cannot fit contents of JaggedArray into the given starts array") elif starts is None: stops = awkward.util.toarray(stops, awkward.util.INDEXTYPE) if len(self) != len(stops): - raise IndexError("cannot fit JaggedArray of length {0} into stops of length {1}".format(len(self), len(stops))) + raise ValueError("cannot fit JaggedArray of length {0} into stops of length {1}".format(len(self), len(stops))) starts = stops - self.counts if (stops[:-1] > starts[1:]).any(): - raise IndexError("cannot fit contents of JaggedArray into the given stops array") + raise ValueError("cannot fit contents of JaggedArray into the given stops array") else: if not awkward.util.numpy.array_equal(stops - starts, self.counts): - raise IndexError("cannot fit contents of JaggedArray into the given starts and stops arrays") + raise ValueError("cannot fit contents of JaggedArray into the given starts and stops arrays") self._validstartsstops(starts, stops) @@ -722,7 +722,7 @@ def argcross(self, other): self._valid() if not isinstance(other, JaggedArray): - raise ValueError("both arrays must be JaggedArrays") + raise TypeError("both arrays must be JaggedArrays") if len(self) != len(other): raise ValueError("both JaggedArrays must have the same length") @@ -1000,7 +1000,7 @@ def concat(cls, first, *rest): # all elements of first followed by all elemen x._valid() if not all(isinstance(x, JaggedArray) for x in arrays): - raise ValueError("cannot hconcat JaggedArrays with non-JaggedArrays") + raise TypeError("cannot concat JaggedArrays with non-JaggedArrays") starts = awkward.util.numpy.concatenate([x._starts for x in arrays]) stops = awkward.util.numpy.concatenate([x._stops for x in arrays]) @@ -1126,7 +1126,7 @@ def content(self): def content(self, value): value = awkward.util.toarray(value, awkward.util.CHARTYPE, awkward.util.numpy.ndarray) if len(value.shape) != 1: - raise TypeError("content of ByteJaggedArray must have 1-dimensional shape") + raise ValueError("content of ByteJaggedArray must have 1-dimensional shape") self._content = value.view(awkward.util.CHARTYPE) self._isvalid = False @@ -1229,31 +1229,31 @@ def _tojagged(self, starts=None, stops=None, copy=True): elif stops is None: starts = awkward.util.toarray(starts, awkward.util.INDEXTYPE) if self._starts.shape != starts.shape: - raise IndexError("cannot fit ByteJaggedArray with shape {0} into starts with shape {1}".format(self._starts.shape, starts.shape)) + raise ValueError("cannot fit ByteJaggedArray with shape {0} into starts with shape {1}".format(self._starts.shape, starts.shape)) bytestarts = starts * self._subdtype.itemsize bytestops = bytestarts + self.counts stops = self._divitemsize(bytestops) if (stops[:-1] > starts[1:]).any(): - raise IndexError("cannot fit contents of ByteJaggedArray into the given starts array") + raise ValueError("cannot fit contents of ByteJaggedArray into the given starts array") elif starts is None: stops = awkward.util.toarray(stops, awkward.util.INDEXTYPE) if self._stops.shape != stops.shape: - raise IndexError("cannot fit ByteJaggedArray with shape {0} into stops with shape {1}".format(self._stops.shape, stops.shape)) + raise ValueError("cannot fit ByteJaggedArray with shape {0} into stops with shape {1}".format(self._stops.shape, stops.shape)) bytestops = stops * self._subdtype.itemsize bytestarts = bytestops - self.counts starts = self._divitemsize(bytestarts) if (stops[:-1] > starts[1:]).any(): - raise IndexError("cannot fit contents of ByteJaggedArray into the given stops array") + raise ValueError("cannot fit contents of ByteJaggedArray into the given stops array") else: bytestarts, bytestops = starts * self._subdtype.itemsize, stops * self._subdtype.itemsize if not awkward.util.numpy.array_equal(bytestops - bytestarts, self.counts): - raise IndexError("cannot fit contents of ByteJaggedArray into the given starts and stops arrays") + raise ValueError("cannot fit contents of ByteJaggedArray into the given starts and stops arrays") JaggedArray._validstartsstops(bytestarts, bytestops) if (bytestops - bytestarts != (stops - starts) * self._subdtype.itemsize).any(): diff --git a/awkward/array/masked.py b/awkward/array/masked.py index d00d9bd2..23050432 100644 --- a/awkward/array/masked.py +++ b/awkward/array/masked.py @@ -113,7 +113,7 @@ def mask(self): def mask(self, value): value = awkward.util.toarray(value, awkward.util.MASKTYPE, awkward.util.numpy.ndarray) if len(value.shape) != 1: - raise TypeError("mask must have 1-dimensional shape") + raise ValueError("mask must have 1-dimensional shape") if not issubclass(value.dtype.type, (awkward.util.numpy.bool_, awkward.util.numpy.bool)): value = (value != 0) self._mask = value @@ -299,7 +299,7 @@ def mask(self): def mask(self, value): value = awkward.util.toarray(value, awkward.util.BITMASKTYPE, awkward.util.numpy.ndarray) if len(value.shape) != 1: - raise TypeError("mask must have 1-dimensional shape") + raise ValueError("mask must have 1-dimensional shape") self._mask = value.view(awkward.util.BITMASKTYPE) def __len__(self): @@ -324,7 +324,7 @@ def bit2bool(bitmask, lsborder=False): def bool2bit(boolmask, lsborder=False): boolmask = awkward.util.toarray(boolmask, awkward.util.MASKTYPE, awkward.util.numpy.ndarray) if len(boolmask.shape) != 1: - raise TypeError("boolmask must have 1-dimensional shape") + raise ValueError("boolmask must have 1-dimensional shape") if not issubclass(boolmask.dtype.type, (awkward.util.numpy.bool_, awkward.util.numpy.bool)): boolmask = (boolmask != 0) @@ -513,7 +513,7 @@ def mask(self, value): if not issubclass(value.dtype.type, awkward.util.numpy.integer): raise TypeError("starts must have integer dtype") if len(value.shape) != 1: - raise TypeError("mask must have 1-dimensional shape") + raise ValueError("mask must have 1-dimensional shape") self._mask = value self._isvalid = False diff --git a/awkward/array/table.py b/awkward/array/table.py index 6a20040d..c1be4f00 100644 --- a/awkward/array/table.py +++ b/awkward/array/table.py @@ -62,7 +62,7 @@ def __getattr__(self, name): if content is not None: return content[self._index] - raise AttributeError("neither _{0} is not a column in this {1}".format(name, self._table.rowname)) + raise AttributeError("{0} is not a column in this {1}".format(repr(name), self._table.rowname)) def __getitem__(self, where): if isinstance(where, awkward.util.string): diff --git a/awkward/array/union.py b/awkward/array/union.py index 88fd7e20..40e99b85 100644 --- a/awkward/array/union.py +++ b/awkward/array/union.py @@ -121,9 +121,13 @@ def contents(self): @contents.setter def contents(self, value): + try: + iter(value) + except TypeError: + raise TypeError("contents must be iterable") value = tuple(awkward.util.toarray(x, awkward.util.DEFAULTTYPE) for x in value) if len(value) == 0: - raise ValueError("contents must be a non-empty iterable") + raise ValueError("contents must be non-empty") self._contents = value self._dtype = None self._isvalid = False diff --git a/awkward/array/virtual.py b/awkward/array/virtual.py index f3b5c240..9f048579 100644 --- a/awkward/array/virtual.py +++ b/awkward/array/virtual.py @@ -226,7 +226,7 @@ def materialize(self): del array[n] if self._type is not None and self._type != awkward.type.fromarray(array): - raise ValueError("materialized array has type\n\n{0}\n\nexpected type\n\n{1}".format(awkward.type.fromarray(array).__str__(indent=" "), self._type.__str__(indent=" "))) + raise TypeError("materialized array has type\n\n{0}\n\nexpected type\n\n{1}".format(awkward.type.fromarray(array).__str__(indent=" "), self._type.__str__(indent=" "))) if self._cache is None: # states (1), (2), and (6) diff --git a/awkward/version.py b/awkward/version.py index 464b2e41..900ccf0b 100644 --- a/awkward/version.py +++ b/awkward/version.py @@ -30,7 +30,7 @@ import re -__version__ = "0.1.0" +__version__ = "0.2.0" version = __version__ version_info = tuple(re.split(r"[-\.]", __version__))