public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/psi4] rawhide: Update to 1.11.
@ 2026-07-29 13:28 Susi Lehtola
  0 siblings, 0 replies; only message in thread
From: Susi Lehtola @ 2026-07-29 13:28 UTC (permalink / raw)
  To: git-commits

A new commit has been pushed.

Repo   : rpms/psi4
Branch : rawhide
Commit : a5de9f3f7b20b7d218c79691591adfa738eed1da
Author : Susi Lehtola <jussilehtola@fedoraproject.org>
Date   : 2026-07-29T13:28:06+00:00
Stats  : +1580/-917 in 5 file(s)
URL    : https://src.fedoraproject.org/rpms/psi4/c/a5de9f3f7b20b7d218c79691591adfa738eed1da?branch=rawhide

Log:
Update to 1.11.

---
diff --git a/3389.patch b/3389.patch
deleted file mode 100644
index 642c60e..0000000
--- a/3389.patch
+++ /dev/null
@@ -1,842 +0,0 @@
-From d8c29bf947146f6af8be1131e5ca3d42852e8b47 Mon Sep 17 00:00:00 2001
-From: "Lori A. Burns" <lori.burns7@gmail.com>
-Date: Thu, 7 May 2026 00:03:15 -0400
-Subject: [PATCH] make qcmanybody optional
-
----
- CMakeLists.txt                                |  1 +
- codedeps.yaml                                 |  4 +-
- doc/sphinxman/source/build_planning.rst       |  4 +-
- doc/sphinxman/source/external.rst             |  1 +
- doc/sphinxman/source/nbody.rst                |  3 +-
- external/upstream/qcmanybody/CMakeLists.txt   | 72 ++++++++++---------
- psi4/__init__.py                              |  2 +
- psi4/driver/driver_nbody.py                   | 33 ++++++++-
- psi4/extras.py                                |  1 +
- pytest.ini                                    |  4 +-
- tests/cbs-xtpl-nbody/test_input.py            |  4 +-
- tests/ddd-function-kwargs/test_input.py       |  4 +-
- tests/dfmp2-1/test_input.py                   |  4 +-
- tests/dfmp2-ecp/test_input.py                 |  3 +-
- tests/dfmp2-fc/test_input.py                  |  4 +-
- tests/dft-custom-dhdf/test_input.py           |  4 +-
- tests/dftd3/nbody-cp-gradient/test_input.py   |  3 +-
- tests/mp2-def2/test_input.py                  |  4 +-
- tests/nbody-convergence/test_input.py         |  4 +-
- tests/nbody-cp-gradient/test_input.py         |  4 +-
- tests/nbody-freq/test_input.py                |  4 +-
- tests/nbody-he-4b/test_input.py               |  4 +-
- tests/nbody-he-cluster/test_input.py          |  4 +-
- tests/nbody-hessian/test_input.py             |  4 +-
- tests/nbody-intermediates/test_input.py       |  4 +-
- tests/nbody-multi-level-2/test_input.py       |  4 +-
- tests/nbody-multi-level/test_input.py         |  4 +-
- tests/nbody-nocp-gradient/test_input.py       |  4 +-
- tests/nbody-vmfc-gradient/test_input.py       |  4 +-
- tests/nbody-vmfc-hessian/test_input.py        |  4 +-
- tests/pytests/addons.py                       |  6 +-
- tests/pytests/test_addons.py                  |  3 +-
- tests/pytests/test_addons_qcschema.py         |  3 +-
- tests/pytests/test_compositejk.py             |  4 +-
- tests/pytests/test_dft_benchmarks.py          |  4 +-
- tests/pytests/test_dftd3.py                   |  3 +-
- tests/pytests/test_nbody.py                   |  5 +-
- .../test_nbody_multi_level_qcschema.py        |  5 +-
- tests/pytests/test_psi4.py                    |  3 +-
- tests/pytests/test_psi4_qcschema.py           |  3 +-
- tests/tu6-cp-ne2/test_input.py                |  4 +-
- 41 files changed, 145 insertions(+), 101 deletions(-)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 8ea2f9f0b64..1e04c3e4f14 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -127,6 +127,7 @@ option(ENABLE_gdma "Enables Stone's GDMA multipole code (requires Fortran; can a
- option(ENABLE_IntegratorXX "Enables use of IntegratorXX density functional grids library" OFF)
- option(ENABLE_OpenOrbitalOptimizer "Enables the OpenOrbitalOptimizer library (requires Armadillo)" OFF)
- option(ENABLE_PCMSolver "Enables PCMSolver library (requires Fortran)" OFF)
-+option(ENABLE_qcmanybody "Enables qcmanybody for n-body/BSSE workflows (can also be added at runtime)" OFF)
- option(ENABLE_snsmp2 "Enables SNSMP2 plugin (can also be added at runtime)" OFF)
- option(ENABLE_v2rdm_casscf "Enables V2RDM_CASSCF plugin (requires Fortran; can also be added at runtime)" OFF)
- option(ENABLE_psi4fockci "Enables Psi4FockCI plugin (can also be added at runtime)" OFF)
-diff --git a/codedeps.yaml b/codedeps.yaml
-index 124c74c4492..316780b00d3 100644
---- a/codedeps.yaml
-+++ b/codedeps.yaml
-@@ -1490,8 +1490,8 @@ data:
-   - project: qcmanybody
-     use:
-       added: "1.10"
--      required: true
--      required_note: "Allows BSSE treatments and MBE analyses. Prior to v1.10, internal code was used."
-+      required: false
-+      required_note: "Allows BSSE treatments and MBE analyses. Required for v1.10. Prior to v1.10, internal code was used."
-       buildable: true
-       buildtime: true
-       buildtime_note: "buildtime for cmake checks; otherwise, runtime."
-diff --git a/doc/sphinxman/source/build_planning.rst b/doc/sphinxman/source/build_planning.rst
-index ef913ecc7be..73dd6c3dd9b 100644
---- a/doc/sphinxman/source/build_planning.rst
-+++ b/doc/sphinxman/source/build_planning.rst
-@@ -241,8 +241,6 @@ build system will automatically download and build.
- 
- * optking |w---w| `[what is optking] <https://optking.readthedocs.io/en/latest/>`_ (runtime dependency, required at build-time) 
- 
--* QCManyBody |w---w| `[what is QCManyBody?] <https://molssi.github.io/QCManyBody/>`_ (August 2025; added by v1.10; runtime dependency, required at build-time)
--
- Additionally, there are runtime-only dependencies:
- 
- * msgpack-python for MessagePack https://msgpack.org/ (transitive dependency of QCElemental; optional for QCElemental but required for |PSIfour|)
-@@ -374,6 +372,8 @@ Additionally, there are runtime-loaded capabilities:
- 
- * :ref:`ddx <sec:ddx>` |w---w| https://github.com/ddsolvation/ddx
- 
-+* QCManyBody |w---w| `[what is QCManyBody?] <https://molssi.github.io/QCManyBody/>`_ (May 2025; optional by v1.11; * August 2025; added required by v1.10; runtime dependency, optional at build-time)
-+
- 
- .. _`faq:condapsi4dev`:
- 
-diff --git a/doc/sphinxman/source/external.rst b/doc/sphinxman/source/external.rst
-index 14fd2758e0c..54f8c3a4711 100644
---- a/doc/sphinxman/source/external.rst
-+++ b/doc/sphinxman/source/external.rst
-@@ -723,4 +723,5 @@ These environment variables will influence |PSIfours| behavior.
- .. envvar:: QCMANYBODY_EMBEDDING_CHARGES
- 
-    Set to allow embedding charges with many-body/counterpoise computations.
-+   Relevant when QCManyBody addon is present.
- 
-diff --git a/doc/sphinxman/source/nbody.rst b/doc/sphinxman/source/nbody.rst
-index cd51c98142b..13778efd450 100644
---- a/doc/sphinxman/source/nbody.rst
-+++ b/doc/sphinxman/source/nbody.rst
-@@ -50,7 +50,8 @@ Basis Set Superposition Corrections
- 
- The nbody function computes counterpoise-corrected (CP), non-CP (noCP), and Valiron-Mayer Function Counterpoise (VMFC) interaction energies for complexes composed of arbitrary numbers of monomers.
- 
--.. caution:: August 2025, v1.10 many-body computations are no longer
-+.. caution:: May 2026, v1.11 QCManyBody is no longer required but may need to be
-+   separately installed. August 2025, v1.10 many-body computations are no longer
-    using internal driver code but have been offloaded to QCManyBody
-    software.
- 
-diff --git a/external/upstream/qcmanybody/CMakeLists.txt b/external/upstream/qcmanybody/CMakeLists.txt
-index cb510f0f67c..ef1aefbb53a 100644
---- a/external/upstream/qcmanybody/CMakeLists.txt
-+++ b/external/upstream/qcmanybody/CMakeLists.txt
-@@ -1,41 +1,45 @@
--if(NOT (${CMAKE_DISABLE_FIND_PACKAGE_qcmanybody}))
--    include(FindPythonModule)
--    find_python_module(qcmanybody ATLEAST 0.5.1 QUIET)
--endif()
-+if(${ENABLE_qcmanybody})
-+    if(NOT (${CMAKE_DISABLE_FIND_PACKAGE_qcmanybody}))
-+        include(FindPythonModule)
-+        find_python_module(qcmanybody ATLEAST 0.5.1 QUIET)
-+    endif()
- 
--if(${qcmanybody_FOUND})
--    message(STATUS "${Cyan}Found qcmanybody${ColourReset}: ${PY_qcmanybody} (found version ${qcmanybody_VERSION})")
--    add_library(qcmanybody_external INTERFACE)  # dummy
-+    if(${qcmanybody_FOUND})
-+        message(STATUS "${Cyan}Found qcmanybody${ColourReset}: ${PY_qcmanybody} (found version ${qcmanybody_VERSION})")
-+        add_library(qcmanybody_external INTERFACE)  # dummy
- 
--    if(${CMAKE_INSIST_FIND_PACKAGE_qcmanybody})
--        message(VERBOSE "Suitable qcmanybody located externally as user insists")
--    endif()
-+        if(${CMAKE_INSIST_FIND_PACKAGE_qcmanybody})
-+            message(VERBOSE "Suitable qcmanybody located externally as user insists")
-+        endif()
- 
--else()
--    if(${CMAKE_INSIST_FIND_PACKAGE_qcmanybody})
--        message(FATAL_ERROR "Suitable qcmanybody could not be externally located as user insists")
--    endif()
-+    else()
-+        if(${CMAKE_INSIST_FIND_PACKAGE_qcmanybody})
-+            message(FATAL_ERROR "Suitable qcmanybody could not be externally located as user insists")
-+        endif()
- 
--    include(ExternalProject)
--    message(STATUS "Suitable qcmanybody could not be located, ${Magenta}Building qcmanybody${ColourReset} instead.")
-+        include(ExternalProject)
-+        message(STATUS "Suitable qcmanybody could not be located, ${Magenta}Building qcmanybody${ColourReset} instead.")
- 
--    file(TO_NATIVE_PATH "${STAGED_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${PYMOD_INSTALL_LIBDIR}" _install_lib)
-+        file(TO_NATIVE_PATH "${STAGED_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${PYMOD_INSTALL_LIBDIR}" _install_lib)
- 
--    # Must have specialty egg to compute version correctly, so the URL is only grabbing a dummy file. It's
--    #   the pip command that's really selecting the source.
--    ExternalProject_Add(qcmanybody_external
--        DEPENDS qcelemental_external
--                qcengine_external
--        BUILD_ALWAYS 1
--        DOWNLOAD_COMMAND ""
--        CONFIGURE_COMMAND ""
--        UPDATE_COMMAND ""
--        BUILD_COMMAND ""
--        BUILD_IN_SOURCE 1
--        # master: INSTALL_COMMAND ${Python_EXECUTABLE} -m pip install git+https://github.com/MolSSI/ QCManyBody.git#egg=proj
--        INSTALL_COMMAND ${Python_EXECUTABLE} -m pip install git+https://github.com/MolSSI/QCManyBody.git@v0.5.1#egg=proj  # edit in codedeps
--                                                      --target=${_install_lib}
--                                                      --no-deps
--                                                      #-v
--        )
-+        # Must have specialty egg to compute version correctly, so the URL is only grabbing a dummy file. It's
-+        #   the pip command that's really selecting the source.
-+        ExternalProject_Add(qcmanybody_external
-+            DEPENDS qcelemental_external
-+                    qcengine_external
-+            BUILD_ALWAYS 1
-+            DOWNLOAD_COMMAND ""
-+            CONFIGURE_COMMAND ""
-+            UPDATE_COMMAND ""
-+            BUILD_COMMAND ""
-+            BUILD_IN_SOURCE 1
-+            # master: INSTALL_COMMAND ${Python_EXECUTABLE} -m pip install git+https://github.com/MolSSI/ QCManyBody.git#egg=proj
-+            INSTALL_COMMAND ${Python_EXECUTABLE} -m pip install git+https://github.com/MolSSI/QCManyBody.git@v0.5.1#egg=proj  # edit in codedeps
-+                                                          --target=${_install_lib}
-+                                                          --no-deps
-+                                                          #-v
-+            )
-+    endif()
-+else()
-+    add_library(qcmanybody_external INTERFACE)  # dummy
- endif()
-diff --git a/psi4/__init__.py b/psi4/__init__.py
-index 22332ee30ec..418a8646d62 100644
---- a/psi4/__init__.py
-+++ b/psi4/__init__.py
-@@ -120,6 +120,8 @@
-     sys.path.insert(1, r"@gdma_PYMOD@")
- if "@ENABLE_bse@".upper() in ["1", "ON", "YES", "TRUE", "Y"]:  # bse
-     sys.path.insert(1, r"@bse_PYMOD@")
-+if "@ENABLE_qcmanybody@".upper() in ["1", "ON", "YES", "TRUE", "Y"]:  # qcmanybody
-+    sys.path.insert(1, r"@qcmanybody_PYMOD@")
- 
- # Create a custom logger
- import logging
-diff --git a/psi4/driver/driver_nbody.py b/psi4/driver/driver_nbody.py
-index a554b9b4118..02eef5a899b 100644
---- a/psi4/driver/driver_nbody.py
-+++ b/psi4/driver/driver_nbody.py
-@@ -119,9 +119,30 @@
- from pydantic.v1 import validator
- 
- from qcelemental.models import Molecule
--from qcmanybody.models.v1 import AtomicSpecification, ManyBodyInput, ManyBodyResult, BsseEnum
--from qcmanybody import ManyBodyCore, ManyBodyComputer as ManyBodyComputerQCNG
--from qcmanybody.utils import delabeler, labeler, translate_qcvariables, modelchem_labels
-+
-+_QCMANYBODY_IMPORT_ERROR = None
-+try:
-+    from qcmanybody.models.v1 import AtomicSpecification, ManyBodyInput, ManyBodyResult, BsseEnum
-+    from qcmanybody import ManyBodyCore, ManyBodyComputer as ManyBodyComputerQCNG
-+    from qcmanybody.utils import delabeler, labeler, translate_qcvariables, modelchem_labels
-+except ModuleNotFoundError as err:
-+    _QCMANYBODY_IMPORT_ERROR = err
-+    AtomicSpecification = Any
-+    ManyBodyInput = Any
-+    ManyBodyResult = Any
-+    BsseEnum = Any
-+    ManyBodyCore = Any
-+    ManyBodyComputerQCNG = object
-+
-+
-+def _ensure_qcmanybody() -> None:
-+    if _QCMANYBODY_IMPORT_ERROR is None:
-+        return
-+
-+    raise ModuleNotFoundError(
-+        "Python module qcmanybody not found that is required for many-body/counterpoise (`bsse_type`) computations. "
-+        "Solve by installing it: `conda install -c conda-forge qcmanybody` or `pip install qcmanybody`"
-+    ) from _QCMANYBODY_IMPORT_ERROR
- 
- if TYPE_CHECKING:
-     import qcportal
-@@ -410,6 +431,8 @@ def set_molecule(cls, v: Any) -> Molecule:
-     @classmethod
-     def from_psi4_task_planner(cls, *, molecule, method, basis, driver, keywords, **mbkwargs):
- 
-+        _ensure_qcmanybody()
-+
-         atomic_spec = AtomicSpecification(
-             model={"method": method, "basis": basis},
-             program="psi4",
-@@ -506,6 +529,8 @@ def build_tasks(
-             Number of new tasks planned by this call including any supersystem.
- 
-         """
-+        _ensure_qcmanybody()
-+
-         # TODO method not coming from levels right
- 
-         # Get the n-body orders for this level. e.g., [1] or [2, 3] or ["supersystem"]
-@@ -575,6 +600,8 @@ def get_results(
-             All MBE results collected into a QCSchema model.
- 
-         """
-+        _ensure_qcmanybody()
-+
-         component_results = {k: v.get_results(client=client) for k, v in self.task_list.items()}
-         component_properties = {}
-         props = {"energy", "gradient", "hessian"}
-diff --git a/psi4/extras.py b/psi4/extras.py
-index 794c4dae547..c3b5a6011d9 100644
---- a/psi4/extras.py
-+++ b/psi4/extras.py
-@@ -180,6 +180,7 @@ def psi4_which(command, *, return_bool: bool = False, raise_error: bool = False,
-     "gauxc": _CMake_to_Py_boolean("@ENABLE_gauxc@"),
-     "integratorxx": _CMake_to_Py_boolean("@ENABLE_IntegratorXX@"),
-     "ooo": _CMake_to_Py_boolean("@ENABLE_OpenOrbitalOptimizer@"),
-+    "qcmanybody": which_import("qcmanybody", return_bool=True),
- }
- 
- 
-diff --git a/pytest.ini b/pytest.ini
-index 45057bbb9ad..66f90ad870d 100644
---- a/pytest.ini
-+++ b/pytest.ini
-@@ -93,7 +93,7 @@ markers =
-     mints
-     mom
-     mp2
--    nbody: "tests that use the nbody aka manybody wrapper"
-+    nbody: "tests that use the nbody aka manybody wrapper; alias to qcmanybody marker"
-     noc1
-     numint: "tests that use NumIntHelper"
-     numpy
-@@ -180,6 +180,7 @@ markers =
-     qcfractal: "tests using QCFractal software; skip if unavailable"
-     qcfractal_next: "tests using QCFractal software, next branch; skip if unavailable"
-     qcportal: "tests using QCPortal software; skip if unavailable"
-+    qcmanybody: "tests using QCManyBody software; skip if unavailable; alias to nbody marker"
-     psi4
-     
- 
-@@ -187,4 +188,3 @@ markers =
- # filterwarnings =
- #     error
- #     ignore:unclosed file:ResourceWarning
--
-diff --git a/tests/cbs-xtpl-nbody/test_input.py b/tests/cbs-xtpl-nbody/test_input.py
-index 27584e7d16f..c34e747f100 100644
---- a/tests/cbs-xtpl-nbody/test_input.py
-+++ b/tests/cbs-xtpl-nbody/test_input.py
-@@ -1,6 +1,6 @@
- from addons import *
- 
--@ctest_labeler("cbs;nbody")
-+@uusing("qcmanybody")
-+@ctest_labeler("cbs")
- def test_cbs_xtpl_nbody():
-     ctest_runner(__file__)
--
-diff --git a/tests/ddd-function-kwargs/test_input.py b/tests/ddd-function-kwargs/test_input.py
-index d56b322c643..37216a71829 100644
---- a/tests/ddd-function-kwargs/test_input.py
-+++ b/tests/ddd-function-kwargs/test_input.py
-@@ -1,6 +1,6 @@
- from addons import *
- 
--@ctest_labeler("findif;nbody;gradient")
-+@uusing("qcmanybody")
-+@ctest_labeler("findif;gradient")
- def test_ddd_function_kwargs():
-     ctest_runner(__file__)
--
-diff --git a/tests/dfmp2-1/test_input.py b/tests/dfmp2-1/test_input.py
-index 4f8f3b89542..199f1da3d4f 100644
---- a/tests/dfmp2-1/test_input.py
-+++ b/tests/dfmp2-1/test_input.py
-@@ -1,6 +1,6 @@
- from addons import *
- 
--@ctest_labeler("quick;smoke;df;dfmp2;cart;nbody")
-+@uusing("qcmanybody")
-+@ctest_labeler("quick;smoke;df;dfmp2;cart")
- def test_dfmp2_1():
-     ctest_runner(__file__)
--
-diff --git a/tests/dfmp2-ecp/test_input.py b/tests/dfmp2-ecp/test_input.py
-index 8a21eda1c89..2441b0fd5e9 100644
---- a/tests/dfmp2-ecp/test_input.py
-+++ b/tests/dfmp2-ecp/test_input.py
-@@ -2,7 +2,8 @@
- from addons import *
- 
- @uusing("ecpint")
--@ctest_labeler("quick;df;dfmp2;ecp;nbody")
-+@uusing("qcmanybody")
-+@ctest_labeler("quick;df;dfmp2;ecp")
- @pytest.mark.parametrize("oopkg", [
-     pytest.param(False, id="internal"),
-     pytest.param(True,  id="openorbitaloptimizer", marks=using("ooo")),
-diff --git a/tests/dfmp2-fc/test_input.py b/tests/dfmp2-fc/test_input.py
-index 5141f0227b2..eda3ee25477 100644
---- a/tests/dfmp2-fc/test_input.py
-+++ b/tests/dfmp2-fc/test_input.py
-@@ -1,6 +1,6 @@
- from addons import *
- 
--@ctest_labeler("quick;df;dfmp2;nbody")
-+@uusing("qcmanybody")
-+@ctest_labeler("quick;df;dfmp2")
- def test_dfmp2_fc():
-     ctest_runner(__file__)
--
-diff --git a/tests/dft-custom-dhdf/test_input.py b/tests/dft-custom-dhdf/test_input.py
-index 7d649f38da6..eb136c2210b 100644
---- a/tests/dft-custom-dhdf/test_input.py
-+++ b/tests/dft-custom-dhdf/test_input.py
-@@ -1,6 +1,6 @@
- from addons import *
- 
--@ctest_labeler("dft;scf;nbody")
-+@uusing("qcmanybody")
-+@ctest_labeler("dft;scf")
- def test_dft_custom_dhdf():
-     ctest_runner(__file__)
--
-diff --git a/tests/dftd3/nbody-cp-gradient/test_input.py b/tests/dftd3/nbody-cp-gradient/test_input.py
-index 07746f35f27..1d26cb042b3 100644
---- a/tests/dftd3/nbody-cp-gradient/test_input.py
-+++ b/tests/dftd3/nbody-cp-gradient/test_input.py
-@@ -1,6 +1,7 @@
- from addons import *
- 
- @uusing("dftd3")
--@ctest_labeler("cart;nbody;gradient")
-+@uusing("qcmanybody")
-+@ctest_labeler("cart;gradient")
- def test_dftd3_nbody_cp_gradient():
-     ctest_runner(__file__)
-diff --git a/tests/mp2-def2/test_input.py b/tests/mp2-def2/test_input.py
-index b3d6ab9a736..c9f7e562bac 100644
---- a/tests/mp2-def2/test_input.py
-+++ b/tests/mp2-def2/test_input.py
-@@ -1,6 +1,6 @@
- from addons import *
- 
--@ctest_labeler("mp2;cart;nbody")
-+@uusing("qcmanybody")
-+@ctest_labeler("mp2;cart")
- def test_mp2_def2():
-     ctest_runner(__file__)
--
-diff --git a/tests/nbody-convergence/test_input.py b/tests/nbody-convergence/test_input.py
-index ca79137c733..85818e08324 100644
---- a/tests/nbody-convergence/test_input.py
-+++ b/tests/nbody-convergence/test_input.py
-@@ -1,6 +1,6 @@
- from addons import *
- 
--@ctest_labeler("nbody;gradient")
-+@uusing("qcmanybody")
-+@ctest_labeler("gradient")
- def test_nbody_convergence():
-     ctest_runner(__file__)
--
-diff --git a/tests/nbody-cp-gradient/test_input.py b/tests/nbody-cp-gradient/test_input.py
-index c12444621b6..aa7e6cee22b 100644
---- a/tests/nbody-cp-gradient/test_input.py
-+++ b/tests/nbody-cp-gradient/test_input.py
-@@ -1,12 +1,12 @@
- import pytest
- from addons import *
- 
-+@uusing("qcmanybody")
- @pytest.mark.parametrize("distributed", [
-     pytest.param(False, id="internal"),
-     pytest.param(True,  id="snowflake", marks=using("qcfractal_next")),
- ])
--@ctest_labeler("nbody;gradient")
-+@ctest_labeler("gradient")
- def test_nbody_cp_gradient(distributed):
-     setenv = ["_PSI4_USE_QCF"] if distributed else None
-     ctest_runner(__file__, setenv=setenv)
--
-diff --git a/tests/nbody-freq/test_input.py b/tests/nbody-freq/test_input.py
-index 4179468c85f..a00baa262df 100644
---- a/tests/nbody-freq/test_input.py
-+++ b/tests/nbody-freq/test_input.py
-@@ -1,6 +1,6 @@
- from addons import *
- 
--@ctest_labeler("nbody;freq;hessian;gradient;opt")
-+@uusing("qcmanybody")
-+@ctest_labeler("freq;hessian;gradient;opt")
- def test_nbody_freq():
-     ctest_runner(__file__)
--
-diff --git a/tests/nbody-he-4b/test_input.py b/tests/nbody-he-4b/test_input.py
-index 02fd908076f..f9bf44c7f85 100644
---- a/tests/nbody-he-4b/test_input.py
-+++ b/tests/nbody-he-4b/test_input.py
-@@ -1,12 +1,12 @@
- import pytest
- from addons import *
- 
-+@uusing("qcmanybody")
- @pytest.mark.parametrize("distributed", [
-     pytest.param(False, id="internal"),
-     pytest.param(True,  id="snowflake", marks=using("qcfractal_next")),
- ])
--@ctest_labeler("nbody;cart")
-+@ctest_labeler("cart")
- def test_nbody_he_4b(distributed):
-     setenv = ["_PSI4_USE_QCF"] if distributed else None
-     ctest_runner(__file__, setenv=setenv)
--
-diff --git a/tests/nbody-he-cluster/test_input.py b/tests/nbody-he-cluster/test_input.py
-index b2df4668d78..ca40affec67 100644
---- a/tests/nbody-he-cluster/test_input.py
-+++ b/tests/nbody-he-cluster/test_input.py
-@@ -1,6 +1,6 @@
- from addons import *
- 
--@ctest_labeler("nbody;cart")
-+@uusing("qcmanybody")
-+@ctest_labeler("cart")
- def test_nbody_he_cluster():
-     ctest_runner(__file__)
--
-diff --git a/tests/nbody-hessian/test_input.py b/tests/nbody-hessian/test_input.py
-index fb54e2c8fbe..906c029cbe2 100644
---- a/tests/nbody-hessian/test_input.py
-+++ b/tests/nbody-hessian/test_input.py
-@@ -1,6 +1,6 @@
- from addons import *
- 
--@ctest_labeler("nbody;hessian")
-+@uusing("qcmanybody")
-+@ctest_labeler("hessian")
- def test_nbody_hessian():
-     ctest_runner(__file__)
--
-diff --git a/tests/nbody-intermediates/test_input.py b/tests/nbody-intermediates/test_input.py
-index 3daeb7079fc..625cd8729e8 100644
---- a/tests/nbody-intermediates/test_input.py
-+++ b/tests/nbody-intermediates/test_input.py
-@@ -1,6 +1,6 @@
- from addons import *
- 
--@ctest_labeler("nbody")
-+@uusing("qcmanybody")
-+@ctest_labeler("")
- def test_nbody_intermediates():
-     ctest_runner(__file__)
--
-diff --git a/tests/nbody-multi-level-2/test_input.py b/tests/nbody-multi-level-2/test_input.py
-index 75aac98456a..6e7da06eb9b 100644
---- a/tests/nbody-multi-level-2/test_input.py
-+++ b/tests/nbody-multi-level-2/test_input.py
-@@ -1,6 +1,6 @@
- from addons import *
- 
--@ctest_labeler("nbody")
-+@uusing("qcmanybody")
-+@ctest_labeler("")
- def test_nbody_multi_level_2():
-     ctest_runner(__file__)
--
-diff --git a/tests/nbody-multi-level/test_input.py b/tests/nbody-multi-level/test_input.py
-index 99c0c9faca0..0afe1a1bc9e 100644
---- a/tests/nbody-multi-level/test_input.py
-+++ b/tests/nbody-multi-level/test_input.py
-@@ -1,7 +1,8 @@
- import pytest
- from addons import *
- 
--@ctest_labeler("nbody;extern")
-+@uusing("qcmanybody")
-+@ctest_labeler("extern")
- @pytest.mark.parametrize("distributed", [
-     pytest.param(False, id="internal"),
-     pytest.param(True,  id="snowflake", marks=[*using("qcfractal_next"), pytest.mark.medlong]),
-@@ -10,4 +11,3 @@ def test_nbody_multi_level(distributed, monkeypatch):
-     setenv = ["_PSI4_USE_QCF"] if distributed else None
-     monkeypatch.setenv("QCMANYBODY_EMBEDDING_CHARGES", "1")
-     ctest_runner(__file__, setenv=setenv)
--
-diff --git a/tests/nbody-nocp-gradient/test_input.py b/tests/nbody-nocp-gradient/test_input.py
-index cc75771ad37..55a9bef4dc1 100644
---- a/tests/nbody-nocp-gradient/test_input.py
-+++ b/tests/nbody-nocp-gradient/test_input.py
-@@ -1,6 +1,6 @@
- from addons import *
- 
--@ctest_labeler("nbody;gradient")
-+@uusing("qcmanybody")
-+@ctest_labeler("gradient")
- def test_nbody_nocp_gradient():
-     ctest_runner(__file__)
--
-diff --git a/tests/nbody-vmfc-gradient/test_input.py b/tests/nbody-vmfc-gradient/test_input.py
-index fa2ec7d45c2..0027999bc7c 100644
---- a/tests/nbody-vmfc-gradient/test_input.py
-+++ b/tests/nbody-vmfc-gradient/test_input.py
-@@ -1,6 +1,6 @@
- from addons import *
- 
--@ctest_labeler("nbody;gradient")
-+@uusing("qcmanybody")
-+@ctest_labeler("gradient")
- def test_nbody_vmfc_gradient():
-     ctest_runner(__file__)
--
-diff --git a/tests/nbody-vmfc-hessian/test_input.py b/tests/nbody-vmfc-hessian/test_input.py
-index 6b3872fc592..7cc3d08be9a 100644
---- a/tests/nbody-vmfc-hessian/test_input.py
-+++ b/tests/nbody-vmfc-hessian/test_input.py
-@@ -1,7 +1,8 @@
- import pytest
- from addons import *
- 
--@ctest_labeler("nbody;hessian;d2ints")
-+@uusing("qcmanybody")
-+@ctest_labeler("hessian;d2ints")
- 
- @pytest.mark.parametrize("distributed", [
-     pytest.param(False, id="internal"),
-@@ -10,4 +11,3 @@
- def test_nbody_vmfc_hessian(distributed):
-     setenv = ["_PSI4_USE_QCF"] if distributed else None
-     ctest_runner(__file__, setenv=setenv)
--
-diff --git a/tests/pytests/addons.py b/tests/pytests/addons.py
-index c6518356819..644f1a42a4e 100644
---- a/tests/pytests/addons.py
-+++ b/tests/pytests/addons.py
-@@ -90,6 +90,7 @@ def is_nvidia_gpu_present():
-     "qcfractal": which_import("qcfractal", return_bool=True),
-     "qcfractal_next": is_qcfractal_new_enough("0.49"),
-     "qcportal": which_import("qcportal", return_bool=True),
-+    "qcmanybody": which_import("qcmanybody", return_bool=True),
-     "bse": which_import("basis_set_exchange", return_bool=True),
-     "einsums": psi4.addons("einsums"),
-     "pyeinsums": which_import("einsums", return_bool=True),
-@@ -126,7 +127,10 @@ def _using(program: str) -> None:
-         general = pytest.mark.addon
-         particular = getattr(pytest.mark, program)
- 
--        all_marks = (skip, general, particular)
-+        if program == "qcmanybody":
-+            all_marks = (skip, general, particular, getattr(pytest.mark, "nbody"))
-+        else:
-+            all_marks = (skip, general, particular)
-         _using_cache[program] = [_compose_decos(all_marks), all_marks]
- 
- 
-diff --git a/tests/pytests/test_addons.py b/tests/pytests/test_addons.py
-index 60f809eef17..36eaf76f83b 100644
---- a/tests/pytests/test_addons.py
-+++ b/tests/pytests/test_addons.py
-@@ -907,7 +907,7 @@ def test_gpu_dfcc():
- 
- 
- 
--@pytest.mark.nbody
-+@uusing("qcmanybody")
- @uusing("dftd3")
- @uusing("gcp")
- def test_grimme_3c():
-@@ -1617,4 +1617,3 @@ def test_pyeinsums_gemm(a, b, c, dtype, array):
-     for i in range(a):
-         for j in range(c):
-             assert C[i, j] == pytest.approx(C_actual[i, j])
--
-diff --git a/tests/pytests/test_addons_qcschema.py b/tests/pytests/test_addons_qcschema.py
-index 3daa45977ca..afd2c832785 100644
---- a/tests/pytests/test_addons_qcschema.py
-+++ b/tests/pytests/test_addons_qcschema.py
-@@ -562,7 +562,7 @@ def test_v2rdm_casscf():
- #    assert psi4.compare_values(en_gpu_dfcc, en_dfcc, 8, "CCSD total energy")
- 
- 
--@pytest.mark.nbody
-+@uusing("qcmanybody")
- @uusing("dftd3")
- @uusing("gcp")
- def test_grimme_3c():
-@@ -829,4 +829,3 @@ def test_ddx_tdscf_gaussian():
-     for i in range(5):
-         e_calc.append(atres.extras["qcvars"][f'TD-HF ROOT 0 -> ROOT {i+1} EXCITATION ENERGY - A TRANSITION'])
-     psi4.compare_values(exc_energies[:5], e_calc, 4, 'PCM EXCITATION ENERGY ')
--
-diff --git a/tests/pytests/test_compositejk.py b/tests/pytests/test_compositejk.py
-index b0030c87f7e..dc2bc36428a 100644
---- a/tests/pytests/test_compositejk.py
-+++ b/tests/pytests/test_compositejk.py
-@@ -111,7 +111,7 @@ def test_composite_call(j_algo, k_algo, mols, request):
-                       "molecule" : "h2o_nap1",
-                       "bsse_type" : "CP",
-                       },
--                      marks=pytest.mark.nbody,
-+                      marks=using("qcmanybody"),
-                       id="h2o/na+ (rhf ie)"),
-     ],
- )
-@@ -216,7 +216,7 @@ def test_seminum(inp, scf, mols, request):
-                       "molecule" : "h2o_nap1",
-                       "bsse_type" : "CP",
-                       },
--                      marks=pytest.mark.nbody,
-+                      marks=using("qcmanybody"),
-                       id="h2o/na+ (rhf ie)"),
-     ],
- )
-diff --git a/tests/pytests/test_dft_benchmarks.py b/tests/pytests/test_dft_benchmarks.py
-index 975e3cc39b0..106ac5d48d3 100644
---- a/tests/pytests/test_dft_benchmarks.py
-+++ b/tests/pytests/test_dft_benchmarks.py
-@@ -2,7 +2,7 @@
- 
- import pytest
- from utils import *
--from addons import using
-+from addons import using, uusing
- 
- import psi4
- 
-@@ -178,7 +178,7 @@ def test_dft_bench_ionization(func, expected, basis, dft_bench_systems, request)
- 
- 
- 
--@pytest.mark.nbody
-+@uusing("qcmanybody")
- @pytest.mark.scf
- @pytest.mark.dft
- @pytest.mark.long
-diff --git a/tests/pytests/test_dftd3.py b/tests/pytests/test_dftd3.py
-index 552a167cb4e..7e0461ed2bf 100644
---- a/tests/pytests/test_dftd3.py
-+++ b/tests/pytests/test_dftd3.py
-@@ -113,7 +113,7 @@ def test_dftd3_dft_grad_lr3():
- s16_r2scan50_psi4 = np.array([-155.6575747, -78.4586347, -77.1962996])
- 
- 
--@pytest.mark.nbody
-+@uusing("qcmanybody")
- @pytest.mark.parametrize("mode", [
-     pytest.param("abs", marks=pytest.mark.long),
-     pytest.param("ie", marks=pytest.mark.quick),
-@@ -191,4 +191,3 @@ def test_grimme_3c(mtdbas, ref, mode):
- 
-         ene = psi4.energy(mtdbas, bsse_type='nocp')
-         assert psi4.compare_values(kcal * (ref[0] - ref[1] - ref[2]), kcal * ene, 1.1e-3, mtdbas)
--
-diff --git a/tests/pytests/test_nbody.py b/tests/pytests/test_nbody.py
-index 5741f5046b4..24b9dacaf97 100644
---- a/tests/pytests/test_nbody.py
-+++ b/tests/pytests/test_nbody.py
-@@ -2,9 +2,10 @@
- import pytest
- import numpy as np
- from qcelemental.testing import compare, compare_values
-+from addons import uusing
- import psi4
- 
--pytestmark = [pytest.mark.psi, pytest.mark.api, pytest.mark.nbody]
-+pytestmark = [pytest.mark.psi, pytest.mark.api]
- 
- _tot_cp_ene = -155.40761029
- _ie_cp_ene = -0.00172611
-@@ -121,6 +122,7 @@
-     ("gradient", ["nocp", "cp"], None , 5, _tot_uncp_grad, "uncpcp"),  # return tot G          5
-     ("gradient", ["nocp", "ssfc"], None , 5, _tot_uncp_grad, "uncpcp"),  # return tot G          5
- ])
-+@uusing("qcmanybody")
- def test_nbody_number(driver, bsse_type, return_total_data, nbody_number, return_result, stdoutkey):
- 
-     eneyne = psi4.geometry("""
-@@ -160,4 +162,3 @@ def test_nbody_number(driver, bsse_type, return_total_data, nbody_number, return
-     assert compare_values(return_result, ret.return_result, atol=1.e-6, label="manybody")
-     assert compare(nbody_number, ret.extras["qcvars"]["NBODY NUMBER"], label="nbody number")
-     assert re.search(_stdouts[stdoutkey], ret.stdout, re.MULTILINE), f"N-Body pattern not found: {_stdouts[stdoutkey]}"
--
-diff --git a/tests/pytests/test_nbody_multi_level_qcschema.py b/tests/pytests/test_nbody_multi_level_qcschema.py
-index be576046cf6..7b79e3d6c0c 100644
---- a/tests/pytests/test_nbody_multi_level_qcschema.py
-+++ b/tests/pytests/test_nbody_multi_level_qcschema.py
-@@ -3,10 +3,11 @@
- import pprint
- 
- import pytest
-+from addons import uusing
- 
- import psi4
- 
--pytestmark = [pytest.mark.psi, pytest.mark.api, pytest.mark.nbody]
-+pytestmark = [pytest.mark.psi, pytest.mark.api]
- 
- @pytest.fixture
- def base_schema():
-@@ -65,6 +66,7 @@ def base_schema():
-                   'VMFC-CORRECTED TOTAL ENERGY THROUGH 2-BODY': -224.943882712817},
-                  id='nbody-embedded', marks=pytest.mark.extern),
- ])
-+@uusing("qcmanybody")
- def test_nbody_levels(inp, expected, base_schema, monkeypatch):
-     monkeypatch.setenv("QCMANYBODY_EMBEDDING_CHARGES", "1")
-     # reference for nbody-multilevel generated with this larger fitting basis for sto-3g. fails otherwise by 3.e-5
-@@ -85,4 +87,3 @@ def test_nbody_levels(inp, expected, base_schema, monkeypatch):
- 
-     for b, v in expected.items():
-         assert psi4.compare_values(v, otp.extras["qcvars"][b], 6, b)
--
-diff --git a/tests/pytests/test_psi4.py b/tests/pytests/test_psi4.py
-index d7df6249f2e..8eacacc12b7 100644
---- a/tests/pytests/test_psi4.py
-+++ b/tests/pytests/test_psi4.py
-@@ -1,5 +1,6 @@
- import numpy as np
- import pytest
-+from addons import uusing
- 
- import psi4
- 
-@@ -85,7 +86,7 @@ def test_psi4_cas():
-     assert psi4.compare_values(-76.073865006902, casscf_energy, 6, 'CASSCF Energy')
- 
- 
--@pytest.mark.nbody
-+@uusing("qcmanybody")
- @pytest.mark.smoke
- def test_psi4_dfmp2():
-     """dfmp2-1"""
-diff --git a/tests/pytests/test_psi4_qcschema.py b/tests/pytests/test_psi4_qcschema.py
-index 295d44f572d..0576d989b02 100644
---- a/tests/pytests/test_psi4_qcschema.py
-+++ b/tests/pytests/test_psi4_qcschema.py
-@@ -4,6 +4,7 @@
- import pprint
- import os
- from shutil import copytree
-+from addons import uusing
- 
- import psi4
- 
-@@ -95,7 +96,7 @@ def test_psi4_cas(datadir):
-     assert psi4.compare_values(-76.073865006902, atres.return_result, 6, 'CASSCF Energy')
- 
- 
--@pytest.mark.nbody
-+@uusing("qcmanybody")
- def test_psi4_dfmp2(datadir):
-     """dfmp2-1"""
-     #! Density fitted MP2 cc-PVDZ/cc-pVDZ-RI computation of formic acid dimer binding energy
-diff --git a/tests/tu6-cp-ne2/test_input.py b/tests/tu6-cp-ne2/test_input.py
-index d4086c15ee3..138e8e005ca 100644
---- a/tests/tu6-cp-ne2/test_input.py
-+++ b/tests/tu6-cp-ne2/test_input.py
-@@ -1,6 +1,6 @@
- from addons import *
- 
--@ctest_labeler("tutorial;nbody")
-+@uusing("qcmanybody")
-+@ctest_labeler("tutorial")
- def test_tu6_cp_ne2():
-     ctest_runner(__file__)
--

diff --git a/3389_new.patch b/3389_new.patch
new file mode 100644
index 0000000..1db70eb
--- /dev/null
+++ b/3389_new.patch
@@ -0,0 +1,1570 @@
+diff -up psi4-1.11/CMakeLists.txt.noqcmb psi4-1.11/CMakeLists.txt
+--- psi4-1.11/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/CMakeLists.txt	2026-07-23 10:43:03.925378404 +0000
+@@ -134,6 +134,7 @@ option(ENABLE_gdma "Enables Stone's GDMA
+ option(ENABLE_IntegratorXX "Enables use of IntegratorXX density functional grids library" OFF)
+ option(ENABLE_OpenOrbitalOptimizer "Enables the OpenOrbitalOptimizer library (requires Armadillo)" OFF)
+ option(ENABLE_PCMSolver "Enables PCMSolver library (requires Fortran)" OFF)
++option(ENABLE_qcmanybody "Enables qcmanybody for n-body/BSSE workflows (can also be added at runtime)" OFF)
+ option(ENABLE_snsmp2 "Enables SNSMP2 plugin (can also be added at runtime)" OFF)
+ option(ENABLE_v2rdm_casscf "Enables V2RDM_CASSCF plugin (requires Fortran; can also be added at runtime)" OFF)
+ option(ENABLE_psi4fockci "Enables Psi4FockCI plugin (can also be added at runtime)" OFF)
+@@ -323,7 +324,6 @@ ExternalProject_Add(psi4-core
+               -DPSI4_ROOT=${CMAKE_CURRENT_SOURCE_DIR}
+               -DENABLE_ambit=${ENABLE_ambit}
+               -DENABLE_CheMPS2=${ENABLE_CheMPS2}
+-              -DENABLE_cppe=${ENABLE_cppe}
+               -DENABLE_dkh=${ENABLE_dkh}
+               -DENABLE_IntegratorXX=${ENABLE_IntegratorXX}
+               -DENABLE_gauxc=${ENABLE_gauxc}
+@@ -333,7 +333,6 @@ ExternalProject_Add(psi4-core
+               -DENABLE_simint=${ENABLE_simint}
+               -DENABLE_gdma=${ENABLE_gdma}
+               -DENABLE_PCMSolver=${ENABLE_PCMSolver}
+-              -DENABLE_ddx=${ENABLE_ddx}
+               -DENABLE_mdi=${ENABLE_mdi}
+               -DENABLE_BrianQC=${ENABLE_BrianQC}
+               -DENABLE_OpenOrbitalOptimizer=${ENABLE_OpenOrbitalOptimizer}
+diff -up psi4-1.11/codedeps.yaml.noqcmb psi4-1.11/codedeps.yaml
+--- psi4-1.11/codedeps.yaml.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/codedeps.yaml	2026-07-23 10:43:03.927243876 +0000
+@@ -675,9 +675,11 @@ data:
+         - qcportal
+         - "setuptools<82.0.0"
+         - sphobjinv
++        - qcmanybody
+       aux_build_names_note:
+         qcportal: "Required for docs to resolve objects in pydantic classes."
+         sphobjinv: "Required for easy debugging in CI, not needed for local docs build."
++        qcmanybody: "Required for docs to resolve objects in pydantic classes."
+       cmake:
+         SPHINX_ROOT: ${CONDA_PREFIX}
+         //SPHINXMAN_STRICT: OFF
+@@ -1517,10 +1519,10 @@ data:
+   - project: qcmanybody
+     use:
+       added: "1.10"
+-      required: true
+-      required_note: "Allows BSSE treatments and MBE analyses. Prior to v1.10, internal code was used."
++      required: false
++      required_note: "Allows BSSE treatments and MBE analyses. Optional for v1.12. Required for v1.10 & 1.11. Prior to v1.10, internal code was used."
+       buildable: true
+-      buildtime: true
++      buildtime: false
+       buildtime_note: "buildtime for cmake checks; otherwise, runtime."
+       cms: true
+     repository:
+@@ -1532,16 +1534,18 @@ data:
+     cmake:
+       name: qcmanybody
+       constraint: "ATLEAST 0.7.1"
++      enable: "ENABLE_qcmanybody"
+       target: null
+     conda:
+       channel: conda-forge
+       name: qcmanybody
+       constraint: ">=0.7.1"
+       cmake:
++        ENABLE_qcmanybody: true
+         //CMAKE_INSIST_FIND_PACKAGE_qcmanybody: true
+         //CMAKE_DISABLE_FIND_PACKAGE_qcmanybody: true
+-      cmake_note: "Primarily OTF runtime detected."
+-
++      cmake_note: "Primarily OTF runtime detected. With package present, CMake enabling only relevant for CTest."
++      
+   - project: openorbitaloptimizer
+     use:
+       added: "1.10"
+diff -up psi4-1.11/doc/sphinxman/source/build_planning.rst.noqcmb psi4-1.11/doc/sphinxman/source/build_planning.rst
+--- psi4-1.11/doc/sphinxman/source/build_planning.rst.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/doc/sphinxman/source/build_planning.rst	2026-07-23 10:43:03.919628662 +0000
+@@ -244,8 +244,6 @@ build system will automatically download
+ 
+ * optking |w---w| `[what is optking] <https://optking.readthedocs.io/en/latest/>`_ (runtime dependency, required at build-time) 
+ 
+-* QCManyBody |w---w| `[what is QCManyBody?] <https://molssi.github.io/QCManyBody/>`_ (August 2025; added by v1.10; runtime dependency, required at build-time)
+-
+ Additionally, there are runtime-only dependencies:
+ 
+ * msgpack-python for MessagePack https://msgpack.org/ (transitive dependency of QCElemental; optional for QCElemental but required for |PSIfour|)
+@@ -377,6 +375,8 @@ Additionally, there are runtime-loaded c
+ 
+ * :ref:`ddx <sec:ddx>` |w---w| https://github.com/ddsolvation/ddx
+ 
++* QCManyBody |w---w| `[what is QCManyBody?] <https://molssi.github.io/QCManyBody/>`_ (July 2026 - optional by v1.12; August 2025 - added required by v1.10; runtime dependency, optional at build-time)
++
+ 
+ .. _`faq:condapsi4dev`:
+ 
+diff -up psi4-1.11/doc/sphinxman/source/external.rst.noqcmb psi4-1.11/doc/sphinxman/source/external.rst
+--- psi4-1.11/doc/sphinxman/source/external.rst.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/doc/sphinxman/source/external.rst	2026-07-23 10:43:03.828436082 +0000
+@@ -728,4 +728,5 @@ These environment variables will influen
+ .. envvar:: QCMANYBODY_EMBEDDING_CHARGES
+ 
+    Set to allow embedding charges with many-body/counterpoise computations.
++   Relevant when QCManyBody addon is present.
+ 
+diff -up psi4-1.11/doc/sphinxman/source/nbody.rst.noqcmb psi4-1.11/doc/sphinxman/source/nbody.rst
+--- psi4-1.11/doc/sphinxman/source/nbody.rst.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/doc/sphinxman/source/nbody.rst	2026-07-23 10:43:03.920071300 +0000
+@@ -50,7 +50,8 @@ Basis Set Superposition Corrections
+ 
+ The nbody function computes counterpoise-corrected (CP), non-CP (noCP), and Valiron-Mayer Function Counterpoise (VMFC) interaction energies for complexes composed of arbitrary numbers of monomers.
+ 
+-.. caution:: August 2025, v1.10 many-body computations are no longer
++.. caution:: July 2026, v1.12 QCManyBody is no longer required but may need to be
++   separately installed. August 2025, v1.10 many-body computations are no longer
+    using internal driver code but have been offloaded to QCManyBody
+    software.
+ 
+diff -up psi4-1.11/external/upstream/ambit/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/ambit/CMakeLists.txt
+--- psi4-1.11/external/upstream/ambit/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/ambit/CMakeLists.txt	2026-07-23 10:43:03.920659066 +0000
+@@ -76,5 +76,6 @@ if(${ENABLE_ambit})
+         set(ambit_DIR ${STAGED_INSTALL_PREFIX}/${_ambit_dir} CACHE PATH "path to internally built ambitConfig.cmake" FORCE)
+     endif()
+ else()
++    message(STATUS "Optional addon ${Blue}unsought: ambit${ColourReset}")
+     add_library(ambit_external INTERFACE)  # dummy
+ endif()
+diff -up psi4-1.11/external/upstream/bse/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/bse/CMakeLists.txt
+--- psi4-1.11/external/upstream/bse/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/bse/CMakeLists.txt	2026-07-23 10:43:03.920848412 +0000
+@@ -38,6 +38,7 @@ if(${ENABLE_bse})
+             )
+     endif()
+ else()
++    message(STATUS "Optional addon ${Blue}unsought: bse${ColourReset} (basis_set_exchange; deferrable to runtime)")
+     add_library(bse_external INTERFACE)  # dummy
+ endif()
+ 
+diff -up psi4-1.11/external/upstream/chemps2/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/chemps2/CMakeLists.txt
+--- psi4-1.11/external/upstream/chemps2/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/chemps2/CMakeLists.txt	2026-07-23 10:43:03.920997972 +0000
+@@ -70,6 +70,7 @@ if(${ENABLE_CheMPS2})
+         set(CheMPS2_DIR ${STAGED_INSTALL_PREFIX}/share/cmake/CheMPS2 CACHE PATH "path to internally built CheMPS2Config.cmake" FORCE)
+     endif()
+ else()
++    message(STATUS "Optional addon ${Blue}unsought: CheMPS2${ColourReset}")
+     add_library(chemps2_external INTERFACE)  # dummy
+ endif()
+ 
+diff -up psi4-1.11/external/upstream/cppe/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/cppe/CMakeLists.txt
+--- psi4-1.11/external/upstream/cppe/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/cppe/CMakeLists.txt	2026-07-23 10:43:03.921151833 +0000
+@@ -55,5 +55,6 @@ if(${ENABLE_cppe})
+ 
+     endif()
+ else()
++    message(STATUS "Optional addon ${Blue}unsought: cppe${ColourReset} (deferrable to runtime)")
+     add_library(cppe_external INTERFACE)  # dummy
+ endif()
+diff -up psi4-1.11/external/upstream/ddx/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/ddx/CMakeLists.txt
+--- psi4-1.11/external/upstream/ddx/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/ddx/CMakeLists.txt	2026-07-23 10:43:03.921307007 +0000
+@@ -37,5 +37,6 @@ if(${ENABLE_ddx})
+             )
+     endif()
+ else()
++    message(STATUS "Optional addon ${Blue}unsought: ddx${ColourReset} (deferrable to runtime)")
+     add_library(ddx_external INTERFACE)  # dummy
+ endif()
+diff -up psi4-1.11/external/upstream/dkh/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/dkh/CMakeLists.txt
+--- psi4-1.11/external/upstream/dkh/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/dkh/CMakeLists.txt	2026-07-23 10:43:03.921470214 +0000
+@@ -49,6 +49,7 @@ if(${ENABLE_dkh})
+         set(dkh_DIR ${STAGED_INSTALL_PREFIX}/${_dkh_dir} CACHE PATH "path to internally built dkhConfig.cmake" FORCE)
+     endif()
+ else()
++    message(STATUS "Optional addon ${Blue}unsought: dkh${ColourReset}")
+     add_library(dkh_external INTERFACE)  # dummy
+ endif()
+ 
+diff -up psi4-1.11/external/upstream/ecpint/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/ecpint/CMakeLists.txt
+--- psi4-1.11/external/upstream/ecpint/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/ecpint/CMakeLists.txt	2026-07-23 10:43:03.921623394 +0000
+@@ -43,6 +43,7 @@ if(${ENABLE_ecpint})
+         set(ecpint_DIR ${STAGED_INSTALL_PREFIX}/lib/cmake/ecpint CACHE PATH "path to internally built ecpint-config.cmake" FORCE)
+     endif()
+ else()
++    message(STATUS "Optional addon ${Blue}unsought: ecpint${ColourReset}")
+     add_library(ecpint_external INTERFACE)  # dummy
+ endif()
+ 
+diff -up psi4-1.11/external/upstream/einsums/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/einsums/CMakeLists.txt
+--- psi4-1.11/external/upstream/einsums/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/einsums/CMakeLists.txt	2026-07-23 10:43:03.921797895 +0000
+@@ -66,5 +66,6 @@ if(${ENABLE_Einsums})
+         set(Einsums_DIR ${STAGED_INSTALL_PREFIX}/${_einsums_dir} CACHE PATH "path to internally built EinsumsConfig.cmake" FORCE)
+     endif()
+ else()
++    message(STATUS "Optional addon ${Blue}unsought: einsums${ColourReset}")
+     add_library(einsums_external INTERFACE)  # dummy
+ endif()
+diff -up psi4-1.11/external/upstream/gauxc/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/gauxc/CMakeLists.txt
+--- psi4-1.11/external/upstream/gauxc/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/gauxc/CMakeLists.txt	2026-07-23 10:43:03.921956259 +0000
+@@ -99,5 +99,6 @@ if(${ENABLE_gauxc})
+         set(gauxc_DIR ${STAGED_INSTALL_PREFIX}/share/cmake/gauxc CACHE PATH "path to internally built gauxcConfig.cmake" FORCE)
+     endif()
+ else()
++    message(STATUS "Optional addon ${Blue}unsought: gauxc${ColourReset}")
+     add_library(gauxc_external INTERFACE)  # dummy
+ endif()
+diff -up psi4-1.11/external/upstream/gdma/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/gdma/CMakeLists.txt
+--- psi4-1.11/external/upstream/gdma/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/gdma/CMakeLists.txt	2026-07-23 10:43:03.922119034 +0000
+@@ -55,6 +55,7 @@ if(${ENABLE_gdma})
+         set(gdma_DIR ${STAGED_INSTALL_PREFIX}/${_gdma_dir} CACHE PATH "path to internally built gdmaConfig.cmake" FORCE)
+     endif()
+ else()
++    message(STATUS "Optional addon ${Blue}unsought: gdma${ColourReset} (deferrable to runtime)")
+     add_library(gdma_external INTERFACE)  # dummy
+ endif()
+ 
+diff -up psi4-1.11/external/upstream/integratorxx/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/integratorxx/CMakeLists.txt
+--- psi4-1.11/external/upstream/integratorxx/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/integratorxx/CMakeLists.txt	2026-07-23 10:43:03.922273925 +0000
+@@ -32,6 +32,7 @@ if(${ENABLE_IntegratorXX})
+         set(IntegratorXX_DIR ${STAGED_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/IntegratorXX CACHE PATH "path to internally built IntegratorXXConfig.cmake" FORCE)
+     endif()
+ else()
++    message(STATUS "Optional addon ${Blue}unsought: IntegratorXX${ColourReset}")
+     add_library(integratorxx_external INTERFACE)  # dummy
+ endif()
+ 
+diff -up psi4-1.11/external/upstream/libefp/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/libefp/CMakeLists.txt
+--- psi4-1.11/external/upstream/libefp/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/libefp/CMakeLists.txt	2026-07-23 10:43:03.922427202 +0000
+@@ -49,5 +49,6 @@ if(${ENABLE_libefp})
+         set(libefp_DIR ${STAGED_INSTALL_PREFIX}/share/cmake/libefp CACHE PATH "path to internally built libefpConfig.cmake" FORCE)
+     endif()
+ else()
++    message(STATUS "Optional addon ${Blue}unsought: libefp${ColourReset} (deferrable to runtime)")
+     add_library(libefp_external INTERFACE)  # dummy
+ endif()
+diff -up psi4-1.11/external/upstream/mdi/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/mdi/CMakeLists.txt
+--- psi4-1.11/external/upstream/mdi/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/mdi/CMakeLists.txt	2026-07-23 10:43:03.922576764 +0000
+@@ -45,5 +45,6 @@ if(${ENABLE_mdi})
+         set(mdi_DIR ${STAGED_INSTALL_PREFIX}/share/cmake/mdi CACHE PATH "path to internally built mdiConfig.cmake" FORCE)
+     endif()
+ else()
++    message(STATUS "Optional addon ${Blue}unsought: mdi${ColourReset} (deferrable to runtime)")
+     add_library(mdi_external INTERFACE)  # dummy
+ endif()
+diff -up psi4-1.11/external/upstream/openorbitaloptimizer/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/openorbitaloptimizer/CMakeLists.txt
+--- psi4-1.11/external/upstream/openorbitaloptimizer/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/openorbitaloptimizer/CMakeLists.txt	2026-07-23 10:43:03.922772670 +0000
+@@ -40,5 +40,6 @@ if(${ENABLE_OpenOrbitalOptimizer})
+         set(OpenOrbitalOptimizer_DIR ${STAGED_INSTALL_PREFIX}/${_ooo_dir} CACHE PATH "path to internally built OpenOrbitalOptimizerConfig.cmake" FORCE)
+     endif()
+ else()
++    message(STATUS "Optional addon ${Blue}unsought: OpenOrbitalOptimizer${ColourReset}")
+     add_library(openorbitaloptimizer_external INTERFACE)  # dummy
+ endif()
+diff -up psi4-1.11/external/upstream/pcmsolver/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/pcmsolver/CMakeLists.txt
+--- psi4-1.11/external/upstream/pcmsolver/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/pcmsolver/CMakeLists.txt	2026-07-23 10:43:03.922932629 +0000
+@@ -68,5 +68,6 @@
+         set(PCMSolver_DIR ${STAGED_INSTALL_PREFIX}/${_pcmsolver_dir} CACHE PATH "path to internally built PCMSolverConfig.cmake" FORCE)
+     endif()
+ else()
++    message(STATUS "Optional addon ${Blue}unsought: PCMSolver${ColourReset}")
+     add_library(pcmsolver_external INTERFACE)  # dummy
+ endif()
+diff -up psi4-1.11/external/upstream/pylibefp/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/pylibefp/CMakeLists.txt
+--- psi4-1.11/external/upstream/pylibefp/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/pylibefp/CMakeLists.txt	2026-07-23 10:43:03.923084534 +0000
+@@ -60,6 +60,7 @@ if(${ENABLE_libefp})
+         set(pylibefp_DIR ${STAGED_INSTALL_PREFIX}/share/cmake/pylibefp CACHE PATH "path to internally built pylibefpConfig.cmake" FORCE)
+     endif()
+ else()
++    message(STATUS "Optional addon ${Blue}unsought: libefp${ColourReset} (deferrable to runtime)")
+     add_library(pylibefp_external INTERFACE)  # dummy
+ endif()
+ 
+diff -up psi4-1.11/external/upstream/qcmanybody/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/qcmanybody/CMakeLists.txt
+--- psi4-1.11/external/upstream/qcmanybody/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/qcmanybody/CMakeLists.txt	2026-07-23 10:43:03.923229960 +0000
+@@ -1,41 +1,46 @@
+-if(NOT (${CMAKE_DISABLE_FIND_PACKAGE_qcmanybody}))
+-    include(FindPythonModule)
+-    find_python_module(qcmanybody ATLEAST 0.7.1 QUIET)
+-endif()
+-
+-if(${qcmanybody_FOUND})
+-    message(STATUS "${Cyan}Found qcmanybody${ColourReset}: ${PY_qcmanybody} (found version ${qcmanybody_VERSION})")
+-    add_library(qcmanybody_external INTERFACE)  # dummy
+-
+-    if(${CMAKE_INSIST_FIND_PACKAGE_qcmanybody})
+-        message(VERBOSE "Suitable qcmanybody located externally as user insists")
++if(${ENABLE_qcmanybody})
++    if(NOT (${CMAKE_DISABLE_FIND_PACKAGE_qcmanybody}))
++        include(FindPythonModule)
++        find_python_module(qcmanybody ATLEAST 0.7.1 QUIET)
+     endif()
+ 
+-else()
+-    if(${CMAKE_INSIST_FIND_PACKAGE_qcmanybody})
+-        message(FATAL_ERROR "Suitable qcmanybody could not be externally located as user insists")
++    if(${qcmanybody_FOUND})
++        message(STATUS "${Cyan}Found qcmanybody${ColourReset}: ${PY_qcmanybody} (found version ${qcmanybody_VERSION})")
++        add_library(qcmanybody_external INTERFACE)  # dummy
++
++        if(${CMAKE_INSIST_FIND_PACKAGE_qcmanybody})
++            message(VERBOSE "Suitable qcmanybody located externally as user insists")
++        endif()
++
++    else()
++        if(${CMAKE_INSIST_FIND_PACKAGE_qcmanybody})
++            message(FATAL_ERROR "Suitable qcmanybody could not be externally located as user insists")
++        endif()
++
++        include(ExternalProject)
++        message(STATUS "Suitable qcmanybody could not be located, ${Magenta}Building qcmanybody${ColourReset} instead.")
++
++        file(TO_NATIVE_PATH "${STAGED_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${PYMOD_INSTALL_LIBDIR}" _install_lib)
++
++        # Must have specialty egg to compute version correctly, so the URL is only grabbing a dummy file. It's
++        #   the pip command that's really selecting the source.
++        ExternalProject_Add(qcmanybody_external
++            DEPENDS qcelemental_external
++                    qcengine_external
++            BUILD_ALWAYS 1
++            DOWNLOAD_COMMAND ""
++            CONFIGURE_COMMAND ""
++            UPDATE_COMMAND ""
++            BUILD_COMMAND ""
++            BUILD_IN_SOURCE 1
++            # master: INSTALL_COMMAND ${Python_EXECUTABLE} -m pip install git+https://github.com/MolSSI/ QCManyBody.git#egg=proj
++            INSTALL_COMMAND ${Python_EXECUTABLE} -m pip install git+https://github.com/MolSSI/QCManyBody.git@v0.7.1#egg=proj  # edit in codedeps
++                                                          --target=${_install_lib}
++                                                          --no-deps
++                                                          #-v
++            )
+     endif()
+-
+-    include(ExternalProject)
+-    message(STATUS "Suitable qcmanybody could not be located, ${Magenta}Building qcmanybody${ColourReset} instead.")
+-
+-    file(TO_NATIVE_PATH "${STAGED_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${PYMOD_INSTALL_LIBDIR}" _install_lib)
+-
+-    # Must have specialty egg to compute version correctly, so the URL is only grabbing a dummy file. It's
+-    #   the pip command that's really selecting the source.
+-    ExternalProject_Add(qcmanybody_external
+-        DEPENDS qcelemental_external
+-                qcengine_external
+-        BUILD_ALWAYS 1
+-        DOWNLOAD_COMMAND ""
+-        CONFIGURE_COMMAND ""
+-        UPDATE_COMMAND ""
+-        BUILD_COMMAND ""
+-        BUILD_IN_SOURCE 1
+-        # master: INSTALL_COMMAND ${Python_EXECUTABLE} -m pip install git+https://github.com/MolSSI/ QCManyBody.git#egg=proj
+-        INSTALL_COMMAND ${Python_EXECUTABLE} -m pip install git+https://github.com/MolSSI/QCManyBody.git@v0.7.1#egg=proj  # edit in codedeps
+-                                                      --target=${_install_lib}
+-                                                      --no-deps
+-                                                      #-v
+-        )
++else()
++    message(STATUS "Optional addon ${Blue}unsought: qcmanybody${ColourReset} (deferrable to runtime)")
++    add_library(qcmanybody_external INTERFACE)  # dummy
+ endif()
+diff -up psi4-1.11/external/upstream/simint/CMakeLists.txt.noqcmb psi4-1.11/external/upstream/simint/CMakeLists.txt
+--- psi4-1.11/external/upstream/simint/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/external/upstream/simint/CMakeLists.txt	2026-07-23 10:43:03.923383733 +0000
+@@ -54,5 +54,6 @@ if(${ENABLE_simint})
+         set(simint_DIR ${STAGED_INSTALL_PREFIX}/share/cmake/simint CACHE PATH "path to internally built simintConfig.cmake" FORCE)
+     endif()
+ else()
++    message(STATUS "Optional addon ${Blue}unsought: simint${ColourReset}")
+     add_library(simint_external INTERFACE)  # dummy
+ endif()
+diff -up psi4-1.11/.github/workflows/docs-pr.yml.noqcmb psi4-1.11/.github/workflows/docs-pr.yml
+--- psi4-1.11/.github/workflows/docs-pr.yml.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/.github/workflows/docs-pr.yml	2026-07-23 10:43:03.917956046 +0000
+@@ -23,14 +23,14 @@ jobs:
+     # fetch-depth: 0 gets git history so Psi4 version computable
+     - name: Checkout
+       if: ${{ github.repository == 'psi4/psi4' }}
+-      uses: actions/checkout@v4
++      uses: actions/checkout@v6
+       with:
+         fetch-depth: 0
+         path: code
+ 
+     - name: Checkout psi4/psi4docs Repo
+       if: ${{ github.repository == 'psi4/psi4' }}
+-      uses: actions/checkout@v4
++      uses: actions/checkout@v6
+       with:
+         repository: psi4/psi4docs
+         path: docs
+diff -up psi4-1.11/.github/workflows/docs.yml.noqcmb psi4-1.11/.github/workflows/docs.yml
+--- psi4-1.11/.github/workflows/docs.yml.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/.github/workflows/docs.yml	2026-07-23 10:43:03.918128518 +0000
+@@ -33,14 +33,14 @@ jobs:
+     # fetch-depth: 0 gets git history so Psi4 version computable
+     - name: Checkout
+       if: ${{ github.repository == 'psi4/psi4' }}
+-      uses: actions/checkout@v4
++      uses: actions/checkout@v6
+       with:
+         fetch-depth: 0
+         path: code
+ 
+     - name: Checkout website repo
+       if: ${{ github.repository == 'psi4/psi4' }}
+-      uses: actions/checkout@v4
++      uses: actions/checkout@v6
+       with:
+         repository: psi4/psi4docs
+         path: docs
+diff -up psi4-1.11/.github/workflows/ecosystem.yml.noqcmb psi4-1.11/.github/workflows/ecosystem.yml
+--- psi4-1.11/.github/workflows/ecosystem.yml.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/.github/workflows/ecosystem.yml	2026-07-23 10:43:03.928705523 +0000
+@@ -151,7 +151,7 @@ jobs:
+ 
+       # fetch-depth: 0 gets git history so Psi4 version is computable
+     - name: Checkout Psi4
+-      uses: actions/checkout@v4
++      uses: actions/checkout@v6
+       with:
+         fetch-depth: 0
+ 
+@@ -340,7 +340,7 @@ jobs:
+ 
+     - name: Special Config - Download MolSSI/QCFractal Repo
+       if: runner.os == 'Linux'
+-      uses: actions/checkout@v4
++      uses: actions/checkout@v6
+       with:
+         repository: MolSSI/QCFractal
+         path: qca
+@@ -456,6 +456,26 @@ jobs:
+         conda install conda-tree -c conda-forge
+         conda-tree deptree
+ 
++    - name: dlopen -- Remove Addons
++      if: matrix.cfg.python-version == '3.14' && runner.os != 'Windows'
++      run: conda remove qcmanybody --force -y
++
++    - name: dlopen -- Runtime Conda environment
++      if: matrix.cfg.python-version == '3.14' && runner.os != 'Windows'
++      working-directory: ./objdir
++      run: |
++        conda info
++        conda list
++        PYTHONPATH=stage/lib python -c "import psi4; print(psi4.__file__)"
++
++    - name: dlopen -- Test Addons with Pytest
++      if: matrix.cfg.python-version == '3.14' && runner.os != 'Windows'
++      working-directory: ./objdir
++      run: |
++        export PYTHONPATH=stage/lib
++        pytest --cache-clear -v -rws --color yes -n auto -m qcmanybody stage/lib/psi4/tests/
++        pytest --cache-clear -v -rws --color yes -n auto -k missing stage/lib/psi4/tests/
++
+ # Notes
+ # -----
+ 
+diff -up psi4-1.11/psi4/CMakeLists.txt.noqcmb psi4-1.11/psi4/CMakeLists.txt
+--- psi4-1.11/psi4/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/psi4/CMakeLists.txt	2026-07-23 10:43:03.923562916 +0000
+@@ -140,7 +140,7 @@ if(${ENABLE_libefp})
+     #list(APPEND _addons ${_loc})
+     message(STATUS "${Cyan}Using pylibefp${ColourReset}: ${_loc} (version ${pylibefp_VERSION})")
+ else()
+-    message(STATUS "Disabled libefp ${libefp_DIR} ${pylibefp_DIR}")
++    message(STATUS "Disabled libefp ${libefp_DIR} ${pylibefp_DIR} (deferrable to runtime)")
+ endif()
+ 
+ if(${ENABLE_Einsums})
+@@ -183,7 +183,7 @@ if(${ENABLE_gdma})
+     get_property(_loc TARGET gdma::pygdma PROPERTY LOCATION)
+     message(STATUS "${Cyan}Found gdma${ColourReset}: ${_loc} (version ${gdma_VERSION})")
+ else()
+-    message(STATUS "Disabled gdma ${gdma_DIR}")
++    message(STATUS "Disabled gdma ${gdma_DIR} (deferrable to runtime)")
+ endif()
+ 
+ find_package(Libint2 2.8.1 CONFIG REQUIRED  # edit in codedeps
+@@ -209,7 +209,7 @@ if(${ENABLE_mdi})
+     list(APPEND _addons ${_loc})
+     message(STATUS "${Cyan}Using mdi${ColourReset}: ${_loc} (version ${mdi_VERSION})")
+ else()
+-    message(STATUS "Disabled MDI ${mdi_DIR}")
++    message(STATUS "Disabled MDI ${mdi_DIR} (deferrable to runtime)")
+ endif ()
+ 
+ if(${ENABLE_OpenOrbitalOptimizer})
+diff -up psi4-1.11/psi4/driver/driver_nbody.py.noqcmb psi4-1.11/psi4/driver/driver_nbody.py
+--- psi4-1.11/psi4/driver/driver_nbody.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/psi4/driver/driver_nbody.py	2026-07-23 10:43:03.928197256 +0000
+@@ -118,10 +118,32 @@ from .task_base import AtomicComputer, E
+ from pydantic import field_validator
+ 
+ from qcelemental.models.v2 import Molecule, AtomicSpecification
+-from qcmanybody.models.v2 import ManyBodyInput, ManyBodyResult, BsseEnum
+-from qcmanybody import ManyBodyCore
+-from qcmanybody.v2 import ManyBodyComputer as ManyBodyComputerQCNG
+-from qcmanybody.utils import delabeler, labeler, translate_qcvariables, modelchem_labels
++
++_QCMANYBODY_IMPORT_ERROR = None
++try:
++    from qcmanybody.models.v2 import ManyBodyInput, ManyBodyResult, BsseEnum
++    from qcmanybody import ManyBodyCore
++    from qcmanybody.v2 import ManyBodyComputer as ManyBodyComputerQCNG
++    from qcmanybody.utils import delabeler, labeler, translate_qcvariables, modelchem_labels
++except ImportError as err:
++    _QCMANYBODY_IMPORT_ERROR = err
++    ManyBodyInput = Any
++    ManyBodyResult = Any
++    BsseEnum = Any
++    ManyBodyCore = Any
++    ManyBodyComputerQCNG = object
++
++
++def _ensure_qcmanybody() -> None:
++    if _QCMANYBODY_IMPORT_ERROR is None:
++        return
++
++    raise ModuleNotFoundError(
++        "Python module qcmanybody not found (or incompatible) that is required for many-body/counterpoise "
++        "(`bsse_type`) computations. Install/upgrade to `qcmanybody>=0.7.1` with "
++        "`conda install -c conda-forge qcmanybody` or `pip install -U qcmanybody`. "
++        f"Original import error: {_QCMANYBODY_IMPORT_ERROR}"
++    ) from _QCMANYBODY_IMPORT_ERROR
+ 
+ if TYPE_CHECKING:
+     import qcportal
+@@ -411,6 +433,8 @@ class ManyBodyComputer(ManyBodyComputerQ
+     @classmethod
+     def from_psi4_task_planner(cls, *, molecule, method, basis, driver, keywords, **mbkwargs):
+ 
++        _ensure_qcmanybody()
++
+         atomic_spec = AtomicSpecification(
+             model={"method": method, "basis": basis},
+             program="psi4",
+@@ -505,6 +529,8 @@ class ManyBodyComputer(ManyBodyComputerQ
+             Number of new tasks planned by this call including any supersystem.
+ 
+         """
++        _ensure_qcmanybody()
++
+         # TODO method not coming from levels right
+ 
+         # Get the n-body orders for this level. e.g., [1] or [2, 3] or ["supersystem"]
+@@ -574,6 +600,8 @@ class ManyBodyComputer(ManyBodyComputerQ
+             All MBE results collected into a QCSchema model.
+ 
+         """
++        _ensure_qcmanybody()
++
+         component_results = {k: v.get_results(client=client).convert_v(2) for k, v in self.task_list.items()}
+         component_properties = {}
+         props = {"energy", "gradient", "hessian"}
+diff -up psi4-1.11/psi4/extras.py.noqcmb psi4-1.11/psi4/extras.py
+--- psi4-1.11/psi4/extras.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/psi4/extras.py	2026-07-23 10:43:03.829627156 +0000
+@@ -180,6 +180,7 @@ _addons_ = {
+     "gauxc": _CMake_to_Py_boolean("@ENABLE_gauxc@"),
+     "integratorxx": _CMake_to_Py_boolean("@ENABLE_IntegratorXX@"),
+     "ooo": _CMake_to_Py_boolean("@ENABLE_OpenOrbitalOptimizer@"),
++    "qcmanybody": which_import("qcmanybody", return_bool=True),
+ }
+ 
+ 
+diff -up psi4-1.11/psi4/__init__.py.noqcmb psi4-1.11/psi4/__init__.py
+--- psi4-1.11/psi4/__init__.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/psi4/__init__.py	2026-07-23 10:43:03.925174398 +0000
+@@ -109,18 +109,14 @@ from .driver.schema_wrapper import run_q
+ # * Note that this is a "battening down the hatches" for the many
+ #   rather than letting PYTHONPATH rule for the few.
+ import sys
+-if "@ENABLE_PCMSolver@".upper() in ["1", "ON", "YES", "TRUE", "Y"]:  # PCMSolver
++_enabled_choice = ("1", "ON", "YES", "TRUE", "Y")
++if "@ENABLE_PCMSolver@".upper() in _enabled_choice:  # PCMSolver
+     sys.path.insert(1, r"@PCMSolver_PYMOD@")
+-if "@ENABLE_cppe@".upper() in ["1", "ON", "YES", "TRUE", "Y"]:  # cppe
+-    sys.path.insert(1, r"@cppe_PYMOD@")
+-if "@ENABLE_ddx@".upper() in ["1", "ON", "YES", "TRUE", "Y"]:  # pyddx
+-    sys.path.insert(1, r"@pyddx_PYMOD@")
+-if "@ENABLE_libefp@".upper() in ["1", "ON", "YES", "TRUE", "Y"]:  # pylibefp
+-    sys.path.insert(1, r"@pylibefp_PYMOD@")
+-if "@ENABLE_gdma@".upper() in ["1", "ON", "YES", "TRUE", "Y"]:  # gdma
++if "@ENABLE_libefp@".upper() in _enabled_choice:  # pylibefp
++    sys.path.insert(1, str(Path(r"@PY_pylibefp@").resolve().parent))
++if "@ENABLE_gdma@".upper() in _enabled_choice:  # gdma
+     sys.path.insert(1, r"@gdma_PYMOD@")
+-if "@ENABLE_bse@".upper() in ["1", "ON", "YES", "TRUE", "Y"]:  # bse
+-    sys.path.insert(1, r"@bse_PYMOD@")
++del _enabled_choice
+ 
+ # Create a custom logger
+ import logging
+diff -up psi4-1.11/pytest.ini.noqcmb psi4-1.11/pytest.ini
+--- psi4-1.11/pytest.ini.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/pytest.ini	2026-07-23 10:43:03.829833903 +0000
+@@ -93,7 +93,7 @@ markers =
+     mints
+     mom
+     mp2
+-    nbody: "tests that use the nbody aka manybody wrapper"
++    nbody: "tests that use the nbody aka manybody wrapper; alias to qcmanybody marker"
+     noc1
+     numint: "tests that use NumIntHelper"
+     numpy
+@@ -181,6 +181,7 @@ markers =
+     qcfractal: "tests using QCFractal software; skip if unavailable"
+     qcfractal_next: "tests using QCFractal software, next branch; skip if unavailable"
+     qcportal: "tests using QCPortal software; skip if unavailable"
++    qcmanybody: "tests using QCManyBody software; skip if unavailable; alias to nbody marker"
+     psi4
+     
+ 
+@@ -188,4 +189,3 @@ markers =
+ # filterwarnings =
+ #     error
+ #     ignore:unclosed file:ResourceWarning
+-
+diff -up psi4-1.11/tests/cbs-xtpl-nbody/test_input.py.noqcmb psi4-1.11/tests/cbs-xtpl-nbody/test_input.py
+--- psi4-1.11/tests/cbs-xtpl-nbody/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/cbs-xtpl-nbody/test_input.py	2026-07-23 10:43:03.829993598 +0000
+@@ -1,6 +1,6 @@
+ from addons import *
+ 
+-@ctest_labeler("cbs;nbody")
++@uusing("qcmanybody")
++@ctest_labeler("cbs")
+ def test_cbs_xtpl_nbody():
+     ctest_runner(__file__)
+-
+diff -up psi4-1.11/tests/cfour/CMakeLists.txt.noqcmb psi4-1.11/tests/cfour/CMakeLists.txt
+--- psi4-1.11/tests/cfour/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/cfour/CMakeLists.txt	2026-07-23 10:43:03.906575105 +0000
+@@ -20,7 +20,9 @@ add_subdirectory(scf4)
+ add_subdirectory(mp2-1)
+ add_subdirectory(pywrap-db1)
+ add_subdirectory(pywrap-basis)
+-add_subdirectory(dfmp2-1)
++if(ENABLE_qcmanybody)
++    add_subdirectory(dfmp2-1)
++endif()
+ add_subdirectory(sp-rhf-scf)
+ add_subdirectory(sp-rhf-mp2)
+ add_subdirectory(sp-rhf-ccsd)
+diff -up psi4-1.11/tests/CMakeLists.txt.noqcmb psi4-1.11/tests/CMakeLists.txt
+--- psi4-1.11/tests/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/CMakeLists.txt	2026-07-23 10:43:03.906233614 +0000
+@@ -32,7 +32,7 @@
+ foreach(test_name aediis-1
+                   casscf-fzc-sp casscf-semi casscf-sa-sp ao-casscf-sp casscf-sp castup1
+                   castup2 castup3 cbs-delta-energy cbs-parser cbs-xtpl-alpha cbs-xtpl-energy
+-                  cbs-xtpl-freq cbs-xtpl-gradient cbs-xtpl-opt cbs-xtpl-func cbs-xtpl-nbody
++                  cbs-xtpl-freq cbs-xtpl-gradient cbs-xtpl-opt cbs-xtpl-func
+                   cbs-xtpl-wrapper cbs-xtpl-dict cc1 cc10 cc11 cc12 cc13 cc13a cc13b cc13c
+                   cc13d cc14 cc15 cc16 cc17 cc18 cc19 cc2 cc21 cc22 cc23 cc24 cc25 cc26 cc27 cc28
+                   cc29 cc3 cc30 cc31 cc32 cc33 cc34 cc35 cc36 cc37 cc38 cc39
+@@ -46,7 +46,7 @@ foreach(test_name aediis-1
+                   dct10 dct11 dct12 ao-dfcasscf-sp density-screen-1 density-screen-2 dfcasscf-sa-sp
+                   dfcasscf-fzc-sp dfcasscf-sp dfccd1 dfccdl1 dfccd-grad1 dfccsd1 dfccsdl1 dfccsd-grad1
+                   dfccsd-t-grad1
+-                  dfccsdt1 dfccsdat1 dfmp2-1 dfmp2-2 dfmp2-3 dfmp2-4 dfmp2-5 dfmp2-fc dfmp2-freq1 dfmp2-freq2
++                  dfccsdt1 dfccsdat1 dfmp2-2 dfmp2-3 dfmp2-4 dfmp2-5 dfmp2-freq1 dfmp2-freq2
+                   dfccsd-grad2 dfccsd-t-grad2 dfccsdat2 dfccsdt2
+                   dfmp2-grad1 dfmp2-grad2 dfmp2-grad3 dfmp2-grad4 dfmp2-grad5 dfomp2-1 dfomp2-2 dfomp2-3
+                   dfomp2-4 dfomp2-grad1 dfomp2-grad2 dfomp2-grad3 dfomp3-1 dfomp3-2
+@@ -70,10 +70,8 @@ foreach(test_name aediis-1
+                   mbis-1 mbis-2 mbis-3 mbis-4 mbis-5 mbis-6 mbis-7 mcscf1 mcscf2 mcscf3
+                   mints1 mints2 mints3 mints4 mints5 mints6 mints8 mints-benchmark mints-helper
+                   mints9 mints10 mints15 molden1 molden2 mom mom-h2o-3 mom-h2o-4
+-                  mp2-1  mp2-def2 mp2-grad1 mp2-grad2 mp2-grad3 mp2-h mp2p5-grad1 mp2p5-grad2 mp3-grad1 mp3-grad2
+-                  mp2-property mp2f12-1 mpn-bh nbody-he-cluster nbody-intermediates nbody-nocp-gradient
+-                  nbo nbody-cp-gradient nbody-vmfc-gradient nbody-vmfc-hessian nbody-hessian nbody-convergence
+-                  nbody-freq nbody-multi-level nbody-multi-level-2 numint1 numpy-array-interface
++                  mp2-1 mp2-grad1 mp2-grad2 mp2-grad3 mp2-h mp2p5-grad1 mp2p5-grad2 mp3-grad1 mp3-grad2
++                  mp2-property mp2f12-1 mpn-bh nbo numint1 numpy-array-interface
+                   olccd-freq1 olccd-grad1 olccd-grad2 olccd1 olccd2 olccd3
+                   omp2-1 omp2-2 omp2-3 omp2-4 omp2-5 omp2-grad1 omp2-grad2
+                   omp2p5-1 omp2p5-2 omp2p5-grad1 omp2p5-grad2 omp3-1 omp3-2
+@@ -101,14 +99,14 @@ foreach(test_name aediis-1
+                   soscf-dft stability1 dfep2-1 dfep2-2 sapt-dft1 sapt-dft2 sapt-compare sapt-sf1 dft-custom dft-reference
+                   stability2 stability3 tu1-h2o-energy tu2-ch2-energy tu3-h2o-opt scf-response1 scf-response2 scf-response3
+                   scf-cholesky-basis scf-auto-cholesky
+-                  tu4-h2o-freq tu5-sapt tu6-cp-ne2 x2c1 x2c2 x2c3 x2c-perturb-h zaptn-nh2 zora
++                  tu4-h2o-freq tu5-sapt x2c1 x2c2 x2c3 x2c-perturb-h zaptn-nh2 zora
+                   options1 cubeprop-esp dft-smoke scf-hess1 scf-hess2 scf-hess3 scf-hess4 scf-hess5 scf-freq1 dft-jk scf-coverage
+-                  dft-custom-dhdf dft-custom-hybrid dft-custom-mgga dft-custom-gga
++                  dft-custom-hybrid dft-custom-mgga dft-custom-gga
+                   pywrap-bfs pywrap-align pywrap-align-chiral mints12 cc-module
+                   tdscf-1 tdscf-2 tdscf-3 tdscf-4 tdscf-5 tdscf-6 tdscf-7
+                   dft-pruning freq-masses sapt9 sapt10 sapt11 scf-uhf-grad-nobeta
+                   linK-1 linK-2 linK-3
+-                  cbs-xtpl-energy-conv ddd-deriv nbody-he-4b ddd-function-kwargs dfmp2f12-1
++                  cbs-xtpl-energy-conv ddd-deriv dfmp2f12-1
+                   )
+     add_subdirectory(${test_name})
+ endforeach()
+@@ -280,7 +278,9 @@ endif()
+ if(ENABLE_ecpint)
+     add_subdirectory(aediis-2)
+     add_subdirectory(basis-ecp)
+-    add_subdirectory(dfmp2-ecp)
++    if(ENABLE_qcmanybody)
++        add_subdirectory(dfmp2-ecp)
++    endif()
+     add_subdirectory(sapt-ecp)
+     add_subdirectory(scf-ecp)
+     add_subdirectory(scf-ecp2)
+@@ -289,6 +289,32 @@ if(ENABLE_ecpint)
+     message(STATUS "Adding test cases: Psi4 + ecpint")
+ endif()
+ 
++# <<<  QCManyBody  >>>
++
++if(ENABLE_qcmanybody)
++    add_subdirectory(cbs-xtpl-nbody)
++    add_subdirectory(ddd-function-kwargs)
++    add_subdirectory(dfmp2-1)
++    add_subdirectory(dfmp2-fc)
++    add_subdirectory(dft-custom-dhdf)
++    add_subdirectory(dlpnocc-3)
++    add_subdirectory(mp2-def2)
++    add_subdirectory(nbody-convergence)
++    add_subdirectory(nbody-cp-gradient)
++    add_subdirectory(nbody-freq)
++    add_subdirectory(nbody-he-4b)
++    add_subdirectory(nbody-he-cluster)
++    add_subdirectory(nbody-hessian)
++    add_subdirectory(nbody-intermediates)
++    add_subdirectory(nbody-multi-level)
++    add_subdirectory(nbody-multi-level-2)
++    add_subdirectory(nbody-nocp-gradient)
++    add_subdirectory(nbody-vmfc-gradient)
++    add_subdirectory(nbody-vmfc-hessian)
++    add_subdirectory(tu6-cp-ne2)
++    message(STATUS "Adding test cases: Psi4 + qcmanybody")
++endif()
++
+ # plugin regime
+ if(ENABLE_PLUGIN_TESTING)
+     add_subdirectory(plugins)
+diff -up psi4-1.11/tests/ddd-function-kwargs/test_input.py.noqcmb psi4-1.11/tests/ddd-function-kwargs/test_input.py
+--- psi4-1.11/tests/ddd-function-kwargs/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/ddd-function-kwargs/test_input.py	2026-07-23 10:43:03.830118208 +0000
+@@ -1,6 +1,6 @@
+ from addons import *
+ 
+-@ctest_labeler("findif;nbody;gradient")
++@uusing("qcmanybody")
++@ctest_labeler("findif;gradient")
+ def test_ddd_function_kwargs():
+     ctest_runner(__file__)
+-
+diff -up psi4-1.11/tests/dfmp2-1/test_input.py.noqcmb psi4-1.11/tests/dfmp2-1/test_input.py
+--- psi4-1.11/tests/dfmp2-1/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/dfmp2-1/test_input.py	2026-07-23 10:43:03.830241091 +0000
+@@ -1,6 +1,6 @@
+ from addons import *
+ 
+-@ctest_labeler("quick;smoke;df;dfmp2;cart;nbody")
++@uusing("qcmanybody")
++@ctest_labeler("quick;smoke;df;dfmp2;cart")
+ def test_dfmp2_1():
+     ctest_runner(__file__)
+-
+diff -up psi4-1.11/tests/dfmp2-ecp/test_input.py.noqcmb psi4-1.11/tests/dfmp2-ecp/test_input.py
+--- psi4-1.11/tests/dfmp2-ecp/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/dfmp2-ecp/test_input.py	2026-07-23 10:43:03.830365941 +0000
+@@ -2,7 +2,8 @@ import pytest
+ from addons import *
+ 
+ @uusing("ecpint")
+-@ctest_labeler("quick;df;dfmp2;ecp;nbody")
++@uusing("qcmanybody")
++@ctest_labeler("quick;df;dfmp2;ecp")
+ @pytest.mark.parametrize("oopkg", [
+     pytest.param(False, id="internal"),
+     pytest.param(True,  id="openorbitaloptimizer", marks=using("ooo")),
+diff -up psi4-1.11/tests/dfmp2-fc/test_input.py.noqcmb psi4-1.11/tests/dfmp2-fc/test_input.py
+--- psi4-1.11/tests/dfmp2-fc/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/dfmp2-fc/test_input.py	2026-07-23 10:43:03.830490551 +0000
+@@ -1,6 +1,6 @@
+ from addons import *
+ 
+-@ctest_labeler("quick;df;dfmp2;nbody")
++@uusing("qcmanybody")
++@ctest_labeler("quick;df;dfmp2")
+ def test_dfmp2_fc():
+     ctest_runner(__file__)
+-
+diff -up psi4-1.11/tests/dft-custom-dhdf/test_input.py.noqcmb psi4-1.11/tests/dft-custom-dhdf/test_input.py
+--- psi4-1.11/tests/dft-custom-dhdf/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/dft-custom-dhdf/test_input.py	2026-07-23 10:43:03.830618553 +0000
+@@ -1,6 +1,6 @@
+ from addons import *
+ 
+-@ctest_labeler("dft;scf;nbody")
++@uusing("qcmanybody")
++@ctest_labeler("dft;scf")
+ def test_dft_custom_dhdf():
+     ctest_runner(__file__)
+-
+diff -up psi4-1.11/tests/dftd3/CMakeLists.txt.noqcmb psi4-1.11/tests/dftd3/CMakeLists.txt
+--- psi4-1.11/tests/dftd3/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/dftd3/CMakeLists.txt	2026-07-23 10:43:03.906712877 +0000
+@@ -2,4 +2,6 @@ add_subdirectory(energy)
+ add_subdirectory(grad)
+ add_subdirectory(psithon2)
+ add_subdirectory(version)
+-add_subdirectory(nbody-cp-gradient)
++if(ENABLE_qcmanybody)
++    add_subdirectory(nbody-cp-gradient)
++endif()
+diff -up psi4-1.11/tests/dftd3/nbody-cp-gradient/test_input.py.noqcmb psi4-1.11/tests/dftd3/nbody-cp-gradient/test_input.py
+--- psi4-1.11/tests/dftd3/nbody-cp-gradient/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/dftd3/nbody-cp-gradient/test_input.py	2026-07-23 10:43:03.830801705 +0000
+@@ -1,6 +1,7 @@
+ from addons import *
+ 
+ @uusing("dftd3")
+-@ctest_labeler("cart;nbody;gradient")
++@uusing("qcmanybody")
++@ctest_labeler("cart;gradient")
+ def test_dftd3_nbody_cp_gradient():
+     ctest_runner(__file__)
+diff -up psi4-1.11/tests/dlpnocc-3/CMakeLists.txt.noqcmb psi4-1.11/tests/dlpnocc-3/CMakeLists.txt
+--- psi4-1.11/tests/dlpnocc-3/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/dlpnocc-3/CMakeLists.txt	2026-07-23 10:43:03.906874829 +0000
+@@ -1,3 +1,3 @@
+ include(TestingMacros)
+ 
+-add_regression_test(dlpnocc-3 "psi;dlpno;cc;quick")
+\ No newline at end of file
++add_regression_test(dlpnocc-3 "psi;dlpno;cc;quick")
+diff -up psi4-1.11/tests/dlpnocc-3/test_input.py.noqcmb psi4-1.11/tests/dlpnocc-3/test_input.py
+--- psi4-1.11/tests/dlpnocc-3/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/dlpnocc-3/test_input.py	2026-07-23 10:43:03.909042167 +0000
+@@ -1,5 +1,6 @@
+ from addons import *
+ 
++@uusing("qcmanybody")
+ @ctest_labeler("dlpno;cc;quick")
+ def test_dlpnocc_3():
+-    ctest_runner(__file__)
+\ No newline at end of file
++    ctest_runner(__file__)
+diff -up psi4-1.11/tests/gcp/CMakeLists.txt.noqcmb psi4-1.11/tests/gcp/CMakeLists.txt
+--- psi4-1.11/tests/gcp/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/gcp/CMakeLists.txt	2026-07-23 10:43:03.909174652 +0000
+@@ -1,5 +1,7 @@
+ add_subdirectory(pbeh3c)
+-add_subdirectory(hf3c)
++if (ENABLE_qcmanybody)
++    add_subdirectory(hf3c)
++endif()
+ add_subdirectory(hf3c-gradient)
+ add_subdirectory(hf3c-hessian)
+ add_subdirectory(dft-custom-hybrid)
+diff -up psi4-1.11/tests/gcp/hf3c/test_input.py.noqcmb psi4-1.11/tests/gcp/hf3c/test_input.py
+--- psi4-1.11/tests/gcp/hf3c/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/gcp/hf3c/test_input.py	2026-07-23 10:43:03.909313094 +0000
+@@ -1,5 +1,6 @@
+ from addons import *
+ 
++@uusing("qcmanybody")
+ @uusing("gcp")
+ @uusing("dftd3")
+ @ctest_labeler("quick;smoke")
+diff -up psi4-1.11/tests/mp2-def2/test_input.py.noqcmb psi4-1.11/tests/mp2-def2/test_input.py
+--- psi4-1.11/tests/mp2-def2/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/mp2-def2/test_input.py	2026-07-23 10:43:03.830928242 +0000
+@@ -1,6 +1,6 @@
+ from addons import *
+ 
+-@ctest_labeler("mp2;cart;nbody")
++@uusing("qcmanybody")
++@ctest_labeler("mp2;cart")
+ def test_mp2_def2():
+     ctest_runner(__file__)
+-
+diff -up psi4-1.11/tests/nbody-convergence/test_input.py.noqcmb psi4-1.11/tests/nbody-convergence/test_input.py
+--- psi4-1.11/tests/nbody-convergence/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/nbody-convergence/test_input.py	2026-07-23 10:43:03.831049950 +0000
+@@ -1,6 +1,6 @@
+ from addons import *
+ 
+-@ctest_labeler("nbody;gradient")
++@uusing("qcmanybody")
++@ctest_labeler("gradient")
+ def test_nbody_convergence():
+     ctest_runner(__file__)
+-
+diff -up psi4-1.11/tests/nbody-cp-gradient/test_input.py.noqcmb psi4-1.11/tests/nbody-cp-gradient/test_input.py
+--- psi4-1.11/tests/nbody-cp-gradient/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/nbody-cp-gradient/test_input.py	2026-07-23 10:43:03.831174042 +0000
+@@ -1,12 +1,12 @@
+ import pytest
+ from addons import *
+ 
++@uusing("qcmanybody")
+ @pytest.mark.parametrize("distributed", [
+     pytest.param(False, id="internal"),
+     pytest.param(True,  id="snowflake", marks=using("qcfractal_next")),
+ ])
+-@ctest_labeler("nbody;gradient")
++@ctest_labeler("gradient")
+ def test_nbody_cp_gradient(distributed):
+     setenv = ["_PSI4_USE_QCF"] if distributed else None
+     ctest_runner(__file__, setenv=setenv)
+-
+diff -up psi4-1.11/tests/nbody-freq/test_input.py.noqcmb psi4-1.11/tests/nbody-freq/test_input.py
+--- psi4-1.11/tests/nbody-freq/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/nbody-freq/test_input.py	2026-07-23 10:43:03.831297430 +0000
+@@ -1,6 +1,6 @@
+ from addons import *
+ 
+-@ctest_labeler("nbody;freq;hessian;gradient;opt")
++@uusing("qcmanybody")
++@ctest_labeler("freq;hessian;gradient;opt")
+ def test_nbody_freq():
+     ctest_runner(__file__)
+-
+diff -up psi4-1.11/tests/nbody-he-4b/test_input.py.noqcmb psi4-1.11/tests/nbody-he-4b/test_input.py
+--- psi4-1.11/tests/nbody-he-4b/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/nbody-he-4b/test_input.py	2026-07-23 10:43:03.831420061 +0000
+@@ -1,12 +1,12 @@
+ import pytest
+ from addons import *
+ 
++@uusing("qcmanybody")
+ @pytest.mark.parametrize("distributed", [
+     pytest.param(False, id="internal"),
+     pytest.param(True,  id="snowflake", marks=using("qcfractal_next")),
+ ])
+-@ctest_labeler("nbody;cart")
++@ctest_labeler("cart")
+ def test_nbody_he_4b(distributed):
+     setenv = ["_PSI4_USE_QCF"] if distributed else None
+     ctest_runner(__file__, setenv=setenv)
+-
+diff -up psi4-1.11/tests/nbody-he-cluster/test_input.py.noqcmb psi4-1.11/tests/nbody-he-cluster/test_input.py
+--- psi4-1.11/tests/nbody-he-cluster/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/nbody-he-cluster/test_input.py	2026-07-23 10:43:03.831541486 +0000
+@@ -1,6 +1,6 @@
+ from addons import *
+ 
+-@ctest_labeler("nbody;cart")
++@uusing("qcmanybody")
++@ctest_labeler("cart")
+ def test_nbody_he_cluster():
+     ctest_runner(__file__)
+-
+diff -up psi4-1.11/tests/nbody-hessian/test_input.py.noqcmb psi4-1.11/tests/nbody-hessian/test_input.py
+--- psi4-1.11/tests/nbody-hessian/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/nbody-hessian/test_input.py	2026-07-23 10:43:03.831665428 +0000
+@@ -1,6 +1,6 @@
+ from addons import *
+ 
+-@ctest_labeler("nbody;hessian")
++@uusing("qcmanybody")
++@ctest_labeler("hessian")
+ def test_nbody_hessian():
+     ctest_runner(__file__)
+-
+diff -up psi4-1.11/tests/nbody-intermediates/CMakeLists.txt.noqcmb psi4-1.11/tests/nbody-intermediates/CMakeLists.txt
+--- psi4-1.11/tests/nbody-intermediates/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/nbody-intermediates/CMakeLists.txt	2026-07-23 10:43:03.907163741 +0000
+@@ -1,3 +1,3 @@
+ include(TestingMacros)
+ 
+-add_regression_test(nbody-intermediates "psi;nbody") 
++add_regression_test(nbody-intermediates "psi;nbody")
+diff -up psi4-1.11/tests/nbody-intermediates/test_input.py.noqcmb psi4-1.11/tests/nbody-intermediates/test_input.py
+--- psi4-1.11/tests/nbody-intermediates/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/nbody-intermediates/test_input.py	2026-07-23 10:43:03.831820726 +0000
+@@ -1,6 +1,6 @@
+ from addons import *
+ 
+-@ctest_labeler("nbody")
++@uusing("qcmanybody")
++@ctest_labeler("")
+ def test_nbody_intermediates():
+     ctest_runner(__file__)
+-
+diff -up psi4-1.11/tests/nbody-multi-level-2/test_input.py.noqcmb psi4-1.11/tests/nbody-multi-level-2/test_input.py
+--- psi4-1.11/tests/nbody-multi-level-2/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/nbody-multi-level-2/test_input.py	2026-07-23 10:43:03.831945212 +0000
+@@ -1,6 +1,6 @@
+ from addons import *
+ 
+-@ctest_labeler("nbody")
++@uusing("qcmanybody")
++@ctest_labeler("")
+ def test_nbody_multi_level_2():
+     ctest_runner(__file__)
+-
+diff -up psi4-1.11/tests/nbody-multi-level/input.dat.noqcmb psi4-1.11/tests/nbody-multi-level/input.dat
+--- psi4-1.11/tests/nbody-multi-level/input.dat.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/nbody-multi-level/input.dat	2026-07-23 10:43:03.926832837 +0000
+@@ -24,7 +24,7 @@ units bohr
+ set cc_type df
+ set df_basis_mp2 def2-qzvpp-ri  # not a recommendation. present to compensate for change in default
+ 
+-species_comparison_dict = {"§A_(2)@(2)": -74.9994424129044, "§B_(2)@(2)": -74.96344779297539}
++species_comparison_dict = {f"{chr(0xA7)}A_(2)@(2)": -74.9994424129044, f"{chr(0xA7)}B_(2)@(2)": -74.96344779297539}
+ species_comparison_dict = {f"n-body {k} total energy": v for k, v in species_comparison_dict.items()}  #TEST
+ 
+ # Compute 1-body contribution with ccsd(t) and 2-body contribution with mp2
+diff -up psi4-1.11/tests/nbody-multi-level/test_input.py.noqcmb psi4-1.11/tests/nbody-multi-level/test_input.py
+--- psi4-1.11/tests/nbody-multi-level/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/nbody-multi-level/test_input.py	2026-07-23 10:43:03.832075734 +0000
+@@ -1,7 +1,8 @@
+ import pytest
+ from addons import *
+ 
+-@ctest_labeler("nbody;extern")
++@uusing("qcmanybody")
++@ctest_labeler("extern")
+ @pytest.mark.parametrize("distributed", [
+     pytest.param(False, id="internal"),
+     pytest.param(True,  id="snowflake", marks=[*using("qcfractal_next"), pytest.mark.medlong]),
+@@ -10,4 +11,3 @@ def test_nbody_multi_level(distributed,
+     setenv = ["_PSI4_USE_QCF"] if distributed else None
+     monkeypatch.setenv("QCMANYBODY_EMBEDDING_CHARGES", "1")
+     ctest_runner(__file__, setenv=setenv)
+-
+diff -up psi4-1.11/tests/nbody-nocp-gradient/test_input.py.noqcmb psi4-1.11/tests/nbody-nocp-gradient/test_input.py
+--- psi4-1.11/tests/nbody-nocp-gradient/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/nbody-nocp-gradient/test_input.py	2026-07-23 10:43:03.832207967 +0000
+@@ -1,6 +1,6 @@
+ from addons import *
+ 
+-@ctest_labeler("nbody;gradient")
++@uusing("qcmanybody")
++@ctest_labeler("gradient")
+ def test_nbody_nocp_gradient():
+     ctest_runner(__file__)
+-
+diff -up psi4-1.11/tests/nbody-vmfc-gradient/test_input.py.noqcmb psi4-1.11/tests/nbody-vmfc-gradient/test_input.py
+--- psi4-1.11/tests/nbody-vmfc-gradient/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/nbody-vmfc-gradient/test_input.py	2026-07-23 10:43:03.832329523 +0000
+@@ -1,6 +1,6 @@
+ from addons import *
+ 
+-@ctest_labeler("nbody;gradient")
++@uusing("qcmanybody")
++@ctest_labeler("gradient")
+ def test_nbody_vmfc_gradient():
+     ctest_runner(__file__)
+-
+diff -up psi4-1.11/tests/nbody-vmfc-hessian/test_input.py.noqcmb psi4-1.11/tests/nbody-vmfc-hessian/test_input.py
+--- psi4-1.11/tests/nbody-vmfc-hessian/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/nbody-vmfc-hessian/test_input.py	2026-07-23 10:43:03.832457609 +0000
+@@ -1,7 +1,8 @@
+ import pytest
+ from addons import *
+ 
+-@ctest_labeler("nbody;hessian;d2ints")
++@uusing("qcmanybody")
++@ctest_labeler("hessian;d2ints")
+ 
+ @pytest.mark.parametrize("distributed", [
+     pytest.param(False, id="internal"),
+@@ -10,4 +11,3 @@ from addons import *
+ def test_nbody_vmfc_hessian(distributed):
+     setenv = ["_PSI4_USE_QCF"] if distributed else None
+     ctest_runner(__file__, setenv=setenv)
+-
+diff -up psi4-1.11/tests/pcmsolver/CMakeLists.txt.noqcmb psi4-1.11/tests/pcmsolver/CMakeLists.txt
+--- psi4-1.11/tests/pcmsolver/CMakeLists.txt.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/pcmsolver/CMakeLists.txt	2026-07-23 10:43:03.926106672 +0000
+@@ -3,7 +3,9 @@ add_subdirectory(dipole)
+ add_subdirectory(scf)
+ add_subdirectory(opt-fd)
+ add_subdirectory(ccsd-pte)
+-add_subdirectory(ghost)
++if (ENABLE_qcmanybody)
++    add_subdirectory(ghost)
++endif()
+ add_subdirectory(alpha)
+ add_subdirectory(tdscf)
+ add_subdirectory(uhf-tdscf)
+diff -up psi4-1.11/tests/pcmsolver/ghost/test_input.py.noqcmb psi4-1.11/tests/pcmsolver/ghost/test_input.py
+--- psi4-1.11/tests/pcmsolver/ghost/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/pcmsolver/ghost/test_input.py	2026-07-23 10:43:03.909452883 +0000
+@@ -1,5 +1,6 @@
+ from addons import *
+ 
++@uusing("qcmanybody")
+ @uusing("pcmsolver")
+ @ctest_labeler("quick;smoke;ghosts")
+ def test_pcmsolver_ghost():
+diff -up psi4-1.11/tests/pytests/addons.py.noqcmb psi4-1.11/tests/pytests/addons.py
+--- psi4-1.11/tests/pytests/addons.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/pytests/addons.py	2026-07-23 10:43:03.917720783 +0000
+@@ -90,6 +90,7 @@ _programs = {
+     "qcfractal": which_import("qcfractal", return_bool=True),
+     "qcfractal_next": is_qcfractal_new_enough("0.49"),
+     "qcportal": which_import("qcportal", return_bool=True),
++    "qcmanybody": which_import("qcmanybody", return_bool=True),
+     "bse": which_import("basis_set_exchange", return_bool=True),
+     "einsums": psi4.addons("einsums"),
+     "pyeinsums": which_import("einsums", return_bool=True),
+@@ -126,7 +127,10 @@ def _using(program: str) -> None:
+         general = pytest.mark.addon
+         particular = getattr(pytest.mark, program)
+ 
+-        all_marks = (skip, general, particular)
++        if program == "qcmanybody":
++            all_marks = (skip, general, particular, getattr(pytest.mark, "nbody"))
++        else:
++            all_marks = (skip, general, particular)
+         _using_cache[program] = [_compose_decos(all_marks), all_marks]
+ 
+ 
+@@ -200,6 +204,10 @@ def ctest_runner(inputdatloc, *, extra_i
+     else:
+         env["PYTHONPATH"] = str(psiimport)
+ 
++    # On Windows, ensure UTF-8 encoding for stdout to handle section symbols and other Unicode
++    if sys.platform.startswith("win"):
++        env["PYTHONIOENCODING"] = "utf-8"
++
+     if setenv:
+         for ev in setenv:
+             env[ev] = "1"
+diff -up psi4-1.11/tests/pytests/test_addons.py.noqcmb psi4-1.11/tests/pytests/test_addons.py
+--- psi4-1.11/tests/pytests/test_addons.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/pytests/test_addons.py	2026-07-23 10:43:03.832923591 +0000
+@@ -913,7 +913,7 @@ def test_gpu_dfcc():
+ 
+ 
+ 
+-@pytest.mark.nbody
++@uusing("qcmanybody")
+ @uusing("dftd3")
+ @uusing("gcp")
+ def test_grimme_3c():
+diff -up psi4-1.11/tests/pytests/test_addons_qcschema.py.noqcmb psi4-1.11/tests/pytests/test_addons_qcschema.py
+--- psi4-1.11/tests/pytests/test_addons_qcschema.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/pytests/test_addons_qcschema.py	2026-07-23 10:43:03.833354891 +0000
+@@ -680,7 +680,7 @@ def test_v2rdm_casscf(schver):
+ #    assert psi4.compare_values(en_gpu_dfcc, en_dfcc, 8, "CCSD total energy")
+ 
+ 
+-@pytest.mark.nbody
++@uusing("qcmanybody")
+ @uusing("dftd3")
+ @uusing("gcp")
+ @pytest.mark.parametrize("schver", [pytest.param(1, marks=[pytest.mark.skipif(_ispy314, reason="Py314+QCSk1")]), pytest.param(2)])
+diff -up psi4-1.11/tests/pytests/test_compositejk.py.noqcmb psi4-1.11/tests/pytests/test_compositejk.py
+--- psi4-1.11/tests/pytests/test_compositejk.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/pytests/test_compositejk.py	2026-07-23 10:43:03.833806034 +0000
+@@ -111,7 +111,7 @@ def test_composite_call(j_algo, k_algo,
+                       "molecule" : "h2o_nap1",
+                       "bsse_type" : "CP",
+                       },
+-                      marks=pytest.mark.nbody,
++                      marks=using("qcmanybody"),
+                       id="h2o/na+ (rhf ie)"),
+     ],
+ )
+@@ -213,7 +213,7 @@ def test_seminum(inp, scf, mols, request
+                       "molecule" : "h2o_nap1",
+                       "bsse_type" : "CP",
+                       },
+-                      marks=pytest.mark.nbody,
++                      marks=using("qcmanybody"),
+                       id="h2o/na+ (rhf ie)"),
+     ],
+ )
+diff -up psi4-1.11/tests/pytests/test_dft_benchmarks.py.noqcmb psi4-1.11/tests/pytests/test_dft_benchmarks.py
+--- psi4-1.11/tests/pytests/test_dft_benchmarks.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/pytests/test_dft_benchmarks.py	2026-07-23 10:43:03.834022531 +0000
+@@ -2,7 +2,7 @@ import numpy as np
+ 
+ import pytest
+ from utils import *
+-from addons import using
++from addons import using, uusing
+ 
+ import psi4
+ 
+@@ -176,7 +176,7 @@ def test_dft_bench_ionization(func, expe
+ 
+ 
+ 
+-@pytest.mark.nbody
++@uusing("qcmanybody")
+ @pytest.mark.scf
+ @pytest.mark.dft
+ @pytest.mark.long
+diff -up psi4-1.11/tests/pytests/test_dftd3.py.noqcmb psi4-1.11/tests/pytests/test_dftd3.py
+--- psi4-1.11/tests/pytests/test_dftd3.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/pytests/test_dftd3.py	2026-07-23 10:43:03.834206292 +0000
+@@ -113,7 +113,7 @@ s16_r2scanh_psi4 = np.array([-155.681254
+ s16_r2scan50_psi4 = np.array([-155.6575747, -78.4586347, -77.1962996])
+ 
+ 
+-@pytest.mark.nbody
++@uusing("qcmanybody")
+ @pytest.mark.parametrize("mode", [
+     pytest.param("abs", marks=pytest.mark.long),
+     pytest.param("ie", marks=pytest.mark.quick),
+@@ -185,4 +185,3 @@ def test_grimme_3c(mtdbas, ref, mode):
+ 
+         ene = psi4.energy(mtdbas, bsse_type='nocp')
+         assert psi4.compare_values(kcal * (ref[0] - ref[1] - ref[2]), kcal * ene, 1.1e-3, mtdbas)
+-
+diff -up psi4-1.11/tests/pytests/test_missing_qcmanybody.py.noqcmb psi4-1.11/tests/pytests/test_missing_qcmanybody.py
+--- psi4-1.11/tests/pytests/test_missing_qcmanybody.py.noqcmb	2026-07-23 10:43:03.907486451 +0000
++++ psi4-1.11/tests/pytests/test_missing_qcmanybody.py	2026-07-23 10:43:03.905397449 +0000
+@@ -0,0 +1,111 @@
++import sys
++
++import pytest
++from qcelemental.util import which_import
++
++import psi4
++from psi4.driver.task_planner import task_planner
++
++pytestmark = [
++    pytest.mark.quick,
++    pytest.mark.psi,
++    pytest.mark.api,
++    pytest.mark.skipif(
++        which_import("qcmanybody", return_bool=True),
++        reason="qcmanybody installed; tests target missing-addon behavior",
++    ),
++]
++
++
++_MSG = "Python module qcmanybody not found"
++
++
++@pytest.fixture
++def dimer():
++    return psi4.geometry(
++        """
++        He 0 0 -2
++        --
++        He 0 0 2
++        units au
++        """
++    )
++
++
++@pytest.mark.parametrize(
++    "driver,method,kwargs",
++    [
++        (psi4.energy, "hf", {"bsse_type": "cp"}),
++        (psi4.gradient, "hf", {"bsse_type": "cp"}),
++        (psi4.hessian, "hf", {"bsse_type": "cp", "dertype": "energy"}),
++    ],
++)
++def test_missing_qcmanybody_via_driver(driver, method, kwargs, dimer):
++    with pytest.raises(ModuleNotFoundError, match=_MSG):
++        driver(method, molecule=dimer, **kwargs)
++
++
++def test_missing_qcmanybody_via_return_plan(dimer):
++    with pytest.raises(ModuleNotFoundError, match=_MSG):
++        psi4.gradient("HF/cc-pV[D,T]Z", molecule=dimer, bsse_type="cp", return_plan=True)
++
++
++@pytest.mark.parametrize("driver,method", [("energy", "MP2/cc-pVDZ"), ("gradient", "MP2/cc-pV[D,T]Z")])
++def test_missing_qcmanybody_via_task_planner(driver, method, dimer):
++    with pytest.raises(ModuleNotFoundError, match=_MSG):
++        task_planner(driver, method, dimer, bsse_type="cp")
++
++
++@pytest.mark.parametrize("schver", [1, 2])
++def test_missing_qcmanybody_via_qcschema(schver, dimer):
++    if schver == 1:
++        qcs_input = {
++            "schema_name": "qcschema_input",
++            "schema_version": 1,
++            "molecule": dimer.to_schema(dtype=2),
++            "driver": "energy",
++            "model": {"method": "hf", "basis": "sto-3g"},
++            "keywords": {"function_kwargs": {"bsse_type": ["cp", "nocp"], "return_total_data": True}},
++        }
++    else:
++        qcs_input = {
++            "schema_name": "qcschema_atomic_input",
++            "schema_version": 2,
++            "molecule": dimer.to_schema(dtype=3),
++            "specification": {
++                "driver": "energy",
++                "model": {"method": "hf", "basis": "sto-3g"},
++                "keywords": {"function_kwargs": {"bsse_type": ["cp", "nocp"], "return_total_data": True}},
++            },
++        }
++
++    return_version = 2 if schver == 1 and sys.version_info >= (3, 14) else -1
++    ret = psi4.schema_wrapper.run_qcschema(qcs_input, return_version=return_version)
++
++    assert not ret.success
++    assert ret.error.error_type == "ModuleNotFoundError"
++    assert _MSG in ret.error.error_message
++
++
++def test_missing_qcmanybody_via_qcschema_levels(dimer):
++    qcs_input = {
++        "schema_name": "qcschema_atomic_input",
++        "schema_version": 2,
++        "molecule": dimer.to_schema(dtype=3),
++        "specification": {
++            "driver": "energy",
++            "model": {"method": "", "basis": "(auto)"},
++            "keywords": {
++                "function_kwargs": {
++                    "bsse_type": "nocp",
++                    "levels": {1: "mp2/sto-3g", "supersystem": "scf/sto-3g"},
++                }
++            },
++        },
++    }
++
++    ret = psi4.schema_wrapper.run_qcschema(qcs_input)
++
++    assert not ret.success
++    assert ret.error.error_type == "ModuleNotFoundError"
++    assert _MSG in ret.error.error_message
+diff -up psi4-1.11/tests/pytests/test_nbody_multi_level_qcschema.py.noqcmb psi4-1.11/tests/pytests/test_nbody_multi_level_qcschema.py
+--- psi4-1.11/tests/pytests/test_nbody_multi_level_qcschema.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/pytests/test_nbody_multi_level_qcschema.py	2026-07-23 10:43:03.834550516 +0000
+@@ -4,10 +4,11 @@ import copy
+ import pprint
+ 
+ import pytest
++from addons import uusing
+ 
+ import psi4
+ 
+-pytestmark = [pytest.mark.psi, pytest.mark.api, pytest.mark.nbody]
++pytestmark = [pytest.mark.psi, pytest.mark.api]
+ 
+ _sch_name = {1: "qcschema_output", 2: "qcschema_atomic_result"}
+ _ispy314 = sys.version_info >= (3, 14)
+@@ -88,6 +89,7 @@ def base_schema():
+                   'VMFC-CORRECTED TOTAL ENERGY THROUGH 2-BODY': -224.943882712817},
+                  id='nbody-embedded', marks=pytest.mark.extern),
+ ])
++@uusing("qcmanybody")
+ def test_nbody_levels(inp, expected, base_schema, monkeypatch, schver):
+     monkeypatch.setenv("QCMANYBODY_EMBEDDING_CHARGES", "1")
+     # reference for nbody-multilevel generated with this larger fitting basis for sto-3g. fails otherwise by 3.e-5
+@@ -112,4 +114,3 @@ def test_nbody_levels(inp, expected, bas
+ 
+     for b, v in expected.items():
+         assert psi4.compare_values(v, otp.extras["qcvars"][b], 6, b)
+-
+diff -up psi4-1.11/tests/pytests/test_nbody.py.noqcmb psi4-1.11/tests/pytests/test_nbody.py
+--- psi4-1.11/tests/pytests/test_nbody.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/pytests/test_nbody.py	2026-07-23 10:43:03.914320623 +0000
+@@ -4,9 +4,10 @@ import re
+ import pytest
+ import numpy as np
+ from qcelemental.testing import compare, compare_values
++from addons import uusing
+ import psi4
+ 
+-pytestmark = [pytest.mark.psi, pytest.mark.api, pytest.mark.nbody]
++pytestmark = [pytest.mark.psi, pytest.mark.api]
+ 
+ _sch_name = {1: "qcschema_output", 2: "qcschema_atomic_result"}
+ _ispy314 = sys.version_info >= (3, 14)
+@@ -62,35 +63,47 @@ _ie_uncp_grad = np.array(
+      [ 0.           ,   0.            ,  0.000044919089]])
+ 
+ 
++_SEC_A = chr(0xA7) + "A"
++
++
++def _normalize_nbody_text(s: str) -> str:
++    """Normalize section symbol encoding on Windows to handle mojibake patterns."""
++    return (
++        s.replace("\ufffdA", "§A")   # '�A' -> '§A' (replacement char mojibake)
++         .replace("§", "§")         # Windows cp1252 double-encoding
++         .replace("\xa7", "§")       # Direct byte representation
++    )
++
++
+ _stdouts = {
+-    "cp_T": r"""
++    "cp_T": rf"""
+ \s*   ==> N-Body: Counterpoise Corrected \(CP\) energies <==
+ \s*     MC n-Body\s+Total Energy            Interaction Energy                          N-body Contribution to Interaction Energy
+ \s*                   \[Eh\]                    \[Eh\]                  \[kcal/mol\]            \[Eh\]                  \[kcal/mol\]
+-\s*           §A\s+1     -155.405884\d\d\d\d\d\d        0.000000000000        0.000000000000        0.000000000000        0.000000000000
+-\s*  FULL/RTN §A\s+2     -155.407610\d\d\d\d\d\d       -0.001726\d\d\d\d\d\d       -1.0831\d\d\d\d\d\d\d\d       -0.001726\d\d\d\d\d\d       -1.0831\d\d\d\d\d\d\d\d
++\s*           {_SEC_A}\s+1     -155.405884\d\d\d\d\d\d        0.000000000000        0.000000000000        0.000000000000        0.000000000000
++\s*  FULL/RTN {_SEC_A}\s+2     -155.407610\d\d\d\d\d\d       -0.001726\d\d\d\d\d\d       -1.0831\d\d\d\d\d\d\d\d       -0.001726\d\d\d\d\d\d       -1.0831\d\d\d\d\d\d\d\d
+ \s*
+-\s*MC Legend: §A: "\(auto\)"
++\s*MC Legend: {_SEC_A}: "\(auto\)"
+ \s*
+ """,
+-    "cp_F": r"""
++    "cp_F": rf"""
+ \s*   ==> N-Body: Counterpoise Corrected \(CP\) energies <==
+ \s*     MC n-Body\s+Total Energy            Interaction Energy                          N-body Contribution to Interaction Energy
+ \s*                   \[Eh\]                    \[Eh\]                  \[kcal/mol\]            \[Eh\]                  \[kcal/mol\]
+-\s*           §A\s+1        N/A                   0.000000000000        0.000000000000        0.000000000000        0.000000000000
+-\s*  FULL/RTN §A\s+2        N/A                  -0.001726\d\d\d\d\d\d       -1.0831\d\d\d\d\d\d\d\d       -0.001726\d\d\d\d\d\d       -1.0831\d\d\d\d\d\d\d\d
++\s*           {_SEC_A}\s+1        N/A                   0.000000000000        0.000000000000        0.000000000000        0.000000000000
++\s*  FULL/RTN {_SEC_A}\s+2        N/A                  -0.001726\d\d\d\d\d\d       -1.0831\d\d\d\d\d\d\d\d       -0.001726\d\d\d\d\d\d       -1.0831\d\d\d\d\d\d\d\d
+ \s*
+-\s*MC Legend: §A: "\(auto\)"
++\s*MC Legend: {_SEC_A}: "\(auto\)"
+ \s*
+ """,
+-    "uncp": r"""
++    "uncp": rf"""
+ \s*   ==> N-Body: Non-Counterpoise Corrected \(NoCP\) energies <==
+ \s*     MC n-Body\s+Total Energy            Interaction Energy                          N-body Contribution to Interaction Energy
+ \s*                   \[Eh\]                    \[Eh\]                  \[kcal/mol\]            \[Eh\]                  \[kcal/mol\]
+-\s*           §A\s+1     -155.405884\d\d\d\d\d\d        0.000000000000        0.000000000000        0.000000000000        0.000000000000
+-\s*  FULL/RTN §A\s+2     -155.408871\d\d\d\d\d\d       -0.002987\d\d\d\d\d\d       -1.8746\d\d\d\d\d\d\d\d       -0.002987\d\d\d\d\d\d       -1.8746\d\d\d\d\d\d\d\d
++\s*           {_SEC_A}\s+1     -155.405884\d\d\d\d\d\d        0.000000000000        0.000000000000        0.000000000000        0.000000000000
++\s*  FULL/RTN {_SEC_A}\s+2     -155.408871\d\d\d\d\d\d       -0.002987\d\d\d\d\d\d       -1.8746\d\d\d\d\d\d\d\d       -0.002987\d\d\d\d\d\d       -1.8746\d\d\d\d\d\d\d\d
+ \s*
+-\s*MC Legend: §A: "\(auto\)"
++\s*MC Legend: {_SEC_A}: "\(auto\)"
+ \s*
+ """,
+ }
+@@ -126,6 +139,7 @@ _stdouts["uncpcp"] = _stdouts["uncp"] +
+     ("gradient", ["nocp", "cp"], None , 5, _tot_uncp_grad, "uncpcp"),  # return tot G          5
+     ("gradient", ["nocp", "ssfc"], None , 5, _tot_uncp_grad, "uncpcp"),  # return tot G          5
+ ])
++@uusing("qcmanybody")
+ def test_nbody_number(driver, bsse_type, return_total_data, nbody_number, return_result, stdoutkey):
+ 
+     eneyne = psi4.geometry("""
+@@ -195,4 +209,4 @@ H   0.000000   0.000000   3.963929
+ 
+     assert compare_values(return_result, ret.return_result, atol=1.e-6, label="manybody")
+     assert compare(nbody_number, ret.extras["qcvars"]["NBODY NUMBER"], label="nbody number")
+-    assert re.search(_stdouts[stdoutkey], ret.stdout, re.MULTILINE), f"N-Body pattern not found: {_stdouts[stdoutkey]}"
++    assert re.search(_stdouts[stdoutkey], _normalize_nbody_text(ret.stdout), re.MULTILINE), f"N-Body pattern not found: {_stdouts[stdoutkey]}"
+diff -up psi4-1.11/tests/pytests/test_psi4.py.noqcmb psi4-1.11/tests/pytests/test_psi4.py
+--- psi4-1.11/tests/pytests/test_psi4.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/pytests/test_psi4.py	2026-07-23 10:43:03.834711682 +0000
+@@ -1,5 +1,6 @@
+ import numpy as np
+ import pytest
++from addons import uusing
+ 
+ import psi4
+ 
+@@ -112,7 +113,7 @@ def test_psi4_cas():
+     assert psi4.compare_values(-76.073865006902, casscf_energy, 6, 'CASSCF Energy')
+ 
+ 
+-@pytest.mark.nbody
++@uusing("qcmanybody")
+ @pytest.mark.smoke
+ def test_psi4_dfmp2():
+     """dfmp2-1"""
+diff -up psi4-1.11/tests/pytests/test_psi4_qcschema.py.noqcmb psi4-1.11/tests/pytests/test_psi4_qcschema.py
+--- psi4-1.11/tests/pytests/test_psi4_qcschema.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/pytests/test_psi4_qcschema.py	2026-07-23 10:43:03.926271703 +0000
+@@ -5,6 +5,7 @@ import pytest
+ import pprint
+ import os
+ from shutil import copytree
++from addons import uusing
+ 
+ import psi4
+ 
+@@ -113,7 +114,7 @@ def test_psi4_cas(datadir, schver):
+     assert psi4.compare_values(-76.073865006902, atres.return_result, 6, 'CASSCF Energy')
+ 
+ 
+-@pytest.mark.nbody
++@uusing("qcmanybody")
+ @pytest.mark.parametrize("schver", [pytest.param(1, marks=[pytest.mark.skipif(_ispy314, reason="Py314+QCSk1")]), pytest.param(2)])
+ def test_psi4_dfmp2(datadir, schver):
+     """dfmp2-1"""
+diff -up psi4-1.11/tests/pytests/test_qcfractal.py.noqcmb psi4-1.11/tests/pytests/test_qcfractal.py
+--- psi4-1.11/tests/pytests/test_qcfractal.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/pytests/test_qcfractal.py	2026-07-23 10:43:03.907462347 +0000
+@@ -11,6 +11,7 @@ pytestmark = [pytest.mark.psi, pytest.ma
+ 
+ @uusing("qcfractal")
+ @uusing("qcportal")
++@uusing("qcmanybody")
+ @pytest.mark.cbs
+ @pytest.mark.smoke
+ @pytest.mark.quick
+diff -up psi4-1.11/tests/pytests/test_qcmanybody.py.noqcmb psi4-1.11/tests/pytests/test_qcmanybody.py
+diff -up psi4-1.11/tests/pytests/test_task_planner.py.noqcmb psi4-1.11/tests/pytests/test_task_planner.py
+--- psi4-1.11/tests/pytests/test_task_planner.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/pytests/test_task_planner.py	2026-07-23 10:43:03.905840127 +0000
+@@ -101,6 +101,7 @@ def test_cbs_extrapolation_gradient_1_0(
+             assert plan3.driver == "energy"
+ 
+ 
++@uusing("qcmanybody")
+ def test_nbody_dimer():
+     mol = psi4.geometry(
+         """
+@@ -133,6 +134,7 @@ def test_nbody_dimer():
+         assert kmol["real"] == ghostiness[k2][1]
+ 
+ 
++@uusing("qcmanybody")
+ def test_nbody_dimer_gradient():
+     mol = psi4.geometry(
+         """
+@@ -165,6 +167,7 @@ def test_nbody_dimer_gradient():
+         assert kmol["real"] == ghostiness[k2][1]
+ 
+ 
++@uusing("qcmanybody")
+ @pytest.mark.parametrize("mtd, kw", [("mp2", {"dertype": 0}), ("mp5", {})])
+ def test_nbody_dimer_gradient_1_0(mtd, kw):
+     mol = psi4.geometry(
+@@ -231,6 +234,7 @@ def test_nbody_dimer_gradient_1_0(mtd, k
+             # assert plan3.keywords['E_CONVERGENCE'] == 1.e-10
+ 
+ 
++@uusing("qcmanybody")
+ def test_nbody_dimer_cbs():
+     mol = psi4.geometry(
+         """
+@@ -255,6 +259,7 @@ def test_nbody_dimer_cbs():
+             assert plan3.driver == "energy"
+ 
+ 
++@uusing("qcmanybody")
+ def test_nbody_dimer_cbs_gradient():
+     mol = psi4.geometry(
+         """
+@@ -279,6 +284,7 @@ def test_nbody_dimer_cbs_gradient():
+             assert plan3.driver == "gradient"
+ 
+ 
++@uusing("qcmanybody")
+ @pytest.mark.parametrize("mtd, kw", [("mp2", {"dertype": 0}), ("mp5", {})])
+ def test_nbody_dimer_cbs_gradient_1_0(mtd, kw):
+     mol = psi4.geometry(
+diff -up psi4-1.11/tests/tu6-cp-ne2/test_input.py.noqcmb psi4-1.11/tests/tu6-cp-ne2/test_input.py
+--- psi4-1.11/tests/tu6-cp-ne2/test_input.py.noqcmb	2026-06-30 02:22:36.000000000 +0000
++++ psi4-1.11/tests/tu6-cp-ne2/test_input.py	2026-07-23 10:43:03.835099850 +0000
+@@ -1,6 +1,6 @@
+ from addons import *
+ 
+-@ctest_labeler("tutorial;nbody")
++@uusing("qcmanybody")
++@ctest_labeler("tutorial")
+ def test_tu6_cp_ne2():
+     ctest_runner(__file__)
+-

diff --git a/3400.patch b/3400.patch
deleted file mode 100644
index 795a244..0000000
--- a/3400.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 18f43c3713c8e791e80e797fa0bd3e1feb98a709 Mon Sep 17 00:00:00 2001
-From: Susi Lehtola <susi.lehtola@gmail.com>
-Date: Mon, 18 May 2026 19:25:31 +0300
-Subject: [PATCH] cmake: forward per-config flag variants to psi4-core subbuild
-
-The outer superbuild's ExternalProject_Add(psi4-core ...) was forwarding
-CMAKE_<LANG>_FLAGS but none of the per-configuration variants
-(CMAKE_<LANG>_FLAGS_{DEBUG,RELEASE,RELWITHDEBINFO,MINSIZEREL}). A user
-override like -DCMAKE_CXX_FLAGS_RELEASE="-DNDEBUG" on the outer cmake
-landed in the outer cache but never reached the inner psi4-core build,
-which silently fell back to CMake's auto-populated defaults.
-
-Forward all four configuration variants for C, C++, and Fortran.
-
-Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
----
- CMakeLists.txt | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 26eeb21e6a..0ba53433c9 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -276,9 +276,17 @@ ExternalProject_Add(psi4-core
-               -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-               -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-               -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
-+              -DCMAKE_CXX_FLAGS_DEBUG=${CMAKE_CXX_FLAGS_DEBUG}
-+              -DCMAKE_CXX_FLAGS_RELEASE=${CMAKE_CXX_FLAGS_RELEASE}
-+              -DCMAKE_CXX_FLAGS_RELWITHDEBINFO=${CMAKE_CXX_FLAGS_RELWITHDEBINFO}
-+              -DCMAKE_CXX_FLAGS_MINSIZEREL=${CMAKE_CXX_FLAGS_MINSIZEREL}
-               -DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS}
-               -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-               -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
-+              -DCMAKE_C_FLAGS_DEBUG=${CMAKE_C_FLAGS_DEBUG}
-+              -DCMAKE_C_FLAGS_RELEASE=${CMAKE_C_FLAGS_RELEASE}
-+              -DCMAKE_C_FLAGS_RELWITHDEBINFO=${CMAKE_C_FLAGS_RELWITHDEBINFO}
-+              -DCMAKE_C_FLAGS_MINSIZEREL=${CMAKE_C_FLAGS_MINSIZEREL}
-               -DCMAKE_CXX_STANDARD=${psi4_CXX_STANDARD}
-               -DCMAKE_CXX_STANDARD_REQUIRED=ON
-               -DCMAKE_CXX_EXTENSIONS=OFF
-@@ -287,6 +295,10 @@ ExternalProject_Add(psi4-core
-               -DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE}
-               -DCMAKE_Fortran_COMPILER=${CMAKE_Fortran_COMPILER}
-               -DCMAKE_Fortran_FLAGS=${CMAKE_Fortran_FLAGS}
-+              -DCMAKE_Fortran_FLAGS_DEBUG=${CMAKE_Fortran_FLAGS_DEBUG}
-+              -DCMAKE_Fortran_FLAGS_RELEASE=${CMAKE_Fortran_FLAGS_RELEASE}
-+              -DCMAKE_Fortran_FLAGS_RELWITHDEBINFO=${CMAKE_Fortran_FLAGS_RELWITHDEBINFO}
-+              -DCMAKE_Fortran_FLAGS_MINSIZEREL=${CMAKE_Fortran_FLAGS_MINSIZEREL}
-               -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
-               -DCMAKE_INSTALL_BINDIR=${CMAKE_INSTALL_BINDIR}
-               -DCMAKE_INSTALL_DATADIR=${CMAKE_INSTALL_DATADIR}

diff --git a/psi4-1.3.2-python3.patch b/psi4-1.3.2-python3.patch
deleted file mode 100644
index 5747941..0000000
--- a/psi4-1.3.2-python3.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -up psi4-1.3.2/tests/runtest.py.python3 psi4-1.3.2/tests/runtest.py
---- psi4-1.3.2/tests/runtest.py.python3	2019-05-15 17:05:49.000000000 +0200
-+++ psi4-1.3.2/tests/runtest.py	2020-01-13 22:30:59.679991141 +0100
-@@ -118,7 +118,7 @@ elif os.path.isfile(infile.replace(".dat
-     else:
-         os.environ["PYTHONPATH"] = psilibdir
-     outfile = os.path.dirname(infile) + os.path.sep + outfile
--    pyexitcode = backtick(["python", infile, " > ", outfile])
-+    pyexitcode = backtick(["python3", infile, " > ", outfile])
- else:
-     raise Exception("\n\nError: Input file %s not found\n" % infile)
- 

diff --git a/psi4.spec b/psi4.spec
index 28db742..72daf38 100644
--- a/psi4.spec
+++ b/psi4.spec
@@ -14,19 +14,16 @@ ExcludeArch: %{ix86}
 
 Name:           psi4
 Epoch:          1
-Version:        1.10.0
-Release:        0.2.alpha%{?dist}
+Version:        1.11
+Release:        1%{?dist}
 Summary:        An ab initio quantum chemistry package
 # Automatically converted from old format: LGPLv3 and MIT - review is highly recommended.
 License:        LGPL-3.0-only AND LicenseRef-Callaway-MIT
 URL:            http://www.psicode.org/
-#Source0:        https://github.com/psi4/psi4/archive/v%{version}/psi4-%{version}.tar.gz
-Source0:        https://github.com/psi4/psi4/archive/refs/heads/master.zip
+Source0:        https://github.com/psi4/psi4/archive/v%{version}/psi4-%{version}.tar.gz
 
-# Make qcmanybody optional
-Patch0:         https://github.com/psi4/psi4/pull/3389.patch
-# Fix the propagation of cmake flags to the deeper build
-Patch1:         https://github.com/psi4/psi4/pull/3400.patch
+# Make qcmanybody optional, from https://github.com/psi4/psi4/pull/3389.patch
+Patch0:         3389_new.patch
 
 BuildRequires:  cmake
 BuildRequires:  bison-devel
@@ -80,6 +77,7 @@ Requires:       python3-qcengine
 Requires:       python3-qcelemental
 Requires:       python3-deepdiff
 Requires:       python3-optking
+Requires:       python3-dftd4
 # For directory ownership
 Requires:       cmake
 
@@ -116,10 +114,8 @@ This package contains necessary data files for PSI4, e.g., basis sets
 and the quadrature grids.
 
 %prep
-#setup -q
-%setup -q -n psi4-master
+%setup -q
 %patch -P 0 -p 1 -b .noqcmb
-%patch -P 1 -p 1 -b .cmakeflags
 # Prevent versioner from seeing any top-level git directories
 sed -i 's/if is_git_repo(cwd=cwd, extraneous_toplevel_patterns=.*):/if False:/' psi4/versioner.py
 
@@ -174,6 +170,9 @@ ctest -L smoketests --output-on-failure
 %{_datadir}/psi4/
 
 %changelog
+* Wed Jul 29 2026 Susi Lehtola <jussilehtola@fedoraproject.org> - 1:1.11-1
+- Update to 1.11.
+
 * Thu Jul 16 2026 Fedora Release Engineering <releng@fedoraproject.org> - 1:1.10.0-0.2.alpha
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild
 

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-07-29 13:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-29 13:28 [rpms/psi4] rawhide: Update to 1.11 Susi Lehtola

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox