Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/statsmodels/tools/decorators.py : 60%

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
1from statsmodels.tools.sm_exceptions import CacheWriteWarning
2from statsmodels.compat.pandas import cache_readonly as PandasCacheReadonly
4import warnings
6__all__ = ['cache_readonly', 'cache_writable', 'deprecated_alias',
7 'ResettableCache']
10class ResettableCache(dict):
11 """DO NOT USE. BACKWARD COMPAT ONLY"""
12 def __init__(self, *args, **kwargs):
13 super(ResettableCache, self).__init__(*args, **kwargs)
14 self.__dict__ = self
17def deprecated_alias(old_name, new_name, remove_version=None, msg=None,
18 warning=FutureWarning):
19 """
20 Deprecate attribute in favor of alternative name.
22 Parameters
23 ----------
24 old_name : str
25 Old, deprecated name
26 new_name : str
27 New name
28 remove_version : str, optional
29 Version that the alias will be removed
30 msg : str, optional
31 Message to show. Default is
32 `old_name` is a deprecated alias for `new_name`
33 warning : Warning, optional
34 Warning class to give. Default is FutureWarning.
36 Notes
37 -----
38 Older or less-used classes may not conform to statsmodels naming
39 conventions. `deprecated_alias` lets us bring them into conformance
40 without breaking backward-compatibility.
42 Example
43 -------
44 Instances of the `Foo` class have a `nvars` attribute, but it _should_
45 be called `neqs`:
47 class Foo(object):
48 nvars = deprecated_alias('nvars', 'neqs')
49 def __init__(self, neqs):
50 self.neqs = neqs
52 >>> foo = Foo(3)
53 >>> foo.nvars
54 __main__:1: FutureWarning: nvars is a deprecated alias for neqs
55 3
56 """
58 if msg is None:
59 msg = '%s is a deprecated alias for %s' % (old_name, new_name)
60 if remove_version is not None:
61 msg += ', will be removed in version %s' % remove_version
63 def fget(self):
64 warnings.warn(msg, warning, stacklevel=2)
65 return getattr(self, new_name)
67 def fset(self, value):
68 warnings.warn(msg, warning, stacklevel=2)
69 setattr(self, new_name, value)
71 res = property(fget=fget, fset=fset)
72 return res
75class CachedAttribute(object):
77 def __init__(self, func, cachename=None):
78 self.fget = func
79 self.name = func.__name__
80 self.cachename = cachename or '_cache'
82 def __get__(self, obj, type=None):
83 if obj is None:
84 return self.fget
85 # Get the cache or set a default one if needed
86 _cachename = self.cachename
87 _cache = getattr(obj, _cachename, None)
88 if _cache is None:
89 setattr(obj, _cachename, {})
90 _cache = getattr(obj, _cachename)
91 # Get the name of the attribute to set and cache
92 name = self.name
93 _cachedval = _cache.get(name, None)
94 if _cachedval is None:
95 _cachedval = self.fget(obj)
96 _cache[name] = _cachedval
98 return _cachedval
100 def __set__(self, obj, value):
101 errmsg = "The attribute '%s' cannot be overwritten" % self.name
102 warnings.warn(errmsg, CacheWriteWarning)
105class CachedWritableAttribute(CachedAttribute):
106 def __set__(self, obj, value):
107 _cache = getattr(obj, self.cachename)
108 name = self.name
109 _cache[name] = value
112class _cache_readonly(property):
113 """
114 Decorator for CachedAttribute
115 """
117 def __init__(self, cachename=None):
118 self.func = None
119 self.cachename = cachename
121 def __call__(self, func):
122 return CachedAttribute(func,
123 cachename=self.cachename)
126class cache_writable(_cache_readonly):
127 """
128 Decorator for CachedWritableAttribute
129 """
130 def __call__(self, func):
131 return CachedWritableAttribute(func,
132 cachename=self.cachename)
135# Use pandas since it works with docs correctly
136cache_readonly = PandasCacheReadonly
137# cached_value and cached_data behave identically to cache_readonly, but
138# are used by `remove_data` to
139# a) identify array-like attributes to remove (cached_data)
140# b) make sure certain values are evaluated before caching (cached_value)
141# TODO: Disabled since the subclasses break doc strings
142# class cached_data(PandasCacheReadonly):
143# pass
145cached_data = PandasCacheReadonly
147# class cached_value(PandasCacheReadonly):
148# pass
150cached_value = PandasCacheReadonly
153def nottest(fn):
154 fn.__test__ = False
155 return fn