For those suggesting the operator module is actually a good choice, there's no way to add this function without making major changes to the module description (go read it - I only realised the problem when I went to add the docs). It's a bad fit (*much* worse than types or a class method)
--
Sent from my phone, thus the relative brevity :)
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
On May 09, 2012, at 05:20 PM, Nick Coghlan wrote:+1
>Ah, good point. In that case, consider me convinced: static method it
>is. It can join mro() as the second non-underscore method defined on
>type().
If I may dip into the bikeshed paint once more. I think it would be useful to
establish a naming convention for alternative constructors implemented as
{static,class}methods. I don't like `build_class()` much. Would you be
opposed to `type.new()`?
Given that the statement form is referred to as a "class definition", and this is the dynamic equivalent, I'm inclined to go with "type.define()". Dynamic type definition is more consistent with existing terminology than dynamic type creation.
--