Constrained Values
A lightweight Python library for creating type-safe, self-validating value objects — transforming primitive data into meaningful, domain-aware objects with rich validation and transformation pipelines.
🧭 Philosophy: Beyond Primitive Types
In most codebases, we pass around raw values without context:
- Is
temperature = 25Celsius or Fahrenheit? - Is
spi_mode = 2valid for this device? - What does
-32768mean again?
Primitive values lack meaning, constraints, and domain intent.
This is Primitive Obsession — a subtle but pervasive design smell.
Constrained Values replaces primitives with expressive, validated objects that make validity explicit.
Each object carries its status (OK or EXCEPTION) and associated errors.
By default, invalid values can exist safely and report their state — but if you want to enforce strict invariants, you can enable exception mode to raise immediately on invalid input.
✨ Features
- 🧩 Rich Value Objects – Replace primitives with expressive, validated domain objects.
- 🔗 Composable Pipelines – Chain multiple validation and transformation strategies.
- 🧠 Built-in Validators – Range checks, enums, type coercion, and more.
- ⚙️ Custom Logic – Easily extend with your own domain-specific rules.
- 🚦 Clear Error Handling – Track validation status and descriptive messages.
- 🧯 Strict/Exception Mode (optional) – By default, invalid values are reported non-destructively; enable strict mode to raise exceptions and enforce invariants at creation.
- 🧾 Type-Safety – Each value enforces its canonical type at runtime.
🚀 Installation
pip install constrained-values
💡 Quick Example
from constrained_values import RangeValue
class Temperature(RangeValue):
"""Temperature constrained between 0 and 100°C."""
def __init__(self, value):
super().__init__(value, low_value=0, high_value=100)
def main() -> None:
# ✅ Valid temperature
t = Temperature(42)
print("Value:", t.value) # 42
print("Status:", t.status.name) # OK
print("Details:", t.details) # validation successful
# 🚫 Invalid temperature
t_invalid = Temperature(120)
print("Value:", t_invalid.value) # None
print("Status:", t_invalid.status) # Status.EXCEPTION
print("Details:", t_invalid.details) # Value must be less than or equal to 100, got 120
if __name__ == "__main__":
main()
🔥 Strict version
If you want the behavior where invalid input throws immediately, use the StrictValue mixin:
class StrictTemperature(RangeValue, StrictValue):
"""Same range constraint but raises if invalid."""
def __init__(self, value):
RangeValue.__init__(self, value, low_value=0, high_value=100)
def main() -> None:
t = StrictTemperature(42)
print("Value:", t.value) # 42
try:
StrictTemperature(120)
except ValueError as e:
print(e) # Failed Constraints for value - '120': Value must be less than or equal to 100, got 120
if __name__ == "__main__":
main()
Metadata
Release files for constrained-values 0.1.7
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| constrained_values-0.1.7.tar.gz | 25.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| constrained_values-0.1.7-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 41.2 kB
Release files / constrained_values-0.1.7.tar.gz
| Download URL | constrained_values-0.1.7.tar.gz |
|---|---|
| Size | 25.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dee6be3bc64f2d993319116273d3f0ee4cb35bc529baa888e6c14c7eb3aecedd
|
|
BLAKE2b-256 checksum How to use checksums |
e89f43fb1f93048532082a5387a48d720de6eeee9af128502e4a3a9fece5dc11
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 26, 2025.
Transparency logRelease files / constrained_values-0.1.7-py3-none-any.whl
| Download URL | constrained_values-0.1.7-py3-none-any.whl |
|---|---|
| Size | 15.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cf93cbbb92997e7540300207c89e5fa5bf258b2ad7c8b06ead9dff28398f9910
|
|
BLAKE2b-256 checksum How to use checksums |
8a4c9f76e9a1c5a249678449e997def2cc2fb47b65a72b7f858f6b452eeef516
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 26, 2025.
Transparency log