|
| 1 | +``interface`` |
| 2 | +============= |
| 3 | + |
| 4 | +|build status| |
| 5 | + |
| 6 | +``interface`` provides facilities for declaring interfaces and for statically |
| 7 | +asserting that classes implement those interfaces. |
| 8 | + |
| 9 | +``interface`` improves on Python's ``abc`` module in two ways: |
| 10 | + |
| 11 | +1. Interface requirements are checked at class creation time, rather than at |
| 12 | + instance creation time. This means that ``interface`` can tell you if a |
| 13 | + class fails to meet the requirements of an interface even if you never |
| 14 | + create any instances of that class. |
| 15 | + |
| 16 | +2. ``interface`` requires that method signatures of interface implementations |
| 17 | + are compatible with the signatures declared in the interface. For example, |
| 18 | + the following code using ``abc`` does not produce an error: |
| 19 | + |
| 20 | + .. code-block:: python |
| 21 | +
|
| 22 | + from abc import ABCMeta, abstractmethod |
| 23 | +
|
| 24 | + class Base(metaclass=ABCMeta): |
| 25 | +
|
| 26 | + @abstractmethod |
| 27 | + def method(self, a, b): |
| 28 | + pass |
| 29 | +
|
| 30 | + class Implementation(MyABC): |
| 31 | +
|
| 32 | + def method(self): |
| 33 | + return "This shouldn't work." |
| 34 | +
|
| 35 | + impl = Implementation() |
| 36 | +
|
| 37 | + The equivalent code using ``interface`` produces an error indicating that |
| 38 | + the signature of ``Implementation.method`` is incompatible with that of |
| 39 | + ``Base.method``. |
| 40 | + |
| 41 | + .. code-block:: python |
| 42 | +
|
| 43 | + >>> from interface import implements, Interface |
| 44 | + >>> class I(Interface): |
| 45 | + ... def method(self, a, b): |
| 46 | + ... pass |
| 47 | + ... |
| 48 | + >>> class C(implements(I)): |
| 49 | + ... def method(self): |
| 50 | + ... return "This shouldn't work" |
| 51 | + ... |
| 52 | + TypeError: |
| 53 | + class C failed to implement interface I: |
| 54 | +
|
| 55 | + The following methods were implemented but had invalid signatures: |
| 56 | + - method(self) != method(self, a, b) |
| 57 | +
|
| 58 | +Defining an Interface |
| 59 | +~~~~~~~~~~~~~~~~~~~~~ |
| 60 | + |
| 61 | +To define an interface, simply subclass from ``interface.Interface`` and define |
| 62 | +method stubs in your class body. |
| 63 | + |
| 64 | +.. code-block:: python |
| 65 | +
|
| 66 | + from interface import Interface |
| 67 | +
|
| 68 | + class MyInterface(Interface): |
| 69 | +
|
| 70 | + def method1(self): |
| 71 | + pass |
| 72 | +
|
| 73 | + def method2(self, arg1, arg2): |
| 74 | + pass |
| 75 | +
|
| 76 | +Implementing an Interface |
| 77 | +~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 78 | + |
| 79 | +To declare that a particular class implements an interface ``I``, pass |
| 80 | +``implements(I)`` as a base class for your class. |
| 81 | + |
| 82 | +.. code-block:: python |
| 83 | +
|
| 84 | + from interface import implements |
| 85 | +
|
| 86 | + class MyClass(implements(MyInterface)): |
| 87 | +
|
| 88 | + def method1(self): |
| 89 | + return "method1" |
| 90 | +
|
| 91 | + def method2(self, arg1, arg2): |
| 92 | + return "method2" |
| 93 | +
|
| 94 | +.. |build status| image:: https://travis-ci.org/ssanderson/interface.svg?branch=master |
| 95 | + :target: https://travis-ci.org/ssanderson/interface |
0 commit comments