[Python-Dev] Possible rough edges in Python 3 metaclasses (was Re: Language reference updated for metaclasses)
PJ Eby
pje at telecommunity.com
Tue Jun 5 06:03:17 CEST 2012
On Mon, Jun 4, 2012 at 10:43 PM, Eric Snow <ericsnowcurrently at gmail.com>wrote:
> On Mon, Jun 4, 2012 at 6:10 PM, PJ Eby <pje at telecommunity.com> wrote:
> > I mean that class-level __metaclass__ is no longer supported as of PEP
> 3115,
> > so I can't use that as a way to non-invasively obtain the enclosing
> class at
> > class creation time.
>
> Depends on what you mean by non-invasive:
>
Non-invasive meaning, "not requiring the user of the descriptor or
decorator to make extra declarations-at-a-distance, especially ones that
increase the likelihood of clashing machinery if multiple frameworks
require the same functionality." ;-)
That means class decorators, mixins, and explicit metaclasses don't work.
The class decorator adds yak shaving, and the others lead to functional
clashing.
Currently, my choices for porting these libraries (and their dependents) to
Python 3 are (in roughly descending order of preference):
1. Replace __builtins__.__build_class__ and hope PyPy et al follow
CPython's lead,
2. Abuse sys.set_trace() and __class__ to get a callback at the right
moment (because set_trace() *is* supported on other implementations in
practice right now, at least for 2.x), or
3. Write a class decorator like "@py3_is_less_dynamic_than_py2", put it in
a common library, and ask everybody and their dog to use it on any class
whose body contains any decorator or descriptor from any of my libraries
(or which someone else *derived* from any of my libraries, etc. ad
nauseam), oh and good luck finding which ones all of them are, and yeah, if
you miss it, stuff might not work. (Note, by the way, that this goes
against the advice of not changing APIs while migrating to Python 3... and
let's not forget all the documentation that has to be changed, each piece
of which must explain and motivate this new and apparently-pointless
decorator to the library's user.)
I would prefer to have an option 4 or 5 (where there's a standard Python
way to get a class creation callback from a class body), but #1 is honestly
the most attractive at the moment, as I might only need to implement it in
*one* library, with no changes to clients, including people who've built
stuff based on that library or any of its clients, recursively. (#2 would
also do it, but I was *really* hoping to get rid of that hack in Python 3.)
Given these choices, I hope it's more understandable why I'd want to lobby
for at least documenting __build_class__ and its replaceability, and
perhaps encouraging other Python 3 implementations to offer the same
feature. Given that implementing PEP 3115 and types.new_class() mean the
same functionality has to be present, and given that class creation is
generally not a performance-critical function, there's little reason for a
sufficiently dynamic Python implementation (by which I basically mean
Jython, IronPython, and PyPy) to support it. (More-static implementations
don't always even support metaclasses to begin with, so they're not going
to lose anything important by not supporting dynamic __build_class__.)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20120605/0137f4e8/attachment.html>
More information about the Python-Dev
mailing list