
urban.dani+py at gmail
May 8, 2012, 11:37 PM
Post #15 of 37
(719 views)
Permalink
|
On Wed, May 9, 2012 at 3:10 AM, Nick Coghlan <ncoghlan [at] gmail> wrote: > On Wed, May 9, 2012 at 8:37 AM, Tres Seaver <tseaver [at] palladion> wrote: >>> No, the "mcl" in the call is just the designated metaclass - the >>> *actual* metaclass of the resulting class definition may be something >>> different. That's why this is a separate method from mcl.__new__. >> >> Why not make it a static method, if there is no notion of a useful 'cls' >> argument? > > We need the explicitly declared metaclass as well as the bases in > order to determine the correct metaclass. Note, that the current patch (at http://bugs.python.org/issue14588) obtains the explicitly declared metaclass from the keywords dict (exactly like the class statement). > As a static method, the invocation would look like: > > Â Â type.build_class(mcl, bases, keywords, exec_body) So I think, that in theory, this static method could work exactly like the operator.build_class function in the patch: type.build_class(name, bases, kwds, exec_body) (it doesn't need the mcls in a separate argument, it is in kwds). > Since mcl will always be an instance of type in 3.x (due to all > classes being subtypes of object), it makes more sense to just make it > a class method and invoke the method on the declared metaclass: > > Â Â mcl.build_class(bases, keywords, exec_body) We could do that, but "mcl will always be an instance of type in 3.x" is not strictly true: an arbitrary callable is still allowed as a metaclass in a class statement, so I think the build_class function should support it too. > The following assertion *does not* hold reliably: > > Â Â cls = mcl.build_class(bases, keywords, exec_body) > Â Â assert type(cls) == mcl # Not guaranteed Right. > Instead, the invariant that holds is the weaker assertion: > > Â Â cls = mcl.build_class(bases, keywords, exec_body) > Â Â assert isinstance(cls, mcl) But if mcl is an arbitrary callable, this is also not always true (of course, then the invocation above wouldn't work, but with a class statement we could still create such "classes": >>> def f(mcls, name, bases): ... return 0 ... >>> class C(metaclass=f): ... pass ... >>> C 0 Daniel _______________________________________________ Python-Dev mailing list Python-Dev [at] python http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
|