Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pyasn1/type/univ.py: 38%
1274 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 07:30 +0000
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 07:30 +0000
1#
2# This file is part of pyasn1 software.
3#
4# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
5# License: http://snmplabs.com/pyasn1/license.html
6#
7import math
8import sys
10from pyasn1 import error
11from pyasn1.codec.ber import eoo
12from pyasn1.compat import binary
13from pyasn1.compat import integer
14from pyasn1.compat import octets
15from pyasn1.type import base
16from pyasn1.type import constraint
17from pyasn1.type import namedtype
18from pyasn1.type import namedval
19from pyasn1.type import tag
20from pyasn1.type import tagmap
22NoValue = base.NoValue
23noValue = NoValue()
25__all__ = ['Integer', 'Boolean', 'BitString', 'OctetString', 'Null',
26 'ObjectIdentifier', 'Real', 'Enumerated',
27 'SequenceOfAndSetOfBase', 'SequenceOf', 'SetOf',
28 'SequenceAndSetBase', 'Sequence', 'Set', 'Choice', 'Any',
29 'NoValue', 'noValue']
31# "Simple" ASN.1 types (yet incomplete)
34class Integer(base.SimpleAsn1Type):
35 """Create |ASN.1| schema or value object.
37 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its
38 objects are immutable and duck-type Python :class:`int` objects.
40 Keyword Args
41 ------------
42 value: :class:`int`, :class:`str` or |ASN.1| object
43 Python :class:`int` or :class:`str` literal or |ASN.1| class
44 instance. If `value` is not given, schema object will be created.
46 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
47 Object representing non-default ASN.1 tag(s)
49 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
50 Object representing non-default ASN.1 subtype constraint(s). Constraints
51 verification for |ASN.1| type occurs automatically on object
52 instantiation.
54 namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
55 Object representing non-default symbolic aliases for numbers
57 Raises
58 ------
59 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
60 On constraint violation or bad initializer.
62 Examples
63 --------
65 .. code-block:: python
67 class ErrorCode(Integer):
68 '''
69 ASN.1 specification:
71 ErrorCode ::=
72 INTEGER { disk-full(1), no-disk(-1),
73 disk-not-formatted(2) }
75 error ErrorCode ::= disk-full
76 '''
77 namedValues = NamedValues(
78 ('disk-full', 1), ('no-disk', -1),
79 ('disk-not-formatted', 2)
80 )
82 error = ErrorCode('disk-full')
83 """
84 #: Set (on class, not on instance) or return a
85 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
86 #: associated with |ASN.1| type.
87 tagSet = tag.initTagSet(
88 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x02)
89 )
91 #: Set (on class, not on instance) or return a
92 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
93 #: imposing constraints on |ASN.1| type initialization values.
94 subtypeSpec = constraint.ConstraintsIntersection()
96 #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
97 #: representing symbolic aliases for numbers
98 namedValues = namedval.NamedValues()
100 # Optimization for faster codec lookup
101 typeId = base.SimpleAsn1Type.getTypeId()
103 def __init__(self, value=noValue, **kwargs):
104 if 'namedValues' not in kwargs:
105 kwargs['namedValues'] = self.namedValues
107 base.SimpleAsn1Type.__init__(self, value, **kwargs)
109 def __and__(self, value):
110 return self.clone(self._value & value)
112 def __rand__(self, value):
113 return self.clone(value & self._value)
115 def __or__(self, value):
116 return self.clone(self._value | value)
118 def __ror__(self, value):
119 return self.clone(value | self._value)
121 def __xor__(self, value):
122 return self.clone(self._value ^ value)
124 def __rxor__(self, value):
125 return self.clone(value ^ self._value)
127 def __lshift__(self, value):
128 return self.clone(self._value << value)
130 def __rshift__(self, value):
131 return self.clone(self._value >> value)
133 def __add__(self, value):
134 return self.clone(self._value + value)
136 def __radd__(self, value):
137 return self.clone(value + self._value)
139 def __sub__(self, value):
140 return self.clone(self._value - value)
142 def __rsub__(self, value):
143 return self.clone(value - self._value)
145 def __mul__(self, value):
146 return self.clone(self._value * value)
148 def __rmul__(self, value):
149 return self.clone(value * self._value)
151 def __mod__(self, value):
152 return self.clone(self._value % value)
154 def __rmod__(self, value):
155 return self.clone(value % self._value)
157 def __pow__(self, value, modulo=None):
158 return self.clone(pow(self._value, value, modulo))
160 def __rpow__(self, value):
161 return self.clone(pow(value, self._value))
163 def __floordiv__(self, value):
164 return self.clone(self._value // value)
166 def __rfloordiv__(self, value):
167 return self.clone(value // self._value)
169 if sys.version_info[0] <= 2:
170 def __div__(self, value):
171 if isinstance(value, float):
172 return Real(self._value / value)
173 else:
174 return self.clone(self._value / value)
176 def __rdiv__(self, value):
177 if isinstance(value, float):
178 return Real(value / self._value)
179 else:
180 return self.clone(value / self._value)
181 else:
182 def __truediv__(self, value):
183 return Real(self._value / value)
185 def __rtruediv__(self, value):
186 return Real(value / self._value)
188 def __divmod__(self, value):
189 return self.clone(divmod(self._value, value))
191 def __rdivmod__(self, value):
192 return self.clone(divmod(value, self._value))
194 __hash__ = base.SimpleAsn1Type.__hash__
196 def __int__(self):
197 return int(self._value)
199 if sys.version_info[0] <= 2:
200 def __long__(self):
201 return long(self._value)
203 def __float__(self):
204 return float(self._value)
206 def __abs__(self):
207 return self.clone(abs(self._value))
209 def __index__(self):
210 return int(self._value)
212 def __pos__(self):
213 return self.clone(+self._value)
215 def __neg__(self):
216 return self.clone(-self._value)
218 def __invert__(self):
219 return self.clone(~self._value)
221 def __round__(self, n=0):
222 r = round(self._value, n)
223 if n:
224 return self.clone(r)
225 else:
226 return r
228 def __floor__(self):
229 return math.floor(self._value)
231 def __ceil__(self):
232 return math.ceil(self._value)
234 if sys.version_info[0:2] > (2, 5):
235 def __trunc__(self):
236 return self.clone(math.trunc(self._value))
238 def __lt__(self, value):
239 return self._value < value
241 def __le__(self, value):
242 return self._value <= value
244 def __eq__(self, value):
245 return self._value == value
247 def __ne__(self, value):
248 return self._value != value
250 def __gt__(self, value):
251 return self._value > value
253 def __ge__(self, value):
254 return self._value >= value
256 def prettyIn(self, value):
257 try:
258 return int(value)
260 except ValueError:
261 try:
262 return self.namedValues[value]
264 except KeyError:
265 raise error.PyAsn1Error(
266 'Can\'t coerce %r into integer: %s' % (value, sys.exc_info()[1])
267 )
269 def prettyOut(self, value):
270 try:
271 return str(self.namedValues[value])
273 except KeyError:
274 return str(value)
276 # backward compatibility
278 def getNamedValues(self):
279 return self.namedValues
282class Boolean(Integer):
283 """Create |ASN.1| schema or value object.
285 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its
286 objects are immutable and duck-type Python :class:`int` objects.
288 Keyword Args
289 ------------
290 value: :class:`int`, :class:`str` or |ASN.1| object
291 Python :class:`int` or :class:`str` literal or |ASN.1| class
292 instance. If `value` is not given, schema object will be created.
294 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
295 Object representing non-default ASN.1 tag(s)
297 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
298 Object representing non-default ASN.1 subtype constraint(s).Constraints
299 verification for |ASN.1| type occurs automatically on object
300 instantiation.
302 namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
303 Object representing non-default symbolic aliases for numbers
305 Raises
306 ------
307 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
308 On constraint violation or bad initializer.
310 Examples
311 --------
312 .. code-block:: python
314 class RoundResult(Boolean):
315 '''
316 ASN.1 specification:
318 RoundResult ::= BOOLEAN
320 ok RoundResult ::= TRUE
321 ko RoundResult ::= FALSE
322 '''
323 ok = RoundResult(True)
324 ko = RoundResult(False)
325 """
326 #: Set (on class, not on instance) or return a
327 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
328 #: associated with |ASN.1| type.
329 tagSet = tag.initTagSet(
330 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x01),
331 )
333 #: Set (on class, not on instance) or return a
334 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
335 #: imposing constraints on |ASN.1| type initialization values.
336 subtypeSpec = Integer.subtypeSpec + constraint.SingleValueConstraint(0, 1)
338 #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
339 #: representing symbolic aliases for numbers
340 namedValues = namedval.NamedValues(('False', 0), ('True', 1))
342 # Optimization for faster codec lookup
343 typeId = Integer.getTypeId()
345if sys.version_info[0] < 3:
346 SizedIntegerBase = long
347else:
348 SizedIntegerBase = int
351class SizedInteger(SizedIntegerBase):
352 bitLength = leadingZeroBits = None
354 def setBitLength(self, bitLength):
355 self.bitLength = bitLength
356 self.leadingZeroBits = max(bitLength - integer.bitLength(self), 0)
357 return self
359 def __len__(self):
360 if self.bitLength is None:
361 self.setBitLength(integer.bitLength(self))
363 return self.bitLength
366class BitString(base.SimpleAsn1Type):
367 """Create |ASN.1| schema or value object.
369 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its
370 objects are immutable and duck-type both Python :class:`tuple` (as a tuple
371 of bits) and :class:`int` objects.
373 Keyword Args
374 ------------
375 value: :class:`int`, :class:`str` or |ASN.1| object
376 Python :class:`int` or :class:`str` literal representing binary
377 or hexadecimal number or sequence of integer bits or |ASN.1| object.
378 If `value` is not given, schema object will be created.
380 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
381 Object representing non-default ASN.1 tag(s)
383 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
384 Object representing non-default ASN.1 subtype constraint(s). Constraints
385 verification for |ASN.1| type occurs automatically on object
386 instantiation.
388 namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
389 Object representing non-default symbolic aliases for numbers
391 binValue: :py:class:`str`
392 Binary string initializer to use instead of the *value*.
393 Example: '10110011'.
395 hexValue: :py:class:`str`
396 Hexadecimal string initializer to use instead of the *value*.
397 Example: 'DEADBEEF'.
399 Raises
400 ------
401 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
402 On constraint violation or bad initializer.
404 Examples
405 --------
406 .. code-block:: python
408 class Rights(BitString):
409 '''
410 ASN.1 specification:
412 Rights ::= BIT STRING { user-read(0), user-write(1),
413 group-read(2), group-write(3),
414 other-read(4), other-write(5) }
416 group1 Rights ::= { group-read, group-write }
417 group2 Rights ::= '0011'B
418 group3 Rights ::= '3'H
419 '''
420 namedValues = NamedValues(
421 ('user-read', 0), ('user-write', 1),
422 ('group-read', 2), ('group-write', 3),
423 ('other-read', 4), ('other-write', 5)
424 )
426 group1 = Rights(('group-read', 'group-write'))
427 group2 = Rights('0011')
428 group3 = Rights(0x3)
429 """
430 #: Set (on class, not on instance) or return a
431 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
432 #: associated with |ASN.1| type.
433 tagSet = tag.initTagSet(
434 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x03)
435 )
437 #: Set (on class, not on instance) or return a
438 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
439 #: imposing constraints on |ASN.1| type initialization values.
440 subtypeSpec = constraint.ConstraintsIntersection()
442 #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
443 #: representing symbolic aliases for numbers
444 namedValues = namedval.NamedValues()
446 # Optimization for faster codec lookup
447 typeId = base.SimpleAsn1Type.getTypeId()
449 defaultBinValue = defaultHexValue = noValue
451 def __init__(self, value=noValue, **kwargs):
452 if value is noValue:
453 if kwargs:
454 try:
455 value = self.fromBinaryString(kwargs.pop('binValue'), internalFormat=True)
457 except KeyError:
458 pass
460 try:
461 value = self.fromHexString(kwargs.pop('hexValue'), internalFormat=True)
463 except KeyError:
464 pass
466 if value is noValue:
467 if self.defaultBinValue is not noValue:
468 value = self.fromBinaryString(self.defaultBinValue, internalFormat=True)
470 elif self.defaultHexValue is not noValue:
471 value = self.fromHexString(self.defaultHexValue, internalFormat=True)
473 if 'namedValues' not in kwargs:
474 kwargs['namedValues'] = self.namedValues
476 base.SimpleAsn1Type.__init__(self, value, **kwargs)
478 def __str__(self):
479 return self.asBinary()
481 def __eq__(self, other):
482 other = self.prettyIn(other)
483 return self is other or self._value == other and len(self._value) == len(other)
485 def __ne__(self, other):
486 other = self.prettyIn(other)
487 return self._value != other or len(self._value) != len(other)
489 def __lt__(self, other):
490 other = self.prettyIn(other)
491 return len(self._value) < len(other) or len(self._value) == len(other) and self._value < other
493 def __le__(self, other):
494 other = self.prettyIn(other)
495 return len(self._value) <= len(other) or len(self._value) == len(other) and self._value <= other
497 def __gt__(self, other):
498 other = self.prettyIn(other)
499 return len(self._value) > len(other) or len(self._value) == len(other) and self._value > other
501 def __ge__(self, other):
502 other = self.prettyIn(other)
503 return len(self._value) >= len(other) or len(self._value) == len(other) and self._value >= other
505 # Immutable sequence object protocol
507 def __len__(self):
508 return len(self._value)
510 def __getitem__(self, i):
511 if i.__class__ is slice:
512 return self.clone([self[x] for x in range(*i.indices(len(self)))])
513 else:
514 length = len(self._value) - 1
515 if i > length or i < 0:
516 raise IndexError('bit index out of range')
517 return (self._value >> (length - i)) & 1
519 def __iter__(self):
520 length = len(self._value)
521 while length:
522 length -= 1
523 yield (self._value >> length) & 1
525 def __reversed__(self):
526 return reversed(tuple(self))
528 # arithmetic operators
530 def __add__(self, value):
531 value = self.prettyIn(value)
532 return self.clone(SizedInteger(self._value << len(value) | value).setBitLength(len(self._value) + len(value)))
534 def __radd__(self, value):
535 value = self.prettyIn(value)
536 return self.clone(SizedInteger(value << len(self._value) | self._value).setBitLength(len(self._value) + len(value)))
538 def __mul__(self, value):
539 bitString = self._value
540 while value > 1:
541 bitString <<= len(self._value)
542 bitString |= self._value
543 value -= 1
544 return self.clone(bitString)
546 def __rmul__(self, value):
547 return self * value
549 def __lshift__(self, count):
550 return self.clone(SizedInteger(self._value << count).setBitLength(len(self._value) + count))
552 def __rshift__(self, count):
553 return self.clone(SizedInteger(self._value >> count).setBitLength(max(0, len(self._value) - count)))
555 def __int__(self):
556 return self._value
558 def __float__(self):
559 return float(self._value)
561 if sys.version_info[0] < 3:
562 def __long__(self):
563 return self._value
565 def asNumbers(self):
566 """Get |ASN.1| value as a sequence of 8-bit integers.
568 If |ASN.1| object length is not a multiple of 8, result
569 will be left-padded with zeros.
570 """
571 return tuple(octets.octs2ints(self.asOctets()))
573 def asOctets(self):
574 """Get |ASN.1| value as a sequence of octets.
576 If |ASN.1| object length is not a multiple of 8, result
577 will be left-padded with zeros.
578 """
579 return integer.to_bytes(self._value, length=len(self))
581 def asInteger(self):
582 """Get |ASN.1| value as a single integer value.
583 """
584 return self._value
586 def asBinary(self):
587 """Get |ASN.1| value as a text string of bits.
588 """
589 binString = binary.bin(self._value)[2:]
590 return '0' * (len(self._value) - len(binString)) + binString
592 @classmethod
593 def fromHexString(cls, value, internalFormat=False, prepend=None):
594 """Create a |ASN.1| object initialized from the hex string.
596 Parameters
597 ----------
598 value: :class:`str`
599 Text string like 'DEADBEEF'
600 """
601 try:
602 value = SizedInteger(value, 16).setBitLength(len(value) * 4)
604 except ValueError:
605 raise error.PyAsn1Error('%s.fromHexString() error: %s' % (cls.__name__, sys.exc_info()[1]))
607 if prepend is not None:
608 value = SizedInteger(
609 (SizedInteger(prepend) << len(value)) | value
610 ).setBitLength(len(prepend) + len(value))
612 if not internalFormat:
613 value = cls(value)
615 return value
617 @classmethod
618 def fromBinaryString(cls, value, internalFormat=False, prepend=None):
619 """Create a |ASN.1| object initialized from a string of '0' and '1'.
621 Parameters
622 ----------
623 value: :class:`str`
624 Text string like '1010111'
625 """
626 try:
627 value = SizedInteger(value or '0', 2).setBitLength(len(value))
629 except ValueError:
630 raise error.PyAsn1Error('%s.fromBinaryString() error: %s' % (cls.__name__, sys.exc_info()[1]))
632 if prepend is not None:
633 value = SizedInteger(
634 (SizedInteger(prepend) << len(value)) | value
635 ).setBitLength(len(prepend) + len(value))
637 if not internalFormat:
638 value = cls(value)
640 return value
642 @classmethod
643 def fromOctetString(cls, value, internalFormat=False, prepend=None, padding=0):
644 """Create a |ASN.1| object initialized from a string.
646 Parameters
647 ----------
648 value: :class:`str` (Py2) or :class:`bytes` (Py3)
649 Text string like '\\\\x01\\\\xff' (Py2) or b'\\\\x01\\\\xff' (Py3)
650 """
651 value = SizedInteger(integer.from_bytes(value) >> padding).setBitLength(len(value) * 8 - padding)
653 if prepend is not None:
654 value = SizedInteger(
655 (SizedInteger(prepend) << len(value)) | value
656 ).setBitLength(len(prepend) + len(value))
658 if not internalFormat:
659 value = cls(value)
661 return value
663 def prettyIn(self, value):
664 if isinstance(value, SizedInteger):
665 return value
666 elif octets.isStringType(value):
667 if not value:
668 return SizedInteger(0).setBitLength(0)
670 elif value[0] == '\'': # "'1011'B" -- ASN.1 schema representation (deprecated)
671 if value[-2:] == '\'B':
672 return self.fromBinaryString(value[1:-2], internalFormat=True)
673 elif value[-2:] == '\'H':
674 return self.fromHexString(value[1:-2], internalFormat=True)
675 else:
676 raise error.PyAsn1Error(
677 'Bad BIT STRING value notation %s' % (value,)
678 )
680 elif self.namedValues and not value.isdigit(): # named bits like 'Urgent, Active'
681 names = [x.strip() for x in value.split(',')]
683 try:
685 bitPositions = [self.namedValues[name] for name in names]
687 except KeyError:
688 raise error.PyAsn1Error('unknown bit name(s) in %r' % (names,))
690 rightmostPosition = max(bitPositions)
692 number = 0
693 for bitPosition in bitPositions:
694 number |= 1 << (rightmostPosition - bitPosition)
696 return SizedInteger(number).setBitLength(rightmostPosition + 1)
698 elif value.startswith('0x'):
699 return self.fromHexString(value[2:], internalFormat=True)
701 elif value.startswith('0b'):
702 return self.fromBinaryString(value[2:], internalFormat=True)
704 else: # assume plain binary string like '1011'
705 return self.fromBinaryString(value, internalFormat=True)
707 elif isinstance(value, (tuple, list)):
708 return self.fromBinaryString(''.join([b and '1' or '0' for b in value]), internalFormat=True)
710 elif isinstance(value, BitString):
711 return SizedInteger(value).setBitLength(len(value))
713 elif isinstance(value, intTypes):
714 return SizedInteger(value)
716 else:
717 raise error.PyAsn1Error(
718 'Bad BitString initializer type \'%s\'' % (value,)
719 )
722try:
723 # noinspection PyStatementEffect
724 all
726except NameError: # Python 2.4
727 # noinspection PyShadowingBuiltins
728 def all(iterable):
729 for element in iterable:
730 if not element:
731 return False
732 return True
735class OctetString(base.SimpleAsn1Type):
736 """Create |ASN.1| schema or value object.
738 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its
739 objects are immutable and duck-type Python 2 :class:`str` or
740 Python 3 :class:`bytes`. When used in Unicode context, |ASN.1| type
741 assumes "|encoding|" serialisation.
743 Keyword Args
744 ------------
745 value: :class:`unicode`, :class:`str`, :class:`bytes` or |ASN.1| object
746 class:`str` (Python 2) or :class:`bytes` (Python 3), alternatively
747 class:`unicode` object (Python 2) or :class:`str` (Python 3)
748 representing character string to be serialised into octets
749 (note `encoding` parameter) or |ASN.1| object.
750 If `value` is not given, schema object will be created.
752 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
753 Object representing non-default ASN.1 tag(s)
755 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
756 Object representing non-default ASN.1 subtype constraint(s). Constraints
757 verification for |ASN.1| type occurs automatically on object
758 instantiation.
760 encoding: :py:class:`str`
761 Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
762 :class:`str` (Python 3) the payload when |ASN.1| object is used
763 in text string context.
765 binValue: :py:class:`str`
766 Binary string initializer to use instead of the *value*.
767 Example: '10110011'.
769 hexValue: :py:class:`str`
770 Hexadecimal string initializer to use instead of the *value*.
771 Example: 'DEADBEEF'.
773 Raises
774 ------
775 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
776 On constraint violation or bad initializer.
778 Examples
779 --------
780 .. code-block:: python
782 class Icon(OctetString):
783 '''
784 ASN.1 specification:
786 Icon ::= OCTET STRING
788 icon1 Icon ::= '001100010011001000110011'B
789 icon2 Icon ::= '313233'H
790 '''
791 icon1 = Icon.fromBinaryString('001100010011001000110011')
792 icon2 = Icon.fromHexString('313233')
793 """
794 #: Set (on class, not on instance) or return a
795 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
796 #: associated with |ASN.1| type.
797 tagSet = tag.initTagSet(
798 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x04)
799 )
801 #: Set (on class, not on instance) or return a
802 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
803 #: imposing constraints on |ASN.1| type initialization values.
804 subtypeSpec = constraint.ConstraintsIntersection()
806 # Optimization for faster codec lookup
807 typeId = base.SimpleAsn1Type.getTypeId()
809 defaultBinValue = defaultHexValue = noValue
810 encoding = 'iso-8859-1'
812 def __init__(self, value=noValue, **kwargs):
813 if kwargs:
814 if value is noValue:
815 try:
816 value = self.fromBinaryString(kwargs.pop('binValue'))
818 except KeyError:
819 pass
821 try:
822 value = self.fromHexString(kwargs.pop('hexValue'))
824 except KeyError:
825 pass
827 if value is noValue:
828 if self.defaultBinValue is not noValue:
829 value = self.fromBinaryString(self.defaultBinValue)
831 elif self.defaultHexValue is not noValue:
832 value = self.fromHexString(self.defaultHexValue)
834 if 'encoding' not in kwargs:
835 kwargs['encoding'] = self.encoding
837 base.SimpleAsn1Type.__init__(self, value, **kwargs)
839 if sys.version_info[0] <= 2:
840 def prettyIn(self, value):
841 if isinstance(value, str):
842 return value
844 elif isinstance(value, unicode):
845 try:
846 return value.encode(self.encoding)
848 except (LookupError, UnicodeEncodeError):
849 exc = sys.exc_info()[1]
850 raise error.PyAsn1UnicodeEncodeError(
851 "Can't encode string '%s' with codec "
852 "%s" % (value, self.encoding), exc
853 )
855 elif isinstance(value, (tuple, list)):
856 try:
857 return ''.join([chr(x) for x in value])
859 except ValueError:
860 raise error.PyAsn1Error(
861 "Bad %s initializer '%s'" % (self.__class__.__name__, value)
862 )
864 else:
865 return str(value)
867 def __str__(self):
868 return str(self._value)
870 def __unicode__(self):
871 try:
872 return self._value.decode(self.encoding)
874 except UnicodeDecodeError:
875 exc = sys.exc_info()[1]
876 raise error.PyAsn1UnicodeDecodeError(
877 "Can't decode string '%s' with codec "
878 "%s" % (self._value, self.encoding), exc
879 )
881 def asOctets(self):
882 return str(self._value)
884 def asNumbers(self):
885 return tuple([ord(x) for x in self._value])
887 else:
888 def prettyIn(self, value):
889 if isinstance(value, bytes):
890 return value
892 elif isinstance(value, str):
893 try:
894 return value.encode(self.encoding)
896 except UnicodeEncodeError:
897 exc = sys.exc_info()[1]
898 raise error.PyAsn1UnicodeEncodeError(
899 "Can't encode string '%s' with '%s' "
900 "codec" % (value, self.encoding), exc
901 )
902 elif isinstance(value, OctetString): # a shortcut, bytes() would work the same way
903 return value.asOctets()
905 elif isinstance(value, base.SimpleAsn1Type): # this mostly targets Integer objects
906 return self.prettyIn(str(value))
908 elif isinstance(value, (tuple, list)):
909 return self.prettyIn(bytes(value))
911 else:
912 return bytes(value)
914 def __str__(self):
915 try:
916 return self._value.decode(self.encoding)
918 except UnicodeDecodeError:
919 exc = sys.exc_info()[1]
920 raise error.PyAsn1UnicodeDecodeError(
921 "Can't decode string '%s' with '%s' codec at "
922 "'%s'" % (self._value, self.encoding,
923 self.__class__.__name__), exc
924 )
926 def __bytes__(self):
927 return bytes(self._value)
929 def asOctets(self):
930 return bytes(self._value)
932 def asNumbers(self):
933 return tuple(self._value)
935 #
936 # Normally, `.prettyPrint()` is called from `__str__()`. Historically,
937 # OctetString.prettyPrint() used to return hexified payload
938 # representation in cases when non-printable content is present. At the
939 # same time `str()` used to produce either octet-stream (Py2) or
940 # text (Py3) representations.
941 #
942 # Therefore `OctetString.__str__()` -> `.prettyPrint()` call chain is
943 # reversed to preserve the original behaviour.
944 #
945 # Eventually we should deprecate `.prettyPrint()` / `.prettyOut()` harness
946 # and end up with just `__str__()` producing hexified representation while
947 # both text and octet-stream representation should only be requested via
948 # the `.asOctets()` method.
949 #
950 # Note: ASN.1 OCTET STRING is never mean to contain text!
951 #
953 def prettyOut(self, value):
954 return value
956 def prettyPrint(self, scope=0):
957 # first see if subclass has its own .prettyOut()
958 value = self.prettyOut(self._value)
960 if value is not self._value:
961 return value
963 numbers = self.asNumbers()
965 for x in numbers:
966 # hexify if needed
967 if x < 32 or x > 126:
968 return '0x' + ''.join(('%.2x' % x for x in numbers))
969 else:
970 # this prevents infinite recursion
971 return OctetString.__str__(self)
973 @staticmethod
974 def fromBinaryString(value):
975 """Create a |ASN.1| object initialized from a string of '0' and '1'.
977 Parameters
978 ----------
979 value: :class:`str`
980 Text string like '1010111'
981 """
982 bitNo = 8
983 byte = 0
984 r = []
985 for v in value:
986 if bitNo:
987 bitNo -= 1
988 else:
989 bitNo = 7
990 r.append(byte)
991 byte = 0
992 if v in ('0', '1'):
993 v = int(v)
994 else:
995 raise error.PyAsn1Error(
996 'Non-binary OCTET STRING initializer %s' % (v,)
997 )
998 byte |= v << bitNo
1000 r.append(byte)
1002 return octets.ints2octs(r)
1004 @staticmethod
1005 def fromHexString(value):
1006 """Create a |ASN.1| object initialized from the hex string.
1008 Parameters
1009 ----------
1010 value: :class:`str`
1011 Text string like 'DEADBEEF'
1012 """
1013 r = []
1014 p = []
1015 for v in value:
1016 if p:
1017 r.append(int(p + v, 16))
1018 p = None
1019 else:
1020 p = v
1021 if p:
1022 r.append(int(p + '0', 16))
1024 return octets.ints2octs(r)
1026 # Immutable sequence object protocol
1028 def __len__(self):
1029 return len(self._value)
1031 def __getitem__(self, i):
1032 if i.__class__ is slice:
1033 return self.clone(self._value[i])
1034 else:
1035 return self._value[i]
1037 def __iter__(self):
1038 return iter(self._value)
1040 def __contains__(self, value):
1041 return value in self._value
1043 def __add__(self, value):
1044 return self.clone(self._value + self.prettyIn(value))
1046 def __radd__(self, value):
1047 return self.clone(self.prettyIn(value) + self._value)
1049 def __mul__(self, value):
1050 return self.clone(self._value * value)
1052 def __rmul__(self, value):
1053 return self * value
1055 def __int__(self):
1056 return int(self._value)
1058 def __float__(self):
1059 return float(self._value)
1061 def __reversed__(self):
1062 return reversed(self._value)
1065class Null(OctetString):
1066 """Create |ASN.1| schema or value object.
1068 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its
1069 objects are immutable and duck-type Python :class:`str` objects
1070 (always empty).
1072 Keyword Args
1073 ------------
1074 value: :class:`str` or |ASN.1| object
1075 Python empty :class:`str` literal or any object that evaluates to :obj:`False`
1076 If `value` is not given, schema object will be created.
1078 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
1079 Object representing non-default ASN.1 tag(s)
1081 Raises
1082 ------
1083 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
1084 On constraint violation or bad initializer.
1086 Examples
1087 --------
1088 .. code-block:: python
1090 class Ack(Null):
1091 '''
1092 ASN.1 specification:
1094 Ack ::= NULL
1095 '''
1096 ack = Ack('')
1097 """
1099 #: Set (on class, not on instance) or return a
1100 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
1101 #: associated with |ASN.1| type.
1102 tagSet = tag.initTagSet(
1103 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05)
1104 )
1105 subtypeSpec = OctetString.subtypeSpec + constraint.SingleValueConstraint(octets.str2octs(''))
1107 # Optimization for faster codec lookup
1108 typeId = OctetString.getTypeId()
1110 def prettyIn(self, value):
1111 if value:
1112 return value
1114 return octets.str2octs('')
1116if sys.version_info[0] <= 2:
1117 intTypes = (int, long)
1118else:
1119 intTypes = (int,)
1121numericTypes = intTypes + (float,)
1124class ObjectIdentifier(base.SimpleAsn1Type):
1125 """Create |ASN.1| schema or value object.
1127 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its
1128 objects are immutable and duck-type Python :class:`tuple` objects
1129 (tuple of non-negative integers).
1131 Keyword Args
1132 ------------
1133 value: :class:`tuple`, :class:`str` or |ASN.1| object
1134 Python sequence of :class:`int` or :class:`str` literal or |ASN.1| object.
1135 If `value` is not given, schema object will be created.
1137 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
1138 Object representing non-default ASN.1 tag(s)
1140 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
1141 Object representing non-default ASN.1 subtype constraint(s). Constraints
1142 verification for |ASN.1| type occurs automatically on object
1143 instantiation.
1145 Raises
1146 ------
1147 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
1148 On constraint violation or bad initializer.
1150 Examples
1151 --------
1152 .. code-block:: python
1154 class ID(ObjectIdentifier):
1155 '''
1156 ASN.1 specification:
1158 ID ::= OBJECT IDENTIFIER
1160 id-edims ID ::= { joint-iso-itu-t mhs-motif(6) edims(7) }
1161 id-bp ID ::= { id-edims 11 }
1162 '''
1163 id_edims = ID('2.6.7')
1164 id_bp = id_edims + (11,)
1165 """
1166 #: Set (on class, not on instance) or return a
1167 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
1168 #: associated with |ASN.1| type.
1169 tagSet = tag.initTagSet(
1170 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x06)
1171 )
1173 #: Set (on class, not on instance) or return a
1174 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
1175 #: imposing constraints on |ASN.1| type initialization values.
1176 subtypeSpec = constraint.ConstraintsIntersection()
1178 # Optimization for faster codec lookup
1179 typeId = base.SimpleAsn1Type.getTypeId()
1181 def __add__(self, other):
1182 return self.clone(self._value + other)
1184 def __radd__(self, other):
1185 return self.clone(other + self._value)
1187 def asTuple(self):
1188 return self._value
1190 # Sequence object protocol
1192 def __len__(self):
1193 return len(self._value)
1195 def __getitem__(self, i):
1196 if i.__class__ is slice:
1197 return self.clone(self._value[i])
1198 else:
1199 return self._value[i]
1201 def __iter__(self):
1202 return iter(self._value)
1204 def __contains__(self, value):
1205 return value in self._value
1207 def index(self, suboid):
1208 return self._value.index(suboid)
1210 def isPrefixOf(self, other):
1211 """Indicate if this |ASN.1| object is a prefix of other |ASN.1| object.
1213 Parameters
1214 ----------
1215 other: |ASN.1| object
1216 |ASN.1| object
1218 Returns
1219 -------
1220 : :class:`bool`
1221 :obj:`True` if this |ASN.1| object is a parent (e.g. prefix) of the other |ASN.1| object
1222 or :obj:`False` otherwise.
1223 """
1224 l = len(self)
1225 if l <= len(other):
1226 if self._value[:l] == other[:l]:
1227 return True
1228 return False
1230 def prettyIn(self, value):
1231 if isinstance(value, ObjectIdentifier):
1232 return tuple(value)
1233 elif octets.isStringType(value):
1234 if '-' in value:
1235 raise error.PyAsn1Error(
1236 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
1237 )
1238 try:
1239 return tuple([int(subOid) for subOid in value.split('.') if subOid])
1240 except ValueError:
1241 raise error.PyAsn1Error(
1242 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
1243 )
1245 try:
1246 tupleOfInts = tuple([int(subOid) for subOid in value if subOid >= 0])
1248 except (ValueError, TypeError):
1249 raise error.PyAsn1Error(
1250 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
1251 )
1253 if len(tupleOfInts) == len(value):
1254 return tupleOfInts
1256 raise error.PyAsn1Error('Malformed Object ID %s at %s' % (value, self.__class__.__name__))
1258 def prettyOut(self, value):
1259 return '.'.join([str(x) for x in value])
1262class Real(base.SimpleAsn1Type):
1263 """Create |ASN.1| schema or value object.
1265 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its
1266 objects are immutable and duck-type Python :class:`float` objects.
1267 Additionally, |ASN.1| objects behave like a :class:`tuple` in which case its
1268 elements are mantissa, base and exponent.
1270 Keyword Args
1271 ------------
1272 value: :class:`tuple`, :class:`float` or |ASN.1| object
1273 Python sequence of :class:`int` (representing mantissa, base and
1274 exponent) or :class:`float` instance or |ASN.1| object.
1275 If `value` is not given, schema object will be created.
1277 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
1278 Object representing non-default ASN.1 tag(s)
1280 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
1281 Object representing non-default ASN.1 subtype constraint(s). Constraints
1282 verification for |ASN.1| type occurs automatically on object
1283 instantiation.
1285 Raises
1286 ------
1287 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
1288 On constraint violation or bad initializer.
1290 Examples
1291 --------
1292 .. code-block:: python
1294 class Pi(Real):
1295 '''
1296 ASN.1 specification:
1298 Pi ::= REAL
1300 pi Pi ::= { mantissa 314159, base 10, exponent -5 }
1302 '''
1303 pi = Pi((314159, 10, -5))
1304 """
1305 binEncBase = None # binEncBase = 16 is recommended for large numbers
1307 try:
1308 _plusInf = float('inf')
1309 _minusInf = float('-inf')
1310 _inf = _plusInf, _minusInf
1312 except ValueError:
1313 # Infinity support is platform and Python dependent
1314 _plusInf = _minusInf = None
1315 _inf = ()
1317 #: Set (on class, not on instance) or return a
1318 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
1319 #: associated with |ASN.1| type.
1320 tagSet = tag.initTagSet(
1321 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x09)
1322 )
1324 #: Set (on class, not on instance) or return a
1325 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
1326 #: imposing constraints on |ASN.1| type initialization values.
1327 subtypeSpec = constraint.ConstraintsIntersection()
1329 # Optimization for faster codec lookup
1330 typeId = base.SimpleAsn1Type.getTypeId()
1332 @staticmethod
1333 def __normalizeBase10(value):
1334 m, b, e = value
1335 while m and m % 10 == 0:
1336 m /= 10
1337 e += 1
1338 return m, b, e
1340 def prettyIn(self, value):
1341 if isinstance(value, tuple) and len(value) == 3:
1342 if (not isinstance(value[0], numericTypes) or
1343 not isinstance(value[1], intTypes) or
1344 not isinstance(value[2], intTypes)):
1345 raise error.PyAsn1Error('Lame Real value syntax: %s' % (value,))
1346 if (isinstance(value[0], float) and
1347 self._inf and value[0] in self._inf):
1348 return value[0]
1349 if value[1] not in (2, 10):
1350 raise error.PyAsn1Error(
1351 'Prohibited base for Real value: %s' % (value[1],)
1352 )
1353 if value[1] == 10:
1354 value = self.__normalizeBase10(value)
1355 return value
1356 elif isinstance(value, intTypes):
1357 return self.__normalizeBase10((value, 10, 0))
1358 elif isinstance(value, float) or octets.isStringType(value):
1359 if octets.isStringType(value):
1360 try:
1361 value = float(value)
1362 except ValueError:
1363 raise error.PyAsn1Error(
1364 'Bad real value syntax: %s' % (value,)
1365 )
1366 if self._inf and value in self._inf:
1367 return value
1368 else:
1369 e = 0
1370 while int(value) != value:
1371 value *= 10
1372 e -= 1
1373 return self.__normalizeBase10((int(value), 10, e))
1374 elif isinstance(value, Real):
1375 return tuple(value)
1376 raise error.PyAsn1Error(
1377 'Bad real value syntax: %s' % (value,)
1378 )
1380 def prettyPrint(self, scope=0):
1381 try:
1382 return self.prettyOut(float(self))
1384 except OverflowError:
1385 return '<overflow>'
1387 @property
1388 def isPlusInf(self):
1389 """Indicate PLUS-INFINITY object value
1391 Returns
1392 -------
1393 : :class:`bool`
1394 :obj:`True` if calling object represents plus infinity
1395 or :obj:`False` otherwise.
1397 """
1398 return self._value == self._plusInf
1400 @property
1401 def isMinusInf(self):
1402 """Indicate MINUS-INFINITY object value
1404 Returns
1405 -------
1406 : :class:`bool`
1407 :obj:`True` if calling object represents minus infinity
1408 or :obj:`False` otherwise.
1409 """
1410 return self._value == self._minusInf
1412 @property
1413 def isInf(self):
1414 return self._value in self._inf
1416 def __add__(self, value):
1417 return self.clone(float(self) + value)
1419 def __radd__(self, value):
1420 return self + value
1422 def __mul__(self, value):
1423 return self.clone(float(self) * value)
1425 def __rmul__(self, value):
1426 return self * value
1428 def __sub__(self, value):
1429 return self.clone(float(self) - value)
1431 def __rsub__(self, value):
1432 return self.clone(value - float(self))
1434 def __mod__(self, value):
1435 return self.clone(float(self) % value)
1437 def __rmod__(self, value):
1438 return self.clone(value % float(self))
1440 def __pow__(self, value, modulo=None):
1441 return self.clone(pow(float(self), value, modulo))
1443 def __rpow__(self, value):
1444 return self.clone(pow(value, float(self)))
1446 if sys.version_info[0] <= 2:
1447 def __div__(self, value):
1448 return self.clone(float(self) / value)
1450 def __rdiv__(self, value):
1451 return self.clone(value / float(self))
1452 else:
1453 def __truediv__(self, value):
1454 return self.clone(float(self) / value)
1456 def __rtruediv__(self, value):
1457 return self.clone(value / float(self))
1459 def __divmod__(self, value):
1460 return self.clone(float(self) // value)
1462 def __rdivmod__(self, value):
1463 return self.clone(value // float(self))
1465 def __int__(self):
1466 return int(float(self))
1468 if sys.version_info[0] <= 2:
1469 def __long__(self):
1470 return long(float(self))
1472 def __float__(self):
1473 if self._value in self._inf:
1474 return self._value
1475 else:
1476 return float(
1477 self._value[0] * pow(self._value[1], self._value[2])
1478 )
1480 def __abs__(self):
1481 return self.clone(abs(float(self)))
1483 def __pos__(self):
1484 return self.clone(+float(self))
1486 def __neg__(self):
1487 return self.clone(-float(self))
1489 def __round__(self, n=0):
1490 r = round(float(self), n)
1491 if n:
1492 return self.clone(r)
1493 else:
1494 return r
1496 def __floor__(self):
1497 return self.clone(math.floor(float(self)))
1499 def __ceil__(self):
1500 return self.clone(math.ceil(float(self)))
1502 if sys.version_info[0:2] > (2, 5):
1503 def __trunc__(self):
1504 return self.clone(math.trunc(float(self)))
1506 def __lt__(self, value):
1507 return float(self) < value
1509 def __le__(self, value):
1510 return float(self) <= value
1512 def __eq__(self, value):
1513 return float(self) == value
1515 def __ne__(self, value):
1516 return float(self) != value
1518 def __gt__(self, value):
1519 return float(self) > value
1521 def __ge__(self, value):
1522 return float(self) >= value
1524 if sys.version_info[0] <= 2:
1525 def __nonzero__(self):
1526 return bool(float(self))
1527 else:
1528 def __bool__(self):
1529 return bool(float(self))
1531 __hash__ = base.SimpleAsn1Type.__hash__
1533 def __getitem__(self, idx):
1534 if self._value in self._inf:
1535 raise error.PyAsn1Error('Invalid infinite value operation')
1536 else:
1537 return self._value[idx]
1539 # compatibility stubs
1541 def isPlusInfinity(self):
1542 return self.isPlusInf
1544 def isMinusInfinity(self):
1545 return self.isMinusInf
1547 def isInfinity(self):
1548 return self.isInf
1551class Enumerated(Integer):
1552 """Create |ASN.1| schema or value object.
1554 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its
1555 objects are immutable and duck-type Python :class:`int` objects.
1557 Keyword Args
1558 ------------
1559 value: :class:`int`, :class:`str` or |ASN.1| object
1560 Python :class:`int` or :class:`str` literal or |ASN.1| object.
1561 If `value` is not given, schema object will be created.
1563 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
1564 Object representing non-default ASN.1 tag(s)
1566 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
1567 Object representing non-default ASN.1 subtype constraint(s). Constraints
1568 verification for |ASN.1| type occurs automatically on object
1569 instantiation.
1571 namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
1572 Object representing non-default symbolic aliases for numbers
1574 Raises
1575 ------
1576 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
1577 On constraint violation or bad initializer.
1579 Examples
1580 --------
1582 .. code-block:: python
1584 class RadioButton(Enumerated):
1585 '''
1586 ASN.1 specification:
1588 RadioButton ::= ENUMERATED { button1(0), button2(1),
1589 button3(2) }
1591 selected-by-default RadioButton ::= button1
1592 '''
1593 namedValues = NamedValues(
1594 ('button1', 0), ('button2', 1),
1595 ('button3', 2)
1596 )
1598 selected_by_default = RadioButton('button1')
1599 """
1600 #: Set (on class, not on instance) or return a
1601 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
1602 #: associated with |ASN.1| type.
1603 tagSet = tag.initTagSet(
1604 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x0A)
1605 )
1607 #: Set (on class, not on instance) or return a
1608 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
1609 #: imposing constraints on |ASN.1| type initialization values.
1610 subtypeSpec = constraint.ConstraintsIntersection()
1612 # Optimization for faster codec lookup
1613 typeId = Integer.getTypeId()
1615 #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
1616 #: representing symbolic aliases for numbers
1617 namedValues = namedval.NamedValues()
1620# "Structured" ASN.1 types
1622class SequenceOfAndSetOfBase(base.ConstructedAsn1Type):
1623 """Create |ASN.1| schema or value object.
1625 |ASN.1| class is based on :class:`~pyasn1.type.base.ConstructedAsn1Type`,
1626 its objects are mutable and duck-type Python :class:`list` objects.
1628 Keyword Args
1629 ------------
1630 componentType : :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
1631 A pyasn1 object representing ASN.1 type allowed within |ASN.1| type
1633 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
1634 Object representing non-default ASN.1 tag(s)
1636 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
1637 Object representing non-default ASN.1 subtype constraint(s). Constraints
1638 verification for |ASN.1| type can only occur on explicit
1639 `.isInconsistent` call.
1641 Examples
1642 --------
1644 .. code-block:: python
1646 class LotteryDraw(SequenceOf): # SetOf is similar
1647 '''
1648 ASN.1 specification:
1650 LotteryDraw ::= SEQUENCE OF INTEGER
1651 '''
1652 componentType = Integer()
1654 lotteryDraw = LotteryDraw()
1655 lotteryDraw.extend([123, 456, 789])
1656 """
1657 def __init__(self, *args, **kwargs):
1658 # support positional params for backward compatibility
1659 if args:
1660 for key, value in zip(('componentType', 'tagSet',
1661 'subtypeSpec'), args):
1662 if key in kwargs:
1663 raise error.PyAsn1Error('Conflicting positional and keyword params!')
1664 kwargs['componentType'] = value
1666 self._componentValues = noValue
1668 base.ConstructedAsn1Type.__init__(self, **kwargs)
1670 # Python list protocol
1672 def __getitem__(self, idx):
1673 try:
1674 return self.getComponentByPosition(idx)
1676 except error.PyAsn1Error:
1677 raise IndexError(sys.exc_info()[1])
1679 def __setitem__(self, idx, value):
1680 try:
1681 self.setComponentByPosition(idx, value)
1683 except error.PyAsn1Error:
1684 raise IndexError(sys.exc_info()[1])
1686 def append(self, value):
1687 if self._componentValues is noValue:
1688 pos = 0
1690 else:
1691 pos = len(self._componentValues)
1693 self[pos] = value
1695 def count(self, value):
1696 return list(self._componentValues.values()).count(value)
1698 def extend(self, values):
1699 for value in values:
1700 self.append(value)
1702 if self._componentValues is noValue:
1703 self._componentValues = {}
1705 def index(self, value, start=0, stop=None):
1706 if stop is None:
1707 stop = len(self)
1709 indices, values = zip(*self._componentValues.items())
1711 # TODO: remove when Py2.5 support is gone
1712 values = list(values)
1714 try:
1715 return indices[values.index(value, start, stop)]
1717 except error.PyAsn1Error:
1718 raise ValueError(sys.exc_info()[1])
1720 def reverse(self):
1721 self._componentValues.reverse()
1723 def sort(self, key=None, reverse=False):
1724 self._componentValues = dict(
1725 enumerate(sorted(self._componentValues.values(),
1726 key=key, reverse=reverse)))
1728 def __len__(self):
1729 if self._componentValues is noValue or not self._componentValues:
1730 return 0
1732 return max(self._componentValues) + 1
1734 def __iter__(self):
1735 for idx in range(0, len(self)):
1736 yield self.getComponentByPosition(idx)
1738 def _cloneComponentValues(self, myClone, cloneValueFlag):
1739 for idx, componentValue in self._componentValues.items():
1740 if componentValue is not noValue:
1741 if isinstance(componentValue, base.ConstructedAsn1Type):
1742 myClone.setComponentByPosition(
1743 idx, componentValue.clone(cloneValueFlag=cloneValueFlag)
1744 )
1745 else:
1746 myClone.setComponentByPosition(idx, componentValue.clone())
1748 def getComponentByPosition(self, idx, default=noValue, instantiate=True):
1749 """Return |ASN.1| type component value by position.
1751 Equivalent to Python sequence subscription operation (e.g. `[]`).
1753 Parameters
1754 ----------
1755 idx : :class:`int`
1756 Component index (zero-based). Must either refer to an existing
1757 component or to N+1 component (if *componentType* is set). In the latter
1758 case a new component type gets instantiated and appended to the |ASN.1|
1759 sequence.
1761 Keyword Args
1762 ------------
1763 default: :class:`object`
1764 If set and requested component is a schema object, return the `default`
1765 object instead of the requested component.
1767 instantiate: :class:`bool`
1768 If :obj:`True` (default), inner component will be automatically instantiated.
1769 If :obj:`False` either existing component or the :class:`NoValue` object will be
1770 returned.
1772 Returns
1773 -------
1774 : :py:class:`~pyasn1.type.base.PyAsn1Item`
1775 Instantiate |ASN.1| component type or return existing component value
1777 Examples
1778 --------
1780 .. code-block:: python
1782 # can also be SetOf
1783 class MySequenceOf(SequenceOf):
1784 componentType = OctetString()
1786 s = MySequenceOf()
1788 # returns component #0 with `.isValue` property False
1789 s.getComponentByPosition(0)
1791 # returns None
1792 s.getComponentByPosition(0, default=None)
1794 s.clear()
1796 # returns noValue
1797 s.getComponentByPosition(0, instantiate=False)
1799 # sets component #0 to OctetString() ASN.1 schema
1800 # object and returns it
1801 s.getComponentByPosition(0, instantiate=True)
1803 # sets component #0 to ASN.1 value object
1804 s.setComponentByPosition(0, 'ABCD')
1806 # returns OctetString('ABCD') value object
1807 s.getComponentByPosition(0, instantiate=False)
1809 s.clear()
1811 # returns noValue
1812 s.getComponentByPosition(0, instantiate=False)
1813 """
1814 if isinstance(idx, slice):
1815 indices = tuple(range(len(self)))
1816 return [self.getComponentByPosition(subidx, default, instantiate)
1817 for subidx in indices[idx]]
1819 if idx < 0:
1820 idx = len(self) + idx
1821 if idx < 0:
1822 raise error.PyAsn1Error(
1823 'SequenceOf/SetOf index is out of range')
1825 try:
1826 componentValue = self._componentValues[idx]
1828 except (KeyError, error.PyAsn1Error):
1829 if not instantiate:
1830 return default
1832 self.setComponentByPosition(idx)
1834 componentValue = self._componentValues[idx]
1836 if default is noValue or componentValue.isValue:
1837 return componentValue
1838 else:
1839 return default
1841 def setComponentByPosition(self, idx, value=noValue,
1842 verifyConstraints=True,
1843 matchTags=True,
1844 matchConstraints=True):
1845 """Assign |ASN.1| type component by position.
1847 Equivalent to Python sequence item assignment operation (e.g. `[]`)
1848 or list.append() (when idx == len(self)).
1850 Parameters
1851 ----------
1852 idx: :class:`int`
1853 Component index (zero-based). Must either refer to existing
1854 component or to N+1 component. In the latter case a new component
1855 type gets instantiated (if *componentType* is set, or given ASN.1
1856 object is taken otherwise) and appended to the |ASN.1| sequence.
1858 Keyword Args
1859 ------------
1860 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
1861 A Python value to initialize |ASN.1| component with (if *componentType* is set)
1862 or ASN.1 value object to assign to |ASN.1| component.
1863 If `value` is not given, schema object will be set as a component.
1865 verifyConstraints: :class:`bool`
1866 If :obj:`False`, skip constraints validation
1868 matchTags: :class:`bool`
1869 If :obj:`False`, skip component tags matching
1871 matchConstraints: :class:`bool`
1872 If :obj:`False`, skip component constraints matching
1874 Returns
1875 -------
1876 self
1878 Raises
1879 ------
1880 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
1881 On constraint violation or bad initializer
1882 IndexError
1883 When idx > len(self)
1884 """
1885 if isinstance(idx, slice):
1886 indices = tuple(range(len(self)))
1887 startIdx = indices and indices[idx][0] or 0
1888 for subIdx, subValue in enumerate(value):
1889 self.setComponentByPosition(
1890 startIdx + subIdx, subValue, verifyConstraints,
1891 matchTags, matchConstraints)
1892 return self
1894 if idx < 0:
1895 idx = len(self) + idx
1896 if idx < 0:
1897 raise error.PyAsn1Error(
1898 'SequenceOf/SetOf index is out of range')
1900 componentType = self.componentType
1902 if self._componentValues is noValue:
1903 componentValues = {}
1905 else:
1906 componentValues = self._componentValues
1908 currentValue = componentValues.get(idx, noValue)
1910 if value is noValue:
1911 if componentType is not None:
1912 value = componentType.clone()
1914 elif currentValue is noValue:
1915 raise error.PyAsn1Error('Component type not defined')
1917 elif not isinstance(value, base.Asn1Item):
1918 if (componentType is not None and
1919 isinstance(componentType, base.SimpleAsn1Type)):
1920 value = componentType.clone(value=value)
1922 elif (currentValue is not noValue and
1923 isinstance(currentValue, base.SimpleAsn1Type)):
1924 value = currentValue.clone(value=value)
1926 else:
1927 raise error.PyAsn1Error(
1928 'Non-ASN.1 value %r and undefined component'
1929 ' type at %r' % (value, self))
1931 elif componentType is not None and (matchTags or matchConstraints):
1932 subtypeChecker = (
1933 self.strictConstraints and
1934 componentType.isSameTypeWith or
1935 componentType.isSuperTypeOf)
1937 if not subtypeChecker(value, verifyConstraints and matchTags,
1938 verifyConstraints and matchConstraints):
1939 # TODO: we should wrap componentType with UnnamedType to carry
1940 # additional properties associated with componentType
1941 if componentType.typeId != Any.typeId:
1942 raise error.PyAsn1Error(
1943 'Component value is tag-incompatible: %r vs '
1944 '%r' % (value, componentType))
1946 componentValues[idx] = value
1948 self._componentValues = componentValues
1950 return self
1952 @property
1953 def componentTagMap(self):
1954 if self.componentType is not None:
1955 return self.componentType.tagMap
1957 @property
1958 def components(self):
1959 return [self._componentValues[idx]
1960 for idx in sorted(self._componentValues)]
1962 def clear(self):
1963 """Remove all components and become an empty |ASN.1| value object.
1965 Has the same effect on |ASN.1| object as it does on :class:`list`
1966 built-in.
1967 """
1968 self._componentValues = {}
1969 return self
1971 def reset(self):
1972 """Remove all components and become a |ASN.1| schema object.
1974 See :meth:`isValue` property for more information on the
1975 distinction between value and schema objects.
1976 """
1977 self._componentValues = noValue
1978 return self
1980 def prettyPrint(self, scope=0):
1981 scope += 1
1982 representation = self.__class__.__name__ + ':\n'
1984 if not self.isValue:
1985 return representation
1987 for idx, componentValue in enumerate(self):
1988 representation += ' ' * scope
1989 if (componentValue is noValue and
1990 self.componentType is not None):
1991 representation += '<empty>'
1992 else:
1993 representation += componentValue.prettyPrint(scope)
1995 return representation
1997 def prettyPrintType(self, scope=0):
1998 scope += 1
1999 representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__)
2000 if self.componentType is not None:
2001 representation += ' ' * scope
2002 representation += self.componentType.prettyPrintType(scope)
2003 return representation + '\n' + ' ' * (scope - 1) + '}'
2006 @property
2007 def isValue(self):
2008 """Indicate that |ASN.1| object represents ASN.1 value.
2010 If *isValue* is :obj:`False` then this object represents just ASN.1 schema.
2012 If *isValue* is :obj:`True` then, in addition to its ASN.1 schema features,
2013 this object can also be used like a Python built-in object
2014 (e.g. :class:`int`, :class:`str`, :class:`dict` etc.).
2016 Returns
2017 -------
2018 : :class:`bool`
2019 :obj:`False` if object represents just ASN.1 schema.
2020 :obj:`True` if object represents ASN.1 schema and can be used as a normal value.
2022 Note
2023 ----
2024 There is an important distinction between PyASN1 schema and value objects.
2025 The PyASN1 schema objects can only participate in ASN.1 schema-related
2026 operations (e.g. defining or testing the structure of the data). Most
2027 obvious uses of ASN.1 schema is to guide serialisation codecs whilst
2028 encoding/decoding serialised ASN.1 contents.
2030 The PyASN1 value objects can **additionally** participate in many operations
2031 involving regular Python objects (e.g. arithmetic, comprehension etc).
2032 """
2033 if self._componentValues is noValue:
2034 return False
2036 if len(self._componentValues) != len(self):
2037 return False
2039 for componentValue in self._componentValues.values():
2040 if componentValue is noValue or not componentValue.isValue:
2041 return False
2043 return True
2045 @property
2046 def isInconsistent(self):
2047 """Run necessary checks to ensure |ASN.1| object consistency.
2049 Default action is to verify |ASN.1| object against constraints imposed
2050 by `subtypeSpec`.
2052 Raises
2053 ------
2054 :py:class:`~pyasn1.error.PyAsn1tError` on any inconsistencies found
2055 """
2056 if self.componentType is noValue or not self.subtypeSpec:
2057 return False
2059 if self._componentValues is noValue:
2060 return True
2062 mapping = {}
2064 for idx, value in self._componentValues.items():
2065 # Absent fields are not in the mapping
2066 if value is noValue:
2067 continue
2069 mapping[idx] = value
2071 try:
2072 # Represent SequenceOf/SetOf as a bare dict to constraints chain
2073 self.subtypeSpec(mapping)
2075 except error.PyAsn1Error:
2076 exc = sys.exc_info()[1]
2077 return exc
2079 return False
2081class SequenceOf(SequenceOfAndSetOfBase):
2082 __doc__ = SequenceOfAndSetOfBase.__doc__
2084 #: Set (on class, not on instance) or return a
2085 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
2086 #: associated with |ASN.1| type.
2087 tagSet = tag.initTagSet(
2088 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
2089 )
2091 #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
2092 #: object representing ASN.1 type allowed within |ASN.1| type
2093 componentType = None
2095 #: Set (on class, not on instance) or return a
2096 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
2097 #: imposing constraints on |ASN.1| type initialization values.
2098 subtypeSpec = constraint.ConstraintsIntersection()
2100 # Disambiguation ASN.1 types identification
2101 typeId = SequenceOfAndSetOfBase.getTypeId()
2104class SetOf(SequenceOfAndSetOfBase):
2105 __doc__ = SequenceOfAndSetOfBase.__doc__
2107 #: Set (on class, not on instance) or return a
2108 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
2109 #: associated with |ASN.1| type.
2110 tagSet = tag.initTagSet(
2111 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
2112 )
2114 #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
2115 #: object representing ASN.1 type allowed within |ASN.1| type
2116 componentType = None
2118 #: Set (on class, not on instance) or return a
2119 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
2120 #: imposing constraints on |ASN.1| type initialization values.
2121 subtypeSpec = constraint.ConstraintsIntersection()
2123 # Disambiguation ASN.1 types identification
2124 typeId = SequenceOfAndSetOfBase.getTypeId()
2127class SequenceAndSetBase(base.ConstructedAsn1Type):
2128 """Create |ASN.1| schema or value object.
2130 |ASN.1| class is based on :class:`~pyasn1.type.base.ConstructedAsn1Type`,
2131 its objects are mutable and duck-type Python :class:`dict` objects.
2133 Keyword Args
2134 ------------
2135 componentType: :py:class:`~pyasn1.type.namedtype.NamedType`
2136 Object holding named ASN.1 types allowed within this collection
2138 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
2139 Object representing non-default ASN.1 tag(s)
2141 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
2142 Object representing non-default ASN.1 subtype constraint(s). Constraints
2143 verification for |ASN.1| type can only occur on explicit
2144 `.isInconsistent` call.
2146 Examples
2147 --------
2149 .. code-block:: python
2151 class Description(Sequence): # Set is similar
2152 '''
2153 ASN.1 specification:
2155 Description ::= SEQUENCE {
2156 surname IA5String,
2157 first-name IA5String OPTIONAL,
2158 age INTEGER DEFAULT 40
2159 }
2160 '''
2161 componentType = NamedTypes(
2162 NamedType('surname', IA5String()),
2163 OptionalNamedType('first-name', IA5String()),
2164 DefaultedNamedType('age', Integer(40))
2165 )
2167 descr = Description()
2168 descr['surname'] = 'Smith'
2169 descr['first-name'] = 'John'
2170 """
2171 #: Default :py:class:`~pyasn1.type.namedtype.NamedTypes`
2172 #: object representing named ASN.1 types allowed within |ASN.1| type
2173 componentType = namedtype.NamedTypes()
2176 class DynamicNames(object):
2177 """Fields names/positions mapping for component-less objects"""
2178 def __init__(self):
2179 self._keyToIdxMap = {}
2180 self._idxToKeyMap = {}
2182 def __len__(self):
2183 return len(self._keyToIdxMap)
2185 def __contains__(self, item):
2186 return item in self._keyToIdxMap or item in self._idxToKeyMap
2188 def __iter__(self):
2189 return (self._idxToKeyMap[idx] for idx in range(len(self._idxToKeyMap)))
2191 def __getitem__(self, item):
2192 try:
2193 return self._keyToIdxMap[item]
2195 except KeyError:
2196 return self._idxToKeyMap[item]
2198 def getNameByPosition(self, idx):
2199 try:
2200 return self._idxToKeyMap[idx]
2202 except KeyError:
2203 raise error.PyAsn1Error('Type position out of range')
2205 def getPositionByName(self, name):
2206 try:
2207 return self._keyToIdxMap[name]
2209 except KeyError:
2210 raise error.PyAsn1Error('Name %s not found' % (name,))
2212 def addField(self, idx):
2213 self._keyToIdxMap['field-%d' % idx] = idx
2214 self._idxToKeyMap[idx] = 'field-%d' % idx
2217 def __init__(self, **kwargs):
2218 base.ConstructedAsn1Type.__init__(self, **kwargs)
2219 self._componentTypeLen = len(self.componentType)
2220 if self._componentTypeLen:
2221 self._componentValues = []
2222 else:
2223 self._componentValues = noValue
2224 self._dynamicNames = self._componentTypeLen or self.DynamicNames()
2226 def __getitem__(self, idx):
2227 if octets.isStringType(idx):
2228 try:
2229 return self.getComponentByName(idx)
2231 except error.PyAsn1Error:
2232 # duck-typing dict
2233 raise KeyError(sys.exc_info()[1])
2235 else:
2236 try:
2237 return self.getComponentByPosition(idx)
2239 except error.PyAsn1Error:
2240 # duck-typing list
2241 raise IndexError(sys.exc_info()[1])
2243 def __setitem__(self, idx, value):
2244 if octets.isStringType(idx):
2245 try:
2246 self.setComponentByName(idx, value)
2248 except error.PyAsn1Error:
2249 # duck-typing dict
2250 raise KeyError(sys.exc_info()[1])
2252 else:
2253 try:
2254 self.setComponentByPosition(idx, value)
2256 except error.PyAsn1Error:
2257 # duck-typing list
2258 raise IndexError(sys.exc_info()[1])
2260 def __contains__(self, key):
2261 if self._componentTypeLen:
2262 return key in self.componentType
2263 else:
2264 return key in self._dynamicNames
2266 def __len__(self):
2267 return len(self._componentValues)
2269 def __iter__(self):
2270 return iter(self.componentType or self._dynamicNames)
2272 # Python dict protocol
2274 def values(self):
2275 for idx in range(self._componentTypeLen or len(self._dynamicNames)):
2276 yield self[idx]
2278 def keys(self):
2279 return iter(self)
2281 def items(self):
2282 for idx in range(self._componentTypeLen or len(self._dynamicNames)):
2283 if self._componentTypeLen:
2284 yield self.componentType[idx].name, self[idx]
2285 else:
2286 yield self._dynamicNames[idx], self[idx]
2288 def update(self, *iterValue, **mappingValue):
2289 for k, v in iterValue:
2290 self[k] = v
2291 for k in mappingValue:
2292 self[k] = mappingValue[k]
2294 def clear(self):
2295 """Remove all components and become an empty |ASN.1| value object.
2297 Has the same effect on |ASN.1| object as it does on :class:`dict`
2298 built-in.
2299 """
2300 self._componentValues = []
2301 self._dynamicNames = self.DynamicNames()
2302 return self
2304 def reset(self):
2305 """Remove all components and become a |ASN.1| schema object.
2307 See :meth:`isValue` property for more information on the
2308 distinction between value and schema objects.
2309 """
2310 self._componentValues = noValue
2311 self._dynamicNames = self.DynamicNames()
2312 return self
2314 @property
2315 def components(self):
2316 return self._componentValues
2318 def _cloneComponentValues(self, myClone, cloneValueFlag):
2319 if self._componentValues is noValue:
2320 return
2322 for idx, componentValue in enumerate(self._componentValues):
2323 if componentValue is not noValue:
2324 if isinstance(componentValue, base.ConstructedAsn1Type):
2325 myClone.setComponentByPosition(
2326 idx, componentValue.clone(cloneValueFlag=cloneValueFlag)
2327 )
2328 else:
2329 myClone.setComponentByPosition(idx, componentValue.clone())
2331 def getComponentByName(self, name, default=noValue, instantiate=True):
2332 """Returns |ASN.1| type component by name.
2334 Equivalent to Python :class:`dict` subscription operation (e.g. `[]`).
2336 Parameters
2337 ----------
2338 name: :class:`str`
2339 |ASN.1| type component name
2341 Keyword Args
2342 ------------
2343 default: :class:`object`
2344 If set and requested component is a schema object, return the `default`
2345 object instead of the requested component.
2347 instantiate: :class:`bool`
2348 If :obj:`True` (default), inner component will be automatically
2349 instantiated.
2350 If :obj:`False` either existing component or the :class:`NoValue`
2351 object will be returned.
2353 Returns
2354 -------
2355 : :py:class:`~pyasn1.type.base.PyAsn1Item`
2356 Instantiate |ASN.1| component type or return existing
2357 component value
2358 """
2359 if self._componentTypeLen:
2360 idx = self.componentType.getPositionByName(name)
2361 else:
2362 try:
2363 idx = self._dynamicNames.getPositionByName(name)
2365 except KeyError:
2366 raise error.PyAsn1Error('Name %s not found' % (name,))
2368 return self.getComponentByPosition(idx, default=default, instantiate=instantiate)
2370 def setComponentByName(self, name, value=noValue,
2371 verifyConstraints=True,
2372 matchTags=True,
2373 matchConstraints=True):
2374 """Assign |ASN.1| type component by name.
2376 Equivalent to Python :class:`dict` item assignment operation (e.g. `[]`).
2378 Parameters
2379 ----------
2380 name: :class:`str`
2381 |ASN.1| type component name
2383 Keyword Args
2384 ------------
2385 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
2386 A Python value to initialize |ASN.1| component with (if *componentType* is set)
2387 or ASN.1 value object to assign to |ASN.1| component.
2388 If `value` is not given, schema object will be set as a component.
2390 verifyConstraints: :class:`bool`
2391 If :obj:`False`, skip constraints validation
2393 matchTags: :class:`bool`
2394 If :obj:`False`, skip component tags matching
2396 matchConstraints: :class:`bool`
2397 If :obj:`False`, skip component constraints matching
2399 Returns
2400 -------
2401 self
2402 """
2403 if self._componentTypeLen:
2404 idx = self.componentType.getPositionByName(name)
2405 else:
2406 try:
2407 idx = self._dynamicNames.getPositionByName(name)
2409 except KeyError:
2410 raise error.PyAsn1Error('Name %s not found' % (name,))
2412 return self.setComponentByPosition(
2413 idx, value, verifyConstraints, matchTags, matchConstraints
2414 )
2416 def getComponentByPosition(self, idx, default=noValue, instantiate=True):
2417 """Returns |ASN.1| type component by index.
2419 Equivalent to Python sequence subscription operation (e.g. `[]`).
2421 Parameters
2422 ----------
2423 idx: :class:`int`
2424 Component index (zero-based). Must either refer to an existing
2425 component or (if *componentType* is set) new ASN.1 schema object gets
2426 instantiated.
2428 Keyword Args
2429 ------------
2430 default: :class:`object`
2431 If set and requested component is a schema object, return the `default`
2432 object instead of the requested component.
2434 instantiate: :class:`bool`
2435 If :obj:`True` (default), inner component will be automatically
2436 instantiated.
2437 If :obj:`False` either existing component or the :class:`NoValue`
2438 object will be returned.
2440 Returns
2441 -------
2442 : :py:class:`~pyasn1.type.base.PyAsn1Item`
2443 a PyASN1 object
2445 Examples
2446 --------
2448 .. code-block:: python
2450 # can also be Set
2451 class MySequence(Sequence):
2452 componentType = NamedTypes(
2453 NamedType('id', OctetString())
2454 )
2456 s = MySequence()
2458 # returns component #0 with `.isValue` property False
2459 s.getComponentByPosition(0)
2461 # returns None
2462 s.getComponentByPosition(0, default=None)
2464 s.clear()
2466 # returns noValue
2467 s.getComponentByPosition(0, instantiate=False)
2469 # sets component #0 to OctetString() ASN.1 schema
2470 # object and returns it
2471 s.getComponentByPosition(0, instantiate=True)
2473 # sets component #0 to ASN.1 value object
2474 s.setComponentByPosition(0, 'ABCD')
2476 # returns OctetString('ABCD') value object
2477 s.getComponentByPosition(0, instantiate=False)
2479 s.clear()
2481 # returns noValue
2482 s.getComponentByPosition(0, instantiate=False)
2483 """
2484 try:
2485 if self._componentValues is noValue:
2486 componentValue = noValue
2488 else:
2489 componentValue = self._componentValues[idx]
2491 except IndexError:
2492 componentValue = noValue
2494 if not instantiate:
2495 if componentValue is noValue or not componentValue.isValue:
2496 return default
2497 else:
2498 return componentValue
2500 if componentValue is noValue:
2501 self.setComponentByPosition(idx)
2503 componentValue = self._componentValues[idx]
2505 if default is noValue or componentValue.isValue:
2506 return componentValue
2507 else:
2508 return default
2510 def setComponentByPosition(self, idx, value=noValue,
2511 verifyConstraints=True,
2512 matchTags=True,
2513 matchConstraints=True):
2514 """Assign |ASN.1| type component by position.
2516 Equivalent to Python sequence item assignment operation (e.g. `[]`).
2518 Parameters
2519 ----------
2520 idx : :class:`int`
2521 Component index (zero-based). Must either refer to existing
2522 component (if *componentType* is set) or to N+1 component
2523 otherwise. In the latter case a new component of given ASN.1
2524 type gets instantiated and appended to |ASN.1| sequence.
2526 Keyword Args
2527 ------------
2528 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
2529 A Python value to initialize |ASN.1| component with (if *componentType* is set)
2530 or ASN.1 value object to assign to |ASN.1| component.
2531 If `value` is not given, schema object will be set as a component.
2533 verifyConstraints : :class:`bool`
2534 If :obj:`False`, skip constraints validation
2536 matchTags: :class:`bool`
2537 If :obj:`False`, skip component tags matching
2539 matchConstraints: :class:`bool`
2540 If :obj:`False`, skip component constraints matching
2542 Returns
2543 -------
2544 self
2545 """
2546 componentType = self.componentType
2547 componentTypeLen = self._componentTypeLen
2549 if self._componentValues is noValue:
2550 componentValues = []
2552 else:
2553 componentValues = self._componentValues
2555 try:
2556 currentValue = componentValues[idx]
2558 except IndexError:
2559 currentValue = noValue
2560 if componentTypeLen:
2561 if componentTypeLen < idx:
2562 raise error.PyAsn1Error('component index out of range')
2564 componentValues = [noValue] * componentTypeLen
2566 if value is noValue:
2567 if componentTypeLen:
2568 value = componentType.getTypeByPosition(idx)
2569 if isinstance(value, base.ConstructedAsn1Type):
2570 value = value.clone(cloneValueFlag=componentType[idx].isDefaulted)
2572 elif currentValue is noValue:
2573 raise error.PyAsn1Error('Component type not defined')
2575 elif not isinstance(value, base.Asn1Item):
2576 if componentTypeLen:
2577 subComponentType = componentType.getTypeByPosition(idx)
2578 if isinstance(subComponentType, base.SimpleAsn1Type):
2579 value = subComponentType.clone(value=value)
2581 else:
2582 raise error.PyAsn1Error('%s can cast only scalar values' % componentType.__class__.__name__)
2584 elif currentValue is not noValue and isinstance(currentValue, base.SimpleAsn1Type):
2585 value = currentValue.clone(value=value)
2587 else:
2588 raise error.PyAsn1Error('%s undefined component type' % componentType.__class__.__name__)
2590 elif ((verifyConstraints or matchTags or matchConstraints) and
2591 componentTypeLen):
2592 subComponentType = componentType.getTypeByPosition(idx)
2593 if subComponentType is not noValue:
2594 subtypeChecker = (self.strictConstraints and
2595 subComponentType.isSameTypeWith or
2596 subComponentType.isSuperTypeOf)
2598 if not subtypeChecker(value, verifyConstraints and matchTags,
2599 verifyConstraints and matchConstraints):
2600 if not componentType[idx].openType:
2601 raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
2603 if componentTypeLen or idx in self._dynamicNames:
2604 componentValues[idx] = value
2606 elif len(componentValues) == idx:
2607 componentValues.append(value)
2608 self._dynamicNames.addField(idx)
2610 else:
2611 raise error.PyAsn1Error('Component index out of range')
2613 self._componentValues = componentValues
2615 return self
2617 @property
2618 def isValue(self):
2619 """Indicate that |ASN.1| object represents ASN.1 value.
2621 If *isValue* is :obj:`False` then this object represents just ASN.1 schema.
2623 If *isValue* is :obj:`True` then, in addition to its ASN.1 schema features,
2624 this object can also be used like a Python built-in object (e.g.
2625 :class:`int`, :class:`str`, :class:`dict` etc.).
2627 Returns
2628 -------
2629 : :class:`bool`
2630 :obj:`False` if object represents just ASN.1 schema.
2631 :obj:`True` if object represents ASN.1 schema and can be used as a
2632 normal value.
2634 Note
2635 ----
2636 There is an important distinction between PyASN1 schema and value objects.
2637 The PyASN1 schema objects can only participate in ASN.1 schema-related
2638 operations (e.g. defining or testing the structure of the data). Most
2639 obvious uses of ASN.1 schema is to guide serialisation codecs whilst
2640 encoding/decoding serialised ASN.1 contents.
2642 The PyASN1 value objects can **additionally** participate in many operations
2643 involving regular Python objects (e.g. arithmetic, comprehension etc).
2645 It is sufficient for |ASN.1| objects to have all non-optional and non-defaulted
2646 components being value objects to be considered as a value objects as a whole.
2647 In other words, even having one or more optional components not turned into
2648 value objects, |ASN.1| object is still considered as a value object. Defaulted
2649 components are normally value objects by default.
2650 """
2651 if self._componentValues is noValue:
2652 return False
2654 componentType = self.componentType
2656 if componentType:
2657 for idx, subComponentType in enumerate(componentType.namedTypes):
2658 if subComponentType.isDefaulted or subComponentType.isOptional:
2659 continue
2661 if not self._componentValues:
2662 return False
2664 componentValue = self._componentValues[idx]
2665 if componentValue is noValue or not componentValue.isValue:
2666 return False
2668 else:
2669 for componentValue in self._componentValues:
2670 if componentValue is noValue or not componentValue.isValue:
2671 return False
2673 return True
2675 @property
2676 def isInconsistent(self):
2677 """Run necessary checks to ensure |ASN.1| object consistency.
2679 Default action is to verify |ASN.1| object against constraints imposed
2680 by `subtypeSpec`.
2682 Raises
2683 ------
2684 :py:class:`~pyasn1.error.PyAsn1tError` on any inconsistencies found
2685 """
2686 if self.componentType is noValue or not self.subtypeSpec:
2687 return False
2689 if self._componentValues is noValue:
2690 return True
2692 mapping = {}
2694 for idx, value in enumerate(self._componentValues):
2695 # Absent fields are not in the mapping
2696 if value is noValue:
2697 continue
2699 name = self.componentType.getNameByPosition(idx)
2701 mapping[name] = value
2703 try:
2704 # Represent Sequence/Set as a bare dict to constraints chain
2705 self.subtypeSpec(mapping)
2707 except error.PyAsn1Error:
2708 exc = sys.exc_info()[1]
2709 return exc
2711 return False
2713 def prettyPrint(self, scope=0):
2714 """Return an object representation string.
2716 Returns
2717 -------
2718 : :class:`str`
2719 Human-friendly object representation.
2720 """
2721 scope += 1
2722 representation = self.__class__.__name__ + ':\n'
2723 for idx, componentValue in enumerate(self._componentValues):
2724 if componentValue is not noValue and componentValue.isValue:
2725 representation += ' ' * scope
2726 if self.componentType:
2727 representation += self.componentType.getNameByPosition(idx)
2728 else:
2729 representation += self._dynamicNames.getNameByPosition(idx)
2730 representation = '%s=%s\n' % (
2731 representation, componentValue.prettyPrint(scope)
2732 )
2733 return representation
2735 def prettyPrintType(self, scope=0):
2736 scope += 1
2737 representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__)
2738 for idx, componentType in enumerate(self.componentType.values() or self._componentValues):
2739 representation += ' ' * scope
2740 if self.componentType:
2741 representation += '"%s"' % self.componentType.getNameByPosition(idx)
2742 else:
2743 representation += '"%s"' % self._dynamicNames.getNameByPosition(idx)
2744 representation = '%s = %s\n' % (
2745 representation, componentType.prettyPrintType(scope)
2746 )
2747 return representation + '\n' + ' ' * (scope - 1) + '}'
2749 # backward compatibility
2751 def setDefaultComponents(self):
2752 return self
2754 def getComponentType(self):
2755 if self._componentTypeLen:
2756 return self.componentType
2758 def getNameByPosition(self, idx):
2759 if self._componentTypeLen:
2760 return self.componentType[idx].name
2762class Sequence(SequenceAndSetBase):
2763 __doc__ = SequenceAndSetBase.__doc__
2765 #: Set (on class, not on instance) or return a
2766 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
2767 #: associated with |ASN.1| type.
2768 tagSet = tag.initTagSet(
2769 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
2770 )
2772 #: Set (on class, not on instance) or return a
2773 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
2774 #: imposing constraints on |ASN.1| type initialization values.
2775 subtypeSpec = constraint.ConstraintsIntersection()
2777 #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
2778 #: object imposing size constraint on |ASN.1| objects
2779 componentType = namedtype.NamedTypes()
2781 # Disambiguation ASN.1 types identification
2782 typeId = SequenceAndSetBase.getTypeId()
2784 # backward compatibility
2786 def getComponentTagMapNearPosition(self, idx):
2787 if self.componentType:
2788 return self.componentType.getTagMapNearPosition(idx)
2790 def getComponentPositionNearType(self, tagSet, idx):
2791 if self.componentType:
2792 return self.componentType.getPositionNearType(tagSet, idx)
2793 else:
2794 return idx
2797class Set(SequenceAndSetBase):
2798 __doc__ = SequenceAndSetBase.__doc__
2800 #: Set (on class, not on instance) or return a
2801 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
2802 #: associated with |ASN.1| type.
2803 tagSet = tag.initTagSet(
2804 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
2805 )
2807 #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
2808 #: object representing ASN.1 type allowed within |ASN.1| type
2809 componentType = namedtype.NamedTypes()
2811 #: Set (on class, not on instance) or return a
2812 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
2813 #: imposing constraints on |ASN.1| type initialization values.
2814 subtypeSpec = constraint.ConstraintsIntersection()
2816 # Disambiguation ASN.1 types identification
2817 typeId = SequenceAndSetBase.getTypeId()
2819 def getComponent(self, innerFlag=False):
2820 return self
2822 def getComponentByType(self, tagSet, default=noValue,
2823 instantiate=True, innerFlag=False):
2824 """Returns |ASN.1| type component by ASN.1 tag.
2826 Parameters
2827 ----------
2828 tagSet : :py:class:`~pyasn1.type.tag.TagSet`
2829 Object representing ASN.1 tags to identify one of
2830 |ASN.1| object component
2832 Keyword Args
2833 ------------
2834 default: :class:`object`
2835 If set and requested component is a schema object, return the `default`
2836 object instead of the requested component.
2838 instantiate: :class:`bool`
2839 If :obj:`True` (default), inner component will be automatically
2840 instantiated.
2841 If :obj:`False` either existing component or the :class:`noValue`
2842 object will be returned.
2844 Returns
2845 -------
2846 : :py:class:`~pyasn1.type.base.PyAsn1Item`
2847 a pyasn1 object
2848 """
2849 componentValue = self.getComponentByPosition(
2850 self.componentType.getPositionByType(tagSet),
2851 default=default, instantiate=instantiate
2852 )
2853 if innerFlag and isinstance(componentValue, Set):
2854 # get inner component by inner tagSet
2855 return componentValue.getComponent(innerFlag=True)
2856 else:
2857 # get outer component by inner tagSet
2858 return componentValue
2860 def setComponentByType(self, tagSet, value=noValue,
2861 verifyConstraints=True,
2862 matchTags=True,
2863 matchConstraints=True,
2864 innerFlag=False):
2865 """Assign |ASN.1| type component by ASN.1 tag.
2867 Parameters
2868 ----------
2869 tagSet : :py:class:`~pyasn1.type.tag.TagSet`
2870 Object representing ASN.1 tags to identify one of
2871 |ASN.1| object component
2873 Keyword Args
2874 ------------
2875 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
2876 A Python value to initialize |ASN.1| component with (if *componentType* is set)
2877 or ASN.1 value object to assign to |ASN.1| component.
2878 If `value` is not given, schema object will be set as a component.
2880 verifyConstraints : :class:`bool`
2881 If :obj:`False`, skip constraints validation
2883 matchTags: :class:`bool`
2884 If :obj:`False`, skip component tags matching
2886 matchConstraints: :class:`bool`
2887 If :obj:`False`, skip component constraints matching
2889 innerFlag: :class:`bool`
2890 If :obj:`True`, search for matching *tagSet* recursively.
2892 Returns
2893 -------
2894 self
2895 """
2896 idx = self.componentType.getPositionByType(tagSet)
2898 if innerFlag: # set inner component by inner tagSet
2899 componentType = self.componentType.getTypeByPosition(idx)
2901 if componentType.tagSet:
2902 return self.setComponentByPosition(
2903 idx, value, verifyConstraints, matchTags, matchConstraints
2904 )
2905 else:
2906 componentType = self.getComponentByPosition(idx)
2907 return componentType.setComponentByType(
2908 tagSet, value, verifyConstraints, matchTags, matchConstraints, innerFlag=innerFlag
2909 )
2910 else: # set outer component by inner tagSet
2911 return self.setComponentByPosition(
2912 idx, value, verifyConstraints, matchTags, matchConstraints
2913 )
2915 @property
2916 def componentTagMap(self):
2917 if self.componentType:
2918 return self.componentType.tagMapUnique
2921class Choice(Set):
2922 """Create |ASN.1| schema or value object.
2924 |ASN.1| class is based on :class:`~pyasn1.type.base.ConstructedAsn1Type`,
2925 its objects are mutable and duck-type Python :class:`list` objects.
2927 Keyword Args
2928 ------------
2929 componentType: :py:class:`~pyasn1.type.namedtype.NamedType`
2930 Object holding named ASN.1 types allowed within this collection
2932 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
2933 Object representing non-default ASN.1 tag(s)
2935 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
2936 Object representing non-default ASN.1 subtype constraint(s). Constraints
2937 verification for |ASN.1| type can only occur on explicit
2938 `.isInconsistent` call.
2940 Examples
2941 --------
2943 .. code-block:: python
2945 class Afters(Choice):
2946 '''
2947 ASN.1 specification:
2949 Afters ::= CHOICE {
2950 cheese [0] IA5String,
2951 dessert [1] IA5String
2952 }
2953 '''
2954 componentType = NamedTypes(
2955 NamedType('cheese', IA5String().subtype(
2956 implicitTag=Tag(tagClassContext, tagFormatSimple, 0)
2957 ),
2958 NamedType('dessert', IA5String().subtype(
2959 implicitTag=Tag(tagClassContext, tagFormatSimple, 1)
2960 )
2961 )
2963 afters = Afters()
2964 afters['cheese'] = 'Mascarpone'
2965 """
2966 #: Set (on class, not on instance) or return a
2967 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
2968 #: associated with |ASN.1| type.
2969 tagSet = tag.TagSet() # untagged
2971 #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
2972 #: object representing ASN.1 type allowed within |ASN.1| type
2973 componentType = namedtype.NamedTypes()
2975 #: Set (on class, not on instance) or return a
2976 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
2977 #: imposing constraints on |ASN.1| type initialization values.
2978 subtypeSpec = constraint.ConstraintsIntersection(
2979 constraint.ValueSizeConstraint(1, 1)
2980 )
2982 # Disambiguation ASN.1 types identification
2983 typeId = Set.getTypeId()
2985 _currentIdx = None
2987 def __eq__(self, other):
2988 if self._componentValues:
2989 return self._componentValues[self._currentIdx] == other
2990 return NotImplemented
2992 def __ne__(self, other):
2993 if self._componentValues:
2994 return self._componentValues[self._currentIdx] != other
2995 return NotImplemented
2997 def __lt__(self, other):
2998 if self._componentValues:
2999 return self._componentValues[self._currentIdx] < other
3000 return NotImplemented
3002 def __le__(self, other):
3003 if self._componentValues:
3004 return self._componentValues[self._currentIdx] <= other
3005 return NotImplemented
3007 def __gt__(self, other):
3008 if self._componentValues:
3009 return self._componentValues[self._currentIdx] > other
3010 return NotImplemented
3012 def __ge__(self, other):
3013 if self._componentValues:
3014 return self._componentValues[self._currentIdx] >= other
3015 return NotImplemented
3017 if sys.version_info[0] <= 2:
3018 def __nonzero__(self):
3019 return self._componentValues and True or False
3020 else:
3021 def __bool__(self):
3022 return self._componentValues and True or False
3024 def __len__(self):
3025 return self._currentIdx is not None and 1 or 0
3027 def __contains__(self, key):
3028 if self._currentIdx is None:
3029 return False
3030 return key == self.componentType[self._currentIdx].getName()
3032 def __iter__(self):
3033 if self._currentIdx is None:
3034 raise StopIteration
3035 yield self.componentType[self._currentIdx].getName()
3037 # Python dict protocol
3039 def values(self):
3040 if self._currentIdx is not None:
3041 yield self._componentValues[self._currentIdx]
3043 def keys(self):
3044 if self._currentIdx is not None:
3045 yield self.componentType[self._currentIdx].getName()
3047 def items(self):
3048 if self._currentIdx is not None:
3049 yield self.componentType[self._currentIdx].getName(), self[self._currentIdx]
3051 def checkConsistency(self):
3052 if self._currentIdx is None:
3053 raise error.PyAsn1Error('Component not chosen')
3055 def _cloneComponentValues(self, myClone, cloneValueFlag):
3056 try:
3057 component = self.getComponent()
3058 except error.PyAsn1Error:
3059 pass
3060 else:
3061 if isinstance(component, Choice):
3062 tagSet = component.effectiveTagSet
3063 else:
3064 tagSet = component.tagSet
3065 if isinstance(component, base.ConstructedAsn1Type):
3066 myClone.setComponentByType(
3067 tagSet, component.clone(cloneValueFlag=cloneValueFlag)
3068 )
3069 else:
3070 myClone.setComponentByType(tagSet, component.clone())
3072 def getComponentByPosition(self, idx, default=noValue, instantiate=True):
3073 __doc__ = Set.__doc__
3075 if self._currentIdx is None or self._currentIdx != idx:
3076 return Set.getComponentByPosition(self, idx, default=default,
3077 instantiate=instantiate)
3079 return self._componentValues[idx]
3081 def setComponentByPosition(self, idx, value=noValue,
3082 verifyConstraints=True,
3083 matchTags=True,
3084 matchConstraints=True):
3085 """Assign |ASN.1| type component by position.
3087 Equivalent to Python sequence item assignment operation (e.g. `[]`).
3089 Parameters
3090 ----------
3091 idx: :class:`int`
3092 Component index (zero-based). Must either refer to existing
3093 component or to N+1 component. In the latter case a new component
3094 type gets instantiated (if *componentType* is set, or given ASN.1
3095 object is taken otherwise) and appended to the |ASN.1| sequence.
3097 Keyword Args
3098 ------------
3099 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
3100 A Python value to initialize |ASN.1| component with (if *componentType* is set)
3101 or ASN.1 value object to assign to |ASN.1| component. Once a new value is
3102 set to *idx* component, previous value is dropped.
3103 If `value` is not given, schema object will be set as a component.
3105 verifyConstraints : :class:`bool`
3106 If :obj:`False`, skip constraints validation
3108 matchTags: :class:`bool`
3109 If :obj:`False`, skip component tags matching
3111 matchConstraints: :class:`bool`
3112 If :obj:`False`, skip component constraints matching
3114 Returns
3115 -------
3116 self
3117 """
3118 oldIdx = self._currentIdx
3119 Set.setComponentByPosition(self, idx, value, verifyConstraints, matchTags, matchConstraints)
3120 self._currentIdx = idx
3121 if oldIdx is not None and oldIdx != idx:
3122 self._componentValues[oldIdx] = noValue
3123 return self
3125 @property
3126 def effectiveTagSet(self):
3127 """Return a :class:`~pyasn1.type.tag.TagSet` object of the currently initialized component or self (if |ASN.1| is tagged)."""
3128 if self.tagSet:
3129 return self.tagSet
3130 else:
3131 component = self.getComponent()
3132 return component.effectiveTagSet
3134 @property
3135 def tagMap(self):
3136 """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping
3137 ASN.1 tags to ASN.1 objects contained within callee.
3138 """
3139 if self.tagSet:
3140 return Set.tagMap.fget(self)
3141 else:
3142 return self.componentType.tagMapUnique
3144 def getComponent(self, innerFlag=False):
3145 """Return currently assigned component of the |ASN.1| object.
3147 Returns
3148 -------
3149 : :py:class:`~pyasn1.type.base.PyAsn1Item`
3150 a PyASN1 object
3151 """
3152 if self._currentIdx is None:
3153 raise error.PyAsn1Error('Component not chosen')
3154 else:
3155 c = self._componentValues[self._currentIdx]
3156 if innerFlag and isinstance(c, Choice):
3157 return c.getComponent(innerFlag)
3158 else:
3159 return c
3161 def getName(self, innerFlag=False):
3162 """Return the name of currently assigned component of the |ASN.1| object.
3164 Returns
3165 -------
3166 : :py:class:`str`
3167 |ASN.1| component name
3168 """
3169 if self._currentIdx is None:
3170 raise error.PyAsn1Error('Component not chosen')
3171 else:
3172 if innerFlag:
3173 c = self._componentValues[self._currentIdx]
3174 if isinstance(c, Choice):
3175 return c.getName(innerFlag)
3176 return self.componentType.getNameByPosition(self._currentIdx)
3178 @property
3179 def isValue(self):
3180 """Indicate that |ASN.1| object represents ASN.1 value.
3182 If *isValue* is :obj:`False` then this object represents just ASN.1 schema.
3184 If *isValue* is :obj:`True` then, in addition to its ASN.1 schema features,
3185 this object can also be used like a Python built-in object (e.g.
3186 :class:`int`, :class:`str`, :class:`dict` etc.).
3188 Returns
3189 -------
3190 : :class:`bool`
3191 :obj:`False` if object represents just ASN.1 schema.
3192 :obj:`True` if object represents ASN.1 schema and can be used as a normal
3193 value.
3195 Note
3196 ----
3197 There is an important distinction between PyASN1 schema and value objects.
3198 The PyASN1 schema objects can only participate in ASN.1 schema-related
3199 operations (e.g. defining or testing the structure of the data). Most
3200 obvious uses of ASN.1 schema is to guide serialisation codecs whilst
3201 encoding/decoding serialised ASN.1 contents.
3203 The PyASN1 value objects can **additionally** participate in many operations
3204 involving regular Python objects (e.g. arithmetic, comprehension etc).
3205 """
3206 if self._currentIdx is None:
3207 return False
3209 componentValue = self._componentValues[self._currentIdx]
3211 return componentValue is not noValue and componentValue.isValue
3213 def clear(self):
3214 self._currentIdx = None
3215 return Set.clear(self)
3217 # compatibility stubs
3219 def getMinTagSet(self):
3220 return self.minTagSet
3223class Any(OctetString):
3224 """Create |ASN.1| schema or value object.
3226 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`,
3227 its objects are immutable and duck-type Python 2 :class:`str` or Python 3
3228 :class:`bytes`. When used in Unicode context, |ASN.1| type assumes
3229 "|encoding|" serialisation.
3231 Keyword Args
3232 ------------
3233 value: :class:`unicode`, :class:`str`, :class:`bytes` or |ASN.1| object
3234 :class:`str` (Python 2) or :class:`bytes` (Python 3), alternatively
3235 :class:`unicode` object (Python 2) or :class:`str` (Python 3)
3236 representing character string to be serialised into octets (note
3237 `encoding` parameter) or |ASN.1| object.
3238 If `value` is not given, schema object will be created.
3240 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
3241 Object representing non-default ASN.1 tag(s)
3243 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
3244 Object representing non-default ASN.1 subtype constraint(s). Constraints
3245 verification for |ASN.1| type occurs automatically on object
3246 instantiation.
3248 encoding: :py:class:`str`
3249 Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
3250 :class:`str` (Python 3) the payload when |ASN.1| object is used
3251 in text string context.
3253 binValue: :py:class:`str`
3254 Binary string initializer to use instead of the *value*.
3255 Example: '10110011'.
3257 hexValue: :py:class:`str`
3258 Hexadecimal string initializer to use instead of the *value*.
3259 Example: 'DEADBEEF'.
3261 Raises
3262 ------
3263 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
3264 On constraint violation or bad initializer.
3266 Examples
3267 --------
3268 .. code-block:: python
3270 class Error(Sequence):
3271 '''
3272 ASN.1 specification:
3274 Error ::= SEQUENCE {
3275 code INTEGER,
3276 parameter ANY DEFINED BY code -- Either INTEGER or REAL
3277 }
3278 '''
3279 componentType=NamedTypes(
3280 NamedType('code', Integer()),
3281 NamedType('parameter', Any(),
3282 openType=OpenType('code', {1: Integer(),
3283 2: Real()}))
3284 )
3286 error = Error()
3287 error['code'] = 1
3288 error['parameter'] = Integer(1234)
3289 """
3290 #: Set (on class, not on instance) or return a
3291 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
3292 #: associated with |ASN.1| type.
3293 tagSet = tag.TagSet() # untagged
3295 #: Set (on class, not on instance) or return a
3296 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
3297 #: imposing constraints on |ASN.1| type initialization values.
3298 subtypeSpec = constraint.ConstraintsIntersection()
3300 # Disambiguation ASN.1 types identification
3301 typeId = OctetString.getTypeId()
3303 @property
3304 def tagMap(self):
3305 """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping
3306 ASN.1 tags to ASN.1 objects contained within callee.
3307 """
3308 try:
3309 return self._tagMap
3311 except AttributeError:
3312 self._tagMap = tagmap.TagMap(
3313 {self.tagSet: self},
3314 {eoo.endOfOctets.tagSet: eoo.endOfOctets},
3315 self
3316 )
3318 return self._tagMap
3320# XXX
3321# coercion rules?