Merge pull request #20 from emmanvg/master
Instantiate ImmutableError, more descriptive message. Check the attribute being requested actually exists in object. Fix being able to set certain empty values like: list, strings, False, etc.stix2.1
commit
35e973243f
|
@ -69,22 +69,19 @@ class _STIXBase(collections.Mapping):
|
|||
if list_of_properties and (not list_of_properties_populated or list_of_properties_populated == set(["extensions"])):
|
||||
raise AtLeastOnePropertyError(self.__class__, list_of_properties)
|
||||
|
||||
def _check_properties_dependency(self, list_of_properties, list_of_dependent_properties, values=[]):
|
||||
def _check_properties_dependency(self, list_of_properties, list_of_dependent_properties):
|
||||
failed_dependency_pairs = []
|
||||
current_properties = self.properties_populated()
|
||||
for p in list_of_properties:
|
||||
v = values.pop() if values else None
|
||||
for dp in list_of_dependent_properties:
|
||||
if dp in current_properties and (p not in current_properties or (v and not current_properties(p) == v)):
|
||||
if not self.__getattr__(p) and self.__getattr__(dp):
|
||||
failed_dependency_pairs.append((p, dp))
|
||||
if failed_dependency_pairs:
|
||||
raise DependentPropertiesError(self.__class__, failed_dependency_pairs)
|
||||
|
||||
def _check_object_constraints(self):
|
||||
if self.granular_markings:
|
||||
for m in self.granular_markings:
|
||||
# TODO: check selectors
|
||||
pass
|
||||
for m in self.get("granular_markings", []):
|
||||
# TODO: check selectors
|
||||
pass
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
cls = self.__class__
|
||||
|
@ -100,7 +97,7 @@ class _STIXBase(collections.Mapping):
|
|||
# Remove any keyword arguments whose value is None
|
||||
setting_kwargs = {}
|
||||
for prop_name, prop_value in kwargs.items():
|
||||
if prop_value:
|
||||
if prop_value is not None:
|
||||
setting_kwargs[prop_name] = prop_value
|
||||
|
||||
# Detect any missing required properties
|
||||
|
@ -127,11 +124,20 @@ class _STIXBase(collections.Mapping):
|
|||
|
||||
# Handle attribute access just like key access
|
||||
def __getattr__(self, name):
|
||||
return self.get(name)
|
||||
try:
|
||||
# Return attribute value.
|
||||
return self.__getitem__(name)
|
||||
except KeyError:
|
||||
# If attribute not found, check if its a property of the object.
|
||||
if name in self._properties:
|
||||
return None
|
||||
|
||||
raise AttributeError("'%s' object has no attribute '%s'" %
|
||||
(self.__class__.__name__, name))
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
if name != '_inner' and not name.startswith("_STIXBase__"):
|
||||
raise ImmutableError
|
||||
raise ImmutableError(self.__class__, name)
|
||||
super(_STIXBase, self).__setattr__(name, value)
|
||||
|
||||
def __str__(self):
|
||||
|
|
|
@ -47,8 +47,14 @@ class ExtraPropertiesError(STIXError, TypeError):
|
|||
class ImmutableError(STIXError, ValueError):
|
||||
"""Attempted to modify an object after creation"""
|
||||
|
||||
def __init__(self):
|
||||
super(ImmutableError, self).__init__("Cannot modify properties after creation.")
|
||||
def __init__(self, cls, key):
|
||||
super(ImmutableError, self).__init__()
|
||||
self.cls = cls
|
||||
self.key = key
|
||||
|
||||
def __str__(self):
|
||||
msg = "Cannot modify '{0.key}' property in '{0.cls.__name__}' after creation."
|
||||
return msg.format(self)
|
||||
|
||||
|
||||
class DictionaryKeyError(STIXError, ValueError):
|
||||
|
|
|
@ -129,7 +129,7 @@ def test_cannot_assign_to_indicator_attributes(indicator):
|
|||
with pytest.raises(stix2.exceptions.ImmutableError) as excinfo:
|
||||
indicator.valid_from = dt.datetime.now()
|
||||
|
||||
assert str(excinfo.value) == "Cannot modify properties after creation."
|
||||
assert str(excinfo.value) == "Cannot modify 'valid_from' property in 'Indicator' after creation."
|
||||
|
||||
|
||||
def test_invalid_kwarg_to_indicator():
|
||||
|
|
|
@ -92,7 +92,7 @@ def test_cannot_assign_to_malware_attributes(malware):
|
|||
with pytest.raises(stix2.exceptions.ImmutableError) as excinfo:
|
||||
malware.name = "Cryptolocker II"
|
||||
|
||||
assert str(excinfo.value) == "Cannot modify properties after creation."
|
||||
assert str(excinfo.value) == "Cannot modify 'name' property in 'Malware' after creation."
|
||||
|
||||
|
||||
def test_invalid_kwarg_to_malware():
|
||||
|
|
|
@ -764,8 +764,7 @@ def test_file_example_encryption_error():
|
|||
with pytest.raises(stix2.exceptions.DependentPropertiesError) as excinfo:
|
||||
stix2.File(name="qwerty.dll",
|
||||
is_encrypted=False,
|
||||
encryption_algorithm="AES128-CBC"
|
||||
)
|
||||
encryption_algorithm="AES128-CBC")
|
||||
|
||||
assert excinfo.value.cls == stix2.File
|
||||
assert excinfo.value.dependencies == [("is_encrypted", "encryption_algorithm")]
|
||||
|
|
|
@ -103,7 +103,7 @@ def test_cannot_assign_to_relationship_attributes(relationship):
|
|||
with pytest.raises(stix2.exceptions.ImmutableError) as excinfo:
|
||||
relationship.relationship_type = "derived-from"
|
||||
|
||||
assert str(excinfo.value) == "Cannot modify properties after creation."
|
||||
assert str(excinfo.value) == "Cannot modify 'relationship_type' property in 'Relationship' after creation."
|
||||
|
||||
|
||||
def test_invalid_kwarg_to_relationship():
|
||||
|
|
Loading…
Reference in New Issue