Package IO

Support for handling the IO for all the objects in a package, typically via a ZCML directive.

class AutoPackageSearchingScopedInterfaceObjectIO(context, iface_upper_bound=None, validate_after_update=True)[source]

Bases: nti.externalization.datastructures.ModuleScopedInterfaceObjectIO

A special, magic, type of interface-driven input and output, one designed for the common use case of a package that provides the common pattern:

  • interfaces.py
  • externalization.py (where a subclass of this object lives)
  • configure.zcml (where the subclass is registered as an adapter for each object; you may also then provide mime-factories as well)
  • other modules, where types are defined for the external interfaces.

Once you derive from this class and implement the abstract methods, you need to call __class_init__() (exactly once) on your subclass.

You do not have to derive from this class; the common case is handled via the ZCML directive <ext:registerAutoPackageIO> (nti.externalization.zcml.IAutoPackageExternalizationDirective). You can still customize the behaviour by providing the iobase argument.

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 with update_from_external_object(), not just the keys that were assigned.
classmethod __class_init__()[source]

Class initializer. Should be called exactly once on each distinct subclass.

First, makes all interfaces returned by _ap_enumerate_externalizable_root_interfaces() externalizable by setting the __external_class_name__ tagged value (to _ap_compute_external_class_name_from_interface_and_instance()). (See InterfaceObjectIO.)

Then, find all of the object factories and initialize them using _ap_find_factories(). A namespace object representing these factories is returned.

Changed in version 1.0: Registering the factories using register_legacy_search_module() is no longer done by default. If you are using this class outside of ZCML, you will need to subclass and override this method to make that call yourself. If you are using ZCML, you will need to set the appropriate attribute to True.

classmethod _ap_compute_external_class_name_from_concrete_class(a_type)[source]

Return the string value of the external class name.

By default this will be either the value of __external_class_name__ or, if not found, the value of __name__.

Subclasses may override.

classmethod _ap_compute_external_class_name_from_interface_and_instance(unused_iface, impl)[source]

Assigned as the tagged value __external_class_name__ to each interface. This will be called on an instance implementing iface.

classmethod _ap_compute_external_mimetype(package_name, unused_a_type, ext_class_name)[source]

Return the string value of the external mime type for the given type in the given package having the given external name (probably derived from _ap_compute_external_class_name_from_concrete_class()).

For example, given the arguments (‘nti.assessment’, FooBar, ‘FooBar’), the result will be ‘application/vnd.nextthought.assessment.foobar’.

Subclasses may override.

classmethod _ap_enumerate_externalizable_root_interfaces(interfaces)[source]

Return an iterable of the root interfaces in this package that should be externalized.

Subclasses must implement.

classmethod _ap_enumerate_module_names()[source]

Return an iterable of module names in this package that should be searched to find factories.

Subclasses must implement.

classmethod _ap_find_factories(package_name)[source]

Return a namespace object whose attribute names are external class names and whose attribute values are classes that can be created externally.

For each module returned by _ap_enumerate_module_names(), we will resolve it against the value of package_name (normally that given by _ap_find_package_name()). The module is then searched for classes that live in that module. If a class implements an interface that has a tagged value of __external_class_name__, it is added to the return value. The external class name (the name of the attribute) is computed by _ap_compute_external_class_name_from_concrete_class().

Each class that is found has an appropriate mimeType added to it (derived by _ap_compute_external_mimetype()), if it does not already have one; these classes also have the attribute __external_can_create__ set to true on them if they do not have a value for it at all. This makes the classes ready to be used with registerMimeFactories(), which is done automatically by the ZCML directive IAutoPackageExternalizationDirective.

Each class that is found is also marked as implementing zope.mimetype.interfaces.IContentTypeAware.

classmethod _ap_find_package_interface_module()[source]

Return the module that should be searched for interfaces.

By default, this will be the interfaces sub-module of the package returned from _ap_find_package_name().

Subclasses may override.

classmethod _ap_find_package_name()[source]

Return the package name to search for modules.

By default we look at the module name of the cls object given.

Subclasses may override.

classmethod _ap_find_potential_factories_in_module(module)[source]

Given a module that we’re supposed to examine, iterate over the types that could be factories.

This includes only types defined in that module. Any given type will only be returned once.