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.
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.
level with STIX versions in the same format as is used everywhere
else in the API: "X.Y", as opposed to the "vXY" format used by
the version-specific python packages. This eliminates all of
the awkward conversion from public API format to "vXX" format.
Also a little bit of code rearranging in the registration module
to ensure that some STIX 2.1-specific checks are done whether
version 2.1 is given explicitly or is defaulted to.
In the same module I also added a missing import of
stix2.properties, since my IDE was claiming it could not find a
function from that module.
- stix2.registry, which contains the class mapping structure
and code for scanning stix2 modules for its initial population
- stix2.registration, which contains code used to register custom
STIX types with the registry
- stix2.parsing, which contains code for creating instances of
registered stix2 classes from raw dicts.
This is intended to reduce circular import problems, by giving
dependent code the ability to import a module which has exactly
the functionality it needs, without pulling a lot of other stuff
it doesn't need. Fewer imports means less chance of an import
cycle.
TypeProperty uses a fixed value, so check() was never called. This way
also runs the check at object registration time because the wrapper
creates an instance of TypeProperty and doesn't have to wait for the
object to be instantiated so clean() can be called.
Also fix some tests.
cleaned" property, but actually, the cleaning algorithm works on
a dict copy, so aborting cleaning partway through doesn't
actually affect the object in that way. It would actually cause
the extensions property to be completely uncleaned, rather than
partially cleaned.
- Removed all plain python base classes (e.g. ValueError, TypeError)
- Renamed InvalidPropertyConfigurationError -> PropertyPresenceError,
since incorrect values could be considered a property config error, and
I really just wanted this class to apply to presence (co-)constraint
violations.
- Added ObjectConfigurationError as a superclass of InvalidValueError,
PropertyPresenceError, and any other exception that could be raised
during _STIXBase object init, which is when the spec compliance
checks happen. This class is intended to represent general spec
violations.
- Did some class reordering in exceptions.py, so all the
ObjectConfigurationError subclasses were together.
Changed how property "cleaning" errors were handled:
- Previous docs said they should all be ValueErrors, but that would require
extra exception check-and-replace complexity in the property
implementations, so that requirement is removed. Doc is changed to just
say that cleaning problems should cause exceptions to be raised.
_STIXBase._check_property() now handles most exception types, not just
ValueError.
- Decided to try chaining the original clean error to the InvalidValueError,
in case the extra diagnostics would be helpful in the future. This is
done via 'six' adapter function and only works on python3.
- A small amount of testing was removed, since it was looking at custom
exception properties which became unavailable once the exception was
replaced with InvalidValueError.
Did another pass through unit tests to fix breakage caused by the changed
exception class hierarchy.
Removed unnecessary observable extension handling code from
parse_observable(), since it was all duplicated in ExtensionsProperty.
The redundant code in parse_observable() had different exception behavior
than ExtensionsProperty, which makes the API inconsistent and unit tests
more complicated. (Problems in ExtensionsProperty get replaced with
InvalidValueError, but extensions problems handled directly in
parse_observable() don't get the same replacement, and so the exception
type is different.)
Redid the workbench monkeypatching. The old way was impossible to make
work, and had caused ugly ripple effect hackage in other parts of the
codebase. Now, it replaces the global object maps with factory functions
which behave the same way when called, as real classes. Had to fix up a
few unit tests to get them all passing with this monkeypatching in place.
Also remove all the xfail markings in the workbench test suite, since all
tests now pass.
Since workbench monkeypatching isn't currently affecting any unit tests,
tox.ini was simplified to remove the special-casing for running the
workbench tests.
Removed the v20 workbench test suite, since the workbench currently only
works with the latest stix object version.