From 253989cc52ac89b84725229fa9ef2702aba4669f Mon Sep 17 00:00:00 2001 From: clenk Date: Thu, 6 Apr 2017 16:08:36 -0400 Subject: [PATCH] Coerce boolean properties automatically for values like "true", "F", or 1 --- stix2/properties.py | 25 ++++++++++++++++++++++--- stix2/test/test_indicator.py | 2 +- stix2/test/test_properties.py | 14 +++++++++++++- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/stix2/properties.py b/stix2/properties.py index 471ffa9..b638f5f 100644 --- a/stix2/properties.py +++ b/stix2/properties.py @@ -115,12 +115,31 @@ class IDProperty(Property): class BooleanProperty(Property): - # TODO: Consider coercing some values (like the strings "true" and "false") + + def clean(self, value): + if isinstance(value, bool): + return value + + trues = ['true', 't'] + falses = ['false', 'f'] + try: + if value.lower() in trues: + return True + if value.lower() in falses: + return False + except AttributeError: + if value == 1: + return True + if value == 0: + return False + + raise ValueError("not a coercible boolean value.") def validate(self, value): - if not isinstance(value, bool): + try: + return self.clean(value) + except ValueError: raise ValueError("must be a boolean value.") - return value REF_REGEX = re.compile("^[a-z][a-z-]+[a-z]--[0-9a-fA-F]{8}-[0-9a-fA-F]{4}" diff --git a/stix2/test/test_indicator.py b/stix2/test/test_indicator.py index 11197ed..436bb28 100644 --- a/stix2/test/test_indicator.py +++ b/stix2/test/test_indicator.py @@ -101,7 +101,7 @@ def test_indicator_created_ref_invalid_format(): def test_indicator_revoked_invalid(): with pytest.raises(ValueError) as excinfo: - stix2.Indicator(revoked='false', **INDICATOR_KWARGS) + stix2.Indicator(revoked='no', **INDICATOR_KWARGS) assert str(excinfo.value) == "Invalid value for Indicator 'revoked': must be a boolean value." diff --git a/stix2/test/test_properties.py b/stix2/test/test_properties.py index 6e1d44d..a210302 100644 --- a/stix2/test/test_properties.py +++ b/stix2/test/test_properties.py @@ -78,7 +78,19 @@ def test_boolean_property(): assert bool_prop.validate(True) is not None assert bool_prop.validate(False) is not None - for invalid in ('true', 'false', "T", "F", 1, 0): + assert bool_prop.validate('True') is not None + assert bool_prop.validate('False') is not None + assert bool_prop.validate('true') is not None + assert bool_prop.validate('false') is not None + assert bool_prop.validate('TRUE') is not None + assert bool_prop.validate('FALSE') is not None + assert bool_prop.validate('T') is not None + assert bool_prop.validate('F') is not None + assert bool_prop.validate('t') is not None + assert bool_prop.validate('f') is not None + assert bool_prop.validate(1) is not None + assert bool_prop.validate(0) is not None + for invalid in ('abc', ['false'], {'true': 'true'}, 2, -1): print(invalid) with pytest.raises(ValueError): bool_prop.validate(invalid)