Coverage for pyVHDLModel/Predefined.py: 97%

51 statements  

« prev     ^ index     » next       coverage.py v7.17.0, created at 2026-10-22 19:31 +0000

1# ==================================================================================================================== # 

2# __ ___ _ ____ _ __ __ _ _ # 

3# _ __ _ \ \ / / | | | _ \| | | \/ | ___ __| | ___| | # 

4# | '_ \| | | \ \ / /| |_| | | | | | | |\/| |/ _ \ / _` |/ _ \ | # 

5# | |_) | |_| |\ V / | _ | |_| | |___| | | | (_) | (_| | __/ | # 

6# | .__/ \__, | \_/ |_| |_|____/|_____|_| |_|\___/ \__,_|\___|_| # 

7# |_| |___/ # 

8# ==================================================================================================================== # 

9# Authors: # 

10# Patrick Lehmann # 

11# # 

12# License: # 

13# ==================================================================================================================== # 

14# Copyright 2017-2026 Patrick Lehmann - Boetzingen, Germany # 

15# Copyright 2016-2017 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"""This module contains base-classes for predefined library and package declarations.""" 

33from typing import Iterable, Optional as Nullable 

34 

35from pyTooling.Common import getTypeName 

36from pyTooling.Decorators import export 

37from pyTooling.MetaClasses import ExtendedType, abstractclass 

38 

39from pyVHDLModel import Library, Package, PackageBody, AllPackageMembersReferenceSymbol, PackageMemberReferenceSymbol 

40from pyVHDLModel.Name import SimpleName, SelectedName, AllName 

41from pyVHDLModel.Symbol import LibraryReferenceSymbol, PackageSymbol 

42from pyVHDLModel.DesignUnit import LibraryClause, UseClause 

43 

44 

45@export 

46@abstractclass 

47class PredefinedLibrary(Library): 

48 """ 

49 A base-class for predefined VHDL libraries. 

50 

51 VHDL defines 2 predefined libraries: 

52 

53 * :class:`~pyVHDLModel.STD.Std` 

54 * :class:`~pyVHDLModel.IEEE.Ieee` 

55 

56 .. seealso:: 

57 

58 * :class:`Ieee <pyVHDLModel.IEEE.Ieee>` 

59 * :class:`Std <pyVHDLModel.STD.Std>` 

60 """ 

61 

62 def __init__(self, packages, documentation: Nullable[str] = None) -> None: 

63 """ 

64 Initializes a predefined library. 

65 

66 :param packages: Dictionary of all packages defined in a library. 

67 :param documentation: Documentation of this library, if the caller has one to supply. VHDL defines 

68 none for a predefined library, so it is empty unless supplied from outside. 

69 """ 

70 super().__init__(getTypeName(self), documentation) 

71 

72 self.AddPackages(packages) 

73 

74 def AddPackages(self, packages) -> None: 

75 for packageType, packageBodyType in packages: 

76 package: Package = packageType() 

77 package.Library = self 

78 self._packages[package.NormalizedIdentifier] = package 

79 

80 if packageBodyType is not None: 

81 packageBody: PackageBody = packageBodyType() 

82 packageBody.Library = self 

83 self._packageBodies[packageBody.NormalizedIdentifier] = packageBody 

84 

85 

86@export 

87class PredefinedPackageMixin( 

88 metaclass=ExtendedType, 

89 mixin=True, 

90 expects=("AddContextItem",) 

91): 

92 """ 

93 A mixin-class for predefined VHDL packages and package bodies. 

94 

95 The host class provides ``AddContextItem(contextItem)``, called to add a library clause or a use clause. 

96 

97 .. seealso:: 

98 

99 * :class:`Predefined package <pyVHDLModel.Predefined.PredefinedPackage>` 

100 * :class:`Predefined package body <pyVHDLModel.Predefined.PredefinedPackageBody>` 

101 """ 

102 

103 def _AddLibraryClause(self, libraries: Iterable[str]) -> None: 

104 symbols = [LibraryReferenceSymbol(SimpleName(libName)) for libName in libraries] 

105 libraryClause = LibraryClause(symbols) 

106 

107 self.AddContextItem(libraryClause) 

108 

109 def _AddPackageClause(self, packages: Iterable[str]) -> None: 

110 symbols = [] 

111 for qualifiedPackageName in packages: 

112 libName, packName, members = qualifiedPackageName.split(".") 

113 

114 packageName = SelectedName(packName, SimpleName(libName)) 

115 if members.lower() == "all": 115 ↛ 118line 115 didn't jump to line 118 because the condition on line 115 was always true

116 symbols.append(AllPackageMembersReferenceSymbol(AllName(packageName))) 

117 else: 

118 symbols.append(PackageMemberReferenceSymbol(SelectedName(members, packageName))) 

119 

120 useClause = UseClause(symbols) 

121 self.AddContextItem(useClause) 

122 

123 

124@export 

125@abstractclass 

126class PredefinedPackage(Package, PredefinedPackageMixin): 

127 """ 

128 A base-class for predefined VHDL packages. 

129 """ 

130 

131 def __init__(self, identifier: Nullable[str] = None) -> None: 

132 """ 

133 Initializes a predefined package. 

134 

135 By default the VHDL package name is the Python class name. Pass ``identifier`` when the two must 

136 differ - e.g. when two vendor flavors of the same VHDL package need distinct Python classes. 

137 

138 :param identifier: The VHDL package name, or ``None`` to use the class name. 

139 """ 

140 super().__init__(getTypeName(self) if identifier is None else identifier) 

141 

142 

143@export 

144@abstractclass 

145class PredefinedPackageBody(PackageBody, PredefinedPackageMixin): 

146 """ 

147 A base-class for predefined VHDL package bodies. 

148 """ 

149 

150 def __init__(self, packageIdentifier: Nullable[str] = None) -> None: 

151 """ 

152 Initializes a predefined package body. 

153 

154 By default the VHDL package name is the Python class name with the trailing ``_Body`` removed. 

155 Pass ``packageIdentifier`` when the two must differ. 

156 

157 :param packageIdentifier: The VHDL name of the package this body implements, or ``None`` to derive 

158 it from the class name. 

159 """ 

160 identifier = getTypeName(self)[:-5] if packageIdentifier is None else packageIdentifier 

161 packageSymbol = PackageSymbol(SimpleName(identifier)) 

162 super().__init__(packageSymbol)