Completed
Push — master ( 203a93...96107c )
by Oleksandr
01:54
created

isotopic_logging.InjectionLocalStack   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 22
Duplicated Lines 0 %

Test Coverage

Coverage 100%
Metric Value
dl 0
loc 22
ccs 15
cts 15
cp 1
rs 10
wmc 6

5 Methods

Rating   Name   Duplication   Size   Complexity  
A push() 0 2 1
A is_empty() 0 3 1
A pop() 0 2 1
A __init__() 0 3 1
A top() 0 6 2
1
# -*- coding: utf-8 -*-
2
3 1
import time
4 1
import threading
5
6 1
from collections import deque, namedtuple
7
8 1
from .injectors import (
9
    DirectPrefixInjector, StaticPrefixInjector, AutoprefixInjector,
10
    HybrydPrefixInjector,
11
)
12 1
from .injectors import merge_injectors
13
14
15 1
StackItem = namedtuple('StackItem', ('injector', 'parent', ))
16
17
18 1
class InjectionLocalStack(threading.local):
19
20 1
    def __init__(self):
21 1
        self._container = deque()
22 1
        super(InjectionLocalStack, self).__init__()
23
24 1
    def push(self, item):
25 1
        self._container.append(item)
26
27 1
    def pop(self):
28 1
        return self._container.pop()
29
30 1
    @property
31
    def top(self):
32 1
        try:
33 1
            return self._container[-1]
34 1
        except IndexError:
35 1
            return None
36
37 1
    @property
38
    def is_empty(self):
39 1
        return not self._container
40
41
42 1
_stack = InjectionLocalStack()
43
44
45 1
class InjectionContext(object):
46
47 1
    _old_enter_time = None
48
49 1
    def __init__(self, injector, inherit=False):
50 1
        if _stack.is_empty:
51 1
            if callable(injector):
52 1
                injector = injector()
53
54 1
            self._push(injector)
55 1
        elif inherit:
56 1
            if callable(injector):
57 1
                injector = injector()
58
59 1
            injector = merge_injectors(_stack.top.injector, injector)
60 1
            self._push(injector)
61
62 1
    def _push(self, injector):
63 1
        item = StackItem(injector, self)
64 1
        _stack.push(item)
65
66 1
    def __enter__(self):
67 1
        inj = _stack.top.injector
68 1
        self._old_enter_time, inj.enter_time = inj.enter_time, time.time()
69 1
        return inj
70
71 1
    def __exit__(self, exc_type, value, traceback):
72 1
        item = _stack.top
73
74 1
        inj = item.injector
75 1
        inj.enter_time, self._old_enter_time = self._old_enter_time, None
76
77 1
        if item.parent is self:
78 1
            _stack.pop()
79
80
81 1
def direct_injector(prefix, inherit=False):
82 1
    return InjectionContext(
83
        lambda: DirectPrefixInjector(prefix),
84
        inherit)
85
86
87 1
def static_injector(prefix, delimiter=None, inherit=False):
88 1
    return InjectionContext(
89
        lambda: StaticPrefixInjector(prefix, delimiter),
90
        inherit)
91
92
93 1
def auto_injector(oid_generator=None, delimiter=None, inherit=False):
94 1
    return InjectionContext(
95
        lambda: AutoprefixInjector(oid_generator, delimiter),
96
        inherit)
97
98
99 1
def hybrid_injector(prefix, oid_generator=None, delimiter=None, inherit=False):
100 1
    return InjectionContext(
101
        lambda: HybrydPrefixInjector(prefix, oid_generator, delimiter),
102
        inherit)
103