cs-py-func 20150115__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Metadata-Version: 1.1
|
|
2
|
+
Name: cs.py.func
|
|
3
|
+
Version: 20150115
|
|
4
|
+
Summary: convenience facilities related to Python functions
|
|
5
|
+
Home-page: https://bitbucket.org/cameron_simpson/css/commits/all
|
|
6
|
+
Author: Cameron Simpson
|
|
7
|
+
Author-email: cs@zip.com.au
|
|
8
|
+
License: UNKNOWN
|
|
9
|
+
Description: Convenience facilities related to Python functions.
|
|
10
|
+
===================================================
|
|
11
|
+
|
|
12
|
+
funcname(func)
|
|
13
|
+
--------------
|
|
14
|
+
|
|
15
|
+
Returns a string to name `func`. I use this instead of func.__name__ because several things do not have a .__name__. It tries to use .__name__, but falls back to ..__str__().
|
|
16
|
+
|
|
17
|
+
@derived_property
|
|
18
|
+
-----------------
|
|
19
|
+
|
|
20
|
+
Decorator for property functions which must be recomputed if another property is updated.
|
|
21
|
+
|
|
22
|
+
@derived_from(property_name)
|
|
23
|
+
----------------------------
|
|
24
|
+
|
|
25
|
+
Convenience wrapper of derived_property which names the parent property.
|
|
26
|
+
|
|
27
|
+
@returns_type(func, basetype)
|
|
28
|
+
-----------------------------
|
|
29
|
+
|
|
30
|
+
Basis for decorators to do type checking of function return values. Example::
|
|
31
|
+
|
|
32
|
+
def returns_bool(func):
|
|
33
|
+
''' Decorator for functions which should return Booleans.
|
|
34
|
+
'''
|
|
35
|
+
return returns_type(func, bool)
|
|
36
|
+
|
|
37
|
+
@returns_bool
|
|
38
|
+
def f(x):
|
|
39
|
+
return x == 1
|
|
40
|
+
|
|
41
|
+
This has been used for debugging functions called far from their definitions.
|
|
42
|
+
|
|
43
|
+
Keywords: python2,python3
|
|
44
|
+
Platform: UNKNOWN
|
|
45
|
+
Classifier: Programming Language :: Python
|
|
46
|
+
Classifier: Programming Language :: Python :: 2
|
|
47
|
+
Classifier: Programming Language :: Python :: 3
|
|
48
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
49
|
+
Classifier: Operating System :: OS Independent
|
|
50
|
+
Classifier: Development Status :: 4 - Beta
|
|
51
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
52
|
+
Classifier: Intended Audience :: Developers
|
|
53
|
+
Requires: cs.excutils
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Convenience facilities related to Python functions.
|
|
2
|
+
===================================================
|
|
3
|
+
|
|
4
|
+
funcname(func)
|
|
5
|
+
--------------
|
|
6
|
+
|
|
7
|
+
Returns a string to name `func`. I use this instead of func.__name__ because several things do not have a .__name__. It tries to use .__name__, but falls back to ..__str__().
|
|
8
|
+
|
|
9
|
+
@derived_property
|
|
10
|
+
-----------------
|
|
11
|
+
|
|
12
|
+
Decorator for property functions which must be recomputed if another property is updated.
|
|
13
|
+
|
|
14
|
+
@derived_from(property_name)
|
|
15
|
+
----------------------------
|
|
16
|
+
|
|
17
|
+
Convenience wrapper of derived_property which names the parent property.
|
|
18
|
+
|
|
19
|
+
@returns_type(func, basetype)
|
|
20
|
+
-----------------------------
|
|
21
|
+
|
|
22
|
+
Basis for decorators to do type checking of function return values. Example::
|
|
23
|
+
|
|
24
|
+
def returns_bool(func):
|
|
25
|
+
''' Decorator for functions which should return Booleans.
|
|
26
|
+
'''
|
|
27
|
+
return returns_type(func, bool)
|
|
28
|
+
|
|
29
|
+
@returns_bool
|
|
30
|
+
def f(x):
|
|
31
|
+
return x == 1
|
|
32
|
+
|
|
33
|
+
This has been used for debugging functions called far from their definitions.
|
|
File without changes
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#!/usr/bin/python
|
|
2
|
+
#
|
|
3
|
+
# Convenience routines for python functions.
|
|
4
|
+
# - Cameron Simpson <cs@zip.com.au> 15apr2014
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
DISTINFO = {
|
|
8
|
+
'description': "convenience facilities related to Python functions",
|
|
9
|
+
'keywords': ["python2", "python3"],
|
|
10
|
+
'classifiers': [
|
|
11
|
+
"Programming Language :: Python",
|
|
12
|
+
"Programming Language :: Python :: 2",
|
|
13
|
+
"Programming Language :: Python :: 3",
|
|
14
|
+
],
|
|
15
|
+
'requires': ['cs.excutils'],
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
from cs.excutils import transmute
|
|
19
|
+
|
|
20
|
+
def funcname(func):
|
|
21
|
+
''' Return a name for the supplied function `func`.
|
|
22
|
+
Several objects do not have a __name__ attribute, such as partials.
|
|
23
|
+
'''
|
|
24
|
+
try:
|
|
25
|
+
return func.__name__
|
|
26
|
+
except AttributeError:
|
|
27
|
+
return str(func)
|
|
28
|
+
|
|
29
|
+
def funccite(func):
|
|
30
|
+
code = func.__code__
|
|
31
|
+
return "%s[%s:%d]" % (funcname(func), code.co_filename, code.co_firstlineno)
|
|
32
|
+
|
|
33
|
+
def callmethod_if(o, method, default=None, a=None, kw=None):
|
|
34
|
+
''' Call the named `method` on the object `o` if it exists.
|
|
35
|
+
If it does not exist, return `default` (which defaults to None).
|
|
36
|
+
Otherwise call getattr(o, method)(*a, **kw).
|
|
37
|
+
`a` defaults to ().
|
|
38
|
+
`kw` defaults to {}.
|
|
39
|
+
'''
|
|
40
|
+
try:
|
|
41
|
+
m = getattr(o, method)
|
|
42
|
+
except AttributeError:
|
|
43
|
+
return default
|
|
44
|
+
if a is None:
|
|
45
|
+
a = ()
|
|
46
|
+
if kw is None:
|
|
47
|
+
kw = {}
|
|
48
|
+
return m(*a, **kw)
|
|
49
|
+
|
|
50
|
+
def derived_property(func, original_revision_name='_revision', lock_name='_lock', property_name=None, unset_object=None):
|
|
51
|
+
''' A property which must be recomputed if the reference revision exceeds the snapshot revision.
|
|
52
|
+
'''
|
|
53
|
+
if property_name is None:
|
|
54
|
+
property_name = '_' + func.__name__
|
|
55
|
+
# the property used to track the reference revision
|
|
56
|
+
property_revision_name = property_name + '__revision'
|
|
57
|
+
|
|
58
|
+
from cs.logutils import X
|
|
59
|
+
|
|
60
|
+
@transmute(AttributeError)
|
|
61
|
+
def property_value(self):
|
|
62
|
+
''' Attempt lockless fetch of property first.
|
|
63
|
+
Use lock if property is unset and up to date.
|
|
64
|
+
'''
|
|
65
|
+
# poll outside lock
|
|
66
|
+
p = getattr(self, property_name, unset_object)
|
|
67
|
+
p_revision = getattr(self, property_revision_name, 0)
|
|
68
|
+
o_revision = getattr(self, original_revision_name)
|
|
69
|
+
if p is unset_object or p_revision < o_revision:
|
|
70
|
+
with getattr(self, lock_name):
|
|
71
|
+
# repoll value inside lock
|
|
72
|
+
p = getattr(self, property_name, unset_object)
|
|
73
|
+
p_revision = getattr(self, property_revision_name, 0)
|
|
74
|
+
o_revision = getattr(self, original_revision_name)
|
|
75
|
+
if p is unset_object or p_revision < o_revision:
|
|
76
|
+
X("COMPUTE .%s... [p_revision=%s, o_revision=%s]", property_name, p_revision, o_revision)
|
|
77
|
+
p = func(self)
|
|
78
|
+
setattr(self, property_name, p)
|
|
79
|
+
##X("COMPUTE .%s: set .%s to %s", self, property_revision_name, o_revision)
|
|
80
|
+
setattr(self, property_revision_name, o_revision)
|
|
81
|
+
else:
|
|
82
|
+
##debug("inside lock, already computed up to date %s", property_name)
|
|
83
|
+
pass
|
|
84
|
+
else:
|
|
85
|
+
##debug("outside lock, already computed up to date %s", property_name)
|
|
86
|
+
pass
|
|
87
|
+
return p
|
|
88
|
+
return property(property_value)
|
|
89
|
+
|
|
90
|
+
def derived_from(property_name):
|
|
91
|
+
''' A property which must be recomputed if the revision of another property exceeds the snapshot revision.
|
|
92
|
+
'''
|
|
93
|
+
return partial(derived_property, original_revision_name='_' + property_name + '__revision')
|
|
94
|
+
|
|
95
|
+
def yields_type(func, basetype):
|
|
96
|
+
''' Decrator which checks that a generator yields values of type `basetype`.
|
|
97
|
+
'''
|
|
98
|
+
funcname = funccite(func)
|
|
99
|
+
def check_yields_type(*a, **kw):
|
|
100
|
+
for item in func(*a, **kw):
|
|
101
|
+
if not isinstance(item, basetype):
|
|
102
|
+
raise TypeError(
|
|
103
|
+
"wrong type yielded from func %s: expected subclass of %s, got %s: %r"
|
|
104
|
+
% (funcname, basetype, type(item), item)
|
|
105
|
+
)
|
|
106
|
+
yield item
|
|
107
|
+
check_yields_type.__name__ = ( 'check_yields_type[%s,basetype=%s]'
|
|
108
|
+
% (funcname, basetype)
|
|
109
|
+
)
|
|
110
|
+
return check_yields_type
|
|
111
|
+
|
|
112
|
+
def returns_type(func, basetype):
|
|
113
|
+
''' Decrator which checks that a function returns values of type `basetype`.
|
|
114
|
+
'''
|
|
115
|
+
funcname = funccite(func)
|
|
116
|
+
def check_returns_type(*a, **kw):
|
|
117
|
+
retval = func(*a, **kw)
|
|
118
|
+
if not isinstance(retval, basetype):
|
|
119
|
+
raise TypeError(
|
|
120
|
+
"wrong type returned from func %s: expected subclass of %s, got %s: %r"
|
|
121
|
+
% (funcname, basetype, type(retval), retval)
|
|
122
|
+
)
|
|
123
|
+
return retval
|
|
124
|
+
check_returns_type.__name__ = ( 'check_returns_type[%s,basetype=%s]'
|
|
125
|
+
% (funcname, basetype)
|
|
126
|
+
)
|
|
127
|
+
return check_returns_type
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/python
|
|
2
|
+
from distutils.core import setup
|
|
3
|
+
setup(
|
|
4
|
+
name = 'cs.py.func',
|
|
5
|
+
description = 'convenience facilities related to Python functions',
|
|
6
|
+
author = 'Cameron Simpson',
|
|
7
|
+
author_email = 'cs@zip.com.au',
|
|
8
|
+
version = '20150115',
|
|
9
|
+
url = 'https://bitbucket.org/cameron_simpson/css/commits/all',
|
|
10
|
+
classifiers = ['Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 3', 'Topic :: Software Development :: Libraries :: Python Modules', 'Operating System :: OS Independent', 'Development Status :: 4 - Beta', 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', 'Intended Audience :: Developers'],
|
|
11
|
+
keywords = ['python2', 'python3'],
|
|
12
|
+
long_description = u"Convenience facilities related to Python functions.\n===================================================\n\nfuncname(func)\n--------------\n\nReturns a string to name `func`. I use this instead of func.__name__ because several things do not have a .__name__. It tries to use .__name__, but falls back to ..__str__().\n\n@derived_property\n-----------------\n\nDecorator for property functions which must be recomputed if another property is updated.\n\n@derived_from(property_name)\n----------------------------\n\nConvenience wrapper of derived_property which names the parent property.\n\n@returns_type(func, basetype)\n-----------------------------\n\nBasis for decorators to do type checking of function return values. Example::\n\n def returns_bool(func):\n ''' Decorator for functions which should return Booleans.\n '''\n return returns_type(func, bool)\n\n @returns_bool\n def f(x):\n return x == 1\n\nThis has been used for debugging functions called far from their definitions.\n",
|
|
13
|
+
package_dir = {'': 'lib/python'},
|
|
14
|
+
py_modules = ['cs.py.func'],
|
|
15
|
+
requires = ['cs.excutils'],
|
|
16
|
+
)
|