{"id":18498535,"url":"https://github.com/xpodev/typeclass","last_synced_at":"2025-10-17T16:31:40.364Z","repository":{"id":91064539,"uuid":"591923513","full_name":"xpodev/typeclass","owner":"xpodev","description":null,"archived":false,"fork":false,"pushed_at":"2023-08-20T11:34:18.000Z","size":10,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-27T22:39:15.577Z","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":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xpodev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2023-01-22T11:13:33.000Z","updated_at":"2023-01-24T22:59:01.000Z","dependencies_parsed_at":null,"dependency_job_id":"ceea39a5-2b43-41d2-8b10-5e2584f69074","html_url":"https://github.com/xpodev/typeclass","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/xpodev/typeclass","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpodev%2Ftypeclass","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpodev%2Ftypeclass/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpodev%2Ftypeclass/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpodev%2Ftypeclass/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xpodev","download_url":"https://codeload.github.com/xpodev/typeclass/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpodev%2Ftypeclass/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267320257,"owners_count":24068527,"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-07-27T02:00:11.917Z","response_time":82,"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":"2024-11-06T13:41:06.523Z","updated_at":"2025-10-17T16:31:40.243Z","avatar_url":"https://github.com/xpodev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Typeclass\n\nWelcome to the `typeclass` Python package! This library allows you to externally implement interface\nin Python, and use classes as if they implemented the typeclass themselves.\n\nLet's see an example usage:\n\n\u003e Suppose we want to create an extensible object model which we need to add support for serializing to\nJSON format. One option that we have is to create a complex serialization function which will iterate\nover a set of attributes and recursively serialize them. Another approach is to let each class implement\nit itself.\n\u003e \n\u003e However, we don't always want to include the serialization code inside the class, or we don't always \n\u003e have access to the type's body. This is where typeclasses come in. Not only do they allow us to extend\n\u003e existing types, but they also allow us to extend types that we don't own. Moreover, they allow us to\n\u003e add types to an hierarchy without modifying the type itself.\n\n\nThis is how we would defint the `JSONSerializable` typeclass:\n\n```python\nfrom typeclass import Typeclass, typeclass_api\n\nclass JSONSerializable(Typeclass):\n    @typeclass_api\n    def serialize(self) -\u003e dict:\n        raise NotImplementedError\n```\n\n\u003e Note that we marked the `serialize` method as abstract. This is because only\nabstract methods are added as methods to the typeclass. If we don't mark it as abstract, it will not be added to implemented types afterwards.\n\nNow, let's define a class that implements the typeclass.\nWe can use the `Typeclass[:]` or `Typeclass[...]` syntax to indicate that the class implements the typeclass.\n\n```python\nclass Person(JSONSerializable[:]):\n    def __init__(self, name: str, age: int):\n        self.name = name\n        self.age = age\n\n    def serialize(self) -\u003e dict:\n        return {\n            \"name\": self.name,\n            \"age\": self.age\n        }\n```\n\nThis is how we'll implement the typeclass on an existing type, such as `dict`:\n\n```python\nclass _(JSONSerializable[dict]):\n    def serialize(self) -\u003e dict:\n        return {\n            key.serialize(): value.serialize()\n            for key, value in self.items()\n        }\n```\n\n\nThen, we can directly use these methods:\n```python\n\u003e\u003e\u003e Person(\"John\", 20).serialize()\n{\"name\": \"John\", \"age\": 20}\n\n\u003e\u003e\u003e isinstance(Person(\"John\", 20), JSONSerializable)\nTrue\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxpodev%2Ftypeclass","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxpodev%2Ftypeclass","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxpodev%2Ftypeclass/lists"}