43 lines
1.8 KiB
Python
43 lines
1.8 KiB
Python
# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
|
|
# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
|
|
|
|
class ClassInitMeta(type):
|
|
|
|
def __new__(meta, class_name, bases, new_attrs):
|
|
cls = type.__new__(meta, class_name, bases, new_attrs)
|
|
if (new_attrs.has_key('__classinit__')
|
|
and not isinstance(cls.__classinit__, staticmethod)):
|
|
setattr(cls, '__classinit__',
|
|
staticmethod(cls.__classinit__.im_func))
|
|
if hasattr(cls, '__classinit__'):
|
|
cls.__classinit__(cls, new_attrs)
|
|
return cls
|
|
|
|
def build_properties(cls, new_attrs):
|
|
"""
|
|
Given a class and a new set of attributes (as passed in by
|
|
__classinit__), create or modify properties based on functions
|
|
with special names ending in __get, __set, and __del.
|
|
"""
|
|
for name, value in new_attrs.items():
|
|
if (name.endswith('__get') or name.endswith('__set')
|
|
or name.endswith('__del')):
|
|
base = name[:-5]
|
|
if hasattr(cls, base):
|
|
old_prop = getattr(cls, base)
|
|
if not isinstance(old_prop, property):
|
|
raise ValueError(
|
|
"Attribute %s is a %s, not a property; function %s is named like a property"
|
|
% (base, type(old_prop), name))
|
|
attrs = {'fget': old_prop.fget,
|
|
'fset': old_prop.fset,
|
|
'fdel': old_prop.fdel,
|
|
'doc': old_prop.__doc__}
|
|
else:
|
|
attrs = {}
|
|
attrs['f' + name[-3:]] = value
|
|
if name.endswith('__get') and value.__doc__:
|
|
attrs['doc'] = value.__doc__
|
|
new_prop = property(**attrs)
|
|
setattr(cls, base, new_prop)
|