summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Etingof <etingof@gmail.com>2019-08-19 21:26:51 +0200
committerIlya Etingof <etingof@gmail.com>2019-08-24 21:37:51 +0200
commit41597f2e7f1820ab4e1c5b085da1f5e168df24bc (patch)
treee552f03ee7846566b4b036c192d9ed326a9e74a5
parentec580e545ef25f117573014d40ca5c512e58dbf3 (diff)
downloadpyasn1-git-add-consistency-check-hook.tar.gz
Add `isInconsistent` property hook to all constructed typesadd-consistency-check-hook
Added `isInconsistent` property to all constructed types. This property conceptually replaces `verifySizeSpec` method to serve a more general purpose e.g. ensuring all required fields are in a good shape. By default this check invokes subtype constraints verification and is run by codecs on value de/serialisation.
-rw-r--r--CHANGES.rst6
-rw-r--r--docs/source/pyasn1/type/base/constructedasn1type.rst2
-rw-r--r--docs/source/pyasn1/type/univ/choice.rst2
-rw-r--r--docs/source/pyasn1/type/univ/sequence.rst2
-rw-r--r--docs/source/pyasn1/type/univ/sequenceof.rst2
-rw-r--r--docs/source/pyasn1/type/univ/set.rst2
-rw-r--r--docs/source/pyasn1/type/univ/setof.rst2
-rw-r--r--pyasn1/codec/ber/decoder.py8
-rw-r--r--pyasn1/codec/ber/encoder.py8
-rw-r--r--pyasn1/codec/cer/encoder.py4
-rw-r--r--pyasn1/codec/native/encoder.py8
-rw-r--r--pyasn1/type/base.py23
-rw-r--r--pyasn1/type/univ.py2
-rw-r--r--tests/type/test_univ.py14
14 files changed, 57 insertions, 28 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 0d9c545..0dcb2f2 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -2,7 +2,11 @@
Revision 0.4.7, released XX-09-2019
-----------------------------------
-No changes yet
+- Added `isInconsistent` property to all constructed types. This property
+ conceptually replaces `verifySizeSpec` method to serve a more general
+ purpose e.g. ensuring all required fields are in a good shape. By default
+ this check invokes subtype constraints verification and is run by codecs
+ on value de/serialisation.
Revision 0.4.6, released 31-07-2019
-----------------------------------
diff --git a/docs/source/pyasn1/type/base/constructedasn1type.rst b/docs/source/pyasn1/type/base/constructedasn1type.rst
index 54d828f..169552f 100644
--- a/docs/source/pyasn1/type/base/constructedasn1type.rst
+++ b/docs/source/pyasn1/type/base/constructedasn1type.rst
@@ -7,4 +7,4 @@
------------
.. autoclass:: pyasn1.type.base.ConstructedAsn1Type(tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), sizeSpec=ConstraintsIntersection(), componentType=None)
- :members: isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec
+ :members: isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec, isInconsistent
diff --git a/docs/source/pyasn1/type/univ/choice.rst b/docs/source/pyasn1/type/univ/choice.rst
index 9731971..9e2b4dc 100644
--- a/docs/source/pyasn1/type/univ/choice.rst
+++ b/docs/source/pyasn1/type/univ/choice.rst
@@ -9,7 +9,7 @@
.. autoclass:: pyasn1.type.univ.Choice(componentType=None, tagSet=tagSet(), subtypeSpec=ConstraintsIntersection(), sizeSpec=ConstraintsIntersection())
:members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, componentType, subtypeSpec, sizeSpec,
getComponentByPosition, setComponentByPosition, getComponentByName, setComponentByName, setDefaultComponents,
- getComponentByType, setComponentByType, getName, getComponent
+ getComponentByType, setComponentByType, getName, getComponent, isInconsistent
.. note::
diff --git a/docs/source/pyasn1/type/univ/sequence.rst b/docs/source/pyasn1/type/univ/sequence.rst
index 0988004..94804c7 100644
--- a/docs/source/pyasn1/type/univ/sequence.rst
+++ b/docs/source/pyasn1/type/univ/sequence.rst
@@ -9,7 +9,7 @@
.. autoclass:: pyasn1.type.univ.Sequence(componentType=NamedTypes(), tagSet=tagSet(), subtypeSpec=ConstraintsIntersection(), sizeSpec=ConstraintsIntersection())
:members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, componentType, subtypeSpec, sizeSpec, getComponentByPosition,
setComponentByPosition, getComponentByName, setComponentByName, setDefaultComponents,
- clear, reset
+ clear, reset, isInconsistent
.. note::
diff --git a/docs/source/pyasn1/type/univ/sequenceof.rst b/docs/source/pyasn1/type/univ/sequenceof.rst
index 6a09b92..be5442e 100644
--- a/docs/source/pyasn1/type/univ/sequenceof.rst
+++ b/docs/source/pyasn1/type/univ/sequenceof.rst
@@ -8,7 +8,7 @@
.. autoclass:: pyasn1.type.univ.SequenceOf(componentType=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), sizeSpec=ConstraintsIntersection())
:members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, componentType, subtypeSpec, sizeSpec,
- getComponentByPosition, setComponentByPosition, clear, reset
+ getComponentByPosition, setComponentByPosition, clear, reset, isInconsistent
.. note::
diff --git a/docs/source/pyasn1/type/univ/set.rst b/docs/source/pyasn1/type/univ/set.rst
index 792d2e9..aad8ee0 100644
--- a/docs/source/pyasn1/type/univ/set.rst
+++ b/docs/source/pyasn1/type/univ/set.rst
@@ -9,7 +9,7 @@
.. autoclass:: pyasn1.type.univ.Set(componentType=NamedTypes(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), sizeSpec=ConstraintsIntersection())
:members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, componentType, subtypeSpec, sizeSpec,
getComponentByPosition, setComponentByPosition, getComponentByName, setComponentByName, setDefaultComponents,
- getComponentByType, setComponentByType, clear, reset
+ getComponentByType, setComponentByType, clear, reset, isInconsistent
.. note::
diff --git a/docs/source/pyasn1/type/univ/setof.rst b/docs/source/pyasn1/type/univ/setof.rst
index 67ef92f..ce519a9 100644
--- a/docs/source/pyasn1/type/univ/setof.rst
+++ b/docs/source/pyasn1/type/univ/setof.rst
@@ -8,7 +8,7 @@
.. autoclass:: pyasn1.type.univ.SetOf(componentType=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), sizeSpec=ConstraintsIntersection())
:members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, componentType, subtypeSpec, sizeSpec,
-  getComponentByPosition, setComponentByPosition, clear, reset
+  getComponentByPosition, setComponentByPosition, clear, reset, isInconsistent
.. note::
diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py
index 3f2d180..5759ab8 100644
--- a/pyasn1/codec/ber/decoder.py
+++ b/pyasn1/codec/ber/decoder.py
@@ -695,7 +695,9 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
asn1Object.setComponentByPosition(idx, component)
else:
- asn1Object.verifySizeSpec()
+ inconsistency = asn1Object.isInconsistent
+ if inconsistency:
+ raise inconsistency
else:
asn1Object = asn1Spec.clone()
@@ -879,7 +881,9 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
asn1Object.setComponentByPosition(idx, component)
else:
- asn1Object.verifySizeSpec()
+ inconsistency = asn1Object.isInconsistent
+ if inconsistency:
+ raise inconsistency
else:
asn1Object = asn1Spec.clone()
diff --git a/pyasn1/codec/ber/encoder.py b/pyasn1/codec/ber/encoder.py
index a5d5fd3..778aa86 100644
--- a/pyasn1/codec/ber/encoder.py
+++ b/pyasn1/codec/ber/encoder.py
@@ -537,7 +537,9 @@ class SequenceEncoder(AbstractItemEncoder):
if asn1Spec is None:
# instance of ASN.1 schema
- value.verifySizeSpec()
+ inconsistency = value.isInconsistent
+ if inconsistency:
+ raise inconsistency
namedTypes = value.componentType
@@ -643,7 +645,9 @@ class SequenceOfEncoder(AbstractItemEncoder):
def _encodeComponents(self, value, asn1Spec, encodeFun, **options):
if asn1Spec is None:
- value.verifySizeSpec()
+ inconsistency = value.isInconsistent
+ if inconsistency:
+ raise inconsistency
else:
asn1Spec = asn1Spec.componentType
diff --git a/pyasn1/codec/cer/encoder.py b/pyasn1/codec/cer/encoder.py
index 6a9db97..935b696 100644
--- a/pyasn1/codec/cer/encoder.py
+++ b/pyasn1/codec/cer/encoder.py
@@ -169,7 +169,9 @@ class SetEncoder(encoder.SequenceEncoder):
if asn1Spec is None:
# instance of ASN.1 schema
- value.verifySizeSpec()
+ inconsistency = value.isInconsistent
+ if inconsistency:
+ raise inconsistency
namedTypes = value.componentType
diff --git a/pyasn1/codec/native/encoder.py b/pyasn1/codec/native/encoder.py
index 4c5908d..4318abd 100644
--- a/pyasn1/codec/native/encoder.py
+++ b/pyasn1/codec/native/encoder.py
@@ -72,7 +72,9 @@ class SetEncoder(AbstractItemEncoder):
protoDict = dict
def encode(self, value, encodeFun, **options):
- value.verifySizeSpec()
+ inconsistency = value.isInconsistent
+ if inconsistency:
+ raise inconsistency
namedTypes = value.componentType
substrate = self.protoDict()
@@ -90,7 +92,9 @@ class SequenceEncoder(SetEncoder):
class SequenceOfEncoder(AbstractItemEncoder):
def encode(self, value, encodeFun, **options):
- value.verifySizeSpec()
+ inconsistency = value.isInconsistent
+ if inconsistency:
+ raise inconsistency
return [encodeFun(x, **options) for x in value]
diff --git a/pyasn1/type/base.py b/pyasn1/type/base.py
index 21e4041..1fd69f9 100644
--- a/pyasn1/type/base.py
+++ b/pyasn1/type/base.py
@@ -655,8 +655,23 @@ class ConstructedAsn1Type(Asn1Type):
return clone
- def verifySizeSpec(self):
- self.sizeSpec(self)
+ @property
+ def isInconsistent(self):
+ """Run necessary checks to ensure object consistency.
+
+ Default action is to verify |ASN.1| object against constraints imposed
+ by `subtypeSpec`.
+
+ Raises
+ ------
+ :py:class:`~pyasn1.error.PyAsn1tError` on any inconsistencies found
+ """
+ try:
+ self.sizeSpec(self)
+
+ except error.PyAsn1Error:
+ exc = sys.exc_info()[1]
+ return exc
def getComponentByPosition(self, idx):
raise error.PyAsn1Error('Method not implemented')
@@ -679,5 +694,9 @@ class ConstructedAsn1Type(Asn1Type):
def getComponentType(self):
return self.componentType
+ def verifySizeSpec(self):
+ self.sizeSpec(self)
+
+
# Backward compatibility
AbstractConstructedAsn1Item = ConstructedAsn1Type
diff --git a/pyasn1/type/univ.py b/pyasn1/type/univ.py
index b39c533..4f305f6 100644
--- a/pyasn1/type/univ.py
+++ b/pyasn1/type/univ.py
@@ -3004,7 +3004,7 @@ class Choice(Set):
if self._currentIdx is not None:
yield self.componentType[self._currentIdx].getName(), self[self._currentIdx]
- def verifySizeSpec(self):
+ def checkConsistency(self):
if self._currentIdx is None:
raise error.PyAsn1Error('Component not chosen')
diff --git a/tests/type/test_univ.py b/tests/type/test_univ.py
index 0092588..4cbfa01 100644
--- a/tests/type/test_univ.py
+++ b/tests/type/test_univ.py
@@ -1040,22 +1040,14 @@ class SequenceOf(BaseTestCase):
else:
pass
- def testSizeSpec(self):
+ def testConsistency(self):
s = self.s1.clone(sizeSpec=constraint.ConstraintsUnion(
constraint.ValueSizeConstraint(1, 1)
))
s.setComponentByPosition(0, univ.OctetString('abc'))
- try:
- s.verifySizeSpec()
- except PyAsn1Error:
- assert 0, 'size spec fails'
+ assert not s.isInconsistent, 'size spec fails'
s.setComponentByPosition(1, univ.OctetString('abc'))
- try:
- s.verifySizeSpec()
- except PyAsn1Error:
- pass
- else:
- assert 0, 'size spec fails'
+ assert s.isInconsistent, 'size spec fails'
def testGetComponentTagMap(self):
assert self.s1.componentType.tagMap.presentTypes == {