/usr/share/pyshared/sqlobject/boundattributes.py is in python-sqlobject 0.12.4-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | """
Bound attributes are attributes that are bound to a specific class and
a specific name. In SQLObject a typical example is a column object,
which knows its name and class.
A bound attribute should define a method ``__addtoclass__(added_class,
name)`` (attributes without this method will simply be treated as
normal). The return value is ignored; if the attribute wishes to
change the value in the class, it must call ``setattr(added_class,
name, new_value)``.
BoundAttribute is a class that facilitates lazy attribute creation.
``bind_attributes(cls, new_attrs)`` is a function that looks for
attributes with this special method. ``new_attrs`` is a dictionary,
as typically passed into ``__classinit__`` with declarative (calling
``bind_attributes`` in ``__classinit__`` would be typical).
Note if you do this that attributes defined in a superclass will not
be rebound in subclasses. If you want to rebind attributes in
subclasses, use ``bind_attributes_local``, which adds a
``__bound_attributes__`` variable to your class to track these active
attributes.
"""
__all__ = ['BoundAttribute', 'BoundFactory', 'bind_attributes',
'bind_attributes_local']
import declarative
import events
class BoundAttribute(declarative.Declarative):
"""
This is a declarative class that passes all the values given to it
to another object. So you can pass it arguments (via
__init__/__call__) or give it the equivalent of keyword arguments
through subclassing. Then a bound object will be added in its
place.
To hook this other object in, override ``make_object(added_class,
name, **attrs)`` and maybe ``set_object(added_class, name,
**attrs)`` (the default implementation of ``set_object``
just resets the attribute to whatever ``make_object`` returned).
Also see ``BoundFactory``.
"""
_private_variables = (
'_private_variables',
'_all_attributes',
'__classinit__',
'__addtoclass__',
'_add_attrs',
'set_object',
'make_object',
'clone_in_subclass',
)
_all_attrs = ()
clone_for_subclass = True
def __classinit__(cls, new_attrs):
declarative.Declarative.__classinit__(cls, new_attrs)
cls._all_attrs = cls._add_attrs(cls, new_attrs)
def __instanceinit__(self, new_attrs):
declarative.Declarative.__instanceinit__(self, new_attrs)
self.__dict__['_all_attrs'] = self._add_attrs(self, new_attrs)
def _add_attrs(this_object, new_attrs):
private = this_object._private_variables
all_attrs = list(this_object._all_attrs)
for key in new_attrs.keys():
if key.startswith('_') or key in private:
continue
if key not in all_attrs:
all_attrs.append(key)
return tuple(all_attrs)
_add_attrs = staticmethod(_add_attrs)
def __addtoclass__(self, cls, added_class, attr_name):
me = self or cls
attrs = {}
for name in me._all_attrs:
attrs[name] = getattr(me, name)
attrs['added_class'] = added_class
attrs['attr_name'] = attr_name
obj = me.make_object(**attrs)
if self.clone_for_subclass:
def on_rebind(new_class_name, bases, new_attrs,
post_funcs, early_funcs):
def rebind(new_class):
me.set_object(
new_class, attr_name,
me.make_object(**attrs))
post_funcs.append(rebind)
events.listen(receiver=on_rebind, soClass=added_class,
signal=events.ClassCreateSignal, weak=False)
me.set_object(added_class, attr_name, obj)
__addtoclass__ = declarative.classinstancemethod(__addtoclass__)
def set_object(cls, added_class, attr_name, obj):
setattr(added_class, attr_name, obj)
set_object = classmethod(set_object)
def make_object(cls, added_class, attr_name, *args, **attrs):
raise NotImplementedError
make_object = classmethod(make_object)
def __setattr__(self, name, value):
self.__dict__['_all_attrs'] = self._add_attrs(self, {name: value})
self.__dict__[name] = value
class BoundFactory(BoundAttribute):
"""
This will bind the attribute to whatever is given by
``factory_class``. This factory should be a callable with the
signature ``factory_class(added_class, attr_name, *args, **kw)``.
The factory will be reinvoked (and the attribute rebound) for
every subclassing.
"""
factory_class = None
_private_variables = (
BoundAttribute._private_variables + ('factory_class',))
def make_object(cls, added_class, attr_name, *args, **kw):
return cls.factory_class(added_class, attr_name, *args, **kw)
|