summaryrefslogtreecommitdiff
path: root/pyasn1
diff options
context:
space:
mode:
authorIlya Etingof <etingof@gmail.com>2019-08-25 15:17:38 +0200
committerGitHub <noreply@github.com>2019-08-25 15:17:38 +0200
commit41ce2e5cfeef488f847c3f58ff3d9d0fceb9ded7 (patch)
tree742135c2f6a578a45bac4850fb72f915f136e464 /pyasn1
parent66afc8921e4f5d3a41e407ab6d95ce7e4ec5383a (diff)
downloadpyasn1-git-41ce2e5cfeef488f847c3f58ff3d9d0fceb9ded7.tar.gz
Deprecate `sizeSpec` in favor of `subtypeSpec` (#172)
This commit deprecates `subtypeSpec` attributes and keyword argument. It is now recommended to pass `ValueSizeConstraint`, as well as all other constraints, to `subtypeSpec`. By way of the change mentioned above, this commit fixes a design bug in a way of how the items assigned to constructed types are verified. Now if `Asn1Type`-based object is assigned, its compatibility is verified based on having all tags and constraint objects as the type in field definition. When a bare Python value is assigned, then field type object is cloned and initialized with the bare value (constraints verificaton would run at this moment).
Diffstat (limited to 'pyasn1')
-rw-r--r--pyasn1/type/base.py31
-rw-r--r--pyasn1/type/char.py4
-rw-r--r--pyasn1/type/univ.py109
3 files changed, 71 insertions, 73 deletions
diff --git a/pyasn1/type/base.py b/pyasn1/type/base.py
index 1fd69f9..834b76e 100644
--- a/pyasn1/type/base.py
+++ b/pyasn1/type/base.py
@@ -498,17 +498,39 @@ class ConstructedAsn1Type(Asn1Type):
strictConstraints = False
componentType = None
- sizeSpec = None
+
+ # backward compatibility, unused
+ sizeSpec = constraint.ConstraintsIntersection()
def __init__(self, **kwargs):
readOnly = {
'componentType': self.componentType,
+ # backward compatibility, unused
'sizeSpec': self.sizeSpec
}
+
+ # backward compatibility: preserve legacy sizeSpec support
+ kwargs = self._moveSizeSpec(**kwargs)
+
readOnly.update(kwargs)
Asn1Type.__init__(self, **readOnly)
+ def _moveSizeSpec(self, **kwargs):
+ # backward compatibility, unused
+ sizeSpec = kwargs.pop('sizeSpec', self.sizeSpec)
+ if sizeSpec:
+ subtypeSpec = kwargs.pop('subtypeSpec', self.subtypeSpec)
+ if subtypeSpec:
+ subtypeSpec = sizeSpec
+
+ else:
+ subtypeSpec += sizeSpec
+
+ kwargs['subtypeSpec'] = subtypeSpec
+
+ return kwargs
+
def __repr__(self):
representation = '%s %s object' % (
self.__class__.__name__, self.isValue and 'value' or 'schema'
@@ -667,7 +689,7 @@ class ConstructedAsn1Type(Asn1Type):
:py:class:`~pyasn1.error.PyAsn1tError` on any inconsistencies found
"""
try:
- self.sizeSpec(self)
+ self.subtypeSpec(self)
except error.PyAsn1Error:
exc = sys.exc_info()[1]
@@ -694,9 +716,10 @@ class ConstructedAsn1Type(Asn1Type):
def getComponentType(self):
return self.componentType
+ # backward compatibility, unused
def verifySizeSpec(self):
- self.sizeSpec(self)
+ self.subtypeSpec(self)
-# Backward compatibility
+ # Backward compatibility
AbstractConstructedAsn1Item = ConstructedAsn1Type
diff --git a/pyasn1/type/char.py b/pyasn1/type/char.py
index 3f8c444..06074da 100644
--- a/pyasn1/type/char.py
+++ b/pyasn1/type/char.py
@@ -39,7 +39,9 @@ class AbstractCharacterString(univ.OctetString):
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
+ Object representing non-default ASN.1 subtype constraint(s). Constraints
+ verification for |ASN.1| type occurs automatically on object
+ instantiation.
encoding: :py:class:`str`
Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
diff --git a/pyasn1/type/univ.py b/pyasn1/type/univ.py
index 4f305f6..fbf8ed5 100644
--- a/pyasn1/type/univ.py
+++ b/pyasn1/type/univ.py
@@ -47,7 +47,9 @@ class Integer(base.SimpleAsn1Type):
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
+ Object representing non-default ASN.1 subtype constraint(s). Constraints
+ verification for |ASN.1| type occurs automatically on object
+ instantiation.
namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
Object representing non-default symbolic aliases for numbers
@@ -293,7 +295,9 @@ class Boolean(Integer):
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
+ Object representing non-default ASN.1 subtype constraint(s).Constraints
+ verification for |ASN.1| type occurs automatically on object
+ instantiation.
namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
Object representing non-default symbolic aliases for numbers
@@ -377,7 +381,9 @@ class BitString(base.SimpleAsn1Type):
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
+ Object representing non-default ASN.1 subtype constraint(s). Constraints
+ verification for |ASN.1| type occurs automatically on object
+ instantiation.
namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
Object representing non-default symbolic aliases for numbers
@@ -747,7 +753,9 @@ class OctetString(base.SimpleAsn1Type):
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
+ Object representing non-default ASN.1 subtype constraint(s). Constraints
+ verification for |ASN.1| type occurs automatically on object
+ instantiation.
encoding: :py:class:`str`
Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
@@ -1130,7 +1138,9 @@ class ObjectIdentifier(base.SimpleAsn1Type):
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
+ Object representing non-default ASN.1 subtype constraint(s). Constraints
+ verification for |ASN.1| type occurs automatically on object
+ instantiation.
Raises
------
@@ -1268,7 +1278,9 @@ class Real(base.SimpleAsn1Type):
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
+ Object representing non-default ASN.1 subtype constraint(s). Constraints
+ verification for |ASN.1| type occurs automatically on object
+ instantiation.
Raises
------
@@ -1552,7 +1564,9 @@ class Enumerated(Integer):
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
+ Object representing non-default ASN.1 subtype constraint(s). Constraints
+ verification for |ASN.1| type occurs automatically on object
+ instantiation.
namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
Object representing non-default symbolic aliases for numbers
@@ -1620,10 +1634,9 @@ class SequenceOfAndSetOfBase(base.ConstructedAsn1Type):
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
-
- sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing collection size constraint
+ Object representing non-default ASN.1 subtype constraint(s). Constraints
+ verification for |ASN.1| type can only occur on explicit
+ `.isInconsistent` call.
Examples
--------
@@ -1645,7 +1658,7 @@ class SequenceOfAndSetOfBase(base.ConstructedAsn1Type):
# support positional params for backward compatibility
if args:
for key, value in zip(('componentType', 'tagSet',
- 'subtypeSpec', 'sizeSpec'), args):
+ 'subtypeSpec'), args):
if key in kwargs:
raise error.PyAsn1Error('Conflicting positional and keyword params!')
kwargs['componentType'] = value
@@ -1921,7 +1934,8 @@ class SequenceOfAndSetOfBase(base.ConstructedAsn1Type):
componentType.isSameTypeWith or
componentType.isSuperTypeOf)
- if not subtypeChecker(value, matchTags, matchConstraints):
+ if not subtypeChecker(value, verifyConstraints and matchTags,
+ verifyConstraints and matchConstraints):
# TODO: we should wrap componentType with UnnamedType to carry
# additional properties associated with componentType
if componentType.typeId != Any.typeId:
@@ -1929,21 +1943,6 @@ class SequenceOfAndSetOfBase(base.ConstructedAsn1Type):
'Component value is tag-incompatible: %r vs '
'%r' % (value, componentType))
- else:
- if not componentType.isSuperTypeOf(
- value, matchTags, matchConstraints):
- raise error.PyAsn1Error(
- 'Component value is tag-incompatible: '
- '%r vs %r' % (value, componentType))
-
- if verifyConstraints and value.isValue:
- try:
- self.subtypeSpec(value, idx)
-
- except error.PyAsn1Error:
- exType, exValue, exTb = sys.exc_info()
- raise exType('%s at %s' % (exValue, self.__class__.__name__))
-
componentValues[idx] = value
self._componentValues = componentValues
@@ -2063,10 +2062,6 @@ class SequenceOf(SequenceOfAndSetOfBase):
#: imposing constraints on |ASN.1| type initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
- #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- #: object imposing size constraint on |ASN.1| objects
- sizeSpec = constraint.ConstraintsIntersection()
-
# Disambiguation ASN.1 types identification
typeId = SequenceOfAndSetOfBase.getTypeId()
@@ -2090,10 +2085,6 @@ class SetOf(SequenceOfAndSetOfBase):
#: imposing constraints on |ASN.1| type initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
- #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- #: object imposing size constraint on |ASN.1| objects
- sizeSpec = constraint.ConstraintsIntersection()
-
# Disambiguation ASN.1 types identification
typeId = SequenceOfAndSetOfBase.getTypeId()
@@ -2113,10 +2104,9 @@ class SequenceAndSetBase(base.ConstructedAsn1Type):
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
-
- sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing collection size constraint
+ Object representing non-default ASN.1 subtype constraint(s). Constraints
+ verification for |ASN.1| type can only occur on explicit
+ `.isInconsistent` call.
Examples
--------
@@ -2562,25 +2552,19 @@ class SequenceAndSetBase(base.ConstructedAsn1Type):
else:
raise error.PyAsn1Error('%s undefined component type' % componentType.__class__.__name__)
- elif (matchTags or matchConstraints) and componentTypeLen:
+ elif ((verifyConstraints or matchTags or matchConstraints) and
+ componentTypeLen):
subComponentType = componentType.getTypeByPosition(idx)
if subComponentType is not noValue:
subtypeChecker = (self.strictConstraints and
subComponentType.isSameTypeWith or
subComponentType.isSuperTypeOf)
- if not subtypeChecker(value, matchTags, matchConstraints):
+ if not subtypeChecker(value, verifyConstraints and matchTags,
+ verifyConstraints and matchConstraints):
if not componentType[idx].openType:
raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
- if verifyConstraints and value.isValue:
- try:
- self.subtypeSpec(value, idx)
-
- except error.PyAsn1Error:
- exType, exValue, exTb = sys.exc_info()
- raise exType('%s at %s' % (exValue, self.__class__.__name__))
-
if componentTypeLen or idx in self._dynamicNames:
componentValues[idx] = value
@@ -2717,10 +2701,6 @@ class Sequence(SequenceAndSetBase):
#: imposing constraints on |ASN.1| type initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
- #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- #: object imposing constraints on |ASN.1| objects
- sizeSpec = constraint.ConstraintsIntersection()
-
#: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
#: object imposing size constraint on |ASN.1| objects
componentType = namedtype.NamedTypes()
@@ -2760,10 +2740,6 @@ class Set(SequenceAndSetBase):
#: imposing constraints on |ASN.1| type initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
- #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- #: object imposing constraints on |ASN.1| objects
- sizeSpec = constraint.ConstraintsIntersection()
-
# Disambiguation ASN.1 types identification
typeId = SequenceAndSetBase.getTypeId()
@@ -2884,10 +2860,9 @@ class Choice(Set):
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
-
- sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing collection size constraint
+ Object representing non-default ASN.1 subtype constraint(s). Constraints
+ verification for |ASN.1| type can only occur on explicit
+ `.isInconsistent` call.
Examples
--------
@@ -2927,11 +2902,7 @@ class Choice(Set):
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
#: imposing constraints on |ASN.1| type initialization values.
- subtypeSpec = constraint.ConstraintsIntersection()
-
- #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- #: object imposing size constraint on |ASN.1| objects
- sizeSpec = constraint.ConstraintsIntersection(
+ subtypeSpec = constraint.ConstraintsIntersection(
constraint.ValueSizeConstraint(1, 1)
)
@@ -3197,7 +3168,9 @@ class Any(OctetString):
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
+ Object representing non-default ASN.1 subtype constraint(s). Constraints
+ verification for |ASN.1| type occurs automatically on object
+ instantiation.
encoding: :py:class:`str`
Unicode codec ID to encode/decode :class:`unicode` (Python 2) or