1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
# ==================================================================================================================== #
# _____ ____ _ _ ____ _ #
# _ __ _ _| ____| _ \ / \ / \ | _ \ ___ _ __ ___ _ __| |_ ___ #
# | '_ \| | | | _| | | | |/ _ \ / _ \ | |_) / _ \ '_ \ / _ \| '__| __/ __| #
# | |_) | |_| | |___| |_| / ___ \ / ___ \ _| _ < __/ |_) | (_) | | | |_\__ \ #
# | .__/ \__, |_____|____/_/ \_\/_/ \_(_)_| \_\___| .__/ \___/|_| \__|___/ #
# |_| |___/ |_| #
# ==================================================================================================================== #
# Authors: #
# Patrick Lehmann #
# #
# License: #
# ==================================================================================================================== #
# Copyright 2021-2026 Electronic Design Automation Abstraction (EDA²) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. #
# You may obtain a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
# #
# SPDX-License-Identifier: Apache-2.0 #
# ==================================================================================================================== #
#
"""
Various report abstract data models and report format converters.
"""
from __future__ import annotations
__author__ = "Patrick Lehmann"
__email__ = "Paebbels@gmail.com"
__copyright__ = "2021-2026, Electronic Design Automation Abstraction (EDA²)"
__license__ = "Apache License, Version 2.0"
__version__ = "0.20.0rc4"
__keywords__ = ["Reports", "Abstract Model", "Data Model", "Unit Testing", "Testcase", "Testsuite", "OSVVM", "YAML", "XML"]
__project_url__ = "https://github.com/edaa-org/pyEDAA.Reports"
__documentation_url__ = "https://edaa-org.github.io/pyEDAA.Reports"
__issue_tracker_url__ = "https://GitHub.com/edaa-org/pyEDAA.Reports/issues"
from enum import Enum
from typing import Any, Hashable, Mapping, Optional as Nullable
from pyTooling.Common import getFullyQualifiedName
from pyTooling.DataModel import KeyValuePairsMixin
from pyTooling.Decorators import export, readonly
from pyTooling.Exceptions import ExceptionBase
from pyTooling.MetaClasses import ExtendedType
@export
class ReportException(ExceptionBase):
"""Base-exception of all exceptions raised by pyEDAA.Reports."""
@export
class Severity(Enum):
Unknown = 0
Debug = 5
Verbose = 10
Normal = 20
Info = 25
Warning = 50
CriticalWarning = 55
Error = 60
Fatal = 70
@export
class Person(KeyValuePairsMixin, metaclass=ExtendedType, slots=True):
"""
A real person: a user ID, a name and an e-mail address.
A person belongs to no single data model: a root registers the persons it refers to, and the same person may be
registered in several roots, e.g. as the author of requirements and as the owner of risks. The role a person acts in,
e.g. a reviewer, is a persona of the requirements model.
"""
_userID: str #: The person's user ID, unique among persons.
_name: str #: The person's name.
_email: Nullable[str] #: The person's e-mail address, if known.
def __init__(
self,
userID: str,
name: str,
email: Nullable[str] = None,
keyValuePairs: Nullable[Mapping[Hashable, Any]] = None
) -> None:
"""
Initialize a person.
:param userID: The person's user ID, e.g. ``paebbels``.
:param name: The person's name.
:param email: Optional, the person's e-mail address. Default: ``None``.
:param keyValuePairs: Optional, the key-value pairs. Default: ``None``.
:raises TypeError: If parameter ``keyValuePairs`` isn't a mapping.
:raises ValueError: If parameter ``userID`` or ``name`` is ``None``.
:raises TypeError: If parameter ``userID``, ``name`` or ``email`` isn't of type :class:`str`.
:raises ValueError: If parameter ``userID`` or ``name`` is empty.
:raises ValueError: If parameter ``email`` isn't of the form ``local@domain``.
"""
super().__init__(keyValuePairs)
for parameterName, text in (("userID", userID), ("name", name)):
if text is None:
raise ValueError(f"Parameter '{parameterName}' is None.")
elif not isinstance(text, str):
ex = TypeError(f"Parameter '{parameterName}' is not of type 'str'.")
ex.add_note(f"Got type '{getFullyQualifiedName(text)}'.")
raise ex
elif text == "":
raise ValueError(f"Parameter '{parameterName}' is empty.")
if email is not None and not isinstance(email, str):
ex = TypeError("Parameter 'email' is not of type 'str'.")
ex.add_note(f"Got type '{getFullyQualifiedName(email)}'.")
raise ex
elif email is not None and "" in email.partition("@"):
ex = ValueError("Parameter 'email' isn't of the form 'local@domain'.")
ex.add_note(f"Got value '{email}'.")
raise ex
self._userID = userID
self._name = name
self._email = email
@readonly
def UserID(self) -> str:
"""
Read-only property to access the person's user ID (:attr:`_userID`).
:returns: The user ID, unique among persons.
"""
return self._userID
@readonly
def Name(self) -> str:
"""
Read-only property to access the person's name (:attr:`_name`).
:returns: The name.
"""
return self._name
@readonly
def Email(self) -> Nullable[str]:
"""
Read-only property to access the person's e-mail address (:attr:`_email`).
:returns: The e-mail address, or ``None`` if unknown.
"""
return self._email
def __repr__(self) -> str:
"""
Return a representation of the person.
:returns: The user ID, the name and the e-mail address, if known.
"""
return f"<Person {self._userID}: {self._name}{'' if self._email is None else f' <{self._email}>'}>"
|