diff --git a/stix2/base.py b/stix2/base.py index b0cf6ff..b26f044 100644 --- a/stix2/base.py +++ b/stix2/base.py @@ -40,14 +40,7 @@ class _STIXBase(collections.Mapping): """Base class for STIX object types""" def object_properties(self): - props = set(self._properties.keys()) - custom_props = list(set(self._inner.keys()) - props) - custom_props.sort() - - all_properties = list(self._properties.keys()) - all_properties.extend(custom_props) # Any custom properties to the bottom - - return all_properties + return list(self._properties.keys()) def _check_property(self, prop_name, prop, kwargs): if prop_name not in kwargs: @@ -109,6 +102,13 @@ class _STIXBase(collections.Mapping): extra_kwargs = list(set(kwargs) - set(cls._properties)) if extra_kwargs: raise ExtraPropertiesError(cls, extra_kwargs) + else: + from .properties import CustomProperty + + # The custom properties will get added to the bottom. + # Matched with a CustomProperty. + extra_kwargs = list(set(kwargs) - set(cls._properties)) + self._properties.update([(x, CustomProperty()) for x in extra_kwargs]) # Remove any keyword arguments whose value is None setting_kwargs = {} diff --git a/stix2/properties.py b/stix2/properties.py index ca7f04c..5b480ac 100644 --- a/stix2/properties.py +++ b/stix2/properties.py @@ -393,3 +393,15 @@ class PatternProperty(StringProperty): raise ValueError(str(errors[0])) return self.string_type(value) + + +class CustomProperty(Property): + """ + The custom property class can be used as a base to extend further + functionality of a custom property. + + Note: + This class is used internally to signal the use of any custom property + that is parsed by any object or `parse()` method and allow_custom=True. + """ + pass