mirror of
https://github.com/JoelBender/bacpypes
synced 2025-09-28 22:15:23 +08:00
synchronize fixes across source directories, remove flakes, decorate is_valid() as a class method and not a static method
This commit is contained in:
parent
6ecb67883d
commit
a7868cfc63
|
@ -201,7 +201,7 @@ class Sequence(object):
|
|||
else:
|
||||
if tag.tagClass != Tag.applicationTagClass or tag.tagNumber != element.klass._app_tag:
|
||||
if not element.optional:
|
||||
raise DecodingError("'%s' expected application tag %s" % (element.name, Tag._app_tag_name[element.klass._app_tag]))
|
||||
raise InvalidParameterDatatype("'%s' expected application tag %s" % (element.name, Tag._app_tag_name[element.klass._app_tag]))
|
||||
else:
|
||||
setattr(self, element.name, None)
|
||||
continue
|
||||
|
|
|
@ -6,7 +6,8 @@ Object
|
|||
|
||||
import sys
|
||||
|
||||
from .errors import ConfigurationError, ExecutionError
|
||||
from .errors import ConfigurationError, ExecutionError, \
|
||||
InvalidParameterDatatype
|
||||
from .debugging import function_debugging, ModuleLogger, Logging
|
||||
|
||||
from .primitivedata import Atomic, BitString, Boolean, CharacterString, Date, \
|
||||
|
@ -194,12 +195,21 @@ class Property(Logging):
|
|||
if not self.mutable:
|
||||
raise ExecutionError(errorClass='property', errorCode='writeAccessDenied')
|
||||
|
||||
# if it's atomic assume correct datatype
|
||||
if issubclass(self.datatype, Atomic):
|
||||
if _debug: Property._debug(" - property is atomic, assumed correct type")
|
||||
elif isinstance(value, self.datatype):
|
||||
if _debug: Property._debug(" - correct type")
|
||||
elif arrayIndex is not None:
|
||||
# if it's atomic, make sure it's valid
|
||||
if issubclass(self.datatype, Atomic):
|
||||
if _debug: Property._debug(" - property is atomic, checking value")
|
||||
if not self.datatype.is_valid(value):
|
||||
raise InvalidParameterDatatype("%s must be of type %s" % (
|
||||
self.identifier, self.datatype.__name__,
|
||||
))
|
||||
|
||||
elif not isinstance(value, self.datatype):
|
||||
if _debug: Property._debug(" - property is not atomic and wrong type")
|
||||
raise InvalidParameterDatatype("%s must be of type %s" % (
|
||||
self.identifier, self.datatype.__name__,
|
||||
))
|
||||
|
||||
if arrayIndex is not None:
|
||||
if not issubclass(self.datatype, Array):
|
||||
raise ExecutionError(errorClass='property', errorCode='propertyIsNotAnArray')
|
||||
|
||||
|
@ -213,10 +223,6 @@ class Property(Logging):
|
|||
arry[arrayIndex] = value
|
||||
|
||||
return
|
||||
elif value is not None:
|
||||
# coerce the value
|
||||
value = self.datatype(value)
|
||||
if _debug: Property._debug(" - coerced the value: %r", value)
|
||||
|
||||
# seems to be OK
|
||||
obj._values[self.identifier] = value
|
||||
|
@ -323,6 +329,8 @@ class ObjectIdentifierProperty(ReadableProperty, Logging):
|
|||
|
||||
class Object(Logging):
|
||||
|
||||
_debug_contents = ('_app',)
|
||||
|
||||
properties = \
|
||||
[ ObjectIdentifierProperty('objectIdentifier', ObjectIdentifier, optional=False)
|
||||
, ReadableProperty('objectName', CharacterString, optional=False)
|
||||
|
@ -393,8 +401,6 @@ class Object(Logging):
|
|||
|
||||
# get the property
|
||||
prop = self._properties.get(attr)
|
||||
if _debug: Object._debug(" - prop: %r", prop)
|
||||
|
||||
if not prop:
|
||||
raise PropertyError(attr)
|
||||
|
||||
|
@ -472,30 +478,26 @@ class Object(Logging):
|
|||
klasses = list(self.__class__.__mro__)
|
||||
klasses.reverse()
|
||||
|
||||
# print special attributes "bottom up"
|
||||
previous_attrs = ()
|
||||
for c in klasses:
|
||||
attrs = getattr(c, '_debug_contents', ())
|
||||
|
||||
# if we have seen this list already, move to the next class
|
||||
if attrs is previous_attrs:
|
||||
continue
|
||||
|
||||
for attr in attrs:
|
||||
file.write("%s%s = %s\n" % (" " * indent, attr, getattr(self, attr)))
|
||||
previous_attrs = attrs
|
||||
|
||||
# build a list of properties "bottom up"
|
||||
properties = []
|
||||
for c in klasses:
|
||||
properties.extend(getattr(c, 'properties', []))
|
||||
|
||||
# print out the values
|
||||
properties_seen = set()
|
||||
for prop in properties:
|
||||
# see if we've seen something with this name
|
||||
if prop.identifier in properties_seen:
|
||||
continue
|
||||
else:
|
||||
properties_seen.add(prop.identifier)
|
||||
|
||||
# get the value
|
||||
value = prop.ReadProperty(self)
|
||||
if value is None:
|
||||
continue
|
||||
|
||||
# if the value has a way to convert it to a dict, use it
|
||||
if hasattr(value, "dict_contents"):
|
||||
value = value.dict_contents(as_class=as_class)
|
||||
|
||||
|
@ -510,24 +512,40 @@ class Object(Logging):
|
|||
klasses = list(self.__class__.__mro__)
|
||||
klasses.reverse()
|
||||
|
||||
# build a list of properties "bottom up"
|
||||
properties = []
|
||||
# print special attributes "bottom up"
|
||||
previous_attrs = ()
|
||||
for c in klasses:
|
||||
properties.extend(getattr(c, 'properties', []))
|
||||
attrs = getattr(c, '_debug_contents', ())
|
||||
|
||||
# print out the values
|
||||
for prop in properties:
|
||||
value = prop.ReadProperty(self)
|
||||
|
||||
# printing out property values that are None is tedious
|
||||
if value is None:
|
||||
# if we have seen this list already, move to the next class
|
||||
if attrs is previous_attrs:
|
||||
continue
|
||||
|
||||
if hasattr(value, "debug_contents"):
|
||||
file.write("%s%s\n" % (" " * indent, prop.identifier))
|
||||
value.debug_contents(indent+1, file, _ids)
|
||||
for attr in attrs:
|
||||
file.write("%s%s = %s\n" % (" " * indent, attr, getattr(self, attr)))
|
||||
previous_attrs = attrs
|
||||
|
||||
# build a list of properties "bottom up"
|
||||
property_names = []
|
||||
for c in klasses:
|
||||
properties = getattr(c, 'properties', [])
|
||||
for property in properties:
|
||||
if property.identifier not in property_names:
|
||||
property_names.append(property.identifier)
|
||||
|
||||
# print out the values
|
||||
for property_name in property_names:
|
||||
property_value = self._values.get(property_name, None)
|
||||
|
||||
# printing out property values that are None is tedious
|
||||
if property_value is None:
|
||||
continue
|
||||
|
||||
if hasattr(property_value, "debug_contents"):
|
||||
file.write("%s%s\n" % (" " * indent, property_name))
|
||||
property_value.debug_contents(indent+1, file, _ids)
|
||||
else:
|
||||
file.write("%s%s = %r\n" % (" " * indent, prop.identifier, value))
|
||||
file.write("%s%s = %r\n" % (" " * indent, property_name, property_value))
|
||||
|
||||
#
|
||||
# Standard Object Types
|
||||
|
|
|
@ -11,7 +11,7 @@ import re
|
|||
|
||||
from .debugging import ModuleLogger, btox
|
||||
|
||||
from .errors import DecodingError, InvalidTag
|
||||
from .errors import DecodingError, InvalidTag, InvalidParameterDatatype
|
||||
from .pdu import PDUData
|
||||
|
||||
# some debugging
|
||||
|
@ -469,8 +469,8 @@ class Atomic(object):
|
|||
except (ValueError, TypeError):
|
||||
raise InvalidParameterDatatype("%s coerce error" % (cls.__name__,))
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
raise NotImplementedError("call on a derived class of Atomic")
|
||||
|
||||
|
@ -508,8 +508,8 @@ class Null(Atomic):
|
|||
|
||||
self.value = ()
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return arg is None
|
||||
|
||||
|
@ -554,8 +554,8 @@ class Boolean(Atomic):
|
|||
# get the data
|
||||
self.value = bool(tag.tagLVT)
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, bool)
|
||||
|
||||
|
@ -615,8 +615,8 @@ class Unsigned(Atomic):
|
|||
# save the result
|
||||
self.value = rslt
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, (int, long)) and (arg >= 0)
|
||||
|
||||
|
@ -690,8 +690,8 @@ class Integer(Atomic):
|
|||
# save the result
|
||||
self.value = rslt
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, (int, long))
|
||||
|
||||
|
@ -735,8 +735,8 @@ class Real(Atomic):
|
|||
# extract the data
|
||||
self.value = struct.unpack('>f',tag.tagData)[0]
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, float)
|
||||
|
||||
|
@ -780,8 +780,8 @@ class Double(Atomic):
|
|||
# extract the data
|
||||
self.value = struct.unpack('>d',tag.tagData)[0]
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, float)
|
||||
|
||||
|
@ -820,8 +820,8 @@ class OctetString(Atomic):
|
|||
|
||||
self.value = tag.tagData
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, str)
|
||||
|
||||
|
@ -886,8 +886,8 @@ class CharacterString(Atomic):
|
|||
else:
|
||||
self.value = '### unknown encoding: %d ###' % (self.strEncoding,)
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, (str, unicode))
|
||||
|
||||
|
@ -977,14 +977,14 @@ class BitString(Atomic):
|
|||
else:
|
||||
self.value = data
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
if isinstance(arg, list):
|
||||
allInts = allStrings = True
|
||||
for elem in arg:
|
||||
allInts = allInts and ((elem == 0) or (elem == 1))
|
||||
allStrings = allStrings and elem in self.bitNames
|
||||
allStrings = allStrings and elem in cls.bitNames
|
||||
|
||||
if allInts or allStrings:
|
||||
return True
|
||||
|
@ -1164,8 +1164,8 @@ class Enumerated(Atomic):
|
|||
# save the result
|
||||
self.value = rslt
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class. If the string
|
||||
value is wrong for the enumeration, the encoding will fail.
|
||||
"""
|
||||
|
@ -1384,8 +1384,8 @@ class Date(Atomic):
|
|||
# rip apart the data
|
||||
self.value = tuple(ord(c) for c in tag.tagData)
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, tuple) and (len(arg) == 4)
|
||||
|
||||
|
@ -1476,8 +1476,8 @@ class Time(Atomic):
|
|||
# rip apart the data
|
||||
self.value = tuple(ord(c) for c in tag.tagData)
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, tuple) and (len(arg) == 4)
|
||||
|
||||
|
@ -1671,8 +1671,8 @@ class ObjectIdentifier(Atomic):
|
|||
# extract the data
|
||||
self.set_long(struct.unpack('>L',tag.tagData)[0])
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, tuple) and (len(arg) == 2)
|
||||
|
||||
|
|
|
@ -195,7 +195,7 @@ class Property(Logging):
|
|||
if not self.mutable:
|
||||
raise ExecutionError(errorClass='property', errorCode='writeAccessDenied')
|
||||
|
||||
# if it's atomic assume correct datatype
|
||||
# if it's atomic, make sure it's valid
|
||||
if issubclass(self.datatype, Atomic):
|
||||
if _debug: Property._debug(" - property is atomic, checking value")
|
||||
if not self.datatype.is_valid(value):
|
||||
|
@ -438,8 +438,6 @@ class Object(Logging):
|
|||
|
||||
# get the property
|
||||
prop = self._properties.get(propid)
|
||||
if _debug: Object._debug(" - prop: %r", prop)
|
||||
|
||||
if not prop:
|
||||
raise PropertyError(propid)
|
||||
|
||||
|
@ -451,8 +449,6 @@ class Object(Logging):
|
|||
|
||||
# get the property
|
||||
prop = self._properties.get(propid)
|
||||
if _debug: Object._debug(" - prop: %r", prop)
|
||||
|
||||
if not prop:
|
||||
raise PropertyError(propid)
|
||||
|
||||
|
@ -488,11 +484,20 @@ class Object(Logging):
|
|||
properties.extend(getattr(c, 'properties', []))
|
||||
|
||||
# print out the values
|
||||
properties_seen = set()
|
||||
for prop in properties:
|
||||
# see if we've seen something with this name
|
||||
if prop.identifier in properties_seen:
|
||||
continue
|
||||
else:
|
||||
properties_seen.add(prop.identifier)
|
||||
|
||||
# get the value
|
||||
value = prop.ReadProperty(self)
|
||||
if value is None:
|
||||
continue
|
||||
|
||||
# if the value has a way to convert it to a dict, use it
|
||||
if hasattr(value, "dict_contents"):
|
||||
value = value.dict_contents(as_class=as_class)
|
||||
|
||||
|
|
|
@ -473,8 +473,8 @@ class Atomic(object):
|
|||
except (ValueError, TypeError):
|
||||
raise InvalidParameterDatatype("%s coerce error" % (cls.__name__,))
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
raise NotImplementedError("call on a derived class of Atomic")
|
||||
|
||||
|
@ -512,8 +512,8 @@ class Null(Atomic):
|
|||
|
||||
self.value = ()
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return arg is None
|
||||
|
||||
|
@ -558,8 +558,8 @@ class Boolean(Atomic):
|
|||
# get the data
|
||||
self.value = bool(tag.tagLVT)
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, bool)
|
||||
|
||||
|
@ -619,8 +619,8 @@ class Unsigned(Atomic):
|
|||
# save the result
|
||||
self.value = rslt
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, (int, long)) and (arg >= 0)
|
||||
|
||||
|
@ -694,8 +694,8 @@ class Integer(Atomic):
|
|||
# save the result
|
||||
self.value = rslt
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, (int, long))
|
||||
|
||||
|
@ -739,8 +739,8 @@ class Real(Atomic):
|
|||
# extract the data
|
||||
self.value = struct.unpack('>f',tag.tagData)[0]
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, float)
|
||||
|
||||
|
@ -784,8 +784,8 @@ class Double(Atomic):
|
|||
# extract the data
|
||||
self.value = struct.unpack('>d',tag.tagData)[0]
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, float)
|
||||
|
||||
|
@ -824,8 +824,8 @@ class OctetString(Atomic):
|
|||
|
||||
self.value = tag.tagData
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, (bytes, bytearray))
|
||||
|
||||
|
@ -891,8 +891,8 @@ class CharacterString(Atomic):
|
|||
else:
|
||||
self.value = '### unknown encoding: %d ###' % (self.strEncoding,)
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, (str, unicode))
|
||||
|
||||
|
@ -982,14 +982,14 @@ class BitString(Atomic):
|
|||
else:
|
||||
self.value = data
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
if isinstance(arg, list):
|
||||
allInts = allStrings = True
|
||||
for elem in arg:
|
||||
allInts = allInts and ((elem == 0) or (elem == 1))
|
||||
allStrings = allStrings and elem in self.bitNames
|
||||
allStrings = allStrings and elem in cls.bitNames
|
||||
|
||||
if allInts or allStrings:
|
||||
return True
|
||||
|
@ -1169,8 +1169,8 @@ class Enumerated(Atomic):
|
|||
# save the result
|
||||
self.value = rslt
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class. If the string
|
||||
value is wrong for the enumeration, the encoding will fail.
|
||||
"""
|
||||
|
@ -1390,8 +1390,8 @@ class Date(Atomic):
|
|||
# rip apart the data
|
||||
self.value = tuple(ord(c) for c in tag.tagData)
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, tuple) and (len(arg) == 4)
|
||||
|
||||
|
@ -1482,8 +1482,8 @@ class Time(Atomic):
|
|||
# rip apart the data
|
||||
self.value = tuple(ord(c) for c in tag.tagData)
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, tuple) and (len(arg) == 4)
|
||||
|
||||
|
@ -1677,8 +1677,8 @@ class ObjectIdentifier(Atomic):
|
|||
# extract the data
|
||||
self.set_long(struct.unpack('>L',tag.tagData)[0])
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, tuple) and (len(arg) == 2)
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@ Object
|
|||
|
||||
import sys
|
||||
|
||||
from .errors import ConfigurationError, ExecutionError
|
||||
from .errors import ConfigurationError, ExecutionError, \
|
||||
InvalidParameterDatatype
|
||||
from .debugging import function_debugging, ModuleLogger, Logging
|
||||
|
||||
from .primitivedata import Atomic, BitString, Boolean, CharacterString, Date, \
|
||||
|
@ -194,12 +195,21 @@ class Property(Logging):
|
|||
if not self.mutable:
|
||||
raise ExecutionError(errorClass='property', errorCode='writeAccessDenied')
|
||||
|
||||
# if it's atomic assume correct datatype
|
||||
#if issubclass(self.datatype, Atomic):
|
||||
# if _debug: Property._debug(" - property is atomic, assumed correct type")
|
||||
if isinstance(value, self.datatype):
|
||||
if _debug: Property._debug(" - correct type")
|
||||
elif arrayIndex is not None:
|
||||
# if it's atomic, make sure it's valid
|
||||
if issubclass(self.datatype, Atomic):
|
||||
if _debug: Property._debug(" - property is atomic, checking value")
|
||||
if not self.datatype.is_valid(value):
|
||||
raise InvalidParameterDatatype("%s must be of type %s" % (
|
||||
self.identifier, self.datatype.__name__,
|
||||
))
|
||||
|
||||
elif not isinstance(value, self.datatype):
|
||||
if _debug: Property._debug(" - property is not atomic and wrong type")
|
||||
raise InvalidParameterDatatype("%s must be of type %s" % (
|
||||
self.identifier, self.datatype.__name__,
|
||||
))
|
||||
|
||||
if arrayIndex is not None:
|
||||
if not issubclass(self.datatype, Array):
|
||||
raise ExecutionError(errorClass='property', errorCode='propertyIsNotAnArray')
|
||||
|
||||
|
@ -213,10 +223,6 @@ class Property(Logging):
|
|||
arry[arrayIndex] = value
|
||||
|
||||
return
|
||||
elif value is not None:
|
||||
# coerce the value
|
||||
value = self.datatype(value)
|
||||
if _debug: Property._debug(" - coerced the value: %r", value)
|
||||
|
||||
# seems to be OK
|
||||
obj._values[self.identifier] = value
|
||||
|
@ -323,6 +329,8 @@ class ObjectIdentifierProperty(ReadableProperty, Logging):
|
|||
|
||||
class Object(Logging):
|
||||
|
||||
_debug_contents = ('_app',)
|
||||
|
||||
properties = \
|
||||
[ ObjectIdentifierProperty('objectIdentifier', ObjectIdentifier, optional=False)
|
||||
, ReadableProperty('objectName', CharacterString, optional=False)
|
||||
|
@ -393,8 +401,6 @@ class Object(Logging):
|
|||
|
||||
# get the property
|
||||
prop = self._properties.get(attr)
|
||||
if _debug: Object._debug(" - prop: %r", prop)
|
||||
|
||||
if not prop:
|
||||
raise PropertyError(attr)
|
||||
|
||||
|
@ -472,30 +478,26 @@ class Object(Logging):
|
|||
klasses = list(self.__class__.__mro__)
|
||||
klasses.reverse()
|
||||
|
||||
# print special attributes "bottom up"
|
||||
previous_attrs = ()
|
||||
for c in klasses:
|
||||
attrs = getattr(c, '_debug_contents', ())
|
||||
|
||||
# if we have seen this list already, move to the next class
|
||||
if attrs is previous_attrs:
|
||||
continue
|
||||
|
||||
for attr in attrs:
|
||||
file.write("%s%s = %s\n" % (" " * indent, attr, getattr(self, attr)))
|
||||
previous_attrs = attrs
|
||||
|
||||
# build a list of properties "bottom up"
|
||||
properties = []
|
||||
for c in klasses:
|
||||
properties.extend(getattr(c, 'properties', []))
|
||||
|
||||
# print out the values
|
||||
properties_seen = set()
|
||||
for prop in properties:
|
||||
# see if we've seen something with this name
|
||||
if prop.identifier in properties_seen:
|
||||
continue
|
||||
else:
|
||||
properties_seen.add(prop.identifier)
|
||||
|
||||
# get the value
|
||||
value = prop.ReadProperty(self)
|
||||
if value is None:
|
||||
continue
|
||||
|
||||
# if the value has a way to convert it to a dict, use it
|
||||
if hasattr(value, "dict_contents"):
|
||||
value = value.dict_contents(as_class=as_class)
|
||||
|
||||
|
@ -510,24 +512,40 @@ class Object(Logging):
|
|||
klasses = list(self.__class__.__mro__)
|
||||
klasses.reverse()
|
||||
|
||||
# build a list of properties "bottom up"
|
||||
properties = []
|
||||
# print special attributes "bottom up"
|
||||
previous_attrs = ()
|
||||
for c in klasses:
|
||||
properties.extend(getattr(c, 'properties', []))
|
||||
attrs = getattr(c, '_debug_contents', ())
|
||||
|
||||
# print out the values
|
||||
for prop in properties:
|
||||
value = prop.ReadProperty(self)
|
||||
|
||||
# printing out property values that are None is tedious
|
||||
if value is None:
|
||||
# if we have seen this list already, move to the next class
|
||||
if attrs is previous_attrs:
|
||||
continue
|
||||
|
||||
if hasattr(value, "debug_contents"):
|
||||
file.write("%s%s\n" % (" " * indent, prop.identifier))
|
||||
value.debug_contents(indent+1, file, _ids)
|
||||
for attr in attrs:
|
||||
file.write("%s%s = %s\n" % (" " * indent, attr, getattr(self, attr)))
|
||||
previous_attrs = attrs
|
||||
|
||||
# build a list of properties "bottom up"
|
||||
property_names = []
|
||||
for c in klasses:
|
||||
properties = getattr(c, 'properties', [])
|
||||
for property in properties:
|
||||
if property.identifier not in property_names:
|
||||
property_names.append(property.identifier)
|
||||
|
||||
# print out the values
|
||||
for property_name in property_names:
|
||||
property_value = self._values.get(property_name, None)
|
||||
|
||||
# printing out property values that are None is tedious
|
||||
if property_value is None:
|
||||
continue
|
||||
|
||||
if hasattr(property_value, "debug_contents"):
|
||||
file.write("%s%s\n" % (" " * indent, property_name))
|
||||
property_value.debug_contents(indent+1, file, _ids)
|
||||
else:
|
||||
file.write("%s%s = %r\n" % (" " * indent, prop.identifier, value))
|
||||
file.write("%s%s = %r\n" % (" " * indent, property_name, property_value))
|
||||
|
||||
#
|
||||
# Standard Object Types
|
||||
|
@ -1032,6 +1050,12 @@ class BitStringValueObject(Object):
|
|||
, OptionalProperty('notifyType', NotifyType)
|
||||
, OptionalProperty('eventTimeStamps', ArrayOf(TimeStamp))
|
||||
, OptionalProperty('eventMessageTexts', ArrayOf(CharacterString))
|
||||
, OptionalProperty('eventMessageTextsConfig', ArrayOf(CharacterString))
|
||||
, OptionalProperty('eventDetectionEnable', Boolean)
|
||||
, OptionalProperty('eventAlgorithmInhibitRef', ObjectPropertyReference)
|
||||
, OptionalProperty('eventAlgorithmInhibit', Boolean)
|
||||
, OptionalProperty('timeDelayNormal', Unsigned)
|
||||
, OptionalProperty('reliabilityEvaluationInhibit', Boolean)
|
||||
]
|
||||
|
||||
@register_object_type
|
||||
|
@ -1117,7 +1141,7 @@ class CredentialDataInputObject(Object):
|
|||
, OptionalProperty('reliability', Reliability)
|
||||
, ReadableProperty('outOfService', Boolean)
|
||||
, ReadableProperty('supportedFormats', ArrayOf(AuthenticationFactorFormat))
|
||||
, ReadableProperty('supportedFormatClasses', ArrayOf(Unsigned))
|
||||
, OptionalProperty('supportedFormatClasses', ArrayOf(Unsigned))
|
||||
, ReadableProperty('updateTime', TimeStamp)
|
||||
, OptionalProperty('eventDetectionEnable', Boolean)
|
||||
, OptionalProperty('notificationClass', Unsigned)
|
||||
|
|
|
@ -11,7 +11,7 @@ import re
|
|||
|
||||
from .debugging import ModuleLogger, btox
|
||||
|
||||
from .errors import DecodingError, InvalidTag
|
||||
from .errors import DecodingError, InvalidTag, InvalidParameterDatatype
|
||||
from .pdu import PDUData
|
||||
|
||||
# some debugging
|
||||
|
@ -495,8 +495,8 @@ class Atomic(object):
|
|||
except (ValueError, TypeError):
|
||||
raise InvalidParameterDatatype("%s coerce error" % (cls.__name__,))
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
raise NotImplementedError("call on a derived class of Atomic")
|
||||
|
||||
|
@ -534,8 +534,8 @@ class Null(Atomic):
|
|||
|
||||
self.value = ()
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return arg is None
|
||||
|
||||
|
@ -580,8 +580,8 @@ class Boolean(Atomic):
|
|||
# get the data
|
||||
self.value = bool(tag.tagLVT)
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, bool)
|
||||
|
||||
|
@ -637,8 +637,8 @@ class Unsigned(Atomic):
|
|||
# save the result
|
||||
self.value = rslt
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, (int, long)) and (arg >= 0)
|
||||
|
||||
|
@ -710,8 +710,8 @@ class Integer(Atomic):
|
|||
# save the result
|
||||
self.value = rslt
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, int)
|
||||
|
||||
|
@ -755,8 +755,8 @@ class Real(Atomic):
|
|||
# extract the data
|
||||
self.value = struct.unpack('>f',tag.tagData)[0]
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, float)
|
||||
|
||||
|
@ -800,8 +800,8 @@ class Double(Atomic):
|
|||
# extract the data
|
||||
self.value = struct.unpack('>d',tag.tagData)[0]
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, float)
|
||||
|
||||
|
@ -840,8 +840,8 @@ class OctetString(Atomic):
|
|||
|
||||
self.value = tag.tagData
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, (bytes, bytearray))
|
||||
|
||||
|
@ -904,8 +904,8 @@ class CharacterString(Atomic):
|
|||
else:
|
||||
self.value = '### unknown encoding: %d ###' % (self.strEncoding,)
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, str)
|
||||
|
||||
|
@ -995,14 +995,14 @@ class BitString(Atomic):
|
|||
else:
|
||||
self.value = data
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
if isinstance(arg, list):
|
||||
allInts = allStrings = True
|
||||
for elem in arg:
|
||||
allInts = allInts and ((elem == 0) or (elem == 1))
|
||||
allStrings = allStrings and elem in self.bitNames
|
||||
allStrings = allStrings and elem in cls.bitNames
|
||||
|
||||
if allInts or allStrings:
|
||||
return True
|
||||
|
@ -1180,8 +1180,8 @@ class Enumerated(Atomic):
|
|||
# save the result
|
||||
self.value = rslt
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class. If the string
|
||||
value is wrong for the enumeration, the encoding will fail.
|
||||
"""
|
||||
|
@ -1398,8 +1398,8 @@ class Date(Atomic):
|
|||
# rip apart the data
|
||||
self.value = tuple(tag.tagData)
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, tuple) and (len(arg) == 4)
|
||||
|
||||
|
@ -1490,8 +1490,8 @@ class Time(Atomic):
|
|||
# rip apart the data
|
||||
self.value = tuple(tag.tagData)
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, tuple) and (len(arg) == 4)
|
||||
|
||||
|
@ -1679,8 +1679,8 @@ class ObjectIdentifier(Atomic):
|
|||
# extract the data
|
||||
self.set_long(struct.unpack('>L',tag.tagData)[0])
|
||||
|
||||
@staticmethod
|
||||
def is_valid(arg):
|
||||
@classmethod
|
||||
def is_valid(cls, arg):
|
||||
"""Return True if arg is valid value for the class."""
|
||||
return isinstance(arg, tuple) and (len(arg) == 2)
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user