/usr/share/pyshared/reportlab/lib/attrmap.py is in python-reportlab 2.5-1.1build1.
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 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | #Copyright ReportLab Europe Ltd. 2000-2004
#see license.txt for license details
#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/lib/attrmap.py
__version__=''' $Id: attrmap.py 3660 2010-02-08 18:17:33Z damian $ '''
__doc__='''Framework for objects whose assignments are checked. Used by graphics.
We developed reportlab/graphics prior to Python 2 and metaclasses. For the
graphics, we wanted to be able to declare the attributes of a class, check
them on assignment, and convert from string arguments. Examples of
attrmap-based objects can be found in reportlab/graphics/shapes. It lets
us defined structures like the one below, which are seen more modern form in
Django models and other frameworks.
We'll probably replace this one day soon, hopefully with no impact on client
code.
class Rect(SolidShape):
"""Rectangle, possibly with rounded corners."""
_attrMap = AttrMap(BASE=SolidShape,
x = AttrMapValue(isNumber),
y = AttrMapValue(isNumber),
width = AttrMapValue(isNumber),
height = AttrMapValue(isNumber),
rx = AttrMapValue(isNumber),
ry = AttrMapValue(isNumber),
)
'''
from UserDict import UserDict
from reportlab.lib.validators import isAnything, _SequenceTypes, DerivedValue
from reportlab import rl_config
class CallableValue:
'''a class to allow callable initial values'''
def __init__(self,func,*args,**kw):
#assert iscallable(func)
self.func = func
self.args = args
self.kw = kw
def __call__(self):
return self.func(*self.args,**self.kw)
class AttrMapValue:
'''Simple multi-value holder for attribute maps'''
def __init__(self,validate=None,desc=None,initial=None, advancedUsage=0, **kw):
self.validate = validate or isAnything
self.desc = desc
self._initial = initial
self._advancedUsage = advancedUsage
for k,v in kw.items():
setattr(self,k,v)
def __getattr__(self,name):
#hack to allow callable initial values
if name=='initial':
if isinstance(self._initial,CallableValue): return self._initial()
return self._initial
elif name=='hidden':
return 0
raise AttributeError, name
def __repr__(self):
return 'AttrMapValue(%s)' % ', '.join(['%s=%r' % i for i in self.__dict__.iteritems()])
class AttrMap(UserDict):
def __init__(self,BASE=None,UNWANTED=[],**kw):
data = {}
if BASE:
if isinstance(BASE,AttrMap):
data = BASE.data #they used BASECLASS._attrMap
else:
if type(BASE) not in (type(()),type([])): BASE = (BASE,)
for B in BASE:
if hasattr(B,'_attrMap'):
data.update(getattr(B._attrMap,'data',{}))
else:
raise ValueError, 'BASE=%s has wrong kind of value' % str(B)
UserDict.__init__(self,data)
self.remove(UNWANTED)
self.data.update(kw)
def update(self,kw):
if isinstance(kw,AttrMap): kw = kw.data
self.data.update(kw)
def remove(self,unwanted):
for k in unwanted:
try:
del self[k]
except KeyError:
pass
def clone(self,UNWANTED=[],**kw):
c = AttrMap(BASE=self,UNWANTED=UNWANTED)
c.update(kw)
return c
def validateSetattr(obj,name,value):
'''validate setattr(obj,name,value)'''
if rl_config.shapeChecking:
map = obj._attrMap
if map and name[0]!= '_':
#we always allow the inherited values; they cannot
#be checked until draw time.
if isinstance(value, DerivedValue):
#let it through
pass
else:
try:
validate = map[name].validate
if not validate(value):
raise AttributeError, "Illegal assignment of '%s' to '%s' in class %s" % (value, name, obj.__class__.__name__)
except KeyError:
raise AttributeError, "Illegal attribute '%s' in class %s" % (name, obj.__class__.__name__)
obj.__dict__[name] = value
def _privateAttrMap(obj,ret=0):
'''clone obj._attrMap if required'''
A = obj._attrMap
oA = getattr(obj.__class__,'_attrMap',None)
if ret:
if oA is A:
return A.clone(), oA
else:
return A, None
else:
if oA is A:
obj._attrMap = A.clone()
def _findObjectAndAttr(src, P):
'''Locate the object src.P for P a string, return parent and name of attribute
'''
P = string.split(P, '.')
if len(P) == 0:
return None, None
else:
for p in P[0:-1]:
src = getattr(src, p)
return src, P[-1]
def hook__setattr__(obj):
if not hasattr(obj,'__attrproxy__'):
C = obj.__class__
import new
obj.__class__=new.classobj(C.__name__,(C,)+C.__bases__,
{'__attrproxy__':[],
'__setattr__':lambda self,k,v,osa=getattr(obj,'__setattr__',None),hook=hook: hook(self,k,v,osa)})
def addProxyAttribute(src,name,validate=None,desc=None,initial=None,dst=None):
'''
Add a proxy attribute 'name' to src with targets dst
'''
#sanity
assert hasattr(src,'_attrMap'), 'src object has no _attrMap'
A, oA = _privateAttrMap(src,1)
if type(dst) not in _SequenceTypes: dst = dst,
D = []
DV = []
for d in dst:
if type(d) in _SequenceTypes:
d, e = d[0], d[1:]
obj, attr = _findObjectAndAttr(src,d)
if obj:
dA = getattr(obj,'_attrMap',None)
|