This time let's focus on something different than usually - Let's check what Zope Interface is all about :)

S0-E10/E30 :)

Zope Interface

Zope Interface is a part of so called Zope Toolkit - a set of libraries used within web-frameworks.

This interface is about making a reusable elements in system that you then re-purpose in a DRY principle.

Zope Interface usage

You may define your own interface for class. This may be good for example to know what tests needs to be created:

import unittest
import json
from zope import interface
from zope.interface.verify import verifyClass
from zope.interface.verify import BrokenImplementation
from zope.interface.tests import test_verify


class ITestObject(interface.Interface):
    def test_simplest_leading_zero():
        """ This test will check if LeadingZeroValidator behave as expected"""


class TestObject(object):
    interface.implements(ITestObject)


@interface.implementer(ITestObject)
class TestObjectProperlyImplements(object):
    def test_simplest_leading_zero(self):
        """"""
        raise NotImplementedError()


class TestIfMyTestObjectImplementsMethods(unittest.TestCase):

    def test_verify_fails(self):
        with self.assertRaises(BrokenImplementation) as context:
            self.assertTrue(verifyClass(ITestObject, TestObject))

    def test_verify_success(self):
        verifyClass(ITestObject, TestObjectProperlyImplements)

    def test_using_test_method(self):
        testobj = TestObjectProperlyImplements()
        with self.assertRaises(NotImplementedError):
            testobj.test_simplest_leading_zero()

NotImplementedError vs verifyClass

While I was researching the topic I've found that using anything inside of methods defined in Interface - will be disregarded.

I wanted to create a more abstract Interface that would prompt about NotImplementedError - than I've found that zope.interface.Interface disregards any body inside of the method.

You need to create class based on this interface to be able to use NotImplementedError as in example above.

Below you can check example of this mis-guided behaviour:

import unittest
import json
from zope import interface
from zope.interface.verify import verifyClass
from zope.interface.verify import BrokenImplementation
from zope.interface.tests import test_verify

class IHowNotCreateInterfaceWithMethodBody(interface.Interface):
    def method_that_should_be_implemented():
        """ This method needs to be implemented by object!"""
        # As it's only interface, you should not give body to it, but we want to learn our lesson so:
        # anything that you do in this will be disregarded
        raise NotImplementedError()


class ImplementingHowNotCreateInterface(object):
    interface.implements(IHowNotCreateInterfaceWithMethodBody)

class TestingHowNotCreateInterface(unittest.TestCase):

    def test_verify(self):
        # at this point it will not fail with "NotImplementedError" - instead you can invoke your method and have AttributeError.
        testobj = ImplementingHowNotCreateInterface()
        with self.assertRaises(AttributeError):
            testobj.method_that_should_be_implemented()
        with self.assertRaises(BrokenImplementation):
            verifyClass(IHowNotCreateInterfaceWithMethodBody, ImplementingHowNotCreateInterface)


if __name__ == '__main__':
    unittest.main()

Acknowledgements

Thanks!

That's it :) Comment, share or don't :)

If you have any suggestions what I should blog about in the next articles - please give me a hint :)

See you tomorrow! Cheers!



Comments

comments powered by Disqus