degal/utils.py
author Tero Marttila <terom@fixme.fi>
Thu, 11 Jun 2009 22:50:21 +0300
changeset 96 d9cf1e272e90
parent 84 891545a38a2b
child 109 66a01c0806f1
permissions -rw-r--r--
fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
44
533b7e8b5d3b strip copyright/license boilerplate from modules, except dexif and formatbytes
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
     1
"""
533b7e8b5d3b strip copyright/license boilerplate from modules, except dexif and formatbytes
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
     2
    Miscellaneous utilities
533b7e8b5d3b strip copyright/license boilerplate from modules, except dexif and formatbytes
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
     3
"""
533b7e8b5d3b strip copyright/license boilerplate from modules, except dexif and formatbytes
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
     4
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
     5
import functools
23
10841abbc01f taggr2, which is starting to shape up
terom
parents: 20
diff changeset
     6
96
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
     7
class LazyProperty (object) :
12
c2d8e9a754a1 Major code restructuring. Version is now 0.5, templates use Mako, and the code is split off into several files under lib/
terom
parents:
diff changeset
     8
    """
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
     9
        Lazy-loaded cached properties.
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    10
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    11
        This functions by overriding the class's property attribute with the actual value attribute in the instance's
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    12
        dict, causing all future attribute lookups to return that directly.
96
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    13
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    14
        >>> class Foo (object) :
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    15
        ...     counter = 0
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    16
        ...     @lazy_load
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    17
        ...     def foo (self) :
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    18
        ...             self.counter += 1
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    19
        ...             return self.counter
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    20
        ... 
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    21
        >>> foo = Foo(); foo.foo, foo.foo, foo.counter
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    22
        (1, 1, 1)
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    23
12
c2d8e9a754a1 Major code restructuring. Version is now 0.5, templates use Mako, and the code is split off into several files under lib/
terom
parents:
diff changeset
    24
    """
c2d8e9a754a1 Major code restructuring. Version is now 0.5, templates use Mako, and the code is split off into several files under lib/
terom
parents:
diff changeset
    25
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    26
    def __init__ (self, func) :
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    27
        """
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    28
            Initialize with no value
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    29
        """
75
18b3b1926720 fix utils.LazyProperty
Tero Marttila <terom@fixme.fi>
parents: 73
diff changeset
    30
        
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    31
        # the getter function
75
18b3b1926720 fix utils.LazyProperty
Tero Marttila <terom@fixme.fi>
parents: 73
diff changeset
    32
        self.func = func
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    33
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    34
        # the attribute name
75
18b3b1926720 fix utils.LazyProperty
Tero Marttila <terom@fixme.fi>
parents: 73
diff changeset
    35
        self.name = func.__name__
19
8d3ffd87cb0b * move cgi-bin to de-cgi-bin so it doesn't conflict with my default alias... need to come up with a real solution to this
terom
parents: 18
diff changeset
    36
73
8897352630a5 misc. stuff in gallery.py utils.py
Tero Marttila <terom@fixme.fi>
parents: 59
diff changeset
    37
    def run (self, obj) :
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    38
        """
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    39
            Run the background func and return the to-be-cached value.
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    40
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    41
            `obj` is the object instance
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    42
        """
28
70b6c13d084f fancy new log format
terom
parents: 27
diff changeset
    43
75
18b3b1926720 fix utils.LazyProperty
Tero Marttila <terom@fixme.fi>
parents: 73
diff changeset
    44
        return self.func(obj)
73
8897352630a5 misc. stuff in gallery.py utils.py
Tero Marttila <terom@fixme.fi>
parents: 59
diff changeset
    45
 
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    46
    def store (self, obj, value) :
73
8897352630a5 misc. stuff in gallery.py utils.py
Tero Marttila <terom@fixme.fi>
parents: 59
diff changeset
    47
        """
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    48
            Store the cached value, overring ourself
73
8897352630a5 misc. stuff in gallery.py utils.py
Tero Marttila <terom@fixme.fi>
parents: 59
diff changeset
    49
        """
96
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    50
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    51
#        print "[%x] %r.__dict__[%r] = %r" % (id(obj), obj, self.name, value)
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    52
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    53
        obj.__dict__[self.name] = value
73
8897352630a5 misc. stuff in gallery.py utils.py
Tero Marttila <terom@fixme.fi>
parents: 59
diff changeset
    54
75
18b3b1926720 fix utils.LazyProperty
Tero Marttila <terom@fixme.fi>
parents: 73
diff changeset
    55
    def __get__ (self, obj, owner) :
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    56
        """
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    57
            Generate the value, store it as the attribute and return it.
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    58
        """
96
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    59
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    60
        # compute value
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    61
        value = self.run(obj)
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    62
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    63
        # store it
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    64
        self.store(obj, value)
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    65
        
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    66
        # return it
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    67
        return value
96
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    68
    
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    69
class LazyIteratorProperty (LazyProperty) :
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    70
    """
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    71
        A lazy-loaded property that automatically converts an iterator/genexp into a list.
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    72
    """
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    73
73
8897352630a5 misc. stuff in gallery.py utils.py
Tero Marttila <terom@fixme.fi>
parents: 59
diff changeset
    74
    def run (self, obj) :
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    75
        """
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    76
            Wrap LazyProperty.run to return a list
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    77
        """
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    78
96
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    79
        return list(self.func(obj))
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    80
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    81
lazy_load = LazyProperty
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    82
lazy_load_iter = LazyIteratorProperty
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    83
96
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    84
# testing
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    85
if __name__ == '__main__' :
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    86
    import doctest
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    87
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    88
    doctest.testmod()
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    89