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 | Provenance | Actions |
|---|---|---|---|---|
| constrained_union-0.1.0.tar.gz | 3.7 kB | Without provenance | Details for constrained_union-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| constrained_union-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for constrained_union-0.1.0-py3-none-any.whl |
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}
|
Security for constrained-union 0.1.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.