Replace 'field' with 'property' to be consistent

with the specification
stix2.1
clenk 2017-05-16 12:27:30 -04:00
parent a520a67511
commit 9761c37f20
12 changed files with 64 additions and 64 deletions

View File

@ -123,7 +123,7 @@ def parse_observable(data, _valid_refs):
obj['_valid_refs'] = _valid_refs
if 'type' not in obj:
raise ValueError("'type' is a required field!")
raise ValueError("'type' is a required property!")
try:
obj_class = OBJ_MAP_OBSERVABLE[obj['type']]
except KeyError:

View File

@ -12,7 +12,7 @@ from .utils import NOW, format_datetime, get_timestamp, parse_into_datetime
__all__ = ['STIXJSONEncoder', '_STIXBase']
DEFAULT_ERROR = "{type} must have {field}='{expected}'."
DEFAULT_ERROR = "{type} must have {property}='{expected}'."
class STIXJSONEncoder(json.JSONEncoder):
@ -95,9 +95,9 @@ class _STIXBase(collections.Mapping):
if prop_value:
setting_kwargs[prop_name] = prop_value
# Detect any missing required fields
required_fields = get_required_properties(cls._properties)
missing_kwargs = set(required_fields) - set(setting_kwargs)
# Detect any missing required properties
required_properties = get_required_properties(cls._properties)
missing_kwargs = set(required_properties) - set(setting_kwargs)
if missing_kwargs:
raise MissingFieldsError(cls, missing_kwargs)

View File

@ -17,31 +17,31 @@ class InvalidValueError(STIXError, ValueError):
class MissingFieldsError(STIXError, ValueError):
"""Missing required field(s) when constructing STIX object."""
"""Missing one or more required properties when constructing STIX object."""
def __init__(self, cls, fields):
def __init__(self, cls, properties):
super(MissingFieldsError, self).__init__()
self.cls = cls
self.fields = sorted(list(fields))
self.properties = sorted(list(properties))
def __str__(self):
msg = "No values for required field(s) for {0}: ({1})."
msg = "No values for required properties for {0}: ({1})."
return msg.format(self.cls.__name__,
", ".join(x for x in self.fields))
", ".join(x for x in self.properties))
class ExtraFieldsError(STIXError, TypeError):
"""Extra field(s) were provided when constructing STIX object."""
"""One or more extra properties were provided when constructing STIX object."""
def __init__(self, cls, fields):
def __init__(self, cls, properties):
super(ExtraFieldsError, self).__init__()
self.cls = cls
self.fields = sorted(list(fields))
self.properties = sorted(list(properties))
def __str__(self):
msg = "Unexpected field(s) for {0}: ({1})."
msg = "Unexpected properties for {0}: ({1})."
return msg.format(self.cls.__name__,
", ".join(x for x in self.fields))
", ".join(x for x in self.properties))
class ImmutableError(STIXError, ValueError):
@ -93,15 +93,15 @@ class UnmodifiablePropertyError(STIXError, ValueError):
class MutuallyExclusivePropertiesError(STIXError, TypeError):
"""Violating interproperty mutually exclusive constraint of a STIX object type."""
def __init__(self, cls, fields):
def __init__(self, cls, properties):
super(MutuallyExclusivePropertiesError, self).__init__()
self.cls = cls
self.fields = sorted(list(fields))
self.properties = sorted(list(properties))
def __str__(self):
msg = "The field(s) for {0}: ({1}) are mutually exclusive."
return msg.format(self.cls.__name__,
", ".join(x for x in self.fields))
", ".join(x for x in self.properties))
class DependentPropertiestError(STIXError, TypeError):
@ -121,15 +121,15 @@ class DependentPropertiestError(STIXError, TypeError):
class AtLeastOnePropertyError(STIXError, TypeError):
"""Violating a constraint of a STIX object type that at least one of the given properties must be populated."""
def __init__(self, cls, fields):
def __init__(self, cls, properties):
super(AtLeastOnePropertyError, self).__init__()
self.cls = cls
self.fields = sorted(list(fields))
self.properties = sorted(list(properties))
def __str__(self):
msg = "At least one of the field(s) for {0}: ({1}) must be populated."
return msg.format(self.cls.__name__,
", ".join(x for x in self.fields))
", ".join(x for x in self.properties))
class RevokeError(STIXError, ValueError):

View File

@ -45,7 +45,7 @@ class Property(object):
- provide a default value for this property.
- `default()` can return the special value `NOW` to use the current
time. This is useful when several timestamps in the same object need
to use the same default value, so calling now() for each field--
to use the same default value, so calling now() for each property--
likely several microseconds apart-- does not work.
Subclasses can instead provide a lambda function for `default` as a keyword
@ -53,7 +53,7 @@ class Property(object):
raise their own exceptions.
When instantiating Properties, `required` and `default` should not be used
together. `default` implies that the field is required in the specification
together. `default` implies that the property is required in the specification
so this function will be used to supply a value if none is provided.
`required` means that the user must provide this; it is required in the
specification and we can't or don't want to create a default value.

View File

@ -114,4 +114,4 @@ def test_external_reference_source_required():
stix2.ExternalReference()
assert excinfo.value.cls == stix2.ExternalReference
assert excinfo.value.fields == ["source_name"]
assert excinfo.value.properties == ["source_name"]

View File

@ -32,7 +32,7 @@ EXPECTED_INDICATOR_REPR = "Indicator(" + " ".join("""
""".split()) + ")"
def test_indicator_with_all_required_fields():
def test_indicator_with_all_required_properties():
now = dt.datetime(2017, 1, 1, 0, 0, 1, tzinfo=pytz.utc)
epoch = dt.datetime(1970, 1, 1, 0, 0, 1, tzinfo=pytz.utc)
@ -51,7 +51,7 @@ def test_indicator_with_all_required_fields():
assert rep == EXPECTED_INDICATOR_REPR
def test_indicator_autogenerated_fields(indicator):
def test_indicator_autogenerated_properties(indicator):
assert indicator.type == 'indicator'
assert indicator.id == 'indicator--00000000-0000-0000-0000-000000000001'
assert indicator.created == FAKE_TIME
@ -89,21 +89,21 @@ def test_indicator_id_must_start_with_indicator():
assert str(excinfo.value) == "Invalid value for Indicator 'id': must start with 'indicator--'."
def test_indicator_required_fields():
def test_indicator_required_properties():
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
stix2.Indicator()
assert excinfo.value.cls == stix2.Indicator
assert excinfo.value.fields == ["labels", "pattern"]
assert str(excinfo.value) == "No values for required field(s) for Indicator: (labels, pattern)."
assert excinfo.value.properties == ["labels", "pattern"]
assert str(excinfo.value) == "No values for required properties for Indicator: (labels, pattern)."
def test_indicator_required_field_pattern():
def test_indicator_required_property_pattern():
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
stix2.Indicator(labels=['malicious-activity'])
assert excinfo.value.cls == stix2.Indicator
assert excinfo.value.fields == ["pattern"]
assert excinfo.value.properties == ["pattern"]
def test_indicator_created_ref_invalid_format():
@ -137,8 +137,8 @@ def test_invalid_kwarg_to_indicator():
stix2.Indicator(my_custom_property="foo", **INDICATOR_KWARGS)
assert excinfo.value.cls == stix2.Indicator
assert excinfo.value.fields == ['my_custom_property']
assert str(excinfo.value) == "Unexpected field(s) for Indicator: (my_custom_property)."
assert excinfo.value.properties == ['my_custom_property']
assert str(excinfo.value) == "Unexpected properties for Indicator: (my_custom_property)."
def test_created_modified_time_are_identical_by_default():

View File

@ -35,28 +35,28 @@ def test_kill_chain_example():
assert str(preattack) == FOO_PRE_ATTACK
def test_kill_chain_required_fields():
def test_kill_chain_required_properties():
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
stix2.KillChainPhase()
assert excinfo.value.cls == stix2.KillChainPhase
assert excinfo.value.fields == ["kill_chain_name", "phase_name"]
assert excinfo.value.properties == ["kill_chain_name", "phase_name"]
def test_kill_chain_required_field_chain_name():
def test_kill_chain_required_property_chain_name():
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
stix2.KillChainPhase(phase_name="weaponization")
assert excinfo.value.cls == stix2.KillChainPhase
assert excinfo.value.fields == ["kill_chain_name"]
assert excinfo.value.properties == ["kill_chain_name"]
def test_kill_chain_required_field_phase_name():
def test_kill_chain_required_property_phase_name():
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
stix2.KillChainPhase(kill_chain_name="lockheed-martin-cyber-kill-chain")
assert excinfo.value.cls == stix2.KillChainPhase
assert excinfo.value.fields == ["phase_name"]
assert excinfo.value.properties == ["phase_name"]

View File

@ -21,7 +21,7 @@ EXPECTED_MALWARE = """{
}"""
def test_malware_with_all_required_fields():
def test_malware_with_all_required_properties():
now = dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
mal = stix2.Malware(
@ -36,7 +36,7 @@ def test_malware_with_all_required_fields():
assert str(mal) == EXPECTED_MALWARE
def test_malware_autogenerated_fields(malware):
def test_malware_autogenerated_properties(malware):
assert malware.type == 'malware'
assert malware.id == 'malware--00000000-0000-0000-0000-000000000001'
assert malware.created == FAKE_TIME
@ -72,20 +72,20 @@ def test_malware_id_must_start_with_malware():
assert str(excinfo.value) == "Invalid value for Malware 'id': must start with 'malware--'."
def test_malware_required_fields():
def test_malware_required_properties():
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
stix2.Malware()
assert excinfo.value.cls == stix2.Malware
assert excinfo.value.fields == ["labels", "name"]
assert excinfo.value.properties == ["labels", "name"]
def test_malware_required_field_name():
def test_malware_required_property_name():
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
stix2.Malware(labels=['ransomware'])
assert excinfo.value.cls == stix2.Malware
assert excinfo.value.fields == ["name"]
assert excinfo.value.properties == ["name"]
def test_cannot_assign_to_malware_attributes(malware):
@ -100,8 +100,8 @@ def test_invalid_kwarg_to_malware():
stix2.Malware(my_custom_property="foo", **MALWARE_KWARGS)
assert excinfo.value.cls == stix2.Malware
assert excinfo.value.fields == ['my_custom_property']
assert str(excinfo.value) == "Unexpected field(s) for Malware: (my_custom_property)."
assert excinfo.value.properties == ['my_custom_property']
assert str(excinfo.value) == "Unexpected properties for Malware: (my_custom_property)."
@pytest.mark.parametrize("data", [

View File

@ -369,7 +369,7 @@ def test_parse_email_message_with_at_least_one_error(data):
stix2.parse_observable(data, [str(i) for i in range(1, 6)])
assert excinfo.value.cls == stix2.EmailMIMEComponent
assert excinfo.value.fields == ["body", "body_raw_ref"]
assert excinfo.value.properties == ["body", "body_raw_ref"]
@pytest.mark.parametrize("data", [
@ -416,7 +416,7 @@ def test_parse_basic_tcp_traffic_with_error(data):
stix2.parse_observable(data, ["4"])
assert excinfo.value.cls == stix2.NetworkTraffic
assert excinfo.value.fields == ["dst_ref", "src_ref"]
assert excinfo.value.properties == ["dst_ref", "src_ref"]
EXPECTED_PROCESS_OD = """{
@ -508,7 +508,7 @@ def test_artifact_mutual_exclusion_error():
payload_bin="VBORw0KGgoAAAANSUhEUgAAADI==")
assert excinfo.value.cls == stix2.Artifact
assert excinfo.value.fields == ["payload_bin", "url"]
assert excinfo.value.properties == ["payload_bin", "url"]
def test_directory_example():

View File

@ -20,7 +20,7 @@ EXPECTED_RELATIONSHIP = """{
}"""
def test_relationship_all_required_fields():
def test_relationship_all_required_properties():
now = dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc)
rel = stix2.Relationship(
@ -35,7 +35,7 @@ def test_relationship_all_required_fields():
assert str(rel) == EXPECTED_RELATIONSHIP
def test_relationship_autogenerated_fields(relationship):
def test_relationship_autogenerated_properties(relationship):
assert relationship.type == 'relationship'
assert relationship.id == 'relationship--00000000-0000-0000-0000-000000000001'
assert relationship.created == FAKE_TIME
@ -73,22 +73,22 @@ def test_relationship_id_must_start_with_relationship():
assert str(excinfo.value) == "Invalid value for Relationship 'id': must start with 'relationship--'."
def test_relationship_required_field_relationship_type():
def test_relationship_required_property_relationship_type():
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
stix2.Relationship()
assert excinfo.value.cls == stix2.Relationship
assert excinfo.value.fields == ["relationship_type", "source_ref", "target_ref"]
assert excinfo.value.properties == ["relationship_type", "source_ref", "target_ref"]
def test_relationship_missing_some_required_fields():
def test_relationship_missing_some_required_properties():
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
stix2.Relationship(relationship_type='indicates')
assert excinfo.value.cls == stix2.Relationship
assert excinfo.value.fields == ["source_ref", "target_ref"]
assert excinfo.value.properties == ["source_ref", "target_ref"]
def test_relationship_required_field_target_ref():
def test_relationship_required_properties_target_ref():
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
stix2.Relationship(
relationship_type='indicates',
@ -96,7 +96,7 @@ def test_relationship_required_field_target_ref():
)
assert excinfo.value.cls == stix2.Relationship
assert excinfo.value.fields == ["target_ref"]
assert excinfo.value.properties == ["target_ref"]
def test_cannot_assign_to_relationship_attributes(relationship):
@ -111,8 +111,8 @@ def test_invalid_kwarg_to_relationship():
stix2.Relationship(my_custom_property="foo", **RELATIONSHIP_KWARGS)
assert excinfo.value.cls == stix2.Relationship
assert excinfo.value.fields == ['my_custom_property']
assert str(excinfo.value) == "Unexpected field(s) for Relationship: (my_custom_property)."
assert excinfo.value.properties == ['my_custom_property']
assert str(excinfo.value) == "Unexpected properties for Relationship: (my_custom_property)."
def test_create_relationship_from_objects_rather_than_ids(indicator, malware):

View File

@ -31,7 +31,7 @@ BAD_SIGHTING = """{
}"""
def test_sighting_all_required_fields():
def test_sighting_all_required_properties():
now = dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc)
s = stix2.Sighting(
@ -79,8 +79,8 @@ def test_invalid_kwarg_to_sighting():
stix2.Sighting(my_custom_property="foo", **SIGHTING_KWARGS)
assert excinfo.value.cls == stix2.Sighting
assert excinfo.value.fields == ['my_custom_property']
assert str(excinfo.value) == "Unexpected field(s) for Sighting: (my_custom_property)."
assert excinfo.value.properties == ['my_custom_property']
assert str(excinfo.value) == "Unexpected properties for Sighting: (my_custom_property)."
def test_create_sighting_from_objects_rather_than_ids(malware): # noqa: F811

View File

@ -142,7 +142,7 @@ def test_versioning_error_usetting_required_property():
campaign_v1.new_version(name=None)
assert excinfo.value.cls == stix2.Campaign
assert excinfo.value.fields == ["name"]
assert excinfo.value.properties == ["name"]
def test_versioning_error_new_version_of_revoked():