Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pyasn1/type/namedval.py: 54%

89 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 06:40 +0000

1# 

2# This file is part of pyasn1 software. 

3# 

4# Copyright (c) 2005-2020, Ilya Etingof <etingof@gmail.com> 

5# License: https://pyasn1.readthedocs.io/en/latest/license.html 

6# 

7# ASN.1 named integers 

8# 

9from pyasn1 import error 

10 

11__all__ = ['NamedValues'] 

12 

13 

14class NamedValues(object): 

15 """Create named values object. 

16 

17 The |NamedValues| object represents a collection of string names 

18 associated with numeric IDs. These objects are used for giving 

19 names to otherwise numerical values. 

20 

21 |NamedValues| objects are immutable and duck-type Python 

22 :class:`dict` object mapping ID to name and vice-versa. 

23 

24 Parameters 

25 ---------- 

26 *args: variable number of two-element :py:class:`tuple` 

27 

28 name: :py:class:`str` 

29 Value label 

30 

31 value: :py:class:`int` 

32 Numeric value 

33 

34 Keyword Args 

35 ------------ 

36 name: :py:class:`str` 

37 Value label 

38 

39 value: :py:class:`int` 

40 Numeric value 

41 

42 Examples 

43 -------- 

44 

45 .. code-block:: pycon 

46 

47 >>> nv = NamedValues('a', 'b', ('c', 0), d=1) 

48 >>> nv 

49 >>> {'c': 0, 'd': 1, 'a': 2, 'b': 3} 

50 >>> nv[0] 

51 'c' 

52 >>> nv['a'] 

53 2 

54 """ 

55 def __init__(self, *args, **kwargs): 

56 self.__names = {} 

57 self.__numbers = {} 

58 

59 anonymousNames = [] 

60 

61 for namedValue in args: 

62 if isinstance(namedValue, (tuple, list)): 

63 try: 

64 name, number = namedValue 

65 

66 except ValueError: 

67 raise error.PyAsn1Error('Not a proper attribute-value pair %r' % (namedValue,)) 

68 

69 else: 

70 anonymousNames.append(namedValue) 

71 continue 

72 

73 if name in self.__names: 

74 raise error.PyAsn1Error('Duplicate name %s' % (name,)) 

75 

76 if number in self.__numbers: 

77 raise error.PyAsn1Error('Duplicate number %s=%s' % (name, number)) 

78 

79 self.__names[name] = number 

80 self.__numbers[number] = name 

81 

82 for name, number in kwargs.items(): 

83 if name in self.__names: 

84 raise error.PyAsn1Error('Duplicate name %s' % (name,)) 

85 

86 if number in self.__numbers: 

87 raise error.PyAsn1Error('Duplicate number %s=%s' % (name, number)) 

88 

89 self.__names[name] = number 

90 self.__numbers[number] = name 

91 

92 if anonymousNames: 

93 

94 number = self.__numbers and max(self.__numbers) + 1 or 0 

95 

96 for name in anonymousNames: 

97 

98 if name in self.__names: 

99 raise error.PyAsn1Error('Duplicate name %s' % (name,)) 

100 

101 self.__names[name] = number 

102 self.__numbers[number] = name 

103 

104 number += 1 

105 

106 def __repr__(self): 

107 representation = ', '.join(['%s=%d' % x for x in self.items()]) 

108 

109 if len(representation) > 64: 

110 representation = representation[:32] + '...' + representation[-32:] 

111 

112 return '<%s object, enums %s>' % ( 

113 self.__class__.__name__, representation) 

114 

115 def __eq__(self, other): 

116 return dict(self) == other 

117 

118 def __ne__(self, other): 

119 return dict(self) != other 

120 

121 def __lt__(self, other): 

122 return dict(self) < other 

123 

124 def __le__(self, other): 

125 return dict(self) <= other 

126 

127 def __gt__(self, other): 

128 return dict(self) > other 

129 

130 def __ge__(self, other): 

131 return dict(self) >= other 

132 

133 def __hash__(self): 

134 return hash(self.items()) 

135 

136 # Python dict protocol (read-only) 

137 

138 def __getitem__(self, key): 

139 try: 

140 return self.__numbers[key] 

141 

142 except KeyError: 

143 return self.__names[key] 

144 

145 def __len__(self): 

146 return len(self.__names) 

147 

148 def __contains__(self, key): 

149 return key in self.__names or key in self.__numbers 

150 

151 def __iter__(self): 

152 return iter(self.__names) 

153 

154 def values(self): 

155 return iter(self.__numbers) 

156 

157 def keys(self): 

158 return iter(self.__names) 

159 

160 def items(self): 

161 for name in self.__names: 

162 yield name, self.__names[name] 

163 

164 # support merging 

165 

166 def __add__(self, namedValues): 

167 return self.__class__(*tuple(self.items()) + tuple(namedValues.items())) 

168 

169 # XXX clone/subtype? 

170 

171 def clone(self, *args, **kwargs): 

172 new = self.__class__(*args, **kwargs) 

173 return self + new 

174 

175 # legacy protocol 

176 

177 def getName(self, value): 

178 if value in self.__numbers: 

179 return self.__numbers[value] 

180 

181 def getValue(self, name): 

182 if name in self.__names: 

183 return self.__names[name] 

184 

185 def getValues(self, *names): 

186 try: 

187 return [self.__names[name] for name in names] 

188 

189 except KeyError: 

190 raise error.PyAsn1Error( 

191 'Unknown bit identifier(s): %s' % (set(names).difference(self.__names),) 

192 )