Thomas Heller wrote: > > "Just van Rossum" <just at letterror.com> wrote ... > > I once proposed (and implemented as an extension to the metaclass hook) > > this: > > > > class Foo: > > __class__ = WeirdClass > > > > I still don't think that's all that bad, especially since it screams > > magic at you... > > Is your code available somewhere? No, but I just found the patch in my archives. It's probably against 1.5.2, so might not even apply to 2.x. I've pasted it below. Just - - - - - 8< - - - - - - - - - - - - - *** ceval.c Tue Dec 1 05:44:30 1998 --- jmetapatch/ceval.c Tue Dec 1 05:44:12 1998 *************** *** 2672,2681 **** --- 2672,2738 ---- if (!PyString_Check(name)) { PyErr_SetString(PyExc_SystemError, "build_class witn non-string name"); return NULL; } + /* __BEGIN__ of Just's Hook + + Guido's metahook is defined as follows: + - if one of the bases has a __class__ attribute (but is + itself not a class!), call that thing with (name, + bases, methods) + In addition I propose almost the opposite: + - if the "methods" dict (__dict__ from the Python + perspective) has a __class__ key, call that thing with + (name, bases, methods) + + This means that metaclasses are not special anymore, and + you have to specify a metaclass *explicitly* to get meta + behaviour. Example: + + class Foo: + __class__ = MyMetaClass + + as apposed to + + MyMeta = MyMetaClass("MyMeta", (), {}) + + class Foo(MyMeta): pass + + as it is with Guido's hook. + + Reasons for this new hook: + - Guido's hook abuses inheritance syntax, making it + impossible to inherit from metaclasses without special + trickery. + - implementing Meta stuff seems cleaner. Or maybe it's + just me... + + At first I thought Guido's hook would not be compatible with + mine, but they work together beautifully: inheritance works + just like you would expect. + */ + { + PyObject *callable = NULL; + callable = PyDict_GetItemString(methods, "__class__"); + if (callable) { + PyObject *args; + PyObject *newclass = NULL; + PyDict_DelItemString(methods, "__class__"); + args = Py_BuildValue( + "(OOO)", name, bases, methods); + if (args != NULL) { + newclass = PyEval_CallObject( + callable, args); + Py_DECREF(args); + } + return newclass; + } else { + PyErr_Clear(); + } + } + /* __END__ of Just's Hook */ n = PyTuple_Size(bases); for (i = 0; i < n; i++) { PyObject *base = PyTuple_GET_ITEM(bases, i); if (!PyClass_Check(base)) { /* Call the base's *type*, if it is callable.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4