jute API¶
-
class
jute.
Attribute
(description=None, *, type=<class 'object'>)[source]¶ Bases:
object
Specify a non-function attribute in an interface.
Variables: - description – The doc-string for the attribute.
- type – The type of a valid value for the attribute.
Any attribute which is part of an interface, but is not a method, should be defined as an
Attribute
:class IExample(jute.Opaque): value = jute.Attribute() def double(self): """Return twice the value.""" @implements(IExample) class Example: value = 1 def double(self): return 2 * self.value
-
class
jute.
Interface
[source]¶ Bases:
type
A metaclass to allow classes to define interfaces.
Each class with this metaclass will create an interface allowing access only to the attributes in the class. Attributes can be provided as functions or using the
Attribute
class. Any other types will be available as attributes of the interface class, but not as attributes of interface instances.An instances of the interface class is a called a provider. A provider maps interface attributes to an underlying Python object. The provider behaves the same as the underlying object, but only allows access to the attributes named in the interface.
-
cast
(interface, source)[source]¶ Attempt to cast one interface to another.
This method allows the caller to access another interface supported by the underlying object. Use the
cast()
method sparingly, since it breaks the model of interface-based programming.Note that upcasting (casting an interface to a base interface) can be done by calling the interface constructor:
class IFoo(jute.Opaque): """An interface.""" class IFooBar(IFoo): """A sub-interface of IFoo.""" class IBaz(jute.Opaque): """A completely different interface.""" @implements(IFooBar, IBaz) class FooBarBaz: """A class that implements all the above interfaces.""" fb1 = IFooBar(FooBarBaz()) foo = IFoo(fb1) # upcast does not need cast fb2 = IFooBar.cast(foo) # downcast needs a cast baz = IBaz.cast(fb2) # sidecast needs a cast
-
implemented_by
(interface, cls)[source]¶ Check if class claims to provide the interface.
Note that classes that implement the
DynamicInterface
interface cannot dynamically claim to implement an interface, although individual instances can claim to provide an interface.Return bool: True
if interface is implemented by the class, elseFalse
.
-
provided_by
(interface, obj)[source]¶ Check if object claims to provide the interface.
This will be true if the object’s class claims to provide the interface. It will also be true if the object provides the
DynamicInterface
interface, and theDynamicInterface.provides_interface()
method returnsTrue
when passed this interface.Return bool: True
if interface is provided by the object, elseFalse
.
-
raise_if_not_provided_by
(interface, obj, validate=None)[source]¶ Return if object provides the interface. Raise an informative error if not.
-
register_implementation
(interface, cls)[source]¶ Register a provider class to the interface.
This is useful for declaring that a standard or third-party class provides an interface, when it cannot be decorated with the
implements
decorator.
-
supported_by
(interface, obj)[source]¶ Check if underlying object claims to provide the interface.
Although it allows the caller to see if the underlying object supports an interface, it does not provide access to the interface, unless the interfaces contain attributes in common. This makes it most useful for performing feature checks using marker interfaces (interfaces that have the same syntax, but additional semantics).
Return bool: True
if the underlying object claims to provide the interface, orFalse
otherwise.
-
-
class
jute.
Opaque
(provider)[source]¶ Bases:
object
An interface with no attributes.
This interface has two uses.
It provides the base class for other interfaces to inherit.
In addition, it can be used as an opaque handle to an object. A method can return an object wrapped by
Opaque
in order to make it inscrutable to callers.
-
class
jute.
DynamicInterface
(provider)[source]¶ Bases:
jute._jute.Opaque
Interface to dynamically provide other interfaces.
-
jute.
implements
(*interfaces)[source]¶ Decorator to mark a class as implementing the supplied interfaces.
To implement an interface, the class instances must define all attributes in the interface.
-
jute.
underlying_object
(interface)[source]¶ Obtain the non-interface object wrapped by this interface.
Use the
underlying_object()
function sparingly, since it breaks the model of interface-based programming. It is primarily useful for debugging.
-
exception
jute.
InterfaceConformanceError
(message)[source]¶ Bases:
Exception
Object does not conform to interface specification.
Exception indicating that an object claims to provide an interface, but does not match the interface specification.
This is almost a
TypeError
, but an object provides two parts to its interface implementation: a claim to provide the interface, and the attributes that match the interface specification. This exception indicates the partial match of claiming to provide the interface, but not actually providing all the attributes required by an interface.It could also be considered an
AttributeError
, as when validation is off, that is the alternative exception (that might be) raised. However, future versions of this module may perform additional validation to catchTypeError
’s (e.g. function parameter matching).It was also tempting to raise a
NotImplementedError
, which captures some of the meaning. However,NotImplementedError
is usually used as a marker for abstract methods or in-progress partial implementations. In particular, a developer of an interface provider class may useNotImplementedError
to satisfy the interface where they know the code does not use a particular attribute of the interface. Using a different exception causes less confusion.