constrained-union
A mypy plugin that verifies every member of a union type implements a given protocol. Catches missing protocol implementations at type-check time, not at runtime.
Installation
Get the package
Install with pip:
pip install constrained-union
Or add constrained-union to your project's dev dependencies:
[dependency-groups]
dev = ["constrained_union"]
Plugin registration
Add to your mypy.ini (or [tool.mypy] section in pyproject.toml):
[mypy]
plugins = constrained_union.mypy_plugin
Usage
Suppose we implement the following types:
from dataclasses import dataclass
@dataclass
class Rectangle:
width: float
height: float
@property
def area(self) -> float:
return self.width * self.height
@dataclass
class Circle:
radius: float
type Shape = Rectangle | Circle
Since Shape is a union type and not a true sum algebraic data type, and python does not provide a way to make sure that each variant of the union type implements certain methods or properties.
In this case, let's suppose we want to enforce that each Shape variant must implement an area property.
from typing import Protocol
class ShapeProperties(Protocol):
@property
def area(self): ...
Adding the following code will trigger an mypy error when performing type checking.
from typing import TYPE_CHECKING
from constrained_union import assert_union_implements
if TYPE_CHECKING:
assert_union_implements[Shape, ShapeProperties]()
# error: Union member "Circle" does not implement protocol "ShapeProperties"
# error: Missing member: area
The call must be placed inside if TYPE_CHECKING: so it does not run at runtime.
Contributing
Contributions are welcome! Feel free to open an issue to report a bug or suggest a feature, or submit a pull request directly. Please follow the guidelines described in CONTRIBUTING.md.
Metadata
Release files for constrained-union 0.1.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 | |
|---|---|---|---|
| constrained_union-0.1.0.tar.gz | 3.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| constrained_union-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 9.1 kB
Release files / constrained_union-0.1.0.tar.gz
| Download URL | constrained_union-0.1.0.tar.gz |
|---|---|
| Size | 3.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b623122fedde9a64fdb0830692bc4057f37129537f84e7eff6f09fabd57358e5
|
|
BLAKE2b-256 checksum How to use checksums |
0453a81b9e6ccc56d24f6107840b52c3123742cc4c94d9ea4c2cf5a9f9f2749d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / constrained_union-0.1.0-py3-none-any.whl
| Download URL | constrained_union-0.1.0-py3-none-any.whl |
|---|---|
| Size | 5.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b2192117d00c97adee11368ab35be60d0ee0b798bcdb098e84b6b7a2b74e4500
|
|
BLAKE2b-256 checksum How to use checksums |
23985f7cdb4cfe47ed2475082353107056fb74e5eae9e91d3dda47f742bb69a3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|