Skip to main content

paramclass-pyomo

paramclass-pyomo adapts Pyomo's imperative modeling API to declarative, class-body model definitions.

It is built on top of paramclass and lets you describe Pyomo components as class attributes, then materialize them onto a pyomo.environ.Block or ConcreteModel.

import pyomo.environ as pyo
from paramclass_pyomo import AbstractBlock


class ToyBlock(AbstractBlock):
    x = pyo.Var(initialize=3)
    c = pyo.Constraint(rule=lambda m: m.x >= 1)
    e = pyo.Expression(rule=lambda m: m.x + 1)
    o = pyo.Objective(rule=lambda m: m.e)


model = pyo.ConcreteModel()
ToyBlock().build(model)

assert pyo.value(model.x) == 3
assert str(model.c.expr) == "1  <=  x"

The goal is to make reusable Pyomo model pieces easier to package, override, compose, test, lint, and statically analyze.

Project Timeline

paramclass-pyomo was developed during 2023-2024 and has been used in production workflows since 2023. Public packaging was added in 2025, and public documentation was added in 2026 to make the project easier to evaluate, install, and reuse outside its original environment.

Install

pip install paramclass-pyomo

For local development alongside paramclass:

uv sync --extra dev
uv run --extra dev pytest

The local UV configuration uses ../paramclass as an editable dependency.

Why

Pyomo is powerful, but reusable model structure often ends up split across factory functions, ad hoc builders, and imperative component assignment:

model = pyo.ConcreteModel()
model.capacity = pyo.Param(initialize=100, mutable=True)
model.used = pyo.Var(bounds=(0, None))
model.limit = pyo.Constraint(rule=lambda m: m.used <= m.capacity)

That style is natural for Pyomo, but it gives developer tooling less structure to inspect. Class-based definitions provide a stable surface for code review, linting, static analysis, generated documentation, and model composition.

AbstractBlock keeps Pyomo's component model, while giving each reusable block a compact Python class definition:

class CapacityBlock(AbstractBlock):
    capacity = pyo.Param(initialize=100, mutable=True)
    used = pyo.Var(bounds=(0, None))
    limit = pyo.Constraint(rule=lambda m: m.used <= m.capacity)

Then build it onto a model:

model = pyo.ConcreteModel()
CapacityBlock().build(model)

This keeps the imperative construction where Pyomo expects it, while moving the authoring experience toward a declarative design.

Examples

Standard Pyomo Keyword Style

Normal Pyomo keyword construction is supported. Use rule= for constraints, expressions, and objectives, and initialize= for parameters and variables.

class ObjectiveBlock(AbstractBlock):
    p = pyo.Param(initialize=7, mutable=True)
    x = pyo.Var(initialize=lambda m: pyo.value(m.p) + 1)
    objective = pyo.Objective(rule=lambda m: m.x)

Shorthand Rule Calls

paramclass-pyomo also supports a shorthand callable style for rules:

class ConstraintBlock(AbstractBlock):
    x = pyo.Var(initialize=3)
    c = pyo.Constraint()(lambda m: m.x >= 1)

This is optional. The standard Pyomo rule= form is usually clearer for public examples and team code.

Nested Blocks

AbstractBlock instances can be assigned as attributes of other AbstractBlocks. Nested blocks are finalized onto the parent block during construction.

class Inner(AbstractBlock):
    x = pyo.Var(initialize=1)


class Outer(AbstractBlock):
    inner = Inner()
    cap = pyo.Constraint(rule=lambda m: m.inner.x <= 10)


model = pyo.ConcreteModel()
Outer().build(model)

Indexed Blocks

Pass indexing arguments to the block constructor when defining nested blocks:

class Unit(AbstractBlock):
    x = pyo.Var(initialize=1)


class System(AbstractBlock):
    units = Unit(["a", "b", "c"])

When a block is indexed, component construction is applied across each block data object.

How It Works

AbstractBlock extends ParamClass and redirects public attribute assignment to the underlying Pyomo block. During build(model), deferred class-body definitions are evaluated and attached to the target model or block.

This lets a Pyomo block definition look declarative to developers and tooling, while still executing through Pyomo's normal component lifecycle.

Pyomo components that already belong to another block are wrapped with a small proxy so they can still be referenced safely from generated components.

Current Limitations

This project intentionally stays close to Pyomo's component model. If a Pyomo constructor requires keyword arguments such as rule= or initialize=, prefer using those explicit keywords in public code.

As with paramclass, Python boolean operators such as and, or, and not are not deferred by the tracing layer.

Testing

uv run --extra dev pytest

Release files for paramclass-pyomo 1.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for paramclass-pyomo 1.1.1
File Size Uploaded
paramclass_pyomo-1.1.1.tar.gz 8.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for paramclass-pyomo 1.1.1
File Interpreter ABI Platform
paramclass_pyomo-1.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 15.6 kB

Release files / paramclass_pyomo-1.1.1.tar.gz

Download URL paramclass_pyomo-1.1.1.tar.gz
Size 8.5 kB
Tags Source
SHA-256 checksum
How to use checksums
fac82f7bb02f414686ae5ed6887d59b461048e950152683fe01e9294e393de9c
BLAKE2b-256 checksum
How to use checksums
6d3a8427ed887ac6d78348468bba7692e33dcbd463a2df4a831267ca90a442c0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / paramclass_pyomo-1.1.1-py3-none-any.whl

Download URL paramclass_pyomo-1.1.1-py3-none-any.whl
Size 7.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1162c6c058fa862aabc785ea13527e8b486b89b510ae7e82dcd043c3ff644d49
BLAKE2b-256 checksum
How to use checksums
ae29a655df684d8a779764aa76eff51bf5259670f718b69d38c841e4c963fc2f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release history Release notifications | RSS feed

This release

1.1.1 This release

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page