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
9
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
21
22NoValue = base.NoValue
23noValue = NoValue()
24
25__all__ = ['Integer', 'Boolean', 'BitString', 'OctetString', 'Null',
26           'ObjectIdentifier', 'Real', 'Enumerated',
27           'SequenceOfAndSetOfBase', 'SequenceOf', 'SetOf',
28           'SequenceAndSetBase', 'Sequence', 'Set', 'Choice', 'Any',
29           'NoValue', 'noValue']
30
31# "Simple" ASN.1 types (yet incomplete)
32
33
34class Integer(base.AbstractSimpleAsn1Item):
35    """Create |ASN.1| type or object.
36
37    |ASN.1| objects are immutable and duck-type Python :class:`int` objects.
38
39    Keyword Args
40    ------------
41    value: :class:`int`, :class:`str` or |ASN.1| object
42        Python integer or string literal or |ASN.1| class instance.
43
44    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
45        Object representing non-default ASN.1 tag(s)
46
47    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
48        Object representing non-default ASN.1 subtype constraint(s)
49
50    namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
51        Object representing non-default symbolic aliases for numbers
52
53    Raises
54    ------
55    :py:class:`~pyasn1.error.PyAsn1Error`
56        On constraint violation or bad initializer.
57
58    Examples
59    --------
60
61    .. code-block:: python
62
63        class ErrorCode(Integer):
64            '''
65            ASN.1 specification:
66
67            ErrorCode ::=
68                INTEGER { disk-full(1), no-disk(-1),
69                          disk-not-formatted(2) }
70
71            error ErrorCode ::= disk-full
72            '''
73            namedValues = NamedValues(
74                ('disk-full', 1), ('no-disk', -1),
75                ('disk-not-formatted', 2)
76            )
77
78        error = ErrorCode('disk-full')
79    """
80    #: Set (on class, not on instance) or return a
81    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
82    #: associated with |ASN.1| type.
83    tagSet = tag.initTagSet(
84        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x02)
85    )
86
87    #: Set (on class, not on instance) or return a
88    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
89    #: imposing constraints on |ASN.1| type initialization values.
90    subtypeSpec = constraint.ConstraintsIntersection()
91
92    #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
93    #: representing symbolic aliases for numbers
94    namedValues = namedval.NamedValues()
95
96    # Optimization for faster codec lookup
97    typeId = base.AbstractSimpleAsn1Item.getTypeId()
98
99    def __init__(self, value=noValue, **kwargs):
100        if 'namedValues' not in kwargs:
101            kwargs['namedValues'] = self.namedValues
102
103        base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
104
105    def __and__(self, value):
106        return self.clone(self._value & value)
107
108    def __rand__(self, value):
109        return self.clone(value & self._value)
110
111    def __or__(self, value):
112        return self.clone(self._value | value)
113
114    def __ror__(self, value):
115        return self.clone(value | self._value)
116
117    def __xor__(self, value):
118        return self.clone(self._value ^ value)
119
120    def __rxor__(self, value):
121        return self.clone(value ^ self._value)
122
123    def __lshift__(self, value):
124        return self.clone(self._value << value)
125
126    def __rshift__(self, value):
127        return self.clone(self._value >> value)
128
129    def __add__(self, value):
130        return self.clone(self._value + value)
131
132    def __radd__(self, value):
133        return self.clone(value + self._value)
134
135    def __sub__(self, value):
136        return self.clone(self._value - value)
137
138    def __rsub__(self, value):
139        return self.clone(value - self._value)
140
141    def __mul__(self, value):
142        return self.clone(self._value * value)
143
144    def __rmul__(self, value):
145        return self.clone(value * self._value)
146
147    def __mod__(self, value):
148        return self.clone(self._value % value)
149
150    def __rmod__(self, value):
151        return self.clone(value % self._value)
152
153    def __pow__(self, value, modulo=None):
154        return self.clone(pow(self._value, value, modulo))
155
156    def __rpow__(self, value):
157        return self.clone(pow(value, self._value))
158
159    def __floordiv__(self, value):
160        return self.clone(self._value // value)
161
162    def __rfloordiv__(self, value):
163        return self.clone(value // self._value)
164
165    if sys.version_info[0] <= 2:
166        def __div__(self, value):
167            if isinstance(value, float):
168                return Real(self._value / value)
169            else:
170                return self.clone(self._value / value)
171
172        def __rdiv__(self, value):
173            if isinstance(value, float):
174                return Real(value / self._value)
175            else:
176                return self.clone(value / self._value)
177    else:
178        def __truediv__(self, value):
179            return Real(self._value / value)
180
181        def __rtruediv__(self, value):
182            return Real(value / self._value)
183
184        def __divmod__(self, value):
185            return self.clone(divmod(self._value, value))
186
187        def __rdivmod__(self, value):
188            return self.clone(divmod(value, self._value))
189
190        __hash__ = base.AbstractSimpleAsn1Item.__hash__
191
192    def __int__(self):
193        return int(self._value)
194
195    if sys.version_info[0] <= 2:
196        def __long__(self):
197            return long(self._value)
198
199    def __float__(self):
200        return float(self._value)
201
202    def __abs__(self):
203        return self.clone(abs(self._value))
204
205    def __index__(self):
206        return int(self._value)
207
208    def __pos__(self):
209        return self.clone(+self._value)
210
211    def __neg__(self):
212        return self.clone(-self._value)
213
214    def __invert__(self):
215        return self.clone(~self._value)
216
217    def __round__(self, n=0):
218        r = round(self._value, n)
219        if n:
220            return self.clone(r)
221        else:
222            return r
223
224    def __floor__(self):
225        return math.floor(self._value)
226
227    def __ceil__(self):
228        return math.ceil(self._value)
229
230    if sys.version_info[0:2] > (2, 5):
231        def __trunc__(self):
232            return self.clone(math.trunc(self._value))
233
234    def __lt__(self, value):
235        return self._value < value
236
237    def __le__(self, value):
238        return self._value <= value
239
240    def __eq__(self, value):
241        return self._value == value
242
243    def __ne__(self, value):
244        return self._value != value
245
246    def __gt__(self, value):
247        return self._value > value
248
249    def __ge__(self, value):
250        return self._value >= value
251
252    def prettyIn(self, value):
253        try:
254            return int(value)
255
256        except ValueError:
257            try:
258                return self.namedValues[value]
259
260            except KeyError:
261                raise error.PyAsn1Error(
262                    'Can\'t coerce %r into integer: %s' % (value, sys.exc_info()[1])
263                )
264
265    def prettyOut(self, value):
266        try:
267            return str(self.namedValues[value])
268
269        except KeyError:
270            return str(value)
271
272    # backward compatibility
273
274    def getNamedValues(self):
275        return self.namedValues
276
277
278class Boolean(Integer):
279    """Create |ASN.1| type or object.
280
281    |ASN.1| objects are immutable and duck-type Python :class:`int` objects.
282
283    Keyword Args
284    ------------
285    value: :class:`int`, :class:`str` or |ASN.1| object
286        Python integer or boolean or string literal or |ASN.1| class instance.
287
288    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
289        Object representing non-default ASN.1 tag(s)
290
291    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
292        Object representing non-default ASN.1 subtype constraint(s)
293
294    namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
295        Object representing non-default symbolic aliases for numbers
296
297    Raises
298    ------
299    :py:class:`~pyasn1.error.PyAsn1Error`
300        On constraint violation or bad initializer.
301
302    Examples
303    --------
304    .. code-block:: python
305
306        class RoundResult(Boolean):
307            '''
308            ASN.1 specification:
309
310            RoundResult ::= BOOLEAN
311
312            ok RoundResult ::= TRUE
313            ko RoundResult ::= FALSE
314            '''
315        ok = RoundResult(True)
316        ko = RoundResult(False)
317    """
318    #: Set (on class, not on instance) or return a
319    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
320    #: associated with |ASN.1| type.
321    tagSet = tag.initTagSet(
322        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x01),
323    )
324
325    #: Set (on class, not on instance) or return a
326    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
327    #: imposing constraints on |ASN.1| type initialization values.
328    subtypeSpec = Integer.subtypeSpec + constraint.SingleValueConstraint(0, 1)
329
330    #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
331    #: representing symbolic aliases for numbers
332    namedValues = namedval.NamedValues(('False', 0), ('True', 1))
333
334    # Optimization for faster codec lookup
335    typeId = Integer.getTypeId()
336
337if sys.version_info[0] < 3:
338    SizedIntegerBase = long
339else:
340    SizedIntegerBase = int
341
342
343class SizedInteger(SizedIntegerBase):
344    bitLength = leadingZeroBits = None
345
346    def setBitLength(self, bitLength):
347        self.bitLength = bitLength
348        self.leadingZeroBits = max(bitLength - integer.bitLength(self), 0)
349        return self
350
351    def __len__(self):
352        if self.bitLength is None:
353            self.setBitLength(integer.bitLength(self))
354
355        return self.bitLength
356
357
358class BitString(base.AbstractSimpleAsn1Item):
359    """Create |ASN.1| schema or value object.
360
361    |ASN.1| objects are immutable and duck-type both Python :class:`tuple` (as a tuple
362    of bits) and :class:`int` objects.
363
364    Keyword Args
365    ------------
366    value: :class:`int`, :class:`str` or |ASN.1| object
367        Python integer or string literal representing binary or hexadecimal
368        number or sequence of integer bits or |ASN.1| object.
369
370    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
371        Object representing non-default ASN.1 tag(s)
372
373    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
374        Object representing non-default ASN.1 subtype constraint(s)
375
376    namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
377        Object representing non-default symbolic aliases for numbers
378
379    binValue: :py:class:`str`
380        Binary string initializer to use instead of the *value*.
381        Example: '10110011'.
382
383    hexValue: :py:class:`str`
384        Hexadecimal string initializer to use instead of the *value*.
385        Example: 'DEADBEEF'.
386
387    Raises
388    ------
389    :py:class:`~pyasn1.error.PyAsn1Error`
390        On constraint violation or bad initializer.
391
392    Examples
393    --------
394    .. code-block:: python
395
396        class Rights(BitString):
397            '''
398            ASN.1 specification:
399
400            Rights ::= BIT STRING { user-read(0), user-write(1),
401                                    group-read(2), group-write(3),
402                                    other-read(4), other-write(5) }
403
404            group1 Rights ::= { group-read, group-write }
405            group2 Rights ::= '0011'B
406            group3 Rights ::= '3'H
407            '''
408            namedValues = NamedValues(
409                ('user-read', 0), ('user-write', 1),
410                ('group-read', 2), ('group-write', 3),
411                ('other-read', 4), ('other-write', 5)
412            )
413
414        group1 = Rights(('group-read', 'group-write'))
415        group2 = Rights('0011')
416        group3 = Rights(0x3)
417    """
418    #: Set (on class, not on instance) or return a
419    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
420    #: associated with |ASN.1| type.
421    tagSet = tag.initTagSet(
422        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x03)
423    )
424
425    #: Set (on class, not on instance) or return a
426    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
427    #: imposing constraints on |ASN.1| type initialization values.
428    subtypeSpec = constraint.ConstraintsIntersection()
429
430    #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
431    #: representing symbolic aliases for numbers
432    namedValues = namedval.NamedValues()
433
434    # Optimization for faster codec lookup
435    typeId = base.AbstractSimpleAsn1Item.getTypeId()
436
437    defaultBinValue = defaultHexValue = noValue
438
439    def __init__(self, value=noValue, **kwargs):
440        if value is noValue:
441            if kwargs:
442                try:
443                    value = self.fromBinaryString(kwargs.pop('binValue'), internalFormat=True)
444
445                except KeyError:
446                    pass
447
448                try:
449                    value = self.fromHexString(kwargs.pop('hexValue'), internalFormat=True)
450
451                except KeyError:
452                    pass
453
454        if value is noValue:
455            if self.defaultBinValue is not noValue:
456                value = self.fromBinaryString(self.defaultBinValue, internalFormat=True)
457
458            elif self.defaultHexValue is not noValue:
459                value = self.fromHexString(self.defaultHexValue, internalFormat=True)
460
461        if 'namedValues' not in kwargs:
462            kwargs['namedValues'] = self.namedValues
463
464        base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
465
466    def __str__(self):
467        return self.asBinary()
468
469    def __eq__(self, other):
470        other = self.prettyIn(other)
471        return self is other or self._value == other and len(self._value) == len(other)
472
473    def __ne__(self, other):
474        other = self.prettyIn(other)
475        return self._value != other or len(self._value) != len(other)
476
477    def __lt__(self, other):
478        other = self.prettyIn(other)
479        return len(self._value) < len(other) or len(self._value) == len(other) and self._value < other
480
481    def __le__(self, other):
482        other = self.prettyIn(other)
483        return len(self._value) <= len(other) or len(self._value) == len(other) and self._value <= other
484
485    def __gt__(self, other):
486        other = self.prettyIn(other)
487        return len(self._value) > len(other) or len(self._value) == len(other) and self._value > other
488
489    def __ge__(self, other):
490        other = self.prettyIn(other)
491        return len(self._value) >= len(other) or len(self._value) == len(other) and self._value >= other
492
493    # Immutable sequence object protocol
494
495    def __len__(self):
496        return len(self._value)
497
498    def __getitem__(self, i):
499        if i.__class__ is slice:
500            return self.clone([self[x] for x in range(*i.indices(len(self)))])
501        else:
502            length = len(self._value) - 1
503            if i > length or i < 0:
504                raise IndexError('bit index out of range')
505            return (self._value >> (length - i)) & 1
506
507    def __iter__(self):
508        length = len(self._value)
509        while length:
510            length -= 1
511            yield (self._value >> length) & 1
512
513    def __reversed__(self):
514        return reversed(tuple(self))
515
516    # arithmetic operators
517
518    def __add__(self, value):
519        value = self.prettyIn(value)
520        return self.clone(SizedInteger(self._value << len(value) | value).setBitLength(len(self._value) + len(value)))
521
522    def __radd__(self, value):
523        value = self.prettyIn(value)
524        return self.clone(SizedInteger(value << len(self._value) | self._value).setBitLength(len(self._value) + len(value)))
525
526    def __mul__(self, value):
527        bitString = self._value
528        while value > 1:
529            bitString <<= len(self._value)
530            bitString |= self._value
531            value -= 1
532        return self.clone(bitString)
533
534    def __rmul__(self, value):
535        return self * value
536
537    def __lshift__(self, count):
538        return self.clone(SizedInteger(self._value << count).setBitLength(len(self._value) + count))
539
540    def __rshift__(self, count):
541        return self.clone(SizedInteger(self._value >> count).setBitLength(max(0, len(self._value) - count)))
542
543    def __int__(self):
544        return self._value
545
546    def __float__(self):
547        return float(self._value)
548
549    if sys.version_info[0] < 3:
550        def __long__(self):
551            return self._value
552
553    def asNumbers(self):
554        """Get |ASN.1| value as a sequence of 8-bit integers.
555
556        If |ASN.1| object length is not a multiple of 8, result
557        will be left-padded with zeros.
558        """
559        return tuple(octets.octs2ints(self.asOctets()))
560
561    def asOctets(self):
562        """Get |ASN.1| value as a sequence of octets.
563
564        If |ASN.1| object length is not a multiple of 8, result
565        will be left-padded with zeros.
566        """
567        return integer.to_bytes(self._value, length=len(self))
568
569    def asInteger(self):
570        """Get |ASN.1| value as a single integer value.
571        """
572        return self._value
573
574    def asBinary(self):
575        """Get |ASN.1| value as a text string of bits.
576        """
577        binString = binary.bin(self._value)[2:]
578        return '0' * (len(self._value) - len(binString)) + binString
579
580    @classmethod
581    def fromHexString(cls, value, internalFormat=False, prepend=None):
582        """Create a |ASN.1| object initialized from the hex string.
583
584        Parameters
585        ----------
586        value: :class:`str`
587            Text string like 'DEADBEEF'
588        """
589        try:
590            value = SizedInteger(value, 16).setBitLength(len(value) * 4)
591
592        except ValueError:
593            raise error.PyAsn1Error('%s.fromHexString() error: %s' % (cls.__name__, sys.exc_info()[1]))
594
595        if prepend is not None:
596            value = SizedInteger(
597                (SizedInteger(prepend) << len(value)) | value
598            ).setBitLength(len(prepend) + len(value))
599
600        if not internalFormat:
601            value = cls(value)
602
603        return value
604
605    @classmethod
606    def fromBinaryString(cls, value, internalFormat=False, prepend=None):
607        """Create a |ASN.1| object initialized from a string of '0' and '1'.
608
609        Parameters
610        ----------
611        value: :class:`str`
612            Text string like '1010111'
613        """
614        try:
615            value = SizedInteger(value or '0', 2).setBitLength(len(value))
616
617        except ValueError:
618            raise error.PyAsn1Error('%s.fromBinaryString() error: %s' % (cls.__name__, sys.exc_info()[1]))
619
620        if prepend is not None:
621            value = SizedInteger(
622                (SizedInteger(prepend) << len(value)) | value
623            ).setBitLength(len(prepend) + len(value))
624
625        if not internalFormat:
626            value = cls(value)
627
628        return value
629
630    @classmethod
631    def fromOctetString(cls, value, internalFormat=False, prepend=None, padding=0):
632        """Create a |ASN.1| object initialized from a string.
633
634        Parameters
635        ----------
636        value: :class:`str` (Py2) or :class:`bytes` (Py3)
637            Text string like '\\\\x01\\\\xff' (Py2) or b'\\\\x01\\\\xff' (Py3)
638        """
639        value = SizedInteger(integer.from_bytes(value) >> padding).setBitLength(len(value) * 8 - padding)
640
641        if prepend is not None:
642            value = SizedInteger(
643                (SizedInteger(prepend) << len(value)) | value
644            ).setBitLength(len(prepend) + len(value))
645
646        if not internalFormat:
647            value = cls(value)
648
649        return value
650
651    def prettyIn(self, value):
652        if isinstance(value, SizedInteger):
653            return value
654        elif octets.isStringType(value):
655            if not value:
656                return SizedInteger(0).setBitLength(0)
657
658            elif value[0] == '\'':  # "'1011'B" -- ASN.1 schema representation (deprecated)
659                if value[-2:] == '\'B':
660                    return self.fromBinaryString(value[1:-2], internalFormat=True)
661                elif value[-2:] == '\'H':
662                    return self.fromHexString(value[1:-2], internalFormat=True)
663                else:
664                    raise error.PyAsn1Error(
665                        'Bad BIT STRING value notation %s' % (value,)
666                    )
667
668            elif self.namedValues and not value.isdigit():  # named bits like 'Urgent, Active'
669                names = [x.strip() for x in value.split(',')]
670
671                try:
672
673                    bitPositions = [self.namedValues[name] for name in names]
674
675                except KeyError:
676                    raise error.PyAsn1Error('unknown bit name(s) in %r' % (names,))
677
678                rightmostPosition = max(bitPositions)
679
680                number = 0
681                for bitPosition in bitPositions:
682                    number |= 1 << (rightmostPosition - bitPosition)
683
684                return SizedInteger(number).setBitLength(rightmostPosition + 1)
685
686            elif value.startswith('0x'):
687                return self.fromHexString(value[2:], internalFormat=True)
688
689            elif value.startswith('0b'):
690                return self.fromBinaryString(value[2:], internalFormat=True)
691
692            else:  # assume plain binary string like '1011'
693                return self.fromBinaryString(value, internalFormat=True)
694
695        elif isinstance(value, (tuple, list)):
696            return self.fromBinaryString(''.join([b and '1' or '0' for b in value]), internalFormat=True)
697
698        elif isinstance(value, BitString):
699            return SizedInteger(value).setBitLength(len(value))
700
701        elif isinstance(value, intTypes):
702            return SizedInteger(value)
703
704        else:
705            raise error.PyAsn1Error(
706                'Bad BitString initializer type \'%s\'' % (value,)
707            )
708
709
710try:
711    # noinspection PyStatementEffect
712    all
713
714except NameError:  # Python 2.4
715    # noinspection PyShadowingBuiltins
716    def all(iterable):
717        for element in iterable:
718            if not element:
719                return False
720        return True
721
722
723class OctetString(base.AbstractSimpleAsn1Item):
724    """Create |ASN.1| schema or value object.
725
726    |ASN.1| objects are immutable and duck-type Python 2 :class:`str` or Python 3 :class:`bytes`.
727    When used in Unicode context, |ASN.1| type assumes "|encoding|" serialisation.
728
729    Keyword Args
730    ------------
731    value: :class:`str`, :class:`bytes` or |ASN.1| object
732        string (Python 2) or bytes (Python 3), alternatively unicode object
733        (Python 2) or string (Python 3) representing character string to be
734        serialised into octets (note `encoding` parameter) or |ASN.1| object.
735
736    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
737        Object representing non-default ASN.1 tag(s)
738
739    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
740        Object representing non-default ASN.1 subtype constraint(s)
741
742    encoding: :py:class:`str`
743        Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
744        :class:`str` (Python 3) the payload when |ASN.1| object is used
745        in text string context.
746
747    binValue: :py:class:`str`
748        Binary string initializer to use instead of the *value*.
749        Example: '10110011'.
750
751    hexValue: :py:class:`str`
752        Hexadecimal string initializer to use instead of the *value*.
753        Example: 'DEADBEEF'.
754
755    Raises
756    ------
757    :py:class:`~pyasn1.error.PyAsn1Error`
758        On constraint violation or bad initializer.
759
760    Examples
761    --------
762    .. code-block:: python
763
764        class Icon(OctetString):
765            '''
766            ASN.1 specification:
767
768            Icon ::= OCTET STRING
769
770            icon1 Icon ::= '001100010011001000110011'B
771            icon2 Icon ::= '313233'H
772            '''
773        icon1 = Icon.fromBinaryString('001100010011001000110011')
774        icon2 = Icon.fromHexString('313233')
775    """
776    #: Set (on class, not on instance) or return a
777    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
778    #: associated with |ASN.1| type.
779    tagSet = tag.initTagSet(
780        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x04)
781    )
782
783    #: Set (on class, not on instance) or return a
784    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
785    #: imposing constraints on |ASN.1| type initialization values.
786    subtypeSpec = constraint.ConstraintsIntersection()
787
788    # Optimization for faster codec lookup
789    typeId = base.AbstractSimpleAsn1Item.getTypeId()
790
791    defaultBinValue = defaultHexValue = noValue
792    encoding = 'iso-8859-1'
793
794    def __init__(self, value=noValue, **kwargs):
795        if kwargs:
796            if value is noValue:
797                try:
798                    value = self.fromBinaryString(kwargs.pop('binValue'))
799
800                except KeyError:
801                    pass
802
803                try:
804                    value = self.fromHexString(kwargs.pop('hexValue'))
805
806                except KeyError:
807                    pass
808
809        if value is noValue:
810            if self.defaultBinValue is not noValue:
811                value = self.fromBinaryString(self.defaultBinValue)
812
813            elif self.defaultHexValue is not noValue:
814                value = self.fromHexString(self.defaultHexValue)
815
816        if 'encoding' not in kwargs:
817            kwargs['encoding'] = self.encoding
818
819        base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
820
821    if sys.version_info[0] <= 2:
822        def prettyIn(self, value):
823            if isinstance(value, str):
824                return value
825            elif isinstance(value, unicode):
826                try:
827                    return value.encode(self.encoding)
828                except (LookupError, UnicodeEncodeError):
829                    raise error.PyAsn1Error(
830                        "Can't encode string '%s' with codec %s" % (value, self.encoding)
831                    )
832            elif isinstance(value, (tuple, list)):
833                try:
834                    return ''.join([chr(x) for x in value])
835                except ValueError:
836                    raise error.PyAsn1Error(
837                        "Bad %s initializer '%s'" % (self.__class__.__name__, value)
838                    )
839            else:
840                return str(value)
841
842        def __str__(self):
843            return str(self._value)
844
845        def __unicode__(self):
846            try:
847                return self._value.decode(self.encoding)
848
849            except UnicodeDecodeError:
850                raise error.PyAsn1Error(
851                    "Can't decode string '%s' with codec %s" % (self._value, self.encoding)
852                )
853
854        def asOctets(self):
855            return str(self._value)
856
857        def asNumbers(self):
858            return tuple([ord(x) for x in self._value])
859
860    else:
861        def prettyIn(self, value):
862            if isinstance(value, bytes):
863                return value
864            elif isinstance(value, str):
865                try:
866                    return value.encode(self.encoding)
867                except UnicodeEncodeError:
868                    raise error.PyAsn1Error(
869                        "Can't encode string '%s' with '%s' codec" % (value, self.encoding)
870                    )
871            elif isinstance(value, OctetString):  # a shortcut, bytes() would work the same way
872                return value.asOctets()
873            elif isinstance(value, base.AbstractSimpleAsn1Item):  # this mostly targets Integer objects
874                return self.prettyIn(str(value))
875            elif isinstance(value, (tuple, list)):
876                return self.prettyIn(bytes(value))
877            else:
878                return bytes(value)
879
880        def __str__(self):
881            try:
882                return self._value.decode(self.encoding)
883
884            except UnicodeDecodeError:
885                raise error.PyAsn1Error(
886                    "Can't decode string '%s' with '%s' codec at '%s'" % (self._value, self.encoding, self.__class__.__name__)
887                )
888
889        def __bytes__(self):
890            return bytes(self._value)
891
892        def asOctets(self):
893            return bytes(self._value)
894
895        def asNumbers(self):
896            return tuple(self._value)
897
898    #
899    # Normally, `.prettyPrint()` is called from `__str__()`. Historically,
900    # OctetString.prettyPrint() used to return hexified payload
901    # representation in cases when non-printable content is present. At the
902    # same time `str()` used to produce either octet-stream (Py2) or
903    # text (Py3) representations.
904    #
905    # Therefore `OctetString.__str__()` -> `.prettyPrint()` call chain is
906    # reversed to preserve the original behaviour.
907    #
908    # Eventually we should deprecate `.prettyPrint()` / `.prettyOut()` harness
909    # and end up with just `__str__()` producing hexified representation while
910    # both text and octet-stream representation should only be requested via
911    # the `.asOctets()` method.
912    #
913    # Note: ASN.1 OCTET STRING is never mean to contain text!
914    #
915
916    def prettyOut(self, value):
917        return value
918
919    def prettyPrint(self, scope=0):
920        # first see if subclass has its own .prettyOut()
921        value = self.prettyOut(self._value)
922
923        if value is not self._value:
924            return value
925
926        numbers = self.asNumbers()
927
928        for x in numbers:
929            # hexify if needed
930            if x < 32 or x > 126:
931                return '0x' + ''.join(('%.2x' % x for x in numbers))
932        else:
933            # this prevents infinite recursion
934            return OctetString.__str__(self)
935
936    @staticmethod
937    def fromBinaryString(value):
938        """Create a |ASN.1| object initialized from a string of '0' and '1'.
939
940        Parameters
941        ----------
942        value: :class:`str`
943            Text string like '1010111'
944        """
945        bitNo = 8
946        byte = 0
947        r = []
948        for v in value:
949            if bitNo:
950                bitNo -= 1
951            else:
952                bitNo = 7
953                r.append(byte)
954                byte = 0
955            if v in ('0', '1'):
956                v = int(v)
957            else:
958                raise error.PyAsn1Error(
959                    'Non-binary OCTET STRING initializer %s' % (v,)
960                )
961            byte |= v << bitNo
962
963        r.append(byte)
964
965        return octets.ints2octs(r)
966
967    @staticmethod
968    def fromHexString(value):
969        """Create a |ASN.1| object initialized from the hex string.
970
971        Parameters
972        ----------
973        value: :class:`str`
974            Text string like 'DEADBEEF'
975        """
976        r = []
977        p = []
978        for v in value:
979            if p:
980                r.append(int(p + v, 16))
981                p = None
982            else:
983                p = v
984        if p:
985            r.append(int(p + '0', 16))
986
987        return octets.ints2octs(r)
988
989    # Immutable sequence object protocol
990
991    def __len__(self):
992        return len(self._value)
993
994    def __getitem__(self, i):
995        if i.__class__ is slice:
996            return self.clone(self._value[i])
997        else:
998            return self._value[i]
999
1000    def __iter__(self):
1001        return iter(self._value)
1002
1003    def __contains__(self, value):
1004        return value in self._value
1005
1006    def __add__(self, value):
1007        return self.clone(self._value + self.prettyIn(value))
1008
1009    def __radd__(self, value):
1010        return self.clone(self.prettyIn(value) + self._value)
1011
1012    def __mul__(self, value):
1013        return self.clone(self._value * value)
1014
1015    def __rmul__(self, value):
1016        return self * value
1017
1018    def __int__(self):
1019        return int(self._value)
1020
1021    def __float__(self):
1022        return float(self._value)
1023
1024    def __reversed__(self):
1025        return reversed(self._value)
1026
1027
1028class Null(OctetString):
1029    """Create |ASN.1| schema or value object.
1030
1031    |ASN.1| objects are immutable and duck-type Python :class:`str` objects (always empty).
1032
1033    Keyword Args
1034    ------------
1035    value: :class:`str` or :py:class:`~pyasn1.type.univ.Null` object
1036        Python empty string literal or any object that evaluates to `False`
1037
1038    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
1039        Object representing non-default ASN.1 tag(s)
1040
1041    Raises
1042    ------
1043    :py:class:`~pyasn1.error.PyAsn1Error`
1044        On constraint violation or bad initializer.
1045
1046    Examples
1047    --------
1048    .. code-block:: python
1049
1050        class Ack(Null):
1051            '''
1052            ASN.1 specification:
1053
1054            Ack ::= NULL
1055            '''
1056        ack = Ack('')
1057    """
1058
1059    #: Set (on class, not on instance) or return a
1060    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
1061    #: associated with |ASN.1| type.
1062    tagSet = tag.initTagSet(
1063        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05)
1064    )
1065    subtypeSpec = OctetString.subtypeSpec + constraint.SingleValueConstraint(octets.str2octs(''))
1066
1067    # Optimization for faster codec lookup
1068    typeId = OctetString.getTypeId()
1069
1070    def prettyIn(self, value):
1071        if value:
1072            return value
1073
1074        return octets.str2octs('')
1075
1076if sys.version_info[0] <= 2:
1077    intTypes = (int, long)
1078else:
1079    intTypes = (int,)
1080
1081numericTypes = intTypes + (float,)
1082
1083
1084class ObjectIdentifier(base.AbstractSimpleAsn1Item):
1085    """Create |ASN.1| schema or value object.
1086
1087    |ASN.1| objects are immutable and duck-type Python :class:`tuple` objects (tuple of non-negative integers).
1088
1089    Keyword Args
1090    ------------
1091    value: :class:`tuple`, :class:`str` or |ASN.1| object
1092        Python sequence of :class:`int` or string literal or |ASN.1| object.
1093
1094    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
1095        Object representing non-default ASN.1 tag(s)
1096
1097    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
1098        Object representing non-default ASN.1 subtype constraint(s)
1099
1100    Raises
1101    ------
1102    :py:class:`~pyasn1.error.PyAsn1Error`
1103        On constraint violation or bad initializer.
1104
1105    Examples
1106    --------
1107    .. code-block:: python
1108
1109        class ID(ObjectIdentifier):
1110            '''
1111            ASN.1 specification:
1112
1113            ID ::= OBJECT IDENTIFIER
1114
1115            id-edims ID ::= { joint-iso-itu-t mhs-motif(6) edims(7) }
1116            id-bp ID ::= { id-edims 11 }
1117            '''
1118        id_edims = ID('2.6.7')
1119        id_bp = id_edims + (11,)
1120    """
1121    #: Set (on class, not on instance) or return a
1122    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
1123    #: associated with |ASN.1| type.
1124    tagSet = tag.initTagSet(
1125        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x06)
1126    )
1127
1128    #: Set (on class, not on instance) or return a
1129    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
1130    #: imposing constraints on |ASN.1| type initialization values.
1131    subtypeSpec = constraint.ConstraintsIntersection()
1132
1133    # Optimization for faster codec lookup
1134    typeId = base.AbstractSimpleAsn1Item.getTypeId()
1135
1136    def __add__(self, other):
1137        return self.clone(self._value + other)
1138
1139    def __radd__(self, other):
1140        return self.clone(other + self._value)
1141
1142    def asTuple(self):
1143        return self._value
1144
1145    # Sequence object protocol
1146
1147    def __len__(self):
1148        return len(self._value)
1149
1150    def __getitem__(self, i):
1151        if i.__class__ is slice:
1152            return self.clone(self._value[i])
1153        else:
1154            return self._value[i]
1155
1156    def __iter__(self):
1157        return iter(self._value)
1158
1159    def __contains__(self, value):
1160        return value in self._value
1161
1162    def index(self, suboid):
1163        return self._value.index(suboid)
1164
1165    def isPrefixOf(self, other):
1166        """Indicate if this |ASN.1| object is a prefix of other |ASN.1| object.
1167
1168        Parameters
1169        ----------
1170        other: |ASN.1| object
1171            |ASN.1| object
1172
1173        Returns
1174        -------
1175        : :class:`bool`
1176            :class:`True` if this |ASN.1| object is a parent (e.g. prefix) of the other |ASN.1| object
1177            or :class:`False` otherwise.
1178        """
1179        l = len(self)
1180        if l <= len(other):
1181            if self._value[:l] == other[:l]:
1182                return True
1183        return False
1184
1185    def prettyIn(self, value):
1186        if isinstance(value, ObjectIdentifier):
1187            return tuple(value)
1188        elif octets.isStringType(value):
1189            if '-' in value:
1190                raise error.PyAsn1Error(
1191                    'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
1192                )
1193            try:
1194                return tuple([int(subOid) for subOid in value.split('.') if subOid])
1195            except ValueError:
1196                raise error.PyAsn1Error(
1197                    'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
1198                )
1199
1200        try:
1201            tupleOfInts = tuple([int(subOid) for subOid in value if subOid >= 0])
1202
1203        except (ValueError, TypeError):
1204            raise error.PyAsn1Error(
1205                'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
1206            )
1207
1208        if len(tupleOfInts) == len(value):
1209            return tupleOfInts
1210
1211        raise error.PyAsn1Error('Malformed Object ID %s at %s' % (value, self.__class__.__name__))
1212
1213    def prettyOut(self, value):
1214        return '.'.join([str(x) for x in value])
1215
1216
1217class Real(base.AbstractSimpleAsn1Item):
1218    """Create |ASN.1| schema or value object.
1219
1220    |ASN.1| objects are immutable and duck-type Python :class:`float` objects.
1221    Additionally, |ASN.1| objects behave like a :class:`tuple` in which case its
1222    elements are mantissa, base and exponent.
1223
1224    Keyword Args
1225    ------------
1226    value: :class:`tuple`, :class:`float` or |ASN.1| object
1227        Python sequence of :class:`int` (representing mantissa, base and
1228        exponent) or float instance or *Real* class instance.
1229
1230    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
1231        Object representing non-default ASN.1 tag(s)
1232
1233    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
1234        Object representing non-default ASN.1 subtype constraint(s)
1235
1236    Raises
1237    ------
1238    :py:class:`~pyasn1.error.PyAsn1Error`
1239        On constraint violation or bad initializer.
1240
1241    Examples
1242    --------
1243    .. code-block:: python
1244
1245        class Pi(Real):
1246            '''
1247            ASN.1 specification:
1248
1249            Pi ::= REAL
1250
1251            pi Pi ::= { mantissa 314159, base 10, exponent -5 }
1252
1253            '''
1254        pi = Pi((314159, 10, -5))
1255    """
1256    binEncBase = None  # binEncBase = 16 is recommended for large numbers
1257
1258    try:
1259        _plusInf = float('inf')
1260        _minusInf = float('-inf')
1261        _inf = _plusInf, _minusInf
1262
1263    except ValueError:
1264        # Infinity support is platform and Python dependent
1265        _plusInf = _minusInf = None
1266        _inf = ()
1267
1268    #: Set (on class, not on instance) or return a
1269    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
1270    #: associated with |ASN.1| type.
1271    tagSet = tag.initTagSet(
1272        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x09)
1273    )
1274
1275    #: Set (on class, not on instance) or return a
1276    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
1277    #: imposing constraints on |ASN.1| type initialization values.
1278    subtypeSpec = constraint.ConstraintsIntersection()
1279
1280    # Optimization for faster codec lookup
1281    typeId = base.AbstractSimpleAsn1Item.getTypeId()
1282
1283    @staticmethod
1284    def __normalizeBase10(value):
1285        m, b, e = value
1286        while m and m % 10 == 0:
1287            m /= 10
1288            e += 1
1289        return m, b, e
1290
1291    def prettyIn(self, value):
1292        if isinstance(value, tuple) and len(value) == 3:
1293            if (not isinstance(value[0], numericTypes) or
1294                    not isinstance(value[1], intTypes) or
1295                    not isinstance(value[2], intTypes)):
1296                raise error.PyAsn1Error('Lame Real value syntax: %s' % (value,))
1297            if (isinstance(value[0], float) and
1298                    self._inf and value[0] in self._inf):
1299                return value[0]
1300            if value[1] not in (2, 10):
1301                raise error.PyAsn1Error(
1302                    'Prohibited base for Real value: %s' % (value[1],)
1303                )
1304            if value[1] == 10:
1305                value = self.__normalizeBase10(value)
1306            return value
1307        elif isinstance(value, intTypes):
1308            return self.__normalizeBase10((value, 10, 0))
1309        elif isinstance(value, float) or octets.isStringType(value):
1310            if octets.isStringType(value):
1311                try:
1312                    value = float(value)
1313                except ValueError:
1314                    raise error.PyAsn1Error(
1315                        'Bad real value syntax: %s' % (value,)
1316                    )
1317            if self._inf and value in self._inf:
1318                return value
1319            else:
1320                e = 0
1321                while int(value) != value:
1322                    value *= 10
1323                    e -= 1
1324                return self.__normalizeBase10((int(value), 10, e))
1325        elif isinstance(value, Real):
1326            return tuple(value)
1327        raise error.PyAsn1Error(
1328            'Bad real value syntax: %s' % (value,)
1329        )
1330
1331    def prettyPrint(self, scope=0):
1332        try:
1333            return self.prettyOut(float(self))
1334
1335        except OverflowError:
1336            return '<overflow>'
1337
1338    @property
1339    def isPlusInf(self):
1340        """Indicate PLUS-INFINITY object value
1341
1342        Returns
1343        -------
1344        : :class:`bool`
1345            :class:`True` if calling object represents plus infinity
1346            or :class:`False` otherwise.
1347
1348        """
1349        return self._value == self._plusInf
1350
1351    @property
1352    def isMinusInf(self):
1353        """Indicate MINUS-INFINITY object value
1354
1355        Returns
1356        -------
1357        : :class:`bool`
1358            :class:`True` if calling object represents minus infinity
1359            or :class:`False` otherwise.
1360        """
1361        return self._value == self._minusInf
1362
1363    @property
1364    def isInf(self):
1365        return self._value in self._inf
1366
1367    def __add__(self, value):
1368        return self.clone(float(self) + value)
1369
1370    def __radd__(self, value):
1371        return self + value
1372
1373    def __mul__(self, value):
1374        return self.clone(float(self) * value)
1375
1376    def __rmul__(self, value):
1377        return self * value
1378
1379    def __sub__(self, value):
1380        return self.clone(float(self) - value)
1381
1382    def __rsub__(self, value):
1383        return self.clone(value - float(self))
1384
1385    def __mod__(self, value):
1386        return self.clone(float(self) % value)
1387
1388    def __rmod__(self, value):
1389        return self.clone(value % float(self))
1390
1391    def __pow__(self, value, modulo=None):
1392        return self.clone(pow(float(self), value, modulo))
1393
1394    def __rpow__(self, value):
1395        return self.clone(pow(value, float(self)))
1396
1397    if sys.version_info[0] <= 2:
1398        def __div__(self, value):
1399            return self.clone(float(self) / value)
1400
1401        def __rdiv__(self, value):
1402            return self.clone(value / float(self))
1403    else:
1404        def __truediv__(self, value):
1405            return self.clone(float(self) / value)
1406
1407        def __rtruediv__(self, value):
1408            return self.clone(value / float(self))
1409
1410        def __divmod__(self, value):
1411            return self.clone(float(self) // value)
1412
1413        def __rdivmod__(self, value):
1414            return self.clone(value // float(self))
1415
1416    def __int__(self):
1417        return int(float(self))
1418
1419    if sys.version_info[0] <= 2:
1420        def __long__(self):
1421            return long(float(self))
1422
1423    def __float__(self):
1424        if self._value in self._inf:
1425            return self._value
1426        else:
1427            return float(
1428                self._value[0] * pow(self._value[1], self._value[2])
1429            )
1430
1431    def __abs__(self):
1432        return self.clone(abs(float(self)))
1433
1434    def __pos__(self):
1435        return self.clone(+float(self))
1436
1437    def __neg__(self):
1438        return self.clone(-float(self))
1439
1440    def __round__(self, n=0):
1441        r = round(float(self), n)
1442        if n:
1443            return self.clone(r)
1444        else:
1445            return r
1446
1447    def __floor__(self):
1448        return self.clone(math.floor(float(self)))
1449
1450    def __ceil__(self):
1451        return self.clone(math.ceil(float(self)))
1452
1453    if sys.version_info[0:2] > (2, 5):
1454        def __trunc__(self):
1455            return self.clone(math.trunc(float(self)))
1456
1457    def __lt__(self, value):
1458        return float(self) < value
1459
1460    def __le__(self, value):
1461        return float(self) <= value
1462
1463    def __eq__(self, value):
1464        return float(self) == value
1465
1466    def __ne__(self, value):
1467        return float(self) != value
1468
1469    def __gt__(self, value):
1470        return float(self) > value
1471
1472    def __ge__(self, value):
1473        return float(self) >= value
1474
1475    if sys.version_info[0] <= 2:
1476        def __nonzero__(self):
1477            return bool(float(self))
1478    else:
1479        def __bool__(self):
1480            return bool(float(self))
1481
1482        __hash__ = base.AbstractSimpleAsn1Item.__hash__
1483
1484    def __getitem__(self, idx):
1485        if self._value in self._inf:
1486            raise error.PyAsn1Error('Invalid infinite value operation')
1487        else:
1488            return self._value[idx]
1489
1490    # compatibility stubs
1491
1492    def isPlusInfinity(self):
1493        return self.isPlusInf
1494
1495    def isMinusInfinity(self):
1496        return self.isMinusInf
1497
1498    def isInfinity(self):
1499        return self.isInf
1500
1501
1502class Enumerated(Integer):
1503    """Create |ASN.1| type or object.
1504
1505    |ASN.1| objects are immutable and duck-type Python :class:`int` objects.
1506
1507    Keyword Args
1508    ------------
1509    value: :class:`int`, :class:`str` or |ASN.1| object
1510        Python integer or string literal or |ASN.1| class instance.
1511
1512    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
1513        Object representing non-default ASN.1 tag(s)
1514
1515    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
1516        Object representing non-default ASN.1 subtype constraint(s)
1517
1518    namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
1519        Object representing non-default symbolic aliases for numbers
1520
1521    Raises
1522    ------
1523    :py:class:`~pyasn1.error.PyAsn1Error`
1524        On constraint violation or bad initializer.
1525
1526    Examples
1527    --------
1528
1529    .. code-block:: python
1530
1531        class RadioButton(Enumerated):
1532            '''
1533            ASN.1 specification:
1534
1535            RadioButton ::= ENUMERATED { button1(0), button2(1),
1536                                         button3(2) }
1537
1538            selected-by-default RadioButton ::= button1
1539            '''
1540            namedValues = NamedValues(
1541                ('button1', 0), ('button2', 1),
1542                ('button3', 2)
1543            )
1544
1545        selected_by_default = RadioButton('button1')
1546    """
1547    #: Set (on class, not on instance) or return a
1548    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
1549    #: associated with |ASN.1| type.
1550    tagSet = tag.initTagSet(
1551        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x0A)
1552    )
1553
1554    #: Set (on class, not on instance) or return a
1555    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
1556    #: imposing constraints on |ASN.1| type initialization values.
1557    subtypeSpec = constraint.ConstraintsIntersection()
1558
1559    # Optimization for faster codec lookup
1560    typeId = Integer.getTypeId()
1561
1562    #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
1563    #: representing symbolic aliases for numbers
1564    namedValues = namedval.NamedValues()
1565
1566
1567# "Structured" ASN.1 types
1568
1569class SequenceOfAndSetOfBase(base.AbstractConstructedAsn1Item):
1570    """Create |ASN.1| type.
1571
1572    |ASN.1| objects are mutable and duck-type Python :class:`list` objects.
1573
1574    Keyword Args
1575    ------------
1576    componentType : :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
1577        A pyasn1 object representing ASN.1 type allowed within |ASN.1| type
1578
1579    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
1580        Object representing non-default ASN.1 tag(s)
1581
1582    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
1583        Object representing non-default ASN.1 subtype constraint(s)
1584
1585    sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
1586        Object representing collection size constraint
1587
1588    Examples
1589    --------
1590
1591    .. code-block:: python
1592
1593        class LotteryDraw(SequenceOf):  #  SetOf is similar
1594            '''
1595            ASN.1 specification:
1596
1597            LotteryDraw ::= SEQUENCE OF INTEGER
1598            '''
1599            componentType = Integer()
1600
1601        lotteryDraw = LotteryDraw()
1602        lotteryDraw.extend([123, 456, 789])
1603    """
1604    def __init__(self, *args, **kwargs):
1605        # support positional params for backward compatibility
1606        if args:
1607            for key, value in zip(('componentType', 'tagSet',
1608                                   'subtypeSpec', 'sizeSpec'), args):
1609                if key in kwargs:
1610                    raise error.PyAsn1Error('Conflicting positional and keyword params!')
1611                kwargs['componentType'] = value
1612
1613        base.AbstractConstructedAsn1Item.__init__(self, **kwargs)
1614
1615    # Python list protocol
1616
1617    def __getitem__(self, idx):
1618        try:
1619            return self.getComponentByPosition(idx)
1620
1621        except error.PyAsn1Error:
1622            raise IndexError(sys.exc_info()[1])
1623
1624    def __setitem__(self, idx, value):
1625        try:
1626            self.setComponentByPosition(idx, value)
1627
1628        except error.PyAsn1Error:
1629            raise IndexError(sys.exc_info()[1])
1630
1631    def clear(self):
1632        self._componentValues = []
1633
1634    def append(self, value):
1635        self[len(self)] = value
1636
1637    def count(self, value):
1638        return self._componentValues.count(value)
1639
1640    def extend(self, values):
1641        for value in values:
1642            self.append(value)
1643
1644    def index(self, value, start=0, stop=None):
1645        if stop is None:
1646            stop = len(self)
1647        try:
1648            return self._componentValues.index(value, start, stop)
1649
1650        except error.PyAsn1Error:
1651            raise ValueError(sys.exc_info()[1])
1652
1653    def reverse(self):
1654        self._componentValues.reverse()
1655
1656    def sort(self, key=None, reverse=False):
1657        self._componentValues.sort(key=key, reverse=reverse)
1658
1659    def __iter__(self):
1660        return iter(self._componentValues)
1661
1662    def _cloneComponentValues(self, myClone, cloneValueFlag):
1663        for idx, componentValue in enumerate(self._componentValues):
1664            if componentValue is not noValue:
1665                if isinstance(componentValue, base.AbstractConstructedAsn1Item):
1666                    myClone.setComponentByPosition(
1667                        idx, componentValue.clone(cloneValueFlag=cloneValueFlag)
1668                    )
1669                else:
1670                    myClone.setComponentByPosition(idx, componentValue.clone())
1671
1672    def getComponentByPosition(self, idx, default=noValue, instantiate=True):
1673        """Return |ASN.1| type component value by position.
1674
1675        Equivalent to Python sequence subscription operation (e.g. `[]`).
1676
1677        Parameters
1678        ----------
1679        idx : :class:`int`
1680            Component index (zero-based). Must either refer to an existing
1681            component or to N+1 component (if *componentType* is set). In the latter
1682            case a new component type gets instantiated and appended to the |ASN.1|
1683            sequence.
1684
1685        Keyword Args
1686        ------------
1687        default: :class:`object`
1688            If set and requested component is a schema object, return the `default`
1689            object instead of the requested component.
1690
1691        instantiate: :class:`bool`
1692            If `True` (default), inner component will be automatically instantiated.
1693            If 'False' either existing component or the `noValue` object will be
1694            returned.
1695
1696        Returns
1697        -------
1698        : :py:class:`~pyasn1.type.base.PyAsn1Item`
1699            Instantiate |ASN.1| component type or return existing component value
1700
1701        Examples
1702        --------
1703
1704        .. code-block:: python
1705
1706            # can also be SetOf
1707            class MySequenceOf(SequenceOf):
1708                componentType = OctetString()
1709
1710            s = MySequenceOf()
1711
1712            # returns component #0 with `.isValue` property False
1713            s.getComponentByPosition(0)
1714
1715            # returns None
1716            s.getComponentByPosition(0, default=None)
1717
1718            s.clear()
1719
1720            # returns noValue
1721            s.getComponentByPosition(0, instantiate=False)
1722
1723            # sets component #0 to OctetString() ASN.1 schema
1724            # object and returns it
1725            s.getComponentByPosition(0, instantiate=True)
1726
1727            # sets component #0 to ASN.1 value object
1728            s.setComponentByPosition(0, 'ABCD')
1729
1730            # returns OctetString('ABCD') value object
1731            s.getComponentByPosition(0, instantiate=False)
1732
1733            s.clear()
1734
1735            # returns noValue
1736            s.getComponentByPosition(0, instantiate=False)
1737        """
1738        try:
1739            componentValue = self._componentValues[idx]
1740
1741        except IndexError:
1742            if not instantiate:
1743                return default
1744
1745            self.setComponentByPosition(idx)
1746
1747            componentValue = self._componentValues[idx]
1748
1749        if default is noValue or componentValue.isValue:
1750            return componentValue
1751        else:
1752            return default
1753
1754    def setComponentByPosition(self, idx, value=noValue,
1755                               verifyConstraints=True,
1756                               matchTags=True,
1757                               matchConstraints=True):
1758        """Assign |ASN.1| type component by position.
1759
1760        Equivalent to Python sequence item assignment operation (e.g. `[]`)
1761        or list.append() (when idx == len(self)).
1762
1763        Parameters
1764        ----------
1765        idx: :class:`int`
1766            Component index (zero-based). Must either refer to existing
1767            component or to N+1 component. In the latter case a new component
1768            type gets instantiated (if *componentType* is set, or given ASN.1
1769            object is taken otherwise) and appended to the |ASN.1| sequence.
1770
1771        Keyword Args
1772        ------------
1773        value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
1774            A Python value to initialize |ASN.1| component with (if *componentType* is set)
1775            or ASN.1 value object to assign to |ASN.1| component.
1776
1777        verifyConstraints: :class:`bool`
1778             If `False`, skip constraints validation
1779
1780        matchTags: :class:`bool`
1781             If `False`, skip component tags matching
1782
1783        matchConstraints: :class:`bool`
1784             If `False`, skip component constraints matching
1785
1786        Returns
1787        -------
1788        self
1789
1790        Raises
1791        ------
1792        IndexError:
1793            When idx > len(self)
1794        """
1795        componentType = self.componentType
1796
1797        try:
1798            currentValue = self._componentValues[idx]
1799        except IndexError:
1800            currentValue = noValue
1801
1802            if len(self._componentValues) < idx:
1803                raise error.PyAsn1Error('Component index out of range')
1804
1805        if value is noValue:
1806            if componentType is not None:
1807                value = componentType.clone()
1808            elif currentValue is noValue:
1809                raise error.PyAsn1Error('Component type not defined')
1810        elif not isinstance(value, base.Asn1Item):
1811            if componentType is not None and isinstance(componentType, base.AbstractSimpleAsn1Item):
1812                value = componentType.clone(value=value)
1813            elif currentValue is not noValue and isinstance(currentValue, base.AbstractSimpleAsn1Item):
1814                value = currentValue.clone(value=value)
1815            else:
1816                raise error.PyAsn1Error('Non-ASN.1 value %r and undefined component type at %r' % (value, self))
1817        elif componentType is not None:
1818            if self.strictConstraints:
1819                if not componentType.isSameTypeWith(value, matchTags, matchConstraints):
1820                    raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
1821            else:
1822                if not componentType.isSuperTypeOf(value, matchTags, matchConstraints):
1823                    raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
1824
1825        if verifyConstraints and value.isValue:
1826            try:
1827                self.subtypeSpec(value, idx)
1828
1829            except error.PyAsn1Error:
1830                exType, exValue, exTb = sys.exc_info()
1831                raise exType('%s at %s' % (exValue, self.__class__.__name__))
1832
1833        if currentValue is noValue:
1834            self._componentValues.append(value)
1835        else:
1836            self._componentValues[idx] = value
1837
1838        return self
1839
1840    @property
1841    def componentTagMap(self):
1842        if self.componentType is not None:
1843            return self.componentType.tagMap
1844
1845    def prettyPrint(self, scope=0):
1846        scope += 1
1847        representation = self.__class__.__name__ + ':\n'
1848        for idx, componentValue in enumerate(self._componentValues):
1849            representation += ' ' * scope
1850            if (componentValue is noValue and
1851                    self.componentType is not None):
1852                representation += '<empty>'
1853            else:
1854                representation += componentValue.prettyPrint(scope)
1855        return representation
1856
1857    def prettyPrintType(self, scope=0):
1858        scope += 1
1859        representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__)
1860        if self.componentType is not None:
1861            representation += ' ' * scope
1862            representation += self.componentType.prettyPrintType(scope)
1863        return representation + '\n' + ' ' * (scope - 1) + '}'
1864
1865
1866    @property
1867    def isValue(self):
1868        """Indicate that |ASN.1| object represents ASN.1 value.
1869
1870        If *isValue* is `False` then this object represents just ASN.1 schema.
1871
1872        If *isValue* is `True` then, in addition to its ASN.1 schema features,
1873        this object can also be used like a Python built-in object (e.g. `int`,
1874        `str`, `dict` etc.).
1875
1876        Returns
1877        -------
1878        : :class:`bool`
1879            :class:`False` if object represents just ASN.1 schema.
1880            :class:`True` if object represents ASN.1 schema and can be used as a normal value.
1881
1882        Note
1883        ----
1884        There is an important distinction between PyASN1 schema and value objects.
1885        The PyASN1 schema objects can only participate in ASN.1 schema-related
1886        operations (e.g. defining or testing the structure of the data). Most
1887        obvious uses of ASN.1 schema is to guide serialisation codecs whilst
1888        encoding/decoding serialised ASN.1 contents.
1889
1890        The PyASN1 value objects can **additionally** participate in many operations
1891        involving regular Python objects (e.g. arithmetic, comprehension etc).
1892        """
1893        for componentValue in self._componentValues:
1894            if componentValue is noValue or not componentValue.isValue:
1895                return False
1896
1897        return True
1898
1899
1900class SequenceOf(SequenceOfAndSetOfBase):
1901    __doc__ = SequenceOfAndSetOfBase.__doc__
1902
1903    #: Set (on class, not on instance) or return a
1904    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
1905    #: associated with |ASN.1| type.
1906    tagSet = tag.initTagSet(
1907        tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
1908    )
1909
1910    #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
1911    #: object representing ASN.1 type allowed within |ASN.1| type
1912    componentType = None
1913
1914    #: Set (on class, not on instance) or return a
1915    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
1916    #: imposing constraints on |ASN.1| type initialization values.
1917    subtypeSpec = constraint.ConstraintsIntersection()
1918
1919    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
1920    #: object imposing size constraint on |ASN.1| objects
1921    sizeSpec = constraint.ConstraintsIntersection()
1922
1923    # Disambiguation ASN.1 types identification
1924    typeId = SequenceOfAndSetOfBase.getTypeId()
1925
1926
1927class SetOf(SequenceOfAndSetOfBase):
1928    __doc__ = SequenceOfAndSetOfBase.__doc__
1929
1930    #: Set (on class, not on instance) or return a
1931    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
1932    #: associated with |ASN.1| type.
1933    tagSet = tag.initTagSet(
1934        tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
1935    )
1936
1937    #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
1938    #: object representing ASN.1 type allowed within |ASN.1| type
1939    componentType = None
1940
1941    #: Set (on class, not on instance) or return a
1942    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
1943    #: imposing constraints on |ASN.1| type initialization values.
1944    subtypeSpec = constraint.ConstraintsIntersection()
1945
1946    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
1947    #: object imposing size constraint on |ASN.1| objects
1948    sizeSpec = constraint.ConstraintsIntersection()
1949
1950    # Disambiguation ASN.1 types identification
1951    typeId = SequenceOfAndSetOfBase.getTypeId()
1952
1953
1954class SequenceAndSetBase(base.AbstractConstructedAsn1Item):
1955    """Create |ASN.1| type.
1956
1957    |ASN.1| objects are mutable and duck-type Python :class:`dict` objects.
1958
1959    Keyword Args
1960    ------------
1961    componentType: :py:class:`~pyasn1.type.namedtype.NamedType`
1962        Object holding named ASN.1 types allowed within this collection
1963
1964    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
1965        Object representing non-default ASN.1 tag(s)
1966
1967    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
1968        Object representing non-default ASN.1 subtype constraint(s)
1969
1970    sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
1971        Object representing collection size constraint
1972
1973    Examples
1974    --------
1975
1976    .. code-block:: python
1977
1978        class Description(Sequence):  #  Set is similar
1979            '''
1980            ASN.1 specification:
1981
1982            Description ::= SEQUENCE {
1983                surname    IA5String,
1984                first-name IA5String OPTIONAL,
1985                age        INTEGER DEFAULT 40
1986            }
1987            '''
1988            componentType = NamedTypes(
1989                NamedType('surname', IA5String()),
1990                OptionalNamedType('first-name', IA5String()),
1991                DefaultedNamedType('age', Integer(40))
1992            )
1993
1994        descr = Description()
1995        descr['surname'] = 'Smith'
1996        descr['first-name'] = 'John'
1997    """
1998    #: Default :py:class:`~pyasn1.type.namedtype.NamedTypes`
1999    #: object representing named ASN.1 types allowed within |ASN.1| type
2000    componentType = namedtype.NamedTypes()
2001
2002
2003    class DynamicNames(object):
2004        """Fields names/positions mapping for component-less objects"""
2005        def __init__(self):
2006            self._keyToIdxMap = {}
2007            self._idxToKeyMap = {}
2008
2009        def __len__(self):
2010            return len(self._keyToIdxMap)
2011
2012        def __contains__(self, item):
2013            return item in self._keyToIdxMap or item in self._idxToKeyMap
2014
2015        def __iter__(self):
2016            return (self._idxToKeyMap[idx] for idx in range(len(self._idxToKeyMap)))
2017
2018        def __getitem__(self, item):
2019            try:
2020                return self._keyToIdxMap[item]
2021
2022            except KeyError:
2023                return self._idxToKeyMap[item]
2024
2025        def getNameByPosition(self, idx):
2026            try:
2027                return self._idxToKeyMap[idx]
2028
2029            except KeyError:
2030                raise error.PyAsn1Error('Type position out of range')
2031
2032        def getPositionByName(self, name):
2033            try:
2034                return self._keyToIdxMap[name]
2035
2036            except KeyError:
2037                raise error.PyAsn1Error('Name %s not found' % (name,))
2038
2039        def addField(self, idx):
2040            self._keyToIdxMap['field-%d' % idx] = idx
2041            self._idxToKeyMap[idx] = 'field-%d' % idx
2042
2043
2044    def __init__(self, **kwargs):
2045        base.AbstractConstructedAsn1Item.__init__(self, **kwargs)
2046        self._componentTypeLen = len(self.componentType)
2047        self._dynamicNames = self._componentTypeLen or self.DynamicNames()
2048
2049    def __getitem__(self, idx):
2050        if octets.isStringType(idx):
2051            try:
2052                return self.getComponentByName(idx)
2053
2054            except error.PyAsn1Error:
2055                # duck-typing dict
2056                raise KeyError(sys.exc_info()[1])
2057
2058        else:
2059            try:
2060                return self.getComponentByPosition(idx)
2061
2062            except error.PyAsn1Error:
2063                # duck-typing list
2064                raise IndexError(sys.exc_info()[1])
2065
2066    def __setitem__(self, idx, value):
2067        if octets.isStringType(idx):
2068            try:
2069                self.setComponentByName(idx, value)
2070
2071            except error.PyAsn1Error:
2072                # duck-typing dict
2073                raise KeyError(sys.exc_info()[1])
2074
2075        else:
2076            try:
2077                self.setComponentByPosition(idx, value)
2078
2079            except error.PyAsn1Error:
2080                # duck-typing list
2081                raise IndexError(sys.exc_info()[1])
2082
2083    def __contains__(self, key):
2084        if self._componentTypeLen:
2085            return key in self.componentType
2086        else:
2087            return key in self._dynamicNames
2088
2089    def __iter__(self):
2090        return iter(self.componentType or self._dynamicNames)
2091
2092    # Python dict protocol
2093
2094    def values(self):
2095        for idx in range(self._componentTypeLen or len(self._dynamicNames)):
2096            yield self[idx]
2097
2098    def keys(self):
2099        return iter(self)
2100
2101    def items(self):
2102        for idx in range(self._componentTypeLen or len(self._dynamicNames)):
2103            if self._componentTypeLen:
2104                yield self.componentType[idx].name, self[idx]
2105            else:
2106                yield self._dynamicNames[idx], self[idx]
2107
2108    def update(self, *iterValue, **mappingValue):
2109        for k, v in iterValue:
2110            self[k] = v
2111        for k in mappingValue:
2112            self[k] = mappingValue[k]
2113
2114    def clear(self):
2115        self._componentValues = []
2116        self._dynamicNames = self.DynamicNames()
2117
2118    def _cloneComponentValues(self, myClone, cloneValueFlag):
2119        for idx, componentValue in enumerate(self._componentValues):
2120            if componentValue is not noValue:
2121                if isinstance(componentValue, base.AbstractConstructedAsn1Item):
2122                    myClone.setComponentByPosition(
2123                        idx, componentValue.clone(cloneValueFlag=cloneValueFlag)
2124                    )
2125                else:
2126                    myClone.setComponentByPosition(idx, componentValue.clone())
2127
2128    def getComponentByName(self, name, default=noValue, instantiate=True):
2129        """Returns |ASN.1| type component by name.
2130
2131        Equivalent to Python :class:`dict` subscription operation (e.g. `[]`).
2132
2133        Parameters
2134        ----------
2135        name: :class:`str`
2136            |ASN.1| type component name
2137
2138        Keyword Args
2139        ------------
2140        default: :class:`object`
2141            If set and requested component is a schema object, return the `default`
2142            object instead of the requested component.
2143
2144        instantiate: :class:`bool`
2145            If `True` (default), inner component will be automatically instantiated.
2146            If 'False' either existing component or the `noValue` object will be
2147            returned.
2148
2149        Returns
2150        -------
2151        : :py:class:`~pyasn1.type.base.PyAsn1Item`
2152            Instantiate |ASN.1| component type or return existing component value
2153        """
2154        if self._componentTypeLen:
2155            idx = self.componentType.getPositionByName(name)
2156        else:
2157            try:
2158                idx = self._dynamicNames.getPositionByName(name)
2159
2160            except KeyError:
2161                raise error.PyAsn1Error('Name %s not found' % (name,))
2162
2163        return self.getComponentByPosition(idx, default=default, instantiate=instantiate)
2164
2165    def setComponentByName(self, name, value=noValue,
2166                           verifyConstraints=True,
2167                           matchTags=True,
2168                           matchConstraints=True):
2169        """Assign |ASN.1| type component by name.
2170
2171        Equivalent to Python :class:`dict` item assignment operation (e.g. `[]`).
2172
2173        Parameters
2174        ----------
2175        name: :class:`str`
2176            |ASN.1| type component name
2177
2178        Keyword Args
2179        ------------
2180        value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
2181            A Python value to initialize |ASN.1| component with (if *componentType* is set)
2182            or ASN.1 value object to assign to |ASN.1| component.
2183
2184        verifyConstraints: :class:`bool`
2185             If `False`, skip constraints validation
2186
2187        matchTags: :class:`bool`
2188             If `False`, skip component tags matching
2189
2190        matchConstraints: :class:`bool`
2191             If `False`, skip component constraints matching
2192
2193        Returns
2194        -------
2195        self
2196        """
2197        if self._componentTypeLen:
2198            idx = self.componentType.getPositionByName(name)
2199        else:
2200            try:
2201                idx = self._dynamicNames.getPositionByName(name)
2202
2203            except KeyError:
2204                raise error.PyAsn1Error('Name %s not found' % (name,))
2205
2206        return self.setComponentByPosition(
2207            idx, value, verifyConstraints, matchTags, matchConstraints
2208        )
2209
2210    def getComponentByPosition(self, idx, default=noValue, instantiate=True):
2211        """Returns |ASN.1| type component by index.
2212
2213        Equivalent to Python sequence subscription operation (e.g. `[]`).
2214
2215        Parameters
2216        ----------
2217        idx: :class:`int`
2218            Component index (zero-based). Must either refer to an existing
2219            component or (if *componentType* is set) new ASN.1 schema object gets
2220            instantiated.
2221
2222        Keyword Args
2223        ------------
2224        default: :class:`object`
2225            If set and requested component is a schema object, return the `default`
2226            object instead of the requested component.
2227
2228        instantiate: :class:`bool`
2229            If `True` (default), inner component will be automatically instantiated.
2230            If 'False' either existing component or the `noValue` object will be
2231            returned.
2232
2233        Returns
2234        -------
2235        : :py:class:`~pyasn1.type.base.PyAsn1Item`
2236            a PyASN1 object
2237
2238        Examples
2239        --------
2240
2241        .. code-block:: python
2242
2243            # can also be Set
2244            class MySequence(Sequence):
2245                componentType = NamedTypes(
2246                    NamedType('id', OctetString())
2247                )
2248
2249            s = MySequence()
2250
2251            # returns component #0 with `.isValue` property False
2252            s.getComponentByPosition(0)
2253
2254            # returns None
2255            s.getComponentByPosition(0, default=None)
2256
2257            s.clear()
2258
2259            # returns noValue
2260            s.getComponentByPosition(0, instantiate=False)
2261
2262            # sets component #0 to OctetString() ASN.1 schema
2263            # object and returns it
2264            s.getComponentByPosition(0, instantiate=True)
2265
2266            # sets component #0 to ASN.1 value object
2267            s.setComponentByPosition(0, 'ABCD')
2268
2269            # returns OctetString('ABCD') value object
2270            s.getComponentByPosition(0, instantiate=False)
2271
2272            s.clear()
2273
2274            # returns noValue
2275            s.getComponentByPosition(0, instantiate=False)
2276        """
2277        try:
2278            componentValue = self._componentValues[idx]
2279
2280        except IndexError:
2281            componentValue = noValue
2282
2283        if not instantiate:
2284            if componentValue is noValue or not componentValue.isValue:
2285                return default
2286            else:
2287                return componentValue
2288
2289        if componentValue is noValue:
2290            self.setComponentByPosition(idx)
2291
2292        componentValue = self._componentValues[idx]
2293
2294        if default is noValue or componentValue.isValue:
2295            return componentValue
2296        else:
2297            return default
2298
2299    def setComponentByPosition(self, idx, value=noValue,
2300                               verifyConstraints=True,
2301                               matchTags=True,
2302                               matchConstraints=True):
2303        """Assign |ASN.1| type component by position.
2304
2305        Equivalent to Python sequence item assignment operation (e.g. `[]`).
2306
2307        Parameters
2308        ----------
2309        idx : :class:`int`
2310            Component index (zero-based). Must either refer to existing
2311            component (if *componentType* is set) or to N+1 component
2312            otherwise. In the latter case a new component of given ASN.1
2313            type gets instantiated and appended to |ASN.1| sequence.
2314
2315        Keyword Args
2316        ------------
2317        value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
2318            A Python value to initialize |ASN.1| component with (if *componentType* is set)
2319            or ASN.1 value object to assign to |ASN.1| component.
2320
2321        verifyConstraints : :class:`bool`
2322             If `False`, skip constraints validation
2323
2324        matchTags: :class:`bool`
2325             If `False`, skip component tags matching
2326
2327        matchConstraints: :class:`bool`
2328             If `False`, skip component constraints matching
2329
2330        Returns
2331        -------
2332        self
2333        """
2334        componentType = self.componentType
2335        componentTypeLen = self._componentTypeLen
2336
2337        try:
2338            currentValue = self._componentValues[idx]
2339
2340        except IndexError:
2341            currentValue = noValue
2342            if componentTypeLen:
2343                if componentTypeLen < idx:
2344                    raise error.PyAsn1Error('component index out of range')
2345
2346                self._componentValues = [noValue] * componentTypeLen
2347
2348        if value is noValue:
2349            if componentTypeLen:
2350                value = componentType.getTypeByPosition(idx)
2351                if isinstance(value, base.AbstractConstructedAsn1Item):
2352                    value = value.clone(cloneValueFlag=componentType[idx].isDefaulted)
2353
2354            elif currentValue is noValue:
2355                raise error.PyAsn1Error('Component type not defined')
2356
2357        elif not isinstance(value, base.Asn1Item):
2358            if componentTypeLen:
2359                subComponentType = componentType.getTypeByPosition(idx)
2360                if isinstance(subComponentType, base.AbstractSimpleAsn1Item):
2361                    value = subComponentType.clone(value=value)
2362
2363                else:
2364                    raise error.PyAsn1Error('%s can cast only scalar values' % componentType.__class__.__name__)
2365
2366            elif currentValue is not noValue and isinstance(currentValue, base.AbstractSimpleAsn1Item):
2367                value = currentValue.clone(value=value)
2368
2369            else:
2370                raise error.PyAsn1Error('%s undefined component type' % componentType.__class__.__name__)
2371
2372        elif (matchTags or matchConstraints) and componentTypeLen:
2373            subComponentType = componentType.getTypeByPosition(idx)
2374            if subComponentType is not noValue:
2375                subtypeChecker = (self.strictConstraints and
2376                                  subComponentType.isSameTypeWith or
2377                                  subComponentType.isSuperTypeOf)
2378
2379                if not subtypeChecker(value, matchTags, matchConstraints):
2380                    if not componentType[idx].openType:
2381                        raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
2382
2383        if verifyConstraints and value.isValue:
2384            try:
2385                self.subtypeSpec(value, idx)
2386
2387            except error.PyAsn1Error:
2388                exType, exValue, exTb = sys.exc_info()
2389                raise exType('%s at %s' % (exValue, self.__class__.__name__))
2390
2391        if componentTypeLen or idx in self._dynamicNames:
2392            self._componentValues[idx] = value
2393
2394        elif len(self._componentValues) == idx:
2395            self._componentValues.append(value)
2396            self._dynamicNames.addField(idx)
2397
2398        else:
2399            raise error.PyAsn1Error('Component index out of range')
2400
2401        return self
2402
2403    @property
2404    def isValue(self):
2405        """Indicate that |ASN.1| object represents ASN.1 value.
2406
2407        If *isValue* is `False` then this object represents just ASN.1 schema.
2408
2409        If *isValue* is `True` then, in addition to its ASN.1 schema features,
2410        this object can also be used like a Python built-in object (e.g. `int`,
2411        `str`, `dict` etc.).
2412
2413        Returns
2414        -------
2415        : :class:`bool`
2416            :class:`False` if object represents just ASN.1 schema.
2417            :class:`True` if object represents ASN.1 schema and can be used as a normal value.
2418
2419        Note
2420        ----
2421        There is an important distinction between PyASN1 schema and value objects.
2422        The PyASN1 schema objects can only participate in ASN.1 schema-related
2423        operations (e.g. defining or testing the structure of the data). Most
2424        obvious uses of ASN.1 schema is to guide serialisation codecs whilst
2425        encoding/decoding serialised ASN.1 contents.
2426
2427        The PyASN1 value objects can **additionally** participate in many operations
2428        involving regular Python objects (e.g. arithmetic, comprehension etc).
2429        """
2430        componentType = self.componentType
2431
2432        if componentType:
2433            for idx, subComponentType in enumerate(componentType.namedTypes):
2434                if subComponentType.isDefaulted or subComponentType.isOptional:
2435                    continue
2436
2437                if not self._componentValues:
2438                    return False
2439
2440                componentValue = self._componentValues[idx]
2441                if componentValue is noValue or not componentValue.isValue:
2442                    return False
2443
2444        else:
2445            for componentValue in self._componentValues:
2446                if componentValue is noValue or not componentValue.isValue:
2447                    return False
2448
2449        return True
2450
2451    def prettyPrint(self, scope=0):
2452        """Return an object representation string.
2453
2454        Returns
2455        -------
2456        : :class:`str`
2457            Human-friendly object representation.
2458        """
2459        scope += 1
2460        representation = self.__class__.__name__ + ':\n'
2461        for idx, componentValue in enumerate(self._componentValues):
2462            if componentValue is not noValue and componentValue.isValue:
2463                representation += ' ' * scope
2464                if self.componentType:
2465                    representation += self.componentType.getNameByPosition(idx)
2466                else:
2467                    representation += self._dynamicNames.getNameByPosition(idx)
2468                representation = '%s=%s\n' % (
2469                    representation, componentValue.prettyPrint(scope)
2470                )
2471        return representation
2472
2473    def prettyPrintType(self, scope=0):
2474        scope += 1
2475        representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__)
2476        for idx, componentType in enumerate(self.componentType.values() or self._componentValues):
2477            representation += ' ' * scope
2478            if self.componentType:
2479                representation += '"%s"' % self.componentType.getNameByPosition(idx)
2480            else:
2481                representation += '"%s"' % self._dynamicNames.getNameByPosition(idx)
2482            representation = '%s = %s\n' % (
2483                representation, componentType.prettyPrintType(scope)
2484            )
2485        return representation + '\n' + ' ' * (scope - 1) + '}'
2486
2487    # backward compatibility
2488
2489    def setDefaultComponents(self):
2490        return self
2491
2492    def getComponentType(self):
2493        if self._componentTypeLen:
2494            return self.componentType
2495
2496    def getNameByPosition(self, idx):
2497        if self._componentTypeLen:
2498            return self.componentType[idx].name
2499
2500
2501class Sequence(SequenceAndSetBase):
2502    __doc__ = SequenceAndSetBase.__doc__
2503
2504    #: Set (on class, not on instance) or return a
2505    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
2506    #: associated with |ASN.1| type.
2507    tagSet = tag.initTagSet(
2508        tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
2509    )
2510
2511    #: Set (on class, not on instance) or return a
2512    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
2513    #: imposing constraints on |ASN.1| type initialization values.
2514    subtypeSpec = constraint.ConstraintsIntersection()
2515
2516    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
2517    #: object imposing constraints on |ASN.1| objects
2518    sizeSpec = constraint.ConstraintsIntersection()
2519
2520    #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
2521    #: object imposing size constraint on |ASN.1| objects
2522    componentType = namedtype.NamedTypes()
2523
2524    # Disambiguation ASN.1 types identification
2525    typeId = SequenceAndSetBase.getTypeId()
2526
2527    # backward compatibility
2528
2529    def getComponentTagMapNearPosition(self, idx):
2530        if self.componentType:
2531            return self.componentType.getTagMapNearPosition(idx)
2532
2533    def getComponentPositionNearType(self, tagSet, idx):
2534        if self.componentType:
2535            return self.componentType.getPositionNearType(tagSet, idx)
2536        else:
2537            return idx
2538
2539
2540class Set(SequenceAndSetBase):
2541    __doc__ = SequenceAndSetBase.__doc__
2542
2543    #: Set (on class, not on instance) or return a
2544    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
2545    #: associated with |ASN.1| type.
2546    tagSet = tag.initTagSet(
2547        tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
2548    )
2549
2550    #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
2551    #: object representing ASN.1 type allowed within |ASN.1| type
2552    componentType = namedtype.NamedTypes()
2553
2554    #: Set (on class, not on instance) or return a
2555    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
2556    #: imposing constraints on |ASN.1| type initialization values.
2557    subtypeSpec = constraint.ConstraintsIntersection()
2558
2559    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
2560    #: object imposing constraints on |ASN.1| objects
2561    sizeSpec = constraint.ConstraintsIntersection()
2562
2563    # Disambiguation ASN.1 types identification
2564    typeId = SequenceAndSetBase.getTypeId()
2565
2566    def getComponent(self, innerFlag=False):
2567        return self
2568
2569    def getComponentByType(self, tagSet, default=noValue,
2570                           instantiate=True, innerFlag=False):
2571        """Returns |ASN.1| type component by ASN.1 tag.
2572
2573        Parameters
2574        ----------
2575        tagSet : :py:class:`~pyasn1.type.tag.TagSet`
2576            Object representing ASN.1 tags to identify one of
2577            |ASN.1| object component
2578
2579        Keyword Args
2580        ------------
2581        default: :class:`object`
2582            If set and requested component is a schema object, return the `default`
2583            object instead of the requested component.
2584
2585        instantiate: :class:`bool`
2586            If `True` (default), inner component will be automatically instantiated.
2587            If 'False' either existing component or the `noValue` object will be
2588            returned.
2589
2590        Returns
2591        -------
2592        : :py:class:`~pyasn1.type.base.PyAsn1Item`
2593            a pyasn1 object
2594        """
2595        componentValue = self.getComponentByPosition(
2596            self.componentType.getPositionByType(tagSet),
2597            default=default, instantiate=instantiate
2598        )
2599        if innerFlag and isinstance(componentValue, Set):
2600            # get inner component by inner tagSet
2601            return componentValue.getComponent(innerFlag=True)
2602        else:
2603            # get outer component by inner tagSet
2604            return componentValue
2605
2606    def setComponentByType(self, tagSet, value=noValue,
2607                           verifyConstraints=True,
2608                           matchTags=True,
2609                           matchConstraints=True,
2610                           innerFlag=False):
2611        """Assign |ASN.1| type component by ASN.1 tag.
2612
2613        Parameters
2614        ----------
2615        tagSet : :py:class:`~pyasn1.type.tag.TagSet`
2616            Object representing ASN.1 tags to identify one of
2617            |ASN.1| object component
2618
2619        Keyword Args
2620        ------------
2621        value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
2622            A Python value to initialize |ASN.1| component with (if *componentType* is set)
2623            or ASN.1 value object to assign to |ASN.1| component.
2624
2625        verifyConstraints : :class:`bool`
2626            If `False`, skip constraints validation
2627
2628        matchTags: :class:`bool`
2629            If `False`, skip component tags matching
2630
2631        matchConstraints: :class:`bool`
2632            If `False`, skip component constraints matching
2633
2634        innerFlag: :class:`bool`
2635            If `True`, search for matching *tagSet* recursively.
2636
2637        Returns
2638        -------
2639        self
2640        """
2641        idx = self.componentType.getPositionByType(tagSet)
2642
2643        if innerFlag:  # set inner component by inner tagSet
2644            componentType = self.componentType.getTypeByPosition(idx)
2645
2646            if componentType.tagSet:
2647                return self.setComponentByPosition(
2648                    idx, value, verifyConstraints, matchTags, matchConstraints
2649                )
2650            else:
2651                componentType = self.getComponentByPosition(idx)
2652                return componentType.setComponentByType(
2653                    tagSet, value, verifyConstraints, matchTags, matchConstraints, innerFlag=innerFlag
2654                )
2655        else:  # set outer component by inner tagSet
2656            return self.setComponentByPosition(
2657                idx, value, verifyConstraints, matchTags, matchConstraints
2658            )
2659
2660    @property
2661    def componentTagMap(self):
2662        if self.componentType:
2663            return self.componentType.tagMapUnique
2664
2665
2666class Choice(Set):
2667    """Create |ASN.1| type.
2668
2669    |ASN.1| objects are mutable and duck-type Python :class:`dict` objects.
2670
2671    Keyword Args
2672    ------------
2673    componentType: :py:class:`~pyasn1.type.namedtype.NamedType`
2674        Object holding named ASN.1 types allowed within this collection
2675
2676    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
2677        Object representing non-default ASN.1 tag(s)
2678
2679    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
2680        Object representing non-default ASN.1 subtype constraint(s)
2681
2682    sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
2683        Object representing collection size constraint
2684
2685    Examples
2686    --------
2687
2688    .. code-block:: python
2689
2690        class Afters(Choice):
2691            '''
2692            ASN.1 specification:
2693
2694            Afters ::= CHOICE {
2695                cheese  [0] IA5String,
2696                dessert [1] IA5String
2697            }
2698            '''
2699            componentType = NamedTypes(
2700                NamedType('cheese', IA5String().subtype(
2701                    implicitTag=Tag(tagClassContext, tagFormatSimple, 0)
2702                ),
2703                NamedType('dessert', IA5String().subtype(
2704                    implicitTag=Tag(tagClassContext, tagFormatSimple, 1)
2705                )
2706            )
2707
2708        afters = Afters()
2709        afters['cheese'] = 'Mascarpone'
2710    """
2711    #: Set (on class, not on instance) or return a
2712    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
2713    #: associated with |ASN.1| type.
2714    tagSet = tag.TagSet()  # untagged
2715
2716    #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
2717    #: object representing ASN.1 type allowed within |ASN.1| type
2718    componentType = namedtype.NamedTypes()
2719
2720    #: Set (on class, not on instance) or return a
2721    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
2722    #: imposing constraints on |ASN.1| type initialization values.
2723    subtypeSpec = constraint.ConstraintsIntersection()
2724
2725    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
2726    #: object imposing size constraint on |ASN.1| objects
2727    sizeSpec = constraint.ConstraintsIntersection(
2728        constraint.ValueSizeConstraint(1, 1)
2729    )
2730
2731    # Disambiguation ASN.1 types identification
2732    typeId = Set.getTypeId()
2733
2734    _currentIdx = None
2735
2736    def __eq__(self, other):
2737        if self._componentValues:
2738            return self._componentValues[self._currentIdx] == other
2739        return NotImplemented
2740
2741    def __ne__(self, other):
2742        if self._componentValues:
2743            return self._componentValues[self._currentIdx] != other
2744        return NotImplemented
2745
2746    def __lt__(self, other):
2747        if self._componentValues:
2748            return self._componentValues[self._currentIdx] < other
2749        return NotImplemented
2750
2751    def __le__(self, other):
2752        if self._componentValues:
2753            return self._componentValues[self._currentIdx] <= other
2754        return NotImplemented
2755
2756    def __gt__(self, other):
2757        if self._componentValues:
2758            return self._componentValues[self._currentIdx] > other
2759        return NotImplemented
2760
2761    def __ge__(self, other):
2762        if self._componentValues:
2763            return self._componentValues[self._currentIdx] >= other
2764        return NotImplemented
2765
2766    if sys.version_info[0] <= 2:
2767        def __nonzero__(self):
2768            return self._componentValues and True or False
2769    else:
2770        def __bool__(self):
2771            return self._componentValues and True or False
2772
2773    def __len__(self):
2774        return self._currentIdx is not None and 1 or 0
2775
2776    def __contains__(self, key):
2777        if self._currentIdx is None:
2778            return False
2779        return key == self.componentType[self._currentIdx].getName()
2780
2781    def __iter__(self):
2782        if self._currentIdx is None:
2783            raise StopIteration
2784        yield self.componentType[self._currentIdx].getName()
2785
2786    # Python dict protocol
2787
2788    def values(self):
2789        if self._currentIdx is not None:
2790            yield self._componentValues[self._currentIdx]
2791
2792    def keys(self):
2793        if self._currentIdx is not None:
2794            yield self.componentType[self._currentIdx].getName()
2795
2796    def items(self):
2797        if self._currentIdx is not None:
2798            yield self.componentType[self._currentIdx].getName(), self[self._currentIdx]
2799
2800    def verifySizeSpec(self):
2801        if self._currentIdx is None:
2802            raise error.PyAsn1Error('Component not chosen')
2803
2804    def _cloneComponentValues(self, myClone, cloneValueFlag):
2805        try:
2806            component = self.getComponent()
2807        except error.PyAsn1Error:
2808            pass
2809        else:
2810            if isinstance(component, Choice):
2811                tagSet = component.effectiveTagSet
2812            else:
2813                tagSet = component.tagSet
2814            if isinstance(component, base.AbstractConstructedAsn1Item):
2815                myClone.setComponentByType(
2816                    tagSet, component.clone(cloneValueFlag=cloneValueFlag)
2817                )
2818            else:
2819                myClone.setComponentByType(tagSet, component.clone())
2820
2821    def getComponentByPosition(self, idx, default=noValue, instantiate=True):
2822        __doc__ = Set.__doc__
2823
2824        if self._currentIdx is None or self._currentIdx != idx:
2825            return Set.getComponentByPosition(self, idx, default=default,
2826                                              instantiate=instantiate)
2827
2828        return self._componentValues[idx]
2829
2830    def setComponentByPosition(self, idx, value=noValue,
2831                               verifyConstraints=True,
2832                               matchTags=True,
2833                               matchConstraints=True):
2834        """Assign |ASN.1| type component by position.
2835
2836        Equivalent to Python sequence item assignment operation (e.g. `[]`).
2837
2838        Parameters
2839        ----------
2840        idx: :class:`int`
2841            Component index (zero-based). Must either refer to existing
2842            component or to N+1 component. In the latter case a new component
2843            type gets instantiated (if *componentType* is set, or given ASN.1
2844            object is taken otherwise) and appended to the |ASN.1| sequence.
2845
2846        Keyword Args
2847        ------------
2848        value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
2849            A Python value to initialize |ASN.1| component with (if *componentType* is set)
2850            or ASN.1 value object to assign to |ASN.1| component. Once a new value is
2851            set to *idx* component, previous value is dropped.
2852
2853        verifyConstraints : :class:`bool`
2854            If `False`, skip constraints validation
2855
2856        matchTags: :class:`bool`
2857            If `False`, skip component tags matching
2858
2859        matchConstraints: :class:`bool`
2860            If `False`, skip component constraints matching
2861
2862        Returns
2863        -------
2864        self
2865        """
2866        oldIdx = self._currentIdx
2867        Set.setComponentByPosition(self, idx, value, verifyConstraints, matchTags, matchConstraints)
2868        self._currentIdx = idx
2869        if oldIdx is not None and oldIdx != idx:
2870            self._componentValues[oldIdx] = noValue
2871        return self
2872
2873    @property
2874    def effectiveTagSet(self):
2875        """Return a :class:`~pyasn1.type.tag.TagSet` object of the currently initialized component or self (if |ASN.1| is tagged)."""
2876        if self.tagSet:
2877            return self.tagSet
2878        else:
2879            component = self.getComponent()
2880            return component.effectiveTagSet
2881
2882    @property
2883    def tagMap(self):
2884        """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping
2885            ASN.1 tags to ASN.1 objects contained within callee.
2886        """
2887        if self.tagSet:
2888            return Set.tagMap.fget(self)
2889        else:
2890            return self.componentType.tagMapUnique
2891
2892    def getComponent(self, innerFlag=False):
2893        """Return currently assigned component of the |ASN.1| object.
2894
2895        Returns
2896        -------
2897        : :py:class:`~pyasn1.type.base.PyAsn1Item`
2898            a PyASN1 object
2899        """
2900        if self._currentIdx is None:
2901            raise error.PyAsn1Error('Component not chosen')
2902        else:
2903            c = self._componentValues[self._currentIdx]
2904            if innerFlag and isinstance(c, Choice):
2905                return c.getComponent(innerFlag)
2906            else:
2907                return c
2908
2909    def getName(self, innerFlag=False):
2910        """Return the name of currently assigned component of the |ASN.1| object.
2911
2912        Returns
2913        -------
2914        : :py:class:`str`
2915            |ASN.1| component name
2916        """
2917        if self._currentIdx is None:
2918            raise error.PyAsn1Error('Component not chosen')
2919        else:
2920            if innerFlag:
2921                c = self._componentValues[self._currentIdx]
2922                if isinstance(c, Choice):
2923                    return c.getName(innerFlag)
2924            return self.componentType.getNameByPosition(self._currentIdx)
2925
2926    @property
2927    def isValue(self):
2928        """Indicate that |ASN.1| object represents ASN.1 value.
2929
2930        If *isValue* is `False` then this object represents just ASN.1 schema.
2931
2932        If *isValue* is `True` then, in addition to its ASN.1 schema features,
2933        this object can also be used like a Python built-in object (e.g. `int`,
2934        `str`, `dict` etc.).
2935
2936        Returns
2937        -------
2938        : :class:`bool`
2939            :class:`False` if object represents just ASN.1 schema.
2940            :class:`True` if object represents ASN.1 schema and can be used as a normal value.
2941
2942        Note
2943        ----
2944        There is an important distinction between PyASN1 schema and value objects.
2945        The PyASN1 schema objects can only participate in ASN.1 schema-related
2946        operations (e.g. defining or testing the structure of the data). Most
2947        obvious uses of ASN.1 schema is to guide serialisation codecs whilst
2948        encoding/decoding serialised ASN.1 contents.
2949
2950        The PyASN1 value objects can **additionally** participate in many operations
2951        involving regular Python objects (e.g. arithmetic, comprehension etc).
2952        """
2953        if self._currentIdx is None:
2954            return False
2955
2956        componentValue = self._componentValues[self._currentIdx]
2957
2958        return componentValue is not noValue and componentValue.isValue
2959
2960    def clear(self):
2961        self._currentIdx = None
2962        Set.clear(self)
2963
2964    # compatibility stubs
2965
2966    def getMinTagSet(self):
2967        return self.minTagSet
2968
2969
2970class Any(OctetString):
2971    """Create |ASN.1| schema or value object.
2972
2973    |ASN.1| objects are immutable and duck-type Python 2 :class:`str` or Python 3
2974    :class:`bytes`. When used in Unicode context, |ASN.1| type assumes "|encoding|"
2975    serialisation.
2976
2977    Keyword Args
2978    ------------
2979    value: :class:`str`, :class:`bytes` or |ASN.1| object
2980        string (Python 2) or bytes (Python 3), alternatively unicode object
2981        (Python 2) or string (Python 3) representing character string to be
2982        serialised into octets (note `encoding` parameter) or |ASN.1| object.
2983
2984    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
2985        Object representing non-default ASN.1 tag(s)
2986
2987    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
2988        Object representing non-default ASN.1 subtype constraint(s)
2989
2990    encoding: :py:class:`str`
2991        Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
2992        :class:`str` (Python 3) the payload when |ASN.1| object is used
2993        in text string context.
2994
2995    binValue: :py:class:`str`
2996        Binary string initializer to use instead of the *value*.
2997        Example: '10110011'.
2998
2999    hexValue: :py:class:`str`
3000        Hexadecimal string initializer to use instead of the *value*.
3001        Example: 'DEADBEEF'.
3002
3003    Raises
3004    ------
3005    :py:class:`~pyasn1.error.PyAsn1Error`
3006        On constraint violation or bad initializer.
3007
3008    Examples
3009    --------
3010    .. code-block:: python
3011
3012        class Error(Sequence):
3013            '''
3014            ASN.1 specification:
3015
3016            Error ::= SEQUENCE {
3017                code      INTEGER,
3018                parameter ANY DEFINED BY code  -- Either INTEGER or REAL
3019            }
3020            '''
3021            componentType=NamedTypes(
3022                NamedType('code', Integer()),
3023                NamedType('parameter', Any(),
3024                          openType=OpenType('code', {1: Integer(),
3025                                                     2: Real()}))
3026            )
3027
3028        error = Error()
3029        error['code'] = 1
3030        error['parameter'] = Integer(1234)
3031    """
3032    #: Set (on class, not on instance) or return a
3033    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
3034    #: associated with |ASN.1| type.
3035    tagSet = tag.TagSet()  # untagged
3036
3037    #: Set (on class, not on instance) or return a
3038    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
3039    #: imposing constraints on |ASN.1| type initialization values.
3040    subtypeSpec = constraint.ConstraintsIntersection()
3041
3042    # Disambiguation ASN.1 types identification
3043    typeId = OctetString.getTypeId()
3044
3045    @property
3046    def tagMap(self):
3047        """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping
3048            ASN.1 tags to ASN.1 objects contained within callee.
3049        """
3050        try:
3051            return self._tagMap
3052
3053        except AttributeError:
3054            self._tagMap = tagmap.TagMap(
3055                {self.tagSet: self},
3056                {eoo.endOfOctets.tagSet: eoo.endOfOctets},
3057                self
3058            )
3059
3060            return self._tagMap
3061
3062# XXX
3063# coercion rules?
3064