MRAB wrote: > On 2019-03-04 18:02, Jimmy Girardet wrote: >> Hello, >> >> I'm looking for an explanation where live classes created by >> types.new_class() : >> >> py> import types >> >> py> types.new_class('A') >> >> types.A >> >> py> types.A >> >> AttributeError: module 'types' has no attribute 'A' >> >> py> _.__module__ >> >> 'types' >> >> >> The new class comes from `types` module without being inside. >> >> That's annoying to me for my use case : >> >> I'm trying to create dataclasses on the fly using make_dataclass (which >> uses types.new_class). For new created classes, I have a cache to not >> recreate twice the same class. >> >> But I want to be sure not to override an existing class somewhere in the >> namespace which is already 'types.MyNewclass'. but how to check it if >> it's not in types ? >> >> To be clear : >> >> make_dataclass('Bla', {}) should raise an error if something named >> 'types.Bla' already exists. >> >> I hope I'm clear enough. >> > 'new_class' creates a new class with the given name and returns a > reference to it. > > The class doesn't 'live' anywhere. > > Although you might /think/ that an object lives in a certain namespace, > it's just that there's a name there that's bound to the object. > > You can, in fact, create 2 classes with the same name. > > >>> import types > >>> t1 = types.new_class('A') > >>> t2 = types.new_class('A') > >>> t1 is t2 > False
However, the underlying type() call assumes that you are going to inject the class into the current module -- which is why the OP's class appears to be part of the types module >>> types.new_class("Foo") <class 'types.Foo'> and >>> type("Foo", (), {}) <class '__main__.Foo'> appears to be in __main__. This is correct in the majority of cases where the class is defined with class A: pass which can be thought of as syntactic sugar for A = type("A", (), {}) In the case of types.new_class() it is rather confusing -- perhaps the function should follow the example of collections.namedtuple and set the __module__ attribute to the caller's namespace. -- https://mail.python.org/mailman/listinfo/python-list