aboutsummaryrefslogtreecommitdiff
path: root/pyasn1/codec
diff options
context:
space:
mode:
authorIlya Etingof <etingof@gmail.com>2019-06-23 19:48:31 +0200
committerGitHub <noreply@github.com>2019-06-23 19:48:31 +0200
commit66d329acaaf204eff63ae595fd7d6f56cd530c72 (patch)
tree46187ae1df17aa9eb728abc2c55ef5ce612c6764 /pyasn1/codec
parentb028644dea4244f1cd2513ab0241c8cb9be43324 (diff)
downloadpyasn1-66d329acaaf204eff63ae595fd7d6f56cd530c72.tar.gz
SequenceOf/SetOf to remain a schema objects (#162)
* Add `omitEmptyOptionals` encoder option Added `omitEmptyOptionals` option which is respected by `Sequence` and `Set` encoders. When `omitEmptyOptionals` is set to `True`, empty initialized optional components are not encoded. Default is `False`. * Change `SequenceOf`/`SetOf` behaviour - New elements to `SequenceOf`/`SetOf` objects can now be added at any position - the requirement for the new elements to reside at the end of the existing ones (i.e. s[len(s)] = 123) is removed. - Removed default initializer from `SequenceOf`/`SetOf` types to ensure consistent behaviour with the rest of ASN.1 types. Before this change, `SequenceOf`/`SetOf` instances immediately become value objects behaving like an empty list. With this change, `SequenceOf`/`SetOf` objects remain schema objects unless a component is added or `.clear()` is called. - Added `.reset()` method to all constructed types to turn value object into a schema object.
Diffstat (limited to 'pyasn1/codec')
-rw-r--r--pyasn1/codec/ber/decoder.py4
-rw-r--r--pyasn1/codec/ber/encoder.py25
2 files changed, 24 insertions, 5 deletions
diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py
index 591bbc4..2e4afbb 100644
--- a/pyasn1/codec/ber/decoder.py
+++ b/pyasn1/codec/ber/decoder.py
@@ -567,6 +567,7 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
return asn1Object, tail
asn1Object = asn1Spec.clone()
+ asn1Object.clear()
if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId):
@@ -682,6 +683,7 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
else:
asn1Object = asn1Spec.clone()
+ asn1Object.clear()
componentType = asn1Spec.componentType
@@ -727,6 +729,7 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
)
asn1Object = asn1Spec.clone()
+ asn1Object.clear()
if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId):
@@ -847,6 +850,7 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
else:
asn1Object = asn1Spec.clone()
+ asn1Object.clear()
componentType = asn1Spec.componentType
diff --git a/pyasn1/codec/ber/encoder.py b/pyasn1/codec/ber/encoder.py
index 65b8514..325ed46 100644
--- a/pyasn1/codec/ber/encoder.py
+++ b/pyasn1/codec/ber/encoder.py
@@ -4,6 +4,8 @@
# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
+import sys
+
from pyasn1 import debug
from pyasn1 import error
from pyasn1.codec.ber import eoo
@@ -93,9 +95,15 @@ class AbstractItemEncoder(object):
# base tag?
if not idx:
- substrate, isConstructed, isOctets = self.encodeValue(
- value, asn1Spec, encodeFun, **options
- )
+ try:
+ substrate, isConstructed, isOctets = self.encodeValue(
+ value, asn1Spec, encodeFun, **options
+ )
+
+ except error.PyAsn1Error:
+ exc = sys.exc_info()
+ raise error.PyAsn1Error(
+ 'Error encoding %r: %s' % (value, exc[1]))
if LOG:
LOG('encoded %svalue %s into %s' % (
@@ -518,6 +526,13 @@ class SequenceEncoder(AbstractItemEncoder):
substrate = null
+ omitEmptyOptionals = options.get(
+ 'omitEmptyOptionals', self.omitEmptyOptionals)
+
+ if LOG:
+ LOG('%sencoding empty OPTIONAL components' % (
+ omitEmptyOptionals and 'not ' or ''))
+
if asn1Spec is None:
# instance of ASN.1 schema
value.verifySizeSpec()
@@ -538,7 +553,7 @@ class SequenceEncoder(AbstractItemEncoder):
LOG('not encoding DEFAULT component %r' % (namedType,))
continue
- if self.omitEmptyOptionals:
+ if omitEmptyOptionals:
options.update(ifNotEmpty=namedType.isOptional)
chunk = encodeFun(component, asn1Spec, **options)
@@ -575,7 +590,7 @@ class SequenceEncoder(AbstractItemEncoder):
LOG('not encoding DEFAULT component %r' % (namedType,))
continue
- if self.omitEmptyOptionals:
+ if omitEmptyOptionals:
options.update(ifNotEmpty=namedType.isOptional)
chunk = encodeFun(component, asn1Spec[idx], **options)