-
Notifications
You must be signed in to change notification settings - Fork 560
Introduce formal principle documentation to support contrib changes #3768
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
74aee3f
ca02f4e
8e18ee1
4822e6d
9e4b67c
5f37e4a
1be9b29
5d7f102
ed7f9dd
6999a91
cff39eb
1b023a8
ce089c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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")`` | ||
mrmundt marked this conversation as resolved.
Show resolved
Hide 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. | ||
|
|
@@ -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] | ||
mrmundt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| 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 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "changes to the source code for |
||
| 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 | ||
| ----------------------------- | ||
|
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
|
@@ -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. | ||
|
|
||
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.