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
« 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
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"
46from enum import Enum
47from typing import Any, Hashable, Mapping, Optional as Nullable
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
56@export
57class ReportException(ExceptionBase):
58 """Base-exception of all exceptions raised by pyEDAA.Reports."""
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
74@export
75class Person(KeyValuePairsMixin, metaclass=ExtendedType, slots=True):
76 """
77 A real person: a user ID, a name and an e-mail address.
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 """
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.
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.
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)
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.")
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
129 self._userID = userID
130 self._name = name
131 self._email = email
133 @readonly
134 def UserID(self) -> str:
135 """
136 Read-only property to access the person's user ID (:attr:`_userID`).
138 :returns: The user ID, unique among persons.
139 """
140 return self._userID
142 @readonly
143 def Name(self) -> str:
144 """
145 Read-only property to access the person's name (:attr:`_name`).
147 :returns: The name.
148 """
149 return self._name
151 @readonly
152 def Email(self) -> Nullable[str]:
153 """
154 Read-only property to access the person's e-mail address (:attr:`_email`).
156 :returns: The e-mail address, or ``None`` if unknown.
157 """
158 return self._email
160 def __repr__(self) -> str:
161 """
162 Return a representation of the person.
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}>'}>"