Datastructures¶
Datastructures to help externalization.
-
class
ExternalizableDictionaryMixin
[source]¶ Bases:
object
Implements a toExternalDictionary method as a base for subclasses.
-
_ext_replacement
()[source]¶ Return the object that we are externalizing.
This class returns
self
, but subclasses will typically override this.
-
toExternalDictionary
(mergeFrom=None, *unused_args, **kwargs)[source]¶ Produce the standard external dictionary for this object.
Uses
_ext_replacement
.
-
-
class
StandardInternalObjectExternalizer
(context)[source]¶ Bases:
nti.externalization.datastructures.ExternalizableDictionaryMixin
An adapter that can be used to implement
IInternalObjectExternalizer
.The result of externalizing is the standard external dictionary for this adapter’s context argument.
This can be registered as-is, or subclassed to add additional items in the external dictionary. In that case, always begin by calling this implemention first and updating the result.
New in version 2.3.0.
The constructor sets
__external_can_create__
toFalse
(because creating from just an externalizer makes no sense) and__external_class_name__
toNone
(if you override this value, it will replace theClass
value in the returned dictionary; it must be a nativestr
).
-
class
AbstractDynamicObjectIO
[source]¶ Bases:
nti.externalization.datastructures.ExternalizableDictionaryMixin
Base class for objects that externalize based on dynamic information.
Abstractions are in place to allow subclasses to map external and internal names independently (this type never uses getattr/setattr/hasattr, except for some standard fields).
See
InterfaceObjectIO
for a complete implementation.-
_ext_accept_external_id
(ext_self, parsed)[source]¶ If the object we’re updating does not have an
id
set, but there is anID
in the external object, should we be able to use it?Returns: boolean
-
_ext_accept_update_key
(k, ext_self, ext_keys)[source]¶ Returns whether or not this key should be accepted for setting on the object, or silently ignored.
Parameters: ext_keys – As an optimization, the value of _ext_all_possible_keys()
is passed. Keys are only accepted if they are in this list.
-
_ext_getattr
(object, name[, default]) → value[source]¶ Return the attribute of the ext_self object with the internal name name. If the attribute does not exist, should raise (typically
AttributeError
), unless default is given, in which case it returns that.Changed in version 1.0a4: Add the default argument.
-
_ext_keys
()[source]¶ Return only the names of attributes that should be externalized. These values will be used as keys in the external dictionary.
See
_ext_all_possible_keys()
. This implementation then filters out private attributes (those beginning with an underscore), and those listed in_excluded_in_ivars_
.This method must return a set of native strings.
-
_ext_primitive_keys
()[source]¶ Return a container of string keys whose values are known to be primitive. This is an optimization for writing.
This method must return a frozenset.
-
_ext_replacement
()[source]¶ Return the object that we are externalizing.
This class returns
self
, but subclasses will typically override this.
-
_ext_replacement_getattr
(name, default=<default value>)[source]¶ Like
_ext_getattr
, but automatically fills in_ext_replacement
for the ext_self argument.New in version 1.0a4.
-
find_factory_for_named_value
(key, value)[source]¶ Uses
find_factory_for
to locate a factory.This does not take into account the current object (context) or the key. It only handles finding factories based on the class or MIME type found within value.
-
toExternalDictionary
(mergeFrom=None, *unused_args, **kwargs)[source]¶ Produce the standard external dictionary for this object.
Uses
_ext_replacement
.
-
-
class
ExternalizableInstanceDict
[source]¶ Bases:
object
Externalizes to a dictionary containing the members of
__dict__
that do not start with an underscore.Meant to be used as a super class; also can be used as an external object superclass.
Consider carefully before using this class. Generally, an interface and
InterfaceObjectIO
are better.Changed in version 1.0a5: No longer extends
AbstractDynamicObjectIO
, just delegates to it. Most of the_ext_`
prefixed methods can no longer be overridden.-
toExternalObject
(mergeFrom=None, *args, **kwargs)[source]¶ See
toExternalObject
. CallstoExternalDictionary
.
-
-
class
InterfaceObjectIO
(context, iface_upper_bound=None, validate_after_update=True)[source]¶ Bases:
nti.externalization.datastructures.AbstractDynamicObjectIO
Externalizes the context to a dictionary based on getting the attributes of an object defined by an interface. If any attribute has a true value for the tagged value
_ext_excluded_out
, it will not be considered for reading or writing.This is an implementation of
IInternalObjectIOFinder
, meaning it can both internalize (update existing objects) and externalize (producing dictionaries), and that it gets to choose the factories used for sub-objects when internalizing.This class is meant to be used as an adapter, so it accepts the object to externalize in the constructor, as well as the interface to use to guide the process. The object is externalized using the most-derived version of the interface given to the constructor that it implements.
If the interface (or an ancestor) has a tagged value
__external_class_name__
, it can either be the value to use for theClass
key, or a callable__external_class_name__(interface, object ) -> name.
(TODO: In the future extend this to multiple, non-overlapping interfaces, and better interface detection (see
ModuleScopedInterfaceObjectIO
for a limited version of this.)This class overrides
_ext_replacement
to return the context.Parameters: - iface_upper_bound – The upper bound on the schema to use
to externalize
ext_self
; we will use the most derived sub-interface of this interface that the object implements. Subclasses can either override this constructor to pass this parameter (while taking one argument themselves, to be usable as an adapter), or they can define the class attribute_ext_iface_upper_bound
- validate_after_update (bool) – If
True
(the default) then the entire schema will be validated after an object has been updated withupdate_from_external_object()
, not just the keys that were assigned.
-
_ext_accept_external_id
(ext_self, parsed)[source]¶ If the interface we’re working from has a tagged value of
__external_accept_id__
on theid
field, then this will return that value; otherwise, returns false.
-
_ext_getattr
(object, name[, default]) → value[source]¶ Return the attribute of the ext_self object with the internal name name. If the attribute does not exist, should raise (typically
AttributeError
), unless default is given, in which case it returns that.Changed in version 1.0a4: Add the default argument.
-
_ext_replacement
()[source]¶ Return the object that we are externalizing.
This class returns
self
, but subclasses will typically override this.
-
find_factory_for_named_value
(key, value)[source]¶ If
AbstractDynamicObjectIO.find_factory_for_named_value
cannot find a factory based on examining value, then we use the context objects’s schema to find a factory.If the schema contains an attribute named key, it will be queried for the tagged value
__external_factory__
. If present, this tagged value should be the name of a factory object implementingIAnonymousObjectFactory
registered in registry (typically registered in the global site).The ZCML directive
IAnonymousObjectFactoryDirective
sets up both the registration and the tagged value.This is useful for internalizing data from external sources that does not provide a class or MIME field within the data.
The most obvious limitation of this is that if the value is part of a sequence, it must be a homogeneous sequence. The factory is called with no arguments, so the only way to deal with heterogeneous sequences is to subclass this object and override this method to examine the value itself.
A second limitation is that the external data key must match the internal schema field name. Again, the only way to remove this limitation is to subclass this object.
If no registered factory is found, and the schema field is a
zope.schema.Dict
with a value type ofzope.schema.Object
, then we return a factory which will update the object in place.Changed in version 1.0a6: Only return an anonymous factory for
IDict
fields when it wants objects for the value.
-
schema
¶ The schema we will use to guide the process
- iface_upper_bound – The upper bound on the schema to use
to externalize
-
class
ModuleScopedInterfaceObjectIO
(context, iface_upper_bound=None, validate_after_update=True)[source]¶ Bases:
nti.externalization.datastructures.InterfaceObjectIO
Only considers the interfaces provided within a given module (usually declared as a class attribute) when searching for the schema to use to externalize an object; the most derived version of interfaces within that module will be used. Subclasses must declare the class attribute
_ext_search_module
to be a module (something with the__name__
) attribute to locate interfaces in.Suitable for use when all the externalizable fields of interest are declared by an interface within a module, and an object does not implement two unrelated interfaces from the same module.
Note
If the object does implement unrelated interfaces, but one (set) of them is a marker interface (featuring no schema fields or attributes), then it can be tagged with
_ext_is_marker_interface
and it will be excluded when determining the most derived interfaces. This can correct some cases that would otherwise raise a TypeError. This tag is not inherited.Parameters: - iface_upper_bound – The upper bound on the schema to use
to externalize
ext_self
; we will use the most derived sub-interface of this interface that the object implements. Subclasses can either override this constructor to pass this parameter (while taking one argument themselves, to be usable as an adapter), or they can define the class attribute_ext_iface_upper_bound
- validate_after_update (bool) – If
True
(the default) then the entire schema will be validated after an object has been updated withupdate_from_external_object()
, not just the keys that were assigned.
- iface_upper_bound – The upper bound on the schema to use
to externalize