Previously the requirement that properties ending in `_ref(s)` were
instances of an appropriate type capable of containing a STIX
`identifier` (the current interpretation of section 3.1 of the STIX 2.1
spec) was only enforced for custom observables. This change refactors
the property checks for custom objects to enforce this and the STIX 2.1
property name requirement (also from section 3.1) in a common helper,
therefore extending the enforcement of both requirements to all custom
object types created by downstream projects.
There is a special case carved out for STIX 2.0 observables which are
required to contain "object references" rather than identifiers. This
special logic is encoded in the reference property validation helper and
enabled by a kwarg which is passed exclusively by the custom observable
registration helper.
and process properties in that order. This establishes iteration
order on object properties, making the object_properties() method
unnecessary. So the latter method has been deleted. All uses
of that method have been removed.
Removed unnecessary deepcopy() in STIXJSONEncoder, to improve
efficiency. This uncovered a bug which had been affecting
STIXdatetime instances. Not deepcopying doesn't trip the bug,
which can change serialization format. This caused a unit
test to fail, which was checking serialization format. I fixed
the unit test.
Fixed a bug in _STIXBase.__repr__ which caused it to omit all
properties with falsey values. This caused several unit tests
to break, since they were written against the old buggy repr
format. Notably, 'revoked=False' was never included in reprs
before, but it is now.
respect to properties. Before, properties were declared on
toplevel-property-extension extensions as if they were going
to be used in the normal way (as actual properties on instances
of the extension), but they were not used that way, and there
was some ugly hackage to make it work. Despite the fact that
property instances were given during extension registration,
they were not used to typecheck, set defaults, etc on toplevel
property extension properties.
I changed how registration and object initialization works with
respect to properties associated with extensions. Now,
extensions work the same as any other object and code is
cleaner. Property instances associated with registered toplevel
extensions are used to enforce requirements like any other
object.
Added some unit tests specifically for property cleaning for
extensions.
Property order (for those contexts where it matters) is updated
to be spec-defined, toplevel extension, custom.
Remove iterable chaining from CustomObject decorator. If all
values are guaranteed lists now, it no longer makes sense to use
it. Simpler and clearer to use plain old list concatenation.
to v21.common. Custom extensions are not specific to SCOs, so I
don't know why it was in that module. Now, ExtensionDefinition
and CustomExtension are together in the same module, just like
MarkingDefinition and CustomMarking are together. Made sense to
me.
toplevel-property-extension style extensions. If an unregistered
extension of that type is encountered, all unrecognized toplevel
props will now be considered extension properties (not custom).
It will no longer turn on the allow_custom flag, which would
allow customizations everywhere.
Also, if all extensions of the aforementioned type are registered,
their properties are now used to properly distinguish between
extension and custom properties. There need not be any ambiguity
in that case.
fixes.
- Fixed bugged logic in _STIXBase._check_at_least_one_property(),
and revamped the code to be simpler and clearer.
- Changed custom extension registration to auto-create an
"extension_type" property based on the attribute of that
name on the custom class, if present.
- The custom extension registration change above uncovered
what seemed like a bug in a unit test: a custom extension
was registered, but it was not given an extension type. The
test used the extension as extension_type="property-extension";
this now causes a standard error about an extra property. I
fixed the test to assign the custom extension the proper type.
- Changed an error message "Cannot determine extension type."
At that point in the code, we in fact have a registered
extension type and the class for it, so it didn't seem to make
any sense. I changed it to say that an extension of that type
couldn't be created from type of value given. Because this is
really about typing (in both the old and new code), I also
changed the exception class to TypeError.
- Changed customization behavior: unregistered
"extension-definition--" style extensions are no longer
considered custom. Their mere presence can no longer be
considered a customization, since it doesn't fit the
criteria, and in fact the extension mechanism is supposed to
supplant the old customization system anyway. Unregistered
extensions of other types are still considered custom.
- Fixed up unit tests according to the exception message
change.
- Added a unit test for unregistered "extension-definition--"
style extensions.
The "loophole" occurs when an object contains an unregistered top-level
extension. Since it's unregistered we can't tell if any custom
properties on the object were defined in that extension so we assume
that they are.