Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
74aee3f
Introduce formal principle documentation to support contrib changes
mrmundt Oct 21, 2025
ca02f4e
Found a weird phrasing that I missed when proofreading
mrmundt Oct 21, 2025
8e18ee1
Whoops, no init files
mrmundt Oct 22, 2025
4822e6d
Move redundant information and do a big rework of contribution guide
mrmundt Oct 22, 2025
9e4b67c
Typo
mrmundt Oct 22, 2025
5f37e4a
Merge branch 'main' into addons-devel
blnicho Oct 27, 2025
1be9b29
Wrong word in contribution guide
mrmundt Oct 27, 2025
5d7f102
Minor corrections in installation docs
blnicho Oct 27, 2025
ed7f9dd
Address blnicho's comments
mrmundt Oct 28, 2025
6999a91
Merge branch 'main' into addons-devel
mrmundt Oct 28, 2025
cff39eb
Add convention about printing to stdout
mrmundt Oct 28, 2025
1b023a8
Merge branch 'main' into addons-devel
blnicho Oct 29, 2025
ce089c4
Merge branch 'main' into addons-devel
mrmundt Nov 4, 2025
af64211
Merge branch 'main' into addons-devel
mrmundt Jan 21, 2026
9c03e5a
Merge branch 'main' into addons-devel
mrmundt Jan 21, 2026
f12f1f7
Save state: Partially addressed comments
mrmundt Jan 21, 2026
31698dc
Merge branch 'main' into addons-devel
mrmundt Jan 23, 2026
8feac13
Update READMEs to have them point to official guidelines
mrmundt Jan 23, 2026
92b607c
Missing end-bold-note
mrmundt Jan 23, 2026
9306204
Merge branch 'main' of github.com:pyomo/pyomo into addons-devel
mrmundt Jan 26, 2026
64b25da
Add all the extra suggested principles
mrmundt Jan 26, 2026
7bdffc1
Missed one principle about logging
mrmundt Jan 26, 2026
854c0c0
Get rid of examples package, put it in docs instead
mrmundt Jan 26, 2026
88f7cae
Remove example from environ
mrmundt Jan 27, 2026
7eccf54
Merge branch 'main' of github.com:pyomo/pyomo into addons-devel
mrmundt Feb 4, 2026
a0c3d47
Apply @jsiirola requested changes
mrmundt Feb 4, 2026
46e9c7b
Address @blnicho 's comments
mrmundt Feb 9, 2026
dc97bbc
Missed colon
mrmundt Feb 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ __pycache__/
*.egg-info/

# Documentation builds
doc/OnlineDocs/api
Comment thread
mrmundt marked this conversation as resolved.
doc/OnlineDocs/_build
doc/OnlineDocs/**/*.spy

Expand Down
189 changes: 142 additions & 47 deletions doc/OnlineDocs/contribution_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,35 @@ at least 70% coverage of the lines modified in the PR and prefer coverage
closer to 90%. We also require that all tests pass before a PR will be
merged.

Tests must import the Pyomo test harness from
``pyomo.common.unittest`` instead of using Python's built-in
``unittest`` module directly. This wrapper extends the standard testing
framework with Pyomo-specific capabilities, including automatic plugin
discovery, solver availability checks, and improved test filtering
controls. Using the provided interface ensures that all tests run
Comment thread
mrmundt marked this conversation as resolved.
Outdated
consistently across Pyomo's multiple CI environments.
A small example is shown below:

.. code-block:: python

import pyomo.common.unittest as unittest

class TestSomething(unittest.TestCase):
def test_basic(self):
self.assertEqual(1 + 1, 2)

Developers can also use any of the predefined ``pytest`` markers to categorize
their tests appropriately.
Markers are declared in ``pyproject.toml``. Some commonly used markers are:

- ``expensive``: tests that take a long time to run
- ``mpi``: tests that require MPI
- ``solver(name)``: dynamic marker to label a test for a specific solver,
e.g., ``@pytest.mark.solver("gurobi")``
Comment thread
mrmundt marked this conversation as resolved.

More details about Pyomo-defined default test behavior can be found in
the `conftest.py file <https://github.com/Pyomo/pyomo/blob/main/conftest.py>`_.

.. note::
If you are having issues getting tests to pass on your Pull Request,
please tag any of the core developers to ask for help.
Expand Down Expand Up @@ -336,33 +365,48 @@ Finally, move to the directory containing the clone of your Pyomo fork and run:

::

pip install -e .
pip install -e .[tests,docs,optional]
Comment thread
mrmundt marked this conversation as resolved.

These commands register the cloned code with the active python environment
Comment thread
mrmundt marked this conversation as resolved.
Outdated
(``pyomodev``). This way, your changes to the source code for ``pyomo`` are
(``pyomodev``) and installs all possible optional dependencies.
This way, your changes to the source code for ``pyomo`` are
Comment thread
mrmundt marked this conversation as resolved.
Outdated
automatically used by the active environment. You can create another conda
environment to switch to alternate versions of pyomo (e.g., stable).

.. note::

The ``optional`` and ``docs`` dependencies are not strictly required;
however, we recommend installing them to ensure that a large number of
tests can be run locally. Optional packages that are not available will
cause tests to skip.

Review Process
--------------

After a PR is opened it will be reviewed by at least two members of the
core development team. The core development team consists of anyone with
write-access to the Pyomo repository. Pull requests opened by a core
write-access to the Pyomo repository. PRs opened by a core
developer only require one review. The reviewers will decide if they
think a PR should be merged or if more changes are necessary.

Reviewers look for:

* Outside of ``pyomo.contrib``: Code rigor and standards, edge cases,
side effects, etc.
* Inside of ``pyomo.contrib``: No “glaringly obvious” problems with
the code
* Documentation and tests

The core development team tries to review pull requests in a timely
manner but we make no guarantees on review timeframes. In addition, PRs
might not be reviewed in the order they are opened in.
* **Core and Addons:** Code rigor, standards compliance, test coverage above
a threshold, and avoidance of unintended side effects (e.g., regressions)
Comment thread
mrmundt marked this conversation as resolved.
Outdated
* **Devel:** Basic code correctness and clarity, with an understanding that
these areas are experimental and evolving
* **All areas:** Code formatting (using ``black``), documentation, and tests

.. note::

For more information about Pyomo's development principles and the
stability expectations for ``addons`` and ``devel``, see
:doc:`/principles`.

The core development team tries to review PRs in a timely
manner, but we make no guarantees on review timeframes. In addition, PRs
might not be reviewed in the order in which they are opened.
Comment thread
mrmundt marked this conversation as resolved.
Outdated


Where to put contributed code
-----------------------------
Expand All @@ -372,58 +416,110 @@ git repository. Next, you should create a branch on your fork dedicated
to the development of the new feature or bug fix you're interested
in. Once you have this branch checked out, you can start coding. Bug
fixes and minor enhancements to existing Pyomo functionality should be
made in the appropriate files in the Pyomo code base. New examples,
features, and packages built on Pyomo should be placed in
``pyomo.contrib``. Follow the link below to find out if
``pyomo.contrib`` is right for your code.

``pyomo.contrib``
-----------------

Pyomo uses the ``pyomo.contrib`` package to facilitate the inclusion
of third-party contributions that enhance Pyomo's core functionality.
The are two ways that ``pyomo.contrib`` can be used to integrate
third-party packages:

* ``pyomo.contrib`` can provide wrappers for separate Python packages, thereby
allowing these packages to be imported as subpackages of pyomo.

* ``pyomo.contrib`` can include contributed packages that are developed and
maintained outside of the Pyomo developer team.

Including contrib packages in the Pyomo source tree provides a
made in the appropriate files in the Pyomo code base.

Larger features, new modeling components, or experimental functionality
should be placed in one of Pyomo's extension namespaces, described below.

Namespaces for Contributed and Experimental Code
++++++++++++++++++++++++++++++++++++++++++++++++

Pyomo has a long history of supporting community-developed extensions.
Comment thread
mrmundt marked this conversation as resolved.
Outdated
Historically, all such contributions were placed under the
``pyomo.contrib`` namespace. This structure allowed new modeling tools and
algorithms to be shared quickly, but over time it became difficult for users
to distinguish between more stable, supported functionality and
experimental or research-oriented code.

As a result, Pyomo is transitioning to a more structured contribution
model with two clear namespaces:

Comment thread
mrmundt marked this conversation as resolved.
* ``pyomo.addons`` – For mostly stable, supported extensions that build on
the Pyomo core. These packages are maintained by dedicated
contributors, follow Pyomo's coding and testing standards, and adhere
to the same backwards compatibility and deprecation policies as the
rest of the codebase.

* ``pyomo.devel`` – For experimental or rapidly evolving
contributions. These modules serve as early experimentation for research ideas,
prototypes, or specialized modeling components. Functionality under
this namespace may change or be removed between releases without
deprecation warnings.

Comment thread
mrmundt marked this conversation as resolved.
This two-tiered structure provides contributors a clear pathway from
**experimentation to supported integration**, while protecting users from
unexpected changes in stable areas of the codebase.

.. list-table::
:header-rows: 1
:widths: 20 30 50

* - Namespace
- Intended Use
- Stability
* - ``pyomo.devel``
- Active research and experimental code
- Unstable; APIs may change without warning
* - ``pyomo.addons``
- Mostly stable, supported extensions maintained by contributors
- Mostly stable APIs; follow Pyomo's standards
* - ``pyomo``
- Core Pyomo modeling framework
- Fully supported and versioned

For specific inclusion requirements and maintenance expectations for each
namespace, see each directory's accompanying ``README.md``.

Submitting a Contributed Package
--------------------------------

Including contributed packages in the Pyomo source tree provides a
convenient mechanism for defining new functionality that can be
optionally deployed by users. We expect this mechanism to include
optionally deployed by users. We expect this mechanism to include
Pyomo extensions and experimental modeling capabilities. However,
contrib packages are treated as optional packages, which are not
maintained by the Pyomo developer team. Thus, it is the responsibility
contributed packages are treated as optional packages, which are not
maintained by the Pyomo developer team. Thus, it is the responsibility
Comment thread
mrmundt marked this conversation as resolved.
Outdated
of the code contributor to keep these packages up-to-date.

Contrib package contributions will be considered as pull-requests,
which will be reviewed by the Pyomo developer team. Specifically,
Contributed packages will be considered as pull requests,
which will be reviewed by the Pyomo developer team. Specifically,
this review will consider the suitability of the proposed capability,
whether tests are available to check the execution of the code, and
whether documentation is available to describe the capability.
Contrib packages will be tested along with Pyomo. If test failures
Contributed packages will be tested along with Pyomo. If test failures
arise, then these packages will be disabled and an issue will be
created to resolve these test failures.
created to resolve these test failures. The Pyomo team reserves the
right to remove contributed packages that are not maintained.

Contrib Packages within Pyomo
+++++++++++++++++++++++++++++
When submitting a new contributed package (under either ``addons`` or
Comment thread
mrmundt marked this conversation as resolved.
Outdated
``devel``), please ensure that:

* The package has at least one maintainer responsible for its upkeep.
* The code includes tests that can be run through Pyomo's
continuous integration framework.
* The package includes a README or module-level documentation that
clearly describes its purpose and usage.
Comment thread
mrmundt marked this conversation as resolved.
Outdated
* Optional dependencies are properly declared in ``setup.py``
under the appropriate ``[optional]`` section.
* The contribution passes all standard style and formatting checks.

Comment thread
mrmundt marked this conversation as resolved.
Contributed Packages within Pyomo
+++++++++++++++++++++++++++++++++

Third-party contributions can be included directly within the
Comment thread
mrmundt marked this conversation as resolved.
Outdated
``pyomo.contrib`` package. The ``pyomo/contrib/example`` package
``pyomo.devel`` or ``pyomo.addons`` namespaces.
The ``pyomo/devel/example`` package
provides an example of how this can be done, including a directory
for plugins and package tests. For example, this package can be
imported as a subpackage of ``pyomo.contrib``::
for plugins and package tests. For example, this package can be
imported as a subpackage of ``pyomo.devel``::

import pyomo.environ as pyo
from pyomo.contrib.example import a
from pyomo.devel.example import a

# Print the value of 'a' defined by this package
print(a)

Although ``pyomo.contrib.example`` is included in the Pyomo source
Although ``pyomo.devel.example`` is included in the Pyomo source
tree, it is treated as an optional package. Pyomo will attempt to
import this package, but if an import failure occurs, Pyomo will
silently ignore it. Otherwise, this pyomo package will be treated
Expand All @@ -432,4 +528,3 @@ like any other. Specifically:
* Plugin classes defined in this package are loaded when ``pyomo.environ`` is loaded.

* Tests in this package are run with other Pyomo tests.

16 changes: 7 additions & 9 deletions doc/OnlineDocs/getting_started/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,16 @@ the following in a shell:
pip install pyomo


Conditional Dependencies
~~~~~~~~~~~~~~~~~~~~~~~~
Optional Dependencies
~~~~~~~~~~~~~~~~~~~~~

Extensions to Pyomo, and many of the contributions in ``pyomo.contrib``,
Comment thread
mrmundt marked this conversation as resolved.
often have conditional dependencies on a variety of third-party Python
often depend on additional third-party Python
packages including but not limited to: matplotlib, networkx, numpy,
openpyxl, pandas, pint, pymysql, pyodbc, pyro4, scipy, sympy, and
xlrd.
openpyxl, pandas, pint, scipy, sympy, and xlrd.

A full list of optional dependencies can be found in Pyomo's
``pyproject.toml`` under the ``[project.optional-dependencies]`` table.
They can be displayed by running:
``setup.py``. They can be displayed by running:

::

Expand All @@ -65,14 +63,14 @@ They can be displayed by running:
Pyomo extensions that require any of these packages will generate
an error message for missing dependencies upon use.

When using *pip*, all conditional dependencies can be installed at once
When using *pip*, all optional dependencies can be installed at once
using the following command:

::

pip install 'pyomo[optional]'

When using *conda*, many of the conditional dependencies are included
When using *conda*, many of the optional dependencies are included
with the standard Anaconda installation.

You can check which Python packages you have installed using the command
Expand Down
Loading
Loading