Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is auto-generated stuff?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup - when you run make -C doc/OnlineDocs html, this is all the automatic api docs that get generated. Which are great, we love them, but I have almost accidentally committed them way too many times.

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
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")``

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]

These commands register the cloned code with the active python environment
(``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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"changes to the source code for pyomo are automatically used - this is from the -e, but, from the way this is written, it sounds like this is because optional dependencies have been installed.

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)
* **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.


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.
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:

* ``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.

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
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
``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 on lines +500 to +501
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary if docs are added to the online docs?

* Optional dependencies are properly declared in ``setup.py``
under the appropriate ``[optional]`` section.
* The contribution passes all standard style and formatting checks.

Contributed Packages within Pyomo
+++++++++++++++++++++++++++++++++

Third-party contributions can be included directly within the
``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``,
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