classoptions

Implement namespaced and inheritable metadata at the class level.


License
MIT
Install
pip install classoptions==0.2.0

Documentation

Description

Implement namespaced and inheritable metadata at the class level.

Inspired on Meta classes from Django models and Django Rest Framework model serializers.

Quick Start

Installation

pip install classoptions

Simple inheritance

from classoptions import ClassOptionsMetaclass
from typing import Any

class Pizza(metaclass=ClassOptionsMetaclass):
    _meta: Any
    
    class DefaultMeta:
        client_can_modify = True
        notes = None

    cooking_temp = 400
    cooking_time = 1    

class HawaiianPizza(Pizza):
    ingredients = ["cheese", "ham", "pineapple"]
    
    class Meta:
        notes = "Do not judge the costumer."
        private_note = "If planning a party, ask first if people like it."
        
print("Hawaiian Pizza:")
print("Ingredients:", ", ".join(HawaiianPizza.ingredients))
print("Cooking Temperature (F):", HawaiianPizza.cooking_temp)
print("Cooking Time (hours):", HawaiianPizza.cooking_time)
print("Client can modify:", HawaiianPizza._meta.client_can_modify)
print("Notes:")
print(HawaiianPizza._meta.notes)
print("Private Note:")
print(HawaiianPizza._meta.private_note)

Outputs:

Hawaiian Pizza:
Ingredients: cheese, ham, pineapple
Cooking Temperature (F): 400
Cooking Time (hours): 1
Client can modify: True
Notes:
Do not judge the costumer.
Private Note:
If planning a party, ask first if people like it.

Multiple Inheritance

Works similar to python inheritance, except we don't need to explicitly inherit from the parent class.

from classoptions import ClassOptionsMetaclass
from typing import Any

class A(metaclass=ClassOptionsMetaclass):
    _meta: Any
    class DefaultMeta:
        color = "red"
        size = 2
        hello = "world"
        i_like_pizza = True

class B(A):
    class DefaultMeta:
        color = "blue"
        size = 3

class C(B):
    class Meta:
        size = 4  # Specific to C only

class D(A):
    class DefaultMeta:
        color = "black"
        hello = "country"

class E(D, C):
    class Meta:
        i_like_hawaiian_pizza = "maybe"

print("E custom meta")
print("i_like_hawaiian_pizza:", E._meta.i_like_hawaiian_pizza)

print("\nInherited from B")
print("size:", E._meta.size)

print("\nInherited from D")
print("color:", E._meta.color)
print("hello:", E._meta.hello)

print("\nInherited from A")
print("i_like_pizza:", E._meta.i_like_pizza)

Outputs:

E custom meta
i_like_hawaiian_pizza: maybe

Inherited from B
size: 3

Inherited from D
color: black
hello: country

Inherited from A
i_like_pizza: True

Using other class/attribute names

With ClassOptionsMetaclass.factory you can overwrite how you define default metadata, class specific metadata, and how you access the result.

from classoptions import ClassOptionsMetaclass
from typing import Any

class A(metaclass=ClassOptionsMetaclass.factory("Options", "DefaultOptions", "_options")):
    _options: Any
    
    class DefaultOptions:
        color = "red"
        size = 2

    cooking_temp = 400
    cooking_time = 1    

class B(A):
    class Options:
        color = "blue"
        
print("B color:", B._options.color)
print("B size:", B._options.size)

Outputs:

B color: blue
B size: 2

License

MIT License.