Hi!

Metaclasses are used in Sage in various ways, but so far there is no framework 
for it.
By consequence, it is not straight forward to combine the features provided by 
different
metaclasses.

I have a proof of concept to improve the situation, and the question is whether 
I should
post it on a ticket and try to make a patch out of it. The latter would 
probably be much
work - that's why I first ask here whether you'd find it useful. Sorry for the 
long post.

For example, try to simultaneously derive a class from UniqueRepresentation 
(metaclass:
ClasscallMetaclass) and Rings().parent_class (metaclass: DynamicMetaclass):

    sage: class Foo(UniqueRepresentation, Rings().parent_class): pass
    Traceback (most recent call last):
    ...
    TypeError: Error when calling the metaclass bases
        metaclass conflict: the metaclass of a derived class must be a 
(non-strict) subclass of the metaclasses of all its bases

Presumably it was for the same reason that ClasscallMetaclass is derived from
NestedClassMetaclass (although these two provide *independent* features),
and that a DynamicClasscallMetaclass was added to DynamicMetaclass.

My basic idea for a metaclass framework is: Use a meta-metaclass, that I'd call
"SageMetaclass". Then, e.g., type(UniqueRepresentation) is ClasscallMetaclass 
(which
is currently the case), and type(ClasscallMetaclass) is SageMetaclass (which 
would
be new).

How can the additional meta-layer help?

The point is that new metaclasses (i.e., instances of SageMetaclass) can be 
created
dynamically. Hence, if you wish to derive a new class from UniqueRepresentation 
and
Rings().parent_class, the result would have a new *automatically created* 
metaclass
ClasscallDynamicClassMetaclass. And if, in addition to that, the resulting class
shall support nested classes, then one can simply merge NestedClassMetaclass as 
well.

For testing, in some module, I defined MyUniqueRepresentation (analogy to
UniqueRepresentation) and a nested class
    class MyNestedClass:
        __metaclass__ = NestedClass
        class Test:
            def bla(self):
                return 5

I also defined
    from sage.all import Parent
    MyParent = my_dynamic_class('MyParent', (Parent,), MyNestedClass.Test)

Hence, MyParent is similar to Rings().parent_class, where Rings.ParentMethods 
plays
the role of MyNestedClass.Test in my example.

And then, I can do (in the module)
    class MyUniqueParent(MyUniqueRepresentation, MyParent):
        def __init__(self, a,b):
            self._data = a,b
        def _repr_(self):
            return repr(self._data)

    class MyOtherUniqueParent(MyUniqueRepresentation, MyParent):
        # Here we have the combination "classcall dynamic nested"!
        __metaclass__ = NestedClass
        def __init__(self, a,b,c):
            self._data = a,b,c
        def _repr_(self):
            return repr(self._data)
        class Test2:
            def foo(self):
                return 6

and finally in a Sage session (after importing stuff):

  sage: from metatest import *
  sage: a = MyUniqueParent(1,2)
  sage: a
  (1, 2)
  sage: a.bla() # inherited from MyParent
  5
  sage: a is loads(dumps(a))  # inherited from MyUniqueRepresentation
  True
  sage: a is MyUniqueParent(1,2)
  True

and

  sage: b = MyOtherUniqueParent(1,2,3)
  sage: t = b.Test2()
  sage: t.foo()
  6
  sage: b.bla()
  5
  sage: loads(dumps(t)).foo()  # nesting works!
  6

Here you can see the hierarchy of metaclasses. Note that
ClasscallDynamicClassNestedClassMetaclass is automatically
created (and is an instance of a dynamic version of
SageMetaclass)!

  sage: type(b)
  <class 'metatest.MyOtherUniqueParent'>
  sage: type(type(b))
  ClasscallDynamicClassNestedClassMetaclass
  sage: type(type(type(b)))
  <class 'metatest.DynamicSageMetaclass'>
  sage: type(type(type(b))).__base__
  <class 'metatest.SageMetaclass'>

Do you think this could be useful?

Best regards,
Simon


-- 
You received this message because you are subscribed to the Google Groups 
"sage-combinat-devel" group.
To post to this group, send email to sage-combinat-devel@googlegroups.com.
To unsubscribe from this group, send email to 
sage-combinat-devel+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sage-combinat-devel?hl=en.

Reply via email to