Skip to content

Commit

Permalink
repl NotImpl w SkipTest if NUTILS_TENSORIAL=test
Browse files Browse the repository at this point in the history
  • Loading branch information
joostvanzwieten committed Sep 20, 2021
1 parent 1ac3c2b commit cfece7f
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 10 deletions.
40 changes: 36 additions & 4 deletions nutils/sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,39 @@ def tri(self) -> numpy.ndarray:
def hull(self) -> numpy.ndarray:
return numpy.take(self._index, self._parent.hull)

class _Empty(Sample):
if os.environ.get('NUTILS_TENSORIAL', None) == 'test': # pragma: nocover

from unittest import SkipTest

class _TensorialSample(Sample):

def getindex(self, ielem: int) -> numpy.ndarray:
raise SkipTest('`{}` does not implement `Sample.getindex`'.format(type(self).__qualname__))

def get_evaluable_indices(self, __ielem: evaluable.Array) -> evaluable.Array:
raise SkipTest('`{}` does not implement `Sample.get_evaluable_indices`'.format(type(self).__qualname__))

def get_evaluable_weights(self, __ielem: evaluable.Array) -> evaluable.Array:
raise SkipTest('`{}` does not implement `Sample.get_evaluable_weights`'.format(type(self).__qualname__))

def update_lower_args(self, __ielem: evaluable.Array, points_shape: _PointsShape, transform_chains: _TransformChainsMap, coordinates: _CoordinatesMap) -> Tuple[_PointsShape, _TransformChainsMap, _CoordinatesMap]:
raise SkipTest('`{}` does not implement `Sample.update_lower_args`'.format(type(self).__qualname__))

@property
def transforms(self) -> Tuple[Transforms, ...]:
raise SkipTest('`{}` does not implement `Sample.transforms`'.format(type(self).__qualname__))

@property
def points(self) -> Tuple[Transforms, ...]:
raise SkipTest('`{}` does not implement `Sample.points`'.format(type(self).__qualname__))

def basis(self) -> function.Array:
raise SkipTest('`{}` does not implement `Sample.basis`'.format(type(self).__qualname__))

else:
_TensorialSample = Sample

class _Empty(_TensorialSample):

def __init__(self, spaces: Tuple[str, ...], ndims: int) -> None:
super().__init__(spaces, ndims, 0, 0)
Expand Down Expand Up @@ -488,7 +520,7 @@ def __rmatmul__(self, __func: function.IntoArray) -> function.Array:
def basis(self) -> function.Array:
return function.zeros((0,), float)

class _Add(Sample):
class _Add(_TensorialSample):

def __init__(self, sample1: Sample, sample2: Sample) -> None:
assert sample1.spaces == sample2.spaces
Expand Down Expand Up @@ -534,7 +566,7 @@ def integral(self, func: function.IntoArray) -> function.Array:
def __rmatmul__(self, func: function.IntoArray) -> function.Array:
return function.concatenate([func @ self._sample1, func @ self._sample2])

class _Mul(Sample):
class _Mul(_TensorialSample):

def __init__(self, sample1: Sample, sample2: Sample) -> None:
assert set(sample1.spaces).isdisjoint(set(sample2.spaces))
Expand Down Expand Up @@ -612,7 +644,7 @@ def basis(self) -> Sample:
basis2 = self._sample2.basis()
return function.ravel(basis1[:,None] * basis2[None,:], axis=0)

class _TakeElements(Sample):
class _TakeElements(_TensorialSample):

__cache__ = '_offsets'

Expand Down
93 changes: 87 additions & 6 deletions nutils/topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
from .elementseq import References
from .pointsseq import PointsSequence
from typing import Any, FrozenSet, Iterable, Iterator, List, Mapping, Optional, Sequence, Tuple, Union
import numpy, functools, collections.abc, itertools, functools, operator, numbers, pathlib, abc, treelog as log
import numpy, functools, collections.abc, itertools, functools, operator, numbers, pathlib, abc, treelog as log, os
_ = numpy.newaxis

_identity = lambda x: x
Expand Down Expand Up @@ -878,12 +878,93 @@ def basis_discont(self, degree: int) -> function.Basis:
coeffs = [ref.get_poly_coeffs('bernstein', degree=degree) for ref in self.references]
return function.DiscontBasis(coeffs, self.f_index, self.f_coords)

if os.environ.get('NUTILS_TENSORIAL', None) == 'test': # pragma: nocover

from unittest import SkipTest

class _TensorialTopology(Topology):

def take_unchecked(self, __indices: numpy.ndarray, __idim: int, __ndim: int) -> Topology:
raise SkipTest('`{}` does not implement `Topology.take_unchecked`'.format(type(self).__qualname__))

def __and__(self, other: Any) -> Topology:
result = super().__and__(other)
if type(self) == type(other) and result is NotImplemented:
raise SkipTest('`{}` does not implement `Topology.__and__`'.format(type(self).__qualname__))
return result

def __rand__(self, other: Any) -> Topology:
result = super().__and__(other)
if result is NotImplemented:
raise SkipTest('`{}` does not implement `Topology.__and__`'.format(type(self).__qualname__))
return result

def __sub__(self, other: Any) -> Topology:
if type(self) == type(other):
raise SkipTest('`{}` does not implement `Topology.__sub__`'.format(type(self).__qualname__))
else:
return NotImplemented

def __rsub__(self, other: Any) -> Topology:
if isinstance(other, Topology):
raise SkipTest('`{}` does not implement `Topology.__sub__`'.format(type(self).__qualname__))
else:
return NotImplemented

@property
def space(self) -> str:
raise SkipTest('`{}` does not implement `Topology.space`'.format(type(self).__qualname__))

@property
def transforms(self) -> transformseq.Transforms:
raise SkipTest('`{}` does not implement `Topology.transforms`'.format(type(self).__qualname__))

@property
def opposites(self) -> transformseq.Transforms:
raise SkipTest('`{}` does not implement `Topology.opposites`'.format(type(self).__qualname__))

@property
def border_transforms(self) -> transformseq.Transforms:
raise SkipTest('`{}` does not implement `Topology.border_transforms`'.format(type(self).__qualname__))

@property
def f_index(self) -> function.Array:
raise SkipTest('`{}` does not implement `Topology.f_index`'.format(type(self).__qualname__))

@property
def f_coords(self) -> function.Array:
raise SkipTest('`{}` does not implement `Topology.f_coords`'.format(type(self).__qualname__))

def refined_by(self, refine: Iterable[int]) -> Topology:
raise SkipTest('`{}` does not implement `Topology.refined_by`'.format(type(self).__qualname__))

def trim(self, levelset: function.Array, maxrefine: int, ndivisions: int = 8, name: str = 'trimmed', leveltopo: Optional[Topology] = None, *, arguments: Optional[_ArgDict] = None) -> Topology:
raise SkipTest('`{}` does not implement `Topology.trim`'.format(type(self).__qualname__))

def subset(self, topo: Topology, newboundary: Optional[Union[str, Topology]] = None, strict: bool = False) -> Topology:
raise SkipTest('`{}` does not implement `Topology.subset`'.format(type(self).__qualname__))

def withgroups(self, vgroups: Mapping[str, Union[str, Topology]] = {}, bgroups: Mapping[str, Union[str, Topology]] = {}, igroups: Mapping[str, Union[str, Topology]] = {}, pgroups: Mapping[str, Union[str, Topology]] = {}) -> Topology:
try:
return super().withgroups(vgroups, bgroups, igroups, pgroups)
except NotImplementedError:
raise SkipTest('`{}` does not implement `Topology.withgroups`'.format(type(self).__qualname__))

def indicator(self, subtopo: Union[str, Topology]) -> Topology:
raise SkipTest('`{}` does not implement `Topology.indicator`'.format(type(self).__qualname__))

def locate(self, geom, coords, *, tol=0, eps=0, maxiter=0, arguments=None, weights=None, maxdist=None, ischeme=None, scale=None) -> Sample:
raise SkipTest('`{}` does not implement `Topology.locate`'.format(type(self).__qualname__))

else:
_TensorialTopology = Topology

class _EmptyUnlowerable(function.Array):

def lower(self, points_shape, transform_chains, coordinates) -> evaluable.Array:
raise ValueError('cannot lower')

class _Empty(Topology):
class _Empty(_TensorialTopology):

def __init__(self, spaces: Tuple[str, ...], space_dims: Tuple[int, ...], ndims: int) -> None:
super().__init__(spaces, space_dims, References.empty(ndims))
Expand Down Expand Up @@ -923,7 +1004,7 @@ def basis_std(self, degree: int, *args, **kwargs) -> function.Array:
def sample(self, ischeme: str, degree: int) -> Sample:
return Sample.empty(self.spaces, self.ndims)

class _DisjointUnion(Topology):
class _DisjointUnion(_TensorialTopology):

def __init__(self, topo1: Topology, topo2: Topology) -> None:
if topo1.spaces != topo2.spaces or topo1.space_dims != topo2.space_dims or topo1.ndims != topo2.ndims:
Expand Down Expand Up @@ -989,7 +1070,7 @@ def select(self, indicator: function.Array, ischeme: str = 'bezier2', **kwargs:
topo2 = self.topo2.select(indicator, ischeme, **kwargs)
return Topology.disjoint_union(topo1, topo2)

class _Mul(Topology):
class _Mul(_TensorialTopology):

def __init__(self, topo1: Topology, topo2: Topology) -> None:
if not set(topo1.spaces).isdisjoint(topo2.spaces):
Expand Down Expand Up @@ -1124,7 +1205,7 @@ def basis(self, name: str, degree: Union[int, Sequence[int]], **kwargs) -> funct
def sample(self, ischeme: str, degree: int) -> Sample:
return self.topo1.sample(ischeme, degree) * self.topo2.sample(ischeme, degree)

class _Take(Topology):
class _Take(_TensorialTopology):

def __init__(self, parent: Topology, indices: types.arraydata) -> None:
self.parent = parent
Expand All @@ -1137,7 +1218,7 @@ def __init__(self, parent: Topology, indices: types.arraydata) -> None:
def sample(self, ischeme: str, degree: int) -> Sample:
return self.parent.sample(ischeme, degree).take_elements(self.indices)

class _WithGroupAliases(Topology):
class _WithGroupAliases(_TensorialTopology):

def __init__(self, parent: Topology, vgroups: Mapping[str, str] = {}, bgroups: Mapping[str, str] = {}, igroups: Mapping[str, str] = {}) -> None:
self.parent = parent
Expand Down
3 changes: 3 additions & 0 deletions tests/test_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ def __repr__(self):

__str__ = __repr__

if os.environ.get('NUTILS_TENSORIAL', None):
DocTestCase = unittest.skip('disabled for tensorial topologies')(DocTestCase)

doctest = unittest.TestSuite()
parser = _doctest.DocTestParser()
finder = _doctest.DocTestFinder(parser=parser)
Expand Down

0 comments on commit cfece7f

Please sign in to comment.