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.9.tar.gz (3.3 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.9-py3-none-any.whl (8.0 kB view details)

Uploaded Python 3

File details

Details for the file interface-py-1.3.9.tar.gz.

File metadata

  • Download URL: interface-py-1.3.9.tar.gz
  • Upload date:
  • Size: 3.3 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.9.tar.gz
Algorithm Hash digest
SHA256 1e03f00a44e493834adf729857325e2f3600fc154579f8014e8f566d2779cfa5
MD5 5103e8e4412e51870996e0b0dddef61a
BLAKE2b-256 562feb580ca9b0868c66995c6003c4562fe5820e43587273a646d5c32f08fb96

See more details on using hashes here.

File details

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

File metadata

  • Download URL: interface_py-1.3.9-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.9-py3-none-any.whl
Algorithm Hash digest
SHA256 8f0bf1fd1843289bf298e33dcd333f7f46c16737f9afae8c90c74ff91519a5a7
MD5 5ff09cc96014081b55f31654c18a6d49
BLAKE2b-256 9f57b3c8d086154702a0f5616c6e2dc731ef71b5ed761f4b60ca9b0596c97212

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