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

68 statements  

« prev     ^ index     » next       coverage.py v7.17.3, created at 2026-11-14 02:26 +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__ = "1.0.0" 

41__keywords__ = [ 

42 "Reports", "Abstract Model", "Data Model", "Unit Testing", "Testcase", "Testsuite", "OSVVM", "XML" 

43] 

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

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

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

47 

48from enum import Enum 

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

50 

51from pyTooling.Common import getFullyQualifiedName 

52from pyTooling.DataModel import KeyValuePairsMixin 

53from pyTooling.Decorators import export, readonly 

54from pyTooling.Exceptions import ExceptionBase 

55from pyTooling.MetaClasses import ExtendedType 

56 

57 

58@export 

59class ReportException(ExceptionBase): 

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

61 

62 

63@export 

64class Severity(Enum): 

65 Unknown = 0 

66 Debug = 5 

67 Verbose = 10 

68 Normal = 20 

69 Info = 25 

70 Warning = 50 

71 CriticalWarning = 55 

72 Error = 60 

73 Fatal = 70 

74 

75 

76@export 

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

78 """ 

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

80 

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

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

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

84 """ 

85 

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

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

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

89 

90 def __init__( 

91 self, 

92 userID: str, 

93 name: str, 

94 email: Nullable[str] = None, 

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

96 ) -> None: 

97 """ 

98 Initialize a person. 

99 

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

101 :param name: The person's name. 

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

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

104 :raises ValueError: If parameter ``userID`` is ``None``. 

105 :raises TypeError: If parameter ``userID`` isn't of type :class:`str`. 

106 :raises ValueError: If parameter ``userID`` is empty. 

107 :raises ValueError: If parameter ``name`` is ``None``. 

108 :raises TypeError: If parameter ``name`` isn't of type :class:`str`. 

109 :raises ValueError: If parameter ``name`` is empty. 

110 :raises TypeError: If parameter ``email`` isn't of type :class:`str`. 

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

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

113 """ 

114 super().__init__(keyValuePairs) 

115 

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

117 if text is None: 

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

119 elif not isinstance(text, str): 

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

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

122 raise ex 

123 elif text == "": 

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

125 

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

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

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

129 raise ex 

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

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

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

133 raise ex 

134 

135 self._userID = userID 

136 self._name = name 

137 self._email = email 

138 

139 @readonly 

140 def UserID(self) -> str: 

141 """ 

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

143 

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

145 """ 

146 return self._userID 

147 

148 @readonly 

149 def Name(self) -> str: 

150 """ 

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

152 

153 :returns: The name. 

154 """ 

155 return self._name 

156 

157 @readonly 

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

159 """ 

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

161 

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

163 """ 

164 return self._email 

165 

166 def __repr__(self) -> str: 

167 """ 

168 Return a representation of the person. 

169 

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

171 """ 

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

173