On Tue, Jun 5, 2012 at 2:03 PM, PJ Eby <p...@telecommunity.com> wrote: > On Mon, Jun 4, 2012 at 10:43 PM, Eric Snow <ericsnowcurren...@gmail.com> > wrote: >> >> On Mon, Jun 4, 2012 at 6:10 PM, PJ Eby <p...@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,
Please don't try to coerce everyone else into supporting such an ugly hack by abusing an implementation detail. There's a reason types.new_class() uses a different signature. Deliberately attempting to present python-dev with a fait accompli instead of building consensus for officially adding a feature to the language is *not cool*. > 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.) Please be patient and let us work out a solution that has at least some level of consensus associated with it, rather than running off and doing your own thing. As I understand it, what you currently do is, from a running decorator, walk the stack with sys._getframes() and insert a "__metaclass__" value into the class namespace. Now, one minor annoyance with current class decorators is that they're *not* inherited. This is sometimes what you want, but sometimes you would prefer to automatically decorate all subclasses as well. Currently, that means writing a custom metaclass to automatically apply the decorators. This has all the problems you have noted with composability. It seems then, that a potentially clean solution may be found by adding a *dynamic* class decoration hook. As a quick sketch of such a scheme, add the following step to the class creation process (between the current class creation process, but before the execution of lexical decorators): for mro_cls in cls.mro(): decorators = mro_cls.__dict__.get("__decorators__", ()) for deco in reversed(decorators): cls = deco(cls) Would such a dynamic class decoration hook meet your use case? Such a hook has use cases (specifically involving decorator inheritance) that *don't* require the use of sys._getframes(), so is far more likely to achieve the necessary level of consensus. As a specific example, the unittest module could use it to provide test parameterisation without needing a custom metaclass. > 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. You've jumped to a hackish solution instead of taking a step back and trying to think of a potentially elegant addition to the language that is more composable and doesn't require modification of process global state. You complain that metaclasses are hard to compose, and your "solution" is to monkeypatch a deliberately undocumented builtin? Regards, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com