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
« 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
11__all__ = ['NamedValues']
14class NamedValues(object):
15 """Create named values object.
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.
21 |NamedValues| objects are immutable and duck-type Python
22 :class:`dict` object mapping ID to name and vice-versa.
24 Parameters
25 ----------
26 *args: variable number of two-element :py:class:`tuple`
28 name: :py:class:`str`
29 Value label
31 value: :py:class:`int`
32 Numeric value
34 Keyword Args
35 ------------
36 name: :py:class:`str`
37 Value label
39 value: :py:class:`int`
40 Numeric value
42 Examples
43 --------
45 .. code-block:: pycon
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 = {}
59 anonymousNames = []
61 for namedValue in args:
62 if isinstance(namedValue, (tuple, list)):
63 try:
64 name, number = namedValue
66 except ValueError:
67 raise error.PyAsn1Error('Not a proper attribute-value pair %r' % (namedValue,))
69 else:
70 anonymousNames.append(namedValue)
71 continue
73 if name in self.__names:
74 raise error.PyAsn1Error('Duplicate name %s' % (name,))
76 if number in self.__numbers:
77 raise error.PyAsn1Error('Duplicate number %s=%s' % (name, number))
79 self.__names[name] = number
80 self.__numbers[number] = name
82 for name, number in kwargs.items():
83 if name in self.__names:
84 raise error.PyAsn1Error('Duplicate name %s' % (name,))
86 if number in self.__numbers:
87 raise error.PyAsn1Error('Duplicate number %s=%s' % (name, number))
89 self.__names[name] = number
90 self.__numbers[number] = name
92 if anonymousNames:
94 number = self.__numbers and max(self.__numbers) + 1 or 0
96 for name in anonymousNames:
98 if name in self.__names:
99 raise error.PyAsn1Error('Duplicate name %s' % (name,))
101 self.__names[name] = number
102 self.__numbers[number] = name
104 number += 1
106 def __repr__(self):
107 representation = ', '.join(['%s=%d' % x for x in self.items()])
109 if len(representation) > 64:
110 representation = representation[:32] + '...' + representation[-32:]
112 return '<%s object, enums %s>' % (
113 self.__class__.__name__, representation)
115 def __eq__(self, other):
116 return dict(self) == other
118 def __ne__(self, other):
119 return dict(self) != other
121 def __lt__(self, other):
122 return dict(self) < other
124 def __le__(self, other):
125 return dict(self) <= other
127 def __gt__(self, other):
128 return dict(self) > other
130 def __ge__(self, other):
131 return dict(self) >= other
133 def __hash__(self):
134 return hash(self.items())
136 # Python dict protocol (read-only)
138 def __getitem__(self, key):
139 try:
140 return self.__numbers[key]
142 except KeyError:
143 return self.__names[key]
145 def __len__(self):
146 return len(self.__names)
148 def __contains__(self, key):
149 return key in self.__names or key in self.__numbers
151 def __iter__(self):
152 return iter(self.__names)
154 def values(self):
155 return iter(self.__numbers)
157 def keys(self):
158 return iter(self.__names)
160 def items(self):
161 for name in self.__names:
162 yield name, self.__names[name]
164 # support merging
166 def __add__(self, namedValues):
167 return self.__class__(*tuple(self.items()) + tuple(namedValues.items()))
169 # XXX clone/subtype?
171 def clone(self, *args, **kwargs):
172 new = self.__class__(*args, **kwargs)
173 return self + new
175 # legacy protocol
177 def getName(self, value):
178 if value in self.__numbers:
179 return self.__numbers[value]
181 def getValue(self, name):
182 if name in self.__names:
183 return self.__names[name]
185 def getValues(self, *names):
186 try:
187 return [self.__names[name] for name in names]
189 except KeyError:
190 raise error.PyAsn1Error(
191 'Unknown bit identifier(s): %s' % (set(names).difference(self.__names),)
192 )