aboutsummaryrefslogtreecommitdiff
path: root/pyasn1/type/base.py
diff options
context:
space:
mode:
Diffstat (limited to 'pyasn1/type/base.py')
-rw-r--r--pyasn1/type/base.py140
1 files changed, 90 insertions, 50 deletions
diff --git a/pyasn1/type/base.py b/pyasn1/type/base.py
index 7995118..21e4041 100644
--- a/pyasn1/type/base.py
+++ b/pyasn1/type/base.py
@@ -12,7 +12,8 @@ from pyasn1.type import constraint
from pyasn1.type import tag
from pyasn1.type import tagmap
-__all__ = ['Asn1Item', 'Asn1ItemBase', 'AbstractSimpleAsn1Item', 'AbstractConstructedAsn1Item']
+__all__ = ['Asn1Item', 'Asn1Type', 'SimpleAsn1Type',
+ 'ConstructedAsn1Type']
class Asn1Item(object):
@@ -25,7 +26,17 @@ class Asn1Item(object):
return Asn1Item._typeCounter
-class Asn1ItemBase(Asn1Item):
+class Asn1Type(Asn1Item):
+ """Base class for all classes representing ASN.1 types.
+
+ In the user code, |ASN.1| class is normally used only for telling
+ ASN.1 objects from others.
+
+ Note
+ ----
+ For as long as ASN.1 is concerned, a way to compare ASN.1 types
+ is to use :meth:`isSameTypeWith` and :meth:`isSuperTypeOf` methods.
+ """
#: Set or return a :py:class:`~pyasn1.type.tag.TagSet` object representing
#: ASN.1 tag(s) associated with |ASN.1| type.
tagSet = tag.TagSet()
@@ -91,8 +102,8 @@ class Asn1ItemBase(Asn1Item):
Returns
-------
: :class:`bool`
- :class:`True` if *other* is |ASN.1| type,
- :class:`False` otherwise.
+ :obj:`True` if *other* is |ASN.1| type,
+ :obj:`False` otherwise.
"""
return (self is other or
(not matchTags or self.tagSet == other.tagSet) and
@@ -115,8 +126,8 @@ class Asn1ItemBase(Asn1Item):
Returns
-------
: :class:`bool`
- :class:`True` if *other* is a subtype of |ASN.1| type,
- :class:`False` otherwise.
+ :obj:`True` if *other* is a subtype of |ASN.1| type,
+ :obj:`False` otherwise.
"""
return (not matchTags or
(self.tagSet.isSuperTagSetOf(other.tagSet)) and
@@ -146,9 +157,13 @@ class Asn1ItemBase(Asn1Item):
def getSubtypeSpec(self):
return self.subtypeSpec
+ # backward compatibility
def hasValue(self):
return self.isValue
+# Backward compatibility
+Asn1ItemBase = Asn1Type
+
class NoValue(object):
"""Create a singleton instance of NoValue class.
@@ -221,19 +236,31 @@ class NoValue(object):
raise error.PyAsn1Error('Attempted "%s" operation on ASN.1 schema object' % attr)
def __repr__(self):
- return '<%s object at 0x%x>' % (self.__class__.__name__, id(self))
+ return '<%s object>' % self.__class__.__name__
noValue = NoValue()
-# Base class for "simple" ASN.1 objects. These are immutable.
-class AbstractSimpleAsn1Item(Asn1ItemBase):
+class SimpleAsn1Type(Asn1Type):
+ """Base class for all simple classes representing ASN.1 types.
+
+ ASN.1 distinguishes types by their ability to hold other objects.
+ Scalar types are known as *simple* in ASN.1.
+
+ In the user code, |ASN.1| class is normally used only for telling
+ ASN.1 objects from others.
+
+ Note
+ ----
+ For as long as ASN.1 is concerned, a way to compare ASN.1 types
+ is to use :meth:`isSameTypeWith` and :meth:`isSuperTypeOf` methods.
+ """
#: Default payload value
defaultValue = noValue
def __init__(self, value=noValue, **kwargs):
- Asn1ItemBase.__init__(self, **kwargs)
+ Asn1Type.__init__(self, **kwargs)
if value is noValue:
value = self.defaultValue
else:
@@ -248,19 +275,18 @@ class AbstractSimpleAsn1Item(Asn1ItemBase):
self._value = value
def __repr__(self):
- representation = '%s %s object at 0x%x' % (
- self.__class__.__name__, self.isValue and 'value' or 'schema', id(self)
- )
+ representation = '%s %s object' % (
+ self.__class__.__name__, self.isValue and 'value' or 'schema')
for attr, value in self.readOnly.items():
if value:
- representation += ' %s %s' % (attr, value)
+ representation += ', %s %s' % (attr, value)
if self.isValue:
value = self.prettyPrint()
if len(value) > 32:
value = value[:16] + '...' + value[-16:]
- representation += ' payload [%s]' % value
+ representation += ', payload [%s]' % value
return '<%s>' % representation
@@ -296,17 +322,18 @@ class AbstractSimpleAsn1Item(Asn1ItemBase):
def isValue(self):
"""Indicate that |ASN.1| object represents ASN.1 value.
- If *isValue* is `False` then this object represents just ASN.1 schema.
+ If *isValue* is :obj:`False` then this object represents just
+ ASN.1 schema.
- If *isValue* is `True` then, in addition to its ASN.1 schema features,
- this object can also be used like a Python built-in object (e.g. `int`,
- `str`, `dict` etc.).
+ If *isValue* is :obj:`True` then, in addition to its ASN.1 schema
+ features, this object can also be used like a Python built-in object
+ (e.g. :class:`int`, :class:`str`, :class:`dict` etc.).
Returns
-------
: :class:`bool`
- :class:`False` if object represents just ASN.1 schema.
- :class:`True` if object represents ASN.1 schema and can be used as a normal value.
+ :obj:`False` if object represents just ASN.1 schema.
+ :obj:`True` if object represents ASN.1 schema and can be used as a normal value.
Note
----
@@ -425,10 +452,12 @@ class AbstractSimpleAsn1Item(Asn1ItemBase):
def prettyPrint(self, scope=0):
return self.prettyOut(self._value)
- # noinspection PyUnusedLocal
def prettyPrintType(self, scope=0):
return '%s -> %s' % (self.tagSet, self.__class__.__name__)
+# Backward compatibility
+AbstractSimpleAsn1Item = SimpleAsn1Type
+
#
# Constructed types:
# * There are five of them: Sequence, SequenceOf/SetOf, Set and Choice
@@ -449,9 +478,22 @@ class AbstractSimpleAsn1Item(Asn1ItemBase):
#
-class AbstractConstructedAsn1Item(Asn1ItemBase):
+class ConstructedAsn1Type(Asn1Type):
+ """Base class for all constructed classes representing ASN.1 types.
+
+ ASN.1 distinguishes types by their ability to hold other objects.
+ Those "nesting" types are known as *constructed* in ASN.1.
- #: If `True`, requires exact component type matching,
+ In the user code, |ASN.1| class is normally used only for telling
+ ASN.1 objects from others.
+
+ Note
+ ----
+ For as long as ASN.1 is concerned, a way to compare ASN.1 types
+ is to use :meth:`isSameTypeWith` and :meth:`isSuperTypeOf` methods.
+ """
+
+ #: If :obj:`True`, requires exact component type matching,
#: otherwise subtype relation is only enforced
strictConstraints = False
@@ -465,51 +507,51 @@ class AbstractConstructedAsn1Item(Asn1ItemBase):
}
readOnly.update(kwargs)
- Asn1ItemBase.__init__(self, **readOnly)
-
- self._componentValues = []
+ Asn1Type.__init__(self, **readOnly)
def __repr__(self):
- representation = '%s %s object at 0x%x' % (
- self.__class__.__name__, self.isValue and 'value' or 'schema', id(self)
+ representation = '%s %s object' % (
+ self.__class__.__name__, self.isValue and 'value' or 'schema'
)
for attr, value in self.readOnly.items():
if value is not noValue:
- representation += ' %s=%r' % (attr, value)
+ representation += ', %s=%r' % (attr, value)
- if self.isValue and self._componentValues:
- representation += ' payload [%s]' % ', '.join([repr(x) for x in self._componentValues])
+ if self.isValue and self.components:
+ representation += ', payload [%s]' % ', '.join(
+ [repr(x) for x in self.components])
return '<%s>' % representation
def __eq__(self, other):
- return self is other and True or self._componentValues == other
+ return self is other or self.components == other
def __ne__(self, other):
- return self._componentValues != other
+ return self.components != other
def __lt__(self, other):
- return self._componentValues < other
+ return self.components < other
def __le__(self, other):
- return self._componentValues <= other
+ return self.components <= other
def __gt__(self, other):
- return self._componentValues > other
+ return self.components > other
def __ge__(self, other):
- return self._componentValues >= other
+ return self.components >= other
if sys.version_info[0] <= 2:
def __nonzero__(self):
- return self._componentValues and True or False
+ return bool(self.components)
else:
def __bool__(self):
- return self._componentValues and True or False
+ return bool(self.components)
- def __len__(self):
- return len(self._componentValues)
+ @property
+ def components(self):
+ raise error.PyAsn1Error('Method not implemented')
def _cloneComponentValues(self, myClone, cloneValueFlag):
pass
@@ -535,8 +577,7 @@ class AbstractConstructedAsn1Item(Asn1ItemBase):
Note
----
Due to the mutable nature of the |ASN.1| object, even if no arguments
- are supplied, new |ASN.1| object will always be created as a shallow
- copy of `self`.
+ are supplied, a new |ASN.1| object will be created and returned.
"""
cloneValueFlag = kwargs.pop('cloneValueFlag', False)
@@ -588,9 +629,8 @@ class AbstractConstructedAsn1Item(Asn1ItemBase):
Note
----
- Due to the immutable nature of the |ASN.1| object, if no arguments
- are supplied, no new |ASN.1| object will be created and `self` will
- be returned instead.
+ Due to the mutable nature of the |ASN.1| object, even if no arguments
+ are supplied, a new |ASN.1| object will be created and returned.
"""
initializers = self.readOnly.copy()
@@ -631,9 +671,6 @@ class AbstractConstructedAsn1Item(Asn1ItemBase):
self[k] = kwargs[k]
return self
- def clear(self):
- self._componentValues = []
-
# backward compatibility
def setDefaultComponents(self):
@@ -641,3 +678,6 @@ class AbstractConstructedAsn1Item(Asn1ItemBase):
def getComponentType(self):
return self.componentType
+
+# Backward compatibility
+AbstractConstructedAsn1Item = ConstructedAsn1Type