{"id":31333394,"url":"https://github.com/xpodev/python-explicit-implementation","last_synced_at":"2025-09-26T01:58:06.241Z","repository":{"id":314938387,"uuid":"1057422128","full_name":"xpodev/python-explicit-implementation","owner":"xpodev","description":null,"archived":false,"fork":false,"pushed_at":"2025-09-15T18:19:49.000Z","size":39,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-15T19:31:11.235Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xpodev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-15T17:48:23.000Z","updated_at":"2025-09-15T18:19:19.000Z","dependencies_parsed_at":"2025-09-19T18:46:04.931Z","dependency_job_id":null,"html_url":"https://github.com/xpodev/python-explicit-implementation","commit_stats":null,"previous_names":["xpodev/python-explicit-implementation"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/xpodev/python-explicit-implementation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpodev%2Fpython-explicit-implementation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpodev%2Fpython-explicit-implementation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpodev%2Fpython-explicit-implementation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpodev%2Fpython-explicit-implementation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xpodev","download_url":"https://codeload.github.com/xpodev/python-explicit-implementation/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpodev%2Fpython-explicit-implementation/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":277009880,"owners_count":25744543,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-25T02:00:09.612Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-09-26T01:58:04.316Z","updated_at":"2025-09-26T01:58:06.230Z","avatar_url":"https://github.com/xpodev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Explicit Implementation\n\n[![PyPI version](https://badge.fury.io/py/explicit-implementation.svg)](https://badge.fury.io/py/explicit-implementation)\n[![Python Support](https://img.shields.io/pypi/pyversions/explicit-implementation.svg)](https://pypi.org/project/explicit-implementation/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nA Python library that provides explicit interface implementations with compile-time safety and clear separation between interface contracts and their implementations.\n\n## Features\n\n- **Explicit Interface Declarations**: Define clear interface contracts using abstract methods\n- **Concrete Method Support**: Include concrete methods in interfaces with default implementations\n- **Flexible Implementation**: Allow partial implementations by default, enforce completeness with `concrete=True`\n- **Compile-time Safety**: Catch implementation errors at class definition time, not runtime\n- **Multiple Interface Support**: Implement multiple interfaces in a single class\n- **Interface Access Control**: Access implementations through specific interface views\n- **Type Safety**: Full typing support with generics for better IDE experience\n- **Diamond Inheritance**: Proper handling of complex inheritance patterns\n\n## Installation\n\n```bash\npip install explicit-implementation\n```\n\n## Quick Start\n\n```python\nfrom explicit_implementation import Interface, abstractmethod, implements\n\n# Define an interface\nclass IDrawable(Interface):\n    @abstractmethod\n    def draw(self) -\u003e str:\n        ...\n\nclass IPrintable(Interface):\n    @abstractmethod\n    def print_info(self) -\u003e str:\n        ...\n\n# Implement the interfaces explicitly\nclass Document(IDrawable, IPrintable):\n    def __init__(self, content: str):\n        self.content = content\n    \n    @implements(IDrawable.draw)\n    def render_document(self) -\u003e str:\n        return f\"Drawing: {self.content}\"\n    \n    @implements(IPrintable.print_info)\n    def document_info(self) -\u003e str:\n        return f\"Document: {self.content}\"\n\n# Use the implementation\ndoc = Document(\"Hello World\")\n\n# Access through specific interfaces\ndrawable = doc.as_interface(IDrawable)\nprintable = doc.as_interface(IPrintable)\n\nprint(drawable.draw())        # \"Drawing: Hello World\"\nprint(printable.print_info()) # \"Document: Hello World\"\n```\n\n## Key Concepts\n\n### Interface Declaration\n\nInterfaces are defined by inheriting from `Interface` and using `@abstractmethod`:\n\n```python\nclass IRepository(Interface):\n    @abstractmethod\n    def save(self, data: dict) -\u003e bool:\n        ...\n    \n    @abstractmethod\n    def load(self, id: str) -\u003e dict:\n        ...\n```\n\n### Explicit Implementation\n\nUse the `@implements` decorator to explicitly map interface methods to implementation methods:\n\n```python\nclass DatabaseRepository(IRepository):\n    @implements(IRepository.save)\n    def save_to_database(self, data: dict) -\u003e bool:\n        # Implementation here\n        return True\n    \n    @implements(IRepository.load)  \n    def load_from_database(self, id: str) -\u003e dict:\n        # Implementation here\n        return {\"id\": id}\n```\n\n### Interface Access\n\nAccess implementations through specific interface views:\n\n```python\nrepo = DatabaseRepository()\n\n# Access through the IRepository interface\nrepository_interface = repo.as_interface(IRepository)\nrepository_interface.save({\"name\": \"example\"})\nrepository_interface.load(\"123\")\n```\n\n### Concrete Methods in Interfaces\n\nInterfaces can include concrete (non-abstract) methods that provide default implementations. These methods can be accessed directly from implementing classes without explicit implementation:\n\n```python\nclass IService(Interface):\n    @abstractmethod\n    def process(self, data: str) -\u003e str:\n        ...\n    \n    def log(self, message: str) -\u003e None:\n        \"\"\"Concrete method with default implementation.\"\"\"\n        print(f\"[LOG] {message}\")\n    \n    @classmethod\n    def get_version(cls) -\u003e str:\n        \"\"\"Concrete class method.\"\"\"\n        return \"1.0.0\"\n\nclass MyService(IService):\n    @implements(IService.process)\n    def process_data(self, data: str) -\u003e str:\n        return f\"Processed: {data}\"\n\nservice = MyService()\n\n# Access concrete methods directly\nservice.log(\"Starting process\")          # Works directly\nservice.get_version()                    # Works directly\n\n# Also accessible through interface casting\ninterface = service.as_interface(IService)\ninterface.log(\"Through interface\")       # Also works\ninterface.get_version()                  # Also works\n```\n\n### Concrete Classes\n\nBy default, partial implementations are allowed at class definition time. To enforce complete implementation:\n\n```python\n# This is allowed - partial implementation class definition\nclass PartialRepository(IRepository):\n    @implements(IRepository.save)\n    def save_to_database(self, data: dict) -\u003e bool:\n        return True\n    # Missing IRepository.load implementation - class definition succeeds\n\n# However, you still can't instantiate classes with unimplemented abstract methods\n# partial = PartialRepository()  # Raises TypeError at instantiation\n\n# This will raise TypeError at class definition time\nclass ConcreteRepository(IRepository, concrete=True):\n    @implements(IRepository.save)\n    def save_to_database(self, data: dict) -\u003e bool:\n        return True\n    # Missing IRepository.load implementation - TypeError at class definition!\n```\n\n## Advanced Usage\n\n### Multiple Interface Implementation\n\n```python\nclass IValidator(Interface):\n    @abstractmethod\n    def validate(self, data: str) -\u003e bool:\n        ...\n\nclass IFormatter(Interface):\n    @abstractmethod\n    def format(self, data: str) -\u003e str:\n        ...\n\nclass DataProcessor(IValidator, IFormatter):\n    @implements(IValidator.validate)\n    def check_data(self, data: str) -\u003e bool:\n        return len(data) \u003e 0\n    \n    @implements(IFormatter.format)\n    def format_data(self, data: str) -\u003e str:\n        return data.upper()\n```\n\n### Interface Inheritance\n\n```python\nclass IBasic(Interface):\n    @abstractmethod\n    def basic_method(self) -\u003e str:\n        ...\n\nclass IExtended(IBasic):\n    @abstractmethod\n    def extended_method(self) -\u003e int:\n        ...\n\nclass Implementation(IExtended):\n    @implements(IBasic.basic_method)\n    def basic_impl(self) -\u003e str:\n        return \"basic\"\n    \n    @implements(IExtended.extended_method)\n    def extended_impl(self) -\u003e int:\n        return 42\n```\n\n### Diamond Inheritance Patterns\n\nIn diamond inheritance, each interface path requires explicit implementation:\n\n```python\nclass IBase(Interface):\n    @abstractmethod\n    def base_method(self) -\u003e str:\n        ...\n\nclass ILeft(IBase):\n    @abstractmethod\n    def left_method(self) -\u003e int:\n        ...\n\nclass IRight(IBase):\n    @abstractmethod\n    def right_method(self) -\u003e bool:\n        ...\n\nclass Diamond(ILeft, IRight):\n    # Can only implement base_method once for IBase\n    @implements(IBase.base_method)\n    def base_impl(self) -\u003e str:\n        return \"base\"\n    \n    @implements(ILeft.left_method)\n    def left_impl(self) -\u003e int:\n        return 42\n    \n    @implements(IRight.right_method)\n    def right_impl(self) -\u003e bool:\n        return True\n\n# Access base_method only through IBase interface\ndiamond = Diamond()\nbase_interface = diamond.as_interface(IBase)\nprint(base_interface.base_method())  # \"base\"\n```\n\n## Error Handling\n\nThe library provides clear error messages for common mistakes:\n\n### Missing Implementation\n\nBy default, partial implementations are allowed:\n\n```python\nclass Incomplete(IDrawable):\n    pass  # Missing @implements for IDrawable.draw\n    # This is allowed by default - no error raised\n```\n\nTo enforce complete implementation, use `concrete=True`:\n\n```python\nclass Concrete(IDrawable, concrete=True):\n    pass  # Missing @implements for IDrawable.draw\n    # Raises: TypeError at class definition time\n```\n\n### Invalid Implementation Target\n\n```python\nclass Invalid(IDrawable):\n    @implements(IPrintable.print_info)  # Wrong interface method\n    def some_method(self) -\u003e str:\n        return \"invalid\"\n    # Raises: TypeError - method not in base interfaces\n```\n\n### Accessing Unimplemented Interface\n\n```python\nclass Partial(IDrawable):\n    @implements(IDrawable.draw)\n    def draw_impl(self) -\u003e str:\n        return \"drawn\"\n\npartial = Partial()\n# This will raise TypeError:\nprintable = partial.as_interface(IPrintable)\n```\n\n## Type Safety\n\nThe library provides full typing support:\n\n```python\nfrom typing import Protocol\n\ndef use_drawable(drawable: IDrawable) -\u003e str:\n    return drawable.draw()\n\ndef process_document(doc: Document) -\u003e tuple[str, str]:\n    drawable = doc.as_interface(IDrawable)  # Type: IDrawable\n    printable = doc.as_interface(IPrintable)  # Type: IPrintable\n    \n    return drawable.draw(), printable.print_info()\n```\n\n## Comparison with ABC\n\n| Feature | ABC | Explicit Implementation |\n|---------|-----|------------------------|\n| Method Names | Must match interface | Can be different |\n| Interface Access | Direct method calls | Through `.as_interface()` |\n| Multiple Interfaces | Name conflicts possible | Clean separation |\n| Implementation Clarity | Implicit | Explicit with `@implements` |\n| Error Detection | Runtime | Compile-time |\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Changelog\n\n### 0.1.1\n- **Bug Fix**: Fixed access to concrete (non-abstract) methods when using `as_interface()`\n- Concrete methods in interfaces can now be properly accessed both directly and through interface casting\n- Added comprehensive test coverage for concrete method access patterns\n- Improved documentation with concrete method usage examples\n\n### 0.1.0\n- Initial release\n- Basic interface and implementation functionality\n- Support for multiple interface implementation\n- Diamond inheritance pattern support\n- Full typing support\n- Comprehensive test coverage\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxpodev%2Fpython-explicit-implementation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxpodev%2Fpython-explicit-implementation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxpodev%2Fpython-explicit-implementation/lists"}