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/*"
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 | |
|---|---|---|---|
| progeny-0.2.0.tar.gz | 3.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| progeny-0.2.0-py2.py3-none-any.whl | Python 2, Python 3 | none | any | Details |
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
|