Skip to content

Commit 727d420

Browse files
committed
fix decoding of variant containing a Null array of of a type that cannot be null
1 parent d634f46 commit 727d420

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

opcua/ua/uatypes.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -742,24 +742,34 @@ class Variant(FrozenClass):
742742
:vartype Value: Any supported type
743743
:ivar VariantType:
744744
:vartype VariantType: VariantType
745+
:ivar Dimension:
746+
:vartype Dimensions: The length of each dimensions. Usually guessed from value.
747+
:ivar is_array:
748+
:vartype is_array: If the variant is an array. Usually guessed from value.
745749
"""
746750

747-
def __init__(self, value=None, varianttype=None, dimensions=None):
751+
def __init__(self, value=None, varianttype=None, dimensions=None, is_array=None):
748752
self.Value = value
749753
self.VariantType = varianttype
750754
self.Dimensions = dimensions
755+
self.is_array = is_array
756+
if self.is_array is None:
757+
if isinstance(value, (list, tuple)):
758+
self.is_array = True
759+
else:
760+
self.is_array = False
751761
self._freeze = True
752762
if isinstance(value, Variant):
753763
self.Value = value.Value
754764
self.VariantType = value.VariantType
755765
if self.VariantType is None:
756766
self.VariantType = self._guess_type(self.Value)
757-
if self.Value is None and self.VariantType not in (
767+
if self.Value is None and not self.is_array and self.VariantType not in (
758768
VariantType.Null,
759769
VariantType.String,
760770
VariantType.DateTime):
761-
raise UaError("Variant of type {0} cannot have value None".format(self.VariantType))
762-
if self.Dimensions is None and type(self.Value) in (list, tuple):
771+
raise UaError("Non array Variant of type {0} cannot have value None".format(self.VariantType))
772+
if self.Dimensions is None and isinstance(self.Value, (list, tuple)):
763773
dims = get_shape(self.Value)
764774
if len(dims) > 1:
765775
self.Dimensions = dims
@@ -828,20 +838,21 @@ def to_binary(self):
828838
@staticmethod
829839
def from_binary(data):
830840
dimensions = None
841+
array = False
831842
encoding = ord(data.read(1))
832843
int_type = encoding & 0b00111111
833844
vtype = datatype_to_varianttype(int_type)
834845
if vtype == VariantType.Null:
835846
return Variant(None, vtype, encoding)
836847
if uabin.test_bit(encoding, 7):
837848
value = uabin.unpack_uatype_array(vtype, data)
849+
array = True
838850
else:
839851
value = uabin.unpack_uatype(vtype, data)
840852
if uabin.test_bit(encoding, 6):
841853
dimensions = uabin.unpack_uatype_array(VariantType.Int32, data)
842854
value = reshape(value, dimensions)
843-
844-
return Variant(value, vtype, dimensions)
855+
return Variant(value, vtype, dimensions, is_array=array)
845856

846857

847858
def reshape(flat, dims):

0 commit comments

Comments
 (0)