/me pages thoughts from 12 months ago back into brain... On Sun, Apr 15, 2012 at 7:36 PM, Daniel Urban <urban.dani...@gmail.com> wrote: > On Tue, Apr 19, 2011 at 16:10, Nick Coghlan <ncogh...@gmail.com> wrote: >> Initially I was going to suggest making __build_class__ part of the >> language definition rather than a CPython implementation detail, but >> then I realised that various CPython specific elements in its >> signature made that a bad idea. > > Are you referring to the first 'func' argument? (Which is basically > the body of the "class" statement, if I'm not mistaken).
Yup, I believe that was my main objection to exposing __build_class__ directly. There's no obligation for implementations to build a throwaway function to evaluate a class body. > __prepare__ also needs the name and optional keyword arguments. So it > probably should be something like "operator.prepare(name, bases, > metaclass, **kw)". But this way it would need almost the same > arguments as __build_class__(func, name, *bases, metaclass=None, > **kwds). True. >> The correct idiom for dynamic type creation in a PEP 3115 world would then >> be: >> >> from operator import prepare >> cls = type(name, bases, prepare(type, bases)) >> >> Thoughts? > > When creating a dynamic type, we may want to do it with a non-empty > namespace. Maybe like this (with the extra arguments mentioned above): > > from operator import prepare > ns = prepare(name, bases, type, **kwargs) > ns.update(my_ns) # add the attributes we want > cls = type(name, bases, ns) > > What about an "operator.build_class(name, bases, ns, **kw)" function? > It would work like this: > > def build_class(name, bases, ns, **kw): > metaclass = kw.pop('metaclass', type) > pns = prepare(name, bases, metaclass, **kw) > pns.update(ns) > return metaclass(name, bases, pns) > > (Where 'prepare' is the same as above). > This way we wouldn't even need to make 'prepare' public, and the new > way to create a dynamic type would be: > > from operator import build_class > cls = build_class(name, bases, ns, **my_kwargs) No, I think we would want to expose the created namespace directly - that way people can use update(), direct assigment, exec(), eval(), or whatever other mechanism they choose to handle the task of populating the namespace. However, a potentially cleaner way to do that might be offer use an optional callback API rather than exposing a separate public prepare() function. Something like: def build_class(name, bases=(), kwds=None, eval_body=None): metaclass, ns = _prepare(name, bases, kwds) if eval_body is not None: eval_body(ns) return metaclass(name, bases, ns) Cheers, 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