summaryrefslogtreecommitdiff
path: root/systrace/catapult/common/py_utils/py_utils/slots_metaclass.py
diff options
context:
space:
mode:
Diffstat (limited to 'systrace/catapult/common/py_utils/py_utils/slots_metaclass.py')
-rw-r--r--systrace/catapult/common/py_utils/py_utils/slots_metaclass.py27
1 files changed, 27 insertions, 0 deletions
diff --git a/systrace/catapult/common/py_utils/py_utils/slots_metaclass.py b/systrace/catapult/common/py_utils/py_utils/slots_metaclass.py
new file mode 100644
index 0000000..ae36c67
--- /dev/null
+++ b/systrace/catapult/common/py_utils/py_utils/slots_metaclass.py
@@ -0,0 +1,27 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+class SlotsMetaclass(type):
+ """This metaclass requires all subclasses to define __slots__.
+
+ Usage:
+ class Foo(object):
+ __metaclass__ = slots_metaclass.SlotsMetaclass
+ __slots__ = '_property0', '_property1',
+
+ __slots__ must be a tuple containing string names of all properties that the
+ class contains.
+ Defining __slots__ reduces memory usage, accelerates property access, and
+ prevents dynamically adding unlisted properties.
+ If you need to dynamically add unlisted properties to a class with this
+ metaclass, then take a step back and rethink your goals. If you really really
+ need to dynamically add unlisted properties to a class with this metaclass,
+ add '__dict__' to its __slots__.
+ """
+
+ def __new__(mcs, name, bases, attrs):
+ assert '__slots__' in attrs, 'Class "%s" must define __slots__' % name
+ assert isinstance(attrs['__slots__'], tuple), '__slots__ must be a tuple'
+
+ return super(SlotsMetaclass, mcs).__new__(mcs, name, bases, attrs)