Well, it seems like the designer of the metaclass mess (me) did not
anticipate this usage. It is pretty straightforward to extend the
expression.py file to cover this particular case.
Johan
Try the inlined patch:
diff --git a/site-packages/dolfin/functions/expression.py
b/site-packages/dolfin/functions/expression.py
index 49040e1..6717b43 100644
--- a/site-packages/dolfin/functions/expression.py
+++ b/site-packages/dolfin/functions/expression.py
@@ -81,7 +81,7 @@ class UserDefinedParameters(dict):
Help class to set user defined parameters in Expressions
"""
def __init__(self, expr, **kwargs):
- assert(isinstance(expr, cpp.Expression))
+ assert isinstance(expr, cpp.Expression)
self._expr = expr
dict.__init__(self, **kwargs)
@@ -103,7 +103,7 @@ class UserDefinedParameters(dict):
def create_compiled_expression_class(cpp_base):
# Check the cpp_base
- assert(isinstance(cpp_base, (types.ClassType, type)))
+ assert isinstance(cpp_base, (types.ClassType, type))
def __init__(self, cppcode, element=None, cell=None, domain=None, \
degree=None, name=None, label=None, **kwargs):
@@ -151,7 +151,8 @@ def create_compiled_expression_class(cpp_base):
return type("CompiledExpression", (Expression, ufl.Coefficient,
cpp_base),\
{"__init__":__init__})
-def create_python_derived_expression_class(class_name, user_bases,
user_dict):
+def create_python_derived_expression_class(class_name, user_bases,
+ user_dict, ExpressionClass):
"""Return Expression class
This function is used to create all the dynamically created Expression
@@ -166,16 +167,19 @@ def
create_python_derived_expression_class(class_name, user_bases, user_dict):
User defined bases
user_dict
Dict with user specified function or attributes
+ ExpressionClass
+ A class that derives from the original Expression class
"""
# Check args
- assert(isinstance(class_name, str))
- assert(isinstance(user_bases, list))
- assert(isinstance(user_dict, dict))
+ assert isinstance(class_name, str)
+ assert isinstance(user_bases, list)
+ assert isinstance(user_dict, dict)
+ assert issubclass(ExpressionClass, Expression)
# Define the bases
- assert(all([isinstance(t, (types.ClassType, type)) for t in
user_bases]))
- bases = tuple([Expression, ufl.Coefficient, cpp.Expression] +
user_bases)
+ assert all([isinstance(t, (types.ClassType, type)) for t in
user_bases])
+ bases = tuple([ExpressionClass, ufl.Coefficient, cpp.Expression] +
user_bases)
user_init = user_dict.pop("__init__", None)
@@ -263,9 +267,9 @@ class ExpressionMetaClass(type):
def __new__(mcs, class_name, bases, dict_):
"""Returns a new Expression class"""
- assert(isinstance(class_name, str)), "Expecting a 'str'"
- assert(isinstance(bases, tuple)), "Expecting a 'tuple'"
- assert(isinstance(dict_, dict)), "Expecting a 'dict'"
+ assert isinstance(class_name, str), "Expecting a 'str'"
+ assert isinstance(bases, tuple), "Expecting a 'tuple'"
+ assert isinstance(dict_, dict), "Expecting a 'dict'"
# First check if we are creating the Expression class
if class_name == "Expression":
@@ -285,17 +289,18 @@ class ExpressionMetaClass(type):
# If creating a fullfledged derived expression class, i.e,
inheriting
# dolfin.Expression, ufl.Coefficient and cpp.Expression (or a
subclass)
# then just return the new class.
- if len(bases) >= 3 and bases[0] == Expression and \
+ if len(bases) >= 3 and issubclass(bases[0], Expression) and \
bases[1] == ufl.Coefficient and issubclass(bases[2], \
cpp.Expression):
# Return the instantiated class
return type.__new__(mcs, class_name, bases, dict_)
# Handle any user provided base classes
+ ExpressionClass = [base for base in bases if issubclass(base,
Expression)][0]
user_bases = list(bases)
# remove Expression, to be added later
- user_bases.remove(Expression)
+ user_bases.remove(ExpressionClass)
# Check the user has provided either an eval or eval_cell method
if not ('eval' in dict_ or 'eval_cell' in dict_):
@@ -317,7 +322,8 @@ class ExpressionMetaClass(type):
raise TypeError, "The overloaded '%s' function must "\
"use three arguments"%eval_name
- return create_python_derived_expression_class(class_name,
user_bases, dict_)
+ return create_python_derived_expression_class(class_name,
user_bases,
+ dict_,
ExpressionClass)
#--- The user interface ---
On Fri, May 23, 2014 at 12:02 PM, Martin Sandve Alnæs <[email protected]>wrote:
> No, you can't do that. Consider moving shared code to a standalone
> function instead.
>
> Martin
>
>
> On 23 May 2014 11:43, Miroslav Kuchta <[email protected]> wrote:
>
>> Hi,
>>
>> I have a question about deriving from user-defined expressions in Python.
>> Consider
>>
>> class A(Expression):
>> def eval(self, values, x):
>> pass
>>
>> class B(A):
>> def eval(self, value, x):
>> pass
>>
>>
>> Running the snippet produces ValueError when ExpressionMetaClass is trying
>> to remove Expression from bases of B. So it seems inheritance is not
>> possible.
>> Are there some tricks to make the example work? Thanks.
>>
>> Regards, Miro
>>
>>
>>
>> _______________________________________________
>> fenics mailing list
>> [email protected]
>> http://fenicsproject.org/mailman/listinfo/fenics
>>
>>
>
> _______________________________________________
> fenics mailing list
> [email protected]
> http://fenicsproject.org/mailman/listinfo/fenics
>
>
_______________________________________________
fenics mailing list
[email protected]
http://fenicsproject.org/mailman/listinfo/fenics