zope.interface

Design-by-contract interfaces for Python objects, components, and adapters.

Library
PyPI
v8.6
351stars
ZPL-2.1

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
61/100Good
Development Activity60
Maintenance16
Community88
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
75/100Good
Architecture85
Code Quality88
Innovation72
Learning Curve55

zope.interface is the reference implementation of “object interfaces” for Python: a way to declare that a class or instance conforms to a named contract (IMyInterface), independent of inheritance. An interface documents the methods and attributes an object promises to provide, without dictating how they’re implemented, which lets unrelated classes satisfy the same contract and lets calling code depend on the contract rather than a concrete type.

Built for the Zope Toolkit and used throughout Plone, Pyramid’s component layer, and Twisted, the package pairs interface declarations with an adapter registry: given an object and the interface a caller needs, the registry can look up (or synthesize via a registered adapter factory) something that provides it. This is the mechanism behind pluggable component architectures, where behavior is composed by registering adapters and utilities rather than subclassing.

The library is split between a pure-Python implementation and an optional C extension (_zope_interface_coptimizations) that accelerates the hot paths — attribute lookup, providedBy/implementedBy checks, and adapter registry queries — used millions of times in a running Zope or Plone instance. Both implementations are kept behavior-identical and are exercised by the same test suite via a PURE_PYTHON environment toggle.

What You Get

  • Interface base class and a class IFoo(Interface): ... syntax for declaring named contracts with documented methods and attributes
  • @implementer(IFoo) class decorator and classImplements/alsoProvides/directlyProvides for attaching interfaces to classes or individual instances
  • providedBy() / implementedBy() introspection to query what interfaces an object or class satisfies at runtime
  • AdapterRegistry / VerifyingAdapterRegistry for registering and looking up adapter factories keyed by (required interfaces, provided interface, name)
  • verify.verifyObject() / verify.verifyClass() to assert at test time that an implementation actually satisfies an interface’s declared methods
  • invariant() and taggedValue() decorators for attaching validation rules and arbitrary metadata to an interface definition
  • An optional C extension mirroring the pure-Python implementation for CPython performance, toggled transparently or forced off via PURE_PYTHON=1

Common Use Cases

  • Defining a plugin contract (e.g. IStorage, IAuthenticationPlugin) that third-party packages implement without inheriting from a base class
  • Building a component architecture where behavior is looked up by interface + context rather than hardcoded, as Zope and Plone do for content types and views
  • Adapting one object to another’s expected shape at a call boundary — e.g. adapting a raw form submission to an IValidatedInput-providing object
  • Asserting implementation correctness in tests with verifyObject() so a mock or fake can’t silently drift from the interface it claims to satisfy
  • Documenting a library’s public extension points as interfaces so consumers know exactly what methods a pluggable component must provide

Under The Hood

Architecture The package centers on two cooperating layers: interface.py, which defines InterfaceClass/Specification and the metaclass magic that turns a class IFoo(Interface): ... body into a queryable, inheritable contract object (with C3-linearized resolution order computed in ro.py); and adapter.py/registry.py, which implement AdapterRegistry as a set of nested lookup tables keyed by required/provided interfaces and adapter name, supporting both exact and MRO-aware fallback lookup. declarations.py is the glue that attaches interfaces to classes (classImplements) or individual objects (alsoProvides) and answers providedBy()/implementedBy() queries, while exceptions.py and verify.py supply the Invalid/DoesNotImplement errors and verifyObject/verifyClass runtime checks. Changing the core Specification/InterfaceClass contract would ripple through every consumer (Zope, Plone, Pyramid, Twisted) since they all key their component lookups off it.

Tech Stack Pure Python 3.10+ with zero runtime dependencies, plus an optional C extension (_zope_interface_coptimizations.c) built via setuptools.Extension in setup.py, with a build_ext subclass that lets the C build fail gracefully and fall back to pure Python (also selectable explicitly via PURE_PYTHON=1). Packaging is declared in pyproject.toml with dynamic README/CHANGES-sourced long description. Testing uses tox across CPython 3.10-3.15 (including free-threaded t builds) plus PyPy3, coverage.py with a 98% fail-under gate, and Sphinx doctest for the docs. CI runs via GitHub Actions (tests.yml, pre-commit.yml).

Code Quality The tests/ package (mirrored under src/zope/interface/tests/ and common/tests/) is extensive, covering both the pure-Python and C-accelerated code paths for every public entry point, run through unittest discover under tox with ZOPE_INTERFACE_STRICT_IRO=1 to catch resolution-order regressions. Coverage is enforced at 98% via tool.coverage.report.fail_under. The CHANGES.rst log shows recurring, specific bug fixes to the C extension’s exception-safety (guarding PyErr_Clear(), replacing borrowed-reference PyDict_GetItem() calls) that indicate careful, security-conscious maintenance rather than surface-level changes. Style is enforced via pre-commit.yml in CI.

What Makes It Unique Unlike Python’s built-in abc.ABCMeta or typing.Protocol, zope.interface interfaces are first-class runtime objects that support explicit declaration (an object can be told it provides an interface without structurally matching it), a full adapter-registry lookup system keyed on multiple interfaces at once, and invariants/tagged values attached to the interface definition itself. Maintaining a hand-written C extension that stays behavior-identical to the pure-Python implementation — verified by running the same test suite against both — is a comparatively rare commitment for a general-purpose typing/contract library, and reflects two decades of use as the load-bearing dispatch mechanism inside Zope/Plone’s component architecture.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search