diff --git a/pkgs/development/python-modules/mip/default.nix b/pkgs/development/python-modules/mip/default.nix new file mode 100644 index 000000000000..6b1c353c23d7 --- /dev/null +++ b/pkgs/development/python-modules/mip/default.nix @@ -0,0 +1,78 @@ +{ lib +, buildPythonPackage +, cffi +, dos2unix +, fetchPypi +, matplotlib +, networkx +, numpy +, pytestCheckHook +, pythonOlder +, gurobi +, gurobipy +# Enable support for the commercial Gurobi solver (requires a license) +, gurobiSupport ? false +# If Gurobi has already been installed outside of the Nix store, specify its +# installation directory here +, gurobiHome ? null +}: + +buildPythonPackage rec { + pname = "mip"; + version = "1.14.1"; + + disabled = pythonOlder "3.7"; + format = "pyproject"; + + src = fetchPypi { + inherit pname version; + sha256 = "sha256-bvpm5vUp15fbv/Sw1Lx70ihA7VHsSUzwFzoFDG+Ow1M="; + }; + + checkInputs = [ matplotlib networkx numpy pytestCheckHook ]; + nativeBuildInputs = [ dos2unix ]; + propagatedBuildInputs = [ + cffi + ] ++ lib.optionals gurobiSupport ([ + gurobipy + ] ++ lib.optional (builtins.isNull gurobiHome) gurobi); + + # Source files have CRLF terminators, which make patch error out when supplied + # with diffs made on *nix machines + prePatch = '' + find . -type f -exec ${dos2unix}/bin/dos2unix {} \; + ''; + + patches = [ + # Some tests try to be smart and dynamically construct a path to their test + # inputs. Unfortunately, since the test phase is run after installation, + # those paths point to the Nix store, which no longer contains the test + # data. This patch hardcodes the data path to point to the source directory. + ./test-data-path.patch + ]; + + postPatch = '' + # Allow cffi versions with a different patch level to be used + substituteInPlace pyproject.toml --replace "cffi==1.15.0" "cffi==1.15.*" + ''; + + # Make MIP use the Gurobi solver, if configured to do so + makeWrapperArgs = lib.optional gurobiSupport + "--set GUROBI_HOME ${if builtins.isNull gurobiHome then gurobi.outPath else gurobiHome}"; + + # Tests that rely on Gurobi are activated only when Gurobi support is enabled + disabledTests = lib.optional (!gurobiSupport) "gurobi"; + + passthru.optional-dependencies = { + inherit gurobipy numpy; + }; + + meta = with lib; { + homepage = "http://python-mip.com/"; + description = "A collection of Python tools for the modeling and solution of Mixed-Integer Linear programs (MIPs)"; + downloadPage = "https://github.com/coin-or/python-mip/releases"; + changelog = "https://github.com/coin-or/python-mip/releases/tag/${version}"; + license = licenses.epl20; + maintainers = with maintainers; [ nessdoor ]; + }; +} diff --git a/pkgs/development/python-modules/mip/test-data-path.patch b/pkgs/development/python-modules/mip/test-data-path.patch new file mode 100644 index 000000000000..d96f34254951 --- /dev/null +++ b/pkgs/development/python-modules/mip/test-data-path.patch @@ -0,0 +1,30 @@ +diff --git a/examples/extract_features_mip.py b/examples/extract_features_mip.py +index cdc109f..90e79fa 100644 +--- a/examples/extract_features_mip.py ++++ b/examples/extract_features_mip.py +@@ -9,9 +9,7 @@ import mip + lp_path = "" + + # using test data, replace with your instance +-lp_path = mip.__file__.replace("mip/__init__.py", "test/data/1443_0-9.lp").replace( +- "mip\\__init__.py", "test\\data\\1443_0-9.lp" +-) ++lp_path = "test/data/1443_0-9.lp" + + m = Model() + if m.solver_name.upper() in ["GRB", "GUROBI"]: +diff --git a/examples/gen_cuts_mip.py b/examples/gen_cuts_mip.py +index f71edae..2799734 100644 +--- a/examples/gen_cuts_mip.py ++++ b/examples/gen_cuts_mip.py +@@ -11,9 +11,7 @@ import mip + lp_path = "" + + # using test data +-lp_path = mip.__file__.replace("mip/__init__.py", "test/data/1443_0-9.lp").replace( +- "mip\\__init__.py", "test\\data\\1443_0-9.lp" +-) ++lp_path = "test/data/1443_0-9.lp" + + m = Model() + if m.solver_name.upper() in ["GRB", "GUROBI"]: diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 4ca17accf532..0526970704a9 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -5798,6 +5798,8 @@ self: super: with self; { inherit (pkgs.darwin) cctools; }; + mip = callPackage ../development/python-modules/mip { }; + misaka = callPackage ../development/python-modules/misaka { }; misoc = callPackage ../development/python-modules/misoc { };