Skip to main content

A package to define interface in Python

Project description

interface-py

interface-py is a lightweight Python package for defining interfaces and concrete implementations with enforced contracts.
It ensures that concrete classes implement all required methods, properties, and fields, including validation for empty or invalid property getters.


Features

  • Define interfaces using the @interface decorator.
  • Enforce that concrete classes implement all interface methods, fields, and properties.
  • Detects and enforces rules for empty, explicit, and invalid getters/setters.
  • Support for fields with four declaration styles:
    1. With annotation only → x: int
    2. With annotation + ...y: float = ...
    3. Without annotation + ...z = ...
    4. With direct type assignment → DataModel = dict or any other type/class
  • Ensures that property getters defined explicitly in interfaces always raise an error.
  • Allows defining properties in interfaces with empty bodies (..., pass, or docstring-only`).
  • Enforce getter, setter, and deleter implementation rules for properties.
  • Supports multi-level interface hierarchies with automatic contract aggregation.
  • Prevents runtime errors from missing implementations.
  • Works alongside Python's built-in ABCs.

Installation

pip install interface-py

Usage

Defining an Interface

from interface_py import interface

@interface
class HumanInterface:
    # field definitions
    name: str
    age: int = ...
    nickname = ...
    DataModel = dict  # direct type assignment
    
    def speak(self): ...
    
    @property
    def rank(self): ...
    
    @rank.setter
    def rank(self, value): ...
  • Property definitions in interfaces may have an empty body (..., pass, or docstring-only`).
  • However, explicit getters (e.g. @rank.getter) are not allowed in interfaces, even if their body is empty.

Multi-level Interface Example

from interface_py import interface, concrete

@interface
class MilitaryHumanInterface(HumanInterface):
    def march(self): ...

@concrete
class Soldier(MilitaryHumanInterface):
    name: str = "John"
    age: int = 25
    nickname = "Eagle"
    
    def speak(self):
        print("Reporting for duty!")

    def march(self):
        print("Marching!")

    @property
    def rank(self):
        return self._rank
    
    @rank.setter
    def rank(self, value):
        self._rank = value
  • MilitaryHumanInterface extends HumanInterface.
  • Soldier implements all required methods, fields, and properties from both interfaces automatically.
  • Multi-level inheritance automatically merges all parent interface contracts.

Field Enforcement Examples

from interface_py import interface, concrete

@interface
class ExampleInterface:
    x: int              # only annotation
    y: float = ...      # annotation with ellipsis
    z = ...             # plain ellipsis
    DataModel = dict    # direct type assignment


# ✅ Correct implementation
@concrete
class GoodImpl(ExampleInterface):
    x: int = 10
    y: float = 3.14
    z = "hello"
    DataModel = dict


# ❌ Incorrect implementation
@concrete
class BadImpl(ExampleInterface):
    x: str = "oops"   # wrong type (expected int)
    # y missing → TypeError
    z = ...           # not allowed to keep ellipsis
    DataModel = list   # wrong type assignment

Method Enforcement Rules

In interfaces, all methods must have an empty body.
Empty bodies are recognized as:

  • pass
  • ...
  • docstring-only functions (for example, a function that only contains a string literal as its body)

In concrete classes, all methods must have a non-empty body.
Methods defined with only pass, ..., or docstring-only are considered unimplemented and raise a TypeError.


Property Enforcement Rules

  • A property can be declared in an interface as:

    @property
    def data(self): ...
    
  • The above is valid and treated as a contract placeholder.

  • However, the following is invalid and raises an error:

    @property
    def data(self):
        pass
    
    @data.getter
    def data(self):
        ...
    
  • Concrete classes must implement the getter, and if defined in the interface, also the setter and deleter.


Validation

  • Instantiating a concrete class that does not implement all interface methods/fields/properties raises a TypeError.
  • Ensures consistent interface contracts across your project.
  • The decorator @interface automatically enforces the interface behavior without requiring any base class.
  • The decorator @concrete ensures that at least one parent of the concrete class is an interface.

Why Use interface-py?

  • Provides contract enforcement in dynamically typed Python.
  • Detects incomplete or empty implementations early.
  • Helps structure large codebases with clear interface and implementation separation.
  • Avoids runtime errors from missing or placeholder methods.
  • Enforces correctness while remaining Pythonic.

License

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

interface_py-1.3.8.tar.gz (9.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

interface_py-1.3.8-py3-none-any.whl (8.0 kB view details)

Uploaded Python 3

File details

Details for the file interface_py-1.3.8.tar.gz.

File metadata

  • Download URL: interface_py-1.3.8.tar.gz
  • Upload date:
  • Size: 9.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for interface_py-1.3.8.tar.gz
Algorithm Hash digest
SHA256 bcd63306fa6262525c47680042a3fb30ceaeae72c4e026422d299e19d763a5fa
MD5 de5ebeb7e5ac1b6f8339de3e60634bd8
BLAKE2b-256 fc4e319fe3e7a3cb3f9c7da46826388d5c72ecbd1ccc1aeae95eb171e69a3c9e

See more details on using hashes here.

File details

Details for the file interface_py-1.3.8-py3-none-any.whl.

File metadata

  • Download URL: interface_py-1.3.8-py3-none-any.whl
  • Upload date:
  • Size: 8.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for interface_py-1.3.8-py3-none-any.whl
Algorithm Hash digest
SHA256 61f78dc841a4e77e1caf559eca0e6c2725f06e280c89fe19c7e05f7d5fca4d66
MD5 9c97360b34b46061a282ea69a9687970
BLAKE2b-256 8062b07859fa132525c5b3d0525fc23055b19a688d20359be85d2640a02bd31d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page