Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pyasn1/type/univ.py: 38%
1263 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:45 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:45 +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#
7import math
8import sys
10from pyasn1 import error
11from pyasn1.codec.ber import eoo
12from pyasn1.compat import integer
13from pyasn1.compat import octets
14from pyasn1.type import base
15from pyasn1.type import constraint
16from pyasn1.type import namedtype
17from pyasn1.type import namedval
18from pyasn1.type import tag
19from pyasn1.type import tagmap
21NoValue = base.NoValue
22noValue = NoValue()
24__all__ = ['Integer', 'Boolean', 'BitString', 'OctetString', 'Null',
25 'ObjectIdentifier', 'Real', 'Enumerated',
26 'SequenceOfAndSetOfBase', 'SequenceOf', 'SetOf',
27 'SequenceAndSetBase', 'Sequence', 'Set', 'Choice', 'Any',
28 'NoValue', 'noValue']
30# "Simple" ASN.1 types (yet incomplete)
33class Integer(base.SimpleAsn1Type):
34 """Create |ASN.1| schema or value object.
36 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its
37 objects are immutable and duck-type Python :class:`int` objects.
39 Keyword Args
40 ------------
41 value: :class:`int`, :class:`str` or |ASN.1| object
42 Python :class:`int` or :class:`str` literal or |ASN.1| class
43 instance. If `value` is not given, schema object will be created.
45 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
46 Object representing non-default ASN.1 tag(s)
48 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
49 Object representing non-default ASN.1 subtype constraint(s). Constraints
50 verification for |ASN.1| type occurs automatically on object
51 instantiation.
53 namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
54 Object representing non-default symbolic aliases for numbers
56 Raises
57 ------
58 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
59 On constraint violation or bad initializer.
61 Examples
62 --------
64 .. code-block:: python
66 class ErrorCode(Integer):
67 '''
68 ASN.1 specification:
70 ErrorCode ::=
71 INTEGER { disk-full(1), no-disk(-1),
72 disk-not-formatted(2) }
74 error ErrorCode ::= disk-full
75 '''
76 namedValues = NamedValues(
77 ('disk-full', 1), ('no-disk', -1),
78 ('disk-not-formatted', 2)
79 )
81 error = ErrorCode('disk-full')
82 """
83 #: Set (on class, not on instance) or return a
84 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
85 #: associated with |ASN.1| type.
86 tagSet = tag.initTagSet(
87 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x02)
88 )
90 #: Set (on class, not on instance) or return a
91 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
92 #: imposing constraints on |ASN.1| type initialization values.
93 subtypeSpec = constraint.ConstraintsIntersection()
95 #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
96 #: representing symbolic aliases for numbers
97 namedValues = namedval.NamedValues()
99 # Optimization for faster codec lookup
100 typeId = base.SimpleAsn1Type.getTypeId()
102 def __init__(self, value=noValue, **kwargs):
103 if 'namedValues' not in kwargs:
104 kwargs['namedValues'] = self.namedValues
106 base.SimpleAsn1Type.__init__(self, value, **kwargs)
108 def __and__(self, value):
109 return self.clone(self._value & value)
111 def __rand__(self, value):
112 return self.clone(value & self._value)
114 def __or__(self, value):
115 return self.clone(self._value | value)
117 def __ror__(self, value):
118 return self.clone(value | self._value)
120 def __xor__(self, value):
121 return self.clone(self._value ^ value)
123 def __rxor__(self, value):
124 return self.clone(value ^ self._value)
126 def __lshift__(self, value):
127 return self.clone(self._value << value)
129 def __rshift__(self, value):
130 return self.clone(self._value >> value)
132 def __add__(self, value):
133 return self.clone(self._value + value)
135 def __radd__(self, value):
136 return self.clone(value + self._value)
138 def __sub__(self, value):
139 return self.clone(self._value - value)
141 def __rsub__(self, value):
142 return self.clone(value - self._value)
144 def __mul__(self, value):
145 return self.clone(self._value * value)
147 def __rmul__(self, value):
148 return self.clone(value * self._value)
150 def __mod__(self, value):
151 return self.clone(self._value % value)
153 def __rmod__(self, value):
154 return self.clone(value % self._value)
156 def __pow__(self, value, modulo=None):
157 return self.clone(pow(self._value, value, modulo))
159 def __rpow__(self, value):
160 return self.clone(pow(value, self._value))
162 def __floordiv__(self, value):
163 return self.clone(self._value // value)
165 def __rfloordiv__(self, value):
166 return self.clone(value // self._value)
168 if sys.version_info[0] <= 2:
169 def __div__(self, value):
170 if isinstance(value, float):
171 return Real(self._value / value)
172 else:
173 return self.clone(self._value / value)
175 def __rdiv__(self, value):
176 if isinstance(value, float):
177 return Real(value / self._value)
178 else:
179 return self.clone(value / self._value)
180 else:
181 def __truediv__(self, value):
182 return Real(self._value / value)
184 def __rtruediv__(self, value):
185 return Real(value / self._value)
187 def __divmod__(self, value):
188 return self.clone(divmod(self._value, value))
190 def __rdivmod__(self, value):
191 return self.clone(divmod(value, self._value))
193 __hash__ = base.SimpleAsn1Type.__hash__
195 def __int__(self):
196 return int(self._value)
198 if sys.version_info[0] <= 2:
199 def __long__(self):
200 return long(self._value)
202 def __float__(self):
203 return float(self._value)
205 def __abs__(self):
206 return self.clone(abs(self._value))
208 def __index__(self):
209 return int(self._value)
211 def __pos__(self):
212 return self.clone(+self._value)
214 def __neg__(self):
215 return self.clone(-self._value)
217 def __invert__(self):
218 return self.clone(~self._value)
220 def __round__(self, n=0):
221 r = round(self._value, n)
222 if n:
223 return self.clone(r)
224 else:
225 return r
227 def __floor__(self):
228 return math.floor(self._value)
230 def __ceil__(self):
231 return math.ceil(self._value)
233 def __trunc__(self):
234 return self.clone(math.trunc(self._value))
236 def __lt__(self, value):
237 return self._value < value
239 def __le__(self, value):
240 return self._value <= value
242 def __eq__(self, value):
243 return self._value == value
245 def __ne__(self, value):
246 return self._value != value
248 def __gt__(self, value):
249 return self._value > value
251 def __ge__(self, value):
252 return self._value >= value
254 def prettyIn(self, value):
255 try:
256 return int(value)
258 except ValueError:
259 try:
260 return self.namedValues[value]
262 except KeyError:
263 raise error.PyAsn1Error(
264 'Can\'t coerce %r into integer: %s' % (value, sys.exc_info()[1])
265 )
267 def prettyOut(self, value):
268 try:
269 return str(self.namedValues[value])
271 except KeyError:
272 return str(value)
274 # backward compatibility
276 def getNamedValues(self):
277 return self.namedValues
280class Boolean(Integer):
281 """Create |ASN.1| schema or value object.
283 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its
284 objects are immutable and duck-type Python :class:`int` objects.
286 Keyword Args
287 ------------
288 value: :class:`int`, :class:`str` or |ASN.1| object
289 Python :class:`int` or :class:`str` literal or |ASN.1| class
290 instance. If `value` is not given, schema object will be created.
292 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
293 Object representing non-default ASN.1 tag(s)
295 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
296 Object representing non-default ASN.1 subtype constraint(s).Constraints
297 verification for |ASN.1| type occurs automatically on object
298 instantiation.
300 namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
301 Object representing non-default symbolic aliases for numbers
303 Raises
304 ------
305 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
306 On constraint violation or bad initializer.
308 Examples
309 --------
310 .. code-block:: python
312 class RoundResult(Boolean):
313 '''
314 ASN.1 specification:
316 RoundResult ::= BOOLEAN
318 ok RoundResult ::= TRUE
319 ko RoundResult ::= FALSE
320 '''
321 ok = RoundResult(True)
322 ko = RoundResult(False)
323 """
324 #: Set (on class, not on instance) or return a
325 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
326 #: associated with |ASN.1| type.
327 tagSet = tag.initTagSet(
328 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x01),
329 )
331 #: Set (on class, not on instance) or return a
332 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
333 #: imposing constraints on |ASN.1| type initialization values.
334 subtypeSpec = Integer.subtypeSpec + constraint.SingleValueConstraint(0, 1)
336 #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
337 #: representing symbolic aliases for numbers
338 namedValues = namedval.NamedValues(('False', 0), ('True', 1))
340 # Optimization for faster codec lookup
341 typeId = Integer.getTypeId()
343if sys.version_info[0] < 3:
344 SizedIntegerBase = long
345else:
346 SizedIntegerBase = int
349class SizedInteger(SizedIntegerBase):
350 bitLength = leadingZeroBits = None
352 def setBitLength(self, bitLength):
353 self.bitLength = bitLength
354 self.leadingZeroBits = max(bitLength - integer.bitLength(self), 0)
355 return self
357 def __len__(self):
358 if self.bitLength is None:
359 self.setBitLength(integer.bitLength(self))
361 return self.bitLength
364class BitString(base.SimpleAsn1Type):
365 """Create |ASN.1| schema or value object.
367 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its
368 objects are immutable and duck-type both Python :class:`tuple` (as a tuple
369 of bits) and :class:`int` objects.
371 Keyword Args
372 ------------
373 value: :class:`int`, :class:`str` or |ASN.1| object
374 Python :class:`int` or :class:`str` literal representing binary
375 or hexadecimal number or sequence of integer bits or |ASN.1| object.
376 If `value` is not given, schema object will be created.
378 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
379 Object representing non-default ASN.1 tag(s)
381 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
382 Object representing non-default ASN.1 subtype constraint(s). Constraints
383 verification for |ASN.1| type occurs automatically on object
384 instantiation.
386 namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
387 Object representing non-default symbolic aliases for numbers
389 binValue: :py:class:`str`
390 Binary string initializer to use instead of the *value*.
391 Example: '10110011'.
393 hexValue: :py:class:`str`
394 Hexadecimal string initializer to use instead of the *value*.
395 Example: 'DEADBEEF'.
397 Raises
398 ------
399 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
400 On constraint violation or bad initializer.
402 Examples
403 --------
404 .. code-block:: python
406 class Rights(BitString):
407 '''
408 ASN.1 specification:
410 Rights ::= BIT STRING { user-read(0), user-write(1),
411 group-read(2), group-write(3),
412 other-read(4), other-write(5) }
414 group1 Rights ::= { group-read, group-write }
415 group2 Rights ::= '0011'B
416 group3 Rights ::= '3'H
417 '''
418 namedValues = NamedValues(
419 ('user-read', 0), ('user-write', 1),
420 ('group-read', 2), ('group-write', 3),
421 ('other-read', 4), ('other-write', 5)
422 )
424 group1 = Rights(('group-read', 'group-write'))
425 group2 = Rights('0011')
426 group3 = Rights(0x3)
427 """
428 #: Set (on class, not on instance) or return a
429 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
430 #: associated with |ASN.1| type.
431 tagSet = tag.initTagSet(
432 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x03)
433 )
435 #: Set (on class, not on instance) or return a
436 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
437 #: imposing constraints on |ASN.1| type initialization values.
438 subtypeSpec = constraint.ConstraintsIntersection()
440 #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
441 #: representing symbolic aliases for numbers
442 namedValues = namedval.NamedValues()
444 # Optimization for faster codec lookup
445 typeId = base.SimpleAsn1Type.getTypeId()
447 defaultBinValue = defaultHexValue = noValue
449 def __init__(self, value=noValue, **kwargs):
450 if value is noValue:
451 if kwargs:
452 try:
453 value = self.fromBinaryString(kwargs.pop('binValue'), internalFormat=True)
455 except KeyError:
456 pass
458 try:
459 value = self.fromHexString(kwargs.pop('hexValue'), internalFormat=True)
461 except KeyError:
462 pass
464 if value is noValue:
465 if self.defaultBinValue is not noValue:
466 value = self.fromBinaryString(self.defaultBinValue, internalFormat=True)
468 elif self.defaultHexValue is not noValue:
469 value = self.fromHexString(self.defaultHexValue, internalFormat=True)
471 if 'namedValues' not in kwargs:
472 kwargs['namedValues'] = self.namedValues
474 base.SimpleAsn1Type.__init__(self, value, **kwargs)
476 def __str__(self):
477 return self.asBinary()
479 def __eq__(self, other):
480 other = self.prettyIn(other)
481 return self is other or self._value == other and len(self._value) == len(other)
483 def __ne__(self, other):
484 other = self.prettyIn(other)
485 return self._value != other or len(self._value) != len(other)
487 def __lt__(self, other):
488 other = self.prettyIn(other)
489 return len(self._value) < len(other) or len(self._value) == len(other) and self._value < other
491 def __le__(self, other):
492 other = self.prettyIn(other)
493 return len(self._value) <= len(other) or len(self._value) == len(other) and self._value <= other
495 def __gt__(self, other):
496 other = self.prettyIn(other)
497 return len(self._value) > len(other) or len(self._value) == len(other) and self._value > other
499 def __ge__(self, other):
500 other = self.prettyIn(other)
501 return len(self._value) >= len(other) or len(self._value) == len(other) and self._value >= other
503 # Immutable sequence object protocol
505 def __len__(self):
506 return len(self._value)
508 def __getitem__(self, i):
509 if i.__class__ is slice:
510 return self.clone([self[x] for x in range(*i.indices(len(self)))])
511 else:
512 length = len(self._value) - 1
513 if i > length or i < 0:
514 raise IndexError('bit index out of range')
515 return (self._value >> (length - i)) & 1
517 def __iter__(self):
518 length = len(self._value)
519 while length:
520 length -= 1
521 yield (self._value >> length) & 1
523 def __reversed__(self):
524 return reversed(tuple(self))
526 # arithmetic operators
528 def __add__(self, value):
529 value = self.prettyIn(value)
530 return self.clone(SizedInteger(self._value << len(value) | value).setBitLength(len(self._value) + len(value)))
532 def __radd__(self, value):
533 value = self.prettyIn(value)
534 return self.clone(SizedInteger(value << len(self._value) | self._value).setBitLength(len(self._value) + len(value)))
536 def __mul__(self, value):
537 bitString = self._value
538 while value > 1:
539 bitString <<= len(self._value)
540 bitString |= self._value
541 value -= 1
542 return self.clone(bitString)
544 def __rmul__(self, value):
545 return self * value
547 def __lshift__(self, count):
548 return self.clone(SizedInteger(self._value << count).setBitLength(len(self._value) + count))
550 def __rshift__(self, count):
551 return self.clone(SizedInteger(self._value >> count).setBitLength(max(0, len(self._value) - count)))
553 def __int__(self):
554 return int(self._value)
556 def __float__(self):
557 return float(self._value)
559 if sys.version_info[0] < 3:
560 def __long__(self):
561 return self._value
563 def asNumbers(self):
564 """Get |ASN.1| value as a sequence of 8-bit integers.
566 If |ASN.1| object length is not a multiple of 8, result
567 will be left-padded with zeros.
568 """
569 return tuple(octets.octs2ints(self.asOctets()))
571 def asOctets(self):
572 """Get |ASN.1| value as a sequence of octets.
574 If |ASN.1| object length is not a multiple of 8, result
575 will be left-padded with zeros.
576 """
577 return integer.to_bytes(self._value, length=len(self))
579 def asInteger(self):
580 """Get |ASN.1| value as a single integer value.
581 """
582 return self._value
584 def asBinary(self):
585 """Get |ASN.1| value as a text string of bits.
586 """
587 binString = bin(self._value)[2:]
588 return '0' * (len(self._value) - len(binString)) + binString
590 @classmethod
591 def fromHexString(cls, value, internalFormat=False, prepend=None):
592 """Create a |ASN.1| object initialized from the hex string.
594 Parameters
595 ----------
596 value: :class:`str`
597 Text string like 'DEADBEEF'
598 """
599 try:
600 value = SizedInteger(value, 16).setBitLength(len(value) * 4)
602 except ValueError:
603 raise error.PyAsn1Error('%s.fromHexString() error: %s' % (cls.__name__, sys.exc_info()[1]))
605 if prepend is not None:
606 value = SizedInteger(
607 (SizedInteger(prepend) << len(value)) | value
608 ).setBitLength(len(prepend) + len(value))
610 if not internalFormat:
611 value = cls(value)
613 return value
615 @classmethod
616 def fromBinaryString(cls, value, internalFormat=False, prepend=None):
617 """Create a |ASN.1| object initialized from a string of '0' and '1'.
619 Parameters
620 ----------
621 value: :class:`str`
622 Text string like '1010111'
623 """
624 try:
625 value = SizedInteger(value or '0', 2).setBitLength(len(value))
627 except ValueError:
628 raise error.PyAsn1Error('%s.fromBinaryString() error: %s' % (cls.__name__, sys.exc_info()[1]))
630 if prepend is not None:
631 value = SizedInteger(
632 (SizedInteger(prepend) << len(value)) | value
633 ).setBitLength(len(prepend) + len(value))
635 if not internalFormat:
636 value = cls(value)
638 return value
640 @classmethod
641 def fromOctetString(cls, value, internalFormat=False, prepend=None, padding=0):
642 """Create a |ASN.1| object initialized from a string.
644 Parameters
645 ----------
646 value: :class:`str` (Py2) or :class:`bytes` (Py3)
647 Text string like '\\\\x01\\\\xff' (Py2) or b'\\\\x01\\\\xff' (Py3)
648 """
649 value = SizedInteger(integer.from_bytes(value) >> padding).setBitLength(len(value) * 8 - padding)
651 if prepend is not None:
652 value = SizedInteger(
653 (SizedInteger(prepend) << len(value)) | value
654 ).setBitLength(len(prepend) + len(value))
656 if not internalFormat:
657 value = cls(value)
659 return value
661 def prettyIn(self, value):
662 if isinstance(value, SizedInteger):
663 return value
664 elif octets.isStringType(value):
665 if not value:
666 return SizedInteger(0).setBitLength(0)
668 elif value[0] == '\'': # "'1011'B" -- ASN.1 schema representation (deprecated)
669 if value[-2:] == '\'B':
670 return self.fromBinaryString(value[1:-2], internalFormat=True)
671 elif value[-2:] == '\'H':
672 return self.fromHexString(value[1:-2], internalFormat=True)
673 else:
674 raise error.PyAsn1Error(
675 'Bad BIT STRING value notation %s' % (value,)
676 )
678 elif self.namedValues and not value.isdigit(): # named bits like 'Urgent, Active'
679 names = [x.strip() for x in value.split(',')]
681 try:
683 bitPositions = [self.namedValues[name] for name in names]
685 except KeyError:
686 raise error.PyAsn1Error('unknown bit name(s) in %r' % (names,))
688 rightmostPosition = max(bitPositions)
690 number = 0
691 for bitPosition in bitPositions:
692 number |= 1 << (rightmostPosition - bitPosition)
694 return SizedInteger(number).setBitLength(rightmostPosition + 1)
696 elif value.startswith('0x'):
697 return self.fromHexString(value[2:], internalFormat=True)
699 elif value.startswith('0b'):
700 return self.fromBinaryString(value[2:], internalFormat=True)
702 else: # assume plain binary string like '1011'
703 return self.fromBinaryString(value, internalFormat=True)
705 elif isinstance(value, (tuple, list)):
706 return self.fromBinaryString(''.join([b and '1' or '0' for b in value]), internalFormat=True)
708 elif isinstance(value, BitString):
709 return SizedInteger(value).setBitLength(len(value))
711 elif isinstance(value, intTypes):
712 return SizedInteger(value)
714 else:
715 raise error.PyAsn1Error(
716 'Bad BitString initializer type \'%s\'' % (value,)
717 )
720class OctetString(base.SimpleAsn1Type):
721 """Create |ASN.1| schema or value object.
723 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its
724 objects are immutable and duck-type Python 2 :class:`str` or
725 Python 3 :class:`bytes`. When used in Unicode context, |ASN.1| type
726 assumes "|encoding|" serialisation.
728 Keyword Args
729 ------------
730 value: :class:`unicode`, :class:`str`, :class:`bytes` or |ASN.1| object
731 class:`str` (Python 2) or :class:`bytes` (Python 3), alternatively
732 class:`unicode` object (Python 2) or :class:`str` (Python 3)
733 representing character string to be serialised into octets
734 (note `encoding` parameter) or |ASN.1| object.
735 If `value` is not given, schema object will be created.
737 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
738 Object representing non-default ASN.1 tag(s)
740 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
741 Object representing non-default ASN.1 subtype constraint(s). Constraints
742 verification for |ASN.1| type occurs automatically on object
743 instantiation.
745 encoding: :py:class:`str`
746 Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
747 :class:`str` (Python 3) the payload when |ASN.1| object is used
748 in text string context.
750 binValue: :py:class:`str`
751 Binary string initializer to use instead of the *value*.
752 Example: '10110011'.
754 hexValue: :py:class:`str`
755 Hexadecimal string initializer to use instead of the *value*.
756 Example: 'DEADBEEF'.
758 Raises
759 ------
760 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
761 On constraint violation or bad initializer.
763 Examples
764 --------
765 .. code-block:: python
767 class Icon(OctetString):
768 '''
769 ASN.1 specification:
771 Icon ::= OCTET STRING
773 icon1 Icon ::= '001100010011001000110011'B
774 icon2 Icon ::= '313233'H
775 '''
776 icon1 = Icon.fromBinaryString('001100010011001000110011')
777 icon2 = Icon.fromHexString('313233')
778 """
779 #: Set (on class, not on instance) or return a
780 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
781 #: associated with |ASN.1| type.
782 tagSet = tag.initTagSet(
783 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x04)
784 )
786 #: Set (on class, not on instance) or return a
787 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
788 #: imposing constraints on |ASN.1| type initialization values.
789 subtypeSpec = constraint.ConstraintsIntersection()
791 # Optimization for faster codec lookup
792 typeId = base.SimpleAsn1Type.getTypeId()
794 defaultBinValue = defaultHexValue = noValue
795 encoding = 'iso-8859-1'
797 def __init__(self, value=noValue, **kwargs):
798 if kwargs:
799 if value is noValue:
800 try:
801 value = self.fromBinaryString(kwargs.pop('binValue'))
803 except KeyError:
804 pass
806 try:
807 value = self.fromHexString(kwargs.pop('hexValue'))
809 except KeyError:
810 pass
812 if value is noValue:
813 if self.defaultBinValue is not noValue:
814 value = self.fromBinaryString(self.defaultBinValue)
816 elif self.defaultHexValue is not noValue:
817 value = self.fromHexString(self.defaultHexValue)
819 if 'encoding' not in kwargs:
820 kwargs['encoding'] = self.encoding
822 base.SimpleAsn1Type.__init__(self, value, **kwargs)
824 if sys.version_info[0] <= 2:
825 def prettyIn(self, value):
826 if isinstance(value, str):
827 return value
829 elif isinstance(value, unicode):
830 try:
831 return value.encode(self.encoding)
833 except (LookupError, UnicodeEncodeError):
834 exc = sys.exc_info()[1]
835 raise error.PyAsn1UnicodeEncodeError(
836 "Can't encode string '%s' with codec "
837 "%s" % (value, self.encoding), exc
838 )
840 elif isinstance(value, (tuple, list)):
841 try:
842 return ''.join([chr(x) for x in value])
844 except ValueError:
845 raise error.PyAsn1Error(
846 "Bad %s initializer '%s'" % (self.__class__.__name__, value)
847 )
849 else:
850 return str(value)
852 def __str__(self):
853 return str(self._value)
855 def __unicode__(self):
856 try:
857 return self._value.decode(self.encoding)
859 except UnicodeDecodeError:
860 exc = sys.exc_info()[1]
861 raise error.PyAsn1UnicodeDecodeError(
862 "Can't decode string '%s' with codec "
863 "%s" % (self._value, self.encoding), exc
864 )
866 def asOctets(self):
867 return str(self._value)
869 def asNumbers(self):
870 return tuple([ord(x) for x in self._value])
872 else:
873 def prettyIn(self, value):
874 if isinstance(value, bytes):
875 return value
877 elif isinstance(value, str):
878 try:
879 return value.encode(self.encoding)
881 except UnicodeEncodeError:
882 exc = sys.exc_info()[1]
883 raise error.PyAsn1UnicodeEncodeError(
884 "Can't encode string '%s' with '%s' "
885 "codec" % (value, self.encoding), exc
886 )
887 elif isinstance(value, OctetString): # a shortcut, bytes() would work the same way
888 return value.asOctets()
890 elif isinstance(value, base.SimpleAsn1Type): # this mostly targets Integer objects
891 return self.prettyIn(str(value))
893 elif isinstance(value, (tuple, list)):
894 return self.prettyIn(bytes(value))
896 else:
897 return bytes(value)
899 def __str__(self):
900 try:
901 return self._value.decode(self.encoding)
903 except UnicodeDecodeError:
904 exc = sys.exc_info()[1]
905 raise error.PyAsn1UnicodeDecodeError(
906 "Can't decode string '%s' with '%s' codec at "
907 "'%s'" % (self._value, self.encoding,
908 self.__class__.__name__), exc
909 )
911 def __bytes__(self):
912 return bytes(self._value)
914 def asOctets(self):
915 return bytes(self._value)
917 def asNumbers(self):
918 return tuple(self._value)
920 #
921 # Normally, `.prettyPrint()` is called from `__str__()`. Historically,
922 # OctetString.prettyPrint() used to return hexified payload
923 # representation in cases when non-printable content is present. At the
924 # same time `str()` used to produce either octet-stream (Py2) or
925 # text (Py3) representations.
926 #
927 # Therefore `OctetString.__str__()` -> `.prettyPrint()` call chain is
928 # reversed to preserve the original behaviour.
929 #
930 # Eventually we should deprecate `.prettyPrint()` / `.prettyOut()` harness
931 # and end up with just `__str__()` producing hexified representation while
932 # both text and octet-stream representation should only be requested via
933 # the `.asOctets()` method.
934 #
935 # Note: ASN.1 OCTET STRING is never mean to contain text!
936 #
938 def prettyOut(self, value):
939 return value
941 def prettyPrint(self, scope=0):
942 # first see if subclass has its own .prettyOut()
943 value = self.prettyOut(self._value)
945 if value is not self._value:
946 return value
948 numbers = self.asNumbers()
950 for x in numbers:
951 # hexify if needed
952 if x < 32 or x > 126:
953 return '0x' + ''.join(('%.2x' % x for x in numbers))
954 else:
955 # this prevents infinite recursion
956 return OctetString.__str__(self)
958 @staticmethod
959 def fromBinaryString(value):
960 """Create a |ASN.1| object initialized from a string of '0' and '1'.
962 Parameters
963 ----------
964 value: :class:`str`
965 Text string like '1010111'
966 """
967 bitNo = 8
968 byte = 0
969 r = []
970 for v in value:
971 if bitNo:
972 bitNo -= 1
973 else:
974 bitNo = 7
975 r.append(byte)
976 byte = 0
977 if v in ('0', '1'):
978 v = int(v)
979 else:
980 raise error.PyAsn1Error(
981 'Non-binary OCTET STRING initializer %s' % (v,)
982 )
983 byte |= v << bitNo
985 r.append(byte)
987 return octets.ints2octs(r)
989 @staticmethod
990 def fromHexString(value):
991 """Create a |ASN.1| object initialized from the hex string.
993 Parameters
994 ----------
995 value: :class:`str`
996 Text string like 'DEADBEEF'
997 """
998 r = []
999 p = []
1000 for v in value:
1001 if p:
1002 r.append(int(p + v, 16))
1003 p = None
1004 else:
1005 p = v
1006 if p:
1007 r.append(int(p + '0', 16))
1009 return octets.ints2octs(r)
1011 # Immutable sequence object protocol
1013 def __len__(self):
1014 return len(self._value)
1016 def __getitem__(self, i):
1017 if i.__class__ is slice:
1018 return self.clone(self._value[i])
1019 else:
1020 return self._value[i]
1022 def __iter__(self):
1023 return iter(self._value)
1025 def __contains__(self, value):
1026 return value in self._value
1028 def __add__(self, value):
1029 return self.clone(self._value + self.prettyIn(value))
1031 def __radd__(self, value):
1032 return self.clone(self.prettyIn(value) + self._value)
1034 def __mul__(self, value):
1035 return self.clone(self._value * value)
1037 def __rmul__(self, value):
1038 return self * value
1040 def __int__(self):
1041 return int(self._value)
1043 def __float__(self):
1044 return float(self._value)
1046 def __reversed__(self):
1047 return reversed(self._value)
1050class Null(OctetString):
1051 """Create |ASN.1| schema or value object.
1053 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its
1054 objects are immutable and duck-type Python :class:`str` objects
1055 (always empty).
1057 Keyword Args
1058 ------------
1059 value: :class:`str` or |ASN.1| object
1060 Python empty :class:`str` literal or any object that evaluates to :obj:`False`
1061 If `value` is not given, schema object will be created.
1063 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
1064 Object representing non-default ASN.1 tag(s)
1066 Raises
1067 ------
1068 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
1069 On constraint violation or bad initializer.
1071 Examples
1072 --------
1073 .. code-block:: python
1075 class Ack(Null):
1076 '''
1077 ASN.1 specification:
1079 Ack ::= NULL
1080 '''
1081 ack = Ack('')
1082 """
1084 #: Set (on class, not on instance) or return a
1085 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
1086 #: associated with |ASN.1| type.
1087 tagSet = tag.initTagSet(
1088 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05)
1089 )
1090 subtypeSpec = OctetString.subtypeSpec + constraint.SingleValueConstraint(octets.str2octs(''))
1092 # Optimization for faster codec lookup
1093 typeId = OctetString.getTypeId()
1095 def prettyIn(self, value):
1096 if value:
1097 return value
1099 return octets.str2octs('')
1101if sys.version_info[0] <= 2:
1102 intTypes = (int, long)
1103else:
1104 intTypes = (int,)
1106numericTypes = intTypes + (float,)
1109class ObjectIdentifier(base.SimpleAsn1Type):
1110 """Create |ASN.1| schema or value object.
1112 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its
1113 objects are immutable and duck-type Python :class:`tuple` objects
1114 (tuple of non-negative integers).
1116 Keyword Args
1117 ------------
1118 value: :class:`tuple`, :class:`str` or |ASN.1| object
1119 Python sequence of :class:`int` or :class:`str` literal or |ASN.1| object.
1120 If `value` is not given, schema object will be created.
1122 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
1123 Object representing non-default ASN.1 tag(s)
1125 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
1126 Object representing non-default ASN.1 subtype constraint(s). Constraints
1127 verification for |ASN.1| type occurs automatically on object
1128 instantiation.
1130 Raises
1131 ------
1132 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
1133 On constraint violation or bad initializer.
1135 Examples
1136 --------
1137 .. code-block:: python
1139 class ID(ObjectIdentifier):
1140 '''
1141 ASN.1 specification:
1143 ID ::= OBJECT IDENTIFIER
1145 id-edims ID ::= { joint-iso-itu-t mhs-motif(6) edims(7) }
1146 id-bp ID ::= { id-edims 11 }
1147 '''
1148 id_edims = ID('2.6.7')
1149 id_bp = id_edims + (11,)
1150 """
1151 #: Set (on class, not on instance) or return a
1152 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
1153 #: associated with |ASN.1| type.
1154 tagSet = tag.initTagSet(
1155 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x06)
1156 )
1158 #: Set (on class, not on instance) or return a
1159 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
1160 #: imposing constraints on |ASN.1| type initialization values.
1161 subtypeSpec = constraint.ConstraintsIntersection()
1163 # Optimization for faster codec lookup
1164 typeId = base.SimpleAsn1Type.getTypeId()
1166 def __add__(self, other):
1167 return self.clone(self._value + other)
1169 def __radd__(self, other):
1170 return self.clone(other + self._value)
1172 def asTuple(self):
1173 return self._value
1175 # Sequence object protocol
1177 def __len__(self):
1178 return len(self._value)
1180 def __getitem__(self, i):
1181 if i.__class__ is slice:
1182 return self.clone(self._value[i])
1183 else:
1184 return self._value[i]
1186 def __iter__(self):
1187 return iter(self._value)
1189 def __contains__(self, value):
1190 return value in self._value
1192 def index(self, suboid):
1193 return self._value.index(suboid)
1195 def isPrefixOf(self, other):
1196 """Indicate if this |ASN.1| object is a prefix of other |ASN.1| object.
1198 Parameters
1199 ----------
1200 other: |ASN.1| object
1201 |ASN.1| object
1203 Returns
1204 -------
1205 : :class:`bool`
1206 :obj:`True` if this |ASN.1| object is a parent (e.g. prefix) of the other |ASN.1| object
1207 or :obj:`False` otherwise.
1208 """
1209 l = len(self)
1210 if l <= len(other):
1211 if self._value[:l] == other[:l]:
1212 return True
1213 return False
1215 def prettyIn(self, value):
1216 if isinstance(value, ObjectIdentifier):
1217 return tuple(value)
1218 elif octets.isStringType(value):
1219 if '-' in value:
1220 raise error.PyAsn1Error(
1221 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
1222 )
1223 try:
1224 return tuple([int(subOid) for subOid in value.split('.') if subOid])
1225 except ValueError:
1226 raise error.PyAsn1Error(
1227 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
1228 )
1230 try:
1231 tupleOfInts = tuple([int(subOid) for subOid in value if subOid >= 0])
1233 except (ValueError, TypeError):
1234 raise error.PyAsn1Error(
1235 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
1236 )
1238 if len(tupleOfInts) == len(value):
1239 return tupleOfInts
1241 raise error.PyAsn1Error('Malformed Object ID %s at %s' % (value, self.__class__.__name__))
1243 def prettyOut(self, value):
1244 return '.'.join([str(x) for x in value])
1247class Real(base.SimpleAsn1Type):
1248 """Create |ASN.1| schema or value object.
1250 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its
1251 objects are immutable and duck-type Python :class:`float` objects.
1252 Additionally, |ASN.1| objects behave like a :class:`tuple` in which case its
1253 elements are mantissa, base and exponent.
1255 Keyword Args
1256 ------------
1257 value: :class:`tuple`, :class:`float` or |ASN.1| object
1258 Python sequence of :class:`int` (representing mantissa, base and
1259 exponent) or :class:`float` instance or |ASN.1| object.
1260 If `value` is not given, schema object will be created.
1262 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
1263 Object representing non-default ASN.1 tag(s)
1265 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
1266 Object representing non-default ASN.1 subtype constraint(s). Constraints
1267 verification for |ASN.1| type occurs automatically on object
1268 instantiation.
1270 Raises
1271 ------
1272 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
1273 On constraint violation or bad initializer.
1275 Examples
1276 --------
1277 .. code-block:: python
1279 class Pi(Real):
1280 '''
1281 ASN.1 specification:
1283 Pi ::= REAL
1285 pi Pi ::= { mantissa 314159, base 10, exponent -5 }
1287 '''
1288 pi = Pi((314159, 10, -5))
1289 """
1290 binEncBase = None # binEncBase = 16 is recommended for large numbers
1292 try:
1293 _plusInf = float('inf')
1294 _minusInf = float('-inf')
1295 _inf = _plusInf, _minusInf
1297 except ValueError:
1298 # Infinity support is platform and Python dependent
1299 _plusInf = _minusInf = None
1300 _inf = ()
1302 #: Set (on class, not on instance) or return a
1303 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
1304 #: associated with |ASN.1| type.
1305 tagSet = tag.initTagSet(
1306 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x09)
1307 )
1309 #: Set (on class, not on instance) or return a
1310 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
1311 #: imposing constraints on |ASN.1| type initialization values.
1312 subtypeSpec = constraint.ConstraintsIntersection()
1314 # Optimization for faster codec lookup
1315 typeId = base.SimpleAsn1Type.getTypeId()
1317 @staticmethod
1318 def __normalizeBase10(value):
1319 m, b, e = value
1320 while m and m % 10 == 0:
1321 m /= 10
1322 e += 1
1323 return m, b, e
1325 def prettyIn(self, value):
1326 if isinstance(value, tuple) and len(value) == 3:
1327 if (not isinstance(value[0], numericTypes) or
1328 not isinstance(value[1], intTypes) or
1329 not isinstance(value[2], intTypes)):
1330 raise error.PyAsn1Error('Lame Real value syntax: %s' % (value,))
1331 if (isinstance(value[0], float) and
1332 self._inf and value[0] in self._inf):
1333 return value[0]
1334 if value[1] not in (2, 10):
1335 raise error.PyAsn1Error(
1336 'Prohibited base for Real value: %s' % (value[1],)
1337 )
1338 if value[1] == 10:
1339 value = self.__normalizeBase10(value)
1340 return value
1341 elif isinstance(value, intTypes):
1342 return self.__normalizeBase10((value, 10, 0))
1343 elif isinstance(value, float) or octets.isStringType(value):
1344 if octets.isStringType(value):
1345 try:
1346 value = float(value)
1347 except ValueError:
1348 raise error.PyAsn1Error(
1349 'Bad real value syntax: %s' % (value,)
1350 )
1351 if self._inf and value in self._inf:
1352 return value
1353 else:
1354 e = 0
1355 while int(value) != value:
1356 value *= 10
1357 e -= 1
1358 return self.__normalizeBase10((int(value), 10, e))
1359 elif isinstance(value, Real):
1360 return tuple(value)
1361 raise error.PyAsn1Error(
1362 'Bad real value syntax: %s' % (value,)
1363 )
1365 def prettyPrint(self, scope=0):
1366 try:
1367 return self.prettyOut(float(self))
1369 except OverflowError:
1370 return '<overflow>'
1372 @property
1373 def isPlusInf(self):
1374 """Indicate PLUS-INFINITY object value
1376 Returns
1377 -------
1378 : :class:`bool`
1379 :obj:`True` if calling object represents plus infinity
1380 or :obj:`False` otherwise.
1382 """
1383 return self._value == self._plusInf
1385 @property
1386 def isMinusInf(self):
1387 """Indicate MINUS-INFINITY object value
1389 Returns
1390 -------
1391 : :class:`bool`
1392 :obj:`True` if calling object represents minus infinity
1393 or :obj:`False` otherwise.
1394 """
1395 return self._value == self._minusInf
1397 @property
1398 def isInf(self):
1399 return self._value in self._inf
1401 def __add__(self, value):
1402 return self.clone(float(self) + value)
1404 def __radd__(self, value):
1405 return self + value
1407 def __mul__(self, value):
1408 return self.clone(float(self) * value)
1410 def __rmul__(self, value):
1411 return self * value
1413 def __sub__(self, value):
1414 return self.clone(float(self) - value)
1416 def __rsub__(self, value):
1417 return self.clone(value - float(self))
1419 def __mod__(self, value):
1420 return self.clone(float(self) % value)
1422 def __rmod__(self, value):
1423 return self.clone(value % float(self))
1425 def __pow__(self, value, modulo=None):
1426 return self.clone(pow(float(self), value, modulo))
1428 def __rpow__(self, value):
1429 return self.clone(pow(value, float(self)))
1431 if sys.version_info[0] <= 2:
1432 def __div__(self, value):
1433 return self.clone(float(self) / value)
1435 def __rdiv__(self, value):
1436 return self.clone(value / float(self))
1437 else:
1438 def __truediv__(self, value):
1439 return self.clone(float(self) / value)
1441 def __rtruediv__(self, value):
1442 return self.clone(value / float(self))
1444 def __divmod__(self, value):
1445 return self.clone(float(self) // value)
1447 def __rdivmod__(self, value):
1448 return self.clone(value // float(self))
1450 def __int__(self):
1451 return int(float(self))
1453 if sys.version_info[0] <= 2:
1454 def __long__(self):
1455 return long(float(self))
1457 def __float__(self):
1458 if self._value in self._inf:
1459 return self._value
1460 else:
1461 return float(
1462 self._value[0] * pow(self._value[1], self._value[2])
1463 )
1465 def __abs__(self):
1466 return self.clone(abs(float(self)))
1468 def __pos__(self):
1469 return self.clone(+float(self))
1471 def __neg__(self):
1472 return self.clone(-float(self))
1474 def __round__(self, n=0):
1475 r = round(float(self), n)
1476 if n:
1477 return self.clone(r)
1478 else:
1479 return r
1481 def __floor__(self):
1482 return self.clone(math.floor(float(self)))
1484 def __ceil__(self):
1485 return self.clone(math.ceil(float(self)))
1487 def __trunc__(self):
1488 return self.clone(math.trunc(float(self)))
1490 def __lt__(self, value):
1491 return float(self) < value
1493 def __le__(self, value):
1494 return float(self) <= value
1496 def __eq__(self, value):
1497 return float(self) == value
1499 def __ne__(self, value):
1500 return float(self) != value
1502 def __gt__(self, value):
1503 return float(self) > value
1505 def __ge__(self, value):
1506 return float(self) >= value
1508 if sys.version_info[0] <= 2:
1509 def __nonzero__(self):
1510 return bool(float(self))
1511 else:
1512 def __bool__(self):
1513 return bool(float(self))
1515 __hash__ = base.SimpleAsn1Type.__hash__
1517 def __getitem__(self, idx):
1518 if self._value in self._inf:
1519 raise error.PyAsn1Error('Invalid infinite value operation')
1520 else:
1521 return self._value[idx]
1523 # compatibility stubs
1525 def isPlusInfinity(self):
1526 return self.isPlusInf
1528 def isMinusInfinity(self):
1529 return self.isMinusInf
1531 def isInfinity(self):
1532 return self.isInf
1535class Enumerated(Integer):
1536 """Create |ASN.1| schema or value object.
1538 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its
1539 objects are immutable and duck-type Python :class:`int` objects.
1541 Keyword Args
1542 ------------
1543 value: :class:`int`, :class:`str` or |ASN.1| object
1544 Python :class:`int` or :class:`str` literal or |ASN.1| object.
1545 If `value` is not given, schema object will be created.
1547 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
1548 Object representing non-default ASN.1 tag(s)
1550 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
1551 Object representing non-default ASN.1 subtype constraint(s). Constraints
1552 verification for |ASN.1| type occurs automatically on object
1553 instantiation.
1555 namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
1556 Object representing non-default symbolic aliases for numbers
1558 Raises
1559 ------
1560 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
1561 On constraint violation or bad initializer.
1563 Examples
1564 --------
1566 .. code-block:: python
1568 class RadioButton(Enumerated):
1569 '''
1570 ASN.1 specification:
1572 RadioButton ::= ENUMERATED { button1(0), button2(1),
1573 button3(2) }
1575 selected-by-default RadioButton ::= button1
1576 '''
1577 namedValues = NamedValues(
1578 ('button1', 0), ('button2', 1),
1579 ('button3', 2)
1580 )
1582 selected_by_default = RadioButton('button1')
1583 """
1584 #: Set (on class, not on instance) or return a
1585 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
1586 #: associated with |ASN.1| type.
1587 tagSet = tag.initTagSet(
1588 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x0A)
1589 )
1591 #: Set (on class, not on instance) or return a
1592 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
1593 #: imposing constraints on |ASN.1| type initialization values.
1594 subtypeSpec = constraint.ConstraintsIntersection()
1596 # Optimization for faster codec lookup
1597 typeId = Integer.getTypeId()
1599 #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
1600 #: representing symbolic aliases for numbers
1601 namedValues = namedval.NamedValues()
1604# "Structured" ASN.1 types
1606class SequenceOfAndSetOfBase(base.ConstructedAsn1Type):
1607 """Create |ASN.1| schema or value object.
1609 |ASN.1| class is based on :class:`~pyasn1.type.base.ConstructedAsn1Type`,
1610 its objects are mutable and duck-type Python :class:`list` objects.
1612 Keyword Args
1613 ------------
1614 componentType : :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
1615 A pyasn1 object representing ASN.1 type allowed within |ASN.1| type
1617 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
1618 Object representing non-default ASN.1 tag(s)
1620 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
1621 Object representing non-default ASN.1 subtype constraint(s). Constraints
1622 verification for |ASN.1| type can only occur on explicit
1623 `.isInconsistent` call.
1625 Examples
1626 --------
1628 .. code-block:: python
1630 class LotteryDraw(SequenceOf): # SetOf is similar
1631 '''
1632 ASN.1 specification:
1634 LotteryDraw ::= SEQUENCE OF INTEGER
1635 '''
1636 componentType = Integer()
1638 lotteryDraw = LotteryDraw()
1639 lotteryDraw.extend([123, 456, 789])
1640 """
1641 def __init__(self, *args, **kwargs):
1642 # support positional params for backward compatibility
1643 if args:
1644 for key, value in zip(('componentType', 'tagSet',
1645 'subtypeSpec'), args):
1646 if key in kwargs:
1647 raise error.PyAsn1Error('Conflicting positional and keyword params!')
1648 kwargs['componentType'] = value
1650 self._componentValues = noValue
1652 base.ConstructedAsn1Type.__init__(self, **kwargs)
1654 # Python list protocol
1656 def __getitem__(self, idx):
1657 try:
1658 return self.getComponentByPosition(idx)
1660 except error.PyAsn1Error:
1661 raise IndexError(sys.exc_info()[1])
1663 def __setitem__(self, idx, value):
1664 try:
1665 self.setComponentByPosition(idx, value)
1667 except error.PyAsn1Error:
1668 raise IndexError(sys.exc_info()[1])
1670 def append(self, value):
1671 if self._componentValues is noValue:
1672 pos = 0
1674 else:
1675 pos = len(self._componentValues)
1677 self[pos] = value
1679 def count(self, value):
1680 return list(self._componentValues.values()).count(value)
1682 def extend(self, values):
1683 for value in values:
1684 self.append(value)
1686 if self._componentValues is noValue:
1687 self._componentValues = {}
1689 def index(self, value, start=0, stop=None):
1690 if stop is None:
1691 stop = len(self)
1693 indices, values = zip(*self._componentValues.items())
1695 # TODO: remove when Py2.5 support is gone
1696 values = list(values)
1698 try:
1699 return indices[values.index(value, start, stop)]
1701 except error.PyAsn1Error:
1702 raise ValueError(sys.exc_info()[1])
1704 def reverse(self):
1705 self._componentValues.reverse()
1707 def sort(self, key=None, reverse=False):
1708 self._componentValues = dict(
1709 enumerate(sorted(self._componentValues.values(),
1710 key=key, reverse=reverse)))
1712 def __len__(self):
1713 if self._componentValues is noValue or not self._componentValues:
1714 return 0
1716 return max(self._componentValues) + 1
1718 def __iter__(self):
1719 for idx in range(0, len(self)):
1720 yield self.getComponentByPosition(idx)
1722 def _cloneComponentValues(self, myClone, cloneValueFlag):
1723 for idx, componentValue in self._componentValues.items():
1724 if componentValue is not noValue:
1725 if isinstance(componentValue, base.ConstructedAsn1Type):
1726 myClone.setComponentByPosition(
1727 idx, componentValue.clone(cloneValueFlag=cloneValueFlag)
1728 )
1729 else:
1730 myClone.setComponentByPosition(idx, componentValue.clone())
1732 def getComponentByPosition(self, idx, default=noValue, instantiate=True):
1733 """Return |ASN.1| type component value by position.
1735 Equivalent to Python sequence subscription operation (e.g. `[]`).
1737 Parameters
1738 ----------
1739 idx : :class:`int`
1740 Component index (zero-based). Must either refer to an existing
1741 component or to N+1 component (if *componentType* is set). In the latter
1742 case a new component type gets instantiated and appended to the |ASN.1|
1743 sequence.
1745 Keyword Args
1746 ------------
1747 default: :class:`object`
1748 If set and requested component is a schema object, return the `default`
1749 object instead of the requested component.
1751 instantiate: :class:`bool`
1752 If :obj:`True` (default), inner component will be automatically instantiated.
1753 If :obj:`False` either existing component or the :class:`NoValue` object will be
1754 returned.
1756 Returns
1757 -------
1758 : :py:class:`~pyasn1.type.base.PyAsn1Item`
1759 Instantiate |ASN.1| component type or return existing component value
1761 Examples
1762 --------
1764 .. code-block:: python
1766 # can also be SetOf
1767 class MySequenceOf(SequenceOf):
1768 componentType = OctetString()
1770 s = MySequenceOf()
1772 # returns component #0 with `.isValue` property False
1773 s.getComponentByPosition(0)
1775 # returns None
1776 s.getComponentByPosition(0, default=None)
1778 s.clear()
1780 # returns noValue
1781 s.getComponentByPosition(0, instantiate=False)
1783 # sets component #0 to OctetString() ASN.1 schema
1784 # object and returns it
1785 s.getComponentByPosition(0, instantiate=True)
1787 # sets component #0 to ASN.1 value object
1788 s.setComponentByPosition(0, 'ABCD')
1790 # returns OctetString('ABCD') value object
1791 s.getComponentByPosition(0, instantiate=False)
1793 s.clear()
1795 # returns noValue
1796 s.getComponentByPosition(0, instantiate=False)
1797 """
1798 if isinstance(idx, slice):
1799 indices = tuple(range(len(self)))
1800 return [self.getComponentByPosition(subidx, default, instantiate)
1801 for subidx in indices[idx]]
1803 if idx < 0:
1804 idx = len(self) + idx
1805 if idx < 0:
1806 raise error.PyAsn1Error(
1807 'SequenceOf/SetOf index is out of range')
1809 try:
1810 componentValue = self._componentValues[idx]
1812 except (KeyError, error.PyAsn1Error):
1813 if not instantiate:
1814 return default
1816 self.setComponentByPosition(idx)
1818 componentValue = self._componentValues[idx]
1820 if default is noValue or componentValue.isValue:
1821 return componentValue
1822 else:
1823 return default
1825 def setComponentByPosition(self, idx, value=noValue,
1826 verifyConstraints=True,
1827 matchTags=True,
1828 matchConstraints=True):
1829 """Assign |ASN.1| type component by position.
1831 Equivalent to Python sequence item assignment operation (e.g. `[]`)
1832 or list.append() (when idx == len(self)).
1834 Parameters
1835 ----------
1836 idx: :class:`int`
1837 Component index (zero-based). Must either refer to existing
1838 component or to N+1 component. In the latter case a new component
1839 type gets instantiated (if *componentType* is set, or given ASN.1
1840 object is taken otherwise) and appended to the |ASN.1| sequence.
1842 Keyword Args
1843 ------------
1844 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
1845 A Python value to initialize |ASN.1| component with (if *componentType* is set)
1846 or ASN.1 value object to assign to |ASN.1| component.
1847 If `value` is not given, schema object will be set as a component.
1849 verifyConstraints: :class:`bool`
1850 If :obj:`False`, skip constraints validation
1852 matchTags: :class:`bool`
1853 If :obj:`False`, skip component tags matching
1855 matchConstraints: :class:`bool`
1856 If :obj:`False`, skip component constraints matching
1858 Returns
1859 -------
1860 self
1862 Raises
1863 ------
1864 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
1865 On constraint violation or bad initializer
1866 IndexError
1867 When idx > len(self)
1868 """
1869 if isinstance(idx, slice):
1870 indices = tuple(range(len(self)))
1871 startIdx = indices and indices[idx][0] or 0
1872 for subIdx, subValue in enumerate(value):
1873 self.setComponentByPosition(
1874 startIdx + subIdx, subValue, verifyConstraints,
1875 matchTags, matchConstraints)
1876 return self
1878 if idx < 0:
1879 idx = len(self) + idx
1880 if idx < 0:
1881 raise error.PyAsn1Error(
1882 'SequenceOf/SetOf index is out of range')
1884 componentType = self.componentType
1886 if self._componentValues is noValue:
1887 componentValues = {}
1889 else:
1890 componentValues = self._componentValues
1892 currentValue = componentValues.get(idx, noValue)
1894 if value is noValue:
1895 if componentType is not None:
1896 value = componentType.clone()
1898 elif currentValue is noValue:
1899 raise error.PyAsn1Error('Component type not defined')
1901 elif not isinstance(value, base.Asn1Item):
1902 if (componentType is not None and
1903 isinstance(componentType, base.SimpleAsn1Type)):
1904 value = componentType.clone(value=value)
1906 elif (currentValue is not noValue and
1907 isinstance(currentValue, base.SimpleAsn1Type)):
1908 value = currentValue.clone(value=value)
1910 else:
1911 raise error.PyAsn1Error(
1912 'Non-ASN.1 value %r and undefined component'
1913 ' type at %r' % (value, self))
1915 elif componentType is not None and (matchTags or matchConstraints):
1916 subtypeChecker = (
1917 self.strictConstraints and
1918 componentType.isSameTypeWith or
1919 componentType.isSuperTypeOf)
1921 if not subtypeChecker(value, verifyConstraints and matchTags,
1922 verifyConstraints and matchConstraints):
1923 # TODO: we should wrap componentType with UnnamedType to carry
1924 # additional properties associated with componentType
1925 if componentType.typeId != Any.typeId:
1926 raise error.PyAsn1Error(
1927 'Component value is tag-incompatible: %r vs '
1928 '%r' % (value, componentType))
1930 componentValues[idx] = value
1932 self._componentValues = componentValues
1934 return self
1936 @property
1937 def componentTagMap(self):
1938 if self.componentType is not None:
1939 return self.componentType.tagMap
1941 @property
1942 def components(self):
1943 return [self._componentValues[idx]
1944 for idx in sorted(self._componentValues)]
1946 def clear(self):
1947 """Remove all components and become an empty |ASN.1| value object.
1949 Has the same effect on |ASN.1| object as it does on :class:`list`
1950 built-in.
1951 """
1952 self._componentValues = {}
1953 return self
1955 def reset(self):
1956 """Remove all components and become a |ASN.1| schema object.
1958 See :meth:`isValue` property for more information on the
1959 distinction between value and schema objects.
1960 """
1961 self._componentValues = noValue
1962 return self
1964 def prettyPrint(self, scope=0):
1965 scope += 1
1966 representation = self.__class__.__name__ + ':\n'
1968 if not self.isValue:
1969 return representation
1971 for idx, componentValue in enumerate(self):
1972 representation += ' ' * scope
1973 if (componentValue is noValue and
1974 self.componentType is not None):
1975 representation += '<empty>'
1976 else:
1977 representation += componentValue.prettyPrint(scope)
1979 return representation
1981 def prettyPrintType(self, scope=0):
1982 scope += 1
1983 representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__)
1984 if self.componentType is not None:
1985 representation += ' ' * scope
1986 representation += self.componentType.prettyPrintType(scope)
1987 return representation + '\n' + ' ' * (scope - 1) + '}'
1990 @property
1991 def isValue(self):
1992 """Indicate that |ASN.1| object represents ASN.1 value.
1994 If *isValue* is :obj:`False` then this object represents just ASN.1 schema.
1996 If *isValue* is :obj:`True` then, in addition to its ASN.1 schema features,
1997 this object can also be used like a Python built-in object
1998 (e.g. :class:`int`, :class:`str`, :class:`dict` etc.).
2000 Returns
2001 -------
2002 : :class:`bool`
2003 :obj:`False` if object represents just ASN.1 schema.
2004 :obj:`True` if object represents ASN.1 schema and can be used as a normal value.
2006 Note
2007 ----
2008 There is an important distinction between PyASN1 schema and value objects.
2009 The PyASN1 schema objects can only participate in ASN.1 schema-related
2010 operations (e.g. defining or testing the structure of the data). Most
2011 obvious uses of ASN.1 schema is to guide serialisation codecs whilst
2012 encoding/decoding serialised ASN.1 contents.
2014 The PyASN1 value objects can **additionally** participate in many operations
2015 involving regular Python objects (e.g. arithmetic, comprehension etc).
2016 """
2017 if self._componentValues is noValue:
2018 return False
2020 if len(self._componentValues) != len(self):
2021 return False
2023 for componentValue in self._componentValues.values():
2024 if componentValue is noValue or not componentValue.isValue:
2025 return False
2027 return True
2029 @property
2030 def isInconsistent(self):
2031 """Run necessary checks to ensure |ASN.1| object consistency.
2033 Default action is to verify |ASN.1| object against constraints imposed
2034 by `subtypeSpec`.
2036 Raises
2037 ------
2038 :py:class:`~pyasn1.error.PyAsn1tError` on any inconsistencies found
2039 """
2040 if self.componentType is noValue or not self.subtypeSpec:
2041 return False
2043 if self._componentValues is noValue:
2044 return True
2046 mapping = {}
2048 for idx, value in self._componentValues.items():
2049 # Absent fields are not in the mapping
2050 if value is noValue:
2051 continue
2053 mapping[idx] = value
2055 try:
2056 # Represent SequenceOf/SetOf as a bare dict to constraints chain
2057 self.subtypeSpec(mapping)
2059 except error.PyAsn1Error:
2060 exc = sys.exc_info()[1]
2061 return exc
2063 return False
2065class SequenceOf(SequenceOfAndSetOfBase):
2066 __doc__ = SequenceOfAndSetOfBase.__doc__
2068 #: Set (on class, not on instance) or return a
2069 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
2070 #: associated with |ASN.1| type.
2071 tagSet = tag.initTagSet(
2072 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
2073 )
2075 #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
2076 #: object representing ASN.1 type allowed within |ASN.1| type
2077 componentType = None
2079 #: Set (on class, not on instance) or return a
2080 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
2081 #: imposing constraints on |ASN.1| type initialization values.
2082 subtypeSpec = constraint.ConstraintsIntersection()
2084 # Disambiguation ASN.1 types identification
2085 typeId = SequenceOfAndSetOfBase.getTypeId()
2088class SetOf(SequenceOfAndSetOfBase):
2089 __doc__ = SequenceOfAndSetOfBase.__doc__
2091 #: Set (on class, not on instance) or return a
2092 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
2093 #: associated with |ASN.1| type.
2094 tagSet = tag.initTagSet(
2095 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
2096 )
2098 #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
2099 #: object representing ASN.1 type allowed within |ASN.1| type
2100 componentType = None
2102 #: Set (on class, not on instance) or return a
2103 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
2104 #: imposing constraints on |ASN.1| type initialization values.
2105 subtypeSpec = constraint.ConstraintsIntersection()
2107 # Disambiguation ASN.1 types identification
2108 typeId = SequenceOfAndSetOfBase.getTypeId()
2111class SequenceAndSetBase(base.ConstructedAsn1Type):
2112 """Create |ASN.1| schema or value object.
2114 |ASN.1| class is based on :class:`~pyasn1.type.base.ConstructedAsn1Type`,
2115 its objects are mutable and duck-type Python :class:`dict` objects.
2117 Keyword Args
2118 ------------
2119 componentType: :py:class:`~pyasn1.type.namedtype.NamedType`
2120 Object holding named ASN.1 types allowed within this collection
2122 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
2123 Object representing non-default ASN.1 tag(s)
2125 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
2126 Object representing non-default ASN.1 subtype constraint(s). Constraints
2127 verification for |ASN.1| type can only occur on explicit
2128 `.isInconsistent` call.
2130 Examples
2131 --------
2133 .. code-block:: python
2135 class Description(Sequence): # Set is similar
2136 '''
2137 ASN.1 specification:
2139 Description ::= SEQUENCE {
2140 surname IA5String,
2141 first-name IA5String OPTIONAL,
2142 age INTEGER DEFAULT 40
2143 }
2144 '''
2145 componentType = NamedTypes(
2146 NamedType('surname', IA5String()),
2147 OptionalNamedType('first-name', IA5String()),
2148 DefaultedNamedType('age', Integer(40))
2149 )
2151 descr = Description()
2152 descr['surname'] = 'Smith'
2153 descr['first-name'] = 'John'
2154 """
2155 #: Default :py:class:`~pyasn1.type.namedtype.NamedTypes`
2156 #: object representing named ASN.1 types allowed within |ASN.1| type
2157 componentType = namedtype.NamedTypes()
2160 class DynamicNames(object):
2161 """Fields names/positions mapping for component-less objects"""
2162 def __init__(self):
2163 self._keyToIdxMap = {}
2164 self._idxToKeyMap = {}
2166 def __len__(self):
2167 return len(self._keyToIdxMap)
2169 def __contains__(self, item):
2170 return item in self._keyToIdxMap or item in self._idxToKeyMap
2172 def __iter__(self):
2173 return (self._idxToKeyMap[idx] for idx in range(len(self._idxToKeyMap)))
2175 def __getitem__(self, item):
2176 try:
2177 return self._keyToIdxMap[item]
2179 except KeyError:
2180 return self._idxToKeyMap[item]
2182 def getNameByPosition(self, idx):
2183 try:
2184 return self._idxToKeyMap[idx]
2186 except KeyError:
2187 raise error.PyAsn1Error('Type position out of range')
2189 def getPositionByName(self, name):
2190 try:
2191 return self._keyToIdxMap[name]
2193 except KeyError:
2194 raise error.PyAsn1Error('Name %s not found' % (name,))
2196 def addField(self, idx):
2197 self._keyToIdxMap['field-%d' % idx] = idx
2198 self._idxToKeyMap[idx] = 'field-%d' % idx
2201 def __init__(self, **kwargs):
2202 base.ConstructedAsn1Type.__init__(self, **kwargs)
2203 self._componentTypeLen = len(self.componentType)
2204 if self._componentTypeLen:
2205 self._componentValues = []
2206 else:
2207 self._componentValues = noValue
2208 self._dynamicNames = self._componentTypeLen or self.DynamicNames()
2210 def __getitem__(self, idx):
2211 if octets.isStringType(idx):
2212 try:
2213 return self.getComponentByName(idx)
2215 except error.PyAsn1Error:
2216 # duck-typing dict
2217 raise KeyError(sys.exc_info()[1])
2219 else:
2220 try:
2221 return self.getComponentByPosition(idx)
2223 except error.PyAsn1Error:
2224 # duck-typing list
2225 raise IndexError(sys.exc_info()[1])
2227 def __setitem__(self, idx, value):
2228 if octets.isStringType(idx):
2229 try:
2230 self.setComponentByName(idx, value)
2232 except error.PyAsn1Error:
2233 # duck-typing dict
2234 raise KeyError(sys.exc_info()[1])
2236 else:
2237 try:
2238 self.setComponentByPosition(idx, value)
2240 except error.PyAsn1Error:
2241 # duck-typing list
2242 raise IndexError(sys.exc_info()[1])
2244 def __contains__(self, key):
2245 if self._componentTypeLen:
2246 return key in self.componentType
2247 else:
2248 return key in self._dynamicNames
2250 def __len__(self):
2251 return len(self._componentValues)
2253 def __iter__(self):
2254 return iter(self.componentType or self._dynamicNames)
2256 # Python dict protocol
2258 def values(self):
2259 for idx in range(self._componentTypeLen or len(self._dynamicNames)):
2260 yield self[idx]
2262 def keys(self):
2263 return iter(self)
2265 def items(self):
2266 for idx in range(self._componentTypeLen or len(self._dynamicNames)):
2267 if self._componentTypeLen:
2268 yield self.componentType[idx].name, self[idx]
2269 else:
2270 yield self._dynamicNames[idx], self[idx]
2272 def update(self, *iterValue, **mappingValue):
2273 for k, v in iterValue:
2274 self[k] = v
2275 for k in mappingValue:
2276 self[k] = mappingValue[k]
2278 def clear(self):
2279 """Remove all components and become an empty |ASN.1| value object.
2281 Has the same effect on |ASN.1| object as it does on :class:`dict`
2282 built-in.
2283 """
2284 self._componentValues = []
2285 self._dynamicNames = self.DynamicNames()
2286 return self
2288 def reset(self):
2289 """Remove all components and become a |ASN.1| schema object.
2291 See :meth:`isValue` property for more information on the
2292 distinction between value and schema objects.
2293 """
2294 self._componentValues = noValue
2295 self._dynamicNames = self.DynamicNames()
2296 return self
2298 @property
2299 def components(self):
2300 return self._componentValues
2302 def _cloneComponentValues(self, myClone, cloneValueFlag):
2303 if self._componentValues is noValue:
2304 return
2306 for idx, componentValue in enumerate(self._componentValues):
2307 if componentValue is not noValue:
2308 if isinstance(componentValue, base.ConstructedAsn1Type):
2309 myClone.setComponentByPosition(
2310 idx, componentValue.clone(cloneValueFlag=cloneValueFlag)
2311 )
2312 else:
2313 myClone.setComponentByPosition(idx, componentValue.clone())
2315 def getComponentByName(self, name, default=noValue, instantiate=True):
2316 """Returns |ASN.1| type component by name.
2318 Equivalent to Python :class:`dict` subscription operation (e.g. `[]`).
2320 Parameters
2321 ----------
2322 name: :class:`str`
2323 |ASN.1| type component name
2325 Keyword Args
2326 ------------
2327 default: :class:`object`
2328 If set and requested component is a schema object, return the `default`
2329 object instead of the requested component.
2331 instantiate: :class:`bool`
2332 If :obj:`True` (default), inner component will be automatically
2333 instantiated.
2334 If :obj:`False` either existing component or the :class:`NoValue`
2335 object will be returned.
2337 Returns
2338 -------
2339 : :py:class:`~pyasn1.type.base.PyAsn1Item`
2340 Instantiate |ASN.1| component type or return existing
2341 component value
2342 """
2343 if self._componentTypeLen:
2344 idx = self.componentType.getPositionByName(name)
2345 else:
2346 try:
2347 idx = self._dynamicNames.getPositionByName(name)
2349 except KeyError:
2350 raise error.PyAsn1Error('Name %s not found' % (name,))
2352 return self.getComponentByPosition(idx, default=default, instantiate=instantiate)
2354 def setComponentByName(self, name, value=noValue,
2355 verifyConstraints=True,
2356 matchTags=True,
2357 matchConstraints=True):
2358 """Assign |ASN.1| type component by name.
2360 Equivalent to Python :class:`dict` item assignment operation (e.g. `[]`).
2362 Parameters
2363 ----------
2364 name: :class:`str`
2365 |ASN.1| type component name
2367 Keyword Args
2368 ------------
2369 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
2370 A Python value to initialize |ASN.1| component with (if *componentType* is set)
2371 or ASN.1 value object to assign to |ASN.1| component.
2372 If `value` is not given, schema object will be set as a component.
2374 verifyConstraints: :class:`bool`
2375 If :obj:`False`, skip constraints validation
2377 matchTags: :class:`bool`
2378 If :obj:`False`, skip component tags matching
2380 matchConstraints: :class:`bool`
2381 If :obj:`False`, skip component constraints matching
2383 Returns
2384 -------
2385 self
2386 """
2387 if self._componentTypeLen:
2388 idx = self.componentType.getPositionByName(name)
2389 else:
2390 try:
2391 idx = self._dynamicNames.getPositionByName(name)
2393 except KeyError:
2394 raise error.PyAsn1Error('Name %s not found' % (name,))
2396 return self.setComponentByPosition(
2397 idx, value, verifyConstraints, matchTags, matchConstraints
2398 )
2400 def getComponentByPosition(self, idx, default=noValue, instantiate=True):
2401 """Returns |ASN.1| type component by index.
2403 Equivalent to Python sequence subscription operation (e.g. `[]`).
2405 Parameters
2406 ----------
2407 idx: :class:`int`
2408 Component index (zero-based). Must either refer to an existing
2409 component or (if *componentType* is set) new ASN.1 schema object gets
2410 instantiated.
2412 Keyword Args
2413 ------------
2414 default: :class:`object`
2415 If set and requested component is a schema object, return the `default`
2416 object instead of the requested component.
2418 instantiate: :class:`bool`
2419 If :obj:`True` (default), inner component will be automatically
2420 instantiated.
2421 If :obj:`False` either existing component or the :class:`NoValue`
2422 object will be returned.
2424 Returns
2425 -------
2426 : :py:class:`~pyasn1.type.base.PyAsn1Item`
2427 a PyASN1 object
2429 Examples
2430 --------
2432 .. code-block:: python
2434 # can also be Set
2435 class MySequence(Sequence):
2436 componentType = NamedTypes(
2437 NamedType('id', OctetString())
2438 )
2440 s = MySequence()
2442 # returns component #0 with `.isValue` property False
2443 s.getComponentByPosition(0)
2445 # returns None
2446 s.getComponentByPosition(0, default=None)
2448 s.clear()
2450 # returns noValue
2451 s.getComponentByPosition(0, instantiate=False)
2453 # sets component #0 to OctetString() ASN.1 schema
2454 # object and returns it
2455 s.getComponentByPosition(0, instantiate=True)
2457 # sets component #0 to ASN.1 value object
2458 s.setComponentByPosition(0, 'ABCD')
2460 # returns OctetString('ABCD') value object
2461 s.getComponentByPosition(0, instantiate=False)
2463 s.clear()
2465 # returns noValue
2466 s.getComponentByPosition(0, instantiate=False)
2467 """
2468 try:
2469 if self._componentValues is noValue:
2470 componentValue = noValue
2472 else:
2473 componentValue = self._componentValues[idx]
2475 except IndexError:
2476 componentValue = noValue
2478 if not instantiate:
2479 if componentValue is noValue or not componentValue.isValue:
2480 return default
2481 else:
2482 return componentValue
2484 if componentValue is noValue:
2485 self.setComponentByPosition(idx)
2487 componentValue = self._componentValues[idx]
2489 if default is noValue or componentValue.isValue:
2490 return componentValue
2491 else:
2492 return default
2494 def setComponentByPosition(self, idx, value=noValue,
2495 verifyConstraints=True,
2496 matchTags=True,
2497 matchConstraints=True):
2498 """Assign |ASN.1| type component by position.
2500 Equivalent to Python sequence item assignment operation (e.g. `[]`).
2502 Parameters
2503 ----------
2504 idx : :class:`int`
2505 Component index (zero-based). Must either refer to existing
2506 component (if *componentType* is set) or to N+1 component
2507 otherwise. In the latter case a new component of given ASN.1
2508 type gets instantiated and appended to |ASN.1| sequence.
2510 Keyword Args
2511 ------------
2512 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
2513 A Python value to initialize |ASN.1| component with (if *componentType* is set)
2514 or ASN.1 value object to assign to |ASN.1| component.
2515 If `value` is not given, schema object will be set as a component.
2517 verifyConstraints : :class:`bool`
2518 If :obj:`False`, skip constraints validation
2520 matchTags: :class:`bool`
2521 If :obj:`False`, skip component tags matching
2523 matchConstraints: :class:`bool`
2524 If :obj:`False`, skip component constraints matching
2526 Returns
2527 -------
2528 self
2529 """
2530 componentType = self.componentType
2531 componentTypeLen = self._componentTypeLen
2533 if self._componentValues is noValue:
2534 componentValues = []
2536 else:
2537 componentValues = self._componentValues
2539 try:
2540 currentValue = componentValues[idx]
2542 except IndexError:
2543 currentValue = noValue
2544 if componentTypeLen:
2545 if componentTypeLen < idx:
2546 raise error.PyAsn1Error('component index out of range')
2548 componentValues = [noValue] * componentTypeLen
2550 if value is noValue:
2551 if componentTypeLen:
2552 value = componentType.getTypeByPosition(idx)
2553 if isinstance(value, base.ConstructedAsn1Type):
2554 value = value.clone(cloneValueFlag=componentType[idx].isDefaulted)
2556 elif currentValue is noValue:
2557 raise error.PyAsn1Error('Component type not defined')
2559 elif not isinstance(value, base.Asn1Item):
2560 if componentTypeLen:
2561 subComponentType = componentType.getTypeByPosition(idx)
2562 if isinstance(subComponentType, base.SimpleAsn1Type):
2563 value = subComponentType.clone(value=value)
2565 else:
2566 raise error.PyAsn1Error('%s can cast only scalar values' % componentType.__class__.__name__)
2568 elif currentValue is not noValue and isinstance(currentValue, base.SimpleAsn1Type):
2569 value = currentValue.clone(value=value)
2571 else:
2572 raise error.PyAsn1Error('%s undefined component type' % componentType.__class__.__name__)
2574 elif ((verifyConstraints or matchTags or matchConstraints) and
2575 componentTypeLen):
2576 subComponentType = componentType.getTypeByPosition(idx)
2577 if subComponentType is not noValue:
2578 subtypeChecker = (self.strictConstraints and
2579 subComponentType.isSameTypeWith or
2580 subComponentType.isSuperTypeOf)
2582 if not subtypeChecker(value, verifyConstraints and matchTags,
2583 verifyConstraints and matchConstraints):
2584 if not componentType[idx].openType:
2585 raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
2587 if componentTypeLen or idx in self._dynamicNames:
2588 componentValues[idx] = value
2590 elif len(componentValues) == idx:
2591 componentValues.append(value)
2592 self._dynamicNames.addField(idx)
2594 else:
2595 raise error.PyAsn1Error('Component index out of range')
2597 self._componentValues = componentValues
2599 return self
2601 @property
2602 def isValue(self):
2603 """Indicate that |ASN.1| object represents ASN.1 value.
2605 If *isValue* is :obj:`False` then this object represents just ASN.1 schema.
2607 If *isValue* is :obj:`True` then, in addition to its ASN.1 schema features,
2608 this object can also be used like a Python built-in object (e.g.
2609 :class:`int`, :class:`str`, :class:`dict` etc.).
2611 Returns
2612 -------
2613 : :class:`bool`
2614 :obj:`False` if object represents just ASN.1 schema.
2615 :obj:`True` if object represents ASN.1 schema and can be used as a
2616 normal value.
2618 Note
2619 ----
2620 There is an important distinction between PyASN1 schema and value objects.
2621 The PyASN1 schema objects can only participate in ASN.1 schema-related
2622 operations (e.g. defining or testing the structure of the data). Most
2623 obvious uses of ASN.1 schema is to guide serialisation codecs whilst
2624 encoding/decoding serialised ASN.1 contents.
2626 The PyASN1 value objects can **additionally** participate in many operations
2627 involving regular Python objects (e.g. arithmetic, comprehension etc).
2629 It is sufficient for |ASN.1| objects to have all non-optional and non-defaulted
2630 components being value objects to be considered as a value objects as a whole.
2631 In other words, even having one or more optional components not turned into
2632 value objects, |ASN.1| object is still considered as a value object. Defaulted
2633 components are normally value objects by default.
2634 """
2635 if self._componentValues is noValue:
2636 return False
2638 componentType = self.componentType
2640 if componentType:
2641 for idx, subComponentType in enumerate(componentType.namedTypes):
2642 if subComponentType.isDefaulted or subComponentType.isOptional:
2643 continue
2645 if not self._componentValues:
2646 return False
2648 componentValue = self._componentValues[idx]
2649 if componentValue is noValue or not componentValue.isValue:
2650 return False
2652 else:
2653 for componentValue in self._componentValues:
2654 if componentValue is noValue or not componentValue.isValue:
2655 return False
2657 return True
2659 @property
2660 def isInconsistent(self):
2661 """Run necessary checks to ensure |ASN.1| object consistency.
2663 Default action is to verify |ASN.1| object against constraints imposed
2664 by `subtypeSpec`.
2666 Raises
2667 ------
2668 :py:class:`~pyasn1.error.PyAsn1tError` on any inconsistencies found
2669 """
2670 if self.componentType is noValue or not self.subtypeSpec:
2671 return False
2673 if self._componentValues is noValue:
2674 return True
2676 mapping = {}
2678 for idx, value in enumerate(self._componentValues):
2679 # Absent fields are not in the mapping
2680 if value is noValue:
2681 continue
2683 name = self.componentType.getNameByPosition(idx)
2685 mapping[name] = value
2687 try:
2688 # Represent Sequence/Set as a bare dict to constraints chain
2689 self.subtypeSpec(mapping)
2691 except error.PyAsn1Error:
2692 exc = sys.exc_info()[1]
2693 return exc
2695 return False
2697 def prettyPrint(self, scope=0):
2698 """Return an object representation string.
2700 Returns
2701 -------
2702 : :class:`str`
2703 Human-friendly object representation.
2704 """
2705 scope += 1
2706 representation = self.__class__.__name__ + ':\n'
2707 for idx, componentValue in enumerate(self._componentValues):
2708 if componentValue is not noValue and componentValue.isValue:
2709 representation += ' ' * scope
2710 if self.componentType:
2711 representation += self.componentType.getNameByPosition(idx)
2712 else:
2713 representation += self._dynamicNames.getNameByPosition(idx)
2714 representation = '%s=%s\n' % (
2715 representation, componentValue.prettyPrint(scope)
2716 )
2717 return representation
2719 def prettyPrintType(self, scope=0):
2720 scope += 1
2721 representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__)
2722 for idx, componentType in enumerate(self.componentType.values() or self._componentValues):
2723 representation += ' ' * scope
2724 if self.componentType:
2725 representation += '"%s"' % self.componentType.getNameByPosition(idx)
2726 else:
2727 representation += '"%s"' % self._dynamicNames.getNameByPosition(idx)
2728 representation = '%s = %s\n' % (
2729 representation, componentType.prettyPrintType(scope)
2730 )
2731 return representation + '\n' + ' ' * (scope - 1) + '}'
2733 # backward compatibility
2735 def setDefaultComponents(self):
2736 return self
2738 def getComponentType(self):
2739 if self._componentTypeLen:
2740 return self.componentType
2742 def getNameByPosition(self, idx):
2743 if self._componentTypeLen:
2744 return self.componentType[idx].name
2746class Sequence(SequenceAndSetBase):
2747 __doc__ = SequenceAndSetBase.__doc__
2749 #: Set (on class, not on instance) or return a
2750 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
2751 #: associated with |ASN.1| type.
2752 tagSet = tag.initTagSet(
2753 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
2754 )
2756 #: Set (on class, not on instance) or return a
2757 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
2758 #: imposing constraints on |ASN.1| type initialization values.
2759 subtypeSpec = constraint.ConstraintsIntersection()
2761 #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
2762 #: object imposing size constraint on |ASN.1| objects
2763 componentType = namedtype.NamedTypes()
2765 # Disambiguation ASN.1 types identification
2766 typeId = SequenceAndSetBase.getTypeId()
2768 # backward compatibility
2770 def getComponentTagMapNearPosition(self, idx):
2771 if self.componentType:
2772 return self.componentType.getTagMapNearPosition(idx)
2774 def getComponentPositionNearType(self, tagSet, idx):
2775 if self.componentType:
2776 return self.componentType.getPositionNearType(tagSet, idx)
2777 else:
2778 return idx
2781class Set(SequenceAndSetBase):
2782 __doc__ = SequenceAndSetBase.__doc__
2784 #: Set (on class, not on instance) or return a
2785 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
2786 #: associated with |ASN.1| type.
2787 tagSet = tag.initTagSet(
2788 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
2789 )
2791 #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
2792 #: object representing ASN.1 type allowed within |ASN.1| type
2793 componentType = namedtype.NamedTypes()
2795 #: Set (on class, not on instance) or return a
2796 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
2797 #: imposing constraints on |ASN.1| type initialization values.
2798 subtypeSpec = constraint.ConstraintsIntersection()
2800 # Disambiguation ASN.1 types identification
2801 typeId = SequenceAndSetBase.getTypeId()
2803 def getComponent(self, innerFlag=False):
2804 return self
2806 def getComponentByType(self, tagSet, default=noValue,
2807 instantiate=True, innerFlag=False):
2808 """Returns |ASN.1| type component by ASN.1 tag.
2810 Parameters
2811 ----------
2812 tagSet : :py:class:`~pyasn1.type.tag.TagSet`
2813 Object representing ASN.1 tags to identify one of
2814 |ASN.1| object component
2816 Keyword Args
2817 ------------
2818 default: :class:`object`
2819 If set and requested component is a schema object, return the `default`
2820 object instead of the requested component.
2822 instantiate: :class:`bool`
2823 If :obj:`True` (default), inner component will be automatically
2824 instantiated.
2825 If :obj:`False` either existing component or the :class:`noValue`
2826 object will be returned.
2828 Returns
2829 -------
2830 : :py:class:`~pyasn1.type.base.PyAsn1Item`
2831 a pyasn1 object
2832 """
2833 componentValue = self.getComponentByPosition(
2834 self.componentType.getPositionByType(tagSet),
2835 default=default, instantiate=instantiate
2836 )
2837 if innerFlag and isinstance(componentValue, Set):
2838 # get inner component by inner tagSet
2839 return componentValue.getComponent(innerFlag=True)
2840 else:
2841 # get outer component by inner tagSet
2842 return componentValue
2844 def setComponentByType(self, tagSet, value=noValue,
2845 verifyConstraints=True,
2846 matchTags=True,
2847 matchConstraints=True,
2848 innerFlag=False):
2849 """Assign |ASN.1| type component by ASN.1 tag.
2851 Parameters
2852 ----------
2853 tagSet : :py:class:`~pyasn1.type.tag.TagSet`
2854 Object representing ASN.1 tags to identify one of
2855 |ASN.1| object component
2857 Keyword Args
2858 ------------
2859 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
2860 A Python value to initialize |ASN.1| component with (if *componentType* is set)
2861 or ASN.1 value object to assign to |ASN.1| component.
2862 If `value` is not given, schema object will be set as a component.
2864 verifyConstraints : :class:`bool`
2865 If :obj:`False`, skip constraints validation
2867 matchTags: :class:`bool`
2868 If :obj:`False`, skip component tags matching
2870 matchConstraints: :class:`bool`
2871 If :obj:`False`, skip component constraints matching
2873 innerFlag: :class:`bool`
2874 If :obj:`True`, search for matching *tagSet* recursively.
2876 Returns
2877 -------
2878 self
2879 """
2880 idx = self.componentType.getPositionByType(tagSet)
2882 if innerFlag: # set inner component by inner tagSet
2883 componentType = self.componentType.getTypeByPosition(idx)
2885 if componentType.tagSet:
2886 return self.setComponentByPosition(
2887 idx, value, verifyConstraints, matchTags, matchConstraints
2888 )
2889 else:
2890 componentType = self.getComponentByPosition(idx)
2891 return componentType.setComponentByType(
2892 tagSet, value, verifyConstraints, matchTags, matchConstraints, innerFlag=innerFlag
2893 )
2894 else: # set outer component by inner tagSet
2895 return self.setComponentByPosition(
2896 idx, value, verifyConstraints, matchTags, matchConstraints
2897 )
2899 @property
2900 def componentTagMap(self):
2901 if self.componentType:
2902 return self.componentType.tagMapUnique
2905class Choice(Set):
2906 """Create |ASN.1| schema or value object.
2908 |ASN.1| class is based on :class:`~pyasn1.type.base.ConstructedAsn1Type`,
2909 its objects are mutable and duck-type Python :class:`list` objects.
2911 Keyword Args
2912 ------------
2913 componentType: :py:class:`~pyasn1.type.namedtype.NamedType`
2914 Object holding named ASN.1 types allowed within this collection
2916 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
2917 Object representing non-default ASN.1 tag(s)
2919 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
2920 Object representing non-default ASN.1 subtype constraint(s). Constraints
2921 verification for |ASN.1| type can only occur on explicit
2922 `.isInconsistent` call.
2924 Examples
2925 --------
2927 .. code-block:: python
2929 class Afters(Choice):
2930 '''
2931 ASN.1 specification:
2933 Afters ::= CHOICE {
2934 cheese [0] IA5String,
2935 dessert [1] IA5String
2936 }
2937 '''
2938 componentType = NamedTypes(
2939 NamedType('cheese', IA5String().subtype(
2940 implicitTag=Tag(tagClassContext, tagFormatSimple, 0)
2941 ),
2942 NamedType('dessert', IA5String().subtype(
2943 implicitTag=Tag(tagClassContext, tagFormatSimple, 1)
2944 )
2945 )
2947 afters = Afters()
2948 afters['cheese'] = 'Mascarpone'
2949 """
2950 #: Set (on class, not on instance) or return a
2951 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
2952 #: associated with |ASN.1| type.
2953 tagSet = tag.TagSet() # untagged
2955 #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
2956 #: object representing ASN.1 type allowed within |ASN.1| type
2957 componentType = namedtype.NamedTypes()
2959 #: Set (on class, not on instance) or return a
2960 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
2961 #: imposing constraints on |ASN.1| type initialization values.
2962 subtypeSpec = constraint.ConstraintsIntersection(
2963 constraint.ValueSizeConstraint(1, 1)
2964 )
2966 # Disambiguation ASN.1 types identification
2967 typeId = Set.getTypeId()
2969 _currentIdx = None
2971 def __eq__(self, other):
2972 if self._componentValues:
2973 return self._componentValues[self._currentIdx] == other
2974 return NotImplemented
2976 def __ne__(self, other):
2977 if self._componentValues:
2978 return self._componentValues[self._currentIdx] != other
2979 return NotImplemented
2981 def __lt__(self, other):
2982 if self._componentValues:
2983 return self._componentValues[self._currentIdx] < other
2984 return NotImplemented
2986 def __le__(self, other):
2987 if self._componentValues:
2988 return self._componentValues[self._currentIdx] <= other
2989 return NotImplemented
2991 def __gt__(self, other):
2992 if self._componentValues:
2993 return self._componentValues[self._currentIdx] > other
2994 return NotImplemented
2996 def __ge__(self, other):
2997 if self._componentValues:
2998 return self._componentValues[self._currentIdx] >= other
2999 return NotImplemented
3001 if sys.version_info[0] <= 2:
3002 def __nonzero__(self):
3003 return self._componentValues and True or False
3004 else:
3005 def __bool__(self):
3006 return self._componentValues and True or False
3008 def __len__(self):
3009 return self._currentIdx is not None and 1 or 0
3011 def __contains__(self, key):
3012 if self._currentIdx is None:
3013 return False
3014 return key == self.componentType[self._currentIdx].getName()
3016 def __iter__(self):
3017 if self._currentIdx is None:
3018 raise StopIteration
3019 yield self.componentType[self._currentIdx].getName()
3021 # Python dict protocol
3023 def values(self):
3024 if self._currentIdx is not None:
3025 yield self._componentValues[self._currentIdx]
3027 def keys(self):
3028 if self._currentIdx is not None:
3029 yield self.componentType[self._currentIdx].getName()
3031 def items(self):
3032 if self._currentIdx is not None:
3033 yield self.componentType[self._currentIdx].getName(), self[self._currentIdx]
3035 def checkConsistency(self):
3036 if self._currentIdx is None:
3037 raise error.PyAsn1Error('Component not chosen')
3039 def _cloneComponentValues(self, myClone, cloneValueFlag):
3040 try:
3041 component = self.getComponent()
3042 except error.PyAsn1Error:
3043 pass
3044 else:
3045 if isinstance(component, Choice):
3046 tagSet = component.effectiveTagSet
3047 else:
3048 tagSet = component.tagSet
3049 if isinstance(component, base.ConstructedAsn1Type):
3050 myClone.setComponentByType(
3051 tagSet, component.clone(cloneValueFlag=cloneValueFlag)
3052 )
3053 else:
3054 myClone.setComponentByType(tagSet, component.clone())
3056 def getComponentByPosition(self, idx, default=noValue, instantiate=True):
3057 __doc__ = Set.__doc__
3059 if self._currentIdx is None or self._currentIdx != idx:
3060 return Set.getComponentByPosition(self, idx, default=default,
3061 instantiate=instantiate)
3063 return self._componentValues[idx]
3065 def setComponentByPosition(self, idx, value=noValue,
3066 verifyConstraints=True,
3067 matchTags=True,
3068 matchConstraints=True):
3069 """Assign |ASN.1| type component by position.
3071 Equivalent to Python sequence item assignment operation (e.g. `[]`).
3073 Parameters
3074 ----------
3075 idx: :class:`int`
3076 Component index (zero-based). Must either refer to existing
3077 component or to N+1 component. In the latter case a new component
3078 type gets instantiated (if *componentType* is set, or given ASN.1
3079 object is taken otherwise) and appended to the |ASN.1| sequence.
3081 Keyword Args
3082 ------------
3083 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
3084 A Python value to initialize |ASN.1| component with (if *componentType* is set)
3085 or ASN.1 value object to assign to |ASN.1| component. Once a new value is
3086 set to *idx* component, previous value is dropped.
3087 If `value` is not given, schema object will be set as a component.
3089 verifyConstraints : :class:`bool`
3090 If :obj:`False`, skip constraints validation
3092 matchTags: :class:`bool`
3093 If :obj:`False`, skip component tags matching
3095 matchConstraints: :class:`bool`
3096 If :obj:`False`, skip component constraints matching
3098 Returns
3099 -------
3100 self
3101 """
3102 oldIdx = self._currentIdx
3103 Set.setComponentByPosition(self, idx, value, verifyConstraints, matchTags, matchConstraints)
3104 self._currentIdx = idx
3105 if oldIdx is not None and oldIdx != idx:
3106 self._componentValues[oldIdx] = noValue
3107 return self
3109 @property
3110 def effectiveTagSet(self):
3111 """Return a :class:`~pyasn1.type.tag.TagSet` object of the currently initialized component or self (if |ASN.1| is tagged)."""
3112 if self.tagSet:
3113 return self.tagSet
3114 else:
3115 component = self.getComponent()
3116 return component.effectiveTagSet
3118 @property
3119 def tagMap(self):
3120 """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping
3121 ASN.1 tags to ASN.1 objects contained within callee.
3122 """
3123 if self.tagSet:
3124 return Set.tagMap.fget(self)
3125 else:
3126 return self.componentType.tagMapUnique
3128 def getComponent(self, innerFlag=False):
3129 """Return currently assigned component of the |ASN.1| object.
3131 Returns
3132 -------
3133 : :py:class:`~pyasn1.type.base.PyAsn1Item`
3134 a PyASN1 object
3135 """
3136 if self._currentIdx is None:
3137 raise error.PyAsn1Error('Component not chosen')
3138 else:
3139 c = self._componentValues[self._currentIdx]
3140 if innerFlag and isinstance(c, Choice):
3141 return c.getComponent(innerFlag)
3142 else:
3143 return c
3145 def getName(self, innerFlag=False):
3146 """Return the name of currently assigned component of the |ASN.1| object.
3148 Returns
3149 -------
3150 : :py:class:`str`
3151 |ASN.1| component name
3152 """
3153 if self._currentIdx is None:
3154 raise error.PyAsn1Error('Component not chosen')
3155 else:
3156 if innerFlag:
3157 c = self._componentValues[self._currentIdx]
3158 if isinstance(c, Choice):
3159 return c.getName(innerFlag)
3160 return self.componentType.getNameByPosition(self._currentIdx)
3162 @property
3163 def isValue(self):
3164 """Indicate that |ASN.1| object represents ASN.1 value.
3166 If *isValue* is :obj:`False` then this object represents just ASN.1 schema.
3168 If *isValue* is :obj:`True` then, in addition to its ASN.1 schema features,
3169 this object can also be used like a Python built-in object (e.g.
3170 :class:`int`, :class:`str`, :class:`dict` etc.).
3172 Returns
3173 -------
3174 : :class:`bool`
3175 :obj:`False` if object represents just ASN.1 schema.
3176 :obj:`True` if object represents ASN.1 schema and can be used as a normal
3177 value.
3179 Note
3180 ----
3181 There is an important distinction between PyASN1 schema and value objects.
3182 The PyASN1 schema objects can only participate in ASN.1 schema-related
3183 operations (e.g. defining or testing the structure of the data). Most
3184 obvious uses of ASN.1 schema is to guide serialisation codecs whilst
3185 encoding/decoding serialised ASN.1 contents.
3187 The PyASN1 value objects can **additionally** participate in many operations
3188 involving regular Python objects (e.g. arithmetic, comprehension etc).
3189 """
3190 if self._currentIdx is None:
3191 return False
3193 componentValue = self._componentValues[self._currentIdx]
3195 return componentValue is not noValue and componentValue.isValue
3197 def clear(self):
3198 self._currentIdx = None
3199 return Set.clear(self)
3201 # compatibility stubs
3203 def getMinTagSet(self):
3204 return self.minTagSet
3207class Any(OctetString):
3208 """Create |ASN.1| schema or value object.
3210 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`,
3211 its objects are immutable and duck-type Python 2 :class:`str` or Python 3
3212 :class:`bytes`. When used in Unicode context, |ASN.1| type assumes
3213 "|encoding|" serialisation.
3215 Keyword Args
3216 ------------
3217 value: :class:`unicode`, :class:`str`, :class:`bytes` or |ASN.1| object
3218 :class:`str` (Python 2) or :class:`bytes` (Python 3), alternatively
3219 :class:`unicode` object (Python 2) or :class:`str` (Python 3)
3220 representing character string to be serialised into octets (note
3221 `encoding` parameter) or |ASN.1| object.
3222 If `value` is not given, schema object will be created.
3224 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
3225 Object representing non-default ASN.1 tag(s)
3227 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
3228 Object representing non-default ASN.1 subtype constraint(s). Constraints
3229 verification for |ASN.1| type occurs automatically on object
3230 instantiation.
3232 encoding: :py:class:`str`
3233 Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
3234 :class:`str` (Python 3) the payload when |ASN.1| object is used
3235 in text string context.
3237 binValue: :py:class:`str`
3238 Binary string initializer to use instead of the *value*.
3239 Example: '10110011'.
3241 hexValue: :py:class:`str`
3242 Hexadecimal string initializer to use instead of the *value*.
3243 Example: 'DEADBEEF'.
3245 Raises
3246 ------
3247 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
3248 On constraint violation or bad initializer.
3250 Examples
3251 --------
3252 .. code-block:: python
3254 class Error(Sequence):
3255 '''
3256 ASN.1 specification:
3258 Error ::= SEQUENCE {
3259 code INTEGER,
3260 parameter ANY DEFINED BY code -- Either INTEGER or REAL
3261 }
3262 '''
3263 componentType=NamedTypes(
3264 NamedType('code', Integer()),
3265 NamedType('parameter', Any(),
3266 openType=OpenType('code', {1: Integer(),
3267 2: Real()}))
3268 )
3270 error = Error()
3271 error['code'] = 1
3272 error['parameter'] = Integer(1234)
3273 """
3274 #: Set (on class, not on instance) or return a
3275 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
3276 #: associated with |ASN.1| type.
3277 tagSet = tag.TagSet() # untagged
3279 #: Set (on class, not on instance) or return a
3280 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
3281 #: imposing constraints on |ASN.1| type initialization values.
3282 subtypeSpec = constraint.ConstraintsIntersection()
3284 # Disambiguation ASN.1 types identification
3285 typeId = OctetString.getTypeId()
3287 @property
3288 def tagMap(self):
3289 """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping
3290 ASN.1 tags to ASN.1 objects contained within callee.
3291 """
3292 try:
3293 return self._tagMap
3295 except AttributeError:
3296 self._tagMap = tagmap.TagMap(
3297 {self.tagSet: self},
3298 {eoo.endOfOctets.tagSet: eoo.endOfOctets},
3299 self
3300 )
3302 return self._tagMap
3304# XXX
3305# coercion rules?