A mypy plugin to validate at type checking time that all variants of a union type implements a protocol
Project description
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.
Project details
Release history Release notifications | RSS feed
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 constrained_union-0.1.0.tar.gz.
File metadata
- Download URL: constrained_union-0.1.0.tar.gz
- Upload date:
- Size: 3.7 kB
- Tags: Source
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b623122fedde9a64fdb0830692bc4057f37129537f84e7eff6f09fabd57358e5
|
|
| MD5 |
d5800a51f579dee0bbd49190ea351988
|
|
| BLAKE2b-256 |
0453a81b9e6ccc56d24f6107840b52c3123742cc4c94d9ea4c2cf5a9f9f2749d
|
File details
Details for the file constrained_union-0.1.0-py3-none-any.whl.
File metadata
- Download URL: constrained_union-0.1.0-py3-none-any.whl
- Upload date:
- Size: 5.4 kB
- Tags: Python 3
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b2192117d00c97adee11368ab35be60d0ee0b798bcdb098e84b6b7a2b74e4500
|
|
| MD5 |
65607a006ed7daf79cb63cfb1dc97af8
|
|
| BLAKE2b-256 |
23985f7cdb4cfe47ed2475082353107056fb74e5eae9e91d3dda47f742bb69a3
|