diff --git a/test/test_strip_forms.py b/test/test_strip_forms.py index 9a74ac506..27e75869d 100644 --- a/test/test_strip_forms.py +++ b/test/test_strip_forms.py @@ -4,7 +4,7 @@ from ufl import Coefficient, Constant, FunctionSpace, Mesh, TestFunction, TrialFunction, dx, grad, inner, triangle from ufl.algorithms import replace_terminal_data, strip_terminal_data from ufl.core.ufl_id import attach_ufl_id -from ufl.core.ufl_type import attach_operators_from_hash_data +from ufl.core.ufl_type import UFLObject from ufl.finiteelement import FiniteElement from ufl.pullback import identity_pullback from ufl.sobolevspace import H1 @@ -13,16 +13,14 @@ """The minimum value returned by sys.getrefcount.""" -@attach_operators_from_hash_data @attach_ufl_id -class AugmentedMesh(Mesh): +class AugmentedMesh(Mesh, UFLObject): def __init__(self, *args, data): super().__init__(*args) self.data = data -@attach_operators_from_hash_data -class AugmentedFunctionSpace(FunctionSpace): +class AugmentedFunctionSpace(FunctionSpace, UFLObject): def __init__(self, *args, data): super().__init__(*args) self.data = data diff --git a/ufl/core/ufl_id.py b/ufl/core/ufl_id.py index 1af849ba1..bc1206761 100644 --- a/ufl/core/ufl_id.py +++ b/ufl/core/ufl_id.py @@ -54,8 +54,6 @@ def init_ufl_id(self, ufl_id): return init_ufl_id # Modify class: - if hasattr(cls, "__slots__"): - assert "_ufl_id" in cls.__slots__ cls._ufl_global_id = 0 cls.ufl_id = _get_ufl_id cls._init_ufl_id = _init_ufl_id(cls) diff --git a/ufl/core/ufl_type.py b/ufl/core/ufl_type.py index b3bfa0bd6..e19a9c340 100644 --- a/ufl/core/ufl_type.py +++ b/ufl/core/ufl_type.py @@ -11,10 +11,8 @@ from __future__ import annotations import typing -import warnings from abc import ABC, abstractmethod -# Avoid circular import import ufl.core as core from ufl.core.compute_expr_hash import compute_expr_hash from ufl.utils.formatting import camel2underscore @@ -48,33 +46,6 @@ def __ne__(self, other): return not self.__eq__(other) -def attach_operators_from_hash_data(cls): - """Class decorator to attach ``__hash__``, ``__eq__`` and ``__ne__`` implementations. - - These are implemented in terms of a ``._ufl_hash_data()`` method on the class, - which should return a tuple or hashable and comparable data. - """ - warnings.warn("attach_operators_from_hash_data deprecated, please use UFLObject instead.", DeprecationWarning) - assert hasattr(cls, "_ufl_hash_data_") - - def __hash__(self): - """__hash__ implementation attached in attach_operators_from_hash_data.""" - return hash(self._ufl_hash_data_()) - cls.__hash__ = __hash__ - - def __eq__(self, other): - """__eq__ implementation attached in attach_operators_from_hash_data.""" - return type(self) is type(other) and self._ufl_hash_data_() == other._ufl_hash_data_() - cls.__eq__ = __eq__ - - def __ne__(self, other): - """__ne__ implementation attached in attach_operators_from_hash_data.""" - return not self.__eq__(other) - cls.__ne__ = __ne__ - - return cls - - def get_base_attr(cls, name): """Return first non-``None`` attribute of given name among base classes.""" for base in cls.mro(): diff --git a/ufl/domain.py b/ufl/domain.py index ecdea376a..f438006d0 100644 --- a/ufl/domain.py +++ b/ufl/domain.py @@ -11,7 +11,7 @@ from ufl.cell import AbstractCell from ufl.core.ufl_id import attach_ufl_id -from ufl.core.ufl_type import attach_operators_from_hash_data +from ufl.core.ufl_type import UFLObject from ufl.corealg.traversal import traverse_unique_terminals from ufl.sobolevspace import H1 @@ -52,9 +52,8 @@ def topological_dimension(self): # AbstractDomain.__init__(self, geometric_dimension, geometric_dimension) -@attach_operators_from_hash_data @attach_ufl_id -class Mesh(AbstractDomain): +class Mesh(AbstractDomain, UFLObject): """Symbolic representation of a mesh.""" def __init__(self, coordinate_element, ufl_id=None, cargo=None): @@ -122,9 +121,8 @@ def _ufl_sort_key_(self): "Mesh", typespecific) -@attach_operators_from_hash_data @attach_ufl_id -class MeshView(AbstractDomain): +class MeshView(AbstractDomain, UFLObject): """Symbolic representation of a mesh.""" def __init__(self, mesh, topological_dimension, ufl_id=None): diff --git a/ufl/functionspace.py b/ufl/functionspace.py index e2cc86dbc..17de9d1a8 100644 --- a/ufl/functionspace.py +++ b/ufl/functionspace.py @@ -9,7 +9,7 @@ # Modified by Massimiliano Leoni, 2016 # Modified by Cecile Daversin-Catty, 2018 -from ufl.core.ufl_type import attach_operators_from_hash_data +from ufl.core.ufl_type import UFLObject from ufl.domain import join_domains from ufl.duals import is_dual, is_primal @@ -29,13 +29,11 @@ class AbstractFunctionSpace(object): def ufl_sub_spaces(self): """Return ufl sub spaces.""" raise NotImplementedError( - "Missing implementation of IFunctionSpace.ufl_sub_spaces in %s." - % self.__class__.__name__ + f"Missing implementation of ufl_sub_spaces in {self.__class__.__name__}." ) -@attach_operators_from_hash_data -class BaseFunctionSpace(AbstractFunctionSpace): +class BaseFunctionSpace(AbstractFunctionSpace, UFLObject): """Base function space.""" def __init__(self, domain, element): @@ -109,13 +107,10 @@ def _ufl_signature_data_(self, renumbering, name=None): def __repr__(self): """Representation.""" - r = "BaseFunctionSpace(%s, %s)" % (repr(self._ufl_domain), - repr(self._ufl_element)) - return r + return f"BaseFunctionSpace({self._ufl_domain!r}, {self._ufl_element!r})" -@attach_operators_from_hash_data -class FunctionSpace(BaseFunctionSpace): +class FunctionSpace(BaseFunctionSpace, UFLObject): """Representation of a Function space.""" _primal = True @@ -135,13 +130,14 @@ def _ufl_signature_data_(self, renumbering): def __repr__(self): """Representation.""" - r = "FunctionSpace(%s, %s)" % (repr(self._ufl_domain), - repr(self._ufl_element)) - return r + return f"FunctionSpace({self._ufl_domain!r}, {self._ufl_element!r})" + def __str__(self): + """String.""" + return f"FunctionSpace({self._ufl_domain}, {self._ufl_element})" -@attach_operators_from_hash_data -class DualSpace(BaseFunctionSpace): + +class DualSpace(BaseFunctionSpace, UFLObject): """Representation of a Dual space.""" _primal = False @@ -165,13 +161,14 @@ def _ufl_signature_data_(self, renumbering): def __repr__(self): """Representation.""" - r = "DualSpace(%s, %s)" % (repr(self._ufl_domain), - repr(self._ufl_element)) - return r + return f"DualSpace({self._ufl_domain!r}, {self._ufl_element!r})" + + def __str__(self): + """String.""" + return f"DualSpace({self._ufl_domain}, {self._ufl_element})" -@attach_operators_from_hash_data -class TensorProductFunctionSpace(AbstractFunctionSpace): +class TensorProductFunctionSpace(AbstractFunctionSpace, UFLObject): """Tensor product function space.""" def __init__(self, *function_spaces): @@ -196,12 +193,14 @@ def _ufl_signature_data_(self, renumbering): def __repr__(self): """Representation.""" - r = "TensorProductFunctionSpace(*%s)" % repr(self._ufl_function_spaces) - return r + return f"TensorProductFunctionSpace(*{self._ufl_function_spaces!r})" + def __str__(self): + """String.""" + return self.__repr__() -@attach_operators_from_hash_data -class MixedFunctionSpace(AbstractFunctionSpace): + +class MixedFunctionSpace(AbstractFunctionSpace, UFLObject): """Mixed function space.""" def __init__(self, *args): @@ -297,4 +296,8 @@ def _ufl_signature_data_(self, renumbering): def __repr__(self): """Representation.""" - return f"MixedFunctionSpace(*{self._ufl_function_spaces})" + return f"MixedFunctionSpace(*{self._ufl_function_spaces!r})" + + def __str__(self): + """String.""" + return self.__repr__()