Coverage for pyEDAA/Reports/__init__.py: 100%

68 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-21 23:49 +0000

1# ==================================================================================================================== # 

2# _____ ____ _ _ ____ _ # 

3# _ __ _ _| ____| _ \ / \ / \ | _ \ ___ _ __ ___ _ __| |_ ___ # 

4# | '_ \| | | | _| | | | |/ _ \ / _ \ | |_) / _ \ '_ \ / _ \| '__| __/ __| # 

5# | |_) | |_| | |___| |_| / ___ \ / ___ \ _| _ < __/ |_) | (_) | | | |_\__ \ # 

6# | .__/ \__, |_____|____/_/ \_\/_/ \_(_)_| \_\___| .__/ \___/|_| \__|___/ # 

7# |_| |___/ |_| # 

8# ==================================================================================================================== # 

9# Authors: # 

10# Patrick Lehmann # 

11# # 

12# License: # 

13# ==================================================================================================================== # 

14# Copyright 2021-2026 Electronic Design Automation Abstraction (EDA²) # 

15# # 

16# Licensed under the Apache License, Version 2.0 (the "License"); # 

17# you may not use this file except in compliance with the License. # 

18# You may obtain a copy of the License at # 

19# # 

20# http://www.apache.org/licenses/LICENSE-2.0 # 

21# # 

22# Unless required by applicable law or agreed to in writing, software # 

23# distributed under the License is distributed on an "AS IS" BASIS, # 

24# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 

25# See the License for the specific language governing permissions and # 

26# limitations under the License. # 

27# # 

28# SPDX-License-Identifier: Apache-2.0 # 

29# ==================================================================================================================== # 

30# 

31""" 

32Various report abstract data models and report format converters. 

33""" 

34from __future__ import annotations 

35 

36__author__ = "Patrick Lehmann" 

37__email__ = "Paebbels@gmail.com" 

38__copyright__ = "2021-2026, Electronic Design Automation Abstraction (EDA²)" 

39__license__ = "Apache License, Version 2.0" 

40__version__ = "0.20.0rc4" 

41__keywords__ = ["Reports", "Abstract Model", "Data Model", "Unit Testing", "Testcase", "Testsuite", "OSVVM", "YAML", "XML"] 

42__project_url__ = "https://github.com/edaa-org/pyEDAA.Reports" 

43__documentation_url__ = "https://edaa-org.github.io/pyEDAA.Reports" 

44__issue_tracker_url__ = "https://GitHub.com/edaa-org/pyEDAA.Reports/issues" 

45 

46from enum import Enum 

47from typing import Any, Hashable, Mapping, Optional as Nullable 

48 

49from pyTooling.Common import getFullyQualifiedName 

50from pyTooling.DataModel import KeyValuePairsMixin 

51from pyTooling.Decorators import export, readonly 

52from pyTooling.Exceptions import ExceptionBase 

53from pyTooling.MetaClasses import ExtendedType 

54 

55 

56@export 

57class ReportException(ExceptionBase): 

58 """Base-exception of all exceptions raised by pyEDAA.Reports.""" 

59 

60 

61@export 

62class Severity(Enum): 

63 Unknown = 0 

64 Debug = 5 

65 Verbose = 10 

66 Normal = 20 

67 Info = 25 

68 Warning = 50 

69 CriticalWarning = 55 

70 Error = 60 

71 Fatal = 70 

72 

73 

74@export 

75class Person(KeyValuePairsMixin, metaclass=ExtendedType, slots=True): 

76 """ 

77 A real person: a user ID, a name and an e-mail address. 

78 

79 A person belongs to no single data model: a root registers the persons it refers to, and the same person may be 

80 registered in several roots, e.g. as the author of requirements and as the owner of risks. The role a person acts in, 

81 e.g. a reviewer, is a persona of the requirements model. 

82 """ 

83 

84 _userID: str #: The person's user ID, unique among persons. 

85 _name: str #: The person's name. 

86 _email: Nullable[str] #: The person's e-mail address, if known. 

87 

88 def __init__( 

89 self, 

90 userID: str, 

91 name: str, 

92 email: Nullable[str] = None, 

93 keyValuePairs: Nullable[Mapping[Hashable, Any]] = None 

94 ) -> None: 

95 """ 

96 Initialize a person. 

97 

98 :param userID: The person's user ID, e.g. ``paebbels``. 

99 :param name: The person's name. 

100 :param email: Optional, the person's e-mail address. Default: ``None``. 

101 :param keyValuePairs: Optional, the key-value pairs. Default: ``None``. 

102 :raises TypeError: If parameter ``keyValuePairs`` isn't a mapping. 

103 :raises ValueError: If parameter ``userID`` or ``name`` is ``None``. 

104 :raises TypeError: If parameter ``userID``, ``name`` or ``email`` isn't of type :class:`str`. 

105 :raises ValueError: If parameter ``userID`` or ``name`` is empty. 

106 :raises ValueError: If parameter ``email`` isn't of the form ``local@domain``. 

107 """ 

108 super().__init__(keyValuePairs) 

109 

110 for parameterName, text in (("userID", userID), ("name", name)): 

111 if text is None: 

112 raise ValueError(f"Parameter '{parameterName}' is None.") 

113 elif not isinstance(text, str): 

114 ex = TypeError(f"Parameter '{parameterName}' is not of type 'str'.") 

115 ex.add_note(f"Got type '{getFullyQualifiedName(text)}'.") 

116 raise ex 

117 elif text == "": 

118 raise ValueError(f"Parameter '{parameterName}' is empty.") 

119 

120 if email is not None and not isinstance(email, str): 

121 ex = TypeError("Parameter 'email' is not of type 'str'.") 

122 ex.add_note(f"Got type '{getFullyQualifiedName(email)}'.") 

123 raise ex 

124 elif email is not None and "" in email.partition("@"): 

125 ex = ValueError("Parameter 'email' isn't of the form 'local@domain'.") 

126 ex.add_note(f"Got value '{email}'.") 

127 raise ex 

128 

129 self._userID = userID 

130 self._name = name 

131 self._email = email 

132 

133 @readonly 

134 def UserID(self) -> str: 

135 """ 

136 Read-only property to access the person's user ID (:attr:`_userID`). 

137 

138 :returns: The user ID, unique among persons. 

139 """ 

140 return self._userID 

141 

142 @readonly 

143 def Name(self) -> str: 

144 """ 

145 Read-only property to access the person's name (:attr:`_name`). 

146 

147 :returns: The name. 

148 """ 

149 return self._name 

150 

151 @readonly 

152 def Email(self) -> Nullable[str]: 

153 """ 

154 Read-only property to access the person's e-mail address (:attr:`_email`). 

155 

156 :returns: The e-mail address, or ``None`` if unknown. 

157 """ 

158 return self._email 

159 

160 def __repr__(self) -> str: 

161 """ 

162 Return a representation of the person. 

163 

164 :returns: The user ID, the name and the e-mail address, if known. 

165 """ 

166 return f"<Person {self._userID}: {self._name}{'' if self._email is None else f' <{self._email}>'}>" 

167