Coverage for pyEDAA/IPXACT/__init__.py: 69%
142 statements
« prev ^ index » next coverage.py v7.6.7, created at 2024-11-17 01:13 +0000
« prev ^ index » next coverage.py v7.6.7, created at 2024-11-17 01:13 +0000
1# ==================================================================================================================== #
2# _____ ____ _ _ ___ ______ __ _ ____ _____ #
3# _ __ _ _| ____| _ \ / \ / \ |_ _| _ \ \/ / / \ / ___|_ _| #
4# | '_ \| | | | _| | | | |/ _ \ / _ \ | || |_) \ / / _ \| | | | #
5# | |_) | |_| | |___| |_| / ___ \ / ___ \ _ | || __// \ / ___ \ |___ | | #
6# | .__/ \__, |_____|____/_/ \_\/_/ \_(_)___|_| /_/\_\/_/ \_\____| |_| #
7# |_| |___/ #
8# ==================================================================================================================== #
9# Authors: #
10# Patrick Lehmann #
11# #
12# License: #
13# ==================================================================================================================== #
14# Copyright 2017-2024 Patrick Lehmann - Bötzingen, Germany #
15# Copyright 2016-2016 Patrick Lehmann - Dresden, Germany #
16# #
17# Licensed under the Apache License, Version 2.0 (the "License"); #
18# you may not use this file except in compliance with the License. #
19# You may obtain a copy of the License at #
20# #
21# http://www.apache.org/licenses/LICENSE-2.0 #
22# #
23# Unless required by applicable law or agreed to in writing, software #
24# distributed under the License is distributed on an "AS IS" BASIS, #
25# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
26# See the License for the specific language governing permissions and #
27# limitations under the License. #
28# #
29# SPDX-License-Identifier: Apache-2.0 #
30# ==================================================================================================================== #
31#
32"""A DOM based IP-XACT implementation for Python."""
33from pathlib import Path
34from sys import version_info
35from textwrap import dedent
36from typing import Union, Dict
38from pyTooling.Decorators import export, readonly
39from pyTooling.Common import getResourceFile, getFullyQualifiedName
40from pyTooling.Versioning import SemanticVersion, CalendarVersion
42from . import Schema
45__author__ = "Patrick Lehmann"
46__email__ = "Paebbels@gmail.com"
47__copyright__ = "2016-2024, Patrick Lehmann"
48__license__ = "Apache License, Version 2.0"
49__version__ = "0.4.0"
52@export
53class IpxactSchema:
54 """Schema descriptor made of version, namespace prefix, URI, URL and local path."""
56 _version: Union[SemanticVersion, CalendarVersion] #: Schema version
57 _namespacePrefix: str #: XML namespace prefix
58 _schemaUri: str #: Schema URI
59 _schemaUrl: str #: Schema URL
60 _localPath: Path #: Local path
62 def __init__(
63 self,
64 version: Union[str, SemanticVersion, CalendarVersion],
65 xmlNamespacePrefix: str,
66 schemaUri: str,
67 schemaUrl: str,
68 localPath: Path
69 ) -> None:
70 """
71 Initializes an IP-XACT Schema description.
73 :param version: Version of the IP-XACT Schema.
74 :param xmlNamespacePrefix: XML namespace prefix (``<prefix:element>``)
75 :param schemaUri: IP-XACT schema URI
76 :param schemaUrl: URL the IP-XACT schema definition file (XSD).
77 :param localPath: Path to the local XSD file.
78 """
80 if version is None: 80 ↛ 81line 80 didn't jump to line 81 because the condition on line 80 was never true
81 raise ValueError(f"Parameter 'version' is None.")
82 elif isinstance(version, str): 82 ↛ 87line 82 didn't jump to line 87 because the condition on line 82 was always true
83 if version.startswith("20"):
84 self._version = CalendarVersion.Parse(version)
85 else:
86 self._version = SemanticVersion.Parse(version)
87 elif isinstance(version, (SemanticVersion, CalendarVersion)):
88 self._version = version
89 else:
90 ex = TypeError(f"Parameter 'version' is neither a 'SemanticVersion', a 'CalendarVersion' nor a string.")
91 if version_info >= (3, 11): # pragma: no cover
92 ex.add_note(f"Got type '{getFullyQualifiedName(version)}'.")
93 raise ex
95 if xmlNamespacePrefix is None: 95 ↛ 96line 95 didn't jump to line 96 because the condition on line 95 was never true
96 raise ValueError(f"Parameter 'namespacePrefix' is None.")
97 elif not isinstance(xmlNamespacePrefix, str): 97 ↛ 98line 97 didn't jump to line 98 because the condition on line 97 was never true
98 ex = TypeError(f"Parameter 'namespacePrefix' is not a string.")
99 if version_info >= (3, 11): # pragma: no cover
100 ex.add_note(f"Got type '{getFullyQualifiedName(version)}'.")
101 raise ex
103 if schemaUri is None: 103 ↛ 104line 103 didn't jump to line 104 because the condition on line 103 was never true
104 raise ValueError(f"Parameter 'schemaUri' is None.")
105 elif not isinstance(schemaUri, str): 105 ↛ 106line 105 didn't jump to line 106 because the condition on line 105 was never true
106 ex = TypeError(f"Parameter 'schemaUri' is not a string.")
107 if version_info >= (3, 11): # pragma: no cover
108 ex.add_note(f"Got type '{getFullyQualifiedName(schemaUri)}'.")
109 raise ex
111 if schemaUrl is None: 111 ↛ 112line 111 didn't jump to line 112 because the condition on line 111 was never true
112 raise ValueError(f"Parameter 'schemaUrl' is None.")
113 elif not isinstance(schemaUrl, str): 113 ↛ 114line 113 didn't jump to line 114 because the condition on line 113 was never true
114 ex = TypeError(f"Parameter 'schemaUrl' is not a string.")
115 if version_info >= (3, 11): # pragma: no cover
116 ex.add_note(f"Got type '{getFullyQualifiedName(schemaUrl)}'.")
117 raise ex
119 if localPath is None: 119 ↛ 120line 119 didn't jump to line 120 because the condition on line 119 was never true
120 raise ValueError(f"Parameter 'localPath' is None.")
121 elif not isinstance(localPath, Path): 121 ↛ 122line 121 didn't jump to line 122 because the condition on line 121 was never true
122 ex = TypeError(f"Parameter 'localPath' is not a Path.")
123 if version_info >= (3, 11): # pragma: no cover
124 ex.add_note(f"Got type '{getFullyQualifiedName(localPath)}'.")
125 raise ex
127 self._namespacePrefix = xmlNamespacePrefix
128 self._schemaUri = schemaUri
129 self._schemaUrl = schemaUrl
130 self._localPath = localPath
132 @readonly
133 def Version(self) -> Union[SemanticVersion, CalendarVersion]:
134 return self._version
136 @readonly
137 def NamespacePrefix(self) -> str:
138 return self._namespacePrefix
140 @readonly
141 def SchemaUri(self) -> str:
142 return self._schemaUri
144 @readonly
145 def SchemaUrl(self) -> str:
146 return self._schemaUrl
148 @readonly
149 def LocalPath(self) -> Path:
150 return self._localPath
153# version, xmlns, URI URL, Local Path
154_IPXACT_10 = IpxactSchema("1.0", "spirit", "http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.0", "", getResourceFile(Schema, "ipxact-1.0/index.xsd"))
155_IPXACT_11 = IpxactSchema("1.1", "spirit", "http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.1", "", getResourceFile(Schema, "ipxact-1.1/index.xsd"))
156_IPXACT_12 = IpxactSchema("1.2", "spirit", "http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.2", "", getResourceFile(Schema, "ipxact-1.2/index.xsd"))
157_IPXACT_14 = IpxactSchema("1.4", "spirit", "http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4", "", getResourceFile(Schema, "ipxact-1.4/index.xsd"))
158_IPXACT_15 = IpxactSchema("1.5", "spirit", "http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.5", "", getResourceFile(Schema, "ipxact-1.5/index.xsd"))
159_IPXACT_2009 = IpxactSchema("2009", "spirit", "http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009", "", getResourceFile(Schema, "ieee-1685-2009/index.xsd"))
160_IPXACT_2014 = IpxactSchema("2014", "ipxact", "http://www.accellera.org/XMLSchema/IPXACT/1685-2014", "http://www.accellera.org/XMLSchema/IPXACT/1685-2014/index.xsd", getResourceFile(Schema, "ieee-1685-2014/index.xsd"))
161_IPXACT_2022 = IpxactSchema("2022", "ipxact", "http://www.accellera.org/XMLSchema/IPXACT/1685-2022", "http://www.accellera.org/XMLSchema/IPXACT/1685-2022/index.xsd", getResourceFile(Schema, "ieee-1685-2022/index.xsd"))
163__VERSION_TABLE__: Dict[str, IpxactSchema] = {
164 '1.0': _IPXACT_10,
165 '1.1': _IPXACT_11,
166 '1.4': _IPXACT_14,
167 '1.5': _IPXACT_15,
168 '2009': _IPXACT_2009,
169 '2014': _IPXACT_2014,
170 '2022': _IPXACT_2022
171} #: Dictionary of all IP-XACT versions mapping to :class:`IpxactSchema` instances.
173__URI_MAP__: Dict[str, IpxactSchema] = {value.SchemaUri: value for key, value in __VERSION_TABLE__.items()} #: Mapping from schema URIs to :class:`IpxactSchema` instances.
175__DEFAULT_VERSION__ = "2022" #: IP-XACT default version
176__DEFAULT_SCHEMA__ = __VERSION_TABLE__[__DEFAULT_VERSION__] #: IP-XACT default Schema
179@export
180class Vlnv:
181 """VLNV data structure (Vendor, Library, Name, Version) as a unique identifier in IP-XACT."""
183 _vendor: str #: Vendor name in a VLNV unique identifier
184 _library: str #: Library name in a VLNV unique identifier
185 _name: str #: Component name in a VLNV unique identifier
186 _version: SemanticVersion #: Version in a VLNV unique identifier
188 def __init__(self, vendor: str, library: str, name: str, version: Union[str, SemanticVersion]) -> None:
189 """
190 Initializes the VLNV data structure.
192 :param vendor: Vendor name in a VLNV unique identifier
193 :param library: Library name in a VLNV unique identifier
194 :param name: Component name in a VLNV unique identifier
195 :param version: Version in a VLNV unique identifier
196 """
198 if vendor is None: 198 ↛ 199line 198 didn't jump to line 199 because the condition on line 198 was never true
199 raise ValueError(f"Parameter 'vendor' is None.")
200 elif not isinstance(vendor, str): 200 ↛ 201line 200 didn't jump to line 201 because the condition on line 200 was never true
201 ex = TypeError(f"Parameter 'vendor' is not a string.")
202 if version_info >= (3, 11): # pragma: no cover
203 ex.add_note(f"Got type '{getFullyQualifiedName(vendor)}'.")
204 raise ex
206 if library is None: 206 ↛ 207line 206 didn't jump to line 207 because the condition on line 206 was never true
207 raise ValueError(f"Parameter 'library' is None.")
208 elif not isinstance(library, str): 208 ↛ 209line 208 didn't jump to line 209 because the condition on line 208 was never true
209 ex = TypeError(f"Parameter 'library' is not a string.")
210 if version_info >= (3, 11): # pragma: no cover
211 ex.add_note(f"Got type '{getFullyQualifiedName(library)}'.")
212 raise ex
214 if name is None: 214 ↛ 215line 214 didn't jump to line 215 because the condition on line 214 was never true
215 raise ValueError(f"Parameter 'name' is None.")
216 elif not isinstance(name, str): 216 ↛ 217line 216 didn't jump to line 217 because the condition on line 216 was never true
217 ex = TypeError(f"Parameter 'name' is not a string.")
218 if version_info >= (3, 11): # pragma: no cover
219 ex.add_note(f"Got type '{getFullyQualifiedName(name)}'.")
220 raise ex
222 if version is None: 222 ↛ 223line 222 didn't jump to line 223 because the condition on line 222 was never true
223 raise ValueError(f"Parameter 'version' is None.")
224 elif isinstance(version, str):
225 self._version = SemanticVersion.Parse(version)
226 elif isinstance(version, SemanticVersion): 226 ↛ 229line 226 didn't jump to line 229 because the condition on line 226 was always true
227 self._version = version
228 else:
229 ex = TypeError(f"Parameter 'version' is neither a 'SemanticVersion' nor a string.")
230 if version_info >= (3, 11): # pragma: no cover
231 ex.add_note(f"Got type '{getFullyQualifiedName(version)}'.")
232 raise ex
234 self._vendor = vendor
235 self._library = library
236 self._name = name
238 @readonly
239 def Vendor(self) -> str:
240 return self._vendor
242 @readonly
243 def Library(self) -> str:
244 return self._library
246 @readonly
247 def Name(self) -> str:
248 return self._name
250 @readonly
251 def Version(self) -> SemanticVersion:
252 return self._version
254 def ToXml(self, indent=1, isVersionedIdentifier=False):
255 """Converts the object's data into XML format."""
257 if isVersionedIdentifier:
258 buffer = dedent("""\
259 {indent}<{xmlns}:vendor>{vendor}</{xmlns}:vendor>
260 {indent}<{xmlns}:library>{library}</{xmlns}:library>
261 {indent}<{xmlns}:name>{name}</{xmlns}:name>
262 {indent}<{xmlns}:version>{version}</{xmlns}:version>\
263 """)
264 else:
265 buffer = """{indent}<{xmlns}:vlnv vendor="{vendor}" library="{library}" name="{name}" version="{version}"/>"""
267 return buffer.format(indent= "\t" *indent, xmlns=__DEFAULT_SCHEMA__.NamespacePrefix, vendor=self._vendor, library=self._library, name=self._name, version=self._version)
270@export
271class RootElement:
272 """Base-class for all IP-XACT data classes."""
274 _vlnv: Vlnv #: VLNV unique identifier.
276 def __init__(self, vlnv: Vlnv) -> None:
277 """
278 Initializes the RootElement with an VLNV field for all derives classes.
280 :param vlnv: VLNV unique identifier.
281 """
282 self._vlnv = vlnv
284 @classmethod
285 def FromFile(cls, file):
286 pass
289@export
290class PyIpxactException(Exception):
291 """Base-exception for all exceptions in this package."""