try: from tiramisu.error import APIError, ValueWarning, ValueOptionError, ValueErrorWarning, PropertiesOptionError except ModuleNotFoundError: import weakref from .i18n import _ def display_list(lst, separator='and', add_quote=False): if separator == 'and': separator = _('and') elif separator == 'or': separator = _('or') if isinstance(lst, tuple) or isinstance(lst, frozenset): lst = list(lst) if len(lst) == 1: ret = lst[0] if not isinstance(ret, str): ret = str(ret) if add_quote: ret = '"{}"'.format(ret) return ret else: lst.sort() lst_ = [] for l in lst[:-1]: if not isinstance(l, str): l = str(l) if add_quote: l = '"{}"'.format(l) lst_.append(_(l)) last = lst[-1] if not isinstance(last, str): last = str(_(last)) if add_quote: last = '"{}"'.format(last) return ', '.join(lst_) + _(' {} ').format(separator) + '{}'.format(last) class APIError(Exception): pass class _CommonError: def __init__(self, val, display_type, opt, err_msg): self.val = val self.display_type = display_type self.opt = weakref.ref(opt) self.err_msg = err_msg super().__init__(self.err_msg) def __str__(self): try: msg = self.prefix except AttributeError: self.prefix = self.tmpl.format(self.val, self.display_type, self.opt().impl_get_display_name()) msg = self.prefix if self.err_msg: if msg: msg += ', {}'.format(self.err_msg) else: msg = self.err_msg if not msg: msg = _('invalid value') return msg class ValueWarning(_CommonError, UserWarning): tmpl = _('attention, "{0}" could be an invalid {1} for "{2}"') class ValueOptionError(_CommonError, ValueError): tmpl = _('"{0}" is an invalid {1} for "{2}"') class ValueErrorWarning(ValueWarning): tmpl = _('"{0}" is an invalid {1} for "{2}"') # Exceptions for an Option class PropertiesOptionError(AttributeError): "attempt to access to an option with a property that is not allowed" def __init__(self, option_bag, proptype, settings, opt_type=None, requires=None, name=None, orig_opt=None): if opt_type: self._opt_type = opt_type self._requires = requires self._name = name self._orig_opt = orig_opt else: if option_bag.option.impl_is_optiondescription(): self._opt_type = 'optiondescription' else: self._opt_type = 'option' self._requires = option_bag.option.impl_getrequires() self._name = option_bag.option.impl_get_display_name() self._orig_opt = None self._option_bag = option_bag self.proptype = proptype self._settings = settings self.msg = None super(PropertiesOptionError, self).__init__(None) def set_orig_opt(self, opt): self._orig_opt = opt def __str__(self): # this part is a bit slow, so only execute when display if self.msg: return self.msg req = self._settings.apply_requires(self._option_bag, True) # if req != {} or self._orig_opt is not None: if req != {}: only_one = len(req) == 1 msg = [] for action, msg_ in req.items(): msg.append('"{0}" ({1})'.format(action, display_list(msg_))) msg = display_list(msg) else: only_one = len(self.proptype) == 1 msg = display_list(list(self.proptype), add_quote=True) if only_one: prop_msg = _('property') else: prop_msg = _('properties') if self._orig_opt: self.msg = str(_('cannot access to {0} "{1}" because "{2}" has {3} {4}' '').format(self._opt_type, self._orig_opt.impl_get_display_name(), self._name, prop_msg, msg)) else: self.msg = str(_('cannot access to {0} "{1}" because has {2} {3}' '').format(self._opt_type, self._name, prop_msg, msg)) del self._requires, self._opt_type, self._name, self._option_bag del self._settings, self._orig_opt return self.msg