Completed
Push — master ( b23d93...0e246a )
by
unknown
01:18
created

zipline.utils.Sentinel   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 20
Duplicated Lines 0 %
Metric Value
dl 0
loc 20
rs 10
wmc 5
1
"""
2
Construction of sentinel objects.
3
4
Sentinel objects are used when you only care to check for object identity.
5
"""
6
import sys
7
from textwrap import dedent
8
9
10
def sentinel(name, doc=None):
11
    try:
12
        value = sentinel._cache[name]  # memoized
13
    except KeyError:
14
        pass
15
    else:
16
        if doc == value.__doc__:
17
            return value
18
19
        raise ValueError(dedent(
20
            """\
21
            New sentinel value %r conflicts with an existing sentinel of the
22
            same name.
23
            Old sentinel docstring: %r
24
            New sentinel docstring: %r
25
            Resolve this conflict by changing the name of one of the sentinels.
26
            """,
27
        ) % (name, value.__doc__, doc))
28
29
    @object.__new__   # bind a single instance to the name 'Sentinel'
30
    class Sentinel(object):
31
        __doc__ = doc
32
        __slots__ = ('__weakref__',)
33
        __name__ = name
34
35
        def __new__(cls):
36
            raise TypeError('cannot create %r instances' % name)
37
38
        def __repr__(self):
39
            return 'sentinel(%r)' % name
40
41
        def __reduce__(self):
42
            return sentinel, (name, doc)
43
44
        def __deepcopy__(self, _memo):
45
            return self
46
47
        def __copy__(self):
48
            return self
49
50
    cls = type(Sentinel)
51
    try:
52
        # traverse up one frame to find the module where this is defined
53
        cls.__module__ = sys._getframe(1).f_globals['__name__']
54
    except (ValueError, KeyError):
55
        # Couldn't get the name from the calling scope, just use None.
56
        cls.__module__ = None
57
58
    sentinel._cache[name] = Sentinel  # cache result
59
    return Sentinel
60
sentinel._cache = {}
61