Completed
Pull Request — master (#275)
by
unknown
04:21
created

UaStatusCodeError.__str__()   A

Complexity

Conditions 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
c 1
b 0
f 1
dl 0
loc 5
rs 9.4285
1
"""
2
Define exceptions to be raised at various places in the stack
3
"""
4
5
class _AutoRegister(type):
6
    def __new__(mcs, name, bases, dict):
7
        SubClass = type.__new__(mcs, name, bases, dict)
8
9
        # register subclass in bases
10
        for base in bases:
11
            try:
12
                subclasses = base._subclasses
13
                code = dict['code']
14
            except (AttributeError, KeyError):
15
                pass
16
            else:
17
                subclasses[code] = SubClass
18
19
        return SubClass
20
21
class UaError(RuntimeError):
22
    pass
23
24
25
class UaStatusCodeError(UaError):
26
    """
27
    This exception is raised when a bad status code is encountered.
28
29
    It exposes the status code number in the `code' property, so the
30
    user can distinguish between the different status codes and maybe
31
    handle some of them.
32
33
    The list of status error codes can be found in opcua.ua.status_codes.
34
    """
35
36
    __metaclass__ = _AutoRegister
37
38
    """ Dict containing all subclasses keyed to their status code. """
39
    _subclasses = {}
40
41
    def __new__(cls, *args):
42
        """
43
        Creates a new UaStatusCodeError but returns a more specific subclass
44
        if possible, e.g.
45
46
            UaStatusCodeError(0x80010000) => BadUnexpectedError()
47
        """
48
49
        # switch class to a more appropriate subclass
50
        if len(args) >= 1:
51
            code = args[0]
52
            try:
53
                cls = cls._subclasses[code]
54
            except (KeyError, AttributeError):
55
                pass
56
            else:
57
                args = args[1:]
58
59
        return UaError.__new__(cls, *args)
60
61
    def __init__(self, code=None):
62
        """
63
        :param code: The code of the exception. Only needed when not instanciating
64
                     a concrete subclass such as BadInternalError.
65
        """
66
        if code is None:
67
            if type(self) is UaStatusCodeError:
68
                raise TypeError("UaStatusCodeError(code) cannot be instantiated without a status code.")
69
        UaError.__init__(self, code)
70
71
    def __str__(self):
72
        # import here to avoid circular import problems
73
        import opcua.ua.status_codes as status_codes
74
75
        return "{1}({0})".format(*status_codes.get_name_and_doc(self.code))
76
77
    @property
78
    def code(self):
79
        """
80
        The code of the status error.
81
        """
82
        return self.args[0]
83
84
class UaStringParsingError(UaError):
85
    pass
86