[Python-Dev] Possible rough edges in Python 3 metaclasses (was Re: Language reference updated for metaclasses) (original) (raw)
Nick Coghlan ncoghlan at gmail.com
Tue Jun 5 01🔞07 CEST 2012
- Previous message: [Python-Dev] Language reference updated for metaclasses
- Next message: [Python-Dev] Possible rough edges in Python 3 metaclasses (was Re: Language reference updated for metaclasses)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Tue, Jun 5, 2012 at 8:58 AM, PJ Eby <pje at telecommunity.com> wrote:
On Mon, Jun 4, 2012 at 6:15 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
It's actually the pre-decoration class, since the cell is initialised before the class is passed to the first decorator. I agree it's a little weird, but I did try to describe it accurately in the new docs. I see that now; it might be helpful to explicitly call that out. This is adding to my list of Python 3 metaclass gripes, though. In Python 2, I have in-the-body-of-a-class decorators implemented using metaclasses, that will no longer work because of PEP 3115...
I'm not quite following this one - do you mean they won't support prepare, won't play nicely with other metaclasses that implement prepare, or something else?
and if I switch to using class decorators instead, then they won't work because of PEP 3135. :-(
Yeah, 3135 has had some "interesting" consequences :P (e.g. class body level class definitions are still broken at the moment if you also reference super: http://bugs.python.org/issue12370)
Meanwhile, mixing metaclasses is more difficult than ever, due to prepare, and none of these flaws can be worked around officially, because buildclass is an "implementation detail". I really want to like Python 3, but am still hoping against hope for the restoration of hooks that metaclass allowed, or some alternative mechanism that would serve the same use cases.
Specifically, my main use case is method-level decorators and attribute descriptors that need to interact with a user-defined class, without requiring that user-defined class to either 1) redundantly decorate the class or 2) inherit from some specific base or inject a specific metaclass. I only use metaclass in 2.x for this because it's the only way for code executed in a class body to gain access to the class at creation time. The reason for wanting this to be transparent is that 1) if you forget the redundant class-decorator, mixin, or metaclass, stuff will silently not work,
Why would it silently not work? What's preventing you from having decorators that create wrapped functions that fail noisily when called, then providing a class decorator that unwraps those functions, fixes them up with the class references they need and stores the unwrapped and updated versions back on the class.
You call it redundant, I call it explicit.
and 2) mixing bases or metaclasses has much higher coupling to the library providing the decorators or descriptors, and greatly increases the likelihood of mixing metaclasses.
So don't do that, then. Be explicit.
And at the moment, the only workaround I can come up with that doesn't involve replacing buildclass is abusing the system trace hook; ISTM that replacing buildclass is the better of those two options.
Stop trying to be implicit. Implicit magic sucks, don't add more (PEP 3135 is bad enough).
At this point, with the additions of types.newclass(), ISTM that every Python implementation will have to have a buildclass function or its equivalent; all that remains is the question of whether they allow replacing it.
types.new_class() is actually a pure Python reimplementation of the PEP 3115 algorithm. Why would it imply the need for a build_class function?
Cheers, Nick.
-- Nick Coghlan  |  ncoghlan at gmail.com  |  Brisbane, Australia
- Previous message: [Python-Dev] Language reference updated for metaclasses
- Next message: [Python-Dev] Possible rough edges in Python 3 metaclasses (was Re: Language reference updated for metaclasses)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]