2010-11-08 04:40:41 -06:00
|
|
|
'''Appy allows you to create easily complete applications in Python.'''
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
2009-10-18 07:52:27 -05:00
|
|
|
import os.path
|
2009-06-29 07:06:01 -05:00
|
|
|
|
2010-11-08 04:40:41 -06:00
|
|
|
# ------------------------------------------------------------------------------
|
2009-10-18 07:52:27 -05:00
|
|
|
def getPath(): return os.path.dirname(__file__)
|
2010-02-01 04:09:26 -06:00
|
|
|
def versionIsGreaterThanOrEquals(version):
|
|
|
|
'''This method returns True if the current Appy version is greater than or
|
|
|
|
equals p_version. p_version must have a format like "0.5.0".'''
|
|
|
|
import appy.version
|
|
|
|
if appy.version.short == 'dev':
|
|
|
|
# We suppose that a developer knows what he is doing, so we return True.
|
|
|
|
return True
|
|
|
|
else:
|
|
|
|
paramVersion = [int(i) for i in version.split('.')]
|
2010-02-04 07:41:51 -06:00
|
|
|
currentVersion = [int(i) for i in appy.version.short.split('.')]
|
2010-02-01 04:09:26 -06:00
|
|
|
return currentVersion >= paramVersion
|
2010-11-08 04:40:41 -06:00
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
class Object:
|
|
|
|
'''At every place we need an object, but without any requirement on its
|
|
|
|
class (methods, attributes,...) we will use this minimalist class.'''
|
|
|
|
def __init__(self, **fields):
|
|
|
|
for k, v in fields.iteritems():
|
|
|
|
setattr(self, k, v)
|
|
|
|
def __repr__(self):
|
|
|
|
res = u'<Object '
|
|
|
|
for attrName, attrValue in self.__dict__.iteritems():
|
|
|
|
v = attrValue
|
|
|
|
if hasattr(v, '__repr__'):
|
|
|
|
v = v.__repr__()
|
|
|
|
try:
|
|
|
|
res += u'%s=%s ' % (attrName, v)
|
|
|
|
except UnicodeDecodeError:
|
|
|
|
res += u'%s=<encoding problem> ' % attrName
|
|
|
|
res = res.strip() + '>'
|
|
|
|
return res.encode('utf-8')
|
2012-03-08 13:56:14 -06:00
|
|
|
def __nonzero__(self):
|
|
|
|
return bool(self.__dict__)
|
2013-05-10 05:16:57 -05:00
|
|
|
def get(self, name, default=None): return getattr(self, name, default)
|
2013-08-21 05:35:30 -05:00
|
|
|
def update(self, other):
|
|
|
|
'''Includes information from p_other into p_self.'''
|
|
|
|
for k, v in other.__dict__.iteritems():
|
|
|
|
setattr(self, k, v)
|
2014-03-25 16:59:06 -05:00
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
class Hack:
|
|
|
|
'''This class proposes methods for patching some existing code with
|
|
|
|
alternative methods.'''
|
|
|
|
@staticmethod
|
2014-05-03 08:18:41 -05:00
|
|
|
def patch(method, replacement, klass=None):
|
2014-03-25 16:59:06 -05:00
|
|
|
'''This method replaces m_method with a p_replacement method, but
|
|
|
|
keeps p_method on its class under name
|
|
|
|
"_base_<initial_method_name>_". In the patched method, one may use
|
2014-05-03 08:18:41 -05:00
|
|
|
Hack.base to call the base method. If p_method is static, you must
|
|
|
|
specify its class in p_klass.'''
|
2014-03-25 16:59:06 -05:00
|
|
|
# Get the class on which the surgery will take place.
|
2014-05-03 08:18:41 -05:00
|
|
|
isStatic = klass
|
|
|
|
klass = klass or method.im_class
|
2014-03-25 16:59:06 -05:00
|
|
|
# On this class, store m_method under its "base" name.
|
2014-05-03 08:18:41 -05:00
|
|
|
name = isStatic and method.func_name or method.im_func.__name__
|
2014-03-25 16:59:06 -05:00
|
|
|
baseName = '_base_%s_' % name
|
|
|
|
setattr(klass, baseName, method)
|
2014-05-03 08:18:41 -05:00
|
|
|
# Store the replacement method on klass. When doing so, even when
|
|
|
|
# m_method is static, it is wrapped in a method. This is why, in
|
|
|
|
# m_base below, when the method is static, we return method.im_func to
|
|
|
|
# retrieve the original static method.
|
2014-03-25 16:59:06 -05:00
|
|
|
setattr(klass, name, replacement)
|
|
|
|
|
|
|
|
@staticmethod
|
2014-05-03 08:18:41 -05:00
|
|
|
def base(method, klass=None):
|
|
|
|
'''Allows to call the base (replaced) method. If p_method is static,
|
|
|
|
you must specify its p_klass.'''
|
|
|
|
isStatic = klass
|
|
|
|
klass = klass or method.im_class
|
|
|
|
name = isStatic and method.func_name or method.im_func.__name__
|
|
|
|
res = getattr(klass, '_base_%s_' % name)
|
|
|
|
if isStatic: res = res.im_func
|
|
|
|
return res
|
2010-11-08 04:40:41 -06:00
|
|
|
# ------------------------------------------------------------------------------
|