tiramisu/tiramisu/error.py

168 lines
5.3 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
# Copyright (C) 2012-2017 Team tiramisu (see AUTHORS for all contributors)
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# ____________________________________________________________
"user defined exceptions"
from .i18n import _
def display_list(lst, separator='and'):
if separator == 'and':
separator = _('and')
elif separator == 'or':
separator = _('or')
if len(lst) == 0:
return ''
elif len(lst) == 1:
ret = lst[0]
if not isinstance(ret, str):
ret = str(ret)
return '"{}"'.format(ret)
else:
if isinstance(lst, tuple):
lst = list(lst)
lst.sort()
lst_ = []
for l in lst[:-1]:
if not isinstance(l, str):
l = str(l)
lst_.append('"{}"'.join(_(l)))
last = lst[-1]
if not isinstance(last, str):
last = str(_(last))
return ', '.join(lst_) + _(' {} ').format(separator) + '"{}"'.format(last)
# Exceptions for an Option
class PropertiesOptionError(AttributeError):
"attempt to access to an option with a property that is not allowed"
def __init__(self,
msg,
proptype,
settings=None,
datas=None,
option_type=None):
self.proptype = proptype
self._settings = settings
self._datas = datas
self._type = option_type
self._orig_opt = None
super(PropertiesOptionError, self).__init__(msg)
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._settings is None:
req = {}
else:
req = self._settings.apply_requires(**self._datas)
#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_)))
else:
only_one = len(self.proptype) == 1
msg = list(self.proptype)
if only_one:
prop_msg = _('property')
else:
prop_msg = _('properties')
msg = display_list(msg)
if self._orig_opt:
return str(_('cannot access to {0} "{1}" because "{2}" has {3} {4}'
'').format(self._type,
self._orig_opt.impl_get_display_name(),
self._datas['config_bag'].option.impl_get_display_name(),
prop_msg,
msg))
return str(_('cannot access to {0} "{1}" because has {2} {3}'
'').format(self._type,
self._datas['config_bag'].option.impl_get_display_name(),
prop_msg,
msg))
#____________________________________________________________
# Exceptions for a Config
class ConfigError(Exception):
"""attempt to change an option's owner without a value
or in case of `_cfgimpl_descr` is None
or if a calculation cannot be carried out"""
pass
class ConflictError(Exception):
"duplicate options are present in a single config"
pass
#____________________________________________________________
# miscellaneous exceptions
class RequirementError(Exception):
"""a recursive loop occurs in the requirements tree
requires
"""
pass
class SlaveError(Exception):
"problem with a slave's value length"
pass
class ConstError(TypeError):
"no uniq value in _NameSpace"
pass
#Warning
class ValueWarning(UserWarning): # pragma: optional cover
"""Option could warn user and not raise ValueError.
Example:
>>> import warnings
>>> from tiramisu.error import ValueWarning
>>> from tiramisu.option import StrOption, OptionDescription
>>> from tiramisu.config import Config
>>> warnings.simplefilter("always", ValueWarning)
>>> def a(val):
... raise ValueError('pouet')
...
>>> s=StrOption('s', '', validator=a, warnings_only=True)
>>> o=OptionDescription('o', '', [s])
>>> c=Config(o)
>>> c.s = 'val'
StrOption:0: ValueWarning: invalid value val for option s: pouet
>>> with warnings.catch_warnings(record=True) as w:
... c.s = 'val'
...
>>> w[0].message.opt == s
True
>>> print(str(w[0].message))
invalid value val for option s: pouet
"""
def __init__(self, msg, opt):
self.opt = opt
super(ValueWarning, self).__init__(msg)
class APIError(Exception):
pass