Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/dogpile/util/langhelpers.py : 37%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import collections
2import re
4from . import compat
7def coerce_string_conf(d):
8 result = {}
9 for k, v in d.items():
10 if not isinstance(v, compat.string_types):
11 result[k] = v
12 continue
14 v = v.strip()
15 if re.match(r"^[-+]?\d+$", v):
16 result[k] = int(v)
17 elif re.match(r"^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?$", v):
18 result[k] = float(v)
19 elif v.lower() in ("false", "true"):
20 result[k] = v.lower() == "true"
21 elif v == "None":
22 result[k] = None
23 else:
24 result[k] = v
25 return result
28class PluginLoader(object):
29 def __init__(self, group):
30 self.group = group
31 self.impls = {}
33 def load(self, name):
34 if name in self.impls:
35 return self.impls[name]()
36 else: # pragma NO COVERAGE
37 import pkg_resources
39 for impl in pkg_resources.iter_entry_points(self.group, name):
40 self.impls[name] = impl.load
41 return impl.load()
42 else:
43 raise self.NotFound(
44 "Can't load plugin %s %s" % (self.group, name)
45 )
47 def register(self, name, modulepath, objname):
48 def load():
49 mod = __import__(modulepath, fromlist=[objname])
50 return getattr(mod, objname)
52 self.impls[name] = load
54 class NotFound(Exception):
55 """The specified plugin could not be found."""
58class memoized_property(object):
59 """A read-only @property that is only evaluated once."""
61 def __init__(self, fget, doc=None):
62 self.fget = fget
63 self.__doc__ = doc or fget.__doc__
64 self.__name__ = fget.__name__
66 def __get__(self, obj, cls):
67 if obj is None:
68 return self
69 obj.__dict__[self.__name__] = result = self.fget(obj)
70 return result
73def to_list(x, default=None):
74 """Coerce to a list."""
75 if x is None:
76 return default
77 if not isinstance(x, (list, tuple)):
78 return [x]
79 else:
80 return x
83class KeyReentrantMutex(object):
84 def __init__(self, key, mutex, keys):
85 self.key = key
86 self.mutex = mutex
87 self.keys = keys
89 @classmethod
90 def factory(cls, mutex):
91 # this collection holds zero or one
92 # thread idents as the key; a set of
93 # keynames held as the value.
94 keystore = collections.defaultdict(set)
96 def fac(key):
97 return KeyReentrantMutex(key, mutex, keystore)
99 return fac
101 def acquire(self, wait=True):
102 current_thread = compat.threading.current_thread().ident
103 keys = self.keys.get(current_thread)
104 if keys is not None and self.key not in keys:
105 # current lockholder, new key. add it in
106 keys.add(self.key)
107 return True
108 elif self.mutex.acquire(wait=wait):
109 # after acquire, create new set and add our key
110 self.keys[current_thread].add(self.key)
111 return True
112 else:
113 return False
115 def release(self):
116 current_thread = compat.threading.current_thread().ident
117 keys = self.keys.get(current_thread)
118 assert keys is not None, "this thread didn't do the acquire"
119 assert self.key in keys, "No acquire held for key '%s'" % self.key
120 keys.remove(self.key)
121 if not keys:
122 # when list of keys empty, remove
123 # the thread ident and unlock.
124 del self.keys[current_thread]
125 self.mutex.release()