• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#
2# This file is part of pyasn1 software.
3#
4# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
5# License: http://snmplabs.com/pyasn1/license.html
6#
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).clone()
2351
2352            elif currentValue is noValue:
2353                raise error.PyAsn1Error('Component type not defined')
2354
2355        elif not isinstance(value, base.Asn1Item):
2356            if componentTypeLen:
2357                subComponentType = componentType.getTypeByPosition(idx)
2358                if isinstance(subComponentType, base.AbstractSimpleAsn1Item):
2359                    value = subComponentType.clone(value=value)
2360
2361                else:
2362                    raise error.PyAsn1Error('%s can cast only scalar values' % componentType.__class__.__name__)
2363
2364            elif currentValue is not noValue and isinstance(currentValue, base.AbstractSimpleAsn1Item):
2365                value = currentValue.clone(value=value)
2366
2367            else:
2368                raise error.PyAsn1Error('%s undefined component type' % componentType.__class__.__name__)
2369
2370        elif (matchTags or matchConstraints) and componentTypeLen:
2371            subComponentType = componentType.getTypeByPosition(idx)
2372            if subComponentType is not noValue:
2373                subtypeChecker = (self.strictConstraints and
2374                                  subComponentType.isSameTypeWith or
2375                                  subComponentType.isSuperTypeOf)
2376
2377                if not subtypeChecker(value, matchTags, matchConstraints):
2378                    if not componentType[idx].openType:
2379                        raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
2380
2381        if verifyConstraints and value.isValue:
2382            try:
2383                self.subtypeSpec(value, idx)
2384
2385            except error.PyAsn1Error:
2386                exType, exValue, exTb = sys.exc_info()
2387                raise exType('%s at %s' % (exValue, self.__class__.__name__))
2388
2389        if componentTypeLen or idx in self._dynamicNames:
2390            self._componentValues[idx] = value
2391
2392        elif len(self._componentValues) == idx:
2393            self._componentValues.append(value)
2394            self._dynamicNames.addField(idx)
2395
2396        else:
2397            raise error.PyAsn1Error('Component index out of range')
2398
2399        return self
2400
2401    @property
2402    def isValue(self):
2403        """Indicate that |ASN.1| object represents ASN.1 value.
2404
2405        If *isValue* is `False` then this object represents just ASN.1 schema.
2406
2407        If *isValue* is `True` then, in addition to its ASN.1 schema features,
2408        this object can also be used like a Python built-in object (e.g. `int`,
2409        `str`, `dict` etc.).
2410
2411        Returns
2412        -------
2413        : :class:`bool`
2414            :class:`False` if object represents just ASN.1 schema.
2415            :class:`True` if object represents ASN.1 schema and can be used as a normal value.
2416
2417        Note
2418        ----
2419        There is an important distinction between PyASN1 schema and value objects.
2420        The PyASN1 schema objects can only participate in ASN.1 schema-related
2421        operations (e.g. defining or testing the structure of the data). Most
2422        obvious uses of ASN.1 schema is to guide serialisation codecs whilst
2423        encoding/decoding serialised ASN.1 contents.
2424
2425        The PyASN1 value objects can **additionally** participate in many operations
2426        involving regular Python objects (e.g. arithmetic, comprehension etc).
2427        """
2428        componentType = self.componentType
2429
2430        if componentType:
2431            for idx, subComponentType in enumerate(componentType.namedTypes):
2432                if subComponentType.isDefaulted or subComponentType.isOptional:
2433                    continue
2434
2435                if not self._componentValues:
2436                    return False
2437
2438                componentValue = self._componentValues[idx]
2439                if componentValue is noValue or not componentValue.isValue:
2440                    return False
2441
2442        else:
2443            for componentValue in self._componentValues:
2444                if componentValue is noValue or not componentValue.isValue:
2445                    return False
2446
2447        return True
2448
2449    def prettyPrint(self, scope=0):
2450        """Return an object representation string.
2451
2452        Returns
2453        -------
2454        : :class:`str`
2455            Human-friendly object representation.
2456        """
2457        scope += 1
2458        representation = self.__class__.__name__ + ':\n'
2459        for idx, componentValue in enumerate(self._componentValues):
2460            if componentValue is not noValue:
2461                representation += ' ' * scope
2462                if self.componentType:
2463                    representation += self.componentType.getNameByPosition(idx)
2464                else:
2465                    representation += self._dynamicNames.getNameByPosition(idx)
2466                representation = '%s=%s\n' % (
2467                    representation, componentValue.prettyPrint(scope)
2468                )
2469        return representation
2470
2471    def prettyPrintType(self, scope=0):
2472        scope += 1
2473        representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__)
2474        for idx, componentType in enumerate(self.componentType.values() or self._componentValues):
2475            representation += ' ' * scope
2476            if self.componentType:
2477                representation += '"%s"' % self.componentType.getNameByPosition(idx)
2478            else:
2479                representation += '"%s"' % self._dynamicNames.getNameByPosition(idx)
2480            representation = '%s = %s\n' % (
2481                representation, componentType.prettyPrintType(scope)
2482            )
2483        return representation + '\n' + ' ' * (scope - 1) + '}'
2484
2485    # backward compatibility
2486
2487    def setDefaultComponents(self):
2488        return self
2489
2490    def getComponentType(self):
2491        if self._componentTypeLen:
2492            return self.componentType
2493
2494    def getNameByPosition(self, idx):
2495        if self._componentTypeLen:
2496            return self.componentType[idx].name
2497
2498
2499class Sequence(SequenceAndSetBase):
2500    __doc__ = SequenceAndSetBase.__doc__
2501
2502    #: Set (on class, not on instance) or return a
2503    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
2504    #: associated with |ASN.1| type.
2505    tagSet = tag.initTagSet(
2506        tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
2507    )
2508
2509    #: Set (on class, not on instance) or return a
2510    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
2511    #: imposing constraints on |ASN.1| type initialization values.
2512    subtypeSpec = constraint.ConstraintsIntersection()
2513
2514    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
2515    #: object imposing constraints on |ASN.1| objects
2516    sizeSpec = constraint.ConstraintsIntersection()
2517
2518    #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
2519    #: object imposing size constraint on |ASN.1| objects
2520    componentType = namedtype.NamedTypes()
2521
2522    # Disambiguation ASN.1 types identification
2523    typeId = SequenceAndSetBase.getTypeId()
2524
2525    # backward compatibility
2526
2527    def getComponentTagMapNearPosition(self, idx):
2528        if self.componentType:
2529            return self.componentType.getTagMapNearPosition(idx)
2530
2531    def getComponentPositionNearType(self, tagSet, idx):
2532        if self.componentType:
2533            return self.componentType.getPositionNearType(tagSet, idx)
2534        else:
2535            return idx
2536
2537
2538class Set(SequenceAndSetBase):
2539    __doc__ = SequenceAndSetBase.__doc__
2540
2541    #: Set (on class, not on instance) or return a
2542    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
2543    #: associated with |ASN.1| type.
2544    tagSet = tag.initTagSet(
2545        tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
2546    )
2547
2548    #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
2549    #: object representing ASN.1 type allowed within |ASN.1| type
2550    componentType = namedtype.NamedTypes()
2551
2552    #: Set (on class, not on instance) or return a
2553    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
2554    #: imposing constraints on |ASN.1| type initialization values.
2555    subtypeSpec = constraint.ConstraintsIntersection()
2556
2557    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
2558    #: object imposing constraints on |ASN.1| objects
2559    sizeSpec = constraint.ConstraintsIntersection()
2560
2561    # Disambiguation ASN.1 types identification
2562    typeId = SequenceAndSetBase.getTypeId()
2563
2564    def getComponent(self, innerFlag=False):
2565        return self
2566
2567    def getComponentByType(self, tagSet, default=noValue,
2568                           instantiate=True, innerFlag=False):
2569        """Returns |ASN.1| type component by ASN.1 tag.
2570
2571        Parameters
2572        ----------
2573        tagSet : :py:class:`~pyasn1.type.tag.TagSet`
2574            Object representing ASN.1 tags to identify one of
2575            |ASN.1| object component
2576
2577        Keyword Args
2578        ------------
2579        default: :class:`object`
2580            If set and requested component is a schema object, return the `default`
2581            object instead of the requested component.
2582
2583        instantiate: :class:`bool`
2584            If `True` (default), inner component will be automatically instantiated.
2585            If 'False' either existing component or the `noValue` object will be
2586            returned.
2587
2588        Returns
2589        -------
2590        : :py:class:`~pyasn1.type.base.PyAsn1Item`
2591            a pyasn1 object
2592        """
2593        componentValue = self.getComponentByPosition(
2594            self.componentType.getPositionByType(tagSet),
2595            default=default, instantiate=instantiate
2596        )
2597        if innerFlag and isinstance(componentValue, Set):
2598            # get inner component by inner tagSet
2599            return componentValue.getComponent(innerFlag=True)
2600        else:
2601            # get outer component by inner tagSet
2602            return componentValue
2603
2604    def setComponentByType(self, tagSet, value=noValue,
2605                           verifyConstraints=True,
2606                           matchTags=True,
2607                           matchConstraints=True,
2608                           innerFlag=False):
2609        """Assign |ASN.1| type component by ASN.1 tag.
2610
2611        Parameters
2612        ----------
2613        tagSet : :py:class:`~pyasn1.type.tag.TagSet`
2614            Object representing ASN.1 tags to identify one of
2615            |ASN.1| object component
2616
2617        Keyword Args
2618        ------------
2619        value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
2620            A Python value to initialize |ASN.1| component with (if *componentType* is set)
2621            or ASN.1 value object to assign to |ASN.1| component.
2622
2623        verifyConstraints : :class:`bool`
2624            If `False`, skip constraints validation
2625
2626        matchTags: :class:`bool`
2627            If `False`, skip component tags matching
2628
2629        matchConstraints: :class:`bool`
2630            If `False`, skip component constraints matching
2631
2632        innerFlag: :class:`bool`
2633            If `True`, search for matching *tagSet* recursively.
2634
2635        Returns
2636        -------
2637        self
2638        """
2639        idx = self.componentType.getPositionByType(tagSet)
2640
2641        if innerFlag:  # set inner component by inner tagSet
2642            componentType = self.componentType.getTypeByPosition(idx)
2643
2644            if componentType.tagSet:
2645                return self.setComponentByPosition(
2646                    idx, value, verifyConstraints, matchTags, matchConstraints
2647                )
2648            else:
2649                componentType = self.getComponentByPosition(idx)
2650                return componentType.setComponentByType(
2651                    tagSet, value, verifyConstraints, matchTags, matchConstraints, innerFlag=innerFlag
2652                )
2653        else:  # set outer component by inner tagSet
2654            return self.setComponentByPosition(
2655                idx, value, verifyConstraints, matchTags, matchConstraints
2656            )
2657
2658    @property
2659    def componentTagMap(self):
2660        if self.componentType:
2661            return self.componentType.tagMapUnique
2662
2663
2664class Choice(Set):
2665    """Create |ASN.1| type.
2666
2667    |ASN.1| objects are mutable and duck-type Python :class:`dict` objects.
2668
2669    Keyword Args
2670    ------------
2671    componentType: :py:class:`~pyasn1.type.namedtype.NamedType`
2672        Object holding named ASN.1 types allowed within this collection
2673
2674    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
2675        Object representing non-default ASN.1 tag(s)
2676
2677    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
2678        Object representing non-default ASN.1 subtype constraint(s)
2679
2680    sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
2681        Object representing collection size constraint
2682
2683    Examples
2684    --------
2685
2686    .. code-block:: python
2687
2688        class Afters(Choice):
2689            '''
2690            ASN.1 specification:
2691
2692            Afters ::= CHOICE {
2693                cheese  [0] IA5String,
2694                dessert [1] IA5String
2695            }
2696            '''
2697            componentType = NamedTypes(
2698                NamedType('cheese', IA5String().subtype(
2699                    implicitTag=Tag(tagClassContext, tagFormatSimple, 0)
2700                ),
2701                NamedType('dessert', IA5String().subtype(
2702                    implicitTag=Tag(tagClassContext, tagFormatSimple, 1)
2703                )
2704            )
2705
2706        afters = Afters()
2707        afters['cheese'] = 'Mascarpone'
2708    """
2709    #: Set (on class, not on instance) or return a
2710    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
2711    #: associated with |ASN.1| type.
2712    tagSet = tag.TagSet()  # untagged
2713
2714    #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
2715    #: object representing ASN.1 type allowed within |ASN.1| type
2716    componentType = namedtype.NamedTypes()
2717
2718    #: Set (on class, not on instance) or return a
2719    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
2720    #: imposing constraints on |ASN.1| type initialization values.
2721    subtypeSpec = constraint.ConstraintsIntersection()
2722
2723    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
2724    #: object imposing size constraint on |ASN.1| objects
2725    sizeSpec = constraint.ConstraintsIntersection(
2726        constraint.ValueSizeConstraint(1, 1)
2727    )
2728
2729    # Disambiguation ASN.1 types identification
2730    typeId = Set.getTypeId()
2731
2732    _currentIdx = None
2733
2734    def __eq__(self, other):
2735        if self._componentValues:
2736            return self._componentValues[self._currentIdx] == other
2737        return NotImplemented
2738
2739    def __ne__(self, other):
2740        if self._componentValues:
2741            return self._componentValues[self._currentIdx] != other
2742        return NotImplemented
2743
2744    def __lt__(self, other):
2745        if self._componentValues:
2746            return self._componentValues[self._currentIdx] < other
2747        return NotImplemented
2748
2749    def __le__(self, other):
2750        if self._componentValues:
2751            return self._componentValues[self._currentIdx] <= other
2752        return NotImplemented
2753
2754    def __gt__(self, other):
2755        if self._componentValues:
2756            return self._componentValues[self._currentIdx] > other
2757        return NotImplemented
2758
2759    def __ge__(self, other):
2760        if self._componentValues:
2761            return self._componentValues[self._currentIdx] >= other
2762        return NotImplemented
2763
2764    if sys.version_info[0] <= 2:
2765        def __nonzero__(self):
2766            return self._componentValues and True or False
2767    else:
2768        def __bool__(self):
2769            return self._componentValues and True or False
2770
2771    def __len__(self):
2772        return self._currentIdx is not None and 1 or 0
2773
2774    def __contains__(self, key):
2775        if self._currentIdx is None:
2776            return False
2777        return key == self.componentType[self._currentIdx].getName()
2778
2779    def __iter__(self):
2780        if self._currentIdx is None:
2781            raise StopIteration
2782        yield self.componentType[self._currentIdx].getName()
2783
2784    # Python dict protocol
2785
2786    def values(self):
2787        if self._currentIdx is not None:
2788            yield self._componentValues[self._currentIdx]
2789
2790    def keys(self):
2791        if self._currentIdx is not None:
2792            yield self.componentType[self._currentIdx].getName()
2793
2794    def items(self):
2795        if self._currentIdx is not None:
2796            yield self.componentType[self._currentIdx].getName(), self[self._currentIdx]
2797
2798    def verifySizeSpec(self):
2799        if self._currentIdx is None:
2800            raise error.PyAsn1Error('Component not chosen')
2801
2802    def _cloneComponentValues(self, myClone, cloneValueFlag):
2803        try:
2804            component = self.getComponent()
2805        except error.PyAsn1Error:
2806            pass
2807        else:
2808            if isinstance(component, Choice):
2809                tagSet = component.effectiveTagSet
2810            else:
2811                tagSet = component.tagSet
2812            if isinstance(component, base.AbstractConstructedAsn1Item):
2813                myClone.setComponentByType(
2814                    tagSet, component.clone(cloneValueFlag=cloneValueFlag)
2815                )
2816            else:
2817                myClone.setComponentByType(tagSet, component.clone())
2818
2819    def getComponentByPosition(self, idx, default=noValue, instantiate=True):
2820        __doc__ = Set.__doc__
2821
2822        if self._currentIdx is None or self._currentIdx != idx:
2823            return Set.getComponentByPosition(self, idx, default=default,
2824                                              instantiate=instantiate)
2825
2826        return self._componentValues[idx]
2827
2828    def setComponentByPosition(self, idx, value=noValue,
2829                               verifyConstraints=True,
2830                               matchTags=True,
2831                               matchConstraints=True):
2832        """Assign |ASN.1| type component by position.
2833
2834        Equivalent to Python sequence item assignment operation (e.g. `[]`).
2835
2836        Parameters
2837        ----------
2838        idx: :class:`int`
2839            Component index (zero-based). Must either refer to existing
2840            component or to N+1 component. In the latter case a new component
2841            type gets instantiated (if *componentType* is set, or given ASN.1
2842            object is taken otherwise) and appended to the |ASN.1| sequence.
2843
2844        Keyword Args
2845        ------------
2846        value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
2847            A Python value to initialize |ASN.1| component with (if *componentType* is set)
2848            or ASN.1 value object to assign to |ASN.1| component. Once a new value is
2849            set to *idx* component, previous value is dropped.
2850
2851        verifyConstraints : :class:`bool`
2852            If `False`, skip constraints validation
2853
2854        matchTags: :class:`bool`
2855            If `False`, skip component tags matching
2856
2857        matchConstraints: :class:`bool`
2858            If `False`, skip component constraints matching
2859
2860        Returns
2861        -------
2862        self
2863        """
2864        oldIdx = self._currentIdx
2865        Set.setComponentByPosition(self, idx, value, verifyConstraints, matchTags, matchConstraints)
2866        self._currentIdx = idx
2867        if oldIdx is not None and oldIdx != idx:
2868            self._componentValues[oldIdx] = noValue
2869        return self
2870
2871    @property
2872    def effectiveTagSet(self):
2873        """Return a :class:`~pyasn1.type.tag.TagSet` object of the currently initialized component or self (if |ASN.1| is tagged)."""
2874        if self.tagSet:
2875            return self.tagSet
2876        else:
2877            component = self.getComponent()
2878            return component.effectiveTagSet
2879
2880    @property
2881    def tagMap(self):
2882        """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping
2883            ASN.1 tags to ASN.1 objects contained within callee.
2884        """
2885        if self.tagSet:
2886            return Set.tagMap.fget(self)
2887        else:
2888            return self.componentType.tagMapUnique
2889
2890    def getComponent(self, innerFlag=False):
2891        """Return currently assigned component of the |ASN.1| object.
2892
2893        Returns
2894        -------
2895        : :py:class:`~pyasn1.type.base.PyAsn1Item`
2896            a PyASN1 object
2897        """
2898        if self._currentIdx is None:
2899            raise error.PyAsn1Error('Component not chosen')
2900        else:
2901            c = self._componentValues[self._currentIdx]
2902            if innerFlag and isinstance(c, Choice):
2903                return c.getComponent(innerFlag)
2904            else:
2905                return c
2906
2907    def getName(self, innerFlag=False):
2908        """Return the name of currently assigned component of the |ASN.1| object.
2909
2910        Returns
2911        -------
2912        : :py:class:`str`
2913            |ASN.1| component name
2914        """
2915        if self._currentIdx is None:
2916            raise error.PyAsn1Error('Component not chosen')
2917        else:
2918            if innerFlag:
2919                c = self._componentValues[self._currentIdx]
2920                if isinstance(c, Choice):
2921                    return c.getName(innerFlag)
2922            return self.componentType.getNameByPosition(self._currentIdx)
2923
2924    @property
2925    def isValue(self):
2926        """Indicate that |ASN.1| object represents ASN.1 value.
2927
2928        If *isValue* is `False` then this object represents just ASN.1 schema.
2929
2930        If *isValue* is `True` then, in addition to its ASN.1 schema features,
2931        this object can also be used like a Python built-in object (e.g. `int`,
2932        `str`, `dict` etc.).
2933
2934        Returns
2935        -------
2936        : :class:`bool`
2937            :class:`False` if object represents just ASN.1 schema.
2938            :class:`True` if object represents ASN.1 schema and can be used as a normal value.
2939
2940        Note
2941        ----
2942        There is an important distinction between PyASN1 schema and value objects.
2943        The PyASN1 schema objects can only participate in ASN.1 schema-related
2944        operations (e.g. defining or testing the structure of the data). Most
2945        obvious uses of ASN.1 schema is to guide serialisation codecs whilst
2946        encoding/decoding serialised ASN.1 contents.
2947
2948        The PyASN1 value objects can **additionally** participate in many operations
2949        involving regular Python objects (e.g. arithmetic, comprehension etc).
2950        """
2951        if self._currentIdx is None:
2952            return False
2953
2954        componentValue = self._componentValues[self._currentIdx]
2955
2956        return componentValue is not noValue and componentValue.isValue
2957
2958    def clear(self):
2959        self._currentIdx = None
2960        Set.clear(self)
2961
2962    # compatibility stubs
2963
2964    def getMinTagSet(self):
2965        return self.minTagSet
2966
2967
2968class Any(OctetString):
2969    """Create |ASN.1| schema or value object.
2970
2971    |ASN.1| objects are immutable and duck-type Python 2 :class:`str` or Python 3
2972    :class:`bytes`. When used in Unicode context, |ASN.1| type assumes "|encoding|"
2973    serialisation.
2974
2975    Keyword Args
2976    ------------
2977    value: :class:`str`, :class:`bytes` or |ASN.1| object
2978        string (Python 2) or bytes (Python 3), alternatively unicode object
2979        (Python 2) or string (Python 3) representing character string to be
2980        serialised into octets (note `encoding` parameter) or |ASN.1| object.
2981
2982    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
2983        Object representing non-default ASN.1 tag(s)
2984
2985    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
2986        Object representing non-default ASN.1 subtype constraint(s)
2987
2988    encoding: :py:class:`str`
2989        Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
2990        :class:`str` (Python 3) the payload when |ASN.1| object is used
2991        in text string context.
2992
2993    binValue: :py:class:`str`
2994        Binary string initializer to use instead of the *value*.
2995        Example: '10110011'.
2996
2997    hexValue: :py:class:`str`
2998        Hexadecimal string initializer to use instead of the *value*.
2999        Example: 'DEADBEEF'.
3000
3001    Raises
3002    ------
3003    :py:class:`~pyasn1.error.PyAsn1Error`
3004        On constraint violation or bad initializer.
3005
3006    Examples
3007    --------
3008    .. code-block:: python
3009
3010        class Error(Sequence):
3011            '''
3012            ASN.1 specification:
3013
3014            Error ::= SEQUENCE {
3015                code      INTEGER,
3016                parameter ANY DEFINED BY code  -- Either INTEGER or REAL
3017            }
3018            '''
3019            componentType=NamedTypes(
3020                NamedType('code', Integer()),
3021                NamedType('parameter', Any(),
3022                          openType=OpenType('code', {1: Integer(),
3023                                                     2: Real()}))
3024            )
3025
3026        error = Error()
3027        error['code'] = 1
3028        error['parameter'] = Integer(1234)
3029    """
3030    #: Set (on class, not on instance) or return a
3031    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
3032    #: associated with |ASN.1| type.
3033    tagSet = tag.TagSet()  # untagged
3034
3035    #: Set (on class, not on instance) or return a
3036    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
3037    #: imposing constraints on |ASN.1| type initialization values.
3038    subtypeSpec = constraint.ConstraintsIntersection()
3039
3040    # Disambiguation ASN.1 types identification
3041    typeId = OctetString.getTypeId()
3042
3043    @property
3044    def tagMap(self):
3045        """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping
3046            ASN.1 tags to ASN.1 objects contained within callee.
3047        """
3048        try:
3049            return self._tagMap
3050
3051        except AttributeError:
3052            self._tagMap = tagmap.TagMap(
3053                {self.tagSet: self},
3054                {eoo.endOfOctets.tagSet: eoo.endOfOctets},
3055                self
3056            )
3057
3058            return self._tagMap
3059
3060# XXX
3061# coercion rules?
3062