Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

namedval.py 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #
  2. # This file is part of pyasn1 software.
  3. #
  4. # Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
  5. # License: http://snmplabs.com/pyasn1/license.html
  6. #
  7. # ASN.1 named integers
  8. #
  9. from pyasn1 import error
  10. __all__ = ['NamedValues']
  11. class NamedValues(object):
  12. """Create named values object.
  13. The |NamedValues| object represents a collection of string names
  14. associated with numeric IDs. These objects are used for giving
  15. names to otherwise numerical values.
  16. |NamedValues| objects are immutable and duck-type Python
  17. :class:`dict` object mapping ID to name and vice-versa.
  18. Parameters
  19. ----------
  20. \*args: variable number of two-element :py:class:`tuple`
  21. name: :py:class:`str`
  22. Value label
  23. value: :py:class:`int`
  24. Numeric value
  25. Keyword Args
  26. ------------
  27. name: :py:class:`str`
  28. Value label
  29. value: :py:class:`int`
  30. Numeric value
  31. Examples
  32. --------
  33. .. code-block:: pycon
  34. >>> nv = NamedValues('a', 'b', ('c', 0), d=1)
  35. >>> nv
  36. >>> {'c': 0, 'd': 1, 'a': 2, 'b': 3}
  37. >>> nv[0]
  38. 'c'
  39. >>> nv['a']
  40. 2
  41. """
  42. def __init__(self, *args, **kwargs):
  43. self.__names = {}
  44. self.__numbers = {}
  45. anonymousNames = []
  46. for namedValue in args:
  47. if isinstance(namedValue, (tuple, list)):
  48. try:
  49. name, number = namedValue
  50. except ValueError:
  51. raise error.PyAsn1Error('Not a proper attribute-value pair %r' % (namedValue,))
  52. else:
  53. anonymousNames.append(namedValue)
  54. continue
  55. if name in self.__names:
  56. raise error.PyAsn1Error('Duplicate name %s' % (name,))
  57. if number in self.__numbers:
  58. raise error.PyAsn1Error('Duplicate number %s=%s' % (name, number))
  59. self.__names[name] = number
  60. self.__numbers[number] = name
  61. for name, number in kwargs.items():
  62. if name in self.__names:
  63. raise error.PyAsn1Error('Duplicate name %s' % (name,))
  64. if number in self.__numbers:
  65. raise error.PyAsn1Error('Duplicate number %s=%s' % (name, number))
  66. self.__names[name] = number
  67. self.__numbers[number] = name
  68. if anonymousNames:
  69. number = self.__numbers and max(self.__numbers) + 1 or 0
  70. for name in anonymousNames:
  71. if name in self.__names:
  72. raise error.PyAsn1Error('Duplicate name %s' % (name,))
  73. self.__names[name] = number
  74. self.__numbers[number] = name
  75. number += 1
  76. def __repr__(self):
  77. representation = ', '.join(['%s=%d' % x for x in self.items()])
  78. if len(representation) > 64:
  79. representation = representation[:32] + '...' + representation[-32:]
  80. return '<%s object 0x%x enums %s>' % (self.__class__.__name__, id(self), representation)
  81. def __eq__(self, other):
  82. return dict(self) == other
  83. def __ne__(self, other):
  84. return dict(self) != other
  85. def __lt__(self, other):
  86. return dict(self) < other
  87. def __le__(self, other):
  88. return dict(self) <= other
  89. def __gt__(self, other):
  90. return dict(self) > other
  91. def __ge__(self, other):
  92. return dict(self) >= other
  93. def __hash__(self):
  94. return hash(self.items())
  95. # Python dict protocol (read-only)
  96. def __getitem__(self, key):
  97. try:
  98. return self.__numbers[key]
  99. except KeyError:
  100. return self.__names[key]
  101. def __len__(self):
  102. return len(self.__names)
  103. def __contains__(self, key):
  104. return key in self.__names or key in self.__numbers
  105. def __iter__(self):
  106. return iter(self.__names)
  107. def values(self):
  108. return iter(self.__numbers)
  109. def keys(self):
  110. return iter(self.__names)
  111. def items(self):
  112. for name in self.__names:
  113. yield name, self.__names[name]
  114. # support merging
  115. def __add__(self, namedValues):
  116. return self.__class__(*tuple(self.items()) + tuple(namedValues.items()))
  117. # XXX clone/subtype?
  118. def clone(self, *args, **kwargs):
  119. new = self.__class__(*args, **kwargs)
  120. return self + new
  121. # legacy protocol
  122. def getName(self, value):
  123. if value in self.__numbers:
  124. return self.__numbers[value]
  125. def getValue(self, name):
  126. if name in self.__names:
  127. return self.__names[name]
  128. def getValues(self, *names):
  129. try:
  130. return [self.__names[name] for name in names]
  131. except KeyError:
  132. raise error.PyAsn1Error(
  133. 'Unknown bit identifier(s): %s' % (set(names).difference(self.__names),)
  134. )