Skip to content

Commit

Permalink
add tests for warnings/errors
Browse files Browse the repository at this point in the history
  • Loading branch information
lilyminium committed Sep 2, 2020
1 parent 2548b00 commit f2d2c5f
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 16 deletions.
25 changes: 10 additions & 15 deletions package/MDAnalysis/core/selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ def __init__(cls, name, bases, classdict):
type.__init__(type, name, bases, classdict)
try:
_SELECTIONDICT[classdict['token']] = cls
_SELECTIONDICT[classdict['token'].lower()] = cls
except KeyError:
pass

Expand Down Expand Up @@ -758,12 +759,13 @@ def apply(self, group):
vals = getattr(group, self.field)
return group[vals == self.value].unique


class RangeSelection(Selection):
"""Range selection for numeric values"""
"""Range selection for int values"""

value_offset = 0
pattern = ".*"
dtype = float
pattern = r"(-?\d+)\s*(?:[:-]|to)\s*(-?\d+)"
dtype = int

def __init__(self, parser, tokens):
values = grab_not_keywords(tokens)
Expand All @@ -787,16 +789,14 @@ def __init__(self, parser, tokens):

for val in _values:
try:
lower = float(val)
lower = self.dtype(val)
upper = None
except ValueError:
# check if in appropriate format 'lower:upper' or 'lower-upper'
selrange = re.match(self.pattern, val)
print(self.pattern, val)
if not selrange:
errmsg = f"Failed to parse number: {val}"
raise ValueError(errmsg) from None
print(self.pattern, val, selrange.groups())
lower, upper = map(self.dtype, selrange.groups())
if lower > upper:
lower, upper = upper, lower
Expand Down Expand Up @@ -825,16 +825,11 @@ def apply(self, group):
class FloatRangeSelection(RangeSelection):
"""Range selection for float values"""

pattern = r"(-?\d+\.?\d*)\s*(?:[:-]|to)\s*(-?\d+\.?\d*)"


class IntRangeSelection(RangeSelection):
"""Range selection for int values"""

pattern = r"(-?\d+)\s*(?:[:-]|to)\s*(-?\d+)"
pattern = r"(-?\d*\.?\d*)\s*(?:[:-]|to)\s*(-?\d*\.?\d*)"
dtype = float


class ByNumSelection(IntRangeSelection):
class ByNumSelection(RangeSelection):
token = 'bynum'
field = 'indices'
value_offset = 1 # queries are in 1 based indices
Expand Down Expand Up @@ -1394,7 +1389,7 @@ def gen_selection_class(singular, attrname, dtype, per_object):
if issubclass(dtype, bool):
basecls = BoolSelection
elif np.issubdtype(dtype, np.integer):
basecls = IntRangeSelection
basecls = RangeSelection
elif np.issubdtype(dtype, np.floating):
basecls = FloatRangeSelection
elif issubclass(dtype, str) or dtype == object:
Expand Down
11 changes: 10 additions & 1 deletion testsuite/MDAnalysisTests/core/test_atomselections.py
Original file line number Diff line number Diff line change
Expand Up @@ -1251,7 +1251,7 @@ def test_mass_sel(selstr, n_atoms):
("resnum -3 : -5", 3), # wrong way around
])
def test_int_sel(selstr, n_res):
# test auto-topattr addition of float (FloatRangeSelection)
# test auto-topattr addition of int (IntRangeSelection)
u = mda.Universe(TPR)
u.residues[-10:].resnums = - (np.arange(10) + 1)
ag = u.select_atoms(selstr).residues
Expand All @@ -1265,3 +1265,12 @@ def test_bool_sel():
assert len(u.select_atoms("aromaticity true")) == 5
assert len(u.select_atoms("not aromaticity")) == 15
assert len(u.select_atoms("aromaticity False")) == 15


def test_error_selection_for_strange_dtype():
with pytest.raises(ValueError) as rec:
MDAnalysis.core.selection.gen_selection_class("star", "stars",
dict, "atom")

err = "No base class defined for dtype"
assert err in str(rec.value)
12 changes: 12 additions & 0 deletions testsuite/MDAnalysisTests/core/test_topologyattrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,3 +501,15 @@ def test_static_typing_from_empty():

assert isinstance(u._topology.masses.values, np.ndarray)
assert isinstance(u.atoms[0].mass, float)


def test_warn_selection_for_strange_dtype():
with pytest.warns(UserWarning) as rec:
class Star(tpattrs.TopologyAttr):
singular = "star" # turns out test_imports doesn't like emoji
attrname = "stars" # :(
per_object = "atom"
dtype = dict

err = "A selection keyword could not be automatically generated"
assert err in rec[0].message.args[0]

0 comments on commit f2d2c5f

Please sign in to comment.