reportlab/lib/attrmap.py
author andy_robinson
Wed, 24 Jul 2002 19:56:39 +0000
changeset 1683 7fa753e4420a
parent 1677 1450177dd19e
child 1693 1a71e3509e39
permissions -rw-r--r--
Removed all trailing whitespace
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
946
0bda695b09ce Initial version
rgbecker
parents:
diff changeset
     1
#copyright ReportLab Inc. 2000
0bda695b09ce Initial version
rgbecker
parents:
diff changeset
     2
#see license.txt for license details
0bda695b09ce Initial version
rgbecker
parents:
diff changeset
     3
#history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/lib/attrmap.py?cvsroot=reportlab
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
     4
#$Header: /tmp/reportlab/reportlab/lib/attrmap.py,v 1.6 2002/07/24 19:56:37 andy_robinson Exp $
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
     5
__version__=''' $Id: attrmap.py,v 1.6 2002/07/24 19:56:37 andy_robinson Exp $ '''
946
0bda695b09ce Initial version
rgbecker
parents:
diff changeset
     6
from UserDict import UserDict
1549
df0706b21a94 Fixed to work with 2.2
rgbecker
parents: 948
diff changeset
     7
from reportlab.lib.validators import isAnything, _SequenceTypes
946
0bda695b09ce Initial version
rgbecker
parents:
diff changeset
     8
0bda695b09ce Initial version
rgbecker
parents:
diff changeset
     9
class CallableValue:
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    10
    '''a class to allow callable initial values'''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    11
    def __init__(self,func,*args,**kw):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    12
        #assert iscallable(func)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    13
        self.func = func
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    14
        self.args = args
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    15
        self.kw = kw
946
0bda695b09ce Initial version
rgbecker
parents:
diff changeset
    16
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    17
    def __call__(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    18
        return apply(self.func,self.args,self.kw)
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
    19
946
0bda695b09ce Initial version
rgbecker
parents:
diff changeset
    20
class AttrMapValue:
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    21
    '''Simple multi-value holder for attribute maps'''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    22
    def __init__(self,validate=None,desc=None,initial=None, **kw):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    23
        self.validate = validate or isAnything
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    24
        self.desc = desc
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    25
        self.initial = initial
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    26
        for k,v in kw.items():
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    27
            setattr(self,k,v)
946
0bda695b09ce Initial version
rgbecker
parents:
diff changeset
    28
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    29
    def __getattr__(self,name):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    30
        #hack to allow callable initial values
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    31
        if name=='initial':
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    32
            if isinstance(self._initial,CallableValue): return self._initial()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    33
            return self._initial
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    34
        elif name=='hidden':
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    35
            return 0
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    36
        raise AttributeError, name
946
0bda695b09ce Initial version
rgbecker
parents:
diff changeset
    37
0bda695b09ce Initial version
rgbecker
parents:
diff changeset
    38
class AttrMap(UserDict):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    39
    def __init__(self,BASE=None,UNWANTED=[],**kw):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    40
        if BASE:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    41
            if isinstance(BASE,AttrMap):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    42
                data = BASE.data                        #they used BASECLASS._attrMap
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    43
            elif hasattr(BASE,'_attrMap'):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    44
                data = getattr(BASE._attrMap,'data',{}) #they gave us the BASECLASS
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    45
            else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    46
                raise ValueError, 'BASE=%s has wrong kind of value' % str(BASE)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    47
        else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    48
            data = {}
946
0bda695b09ce Initial version
rgbecker
parents:
diff changeset
    49
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    50
        UserDict.__init__(self,data)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    51
        self.remove(UNWANTED)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    52
        self.data.update(kw)
948
2531b35adf85 New AttrMap emplacement
rgbecker
parents: 946
diff changeset
    53
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    54
    def update(self,kw):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    55
        if isinstance(kw,AttrMap): kw = kw.data
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    56
        self.data.update(kw)
946
0bda695b09ce Initial version
rgbecker
parents:
diff changeset
    57
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    58
    def remove(self,unwanted):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    59
        for k in unwanted:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    60
            try:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    61
                del self[k]
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    62
            except KeyError:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    63
                pass
946
0bda695b09ce Initial version
rgbecker
parents:
diff changeset
    64
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    65
    def clone(self,UNWANTED=[],**kw):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    66
        c = AttrMap(BASE=self,UNWANTED=UNWANTED)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    67
        c.update(kw)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    68
        return c
948
2531b35adf85 New AttrMap emplacement
rgbecker
parents: 946
diff changeset
    69
2531b35adf85 New AttrMap emplacement
rgbecker
parents: 946
diff changeset
    70
def validateSetattr(obj,name,value):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    71
    '''validate setattr(obj,name,value)'''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    72
    map = obj._attrMap
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    73
    if map and name[0]!= '_':
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    74
        try:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    75
            validate = map[name].validate
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    76
            if not validate(value):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    77
                raise AttributeError, "Illegal assignment of '%s' to '%s' in class %s" % (value, name, obj.__class__.__name__)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    78
        except KeyError:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    79
            raise AttributeError, "Illegal attribute '%s' in class %s" % (name, obj.__class__.__name__)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    80
    obj.__dict__[name] = value
1549
df0706b21a94 Fixed to work with 2.2
rgbecker
parents: 948
diff changeset
    81
df0706b21a94 Fixed to work with 2.2
rgbecker
parents: 948
diff changeset
    82
def _privateAttrMap(obj,ret=0):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    83
    '''clone obj._attrMap if required'''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    84
    A = obj._attrMap
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    85
    oA = getattr(obj.__class__,'_attrMap',None)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    86
    if ret:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    87
        if oA is A:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    88
            return A.clone(), oA
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    89
        else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    90
            return A, None
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    91
    else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    92
        if oA is A:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    93
            obj._attrMap = A.clone()
1549
df0706b21a94 Fixed to work with 2.2
rgbecker
parents: 948
diff changeset
    94
df0706b21a94 Fixed to work with 2.2
rgbecker
parents: 948
diff changeset
    95
def _findObjectAndAttr(src, P):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    96
    '''Locate the object src.P for P a string, return parent and name of attribute
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    97
    '''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    98
    P = string.split(P, '.')
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
    99
    if len(P) == 0:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   100
        return None, None
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   101
    else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   102
        for p in P[0:-1]:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   103
            src = getattr(src, p)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   104
        return src, P[-1]
1549
df0706b21a94 Fixed to work with 2.2
rgbecker
parents: 948
diff changeset
   105
df0706b21a94 Fixed to work with 2.2
rgbecker
parents: 948
diff changeset
   106
def addProxyAttribute(src,name=None,dst=None):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   107
    '''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   108
    Add a proxy attribute 'name' to src with targets dst
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   109
    '''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   110
    #sanity
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   111
    assert hasattr(src,'_attrMap'), 'src object has no _attrMap'
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   112
    A, oA = _privateAttrMap(src,1)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   113
    assert name and name in A.keys(), 'invalid proxy attribute name %s' % repr(name)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   114
    if type(dst) not in _SequenceTypes: dst = dst,
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   115
    D = []
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   116
    DV = []
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   117
    for d in dst:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   118
        if type(d) in _SequenceTypes:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   119
            d, e = d[0], d[1:]
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   120
        obj, attr = _findObjectAndAttr(src,d)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   121
        if obj:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1559
diff changeset
   122
            dA = getattr(obj,'_attrMap',None)
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
   123
            assert dA and attr in dA.keys(), 'target attribute %s not in _attrMap' % d