aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Etingof <etingof@gmail.com>2017-07-23 13:37:14 +0200
committerIlya Etingof <etingof@gmail.com>2017-07-23 13:37:14 +0200
commitacfa2fcc24493a69626c17b23df3de8d771cbcc6 (patch)
tree9abe30b39d62e84f889ccb92d5d63835c30675a7
parentbc7e3b836eb87c0d90ba413c6f89dbe8830a4437 (diff)
downloadpyasn1-acfa2fcc24493a69626c17b23df3de8d771cbcc6.tar.gz
ASN.1 types __init__(), .clone()/.subtype() refactored into kwargs
-rw-r--r--CHANGES.rst2
-rw-r--r--pyasn1/codec/ber/decoder.py10
-rw-r--r--pyasn1/codec/ber/encoder.py2
-rw-r--r--pyasn1/codec/ber/eoo.py4
-rw-r--r--pyasn1/type/base.py168
-rw-r--r--pyasn1/type/char.py27
-rw-r--r--pyasn1/type/univ.py312
7 files changed, 191 insertions, 334 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index fafd7a2..94926e9 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -2,6 +2,8 @@
Revision 0.3.1, released XX-07-2017
-----------------------------------
+- ASN.1 types __init__(), .clone() and .subtype() signatures
+ refactored into keyword arguments to simplify their signatures.
- ASN.1 types initialization refactored to minimize the use of
relatively expensive isNoValue() call
- Lazily pre-populate list of values of Sequence/Set/Choice types
diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py
index fc51c85..ede16a7 100644
--- a/pyasn1/codec/ber/decoder.py
+++ b/pyasn1/codec/ber/decoder.py
@@ -32,11 +32,11 @@ class AbstractSimpleDecoder(AbstractDecoder):
def substrateCollector(asn1Object, substrate, length):
return substrate[:length], substrate[length:]
- def _createComponent(self, asn1Spec, tagSet, value=None):
+ def _createComponent(self, asn1Spec, tagSet, value=base.noValue):
if tagSet[0].tagFormat not in self.tagFormats:
raise error.PyAsn1Error('Invalid tag format %s for %s' % (tagSet[0], self.protoComponent.prettyPrintType()))
if asn1Spec is None:
- return self.protoComponent.clone(value, tagSet)
+ return self.protoComponent.clone(value, tagSet=tagSet)
elif value is None:
return asn1Spec
else:
@@ -47,11 +47,11 @@ class AbstractConstructedDecoder(AbstractDecoder):
tagFormats = (tag.tagFormatConstructed,)
# noinspection PyUnusedLocal
- def _createComponent(self, asn1Spec, tagSet, value=None):
+ def _createComponent(self, asn1Spec, tagSet, value=base.noValue):
if tagSet[0].tagFormat not in self.tagFormats:
raise error.PyAsn1Error('Invalid tag format %s for %s' % (tagSet[0], self.protoComponent.prettyPrintType()))
if asn1Spec is None:
- return self.protoComponent.clone(tagSet)
+ return self.protoComponent.clone(tagSet=tagSet)
else:
return asn1Spec.clone()
@@ -107,7 +107,7 @@ class IntegerDecoder(AbstractSimpleDecoder):
class BooleanDecoder(IntegerDecoder):
protoComponent = univ.Boolean(0)
- def _createComponent(self, asn1Spec, tagSet, value=None):
+ def _createComponent(self, asn1Spec, tagSet, value=base.noValue):
return IntegerDecoder._createComponent(self, asn1Spec, tagSet, value and 1 or 0)
diff --git a/pyasn1/codec/ber/encoder.py b/pyasn1/codec/ber/encoder.py
index 14bd609..dfef38f 100644
--- a/pyasn1/codec/ber/encoder.py
+++ b/pyasn1/codec/ber/encoder.py
@@ -88,7 +88,7 @@ class EndOfOctetsEncoder(AbstractItemEncoder):
class ExplicitlyTaggedItemEncoder(AbstractItemEncoder):
def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
if isinstance(value, base.AbstractConstructedAsn1Item):
- value = value.clone(tagSet=value.tagSet[:-1], cloneValueFlag=1)
+ value = value.clone(tagSet=value.tagSet[:-1], cloneValueFlag=True)
else:
value = value.clone(tagSet=value.tagSet[:-1])
return encodeFun(value, defMode, maxChunkSize), True, True
diff --git a/pyasn1/codec/ber/eoo.py b/pyasn1/codec/ber/eoo.py
index b02f5cc..28e33c5 100644
--- a/pyasn1/codec/ber/eoo.py
+++ b/pyasn1/codec/ber/eoo.py
@@ -15,9 +15,9 @@ class EndOfOctets(base.AbstractSimpleAsn1Item):
_instance = None
- def __new__(cls, *args):
+ def __new__(cls, *args, **kwargs):
if cls._instance is None:
- cls._instance = object.__new__(cls, *args)
+ cls._instance = object.__new__(cls, *args, **kwargs)
return cls._instance
diff --git a/pyasn1/type/base.py b/pyasn1/type/base.py
index 4ee5c21..0f088c6 100644
--- a/pyasn1/type/base.py
+++ b/pyasn1/type/base.py
@@ -34,13 +34,14 @@ class Asn1ItemBase(Asn1Item):
# Disambiguation ASN.1 types identification
typeId = None
- def __init__(self, tagSet=None, subtypeSpec=None):
- if tagSet is not None:
- self.tagSet = tagSet
- if subtypeSpec is not None:
- self.subtypeSpec = subtypeSpec
- self.readOnly = 'subtypeSpec'
- self.readOnly = 'tagSet'
+ def __init__(self, **kwargs):
+ for key in ('tagSet', 'subtypeSpec'):
+ if key not in kwargs:
+ kwargs[key] = getattr(self, key)
+
+ for key, value in kwargs.items():
+ setattr(self, key, value)
+ self.readOnly = key
def __setattr__(self, name, value):
if not name.startswith('_'):
@@ -220,8 +221,8 @@ class AbstractSimpleAsn1Item(Asn1ItemBase):
#: Default payload value
defaultValue = noValue
- def __init__(self, value=noValue, tagSet=None, subtypeSpec=None):
- Asn1ItemBase.__init__(self, tagSet, subtypeSpec)
+ def __init__(self, value=noValue, **kwargs):
+ Asn1ItemBase.__init__(self, **kwargs)
if value is None or value is noValue:
value = self.defaultValue
else:
@@ -300,7 +301,7 @@ class AbstractSimpleAsn1Item(Asn1ItemBase):
"""
return self._value is not noValue
- def clone(self, value=noValue, tagSet=None, subtypeSpec=None):
+ def clone(self, value=noValue, **kwargs):
"""Create a copy of a |ASN.1| type or object.
Any parameters to the *clone()* method will replace corresponding
@@ -323,28 +324,19 @@ class AbstractSimpleAsn1Item(Asn1ItemBase):
:
new instance of |ASN.1| type/value
"""
- isModified = False
-
if value is None or value is noValue:
+ if not kwargs:
+ return self
+
value = self._value
- else:
- isModified = True
- if tagSet is None or tagSet is noValue:
- tagSet = self.tagSet
- else:
- isModified = True
- if subtypeSpec is None or subtypeSpec is noValue:
- subtypeSpec = self.subtypeSpec
- else:
- isModified = True
- if isModified:
- return self.__class__(value, tagSet, subtypeSpec)
- else:
- return self
+ for arg in self.readOnly:
+ if arg not in kwargs:
+ kwargs[arg] = getattr(self, arg)
+
+ return self.__class__(value, **kwargs)
- def subtype(self, value=noValue, implicitTag=None, explicitTag=None,
- subtypeSpec=None):
+ def subtype(self, value=noValue, **kwargs):
"""Create a copy of a |ASN.1| type or object.
Any parameters to the *subtype()* method will be added to the corresponding
@@ -374,31 +366,32 @@ class AbstractSimpleAsn1Item(Asn1ItemBase):
-------
:
new instance of |ASN.1| type/value
- """
- isModified = False
-
+ """
if value is None or value is noValue:
+ if not kwargs:
+ return self
+
value = self._value
- else:
- isModified = True
- if implicitTag is not None and implicitTag is not noValue:
- tagSet = self.tagSet.tagImplicitly(implicitTag)
- isModified = True
- elif explicitTag is not None and explicitTag is not noValue:
- tagSet = self.tagSet.tagExplicitly(explicitTag)
- isModified = True
- else:
- tagSet = self.tagSet
- if subtypeSpec is None or subtypeSpec is noValue:
- subtypeSpec = self.subtypeSpec
- else:
- subtypeSpec += self.subtypeSpec
- isModified = True
- if isModified:
- return self.__class__(value, tagSet, subtypeSpec)
- else:
- return self
+ for arg in self.readOnly:
+ if arg in kwargs:
+ kwargs[arg] += getattr(self, arg)
+ else:
+ kwargs[arg] = getattr(self, arg)
+
+ try:
+ kwargs['tagSet'] = self.tagSet.tagImplicitly(kwargs['implicitTag'])
+
+ except KeyError:
+ pass
+
+ try:
+ kwargs['tagSet'] = self.tagSet.tagExplicitly(kwargs['explicitTag'])
+
+ except KeyError:
+ pass
+
+ return self.__class__(value, **kwargs)
def prettyIn(self, value):
return value
@@ -472,16 +465,14 @@ class AbstractConstructedAsn1Item(Asn1ItemBase):
componentType = None
sizeSpec = None
- def __init__(self, componentType=None, tagSet=None,
- subtypeSpec=None, sizeSpec=None):
- Asn1ItemBase.__init__(self, tagSet, subtypeSpec)
- if componentType is not None:
- self.componentType = componentType
- if sizeSpec is not None:
- self.sizeSpec = sizeSpec
+ def __init__(self, **kwargs):
+ for key in ('componentType', 'sizeSpec'):
+ if key not in kwargs:
+ kwargs[key] = getattr(self, key)
+
+ Asn1ItemBase.__init__(self, **kwargs)
+
self._componentValues = []
- self.readOnly = 'componentType'
- self.readOnly = 'sizeSpec'
def __repr__(self):
representation = []
@@ -527,7 +518,7 @@ class AbstractConstructedAsn1Item(Asn1ItemBase):
def _cloneComponentValues(self, myClone, cloneValueFlag):
pass
- def clone(self, tagSet=None, subtypeSpec=None, sizeSpec=None, cloneValueFlag=None):
+ def clone(self, **kwargs):
"""Create a copy of a |ASN.1| type or object.
Any parameters to the *clone()* method will replace corresponding
@@ -550,19 +541,20 @@ class AbstractConstructedAsn1Item(Asn1ItemBase):
new instance of |ASN.1| type/value
"""
- if tagSet is None:
- tagSet = self.tagSet
- if subtypeSpec is None:
- subtypeSpec = self.subtypeSpec
- if sizeSpec is None:
- sizeSpec = self.sizeSpec
- clone = self.__class__(self.componentType, tagSet, subtypeSpec, sizeSpec)
+ cloneValueFlag = kwargs.pop('cloneValueFlag', False)
+
+ for arg in self.readOnly:
+ if arg not in kwargs:
+ kwargs[arg] = getattr(self, arg)
+
+ clone = self.__class__(**kwargs)
+
if cloneValueFlag:
self._cloneComponentValues(clone, cloneValueFlag)
+
return clone
- def subtype(self, implicitTag=None, explicitTag=None, subtypeSpec=None,
- sizeSpec=None, cloneValueFlag=None):
+ def subtype(self, **kwargs):
"""Create a copy of a |ASN.1| type or object.
Any parameters to the *subtype()* method will be added to the corresponding
@@ -585,23 +577,31 @@ class AbstractConstructedAsn1Item(Asn1ItemBase):
new instance of |ASN.1| type/value
"""
- if implicitTag is not None and implicitTag is not noValue:
- tagSet = self.tagSet.tagImplicitly(implicitTag)
- elif explicitTag is not None and explicitTag is not noValue:
- tagSet = self.tagSet.tagExplicitly(explicitTag)
- else:
- tagSet = self.tagSet
- if subtypeSpec is None or subtypeSpec is noValue:
- subtypeSpec = self.subtypeSpec
- else:
- subtypeSpec += self.subtypeSpec
- if sizeSpec is None or sizeSpec is noValue:
- sizeSpec = self.sizeSpec
- else:
- sizeSpec += self.sizeSpec
- clone = self.__class__(self.componentType, tagSet, subtypeSpec, sizeSpec)
+ cloneValueFlag = kwargs.pop('cloneValueFlag', False)
+
+ for arg in self.readOnly:
+ if arg in kwargs:
+ kwargs[arg] += getattr(self, arg)
+ else:
+ kwargs[arg] = getattr(self, arg)
+
+ try:
+ kwargs['tagSet'] = self.tagSet.tagImplicitly(kwargs['implicitTag'])
+
+ except KeyError:
+ pass
+
+ try:
+ kwargs['tagSet'] = self.tagSet.tagExplicitly(kwargs['explicitTag'])
+
+ except KeyError:
+ pass
+
+ clone = self.__class__(**kwargs)
+
if cloneValueFlag:
self._cloneComponentValues(clone, cloneValueFlag)
+
return clone
def verifySizeSpec(self):
diff --git a/pyasn1/type/char.py b/pyasn1/type/char.py
index 039e536..4bb46aa 100644
--- a/pyasn1/type/char.py
+++ b/pyasn1/type/char.py
@@ -50,10 +50,10 @@ class AbstractCharacterString(univ.OctetString):
if sys.version_info[0] <= 2:
def __str__(self):
try:
- return self._value.encode(self._encoding)
+ return self._value.encode(self.encoding)
except UnicodeEncodeError:
raise error.PyAsn1Error(
- 'Can\'t encode string \'%s\' with \'%s\' codec' % (self._value, self._encoding)
+ 'Can\'t encode string \'%s\' with \'%s\' codec' % (self._value, self.encoding)
)
def __unicode__(self):
@@ -64,10 +64,10 @@ class AbstractCharacterString(univ.OctetString):
return value
elif isinstance(value, str):
try:
- return value.decode(self._encoding)
+ return value.decode(self.encoding)
except (LookupError, UnicodeDecodeError):
raise error.PyAsn1Error(
- 'Can\'t decode string \'%s\' with \'%s\' codec' % (value, self._encoding)
+ 'Can\'t decode string \'%s\' with \'%s\' codec' % (value, self.encoding)
)
elif isinstance(value, (tuple, list)):
try:
@@ -96,10 +96,10 @@ class AbstractCharacterString(univ.OctetString):
def __bytes__(self):
try:
- return self._value.encode(self._encoding)
+ return self._value.encode(self.encoding)
except UnicodeEncodeError:
raise error.PyAsn1Error(
- 'Can\'t encode string \'%s\' with \'%s\' codec' % (self._value, self._encoding)
+ 'Can\'t encode string \'%s\' with \'%s\' codec' % (self._value, self.encoding)
)
def prettyIn(self, value):
@@ -107,10 +107,10 @@ class AbstractCharacterString(univ.OctetString):
return value
elif isinstance(value, bytes):
try:
- return value.decode(self._encoding)
+ return value.decode(self.encoding)
except UnicodeDecodeError:
raise error.PyAsn1Error(
- 'Can\'t decode string \'%s\' with \'%s\' codec' % (value, self._encoding)
+ 'Can\'t decode string \'%s\' with \'%s\' codec' % (value, self.encoding)
)
elif isinstance(value, (tuple, list)):
return self.prettyIn(bytes(value))
@@ -134,8 +134,7 @@ class AbstractCharacterString(univ.OctetString):
def __reversed__(self):
return reversed(self._value)
- def clone(self, value=noValue, tagSet=None, subtypeSpec=None,
- encoding=None, binValue=noValue, hexValue=noValue):
+ def clone(self, value=noValue, **kwargs):
"""Creates a copy of a |ASN.1| type or object.
Any parameters to the *clone()* method will replace corresponding
@@ -165,10 +164,9 @@ class AbstractCharacterString(univ.OctetString):
new instance of |ASN.1| type/value
"""
- return univ.OctetString.clone(self, value, tagSet, subtypeSpec, encoding, binValue, hexValue)
+ return univ.OctetString.clone(self, value, **kwargs)
- def subtype(self, value=noValue, implicitTag=None, explicitTag=None,
- subtypeSpec=None, encoding=None, binValue=noValue, hexValue=noValue):
+ def subtype(self, value=noValue, **kwargs):
"""Creates a copy of a |ASN.1| type or object.
Any parameters to the *subtype()* method will be added to the corresponding
@@ -205,8 +203,7 @@ class AbstractCharacterString(univ.OctetString):
new instance of |ASN.1| type/value
"""
- return univ.OctetString.subtype(self, value, implicitTag, explicitTag, subtypeSpec, encoding, binValue, hexValue)
-
+ return univ.OctetString.subtype(self, value, **kwargs)
class NumericString(AbstractCharacterString):
__doc__ = AbstractCharacterString.__doc__
diff --git a/pyasn1/type/univ.py b/pyasn1/type/univ.py
index 298869b..038744e 100644
--- a/pyasn1/type/univ.py
+++ b/pyasn1/type/univ.py
@@ -64,14 +64,11 @@ class Integer(base.AbstractSimpleAsn1Item):
# Optimization for faster codec lookup
typeId = base.AbstractSimpleAsn1Item.getTypeId()
- def __init__(self, value=noValue, tagSet=None, subtypeSpec=None,
- namedValues=None):
- if namedValues is not None:
- self.namedValues = namedValues
- base.AbstractSimpleAsn1Item.__init__(
- self, value, tagSet, subtypeSpec
- )
- self.readOnly = 'namedValues'
+ def __init__(self, value=noValue, **kwargs):
+ if 'namedValues' not in kwargs:
+ kwargs['namedValues'] = self.namedValues
+
+ base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
def __repr__(self):
if self.namedValues is not self.__class__.namedValues:
@@ -245,7 +242,7 @@ class Integer(base.AbstractSimpleAsn1Item):
except KeyError:
return str(value)
- def clone(self, value=noValue, tagSet=None, subtypeSpec=None, namedValues=None):
+ def clone(self, value=noValue, **kwargs):
"""Create a copy of a |ASN.1| type or object.
Any parameters to the *clone()* method will replace corresponding
@@ -271,32 +268,9 @@ class Integer(base.AbstractSimpleAsn1Item):
:
new instance of |ASN.1| type/value
"""
- isModified = False
-
- if value is None or value is noValue:
- value = self._value
- else:
- isModified = True
- if tagSet is None or tagSet is noValue:
- tagSet = self.tagSet
- else:
- isModified = True
- if subtypeSpec is None or subtypeSpec is noValue:
- subtypeSpec = self.subtypeSpec
- else:
- isModified = True
- if namedValues is None or namedValues is noValue:
- namedValues = self.namedValues
- else:
- isModified = True
-
- if isModified:
- return self.__class__(value, tagSet, subtypeSpec, namedValues)
- else:
- return self
+ return base.AbstractSimpleAsn1Item.clone(self, value, **kwargs)
- def subtype(self, value=noValue, implicitTag=None, explicitTag=None,
- subtypeSpec=None, namedValues=None):
+ def subtype(self, value=noValue, **kwargs):
"""Create a copy of a |ASN.1| type or object.
Any parameters to the *subtype()* method will be added to the corresponding
@@ -332,35 +306,7 @@ class Integer(base.AbstractSimpleAsn1Item):
:
new instance of |ASN.1| type/value
"""
- isModified = False
-
- if value is None or value is noValue:
- value = self._value
- else:
- isModified = True
- if implicitTag is not None and implicitTag is not noValue:
- tagSet = self.tagSet.tagImplicitly(implicitTag)
- isModified = True
- elif explicitTag is not None and explicitTag is not noValue:
- tagSet = self.tagSet.tagExplicitly(explicitTag)
- isModified = True
- else:
- tagSet = self.tagSet
- if subtypeSpec is None or subtypeSpec is noValue:
- subtypeSpec = self.subtypeSpec
- else:
- subtypeSpec += self.subtypeSpec
- isModified = True
- if namedValues is None or namedValues is noValue:
- namedValues = self.namedValues
- else:
- namedValues += self.namedValues
- isModified = True
-
- if isModified:
- return self.__class__(value, tagSet, subtypeSpec, namedValues)
- else:
- return self
+ return base.AbstractSimpleAsn1Item.subtype(self, value, **kwargs)
# backward compatibility
@@ -465,24 +411,34 @@ class BitString(base.AbstractSimpleAsn1Item):
return self.bitLength
- def __init__(self, value=noValue, tagSet=None, subtypeSpec=None,
- namedValues=None, binValue=noValue, hexValue=noValue):
- if namedValues is not None:
- self.namedValues = namedValues
- if binValue is not noValue:
- value = self.fromBinaryString(binValue)
- elif hexValue is not noValue:
- value = self.fromHexString(hexValue)
- elif value is None or value is noValue:
+ def __init__(self, value=noValue, **kwargs):
+ if value is noValue or value is None:
+ if kwargs:
+ try:
+ value = self.fromBinaryString(kwargs.pop('binValue'))
+
+ except KeyError:
+ pass
+
+ try:
+ value = self.fromHexString(kwargs.pop('hexValue'))
+
+ except KeyError:
+ pass
+
+ if value is noValue or value is None:
if self.defaultBinValue is not noValue:
value = self.fromBinaryString(self.defaultBinValue)
+
elif self.defaultHexValue is not noValue:
value = self.fromHexString(self.defaultHexValue)
- base.AbstractSimpleAsn1Item.__init__(self, value, tagSet, subtypeSpec)
- self._readOnly.add('namedValues')
- def clone(self, value=noValue, tagSet=None, subtypeSpec=None,
- namedValues=None, binValue=noValue, hexValue=noValue):
+ if 'namedValues' not in kwargs:
+ kwargs['namedValues'] = self.namedValues
+
+ base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
+
+ def clone(self, value=noValue, **kwargs):
"""Create a copy of a |ASN.1| type or object.
Any parameters to the *clone()* method will replace corresponding
@@ -516,32 +472,9 @@ class BitString(base.AbstractSimpleAsn1Item):
:
new instance of |ASN.1| type/value
"""
- isModified = False
-
- if (value is None or value is noValue) and binValue is noValue and hexValue is noValue:
- value = self._value
- else:
- isModified = True
- if tagSet is None or tagSet is noValue:
- tagSet = self.tagSet
- else:
- isModified = True
- if subtypeSpec is None or subtypeSpec is noValue:
- subtypeSpec = self.subtypeSpec
- else:
- isModified = True
- if namedValues is None or namedValues is noValue:
- namedValues = self.namedValues
- else:
- isModified = True
+ return base.AbstractSimpleAsn1Item.clone(self, value, **kwargs)
- if isModified:
- return self.__class__(value, tagSet, subtypeSpec, namedValues, binValue, hexValue)
- else:
- return self
-
- def subtype(self, value=noValue, implicitTag=None, explicitTag=None,
- subtypeSpec=None, namedValues=None, binValue=noValue, hexValue=noValue):
+ def subtype(self, value=noValue, **kwargs):
"""Create a copy of a |ASN.1| type or object.
Any parameters to the *subtype()* method will be added to the corresponding
@@ -585,35 +518,7 @@ class BitString(base.AbstractSimpleAsn1Item):
:
new instance of |ASN.1| type/value
"""
- isModified = False
-
- if (value is None or value is noValue) and binValue is noValue and hexValue is noValue:
- value = self._value
- else:
- isModified = True
- if implicitTag is not None and implicitTag is not noValue:
- tagSet = self.tagSet.tagImplicitly(implicitTag)
- isModified = True
- elif explicitTag is not None and explicitTag is not noValue:
- tagSet = self.tagSet.tagExplicitly(explicitTag)
- isModified = True
- else:
- tagSet = self.tagSet
- if subtypeSpec is None or subtypeSpec is noValue:
- subtypeSpec = self.subtypeSpec
- else:
- subtypeSpec += self.subtypeSpec
- isModified = True
- if namedValues is None or namedValues is noValue:
- namedValues = self.namedValues
- else:
- namedValues += self.namedValues
- isModified = True
-
- if isModified:
- return self.__class__(value, tagSet, subtypeSpec, namedValues, binValue, hexValue)
- else:
- return self
+ return base.AbstractSimpleAsn1Item.subtype(self, value, **kwargs)
def __str__(self):
return self.asBinary()
@@ -877,26 +782,36 @@ class OctetString(base.AbstractSimpleAsn1Item):
defaultBinValue = defaultHexValue = noValue
encoding = 'iso-8859-1'
- def __init__(self, value=noValue, tagSet=None, subtypeSpec=None,
- encoding=None, binValue=noValue, hexValue=noValue):
- if encoding is None:
- self._encoding = self.encoding
- else:
- self._encoding = encoding
- if binValue is not noValue:
- value = self.fromBinaryString(binValue)
- elif hexValue is not noValue:
- value = self.fromHexString(hexValue)
- elif value is None or value is noValue:
+ def __init__(self, value=noValue, **kwargs):
+ if kwargs:
+ if value is noValue or value is None:
+ try:
+ value = self.fromBinaryString(kwargs.pop('binValue'))
+
+ except KeyError:
+ pass
+
+ try:
+ value = self.fromHexString(kwargs.pop('hexValue'))
+
+ except KeyError:
+ pass
+
+ if value is noValue or value is None:
if self.defaultBinValue is not noValue:
value = self.fromBinaryString(self.defaultBinValue)
+
elif self.defaultHexValue is not noValue:
value = self.fromHexString(self.defaultHexValue)
+
+ if 'encoding' not in kwargs:
+ kwargs['encoding'] = self.encoding
+
self.__asNumbersCache = None
- base.AbstractSimpleAsn1Item.__init__(self, value, tagSet, subtypeSpec)
- def clone(self, value=noValue, tagSet=None, subtypeSpec=None,
- encoding=None, binValue=noValue, hexValue=noValue):
+ base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
+
+ def clone(self, value=noValue, **kwargs):
"""Create a copy of a |ASN.1| type or object.
Any parameters to the *clone()* method will replace corresponding
@@ -930,33 +845,9 @@ class OctetString(base.AbstractSimpleAsn1Item):
:
new instance of |ASN.1| type/value
"""
- isModified = False
+ return base.AbstractSimpleAsn1Item.clone(self, value, **kwargs)
- if (value is None or value is noValue) and binValue is noValue and hexValue is noValue:
- value = self._value
- else:
- isModified = True
- if tagSet is None or tagSet is noValue:
- tagSet = self.tagSet
- else:
- isModified = True
- if subtypeSpec is None or subtypeSpec is noValue:
- subtypeSpec = self.subtypeSpec
- else:
- isModified = True
- if encoding is None or encoding is noValue:
- encoding = self._encoding
- else:
- isModified = True
-
- if isModified:
- return self.__class__(value, tagSet, subtypeSpec, encoding, binValue, hexValue)
- else:
- return self
-
- def subtype(self, value=noValue, implicitTag=None, explicitTag=None,
- subtypeSpec=None, encoding=None, binValue=noValue,
- hexValue=noValue):
+ def subtype(self, value=noValue, **kwargs):
"""Create a copy of a |ASN.1| type or object.
Any parameters to the *subtype()* method will be added to the corresponding
@@ -998,34 +889,7 @@ class OctetString(base.AbstractSimpleAsn1Item):
:
new instance of |ASN.1| type/value
"""
- isModified = False
-
- if (value is None or value is noValue) and binValue is noValue and hexValue is noValue:
- value = self._value
- else:
- isModified = True
- if implicitTag is not None and implicitTag is not noValue:
- tagSet = self.tagSet.tagImplicitly(implicitTag)
- isModified = True
- elif explicitTag is not None and explicitTag is not noValue:
- tagSet = self.tagSet.tagExplicitly(explicitTag)
- isModified = True
- else:
- tagSet = self.tagSet
- if subtypeSpec is None or subtypeSpec is noValue:
- subtypeSpec = self.subtypeSpec
- else:
- subtypeSpec += self.subtypeSpec
- isModified = True
- if encoding is None or encoding is noValue:
- encoding = self._encoding
- else:
- isModified = True
-
- if isModified:
- return self.__class__(value, tagSet, subtypeSpec, encoding, binValue, hexValue)
- else:
- return self
+ return base.AbstractSimpleAsn1Item.subtype(self, value, **kwargs)
if sys.version_info[0] <= 2:
def prettyIn(self, value):
@@ -1033,10 +897,10 @@ class OctetString(base.AbstractSimpleAsn1Item):
return value
elif isinstance(value, unicode):
try:
- return value.encode(self._encoding)
+ return value.encode(self.encoding)
except (LookupError, UnicodeEncodeError):
raise error.PyAsn1Error(
- 'Can\'t encode string \'%s\' with \'%s\' codec' % (value, self._encoding)
+ 'Can\'t encode string \'%s\' with \'%s\' codec' % (value, self.encoding)
)
elif isinstance(value, (tuple, list)):
try:
@@ -1053,11 +917,11 @@ class OctetString(base.AbstractSimpleAsn1Item):
def __unicode__(self):
try:
- return self._value.decode(self._encoding)
+ return self._value.decode(self.encoding)
except UnicodeDecodeError:
raise error.PyAsn1Error(
- 'Can\'t decode string \'%s\' with \'%s\' codec' % (self._value, self._encoding)
+ 'Can\'t decode string \'%s\' with \'%s\' codec' % (self._value, self.encoding)
)
def asOctets(self):
@@ -1074,10 +938,10 @@ class OctetString(base.AbstractSimpleAsn1Item):
return value
elif isinstance(value, str):
try:
- return value.encode(self._encoding)
+ return value.encode(self.encoding)
except UnicodeEncodeError:
raise error.PyAsn1Error(
- 'Can\'t encode string \'%s\' with \'%s\' codec' % (value, self._encoding)
+ 'Can\'t encode string \'%s\' with \'%s\' codec' % (value, self.encoding)
)
elif isinstance(value, OctetString): # a shortcut, bytes() would work the same way
return value.asOctets()
@@ -1090,11 +954,11 @@ class OctetString(base.AbstractSimpleAsn1Item):
def __str__(self):
try:
- return self._value.decode(self._encoding)
+ return self._value.decode(self.encoding)
except UnicodeDecodeError:
raise error.PyAsn1Error(
- 'Can\'t decode string \'%s\' with \'%s\' codec at \'%s\'' % (self._value, self._encoding, self.__class__.__name__)
+ 'Can\'t decode string \'%s\' with \'%s\' codec at \'%s\'' % (self._value, self.encoding, self.__class__.__name__)
)
def __bytes__(self):
@@ -1118,12 +982,12 @@ class OctetString(base.AbstractSimpleAsn1Item):
return octets.octs2str('0x') + ''.join(('%.2x' % x for x in numbers))
else:
try:
- return value.decode(self._encoding)
+ return value.decode(self.encoding)
except UnicodeDecodeError:
raise error.PyAsn1Error(
'Can\'t decode string \'%s\' with \'%s\' codec at \'%s\'' % (
- value, self._encoding, self.__class__.__name__)
+ value, self.encoding, self.__class__.__name__)
)
@staticmethod
@@ -1179,8 +1043,8 @@ class OctetString(base.AbstractSimpleAsn1Item):
r.append('tagSet=%r' % (self.tagSet,))
if self.subtypeSpec is not self.__class__.subtypeSpec:
r.append('subtypeSpec=%r' % (self.subtypeSpec,))
- if self.encoding is not self._encoding:
- r.append('encoding=%r' % (self._encoding,))
+ if self.encoding is not self.__class__.encoding:
+ r.append('encoding=%r' % (self.encoding,))
if doHex:
r.append('hexValue=%r' % ''.join(['%.2x' % x for x in self.asNumbers()]))
return '%s(%s)' % (self.__class__.__name__, ', '.join(r))
@@ -1257,7 +1121,7 @@ class Null(OctetString):
# Optimization for faster codec lookup
typeId = OctetString.getTypeId()
- def clone(self, value=noValue, tagSet=None):
+ def clone(self, value=noValue, **kwargs):
"""Create a copy of a |ASN.1| type or object.
Any parameters to the *clone()* method will replace corresponding
@@ -1277,9 +1141,9 @@ class Null(OctetString):
: :py:class:`~pyasn1.type.univ.Null`
new instance of NULL type/value
"""
- return OctetString.clone(self, value, tagSet)
+ return OctetString.clone(self, value, **kwargs)
- def subtype(self, value=noValue, implicitTag=None, explicitTag=None):
+ def subtype(self, value=noValue, **kwargs):
"""Create a copy of a |ASN.1| type or object.
Any parameters to the *subtype()* method will be added to the corresponding
@@ -1306,7 +1170,7 @@ class Null(OctetString):
: :py:class:`~pyasn1.type.univ.Null`
new instance of NULL type/value
"""
- return OctetString.subtype(self, value, implicitTag, explicitTag)
+ return OctetString.subtype(self, value, **kwargs)
if sys.version_info[0] <= 2:
@@ -1493,7 +1357,7 @@ class Real(base.AbstractSimpleAsn1Item):
# Optimization for faster codec lookup
typeId = base.AbstractSimpleAsn1Item.getTypeId()
- def clone(self, value=noValue, tagSet=None, subtypeSpec=None):
+ def clone(self, value=noValue, **kwargs):
"""Create a copy of a |ASN.1| type or object.
Any parameters to the *clone()* method will replace corresponding
@@ -1516,10 +1380,9 @@ class Real(base.AbstractSimpleAsn1Item):
:
new instance of |ASN.1| type/value
"""
- return base.AbstractSimpleAsn1Item.clone(self, value, tagSet, subtypeSpec)
+ return base.AbstractSimpleAsn1Item.clone(self, value, **kwargs)
- def subtype(self, value=noValue, implicitTag=None, explicitTag=None,
- subtypeSpec=None):
+ def subtype(self, value=noValue, **kwargs):
"""Create a copy of a |ASN.1| type or object.
Any parameters to the *subtype()* method will be added to the corresponding
@@ -1549,7 +1412,7 @@ class Real(base.AbstractSimpleAsn1Item):
:
new instance of |ASN.1| type/value
"""
- return base.AbstractSimpleAsn1Item.subtype(self, value, implicitTag, explicitTag)
+ return base.AbstractSimpleAsn1Item.subtype(self, value, **kwargs)
@staticmethod
def __normalizeBase10(value):
@@ -1821,8 +1684,6 @@ class SequenceOfAndSetOfBase(base.AbstractConstructedAsn1Item):
Object representing collection size constraint
"""
- componentType = None
-
# Python list protocol
def clear(self):
@@ -1935,7 +1796,7 @@ class SequenceOfAndSetOfBase(base.AbstractConstructedAsn1Item):
if len(self._componentValues) < idx:
raise error.PyAsn1Error('Component index out of range')
- if value is None or value is noValue:
+ if value is noValue or value is None:
if componentType is not None:
value = componentType.clone()
elif currentValue is None:
@@ -2099,11 +1960,8 @@ class SequenceAndSetBase(base.AbstractConstructedAsn1Item):
#: object representing named ASN.1 types allowed within |ASN.1| type
componentType = namedtype.NamedTypes()
- def __init__(self, componentType=None, tagSet=None,
- subtypeSpec=None, sizeSpec=None):
- base.AbstractConstructedAsn1Item.__init__(
- self, componentType, tagSet, subtypeSpec, sizeSpec
- )
+ def __init__(self, **kwargs):
+ base.AbstractConstructedAsn1Item.__init__(self, **kwargs)
self._componentTypeLen = len(self.componentType)
def __getitem__(self, idx):