class B(type):
__slots__ = ()
class A(metaclass=B):
pass
A.test = "test"
"A" is instance of metaclass "B" and "B" have __slots__ defined - why I have __dict__ at class A? How I can create class object without __dict__?
class B(type):
__slots__ = ()
class A(metaclass=B):
pass
A.test = "test"
"A" is instance of metaclass "B" and "B" have __slots__ defined - why I have __dict__ at class A? How I can create class object without __dict__?
You cannot do this; classes always have a __dict__.
You can only use __slots__ on classes to produce instances without a __dict__, not on meta types. You'd normally only produce a few classes, so there is not much point in supporting __slots__ on metaclasses.
Don't use __slots__ to prevent attributes being set. Use __setattr__ for that instead:
class NoAttributesClassMeta(type):
def __setattr__(cls, name, value):
if name not in cls.__dict__:
raise AttributeError("Cannot set attributes")
type.__setattr__(cls, name, value)
__slots__ won't stop you from setting an attribute to a class, you need to override __setattr__ for that. Something like this should do it:
class B(type):
def __new__(cls, clsname, bases, dct):
dct['__slots__'] = ('x',)
return type.__new__(cls, clsname, bases, dct)
def __setattr__(cls, attr, val):
if attr not in cls.__slots__:
raise AttributeError('Can\'t set {!r}'.format(attr))
else:
type.__setattr__(cls, attr, val)
class A(metaclass=B):
pass
Demo:
>>> A.x = 1
>>> A.y = 2
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
A.y = 2
File "C:\Python27\so.py", line 7, in __setattr__
raise AttributeError('Can\'t set {!r}'.format(attr))
AttributeError: Can't set 'y'