Skip to content

Commit de33d49

Browse files
author
twhalen
committed
ExpliticKeyTrans
1 parent c0fe963 commit de33d49

File tree

2 files changed

+143
-3
lines changed

2 files changed

+143
-3
lines changed
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
##############################################################################
2+
# Copyright (c) 2003 Zope Foundation and Contributors.
3+
# All Rights Reserved.
4+
#
5+
# This software is subject to the provisions of the Zope Public License,
6+
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
7+
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
8+
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9+
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
10+
# FOR A PARTICULAR PURPOSE.
11+
##############################################################################
12+
"""Cached properties
13+
See the CachedProperty class.
14+
15+
This module was taken from https://github.com/zopefoundation/zope.cachedescriptors.
16+
"""
17+
18+
from functools import update_wrapper
19+
20+
ncaches = 0
21+
22+
23+
class _CachedProperty(object):
24+
"""
25+
Cached property implementation class.
26+
"""
27+
28+
def __init__(self, func, *names):
29+
global ncaches
30+
ncaches += 1
31+
self.data = (func, names,
32+
"_v_cached_property_key_%s" % ncaches,
33+
"_v_cached_property_value_%s" % ncaches)
34+
update_wrapper(self, func)
35+
36+
def __get__(self, inst, class_):
37+
if inst is None:
38+
return self
39+
40+
func, names, key_name, value_name = self.data
41+
42+
key = names and [getattr(inst, name) for name in names]
43+
value = getattr(inst, value_name, self)
44+
45+
if value is not self:
46+
# We have a cached value
47+
if key == getattr(inst, key_name, self):
48+
# Cache is still good!
49+
return value
50+
51+
# We need to compute and cache the value
52+
53+
value = func(inst)
54+
setattr(inst, key_name, key)
55+
setattr(inst, value_name, value)
56+
57+
return value
58+
59+
60+
def CachedProperty(*args):
61+
"""
62+
CachedProperties.
63+
This is usable directly as a decorator when given names, or when not. Any of these patterns
64+
will work:
65+
* ``@CachedProperty``
66+
* ``@CachedProperty()``
67+
* ``@CachedProperty('n','n2')``
68+
* def thing(self: ...; thing = CachedProperty(thing)
69+
* def thing(self: ...; thing = CachedProperty(thing, 'n')
70+
"""
71+
72+
if not args: # @CachedProperty()
73+
return _CachedProperty # A callable that produces the decorated function
74+
75+
arg1 = args[0]
76+
names = args[1:]
77+
if callable(arg1): # @CachedProperty, *or* thing = CachedProperty(thing, ...)
78+
return _CachedProperty(arg1, *names)
79+
80+
# @CachedProperty( 'n' )
81+
# Ok, must be a list of string names. Which means we are used like a factory
82+
# so we return a callable object to produce the actual decorated function
83+
def factory(function):
84+
return _CachedProperty(function, arg1, *names)
85+
86+
return factory
87+
88+
89+
class Lazy(object):
90+
"""Lazy Attributes.
91+
"""
92+
93+
def __init__(self, func, name=None):
94+
if name is None:
95+
name = func.__name__
96+
self.data = (func, name)
97+
update_wrapper(self, func)
98+
99+
def __get__(self, inst, class_):
100+
if inst is None:
101+
return self
102+
103+
func, name = self.data
104+
value = func(inst)
105+
inst.__dict__[name] = value
106+
return value
107+
108+
109+
class readproperty(object):
110+
111+
def __init__(self, func):
112+
self.func = func
113+
update_wrapper(self, func)
114+
115+
def __get__(self, inst, class_):
116+
if inst is None:
117+
return self
118+
119+
func = self.func
120+
return func(inst)
121+
122+
123+
class cachedIn(object):
124+
"""Cached property with given cache attribute."""
125+
126+
def __init__(self, attribute_name):
127+
self.attribute_name = attribute_name
128+
129+
def __call__(self, func):
130+
131+
def get(instance):
132+
try:
133+
value = getattr(instance, self.attribute_name)
134+
except AttributeError:
135+
value = func(instance)
136+
setattr(instance, self.attribute_name, value)
137+
return value
138+
139+
update_wrapper(get, func)
140+
141+
return property(get)

setup.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ def readme():
88

99
setup(
1010
name='py2store',
11-
version='0.0.5',
11+
version='0.0.6',
1212
description='DAO for Python: Tools to create simple and consistent interfaces to complicated and varied data sources.',
1313
long_description=readme(),
1414
long_description_content_type="text/markdown",
@@ -19,7 +19,7 @@ def readme():
1919
install_requires=[],
2020
include_package_data=True,
2121
zip_safe=False,
22-
download_url='https://github.com/i2mint/py2store/archive/v0.0.5.zip',
22+
download_url='https://github.com/i2mint/py2store/archive/v0.0.6.zip',
2323
keywords=['storage', 'interface'],
2424
classifiers=[
2525
'Development Status :: 3 - Alpha',
@@ -31,7 +31,6 @@ def readme():
3131
'Intended Audience :: Developers',
3232
'Topic :: Software Development',
3333
'License :: OSI Approved :: Apache Software License',
34-
'Programming Language :: Python :: 3.6',
3534
'Programming Language :: Python :: 3.7',
3635
],
3736
)

0 commit comments

Comments
 (0)