{"id":15018791,"url":"https://github.com/matteoguadrini/pyrrole","last_synced_at":"2025-10-03T22:30:43.941Z","repository":{"id":62583265,"uuid":"377508531","full_name":"MatteoGuadrini/pyrrole","owner":"MatteoGuadrini","description":"Role system for Python3","archived":true,"fork":false,"pushed_at":"2021-08-28T06:07:09.000Z","size":65,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-16T09:16:34.984Z","etag":null,"topics":["decorators","python-class","python-metaclasses","python3","role","role-api","role-library","roles"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MatteoGuadrini.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-06-16T13:38:03.000Z","updated_at":"2024-11-24T03:59:53.000Z","dependencies_parsed_at":"2022-11-03T21:50:27.265Z","dependency_job_id":null,"html_url":"https://github.com/MatteoGuadrini/pyrrole","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MatteoGuadrini%2Fpyrrole","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MatteoGuadrini%2Fpyrrole/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MatteoGuadrini%2Fpyrrole/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MatteoGuadrini%2Fpyrrole/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MatteoGuadrini","download_url":"https://codeload.github.com/MatteoGuadrini/pyrrole/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235198395,"owners_count":18951499,"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","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":["decorators","python-class","python-metaclasses","python3","role","role-api","role-library","roles"],"created_at":"2024-09-24T19:52:28.050Z","updated_at":"2025-10-03T22:30:38.618Z","avatar_url":"https://github.com/MatteoGuadrini.png","language":"Python","funding_links":["https://www.paypal.me/guos"],"categories":[],"sub_categories":[],"readme":"# pyrrole\n\n\u003cimg src=\"img/Pyrrole_structure.svg\" alt=\"pyrrole formula\" title=\"pyrrole\" width=\"300\" height=\"300\" /\u003e\n\n_pyrrole_ is a Role System for Python3 (3.6 and high). \nIt's inspired by the roles implementation in the [Moose library of Perl](https://metacpan.org/pod/Moose::Role), \nand its main purpose is to use instead of Mixin classes and multiple inheritance.\n\n\u003e ATTENTION: This package is **WIP** in _alpha_ release\n\n## Test\n\nIf you would test before install, follow these instructions:\n```console\n$ git clone https://github.com/MatteoGuadrini/pyrrole.git\n$ cd pyrrole\n$ python -m unittest test_role.py\n```\n\n## Install\n\nFor install this package, run pip install:\n```console\n$ pip install --user pyrrole\n```\n\n\n## Simple role\n\nHere is an example of how a role can be done:\n\n```python\nimport pyrrole\n\nclass FallFromTree(metaclass=pyrrole.Role):\n    pass\n\nclass Fruit:\n    pass\n\n@FallFromTree\nclass Apple(Fruit):\n    pass\n\napple = Apple()\n\nprint(apple.__roles__)\n```\n\nIn this example, the `Apple` class inherits from `Fruit` but not `FallFromTree`. \n`FallFromTree` is a role class that applies to classes so that they acquire the **__roles__** attribute.\n\n## Role method\n\nBy default, all methods or attribute is inherited from a role class except the dunder methods (ex. `__str__`).. \nTo force the import of a dunder or normal method, just enclose the method to inherit in a _role_method_ decorator.\n\n```python\nimport pyrrole\n\nclass FallFromTree(metaclass=pyrrole.Role):\n    \n    @pyrrole.role_method\n    def __str__(cls):\n        return f\"Fall from tree\"\n\nclass Fruit:\n    pass\n\n@FallFromTree\nclass Apple(Fruit):\n    pass\n\napple = Apple()\n\nprint(apple)\n```\n\n## More roles\n\nAn ordinary class can have multiple roles at the same time.\n\n```python\nimport pyrrole\n\n@pyrrole.role                                  # use role with decorator\nclass FallFromTree:\n    \n    def __init__(self, instance):\n        self.trees = list()\n        self.trees.append(instance)\n    \n    def fall(self, tree='tree'):\n        return f\"Fall from {tree}\"\n    \n@pyrrole.role                                   # use role with decorator\nclass Deciduous:\n    \n    def __init__(self, instance):\n        self.trees = list()\n        self.trees.append(instance)\n    \n    def clean_leaf(self):\n        return f\"Clean all leaf\"\n\nclass Fruit:\n    pass\n\n@pyrrole.apply_roles(FallFromTree, Deciduous)               # apply more role at same time\n@pyrrole.rename_role_methods(clean_leaf='clean_apple_leaf') # renamed role names\nclass Apple(Fruit):\n    def clean_leaf(self):\n        return f\"Clean all leaf of apple tree\"\n\napple = Apple()\n\n# apple has role?\npyrrole.has_role(apple, FallFromTree)   # True\npyrrole.has_role(apple, Deciduous)      # True\n\nprint(apple.__roles__)                  # ['FallFromTree', 'Deciduous']\nprint(apple.clean_apple_leaf())         # method renamed from the Deciduous role\nprint(apple.fall('apple tree'))         # method forced inherited from the FallFromTree role\n```\n\n## Open source\n_pyrrole_ is an open source project. Any contribute, It's welcome.\n\n**A great thanks**.\n\nFor donations, press this\n\nFor me\n\n[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.me/guos)\n\nFor [Telethon](http://www.telethon.it/)\n\nThe Telethon Foundation is a non-profit organization recognized by the Ministry of University and Scientific and Technological Research.\nThey were born in 1990 to respond to the appeal of patients suffering from rare diseases.\nCome today, we are organized to dare to listen to them and answers, every day of the year.\n\n\u003ca href=\"https://www.telethon.it/sostienici/dona-ora\"\u003e \u003cimg src=\"https://www.telethon.it/dev/_nuxt/img/c6d474e.svg\" alt=\"Telethon\" title=\"Telethon\" width=\"200\" height=\"104\" /\u003e \u003c/a\u003e\n\n[Adopt the future](https://www.ioadottoilfuturo.it/)\n\n\n## Acknowledgments\n\nThanks to [Giacomo Montagner](https://github.com/kromg) for having the idea. Besides, being a contributor he is a great friend!\n\nThanks to Mark Lutz for writing the _Learning Python_ and _Programming Python_ books that make up my python foundation.\n\nThanks to Kenneth Reitz and Tanya Schlusser for writing the _The Hitchhiker’s Guide to Python_ books.\n\nThanks to Dane Hillard for writing the _Practices of the Python Pro_ books.\n\nSpecial thanks go to my wife, who understood the hours of absence for this development. \nThanks to my children, for the daily inspiration they give me and to make me realize, that life must be simple.\n\nThanks Python!","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatteoguadrini%2Fpyrrole","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmatteoguadrini%2Fpyrrole","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatteoguadrini%2Fpyrrole/lists"}