diff --git a/tiramisu/config.py b/tiramisu/config.py index 811f931..93cfe34 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -26,6 +26,7 @@ from tiramisu.error import (PropertiesOptionError, NotFoundError, from tiramisu.option import OptionDescription, Option, SymLinkOption from tiramisu.setting import groups, Setting, apply_requires from tiramisu.value import Values +from tiramisu.i18n import _ class SubConfig(object): @@ -85,7 +86,7 @@ class SubConfig(object): "validation for the setattr and the getattr" if not isinstance(opt_or_descr, Option) and \ not isinstance(opt_or_descr, OptionDescription): - raise TypeError('Unexpected object: {0}'.format(repr(opt_or_descr))) + raise TypeError(_('Unexpected object: {0}').format(repr(opt_or_descr))) properties = set(self.cfgimpl_get_settings().get_properties(opt_or_descr)) #remove this properties, those properties are validate in value/setting properties = properties - set(['mandatory', 'frozen']) @@ -96,9 +97,9 @@ class SubConfig(object): properties = properties - set(self.cfgimpl_get_settings().get_permissive(opt_or_descr)) properties = list(properties) if properties != []: - raise PropertiesOptionError("trying to access" + raise PropertiesOptionError(_("trying to access" " to an option named: {0} with properties" - " {1}".format(name, str(properties)), + " {1}").format(name, str(properties)), properties) def __getattr__(self, name): @@ -131,10 +132,10 @@ class SubConfig(object): if isinstance(opt_or_descr, OptionDescription): children = self.cfgimpl_get_description()._children if opt_or_descr not in children[1]: - raise AttributeError("{0} with name {1} object has " - "no attribute {2}".format(self.__class__, - opt_or_descr._name, - name)) + raise AttributeError(_("{0} with name {1} object has " + "no attribute {2}").format(self.__class__, + opt_or_descr._name, + name)) return SubConfig(opt_or_descr, self._cfgimpl_context) # special attributes if name.startswith('_cfgimpl_'): @@ -153,16 +154,16 @@ class SubConfig(object): apply_requires(child, self) #needed to ? if child not in self._cfgimpl_descr._children[1]: - raise AttributeError('unknown option %s' % (name)) + raise AttributeError(_('unknown option {}').format(name)) if setting.has_property('everything_frozen'): - raise TypeError("cannot set a value to the option {} if the whole " - "config has been frozen".format(name)) + raise TypeError(_("cannot set a value to the option {} if the whole " + "config has been frozen").format(name)) if setting.has_property('frozen') and setting.has_property('frozen', child, is_apply_req=False): - raise TypeError('cannot change the value to %s for ' - 'option %s this option is frozen' % (str(value), name)) + raise TypeError(_('cannot change the value to {} for ' + 'option {} this option is frozen').format(str(value), name)) self.cfgimpl_get_values()[child] = value def cfgimpl_get_home_by_path(self, path, force_permissive=False, force_properties=None): @@ -226,7 +227,7 @@ class SubConfig(object): """ if group_type is not None: if not isinstance(group_type, groups.GroupType): - raise TypeError("Unknown group_type: {0}".format(group_type)) + raise TypeError(_("Unknown group_type: {0}").format(group_type)) for child in self._cfgimpl_descr._children[1]: if isinstance(child, OptionDescription): try: @@ -320,7 +321,7 @@ class SubConfig(object): if _currpath is None: _currpath = [] if withoption is None and withvalue is not None: - raise ValueError("make_dict can't filtering with value without option") + raise ValueError(_("make_dict can't filtering with value without option")) if withoption is not None: mypath = self.getpath() for path in self.cfgimpl_get_context()._find(bytype=Option, @@ -339,8 +340,8 @@ class SubConfig(object): else: tmypath = mypath + '.' if not path.startswith(tmypath): - raise Exception('unexpected path {}, ' - 'should start with {}'.format(path, mypath)) + raise Exception(_('unexpected path {}, ' + 'should start with {}').format(path, mypath)) path = path[len(tmypath):] self._make_sub_dict(opt, path, pathsvalues, _currpath, flatten) #withoption can be set to None below ! @@ -428,11 +429,11 @@ class Config(SubConfig): homeconfig.setoption(name, child, value) elif len(candidates) > 1: raise AmbigousOptionError( - 'more than one option that ends with %s' % (key, )) + _('more than one option that ends with {}').format(key)) else: raise NoMatchingOptionFound( - 'there is no option that matches %s' - ' or the option is hidden or disabled' % (key, )) + _('there is no option that matches {}' + ' or the option is hidden or disabled').format(key)) def getpath(self): return None @@ -483,7 +484,7 @@ class Config(SubConfig): # return False # return False if type_ not in ('option', 'path', 'value'): - raise ValueError('unknown type_ type {} for _find'.format(type_)) + raise ValueError(_('unknown type_ type {} for _find').format(type_)) find_results = [] opts, paths = self.cfgimpl_get_description()._cache_paths for index in range(0, len(paths)): @@ -517,7 +518,7 @@ class Config(SubConfig): else: find_results.append(retval) if find_results == []: - raise NotFoundError("no option found in config with these criteria") + raise NotFoundError(_("no option found in config with these criteria")) else: return find_results diff --git a/tiramisu/i18n.py b/tiramisu/i18n.py new file mode 100644 index 0000000..a8825b0 --- /dev/null +++ b/tiramisu/i18n.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- + +import gettext +gettext.translation('tiramisu', fallback=True) +_ = gettext.gettext diff --git a/tiramisu/option.py b/tiramisu/option.py index 7a49b98..8f0f0cc 100644 --- a/tiramisu/option.py +++ b/tiramisu/option.py @@ -28,6 +28,7 @@ from IPy import IP from tiramisu.error import (ConfigError, NotFoundError, ConflictConfigError, RequiresError, ValidateError) from tiramisu.setting import groups, multitypes +from tiramisu.i18n import _ name_regexp = re.compile(r'^\d+') @@ -36,7 +37,7 @@ def valid_name(name): try: name = str(name) except: - raise ValueError("not a valid string name") + raise ValueError(_('not a valid string name')) if re.match(name_regexp, name) is None: return True else: @@ -67,7 +68,7 @@ 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)) class Option(BaseInformation): @@ -103,7 +104,7 @@ class Option(BaseInformation): :param validator_args: the validator's parameters """ if not valid_name(name): - raise NameError("invalid name: {0} for option".format(name)) + raise NameError(_("invalid name: {0} for option").format(name)) self._name = name self._informations = {} self.set_information('doc', doc) @@ -113,24 +114,24 @@ class Option(BaseInformation): self._consistency = None if validator is not None: if type(validator) != FunctionType: - raise TypeError("validator must be a function") + raise TypeError(_("validator must be a function")) if validator_args is None: validator_args = {} self._validator = (validator, validator_args) else: self._validator = None if not self._multi and default_multi is not None: - raise ConfigError("a default_multi is set whereas multi is False" - " in option: {0}".format(name)) + raise ConfigError(_("a default_multi is set whereas multi is False" + " in option: {0}").format(name)) if default_multi is not None and not self._validate(default_multi): - raise ConfigError("invalid default_multi value {0} " - "for option {1}".format(str(default_multi), name)) + raise ConfigError(_("invalid default_multi value {0} " + "for option {1}").format(str(default_multi), name)) if callback is not None and (default is not None or default_multi is not None): - raise ConfigError("defaut values not allowed if option: {0} " - "is calculated".format(name)) + raise ConfigError(_("defaut values not allowed if option: {0} " + "is calculated").format(name)) if callback is None and callback_params is not None: - raise ConfigError("params defined for a callback function but " - "no callback defined yet for option {0}".format(name)) + raise ConfigError(_("params defined for a callback function but " + "no callback defined yet for option {0}").format(name)) if callback is not None: self._callback = (callback, callback_params) else: @@ -143,21 +144,21 @@ class Option(BaseInformation): # "for option {1} : not list type" # "".format(str(default), name)) if not self.validate(default): - raise ValidateError("invalid default value {0} " + raise ValidateError(_("invalid default value {0} " "for option {1}" - "".format(str(default), name)) + "").format(str(default), name)) self._multitype = multitypes.default self._default_multi = default_multi else: if default is not None and not self.validate(default): - raise ValidateError("invalid default value {0} " - "for option {1}".format(str(default), name)) + raise ValidateError(_("invalid default value {0} " + "for option {1}").format(str(default), name)) self._default = default if properties is None: properties = () if not isinstance(properties, tuple): - raise ConfigError('invalid properties type {0} for {1},' - ' must be a tuple'.format(type(properties), self._name)) + raise ConfigError(_('invalid properties type {0} for {1},' + ' must be a tuple').format(type(properties), self._name)) self._properties = properties # 'hidden', 'disabled'... def validate(self, value, context=None, validate=True): @@ -183,9 +184,9 @@ class Option(BaseInformation): return cons.valid_consistency(self, value, context, None) else: if not isinstance(value, list): - raise ValidateError("invalid value {0} " + raise ValidateError(_("invalid value {0} " "for option {1} which must be a list" - "".format(value, self._name)) + "").format(value, self._name)) for index in range(0, len(value)): val = value[index] # None allows the reset of the value @@ -268,11 +269,11 @@ class ChoiceOption(Option): callback_params=None, open_values=False, validator=None, validator_args=None, properties=()): if not isinstance(values, tuple): - raise ConfigError('values must be a tuple for {0}'.format(name)) + raise ConfigError(_('values must be a tuple for {0}').format(name)) self._values = values if open_values not in (True, False): - raise ConfigError('Open_values must be a boolean for ' - '{0}'.format(name)) + raise ConfigError(_('open_values must be a boolean for ' + '{0}').format(name)) self._open_values = open_values super(ChoiceOption, self).__init__(name, doc, default=default, default_multi=default_multi, @@ -394,7 +395,7 @@ class NetmaskOption(Option): properties=None, opt_ip=None): if opt_ip is not None and not isinstance(opt_ip, IPOption) and \ not isinstance(opt_ip, NetworkOption): - raise ValueError('opt_ip must be a IPOption not {}'.format(type(opt_ip))) + raise ValueError(_('opt_ip must be a IPOption not {}').format(type(opt_ip))) super(NetmaskOption, self).__init__(name, doc, default=default, default_multi=default_multi, callback=callback, @@ -411,7 +412,7 @@ class NetmaskOption(Option): elif isinstance(opt_ip, NetworkOption): self._consistency = ('cons_network_netmask', (self, opt_ip)) else: - raise ValueError('unknown type for opt_ip') + raise ValueError(_('unknown type for opt_ip')) def _validate(self, value): try: @@ -465,7 +466,7 @@ class OptionDescription(BaseInformation): ``OptionDescription`` instances for nested namespaces). """ if not valid_name(name): - raise NameError("invalid name: {0} for option descr".format(name)) + raise NameError(_("invalid name: {0} for option descr").format(name)) self._name = name self._informations = {} self.set_information('doc', doc) @@ -476,8 +477,8 @@ class OptionDescription(BaseInformation): old = None for child in valid_child: if child == old: - raise ConflictConfigError('duplicate option name: ' - '{0}'.format(child)) + raise ConflictConfigError(_('duplicate option name: ' + '{0}').format(child)) old = child self._children = (tuple(child_names), tuple(children)) validate_requires_arg(requires, self._name) @@ -485,8 +486,8 @@ class OptionDescription(BaseInformation): self._cache_paths = None self._consistencies = None if not isinstance(properties, tuple): - raise ConfigError('invalid properties type {0} for {1},' - ' must be a tuple'.format(type(properties), self._name)) + raise ConfigError(_('invalid properties type {0} for {1},' + ' 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 @@ -498,8 +499,8 @@ class OptionDescription(BaseInformation): try: return self._children[1][self._children[0].index(name)] except ValueError: - raise AttributeError('unknown Option {} in OptionDescription {}' - ''.format(name, self._name)) + raise AttributeError(_('unknown Option {} in OptionDescription {}' + '').format(name, self._name)) def getkey(self, config): return tuple([child.getkey(getattr(config, child._name)) @@ -550,7 +551,7 @@ class OptionDescription(BaseInformation): func, opts = option._consistency for opt in opts: if opt in _consistencies: - raise ValueError('opt {} already in consistency'.format(opt._name)) + raise ValueError(_('opt {} already in consistency').format(opt._name)) _consistencies[opt] = (func, opts) else: _currpath.append(attr) @@ -563,8 +564,8 @@ class OptionDescription(BaseInformation): old = None for child in valid_child: if child == old: - raise ConflictConfigError('duplicate option: ' - '{0}'.format(child)) + raise ConflictConfigError(_('duplicate option: ' + '{0}').format(child)) old = child self._cache_paths = (tuple(cache_option), tuple(cache_path)) self._consistencies = _consistencies @@ -573,13 +574,13 @@ class OptionDescription(BaseInformation): try: return self._cache_paths[0][self._cache_paths[1].index(path)] except ValueError: - raise NotFoundError('no option for path {}'.format(path)) + raise NotFoundError(_('no option for path {}').format(path)) def get_path_by_opt(self, opt): try: return self._cache_paths[1][self._cache_paths[0].index(opt)] except ValueError: - raise NotFoundError('no option {} found'.format(opt)) + raise NotFoundError(_('no option {} found').format(opt)) # ____________________________________________________________ def set_group_type(self, group_type): @@ -589,8 +590,8 @@ class OptionDescription(BaseInformation): that lives in `setting.groups` """ if self._group_type != groups.default: - ConfigError('cannot change group_type if already set ' - '(old {}, new {})'.format(self._group_type, group_type)) + ConfigError(_('cannot change group_type if already set ' + '(old {}, new {})').format(self._group_type, group_type)) if isinstance(group_type, groups.GroupType): self._group_type = group_type if isinstance(group_type, groups.MasterGroupType): @@ -601,12 +602,12 @@ class OptionDescription(BaseInformation): master = None for child in self._children[1]: if isinstance(child, OptionDescription): - raise ConfigError("master group {} shall not have " - "a subgroup".format(self._name)) + raise ConfigError(_("master group {} shall not have " + "a subgroup").format(self._name)) if not child.is_multi(): - raise ConfigError("not allowed option {0} in group {1}" + raise ConfigError(_("not allowed option {0} in group {1}" ": this option is not a multi" - "".format(child._name, self._name)) + "").format(child._name, self._name)) if child._name == self._name: identical_master_child_name = True child._multitype = multitypes.master @@ -614,18 +615,18 @@ class OptionDescription(BaseInformation): else: slaves.append(child) if master is None: - raise ConfigError('master group with wrong master name for {}' - ''.format(self._name)) + raise ConfigError(_('master group with wrong master name for {}' + '').format(self._name)) master._master_slaves = tuple(slaves) for child in self._children[1]: if child != master: child._master_slaves = master child._multitype = multitypes.slave if not identical_master_child_name: - raise ConfigError("the master group: {} has not any " - "master child".format(self._name)) + raise ConfigError(_("the master group: {} has not any " + "master child").format(self._name)) else: - raise ConfigError('not allowed group_type : {0}'.format(group_type)) + raise ConfigError(_('not allowed group_type : {0}').format(group_type)) def get_group_type(self): return self._group_type @@ -644,8 +645,8 @@ def validate_requires_arg(requires, name): config_action = {} for req in requires: if not type(req) == tuple: - raise RequiresError("malformed requirements type for option:" - " {0}, must be a tuple".format(name)) + raise RequiresError(_("malformed requirements type for option:" + " {0}, must be a tuple").format(name)) if len(req) == 3: action = req[2] inverse = False @@ -653,11 +654,11 @@ def validate_requires_arg(requires, name): action = req[2] inverse = req[3] else: - raise RequiresError("malformed requirements for option: {0}" - " invalid len".format(name)) + raise RequiresError(_("malformed requirements for option: {0}" + " invalid len").format(name)) if action in config_action: if inverse != config_action[action]: - raise RequiresError("inconsistency in action types for option: {0}" - " action: {1}".format(name, action)) + raise RequiresError(_("inconsistency in action types for option: {0}" + " action: {1}").format(name, action)) else: config_action[action] = inverse diff --git a/tiramisu/value.py b/tiramisu/value.py index 528185a..a9ef389 100644 --- a/tiramisu/value.py +++ b/tiramisu/value.py @@ -21,6 +21,7 @@ from tiramisu.error import MandatoryError, MultiTypeError, \ ConfigError, ValidateError from tiramisu.setting import owners, multitypes from tiramisu.autolib import carry_out_calculation +from tiramisu.i18n import _ class Values(object): @@ -49,8 +50,8 @@ class Values(object): mastervalue = getattr(self.context, masterpath) masterlen = len(mastervalue) if len(value) > masterlen: - raise MultiTypeError("invalid len for the slave: {0}" - " which has {1} as master".format( + raise MultiTypeError(_("invalid len for the slave: {0}" + " which has {1} as master").format( opt._name, masterpath)) if len(value) < masterlen: for num in range(0, masterlen - len(value)): @@ -85,18 +86,18 @@ class Values(object): setting.has_property('mandatory')) if setting.has_property('mandatory', opt, False) and set_mandatory: if self._is_empty(opt, value) and opt.is_empty_by_default(): - raise MandatoryError("option: {0} is mandatory " - "and shall have a value".format(opt._name)) + raise MandatoryError(_("option: {0} is mandatory " + "and shall have a value").format(opt._name)) #empty value if opt.is_multi(): for val in value: if val == '': - raise MandatoryError("option: {0} is mandatory " - "and shall have not empty value".format(opt._name)) + raise MandatoryError(_("option: {0} is mandatory " + "and shall have not empty value").format(opt._name)) else: if value == '': - raise MandatoryError("option: {0} is mandatory " - "and shall have not empty value".format(opt._name)) + raise MandatoryError(_("option: {0} is mandatory " + "and shall have not empty value").format(opt._name)) def fill_multi(self, opt, result): """fills a multi option with default and calculated values @@ -144,23 +145,23 @@ class Values(object): value = self.fill_multi(opt, value) self._test_mandatory(opt, value, force_properties) if validate and not opt.validate(value, self.context, setting.has_property('validator')): - raise ValidateError('invalid calculated value returned' - ' for option {0}: {1}'.format(opt._name, value)) + raise ValidateError(_('invalid calculated value returned' + ' for option {0}: {1}').format(opt._name, value)) return value def __setitem__(self, opt, value): if not opt.validate(value, self.context, self.context.cfgimpl_get_settings().has_property('validator')): - raise ValidateError('invalid value {}' - ' for option {}'.format(value, opt._name)) + raise ValidateError(_('invalid value {}' + ' for option {}').format(value, opt._name)) if opt.is_multi(): if opt.get_multitype() == multitypes.master: masterlen = len(value) for slave in opt.master_slaves: value_slave = self._get_value(slave) if len(value_slave) > masterlen: - raise MultiTypeError("invalid len for the slave: {0}" - " which has {1} as master".format( + raise MultiTypeError(_("invalid len for the slave: {0}" + " which has {1} as master").format( slave._name, opt._name)) elif len(value_slave) < masterlen: for num in range(0, masterlen - len(value_slave)): @@ -168,8 +169,8 @@ class Values(object): elif opt.get_multitype() == multitypes.slave: if len(self._get_value(opt.master_slaves)) != len(value): - raise MultiTypeError("invalid len for the slave: {0}" - " which has {1} as master".format( + raise MultiTypeError(_("invalid len for the slave: {0}" + " which has {1} as master").format( opt._name, opt.master_slaves._name)) if not isinstance(value, Multi): value = Multi(value, self.context, opt) @@ -177,8 +178,8 @@ class Values(object): def setitem(self, opt, value): if type(value) == list: - raise MultiTypeError("the type of the value {0} which is multi shall " - "be Multi and not list".format(str(value))) + raise MultiTypeError(_("the type of the value {0} which is multi shall " + "be Multi and not list").format(str(value))) self._test_mandatory(opt, value) self.values[opt] = (self.context.cfgimpl_get_settings().getowner(), value) @@ -190,9 +191,9 @@ class Values(object): def setowner(self, opt, owner): if opt not in self.values: - raise ConfigError('no value for {} cannot change owner to {}'.format(opt)) + raise ConfigError(_('no value for {1} cannot change owner to {2}').format(opt)) if not isinstance(owner, owners.Owner): - raise TypeError("invalid generic owner {0}".format(str(owner))) + raise TypeError(_("invalid generic owner {0}").format(str(owner))) self.values[opt] = (owner, self.values[opt][1]) def is_default_owner(self, opt): @@ -233,8 +234,8 @@ class Multi(list): """ if not force: if self.opt.get_multitype() == multitypes.slave: - raise MultiTypeError("cannot append a value on a multi option {0}" - " which is a slave".format(self.opt._name)) + raise MultiTypeError(_("cannot append a value on a multi option {0}" + " which is a slave").format(self.opt._name)) elif self.opt.get_multitype() == multitypes.master: for slave in self.opt.get_master_slaves(): self.context.cfgimpl_get_values()[slave].append(slave.getdefault_multi(), force=True) @@ -244,9 +245,9 @@ class Multi(list): def _validate(self, value): if value is not None and not self.opt._validate(value): - raise ConfigError("invalid value {0} " - "for option {1}".format(str(value), - self.opt._name)) + raise ConfigError(_("invalid value {0} " + "for option {1}").format(str(value), + self.opt._name)) def pop(self, key, force=False): """the list value can be updated (poped) @@ -257,8 +258,8 @@ class Multi(list): """ if not force: if self.opt.multitype == multitypes.slave: - raise MultiTypeError("cannot append a value on a multi option {0}" - " which is a slave".format(self.opt._name)) + raise MultiTypeError(_("cannot append a value on a multi option {0}" + " which is a slave").format(self.opt._name)) elif self.opt.multitype == multitypes.master: for slave in self.opt.get_master_slaves(): self.context.cfgimpl_get_values()[slave].pop(key, force=True)