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
« 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
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"
48from enum import Enum
49from typing import Any, Hashable, Mapping, Optional as Nullable
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
58@export
59class ReportException(ExceptionBase):
60 """Base-exception of all exceptions raised by pyEDAA.Reports."""
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
76@export
77class Person(KeyValuePairsMixin, metaclass=ExtendedType, slots=True):
78 """
79 A real person: a user ID, a name and an e-mail address.
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 """
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.
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.
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)
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.")
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
135 self._userID = userID
136 self._name = name
137 self._email = email
139 @readonly
140 def UserID(self) -> str:
141 """
142 Read-only property to access the person's user ID (:attr:`_userID`).
144 :returns: The user ID, unique among persons.
145 """
146 return self._userID
148 @readonly
149 def Name(self) -> str:
150 """
151 Read-only property to access the person's name (:attr:`_name`).
153 :returns: The name.
154 """
155 return self._name
157 @readonly
158 def Email(self) -> Nullable[str]:
159 """
160 Read-only property to access the person's e-mail address (:attr:`_email`).
162 :returns: The e-mail address, or ``None`` if unknown.
163 """
164 return self._email
166 def __repr__(self) -> str:
167 """
168 Return a representation of the person.
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}>'}>"