ready to be encoded. If that kind of action is performed on unready
object, then :py:exc:`pyderasn.ObjNotReady` exception will be raised.
-All objects have ``copy()`` method, that returns their copy, that can be
+All objects are friendly to ``copy.copy()`` and copied objects can be
safely mutated.
+Also all objects can be safely ``pickle``-d, but pay attention that
+pickling among different PyDERASN versions is prohibited.
+
.. _decoding:
Decoding
def colored(what, *args, **kwargs):
return what
-__version__ = "5.6"
+__version__ = "6.0"
__all__ = (
"Any",
"""
return (self.llen + self.vlen) > 0
- def copy(self): # pragma: no cover
- """Make a copy of object, safe to be mutated
+ def __getstate__(self): # pragma: no cover
+ """Used for making safe to be mutable pickleable copies
"""
raise NotImplementedError()
+ def __setstate__(self, state):
+ if state.version != __version__:
+ raise ValueError("data is pickled by different PyDERASN version")
+ self.tag = self.tag_default
+ self._value = None
+ self._expl = None
+ self.default = None
+ self.optional = False
+ self.offset = 0
+ self.llen = 0
+ self.vlen = 0
+ self.expl_lenindef = False
+ self.lenindef = False
+ self.ber_encoded = False
+
@property
def tlen(self):
"""See :ref:`decoding`
:param tag_only: decode only the tag, without length and contents
(used only in Choice and Set structures, trying to
determine if tag satisfies the scheme)
- :param _ctx_immutable: do we need to copy ``ctx`` before using it
+ :param _ctx_immutable: do we need to ``copy.copy()`` ``ctx``
+ before using it?
:returns: (Obj, remaining data)
.. seealso:: :ref:`decoding`
# ASN.1 primitive types
########################################################################
+BooleanState = namedtuple("BooleanState", (
+ "version",
+ "value",
+ "tag",
+ "expl",
+ "default",
+ "optional",
+ "offset",
+ "llen",
+ "vlen",
+ "expl_lenindef",
+ "lenindef",
+ "ber_encoded",
+))
+
+
class Boolean(Obj):
"""``BOOLEAN`` boolean type
def ready(self):
return self._value is not None
- def copy(self):
- obj = self.__class__()
- obj._value = self._value
- obj.tag = self.tag
- obj._expl = self._expl
- obj.default = self.default
- obj.optional = self.optional
- obj.offset = self.offset
- obj.llen = self.llen
- obj.vlen = self.vlen
- obj.expl_lenindef = self.expl_lenindef
- obj.lenindef = self.lenindef
- obj.ber_encoded = self.ber_encoded
- return obj
+ def __getstate__(self):
+ return BooleanState(
+ __version__,
+ self._value,
+ self.tag,
+ self._expl,
+ self.default,
+ self.optional,
+ self.offset,
+ self.llen,
+ self.vlen,
+ self.expl_lenindef,
+ self.lenindef,
+ self.ber_encoded,
+ )
+
+ def __setstate__(self, state):
+ super(Boolean, self).__setstate__(state)
+ self._value = state.value
+ self.tag = state.tag
+ self._expl = state.expl
+ self.default = state.default
+ self.optional = state.optional
+ self.offset = state.offset
+ self.llen = state.llen
+ self.vlen = state.vlen
+ self.expl_lenindef = state.expl_lenindef
+ self.lenindef = state.lenindef
+ self.ber_encoded = state.ber_encoded
def __nonzero__(self):
self._assert_ready()
yield pp
+IntegerState = namedtuple("IntegerState", (
+ "version",
+ "specs",
+ "value",
+ "bound_min",
+ "bound_max",
+ "tag",
+ "expl",
+ "default",
+ "optional",
+ "offset",
+ "llen",
+ "vlen",
+ "expl_lenindef",
+ "lenindef",
+ "ber_encoded",
+))
+
+
class Integer(Obj):
"""``INTEGER`` integer type
def ready(self):
return self._value is not None
- def copy(self):
- obj = self.__class__(_specs=self.specs)
- obj._value = self._value
- obj._bound_min = self._bound_min
- obj._bound_max = self._bound_max
- obj.tag = self.tag
- obj._expl = self._expl
- obj.default = self.default
- obj.optional = self.optional
- obj.offset = self.offset
- obj.llen = self.llen
- obj.vlen = self.vlen
- obj.expl_lenindef = self.expl_lenindef
- obj.lenindef = self.lenindef
- obj.ber_encoded = self.ber_encoded
- return obj
+ def __getstate__(self):
+ return IntegerState(
+ __version__,
+ self.specs,
+ self._value,
+ self._bound_min,
+ self._bound_max,
+ self.tag,
+ self._expl,
+ self.default,
+ self.optional,
+ self.offset,
+ self.llen,
+ self.vlen,
+ self.expl_lenindef,
+ self.lenindef,
+ self.ber_encoded,
+ )
+
+ def __setstate__(self, state):
+ super(Integer, self).__setstate__(state)
+ self.specs = state.specs
+ self._value = state.value
+ self._bound_min = state.bound_min
+ self._bound_max = state.bound_max
+ self.tag = state.tag
+ self._expl = state.expl
+ self.default = state.default
+ self.optional = state.optional
+ self.offset = state.offset
+ self.llen = state.llen
+ self.vlen = state.vlen
+ self.expl_lenindef = state.expl_lenindef
+ self.lenindef = state.lenindef
+ self.ber_encoded = state.ber_encoded
def __int__(self):
self._assert_ready()
SET01 = frozenset(("0", "1"))
+BitStringState = namedtuple("BitStringState", (
+ "version",
+ "specs",
+ "value",
+ "tag",
+ "expl",
+ "default",
+ "optional",
+ "offset",
+ "llen",
+ "vlen",
+ "expl_lenindef",
+ "lenindef",
+ "ber_encoded",
+ "tag_constructed",
+ "defined",
+))
class BitString(Obj):
def ready(self):
return self._value is not None
- def copy(self):
- obj = self.__class__(_specs=self.specs)
- value = self._value
- if value is not None:
- value = (value[0], value[1])
- obj._value = value
- obj.tag = self.tag
- obj._expl = self._expl
- obj.default = self.default
- obj.optional = self.optional
- obj.offset = self.offset
- obj.llen = self.llen
- obj.vlen = self.vlen
- obj.expl_lenindef = self.expl_lenindef
- obj.lenindef = self.lenindef
- obj.ber_encoded = self.ber_encoded
- return obj
+ def __getstate__(self):
+ return BitStringState(
+ __version__,
+ self.specs,
+ self._value,
+ self.tag,
+ self._expl,
+ self.default,
+ self.optional,
+ self.offset,
+ self.llen,
+ self.vlen,
+ self.expl_lenindef,
+ self.lenindef,
+ self.ber_encoded,
+ self.tag_constructed,
+ self.defined,
+ )
+
+ def __setstate__(self, state):
+ super(BitString, self).__setstate__(state)
+ self.specs = state.specs
+ self._value = state.value
+ self.tag = state.tag
+ self._expl = state.expl
+ self.default = state.default
+ self.optional = state.optional
+ self.offset = state.offset
+ self.llen = state.llen
+ self.vlen = state.vlen
+ self.expl_lenindef = state.expl_lenindef
+ self.lenindef = state.lenindef
+ self.ber_encoded = state.ber_encoded
+ self.tag_constructed = state.tag_constructed
+ self.defined = state.defined
def __iter__(self):
self._assert_ready()
yield pp
+OctetStringState = namedtuple("OctetStringState", (
+ "version",
+ "value",
+ "bound_min",
+ "bound_max",
+ "tag",
+ "expl",
+ "default",
+ "optional",
+ "offset",
+ "llen",
+ "vlen",
+ "expl_lenindef",
+ "lenindef",
+ "ber_encoded",
+ "tag_constructed",
+ "defined",
+))
+
+
class OctetString(Obj):
"""``OCTET STRING`` binary string type
def ready(self):
return self._value is not None
- def copy(self):
- obj = self.__class__()
- obj._value = self._value
- obj._bound_min = self._bound_min
- obj._bound_max = self._bound_max
- obj.tag = self.tag
- obj._expl = self._expl
- obj.default = self.default
- obj.optional = self.optional
- obj.offset = self.offset
- obj.llen = self.llen
- obj.vlen = self.vlen
- obj.expl_lenindef = self.expl_lenindef
- obj.lenindef = self.lenindef
- obj.ber_encoded = self.ber_encoded
- return obj
+ def __getstate__(self):
+ return OctetStringState(
+ __version__,
+ self._value,
+ self._bound_min,
+ self._bound_max,
+ self.tag,
+ self._expl,
+ self.default,
+ self.optional,
+ self.offset,
+ self.llen,
+ self.vlen,
+ self.expl_lenindef,
+ self.lenindef,
+ self.ber_encoded,
+ self.tag_constructed,
+ self.defined,
+ )
+
+ def __setstate__(self, state):
+ super(OctetString, self).__setstate__(state)
+ self._value = state.value
+ self._bound_min = state.bound_min
+ self._bound_max = state.bound_max
+ self.tag = state.tag
+ self._expl = state.expl
+ self.default = state.default
+ self.optional = state.optional
+ self.offset = state.offset
+ self.llen = state.llen
+ self.vlen = state.vlen
+ self.expl_lenindef = state.expl_lenindef
+ self.lenindef = state.lenindef
+ self.ber_encoded = state.ber_encoded
+ self.tag_constructed = state.tag_constructed
+ self.defined = state.defined
def __bytes__(self):
self._assert_ready()
yield pp
+NullState = namedtuple("NullState", (
+ "version",
+ "tag",
+ "expl",
+ "default",
+ "optional",
+ "offset",
+ "llen",
+ "vlen",
+ "expl_lenindef",
+ "lenindef",
+ "ber_encoded",
+))
+
+
class Null(Obj):
"""``NULL`` null object
def ready(self):
return True
- def copy(self):
- obj = self.__class__()
- obj.tag = self.tag
- obj._expl = self._expl
- obj.default = self.default
- obj.optional = self.optional
- obj.offset = self.offset
- obj.llen = self.llen
- obj.vlen = self.vlen
- obj.expl_lenindef = self.expl_lenindef
- obj.lenindef = self.lenindef
- obj.ber_encoded = self.ber_encoded
- return obj
+ def __getstate__(self):
+ return NullState(
+ __version__,
+ self.tag,
+ self._expl,
+ self.default,
+ self.optional,
+ self.offset,
+ self.llen,
+ self.vlen,
+ self.expl_lenindef,
+ self.lenindef,
+ self.ber_encoded,
+ )
+
+ def __setstate__(self, state):
+ super(Null, self).__setstate__(state)
+ self.tag = state.tag
+ self._expl = state.expl
+ self.default = state.default
+ self.optional = state.optional
+ self.offset = state.offset
+ self.llen = state.llen
+ self.vlen = state.vlen
+ self.expl_lenindef = state.expl_lenindef
+ self.lenindef = state.lenindef
+ self.ber_encoded = state.ber_encoded
def __eq__(self, their):
if not issubclass(their.__class__, Null):
yield pp
+ObjectIdentifierState = namedtuple("ObjectIdentifierState", (
+ "version",
+ "value",
+ "tag",
+ "expl",
+ "default",
+ "optional",
+ "offset",
+ "llen",
+ "vlen",
+ "expl_lenindef",
+ "lenindef",
+ "ber_encoded",
+ "defines",
+))
+
+
class ObjectIdentifier(Obj):
"""``OBJECT IDENTIFIER`` OID type
def ready(self):
return self._value is not None
- def copy(self):
- obj = self.__class__()
- obj._value = self._value
- obj.defines = self.defines
- obj.tag = self.tag
- obj._expl = self._expl
- obj.default = self.default
- obj.optional = self.optional
- obj.offset = self.offset
- obj.llen = self.llen
- obj.vlen = self.vlen
- obj.expl_lenindef = self.expl_lenindef
- obj.lenindef = self.lenindef
- obj.ber_encoded = self.ber_encoded
- return obj
+ def __getstate__(self):
+ return ObjectIdentifierState(
+ __version__,
+ self._value,
+ self.tag,
+ self._expl,
+ self.default,
+ self.optional,
+ self.offset,
+ self.llen,
+ self.vlen,
+ self.expl_lenindef,
+ self.lenindef,
+ self.ber_encoded,
+ self.defines,
+ )
+
+ def __setstate__(self, state):
+ super(ObjectIdentifier, self).__setstate__(state)
+ self._value = state.value
+ self.tag = state.tag
+ self._expl = state.expl
+ self.default = state.default
+ self.optional = state.optional
+ self.offset = state.offset
+ self.llen = state.llen
+ self.vlen = state.vlen
+ self.expl_lenindef = state.expl_lenindef
+ self.lenindef = state.lenindef
+ self.ber_encoded = state.ber_encoded
+ self.defines = state.defines
def __iter__(self):
self._assert_ready()
raise InvalidValueType((self.__class__, int, str))
return value
- def copy(self):
- obj = self.__class__(_specs=self.specs)
- obj._value = self._value
- obj._bound_min = self._bound_min
- obj._bound_max = self._bound_max
- obj.tag = self.tag
- obj._expl = self._expl
- obj.default = self.default
- obj.optional = self.optional
- obj.offset = self.offset
- obj.llen = self.llen
- obj.vlen = self.vlen
- obj.expl_lenindef = self.expl_lenindef
- obj.lenindef = self.lenindef
- obj.ber_encoded = self.ber_encoded
- return obj
-
def __call__(
self,
value=None,
return value
+PrintableStringState = namedtuple(
+ "PrintableStringState",
+ OctetStringState._fields + ("allowable_chars",),
+)
+
+
class PrintableString(AllowableCharsMixin, CommonString):
"""Printable string
raise DecodeError("non-printable value")
return value
- def copy(self):
- obj = super(PrintableString, self).copy()
- obj._allowable_chars = self._allowable_chars
- return obj
+ def __getstate__(self):
+ return PrintableStringState(
+ *super(PrintableString, self).__getstate__(),
+ **{"allowable_chars": self._allowable_chars}
+ )
+
+ def __setstate__(self, state):
+ super(PrintableString, self).__setstate__(state)
+ self._allowable_chars = state.allowable_chars
def __call__(
self,
asn1_type_name = "BMPString"
+ChoiceState = namedtuple("ChoiceState", (
+ "version",
+ "specs",
+ "value",
+ "tag",
+ "expl",
+ "default",
+ "optional",
+ "offset",
+ "llen",
+ "vlen",
+ "expl_lenindef",
+ "lenindef",
+ "ber_encoded",
+))
+
+
class Choice(Obj):
"""``CHOICE`` special type
default_obj._value = default_value
self.default = default_obj
if value is None:
- self._value = default_obj.copy()._value
+ self._value = copy(default_obj._value)
def _value_sanitize(self, value):
if isinstance(value, tuple) and len(value) == 2:
self._value[1].bered
)
- def copy(self):
- obj = self.__class__(schema=self.specs)
- obj._expl = self._expl
- obj.default = self.default
- obj.optional = self.optional
- obj.offset = self.offset
- obj.llen = self.llen
- obj.vlen = self.vlen
- obj.expl_lenindef = self.expl_lenindef
- obj.lenindef = self.lenindef
- obj.ber_encoded = self.ber_encoded
- value = self._value
- if value is not None:
- obj._value = (value[0], value[1].copy())
- return obj
+ def __getstate__(self):
+ return ChoiceState(
+ __version__,
+ self.specs,
+ copy(self._value),
+ self.tag,
+ self._expl,
+ self.default,
+ self.optional,
+ self.offset,
+ self.llen,
+ self.vlen,
+ self.expl_lenindef,
+ self.lenindef,
+ self.ber_encoded,
+ )
+
+ def __setstate__(self, state):
+ super(Choice, self).__setstate__(state)
+ self.specs = state.specs
+ self._value = state.value
+ self._expl = state.expl
+ self.default = state.default
+ self.optional = state.optional
+ self.offset = state.offset
+ self.llen = state.llen
+ self.vlen = state.vlen
+ self.expl_lenindef = state.expl_lenindef
+ self.lenindef = state.lenindef
+ self.ber_encoded = state.ber_encoded
def __eq__(self, their):
if isinstance(their, tuple) and len(their) == 2:
))
+AnyState = namedtuple("AnyState", (
+ "version",
+ "value",
+ "tag",
+ "expl",
+ "optional",
+ "offset",
+ "llen",
+ "vlen",
+ "expl_lenindef",
+ "lenindef",
+ "ber_encoded",
+ "defined",
+))
+
+
class Any(Obj):
"""``ANY`` special type
return False
return self.defined[1].bered
- def copy(self):
- obj = self.__class__()
- obj._value = self._value
- obj.tag = self.tag
- obj._expl = self._expl
- obj.optional = self.optional
- obj.offset = self.offset
- obj.llen = self.llen
- obj.vlen = self.vlen
- obj.expl_lenindef = self.expl_lenindef
- obj.lenindef = self.lenindef
- obj.ber_encoded = self.ber_encoded
- return obj
+ def __getstate__(self):
+ return AnyState(
+ __version__,
+ self._value,
+ self.tag,
+ self._expl,
+ self.optional,
+ self.offset,
+ self.llen,
+ self.vlen,
+ self.expl_lenindef,
+ self.lenindef,
+ self.ber_encoded,
+ self.defined,
+ )
+
+ def __setstate__(self, state):
+ super(Any, self).__setstate__(state)
+ self._value = state.value
+ self.tag = state.tag
+ self._expl = state.expl
+ self.optional = state.optional
+ self.offset = state.offset
+ self.llen = state.llen
+ self.vlen = state.vlen
+ self.expl_lenindef = state.expl_lenindef
+ self.lenindef = state.lenindef
+ self.ber_encoded = state.ber_encoded
+ self.defined = state.defined
def __eq__(self, their):
if isinstance(their, binary_type):
return decode_path + rel_path
+SequenceState = namedtuple("SequenceState", (
+ "version",
+ "specs",
+ "value",
+ "tag",
+ "expl",
+ "default",
+ "optional",
+ "offset",
+ "llen",
+ "vlen",
+ "expl_lenindef",
+ "lenindef",
+ "ber_encoded",
+))
+
+
class Sequence(Obj):
"""``SEQUENCE`` structure type
default_obj._value = default_value
self.default = default_obj
if value is None:
- self._value = default_obj.copy()._value
+ self._value = copy(default_obj._value)
@property
def ready(self):
return True
return any(value.bered for value in itervalues(self._value))
- def copy(self):
- obj = self.__class__(schema=self.specs)
- obj.tag = self.tag
- obj._expl = self._expl
- obj.default = self.default
- obj.optional = self.optional
- obj.offset = self.offset
- obj.llen = self.llen
- obj.vlen = self.vlen
- obj.expl_lenindef = self.expl_lenindef
- obj.lenindef = self.lenindef
- obj.ber_encoded = self.ber_encoded
- obj._value = {k: v.copy() for k, v in iteritems(self._value)}
- return obj
+ def __getstate__(self):
+ return SequenceState(
+ __version__,
+ self.specs,
+ {k: copy(v) for k, v in iteritems(self._value)},
+ self.tag,
+ self._expl,
+ self.default,
+ self.optional,
+ self.offset,
+ self.llen,
+ self.vlen,
+ self.expl_lenindef,
+ self.lenindef,
+ self.ber_encoded,
+ )
+
+ def __setstate__(self, state):
+ super(Sequence, self).__setstate__(state)
+ self.specs = state.specs
+ self._value = state.value
+ self.tag = state.tag
+ self._expl = state.expl
+ self.default = state.default
+ self.optional = state.optional
+ self.offset = state.offset
+ self.llen = state.llen
+ self.vlen = state.vlen
+ self.expl_lenindef = state.expl_lenindef
+ self.lenindef = state.lenindef
+ self.ber_encoded = state.ber_encoded
def __eq__(self, their):
if not isinstance(their, self.__class__):
return obj, tail
+SequenceOfState = namedtuple("SequenceOfState", (
+ "version",
+ "spec",
+ "value",
+ "bound_min",
+ "bound_max",
+ "tag",
+ "expl",
+ "default",
+ "optional",
+ "offset",
+ "llen",
+ "vlen",
+ "expl_lenindef",
+ "lenindef",
+ "ber_encoded",
+))
+
+
class SequenceOf(Obj):
"""``SEQUENCE OF`` sequence type
default_obj._value = default_value
self.default = default_obj
if value is None:
- self._value = default_obj.copy()._value
+ self._value = copy(default_obj._value)
def _value_sanitize(self, value):
if issubclass(value.__class__, SequenceOf):
return True
return any(v.bered for v in self._value)
- def copy(self):
- obj = self.__class__(schema=self.spec)
- obj._bound_min = self._bound_min
- obj._bound_max = self._bound_max
- obj.tag = self.tag
- obj._expl = self._expl
- obj.default = self.default
- obj.optional = self.optional
- obj.offset = self.offset
- obj.llen = self.llen
- obj.vlen = self.vlen
- obj.expl_lenindef = self.expl_lenindef
- obj.lenindef = self.lenindef
- obj.ber_encoded = self.ber_encoded
- obj._value = [v.copy() for v in self._value]
- return obj
+ def __getstate__(self):
+ return SequenceOfState(
+ __version__,
+ self.spec,
+ [copy(v) for v in self._value],
+ self._bound_min,
+ self._bound_max,
+ self.tag,
+ self._expl,
+ self.default,
+ self.optional,
+ self.offset,
+ self.llen,
+ self.vlen,
+ self.expl_lenindef,
+ self.lenindef,
+ self.ber_encoded,
+ )
+
+ def __setstate__(self, state):
+ super(SequenceOf, self).__setstate__(state)
+ self.spec = state.spec
+ self._value = state.value
+ self._bound_min = state.bound_min
+ self._bound_max = state.bound_max
+ self.tag = state.tag
+ self._expl = state.expl
+ self.default = state.default
+ self.optional = state.optional
+ self.offset = state.offset
+ self.llen = state.llen
+ self.vlen = state.vlen
+ self.expl_lenindef = state.expl_lenindef
+ self.lenindef = state.lenindef
+ self.ber_encoded = state.ber_encoded
def __eq__(self, their):
if isinstance(their, self.__class__):