Hi Nicolas,

On 22 Apr., 00:37, "Nicolas M. Thiery" <nicolas.thi...@u-psud.fr>
wrote:
> So the question is how many metaclasses we forsee in the future.

Some ideas are below.

> NestedClassMetaclass is really a workaround for a mishandling of
> nested classes by Python;

Abstractly: What NestedClassMetaclass does is to add an __init__
method, that makes sure that something is done when a new class (i.e.,
a new instance of NestedClassMetaclass) is created. Of course, other
metaclasses could provide other useful __init__ methods.

> ClasscallMetaclass implements the analogue of special methods but for
> classes;

In particular, it provides a different __call__ method, so that one
can customize how an instance of a class created with
ClasscallMetaclass is created.

> DynamicMetaclass is only there for pickling;

In particular, it provides __reduce__ for classes that are created
with DynamicMetaclass.

> it's actually fairly
> similar to ClasscallMetaclass: implementing the special method
> __reduce__ for a class; we could have a __classreduce__ in type.

Indeed. Actually, this could be done for *any* method of `type`,
provided we have a framework.

We have

sage: dir(type)
['__abstractmethods__', '__base__', '__bases__', '__basicsize__',
'__call__', '__class__', '__delattr__', '__dict__', '__dictoffset__',
'__doc__', '__eq__', '__flags__', '__format__', '__ge__',
'__getattribute__', '__gt__', '__hash__', '__init__',
'__instancecheck__', '__itemsize__', '__le__', '__lt__', '__module__',
'__mro__', '__name__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasscheck__', '__subclasses__', '__subclasshook__',
'__weakrefoffset__', 'mro']

For each method __bla__, we could have a metaclass ClassblaMetaclass,
that overrides __bla__ such that it can be customised with a
__classbla__ or __classbla_private__ method defined by the user.

We already have ClasscallMetaclass, that overrides __call__,
customisable with __classcall__ and __classcall_private__.

We have NestedClassMetaclass, that in my scheme should be called
ClassinitMetaclass, and is not customisable with __classinit__ yet.

We have DynamicMetaclass, which would be ClassreduceMetaclass in my
scheme, and you suggest to make it customisable with __classreduce__.

There is the abc module: AFAIK, it uses a metaclass overriding
__subclasshook__, and in that sense is ClasssubclassMetaclass.

Looking at the list above, it would at least make sense to have
metaclasses for __new__, perhaps for __instancecheck__, and perhaps
also for a combination of __eq__, __le__, ... , __hash__.

Then, ClasscallMetaclass also adds a __get__ method (that isn't
present in type). Actually I wonder why this is not moved to
NestedClassMetaclass, because the example from the documentation
pretty much looks like an application of NestedClass and not of
Classcall.

One could think of implementing other special methods, such as
__add__: If C1 and C2 are classes with ClassaddMetaclass, then C1+C2
would do something usefull (for example, return a class that has C1
and C2 as bases)

SUMMARY:

Our current metaclasses all work by overriding a "magical" method of
type, or adding a "magical" method to type. Ideally, this should be in
a customisable way. In some cases, we want to override not just one
method. Currently, each combination of customised methods requires to
write a new metaclass. But why not have just *one* metametaclass
"CustomisationMetaclass", such that
CustomisationMetaclass("init","get","reduce") returns a metaclass that
allows customisation of three methods?

Syntax example:

class MyClass(Parent):
    __metaclass__ = CustomisationMetaclass("call","init","add")
    @cached_function
    def __classcall__(cls, *args,**opts):
        out = type.__call__(cls, *args, **opts)
        return out
    @staticmethod
    def __classinit__(cls, *args,**opts):
        globals()[cls.__name__] = cls
    @staticmethod
    def __classadd__(cls, other):
        if cls is other:
            return cls
        return type(cls)(cls.__name__+"And"+other.__name__,
(cls,other), {})

The result would be a cached subclass of Parent that injects itself
into global namespace (and any subclass of MyClass would do the same),
and when adding MyClass to another class then the result would be a
common subclass.

Cheers,
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