diff --git a/.github/workflows/test_branches.yml b/.github/workflows/test_branches.yml index 4e45407e8b2..f6f0277437f 100644 --- a/.github/workflows/test_branches.yml +++ b/.github/workflows/test_branches.yml @@ -23,7 +23,7 @@ env: PYTHON_CORE_PKGS: wheel PYPI_ONLY: z3-solver linear-tree PYPY_EXCLUDE: scipy numdifftools seaborn statsmodels linear-tree - CACHE_VER: v260512.3 + CACHE_VER: v260804.0 NEOS_EMAIL: tests@pyomo.org SRC_REF: ${{ github.head_ref || github.ref }} PYOMO_WORKFLOW: branch diff --git a/.github/workflows/test_pr_and_main.yml b/.github/workflows/test_pr_and_main.yml index f8b8eed355b..64822ed3613 100644 --- a/.github/workflows/test_pr_and_main.yml +++ b/.github/workflows/test_pr_and_main.yml @@ -31,7 +31,7 @@ env: PYTHON_CORE_PKGS: wheel PYPI_ONLY: z3-solver linear-tree PYPY_EXCLUDE: scipy numdifftools seaborn statsmodels linear-tree - CACHE_VER: v260512.3 + CACHE_VER: v260804.0 NEOS_EMAIL: tests@pyomo.org SRC_REF: ${{ github.head_ref || github.ref }} PYOMO_WORKFLOW: | @@ -196,7 +196,7 @@ jobs: PACKAGES: pyutilib - os: ubuntu-latest - python: 'pypy-3.11-v7.3.20' #FIXME: Temporary version pin to avoid PyPy 7.3.21 + python: 'pypy-3.11' TARGET: linux PYENV: pip diff --git a/pyomo/contrib/satsolver/tests/test_satsolver.py b/pyomo/contrib/satsolver/tests/test_satsolver.py index 9e92ca23bef..f527019286d 100644 --- a/pyomo/contrib/satsolver/tests/test_satsolver.py +++ b/pyomo/contrib/satsolver/tests/test_satsolver.py @@ -32,9 +32,13 @@ from pyomo.gdp import Disjunct, Disjunction exdir = join(PYOMO_ROOT_DIR, 'examples', 'gdp') +from pyomo.common.envvar import is_pypy @unittest.skipUnless(z3_available, "Z3 SAT solver is not available.") +@unittest.skipIf( + is_pypy, "satsolver tests stall on pypy; these will no longer be tested." +) class SatSolverTests(unittest.TestCase): def test_simple_sat_model(self): m = ConcreteModel() diff --git a/pyomo/core/tests/unit/test_pickle.py b/pyomo/core/tests/unit/test_pickle.py index f8cf3ab6ed6..706a3bf0927 100644 --- a/pyomo/core/tests/unit/test_pickle.py +++ b/pyomo/core/tests/unit/test_pickle.py @@ -31,8 +31,8 @@ NonNegativeReals, sum_product, ) - -is_pypy = platform.python_implementation().lower().startswith("pypy") +from pyomo.common.dependencies import dill_available +from pyomo.common.envvar import is_pypy def obj_rule(model): @@ -319,7 +319,7 @@ def rule2(model, i): model.con = Constraint(rule=rule1) model.con2 = Constraint(model.a, rule=rule2) instance = model.create_instance() - if is_pypy: + if is_pypy and dill_available: str_ = pickle.dumps(instance) tmp_ = pickle.loads(str_) else: diff --git a/pyomo/gdp/tests/test_mbigm.py b/pyomo/gdp/tests/test_mbigm.py index dfe1aac201b..3f989a8b4a1 100644 --- a/pyomo/gdp/tests/test_mbigm.py +++ b/pyomo/gdp/tests/test_mbigm.py @@ -17,6 +17,7 @@ from pyomo.common.fileutils import import_file, PYOMO_ROOT_DIR from pyomo.common.log import LoggingIntercept import pyomo.common.unittest as unittest +from pyomo.common.envvar import is_pypy from pyomo.core.expr.compare import ( assertExpressionsEqual, assertExpressionsStructurallyEqual, @@ -1136,6 +1137,10 @@ def test_calculate_Ms_infeasible_Disjunct(self): @unittest.skipUnless( SolverFactory('ipopt').available(exception_flag=False), "Ipopt is not available" ) + @unittest.skipIf( + is_pypy, + "tests using multiprocessing stall on pypy; this will no longer be tested.", + ) def test_calculate_Ms_infeasible_Disjunct_local_solver(self): m = self.make_infeasible_disjunct_model() # When multiple exceptions are raised during a diff --git a/pyomo/solvers/plugins/solvers/cuopt_direct.py b/pyomo/solvers/plugins/solvers/cuopt_direct.py index 4ccdc9e631d..11e8dd6741d 100644 --- a/pyomo/solvers/plugins/solvers/cuopt_direct.py +++ b/pyomo/solvers/plugins/solvers/cuopt_direct.py @@ -37,7 +37,11 @@ def _get_cuopt_version(cuopt, avail): CUOPTDirect._name = "cuOpt %s.%s%s" % CUOPTDirect._version -cuopt, cuopt_available = attempt_import("cuopt", callback=_get_cuopt_version) +# Note: catch RuntimeError as the base for CUDARuntimeError, which can +# be raised, e.g., for CUDA driver version mismatches +cuopt, cuopt_available = attempt_import( + "cuopt", callback=_get_cuopt_version, catch_exceptions=(ImportError, RuntimeError) +) @SolverFactory.register("cuopt", doc="Direct python interface to CUOPT") diff --git a/pyomo/solvers/tests/checks/test_cuopt_direct.py b/pyomo/solvers/tests/checks/test_cuopt_direct.py index fa6620a603e..761aab44a56 100644 --- a/pyomo/solvers/tests/checks/test_cuopt_direct.py +++ b/pyomo/solvers/tests/checks/test_cuopt_direct.py @@ -24,7 +24,6 @@ Binary, ) import pytest -from pyomo.common.dependencies import attempt_import from pyomo.opt import check_available_solvers from pyomo.common.tee import capture_output from pyomo.common.tempfiles import TempfileManager diff --git a/setup.py b/setup.py index bcc8af4a666..aecd7e6afbf 100644 --- a/setup.py +++ b/setup.py @@ -215,7 +215,6 @@ def __ne__(self, other): 'scipy', # Needed by autodoc for pynumero ], 'optional': [ - 'dill', # No direct use, but improves lambda pickle 'ipython', # contrib.viewer 'linear-tree; python_version<"3.14"', # contrib.piecewise # FIXME: This is a temporary pin that should be removed @@ -253,6 +252,7 @@ def __ne__(self, other): # install on PyPy (binary wheels are not available), so we # will only "require" them on other (CPython) platforms: 'casadi; implementation_name!="pypy"', # dae + 'dill; implementation_name!="pypy"', # No direct use, but improves lambda pickle 'numdifftools; implementation_name!="pypy"', # pynumero 'pandas; implementation_name!="pypy"', 'seaborn; implementation_name!="pypy"', # parmest.graphics