title: kapro description: Class-level, mixed, and pinned descriptors for Python
[ref: #kapro]
kapro
kapro is a small Python library of property descriptors.
It gives you three public entry points:
class_property— a descriptor that lives on the class and is shared by every instance.mixed_property— a descriptor that can be defined on the class but resolved per instance.pin— a cached instance property that stores its value in the instance dictionary.
[ref: #installation]
Installation
Install with uv:
uv add kapro
Or with any PEP 517-compatible tool:
pip install kapro
[ref: #class-property]
Class-level properties with class_property
class_property behaves like a class-level attribute, but it is computed lazily and cached on the class.
from kapro import class_property
class Config:
@class_property
def name(cls) -> str:
return "default"
assert Config.name == "default"
assert Config().name == "default"
The value is stored on the class, so every instance sees the same value.
[ref: #mixed-property]
Mixed properties with mixed_property
mixed_property calls the same function with the class when accessed on the class and with the instance when accessed on an instance.
from kapro import mixed_property
class User:
def __init__(self, id: int) -> None:
self.id = id
@mixed_property
def label(node) -> str:
if isinstance(node, type):
return "User model"
return f"user: {node.id}"
assert User.label == "User model"
assert User(id=7).label == "user: 7"
[ref: #pin]
Cached instance properties with pin
pin is the cached equivalent of a plain method-based property.
The first access computes the value and stores it in the instance dictionary.
from kapro import pin
class Expensive:
@pin
def payload(self) -> dict:
return {"loaded": True}
obj = Expensive()
assert obj.payload is obj.payload
[ref: #pin-flavors]
pin flavors
pin exposes several variants through class attributes.
| Flavor | Decorator | Caches on |
|---|---|---|
native |
@pin |
instance (default) |
cls |
@pin.cls |
class |
any |
@pin.any |
class or instance |
pre |
@pin.pre |
instance, runs before the underlying call |
post |
@pin.post |
instance, runs after the underlying call |
from kapro import pin
class Service:
@pin.cls
def version(cls) -> str:
return "1.0"
assert Service.version == "1.0"
assert Service().version == "1.0"
[ref: #full-example]
Full example
from kapro import class_property, mixed_property, pin
class App:
@class_property
def name(cls) -> str:
return "MyApp"
@mixed_property
def greeting(node) -> str:
return f"Hello from {node.name}"
@pin
def config(self) -> dict:
return {"debug": True}
assert App.name == "MyApp"
assert App.greeting == "Hello from MyApp"
assert App().greeting == "Hello from MyApp"
app = App()
assert app.config == {"debug": True}
assert app.config is app.config
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kapro-0.0.1.tar.gz.
File metadata
- Download URL: kapro-0.0.1.tar.gz
- Upload date:
- Size: 26.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
89cf4ebc21aba887a0bdb4789429acf14a0b28acf148073c58d86486d63353c2
|
|
| MD5 |
f70b241c6e9cfb1e105f17cdd702eb6b
|
|
| BLAKE2b-256 |
471809a9776cad8a05334c5bf3bb1cbe7c82641ae109066c3d10d249c01d3cde
|
File details
Details for the file kapro-0.0.1-py3-none-any.whl.
File metadata
- Download URL: kapro-0.0.1-py3-none-any.whl
- Upload date:
- Size: 20.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
584cbda980ce223cbe735b2744035fb727314f8762098329f77514a0660b1791
|
|
| MD5 |
a3a867f2444369c3cc4a99b804d5cb45
|
|
| BLAKE2b-256 |
b46f44784df8e889919832dd8a0a555d2c6ef3a63118249b5d28e63738c3a9ae
|