pep 8 lines too long

This commit is contained in:
gwen 2013-08-20 12:08:02 +02:00
parent 513722ed57
commit 564fecc261
5 changed files with 214 additions and 105 deletions

View File

@ -151,7 +151,8 @@ class SubConfig(BaseInformation):
def cfgimpl_get_description(self):
if self._impl_descr is None:
raise ConfigError(_('no optiondescription for this config (may be metaconfig without meta)'))
raise ConfigError(_('no option description found for this config'
' (may be metaconfig without meta)'))
else:
return self._impl_descr
@ -181,7 +182,9 @@ class SubConfig(BaseInformation):
force_permissive=force_permissive)
else:
context = self.cfgimpl_get_context()
path = context.cfgimpl_get_description().impl_get_path_by_opt(child._opt)
path = context.\
cfgimpl_get_description().\
impl_get_path_by_opt(child._opt)
context._setattr(path, value, force_permissive=force_permissive)
def __delattr__(self, name):
@ -217,7 +220,8 @@ class SubConfig(BaseInformation):
# symlink options
if isinstance(opt_or_descr, SymLinkOption):
context = self.cfgimpl_get_context()
path = context.cfgimpl_get_description().impl_get_path_by_opt(opt_or_descr._opt)
path = context.cfgimpl_get_description(
).impl_get_path_by_opt(opt_or_descr._opt)
return context._getattr(path, validate=validate,
force_properties=force_properties,
force_permissive=force_permissive)
@ -245,7 +249,8 @@ class SubConfig(BaseInformation):
return self.cfgimpl_get_context()._find(bytype, byname, byvalue,
first=False,
type_=type_,
_subpath=self.cfgimpl_get_path())
_subpath=self.cfgimpl_get_path()
)
def find_first(self, bytype=None, byname=None, byvalue=None,
type_='option', display_error=True):
@ -273,7 +278,8 @@ class SubConfig(BaseInformation):
"""
def _filter_by_name():
try:
if byname is None or path == byname or path.endswith('.' + byname):
if byname is None or path == byname or \
path.endswith('.' + byname):
return True
except IndexError:
pass
@ -286,7 +292,8 @@ class SubConfig(BaseInformation):
value = getattr(self, path)
if value == byvalue:
return True
except PropertiesOptionError: # a property restricts the access of the value
except PropertiesOptionError: # a property is a restriction
# upon the access of the value
pass
return False
@ -309,7 +316,8 @@ class SubConfig(BaseInformation):
# return False
# return False
if type_ not in ('option', 'path', 'context', 'value'):
raise ValueError(_('unknown type_ type {0} for _find').format(type_))
raise ValueError(_('unknown type_ type {0}'
'for _find').format(type_))
find_results = []
opts, paths = self.cfgimpl_get_description()._cache_paths
for index in range(0, len(paths)):
@ -348,7 +356,8 @@ class SubConfig(BaseInformation):
find_results.append(retval)
if find_results == []:
if display_error:
raise AttributeError(_("no option found in config with these criteria"))
raise AttributeError(_("no option found in config"
" with these criteria"))
else:
#translation is slow
raise AttributeError()
@ -374,15 +383,21 @@ class SubConfig(BaseInformation):
`OptionDescription` than the `withoption` itself::
>>> print cfg.make_dict(withoption='var1')
{'od2.var4': None, 'od2.var5': None, 'od2.var6': None,
'od2.var1': u'value', 'od1.var1': None,
'od1.var3': None, 'od1.var2': None}
{'od2.var4': None, 'od2.var5': None,
'od2.var6': None,
'od2.var1': u'value',
'od1.var1': None,
'od1.var3': None,
'od1.var2': None}
:param withvalue: returns the options that have the value `withvalue`
::
>>> print c.make_dict(withoption='var1', withvalue=u'value')
{'od2.var4': None, 'od2.var5': None, 'od2.var6': None,
>>> print c.make_dict(withoption='var1',
withvalue=u'value')
{'od2.var4': None,
'od2.var5': None,
'od2.var6': None,
'od2.var1': u'value'}
:returns: dict of Option's name (or path) and values
@ -402,7 +417,9 @@ class SubConfig(BaseInformation):
type_='path',
_subpath=mypath):
path = '.'.join(path.split('.')[:-1])
opt = self.cfgimpl_get_context().cfgimpl_get_description().impl_get_opt_by_path(path)
opt = self.cfgimpl_get_context(
).cfgimpl_get_description(
).impl_get_opt_by_path(path)
if mypath is not None:
if mypath == path:
withoption = None
@ -430,7 +447,8 @@ class SubConfig(BaseInformation):
if isinstance(opt, OptionDescription):
try:
pathsvalues += getattr(self, path).make_dict(flatten,
_currpath + path.split('.'))
_currpath +
path.split('.'))
except PropertiesOptionError:
pass # this just a hidden or disabled option
else:
@ -480,7 +498,8 @@ class CommonConfig(SubConfig):
:returns: Option()
"""
if '.' in path:
homeconfig, path = self.cfgimpl_get_home_by_path(path,
homeconfig, path = self.cfgimpl_get_home_by_path(
path,
force_permissive=force_permissive)
return getattr(homeconfig.cfgimpl_get_description(), path)
return getattr(self.cfgimpl_get_description(), path)
@ -512,7 +531,9 @@ class Config(CommonConfig):
self._impl_meta = None
self._impl_informations = {}
def cfgimpl_reset_cache(self, only_expired=False, only=('values', 'settings')):
def cfgimpl_reset_cache(self,
only_expired=False,
only=('values', 'settings')):
if 'values' in only:
self.cfgimpl_get_values().reset_cache(only_expired=only_expired)
if 'settings' in only:
@ -529,13 +550,14 @@ class MetaConfig(CommonConfig):
if meta:
for child in children:
if not isinstance(child, CommonConfig):
raise ValueError(_("metaconfig's children must be config, not {0}"
"").format(type(child)))
raise ValueError(_("metaconfig's children "
"must be config, not {0}"
).format(type(child)))
if self._impl_descr is None:
self._impl_descr = child.cfgimpl_get_description()
elif not self._impl_descr is child.cfgimpl_get_description():
raise ValueError(_('all config in metaconfig must have same '
'optiondescription'))
raise ValueError(_('all config in metaconfig must '
'have the same optiondescription'))
if child.cfgimpl_get_meta() is not None:
raise ValueError(_("child has already a metaconfig's"))
child._impl_meta = self
@ -553,7 +575,9 @@ class MetaConfig(CommonConfig):
"a meta config is a config wich has a setting, that is itself"
return self
def cfgimpl_reset_cache(self, only_expired=False, only=('values', 'settings')):
def cfgimpl_reset_cache(self,
only_expired=False,
only=('values', 'settings')):
if 'values' in only:
self.cfgimpl_get_values().reset_cache(only_expired=only_expired)
if 'settings' in only:
@ -618,7 +642,8 @@ def mandatory_warnings(config):
"""
#if value in cache, properties are not calculated
config.cfgimpl_reset_cache(only=('values',))
for path in config.cfgimpl_get_description().impl_getpaths(include_groups=True):
for path in config.cfgimpl_get_description(
).impl_getpaths(include_groups=True):
try:
config._getattr(path, force_properties=frozenset(('mandatory',)))
except PropertiesOptionError, err:

View File

@ -20,6 +20,8 @@
# the whole pypy projet is under MIT licence
# ____________________________________________________________
"user defined exceptions"
# Exceptions for an Option
class PropertiesOptionError(AttributeError):
"attempt to access to an option with a property that is not allowed"

View File

@ -68,7 +68,8 @@ class BaseInformation(object):
self._impl_informations[key] = value
except AttributeError:
raise AttributeError(_('{0} has no attribute '
'impl_set_information').format(self.__class__.__name__))
'impl_set_information').format(
self.__class__.__name__))
def impl_get_information(self, key, default=None):
"""retrieves one information's item
@ -81,10 +82,12 @@ class BaseInformation(object):
elif default is not None:
return default
else:
raise ValueError(_("Information's item not found: {0}").format(key))
raise ValueError(_("Information's item"
"not found: {0}").format(key))
except AttributeError:
raise AttributeError(_('{0} has no attribute '
'impl_get_information').format(self.__class__.__name__))
'impl_get_information').format(
self.__class__.__name__))
class Option(BaseInformation):
@ -93,8 +96,10 @@ class Option(BaseInformation):
Reminder: an Option object is **not** a container for the value
"""
__slots__ = ('_name', '_requires', '_multi', '_validator', '_default_multi',
'_default', '_properties', '_callback', '_multitype',
__slots__ = ('_name', '_requires', '_multi', '_validator',
'_default_multi',
'_default',
'_properties', '_callback', '_multitype',
'_master_slaves', '_consistencies', '_empty')
_empty = ''
@ -145,13 +150,16 @@ class Option(BaseInformation):
self._validate(default_multi)
except ValueError, err:
raise ValueError(_("invalid default_multi value {0} "
"for option {1}: {2}").format(str(default_multi), name, err))
if callback is not None and (default is not None or default_multi is not None):
"for option {1}: {2}").format(
str(default_multi), name, err))
if callback is not None and (default is not None or
default_multi is not None):
raise ValueError(_("default value not allowed if option: {0} "
"is calculated").format(name))
if callback is None and callback_params is not None:
raise ValueError(_("params defined for a callback function but "
"no callback defined yet for option {0}").format(name))
"no callback defined"
" yet for option {0}").format(name))
if callback is not None:
if type(callback) != FunctionType:
raise ValueError('callback must be a function')
@ -172,14 +180,18 @@ class Option(BaseInformation):
properties = tuple()
if not isinstance(properties, tuple):
raise TypeError(_('invalid properties type {0} for {1},'
' must be a tuple').format(type(properties), self._name))
' must be a tuple').format(
type(properties),
self._name))
self._properties = properties # 'hidden', 'disabled'...
def __eq__(self, other):
"Option comparison"
if not isinstance(other, Option):
return False
slots = list(self.__slots__ + Option.__slots__ + BaseInformation.__slots__)
slots = list(self.__slots__ +
Option.__slots__ +
BaseInformation.__slots__)
for var in slots:
try:
val1 = getattr(self, var)
@ -270,8 +282,11 @@ class Option(BaseInformation):
if _value is None:
return True
if not val_validator(_value):
raise ValueError(_("invalid value {0} for option {1} for object {2}"
"").format(_value, self._name, self.__class__.__name__))
raise ValueError(_("invalid value {0} "
"for option {1} for object {2}"
).format(_value,
self._name,
self.__class__.__name__))
try:
self._validate(_value)
except ValueError, err:
@ -314,7 +329,8 @@ class Option(BaseInformation):
def impl_is_empty_by_default(self):
"no default value has been set yet"
if ((not self.impl_is_multi() and self._default is None) or
(self.impl_is_multi() and (self._default == [] or None in self._default))):
(self.impl_is_multi() and (self._default == []
or None in self._default))):
return True
return False
@ -343,9 +359,13 @@ class Option(BaseInformation):
if self is opt:
raise ValueError('cannot add consistency with itself')
if self.impl_is_multi() != opt.impl_is_multi():
raise ValueError('options in consistency should be multi in two sides')
raise ValueError('options in consistency'
' should be multi in two sides')
func = '_cons_{0}'.format(func)
self._launch_consistency(func, self, self.impl_getdefault(), None, None, opt)
self._launch_consistency(func,
self,
self.impl_getdefault(),
None, None, opt)
self._consistencies.append((func, opt))
self.impl_validate(self.impl_getdefault())
@ -397,7 +417,8 @@ class ChoiceOption(Option):
def _validate(self, value):
if not self._open_values and not value in self._values:
raise ValueError(_('value {0} is not permitted, only {1} is allowed'
raise ValueError(_('value {0} is not permitted, '
'only {1} is allowed'
'').format(value, self._values))
@ -461,7 +482,8 @@ class SymLinkOption(object):
self._name = name
if not isinstance(opt, Option):
raise ValueError(_('malformed symlinkoption '
'must be an option for symlink {0}').format(name))
'must be an option '
'for symlink {0}').format(name))
self._opt = opt
def __getattr__(self, name):
@ -525,7 +547,10 @@ class PortOption(Option):
ports_min = [0, 1, 1024, 49152]
ports_max = [0, 1023, 49151, 65535]
is_finally = False
for index, allowed in enumerate([allow_zero, allow_wellknown, allow_registred, allow_private]):
for index, allowed in enumerate([allow_zero,
allow_wellknown,
allow_registred,
allow_private]):
if self._min_value is None:
if allowed:
self._min_value = ports_min[index]
@ -555,7 +580,8 @@ class PortOption(Option):
if len(value) != 2:
raise ValueError('range must have two values only')
if not value[0] < value[1]:
raise ValueError('first port in range must be smaller than the second one')
raise ValueError('first port in range must be'
' smaller than the second one')
else:
value = [value]
@ -605,7 +631,8 @@ class NetmaskOption(Option):
make_net=not make_net)
except ValueError:
if not make_net:
msg = _("invalid network {0} ({1}) with netmask {2} ({3}),"
msg = _("invalid network {0} ({1}) "
"with netmask {2} ({3}),"
" this network is an IP")
else:
if make_net:
@ -671,7 +698,8 @@ class DomainnameOption(Option):
raise ValueError(_("invalid value for {0}, must have dot"
"").format(self._name))
if len(value) > length:
raise ValueError(_("invalid domainname's length for {0} (max {1})").format(self._name, length))
raise ValueError(_("invalid domainname's length for "
" {0} (max {1})").format(self._name, length))
if len(value) == 1:
raise ValueError(_("invalid domainname's length for {0} (min 2)"
"").format(self._name))
@ -693,7 +721,8 @@ class OptionDescription(BaseInformation):
"""
if not valid_name(name):
raise ValueError(_("invalid name: {0} for optiondescription").format(name))
raise ValueError(_("invalid name: "
" {0} for optiondescription").format(name))
self._name = name
self._impl_informations = {}
self.impl_set_information('doc', doc)
@ -716,7 +745,8 @@ class OptionDescription(BaseInformation):
properties = tuple()
if not isinstance(properties, tuple):
raise TypeError(_('invalid properties type {0} for {1},'
' must be a tuple').format(type(properties), self._name))
' must be a tuple').format(type(properties),
self._name))
self._properties = properties # 'hidden', 'disabled'...
# the group_type is useful for filtering OptionDescriptions in a config
self._group_type = groups.default
@ -728,7 +758,8 @@ class OptionDescription(BaseInformation):
try:
return self._children[1][self._children[0].index(name)]
except ValueError:
raise AttributeError(_('unknown Option {0} in OptionDescription {1}'
raise AttributeError(_('unknown Option {0} '
'in OptionDescription {1}'
'').format(name, self._name))
def impl_getkey(self, config):
@ -756,7 +787,11 @@ class OptionDescription(BaseInformation):
def impl_getchildren(self):
return self._children[1]
def impl_build_cache(self, cache_path=None, cache_option=None, _currpath=None, _consistencies=None):
def impl_build_cache(self,
cache_path=None,
cache_option=None,
_currpath=None,
_consistencies=None):
if _currpath is None and self._cache_paths is not None:
return
if _currpath is None:
@ -779,11 +814,16 @@ class OptionDescription(BaseInformation):
for consistency in option._consistencies:
func, opt = consistency
opts = (option, opt)
_consistencies.setdefault(opt, []).append((func, opts))
_consistencies.setdefault(option, []).append((func, opts))
_consistencies.setdefault(opt,
[]).append((func, opts))
_consistencies.setdefault(option,
[]).append((func, opts))
else:
_currpath.append(attr)
option.impl_build_cache(cache_path, cache_option, _currpath, _consistencies)
option.impl_build_cache(cache_path,
cache_option,
_currpath,
_consistencies)
_currpath.pop()
if save:
#valid no duplicated option
@ -819,7 +859,8 @@ class OptionDescription(BaseInformation):
"""
if self._group_type != groups.default:
raise TypeError(_('cannot change group_type if already set '
'(old {0}, new {1})').format(self._group_type, group_type))
'(old {0}, new {1})').format(self._group_type,
group_type))
if isinstance(group_type, groups.GroupType):
self._group_type = group_type
if isinstance(group_type, groups.MasterGroupType):
@ -836,7 +877,8 @@ class OptionDescription(BaseInformation):
raise ValueError(_("master group {0} shall not have "
"a symlinkoption").format(self._name))
if not child.impl_is_multi():
raise ValueError(_("not allowed option {0} in group {1}"
raise ValueError(_("not allowed option {0} "
"in group {1}"
": this option is not a multi"
"").format(child._name, self._name))
if child._name == self._name:
@ -846,18 +888,20 @@ class OptionDescription(BaseInformation):
else:
slaves.append(child)
if master is None:
raise ValueError(_('master group with wrong master name for {0}'
'').format(self._name))
raise ValueError(_('master group with wrong'
' master name for {0}'
).format(self._name))
master._master_slaves = tuple(slaves)
for child in self.impl_getchildren():
if child != master:
child._master_slaves = master
child._multitype = multitypes.slave
if not identical_master_child_name:
raise ValueError(_("no child has same nom has master group "
"for: {0}").format(self._name))
raise ValueError(_("no child has same nom has master group"
" for: {0}").format(self._name))
else:
raise ValueError(_('not allowed group_type : {0}').format(group_type))
raise ValueError(_('group_type : {0}'
' not allowed').format(group_type))
def impl_get_group_type(self):
return self._group_type
@ -867,8 +911,12 @@ class OptionDescription(BaseInformation):
if consistencies is not None:
for consistency in consistencies:
opt_ = consistency[1]
ret = opt_[0]._launch_consistency(consistency[0], opt, value, context,
index, opt_[1])
ret = opt_[0]._launch_consistency(consistency[0],
opt,
value,
context,
index,
opt_[1])
if ret is False:
return False
return True
@ -930,10 +978,12 @@ def validate_requires_arg(requires, name):
option._validate(expected)
except ValueError, err:
raise ValueError(_('malformed requirements second argument '
'must be valid for option {0}: {1}').format(name, err))
'must be valid for option {0}'
': {1}').format(name, err))
if action in config_action:
if inverse != config_action[action]:
raise ValueError(_("inconsistency in action types for option: {0}"
raise ValueError(_("inconsistency in action types"
" for option: {0}"
" action: {1}").format(name, action))
else:
config_action[action] = inverse
@ -949,7 +999,11 @@ def validate_requires_arg(requires, name):
for opt_requires in ret_requires.values():
ret_action = []
for require in opt_requires.values():
req = (require[0], tuple(require[1]), require[2], require[3], require[4], require[5])
req = (require[0], tuple(require[1]),
require[2],
require[3],
require[4],
require[5])
ret_action.append(req)
ret.append(tuple(ret_action))
return tuple(ret)

View File

@ -28,7 +28,8 @@ from tiramisu.i18n import _
default_encoding = 'utf-8'
expires_time = 5
ro_remove = ('permissive', 'hidden')
ro_append = ('frozen', 'disabled', 'validator', 'everything_frozen', 'mandatory')
ro_append = ('frozen', 'disabled', 'validator', 'everything_frozen',
'mandatory')
rw_remove = ('permissive', 'everything_frozen', 'mandatory')
rw_append = ('frozen', 'disabled', 'validator', 'hidden')
default_properties = ('expire', 'validator')
@ -292,12 +293,15 @@ class Setting(object):
props = list(properties)
if 'frozen' in properties:
raise PropertiesOptionError(_('cannot change the value for '
'option {0} this option is frozen'
'').format(opt_or_descr._name), props)
'option {0} this option is'
' frozen').format(
opt_or_descr._name),
props)
else:
raise PropertiesOptionError(_("trying to access to an option "
"named: {0} with properties {1}"
"").format(opt_or_descr._name, str(props)), props)
"").format(opt_or_descr._name,
str(props)), props)
def _get_permissive(self, opt=None):
return self._permissives.get(opt, frozenset())
@ -361,7 +365,8 @@ class Setting(object):
for requires in opt._requires:
matches = False
for require in requires:
option, expected, action, inverse, transitive, same_action = require
option, expected, action, inverse, \
transitive, same_action = require
path = descr.impl_get_path_by_opt(option)
if path == optpath or path.startswith(optpath + '.'):
raise RequirementError(_("malformed requirements "
@ -374,15 +379,21 @@ class Setting(object):
continue
properties = err.proptype
if same_action and action not in properties:
raise RequirementError(_("option '{0}' has requirement's property error: "
"{1} {2}").format(opt._name, path, properties))
raise RequirementError(_("option '{0}' has "
"requirement's property "
"error: "
"{1} {2}").format(opt._name,
path,
properties))
#transitive action, force expected
value = expected[0]
inverse = False
except AttributeError:
raise AttributeError(_("required option not found: "
"{0}").format(path))
if not inverse and value in expected or inverse and value not in expected:
if (not inverse and
value in expected or
inverse and value not in expected):
matches = True
setting.append(action)
## the calculation cannot be carried out

View File

@ -78,7 +78,8 @@ class Values(object):
opt.impl_validate(opt.impl_getdefault(), self.context,
'validator' in setting)
self.context.cfgimpl_reset_cache()
if opt.impl_is_multi() and opt.impl_get_multitype() == multitypes.master:
if (opt.impl_is_multi() and
opt.impl_get_multitype() == multitypes.master):
for slave in opt.impl_get_master_slaves():
self._reset(slave)
del(self._values[opt])
@ -126,13 +127,17 @@ class Values(object):
# options with callbacks
setting = self.context.cfgimpl_get_settings()
is_frozen = 'frozen' in setting[opt]
#if value is callback and is not set or frozen with force_default_on_freeze
if opt.impl_has_callback() and (self.is_default_owner(opt) or
# if value is callback and is not set
# or frozen with force_default_on_freeze
if opt.impl_has_callback() and (
self.is_default_owner(opt) or
(is_frozen and
'force_default_on_freeze' in setting[opt])):
no_value_slave = False
if opt.impl_is_multi() and opt.impl_get_multitype() == multitypes.slave:
masterp = self.context.cfgimpl_get_description().impl_get_path_by_opt(
if (opt.impl_is_multi() and
opt.impl_get_multitype() == multitypes.slave):
masterp = self.context.cfgimpl_get_description(
).impl_get_path_by_opt(
opt.impl_get_master_slaves())
mastervalue = getattr(self.context, masterp)
lenmaster = len(mastervalue)
@ -142,7 +147,8 @@ class Values(object):
if not no_value_slave:
value = self._getcallback_value(opt)
if opt.impl_is_multi() and opt.impl_get_multitype() == multitypes.slave:
if (opt.impl_is_multi() and
opt.impl_get_multitype() == multitypes.slave):
if not isinstance(value, list):
value = [value for i in range(lenmaster)]
if opt.impl_is_multi():
@ -181,7 +187,8 @@ class Values(object):
self._setvalue(opt, value, force_permissive=force_permissive,
is_write=is_write)
def _setvalue(self, opt, value, force_permissive=False, force_properties=None,
def _setvalue(self, opt, value, force_permissive=False,
force_properties=None,
is_write=True, validate_properties=True):
self.context.cfgimpl_reset_cache()
setting = self.context.cfgimpl_get_settings()
@ -203,7 +210,8 @@ class Values(object):
def setowner(self, opt, owner):
if opt not in self._values:
raise ConfigError(_('no value for {0} cannot change owner to {1}').format(opt._name, owner))
raise ConfigError(_('no value for {0} cannot change owner'
' to {1}').format(opt._name, owner))
if not isinstance(owner, owners.Owner):
raise TypeError(_("invalid generic owner {0}").format(str(owner)))
self._values[opt] = (owner, self._values[opt][1])
@ -289,7 +297,8 @@ class Multi(list):
self.opt._name, slave._name))
elif len(value_slave) < masterlen:
for num in range(0, masterlen - len(value_slave)):
value_slave.append(slave.impl_getdefault_multi(), force=True)
value_slave.append(slave.impl_getdefault_multi(),
force=True)
def __setitem__(self, key, value):
self._validate(value)
@ -314,7 +323,10 @@ class Multi(list):
value = None
self._validate(value)
#set value without valid properties
self.context.cfgimpl_get_values()._setvalue(self.opt, self, validate_properties=not force)
self.context.cfgimpl_get_values(
)._setvalue(self.opt,
self,
validate_properties=not force)
super(Multi, self).append(value)
if not force and self.opt.impl_get_multitype() == multitypes.master:
for slave in self.opt.impl_get_master_slaves():
@ -385,7 +397,12 @@ class Multi(list):
values = self.context.cfgimpl_get_values()
if not values.is_default_owner(slave):
#get multi without valid properties
values.getitem(slave, validate_properties=False).pop(key, force=True)
values.getitem(slave,
validate_properties=False
).pop(key, force=True)
#set value without valid properties
self.context.cfgimpl_get_values()._setvalue(self.opt, self, validate_properties=not force)
self.context.cfgimpl_get_values(
)._setvalue(self.opt,
self,
validate_properties=not force)
return super(Multi, self).pop(key)