key is now always path and change opt by path dictionary storage

This commit is contained in:
2013-08-21 22:21:50 +02:00
parent 707a215a2c
commit b6bb685ca5
12 changed files with 297 additions and 242 deletions

View File

@ -152,24 +152,25 @@ populate_multitypes()
class Property(object):
"a property is responsible of the option's value access rules"
__slots__ = ('_setting', '_properties', '_opt')
__slots__ = ('_setting', '_properties', '_opt', '_path')
def __init__(self, setting, prop, opt=None):
def __init__(self, setting, prop, opt=None, path=None):
self._opt = opt
self._path = path
self._setting = setting
self._properties = prop
def append(self, propname):
self._properties.add(propname)
self._setting._setproperties(self._properties, self._opt)
self._setting._setproperties(self._properties, self._opt, self._path)
def remove(self, propname):
if propname in self._properties:
self._properties.remove(propname)
self._setting._setproperties(self._properties, self._opt)
self._setting._setproperties(self._properties, self._opt, self._path)
def reset(self):
self._setting.reset(opt=self._opt)
self._setting.reset(path=self._path)
def __contains__(self, propname):
return propname in self._properties
@ -200,15 +201,6 @@ class Settings(object):
self._p_ = __import__(import_lib, globals(), locals(), ['Settings'],
-1).Settings(storage)
def _getkey(self, opt):
if self._p_.key_is_path:
if opt is None:
return '_none'
else:
return self._get_opt_path(opt)
else:
return opt
#____________________________________________________________
# properties methods
def __contains__(self, propname):
@ -219,7 +211,14 @@ class Settings(object):
return str(list(self._getproperties()))
def __getitem__(self, opt):
return Property(self, self._getproperties(opt), opt)
if opt is None:
path = None
else:
path = self._get_opt_path(opt)
return self._getitem(opt, path)
def _getitem(self, opt, path):
return Property(self, self._getproperties(opt, path), opt, path)
def __setitem__(self, opt, value):
raise ValueError('you must only append/remove properties')
@ -231,26 +230,32 @@ class Settings(object):
if all_properties:
self._p_.reset_all_propertives()
else:
self._p_.reset_properties(self._getkey(opt))
if opt is None:
path = None
else:
path = self._get_opt_path(opt)
self._p_.reset_properties(path)
self.context.cfgimpl_reset_cache()
def _getproperties(self, opt=None, is_apply_req=True):
def _getproperties(self, opt=None, path=None, is_apply_req=True):
if opt is None:
props = self._p_.getproperties(self._getkey(opt), default_properties)
props = self._p_.getproperties(path, default_properties)
else:
if path is None:
raise ValueError(_('if opt is not None, path should not be None in _getproperties'))
ntime = None
if self._p_.hascache('property', self._getkey(opt)):
if self._p_.hascache('property', path):
ntime = time()
is_cached, props = self._p_.getcache('property', self._getkey(opt), ntime)
is_cached, props = self._p_.getcache('property', path, ntime)
if is_cached:
return props
if is_apply_req:
self.apply_requires(opt)
props = self._p_.getproperties(self._getkey(opt), opt._properties)
self.apply_requires(opt, path)
props = self._p_.getproperties(path, opt._properties)
if 'expire' in self:
if ntime is None:
ntime = time()
self._p_.setcache('property', self._getkey(opt), props, ntime + expires_time)
self._p_.setcache('property', path, props, ntime + expires_time)
return props
def append(self, propname):
@ -261,21 +266,21 @@ class Settings(object):
"deletes property propname in the Config's properties attribute"
Property(self, self._getproperties()).remove(propname)
def _setproperties(self, properties, opt=None):
def _setproperties(self, properties, opt, path):
"""save properties for specified opt
(never save properties if same has option properties)
"""
if opt is None:
self._p_.setproperties(self._getkey(opt), properties)
self._p_.setproperties(path, properties)
else:
if set(opt._properties) == properties:
self._p_.reset_properties(self._getkey(opt))
self._p_.reset_properties(path)
else:
self._p_.setproperties(self._getkey(opt), properties)
self._p_.setproperties(path, properties)
self.context.cfgimpl_reset_cache()
#____________________________________________________________
def validate_properties(self, opt_or_descr, is_descr, is_write,
def validate_properties(self, opt_or_descr, is_descr, is_write, path,
value=None, force_permissive=False,
force_properties=None):
"""
@ -291,9 +296,9 @@ class Settings(object):
property)
"""
# opt properties
properties = copy(self._getproperties(opt_or_descr))
properties = copy(self._getproperties(opt_or_descr, path))
# remove opt permissive
properties -= self._p_.getpermissive(self._getkey(opt_or_descr))
properties -= self._p_.getpermissive(path)
# remove global permissive if need
self_properties = copy(self._getproperties())
if force_permissive is True or 'permissive' in self_properties:
@ -332,11 +337,10 @@ class Settings(object):
"").format(opt_or_descr._name,
str(props)), props)
# XXX should rename it to setpermissive, but kept for retro compatibility
def set_permissive(self, permissive, opt=None):
def setpermissive(self, permissive, path=None):
if not isinstance(permissive, tuple):
raise TypeError(_('permissive must be a tuple'))
self._p_.setpermissive(self._getkey(opt), permissive)
self._p_.setpermissive(path, permissive)
#____________________________________________________________
def setowner(self, owner):
@ -369,28 +373,27 @@ class Settings(object):
else:
self._p_.reset_all_cache('property')
def apply_requires(self, opt):
def apply_requires(self, opt, path):
"carries out the jit (just in time requirements between options"
if opt._requires is None:
return
# filters the callbacks
setting = Property(self, self._getproperties(opt, False), opt)
setting = Property(self, self._getproperties(opt, path, False), opt, path=path)
descr = self.context.cfgimpl_get_description()
optpath = descr.impl_get_path_by_opt(opt)
for requires in opt._requires:
matches = False
for require in requires:
option, expected, action, inverse, \
transitive, same_action = require
path = descr.impl_get_path_by_opt(option)
if path == optpath or path.startswith(optpath + '.'):
reqpath = self._get_opt_path(option)
if reqpath == path or reqpath.startswith(path + '.'):
raise RequirementError(_("malformed requirements "
"imbrication detected for option:"
" '{0}' with requirement on: "
"'{1}'").format(optpath, path))
"'{1}'").format(path, reqpath))
try:
value = self.context._getattr(path, force_permissive=True)
value = self.context._getattr(reqpath, force_permissive=True)
except PropertiesOptionError, err:
if not transitive:
continue
@ -400,14 +403,14 @@ class Settings(object):
"requirement's property "
"error: "
"{1} {2}").format(opt._name,
path,
reqpath,
properties))
# transitive action, force expected
value = expected[0]
inverse = False
except AttributeError:
raise AttributeError(_("required option not found: "
"{0}").format(path))
"{0}").format(reqpath))
if (not inverse and
value in expected or
inverse and value not in expected):