Progeny
Simple (but powerful) management for complex class hierarchies.
Motivation
While XYZClass.__subclasses__() returns the children of a class, there is no built-in way to return all descendants. This is the core of Progeny’s purpose.
In addition, Progeny provides tools to help manage complex, deeply nested class hierarchies - hiding individual classes, keeping a registry of descendants, etc.
Examples
Basic Usage
import progeny
class NotificationHandler(progeny.Base):
def send_message(self, *args, **kwargs):
raise RuntimeError
class CustomerOneNotificationHandler(NotificationHandler):
def send_message(self, *args, **kwargs):
# .. business logic ...
class CustomerTwoNotificationHandler(NotificationHandler):
def send_message(self, *args, **kwargs):
# .. business logic ...
Now we can iterate over all of the subclasses of NotificationHandler:
def send_newsletter():
for handler in NotificationHandler.progeny.values():
handler.send_message('Your attention, please!')
Omitting descendant classes
In some cases, it may be useful to prevent descendant classes from being visible to Progeny.
from progeny import progeny.Base
class NotificationHandler(progeny.Base):
def send_message(self, *args, **kwargs):
raise RuntimeError
class EmailNotificationHandler(NotificationHandler):
__progeny_tracked__ = False
def send_message(self, *args, **kwargs):
# .. business logic ..
class SmsNotificationHandler(NotificationHandler):
__progeny_tracked__ = False
def send_message(self, *args, **kwargs):
# .. business logic ..
class CustomerOneNotificationHandler(EmailNotificationHandler):
pass
class CustomerTwoNotificationHandler(SmsNotificationHandler):
pass
Any classes with __progeny_tracked__ set to a falsy value during class construction will be ignored by Progeny. It’s descendant classes are unaffected:
NotificationHandler.progeny.values()
# {CustomerOneNotificationHandler, CustomerTwoNotificationHandler}
This can be especially handy to conditionally track subclasses based on config context:
class CustomerFooNotificationHandler(EmailNotificationHandler):
__progeny_tracked__ = config.get('CUSTOMER_FOO_ACTIVE')
Using the descendants registry
Progeny makes it easy to choose between descendant classes at runtime:
from progeny import progeny.Base
from my_app.users import UserLevel
class UploadParser(progeny.Base):
pass
class FreeUserUploadParser(UploadParser):
__progeny_key__ = UserLevel.FREE
def parse_upload(self, *args, **kwargs):
# .. logic to parse the upload slowly, using shared resources
class PremiumUserUploadParser(UploadParser):
__progeny_key__ = UserLevel.PAID
def parse_upload(self, *args, **kwargs):
# .. logic to parse the upload immediately with dedicated resources
def parse_upload(data):
UploadParser.progeny.get(session.user.level).parse_upload(data)
Publishing to PyPI
python setup.py sdist bdist_wheel
twine upload "dist/*"
Metadata
Release files for progeny 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| progeny-0.2.0.tar.gz | 3.6 kB | Without provenance | Details for progeny-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| progeny-0.2.0-py2.py3-none-any.whl | Python 3, Python 2 | none | any | Details for progeny-0.2.0-py2.py3-none-any.whl |
Total release size: 7.4 kB
Release files / progeny-0.2.0.tar.gz
| Download URL | progeny-0.2.0.tar.gz |
|---|---|
| Size | 3.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a8cd110c5277590f6f6b9086f6bb7c45b91d1b5917032b43ad15a0bccd050f00
|
|
BLAKE2b-256 checksum How to use checksums |
d413dae926c5e5588615d81ce0e9361410f717f1c8fb34569167601350fdb30f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.1.1 requests-toolbelt/0.9.1 tqdm/4.47.0 CPython/3.8.5
|
Release files / progeny-0.2.0-py2.py3-none-any.whl
| Download URL | progeny-0.2.0-py2.py3-none-any.whl |
|---|---|
| Size | 3.8 kB |
| Tags | Python 2 Python 3 |
|
SHA-256 checksum How to use checksums |
f16c3e0308dae61f1a4f75c478679a798098fa8215067e4d45ba061f6a616d31
|
|
BLAKE2b-256 checksum How to use checksums |
9a7aa75519844f8c2eea2072bf9fa8465da93474a5d6ee9ca828f9ca60f1d3f9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.1.1 requests-toolbelt/0.9.1 tqdm/4.47.0 CPython/3.8.5
|
Security for progeny 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.