File: __init__.py

package info (click to toggle)
python-bx 0.13.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,000 kB
  • sloc: python: 17,136; ansic: 2,326; makefile: 24; sh: 8
file content (112 lines) | stat: -rw-r--r-- 2,889 bytes parent folder | download | duplicates (2)
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
"""
Various useful utilities, mostly taken from the ASPN Python cookbook.
"""

import types

seq_types = type(()), type([])


def flatten(*args):
    for arg in args:
        if type(arg) in seq_types:
            for elem in arg:
                yield from flatten(elem)
        else:
            yield arg


def cross_lists(*sets):
    """Return the cross product of the arguments"""
    wheels = [iter(_) for _ in sets]
    digits = [next(it) for it in wheels]
    while True:
        yield digits[:]
        for i in range(len(digits) - 1, -1, -1):
            try:
                digits[i] = next(wheels[i])
                break
            except StopIteration:
                wheels[i] = iter(sets[i])
                digits[i] = next(wheels[i])
        else:
            break


# Cached / memoized methods


def cachedmethod(function):
    return types.MethodType(Memoize(function), None)


class Memoize:
    def __init__(self, function):
        self._cache = {}
        self._callable = function

    def __call__(self, *args, **kwds):
        cache = self._cache
        key = self._getKey(*args, **kwds)
        try:
            return cache[key]
        except KeyError:
            cachedValue = cache[key] = self._callable(*args, **kwds)
            return cachedValue

    def _getKey(self, *args, **kwds):
        return kwds and (args, ImmutableDict(kwds)) or args


class memoized:
    """Decorator that caches a function's return value each time it is called.
    If called later with the same arguments, the cached value is returned, and
    not re-evaluated.
    """

    def __init__(self, func):
        self.func = func
        self.cache = {}

    def __call__(self, *args):
        try:
            return self.cache[args]
        except KeyError:
            self.cache[args] = value = self.func(*args)
            return value
        except TypeError:
            # uncachable -- for instance, passing a list as an argument.
            # Better to not cache than to blow up entirely.
            return self.func(*args)

    def __repr__(self):
        """Return the function's docstring."""
        return self.func.__doc__


class ImmutableDict(dict):
    """A hashable dict."""

    def __init__(self, *args, **kwds):
        dict.__init__(self, *args, **kwds)

    def __setitem__(self, key, value):
        raise NotImplementedError("dict is immutable")

    def __delitem__(self, key):
        raise NotImplementedError("dict is immutable")

    def clear(self):
        raise NotImplementedError("dict is immutable")

    def setdefault(self, k, default=None):
        raise NotImplementedError("dict is immutable")

    def popitem(self):
        raise NotImplementedError("dict is immutable")

    def update(self, other):
        raise NotImplementedError("dict is immutable")

    def __hash__(self):
        return hash(tuple(self.items()))