Refactor solver flags (#3153)

* Rename Solver keep_specs > keep_user_specs

* Refactor hide libsolv solver flags

* Move Solver flags in Request
This commit is contained in:
Antoine Prouvost 2024-01-25 17:07:54 +01:00 committed by GitHub
parent a310d31da9
commit b270d9f6b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 264 additions and 262 deletions

View File

@ -48,19 +48,9 @@ namespace mamba
{
public:
struct Flags
{
/** Keep the dependencies of the install package in the solution. */
bool keep_dependencies = true;
/** Keep the original required package in the solution. */
bool keep_specs = true;
/** Force reinstallation of jobs. */
bool force_reinstall = false;
};
using Request = solver::Request;
MSolver(MPool pool, std::vector<std::pair<int, int>> flags = {});
MSolver(MPool pool);
~MSolver();
MSolver(const MSolver&) = delete;
@ -68,10 +58,6 @@ namespace mamba
MSolver(MSolver&&);
MSolver& operator=(MSolver&&);
void set_flags(const Flags& flags); // TODO temporary Itf meant to be passed in ctor
[[nodiscard]] auto flags() const -> const Flags&;
[[deprecated]] void py_set_libsolv_flags(const std::vector<std::pair<int, int>>& flags);
[[nodiscard]] bool try_solve();
void must_solve();
[[nodiscard]] bool is_solved() const;
@ -96,13 +82,11 @@ namespace mamba
private:
std::vector<std::pair<int, int>> m_libsolv_flags;
Request m_request;
// Order of m_pool and m_solver is critical since m_pool must outlive m_solver.
MPool m_pool;
// Temporary Pimpl all libsolv to keep it private
std::unique_ptr<solv::ObjSolver> m_solver;
Flags m_flags = {};
bool m_is_solved;
void apply_libsolv_flags();

View File

@ -18,6 +18,22 @@ namespace mamba::solver
{
struct Request
{
struct Flags
{
/** Keep the dependencies of the install package in the solution. */
bool keep_dependencies = true;
/** Keep the original user requested package in the solution. */
bool keep_user_specs = true;
/** Force reinstallation of jobs. */
bool force_reinstall = false;
/** Allow downgrading packages to satisfy requirements. */
bool allow_downgrade = true;
/** Allow uninstalling packages to satisfy requirements. */
bool allow_uninstall = true;
/** Prefer packages by repoitory order. */
bool strict_repo_priority = true;
};
/** Instruct to install a package matching the given spec. */
struct Install
{
@ -64,6 +80,7 @@ namespace mamba::solver
using Item = std::variant<Install, Remove, Update, UpdateAll, Keep, Freeze, Pin>;
using item_list = std::vector<Item>;
Flags flags = {};
item_list items = {};
};

View File

@ -559,24 +559,17 @@ namespace mamba
load_installed_packages_in_pool(ctx, pool, prefix_data);
MSolver solver(
pool,
{
{ SOLVER_FLAG_ALLOW_UNINSTALL, ctx.allow_uninstall },
{ SOLVER_FLAG_ALLOW_DOWNGRADE, ctx.allow_downgrade },
{ SOLVER_FLAG_STRICT_REPO_PRIORITY,
ctx.channel_priority == ChannelPriority::Strict },
}
);
solver.set_flags({
/* .keep_dependencies= */ !no_deps,
/* .keep_specs= */ !only_deps,
/* .force_reinstall= */ force_reinstall,
});
auto request = create_install_request(prefix_data, specs, freeze_installed);
add_pins_to_request(request, ctx, prefix_data, specs, no_pin, no_py_pin);
request.flags = {
/* .keep_dependencies= */ !no_deps,
/* .keep_user_specs= */ !only_deps,
/* .force_reinstall= */ force_reinstall,
/* .allow_downgrade= */ ctx.allow_downgrade,
/* .allow_uninstall= */ ctx.allow_uninstall,
/* .strict_repo_priority= */ ctx.channel_priority == ChannelPriority::Strict,
};
{
auto out = Console::stream();
@ -584,6 +577,7 @@ namespace mamba
// Console stream prints on destrucion
}
auto solver = MSolver(pool);
solver.set_request(std::move(request));
bool success = solver.try_solve();

View File

@ -161,18 +161,18 @@ namespace mamba
}
else
{
MSolver solver(
pool,
{
{ SOLVER_FLAG_ALLOW_DOWNGRADE, 1 },
{ SOLVER_FLAG_ALLOW_UNINSTALL, 1 },
{ SOLVER_FLAG_STRICT_REPO_PRIORITY,
ctx.channel_priority == ChannelPriority::Strict },
}
);
solver.set_request(build_remove_request(ctx, channel_context, raw_specs, prune));
auto request = build_remove_request(ctx, channel_context, raw_specs, prune);
request.flags = {
/* .keep_dependencies= */ true,
/* .keep_user_specs= */ true,
/* .force_reinstall= */ false,
/* .allow_downgrade= */ true,
/* .allow_uninstall= */ true,
/* .strict_repo_priority= */ ctx.channel_priority == ChannelPriority::Strict,
};
auto solver = MSolver(pool);
solver.set_request(std::move(request));
solver.must_solve();
MTransaction transaction(pool, solver, package_caches);

View File

@ -131,15 +131,6 @@ namespace mamba
load_installed_packages_in_pool(ctx, pool, prefix_data);
MSolver solver(
pool,
{
{ SOLVER_FLAG_ALLOW_DOWNGRADE, ctx.allow_downgrade },
{ SOLVER_FLAG_ALLOW_UNINSTALL, ctx.allow_uninstall },
{ SOLVER_FLAG_STRICT_REPO_PRIORITY, ctx.channel_priority == ChannelPriority::Strict },
}
);
auto request = create_update_request(
prefix_data,
raw_update_specs,
@ -155,6 +146,14 @@ namespace mamba
/* no_pin= */ config.at("no_pin").value<bool>(),
/* no_py_pin = */ config.at("no_py_pin").value<bool>()
);
request.flags = {
/* .keep_dependencies= */ true,
/* .keep_user_specs= */ true,
/* .force_reinstall= */ false,
/* .allow_downgrade= */ ctx.allow_downgrade,
/* .allow_uninstall= */ ctx.allow_uninstall,
/* .strict_repo_priority= */ ctx.channel_priority == ChannelPriority::Strict,
};
{
auto out = Console::stream();
@ -162,8 +161,8 @@ namespace mamba
// Console stream prints on destrucion
}
auto solver = MSolver(pool);
solver.set_request(std::move(request));
solver.must_solve();
auto execute_transaction = [&](MTransaction& transaction)

View File

@ -28,9 +28,8 @@
namespace mamba
{
MSolver::MSolver(MPool pool, std::vector<std::pair<int, int>> flags)
: m_libsolv_flags(std::move(flags))
, m_pool(std::move(pool))
MSolver::MSolver(MPool pool)
: m_pool(std::move(pool))
, m_solver(nullptr)
, m_is_solved(false)
{
@ -57,30 +56,6 @@ namespace mamba
m_request = std::move(request);
}
void MSolver::set_flags(const Flags& flags)
{
m_flags = flags;
}
auto MSolver::flags() const -> const Flags&
{
return m_flags;
}
void MSolver::py_set_libsolv_flags(const std::vector<std::pair<int, int>>& flags)
{
m_libsolv_flags = flags;
}
void MSolver::apply_libsolv_flags()
{
// TODO use new API
for (const auto& option : m_libsolv_flags)
{
solver_set_flag(m_solver->raw(), option.first, option.second);
}
}
bool MSolver::is_solved() const
{
return m_is_solved;
@ -106,13 +81,23 @@ namespace mamba
return m_request;
}
namespace
{
void set_solver_flags(solv::ObjSolver& solver, const solver::Request::Flags& flags)
{
::solver_set_flag(solver.raw(), SOLVER_FLAG_ALLOW_DOWNGRADE, flags.allow_downgrade);
::solver_set_flag(solver.raw(), SOLVER_FLAG_ALLOW_UNINSTALL, flags.allow_uninstall);
::solver_set_flag(solver.raw(), SOLVER_FLAG_STRICT_REPO_PRIORITY, flags.strict_repo_priority);
}
}
bool MSolver::try_solve()
{
auto solv_jobs = solver::libsolv::request_to_decision_queue(
m_request,
m_pool.pool(),
m_pool.channel_context().params(),
m_flags.force_reinstall
m_request.flags.force_reinstall
);
if (!solv_jobs)
{
@ -120,7 +105,7 @@ namespace mamba
}
m_solver = std::make_unique<solv::ObjSolver>(m_pool.pool());
apply_libsolv_flags();
set_solver_flags(*m_solver, m_request.flags);
const bool success = solver().solve(m_pool.pool(), solv_jobs.value());
m_is_solved = true;

View File

@ -224,12 +224,12 @@ namespace mamba
auto trans = solv::ObjTransaction::from_solver(pool, solver.solver());
trans.order(pool);
const auto& flags = solver.flags();
if (flags.keep_specs && flags.keep_dependencies)
const auto& flags = solver.request().flags;
if (flags.keep_user_specs && flags.keep_dependencies)
{
m_solution = solver::libsolv::transaction_to_solution(m_pool.pool(), trans);
}
else if (flags.keep_specs && !flags.keep_dependencies)
else if (flags.keep_user_specs && !flags.keep_dependencies)
{
m_solution = solver::libsolv::transaction_to_solution_no_deps(
m_pool.pool(),
@ -237,7 +237,7 @@ namespace mamba
solver.request()
);
}
else if (!flags.keep_specs && flags.keep_dependencies)
else if (!flags.keep_user_specs && flags.keep_dependencies)
{
m_solution = solver::libsolv::transaction_to_solution_only_deps(
m_pool.pool(),
@ -246,7 +246,7 @@ namespace mamba
);
}
if (solver.flags().keep_specs)
if (flags.keep_user_specs)
{
using Request = solver::Request;
solver::for_each_of<Request::Install, Request::Update>(

View File

@ -155,10 +155,7 @@ namespace
auto pool = MPool{ ctx, channel_context };
pool.add_repo_from_repodata_json(repodata_f, "some-url");
auto solver = MSolver(
std::move(pool),
std::vector{ std::pair{ SOLVER_FLAG_ALLOW_DOWNGRADE, 1 } }
);
auto solver = MSolver(std::move(pool));
solver.set_request(std::move(request));
return solver;
@ -173,7 +170,7 @@ TEST_CASE("Test create_problem utility")
ctx,
channel_context,
std::array{ mkpkg("foo", "0.1.0", {}) },
{ { Request::Install{ "foo"_ms } } }
{ {}, { Request::Install{ "foo"_ms } } }
);
const auto solved = solver.try_solve();
REQUIRE(solved);
@ -187,7 +184,7 @@ TEST_CASE("Test empty specs")
ctx,
channel_context,
std::array{ mkpkg("foo", "0.1.0", {}), mkpkg("", "", {}) },
{ { Request::Install{ "foo"_ms } } }
{ {}, { Request::Install{ "foo"_ms } } }
);
const auto solved = solver.try_solve();
REQUIRE(solved);
@ -205,7 +202,7 @@ namespace
mkpkg("A", "0.2.0"),
mkpkg("A", "0.3.0"),
},
{ { Request::Install{ "A=0.4.0"_ms } } }
{ {}, { Request::Install{ "A=0.4.0"_ms } } }
);
}
@ -238,11 +235,12 @@ namespace
mkpkg("intl", "4.0.0"),
mkpkg("intl", "3.0.0"),
},
{ {
Request::Install{ "menu"_ms },
Request::Install{ "icons=1.*"_ms },
Request::Install{ "intl=5.*"_ms },
} }
{ {},
{
Request::Install{ "menu"_ms },
Request::Install{ "icons=1.*"_ms },
Request::Install{ "intl=5.*"_ms },
} }
);
}
@ -300,13 +298,14 @@ namespace
ctx,
channel_context,
packages,
{ {
Request::Install{ "menu"_ms },
Request::Install{ "pyicons=1.*"_ms },
Request::Install{ "intl=5.*"_ms },
Request::Install{ "intl-mod"_ms },
Request::Install{ "pretty>=1.0"_ms },
} }
{ {},
{
Request::Install{ "menu"_ms },
Request::Install{ "pyicons=1.*"_ms },
Request::Install{ "intl=5.*"_ms },
Request::Install{ "intl-mod"_ms },
Request::Install{ "pretty>=1.0"_ms },
} }
);
}
@ -413,10 +412,7 @@ namespace
load_channels(ctx, pool, cache, make_platform_channels(std::move(channels), platforms));
ctx.graphics_params.no_progress_bars = prev_progress_bars_value;
auto solver = MSolver(
std::move(pool),
std::vector{ std::pair{ SOLVER_FLAG_ALLOW_DOWNGRADE, 1 } }
);
auto solver = MSolver(std::move(pool));
solver.set_request(std::move(request));
return solver;
@ -427,7 +423,11 @@ TEST_CASE("Test create_conda_forge utility")
{
auto& ctx = mambatests::context();
auto channel_context = ChannelContext::make_conda_compatible(ctx);
auto solver = create_conda_forge(ctx, channel_context, { { Request::Install{ "xtensor>=0.7"_ms } } });
auto solver = create_conda_forge(
ctx,
channel_context,
{ {}, { Request::Install{ "xtensor>=0.7"_ms } } }
);
const auto solved = solver.try_solve();
REQUIRE(solved);
}
@ -439,7 +439,7 @@ namespace
return create_conda_forge(
ctx,
channel_context,
{ { Request::Install{ "python=2.7"_ms }, Request::Install{ "pytorch=1.12"_ms } } }
{ {}, { Request::Install{ "python=2.7"_ms }, Request::Install{ "pytorch=1.12"_ms } } }
);
}
@ -448,7 +448,7 @@ namespace
return create_conda_forge(
ctx,
channel_context,
{ { Request::Install{ "python=2.7"_ms }, Request::Install{ "pytorch=1.12"_ms } } },
{ {}, { Request::Install{ "python=2.7"_ms }, Request::Install{ "pytorch=1.12"_ms } } },
{ mkpkg("__glibc", "2.17.0"), mkpkg("__cuda", "10.2.0") }
);
}
@ -458,13 +458,14 @@ namespace
return create_conda_forge(
ctx,
channel_context,
{ {
Request::Install{ "python=3.7"_ms },
Request::Install{ "cudatoolkit=11.1"_ms },
Request::Install{ "cudnn=8.0"_ms },
Request::Install{ "pytorch=1.8"_ms },
Request::Install{ "torchvision=0.9=*py37_cu111*"_ms },
} },
{ {},
{
Request::Install{ "python=3.7"_ms },
Request::Install{ "cudatoolkit=11.1"_ms },
Request::Install{ "cudnn=8.0"_ms },
Request::Install{ "pytorch=1.8"_ms },
Request::Install{ "torchvision=0.9=*py37_cu111*"_ms },
} },
{ mkpkg("__glibc", "2.17.0"), mkpkg("__cuda", "11.1") }
);
}
@ -474,7 +475,7 @@ namespace
return create_conda_forge(
ctx,
channel_context,
{ { Request::Install{ "python=3.7"_ms }, Request::Install{ "jpeg=9b"_ms } } }
{ {}, { Request::Install{ "python=3.7"_ms }, Request::Install{ "jpeg=9b"_ms } } }
);
}
@ -483,13 +484,14 @@ namespace
return create_conda_forge(
ctx,
channel_context,
{ {
Request::Install{ "r-base=3.5.* "_ms },
Request::Install{ "pandas=0"_ms },
Request::Install{ "numpy<1.20.0"_ms },
Request::Install{ "matplotlib=2"_ms },
Request::Install{ "r-matchit=4.*"_ms },
} }
{ {},
{
Request::Install{ "r-base=3.5.* "_ms },
Request::Install{ "pandas=0"_ms },
Request::Install{ "numpy<1.20.0"_ms },
Request::Install{ "matplotlib=2"_ms },
Request::Install{ "r-matchit=4.*"_ms },
} }
);
}
@ -498,7 +500,7 @@ namespace
return create_conda_forge(
ctx,
channel_context,
{ { Request::Install{ "scip=8.*"_ms }, Request::Install{ "pyscipopt<4.0"_ms } } }
{ {}, { Request::Install{ "scip=8.*"_ms }, Request::Install{ "pyscipopt<4.0"_ms } } }
);
}
@ -507,7 +509,7 @@ namespace
return create_conda_forge(
ctx,
channel_context,
{ { Request::Install{ "python=3.9.*"_ms }, Request::Install{ "python=3.10.*"_ms } } }
{ {}, { Request::Install{ "python=3.9.*"_ms }, Request::Install{ "python=3.10.*"_ms } } }
);
}
@ -516,7 +518,7 @@ namespace
return create_conda_forge(
ctx,
channel_context,
{ { Request::Install{ "python=3.11"_ms }, Request::Install{ "numba<0.56"_ms } } }
{ {}, { Request::Install{ "python=3.11"_ms }, Request::Install{ "numba<0.56"_ms } } }
);
}

View File

@ -310,9 +310,79 @@ bind_submodule_impl(pybind11::module_ m)
}
));
m.attr("MAMBA_NO_DEPS") = "V2 Migration: Use Solver.Flags instead";
m.attr("MAMBA_ONLY_DEPS") = "V2 Migration: Use Solver.Flags instead";
m.attr("MAMBA_FORCE_REINSTALL") = "V2 Migration: Use Solver.Flags instead";
constexpr auto global_solver_flag_v2_migrator = "V2 Migration: Solver flags set in libmambapy.solver.Request.flags.";
m.attr("MAMBA_NO_DEPS") = global_solver_flag_v2_migrator;
m.attr("MAMBA_ONLY_DEPS") = global_solver_flag_v2_migrator;
m.attr("MAMBA_FORCE_REINSTALL") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_ALLOW_DOWNGRADE") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_ALLOW_ARCHCHANGE") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_ALLOW_VENDORCHANGE") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_ALLOW_UNINSTALL") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_NO_UPDATEPROVIDE") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_SPLITPROVIDES") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_IGNORE_RECOMMENDED") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_ADD_ALREADY_RECOMMENDED") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_NO_INFARCHCHECK") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_ALLOW_NAMECHANGE") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_KEEP_EXPLICIT_OBSOLETES") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_BEST_OBEY_POLICY") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_NO_AUTOTARGET") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_DUP_ALLOW_DOWNGRADE") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_DUP_ALLOW_NAMECHANGE") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_KEEP_ORPHANS") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_BREAK_ORPHANS") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_FOCUS_INSTALLED") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_YUM_OBSOLETES") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_NEED_UPDATEPROVIDE") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_URPM_REORDER") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_FOCUS_BEST") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_STRONG_RECOMMENDS") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_INSTALL_ALSO_UPDATES") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED") = global_solver_flag_v2_migrator;
m.attr("SOLVER_FLAG_STRICT_REPO_PRIORITY") = global_solver_flag_v2_migrator;
constexpr auto global_solver_job_v2_migrator = "V2 Migration: job types are explicitly set in libmambapy.solver.Request.";
m.attr("SOLVER_SOLVABLE") = global_solver_job_v2_migrator;
m.attr("SOLVER_SOLVABLE_NAME") = global_solver_job_v2_migrator;
m.attr("SOLVER_SOLVABLE_PROVIDES") = global_solver_job_v2_migrator;
m.attr("SOLVER_SOLVABLE_ONE_OF") = global_solver_job_v2_migrator;
m.attr("SOLVER_SOLVABLE_REPO") = global_solver_job_v2_migrator;
m.attr("SOLVER_SOLVABLE_ALL") = global_solver_job_v2_migrator;
m.attr("SOLVER_SELECTMASK") = global_solver_job_v2_migrator;
m.attr("SOLVER_NOOP") = global_solver_job_v2_migrator;
m.attr("SOLVER_INSTALL") = global_solver_job_v2_migrator;
m.attr("SOLVER_ERASE") = global_solver_job_v2_migrator;
m.attr("SOLVER_UPDATE") = global_solver_job_v2_migrator;
m.attr("SOLVER_WEAKENDEPS") = global_solver_job_v2_migrator;
m.attr("SOLVER_MULTIVERSION") = global_solver_job_v2_migrator;
m.attr("SOLVER_LOCK") = global_solver_job_v2_migrator;
m.attr("SOLVER_DISTUPGRADE") = global_solver_job_v2_migrator;
m.attr("SOLVER_VERIFY") = global_solver_job_v2_migrator;
m.attr("SOLVER_DROP_ORPHANED") = global_solver_job_v2_migrator;
m.attr("SOLVER_USERINSTALLED") = global_solver_job_v2_migrator;
m.attr("SOLVER_ALLOWUNINSTALL") = global_solver_job_v2_migrator;
m.attr("SOLVER_FAVOR") = global_solver_job_v2_migrator;
m.attr("SOLVER_DISFAVOR") = global_solver_job_v2_migrator;
m.attr("SOLVER_JOBMASK") = global_solver_job_v2_migrator;
m.attr("SOLVER_WEAK") = global_solver_job_v2_migrator;
m.attr("SOLVER_ESSENTIAL") = global_solver_job_v2_migrator;
m.attr("SOLVER_CLEANDEPS") = global_solver_job_v2_migrator;
m.attr("SOLVER_ORUPDATE") = global_solver_job_v2_migrator;
m.attr("SOLVER_FORCEBEST") = global_solver_job_v2_migrator;
m.attr("SOLVER_TARGETED") = global_solver_job_v2_migrator;
m.attr("SOLVER_NOTBYUSER") = global_solver_job_v2_migrator;
m.attr("SOLVER_SETEV") = global_solver_job_v2_migrator;
m.attr("SOLVER_SETEVR") = global_solver_job_v2_migrator;
m.attr("SOLVER_SETARCH") = global_solver_job_v2_migrator;
m.attr("SOLVER_SETVENDOR") = global_solver_job_v2_migrator;
m.attr("SOLVER_SETREPO") = global_solver_job_v2_migrator;
m.attr("SOLVER_NOAUTOSET") = global_solver_job_v2_migrator;
m.attr("SOLVER_SETNAME") = global_solver_job_v2_migrator;
m.attr("SOLVER_SETMASK") = global_solver_job_v2_migrator;
/**************
* Bindings *
@ -456,64 +526,18 @@ bind_submodule_impl(pybind11::module_ m)
.def_readwrite("description", &SolverProblem::description)
.def("__str__", [](const SolverProblem& self) { return self.description; });
py::class_<MSolver::Flags>(pySolver, "Flags")
.def(py::init(
[](bool keep_dependencies, bool keep_specs, bool force_reinstall) -> MSolver::Flags
{
return {
/* .keep_dependencies= */ keep_dependencies,
/* .keep_specs= */ keep_specs,
/* .force_reinstall= */ force_reinstall,
};
}
))
.def_readwrite("keep_dependencies", &MSolver::Flags::keep_dependencies)
.def_readwrite("keep_specs", &MSolver::Flags::keep_specs)
.def_readwrite("force_reinstall", &MSolver::Flags::force_reinstall);
constexpr auto flags_v2_migrator = [](MSolver&, py::args, py::kwargs)
{ throw std::runtime_error("All flags need to be passed in the libmambapy.solver.Request."); };
constexpr auto job_v2_migrator = [](MSolver&, py::args, py::kwargs)
{ throw std::runtime_error("All jobs need to be passed in the libmambapy.solver.Request."); };
pySolver.def(py::init<MPool&, std::vector<std::pair<int, int>>>(), py::keep_alive<1, 2>())
.def(
"add_jobs",
[](MSolver&, int)
{
// V2 migrator
throw std::runtime_error("All jobs must be provided in a single Request.");
}
)
.def(
"add_global_job",
[](MSolver&, int)
{
// V2 migrator
throw std::runtime_error("All jobs must be provided in a single Request.");
}
)
.def(
"add_pin",
[](MSolver&, int)
{
// V2 migrator
throw std::runtime_error("All jobs must be provided in a single Request.");
}
)
.def("set_libsolv_flags", &MSolver::py_set_libsolv_flags)
.def(
"set_flags",
[](MSolver&, const std::vector<std::pair<int, int>>&)
{
// V2 migrator
throw std::runtime_error("Use Solver.set_libsolv_flags instead.");
}
)
.def("set_flags", &MSolver::set_flags)
.def(
"set_postsolve_flags",
[](MSolver&, const std::vector<std::pair<int, int>>&)
{
// V2 migrator
throw std::runtime_error("Use Solver.set_flags with Solver.Flags object instead.");
}
)
pySolver.def(py::init<MPool&>(), py::keep_alive<1, 2>())
.def("add_jobs", job_v2_migrator)
.def("add_global_job", job_v2_migrator)
.def("add_pin", job_v2_migrator)
.def("set_flags", flags_v2_migrator)
.def("set_libsolv_flags", flags_v2_migrator)
.def("set_postsolve_flags", flags_v2_migrator)
.def("is_solved", &MSolver::is_solved)
.def("problems_to_str", &MSolver::problems_to_str)
.def("all_problems_to_str", &MSolver::all_problems_to_str)
@ -1351,74 +1375,6 @@ bind_submodule_impl(pybind11::module_ m)
m.def("cancel_json_output", [] { Console::instance().cancel_json_print(); });
m.attr("SOLVER_SOLVABLE") = SOLVER_SOLVABLE;
m.attr("SOLVER_SOLVABLE_NAME") = SOLVER_SOLVABLE_NAME;
m.attr("SOLVER_SOLVABLE_PROVIDES") = SOLVER_SOLVABLE_PROVIDES;
m.attr("SOLVER_SOLVABLE_ONE_OF") = SOLVER_SOLVABLE_ONE_OF;
m.attr("SOLVER_SOLVABLE_REPO") = SOLVER_SOLVABLE_REPO;
m.attr("SOLVER_SOLVABLE_ALL") = SOLVER_SOLVABLE_ALL;
m.attr("SOLVER_SELECTMASK") = SOLVER_SELECTMASK;
m.attr("SOLVER_NOOP") = SOLVER_NOOP;
m.attr("SOLVER_INSTALL") = SOLVER_INSTALL;
m.attr("SOLVER_ERASE") = SOLVER_ERASE;
m.attr("SOLVER_UPDATE") = SOLVER_UPDATE;
m.attr("SOLVER_WEAKENDEPS") = SOLVER_WEAKENDEPS;
m.attr("SOLVER_MULTIVERSION") = SOLVER_MULTIVERSION;
m.attr("SOLVER_LOCK") = SOLVER_LOCK;
m.attr("SOLVER_DISTUPGRADE") = SOLVER_DISTUPGRADE;
m.attr("SOLVER_VERIFY") = SOLVER_VERIFY;
m.attr("SOLVER_DROP_ORPHANED") = SOLVER_DROP_ORPHANED;
m.attr("SOLVER_USERINSTALLED") = SOLVER_USERINSTALLED;
m.attr("SOLVER_ALLOWUNINSTALL") = SOLVER_ALLOWUNINSTALL;
m.attr("SOLVER_FAVOR") = SOLVER_FAVOR;
m.attr("SOLVER_DISFAVOR") = SOLVER_DISFAVOR;
m.attr("SOLVER_JOBMASK") = SOLVER_JOBMASK;
m.attr("SOLVER_WEAK") = SOLVER_WEAK;
m.attr("SOLVER_ESSENTIAL") = SOLVER_ESSENTIAL;
m.attr("SOLVER_CLEANDEPS") = SOLVER_CLEANDEPS;
m.attr("SOLVER_ORUPDATE") = SOLVER_ORUPDATE;
m.attr("SOLVER_FORCEBEST") = SOLVER_FORCEBEST;
m.attr("SOLVER_TARGETED") = SOLVER_TARGETED;
m.attr("SOLVER_NOTBYUSER") = SOLVER_NOTBYUSER;
m.attr("SOLVER_SETEV") = SOLVER_SETEV;
m.attr("SOLVER_SETEVR") = SOLVER_SETEVR;
m.attr("SOLVER_SETARCH") = SOLVER_SETARCH;
m.attr("SOLVER_SETVENDOR") = SOLVER_SETVENDOR;
m.attr("SOLVER_SETREPO") = SOLVER_SETREPO;
m.attr("SOLVER_NOAUTOSET") = SOLVER_NOAUTOSET;
m.attr("SOLVER_SETNAME") = SOLVER_SETNAME;
m.attr("SOLVER_SETMASK") = SOLVER_SETMASK;
// Solver flags
m.attr("SOLVER_FLAG_ALLOW_DOWNGRADE") = SOLVER_FLAG_ALLOW_DOWNGRADE;
m.attr("SOLVER_FLAG_ALLOW_ARCHCHANGE") = SOLVER_FLAG_ALLOW_ARCHCHANGE;
m.attr("SOLVER_FLAG_ALLOW_VENDORCHANGE") = SOLVER_FLAG_ALLOW_VENDORCHANGE;
m.attr("SOLVER_FLAG_ALLOW_UNINSTALL") = SOLVER_FLAG_ALLOW_UNINSTALL;
m.attr("SOLVER_FLAG_NO_UPDATEPROVIDE") = SOLVER_FLAG_NO_UPDATEPROVIDE;
m.attr("SOLVER_FLAG_SPLITPROVIDES") = SOLVER_FLAG_SPLITPROVIDES;
m.attr("SOLVER_FLAG_IGNORE_RECOMMENDED") = SOLVER_FLAG_IGNORE_RECOMMENDED;
m.attr("SOLVER_FLAG_ADD_ALREADY_RECOMMENDED") = SOLVER_FLAG_ADD_ALREADY_RECOMMENDED;
m.attr("SOLVER_FLAG_NO_INFARCHCHECK") = SOLVER_FLAG_NO_INFARCHCHECK;
m.attr("SOLVER_FLAG_ALLOW_NAMECHANGE") = SOLVER_FLAG_ALLOW_NAMECHANGE;
m.attr("SOLVER_FLAG_KEEP_EXPLICIT_OBSOLETES") = SOLVER_FLAG_KEEP_EXPLICIT_OBSOLETES;
m.attr("SOLVER_FLAG_BEST_OBEY_POLICY") = SOLVER_FLAG_BEST_OBEY_POLICY;
m.attr("SOLVER_FLAG_NO_AUTOTARGET") = SOLVER_FLAG_NO_AUTOTARGET;
m.attr("SOLVER_FLAG_DUP_ALLOW_DOWNGRADE") = SOLVER_FLAG_DUP_ALLOW_DOWNGRADE;
m.attr("SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE") = SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE;
m.attr("SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE") = SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE;
m.attr("SOLVER_FLAG_DUP_ALLOW_NAMECHANGE") = SOLVER_FLAG_DUP_ALLOW_NAMECHANGE;
m.attr("SOLVER_FLAG_KEEP_ORPHANS") = SOLVER_FLAG_KEEP_ORPHANS;
m.attr("SOLVER_FLAG_BREAK_ORPHANS") = SOLVER_FLAG_BREAK_ORPHANS;
m.attr("SOLVER_FLAG_FOCUS_INSTALLED") = SOLVER_FLAG_FOCUS_INSTALLED;
m.attr("SOLVER_FLAG_YUM_OBSOLETES") = SOLVER_FLAG_YUM_OBSOLETES;
m.attr("SOLVER_FLAG_NEED_UPDATEPROVIDE") = SOLVER_FLAG_NEED_UPDATEPROVIDE;
m.attr("SOLVER_FLAG_URPM_REORDER") = SOLVER_FLAG_URPM_REORDER;
m.attr("SOLVER_FLAG_FOCUS_BEST") = SOLVER_FLAG_FOCUS_BEST;
m.attr("SOLVER_FLAG_STRONG_RECOMMENDS") = SOLVER_FLAG_STRONG_RECOMMENDS;
m.attr("SOLVER_FLAG_INSTALL_ALSO_UPDATES") = SOLVER_FLAG_INSTALL_ALSO_UPDATES;
m.attr("SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED") = SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED;
m.attr("SOLVER_FLAG_STRICT_REPO_PRIORITY") = SOLVER_FLAG_STRICT_REPO_PRIORITY;
// Solver rule flags
py::enum_<SolverRuleinfo>(m, "SolverRuleinfo")
.value("SOLVER_RULE_UNKNOWN", SolverRuleinfo::SOLVER_RULE_UNKNOWN)

View File

@ -1,5 +1,3 @@
// Copyright (c) 2023, QuantStack and Mamba Contributors
//
// Distributed under the terms of the BSD 3-Clause License.
//
// The full license is in the file LICENSE, distributed with this software.
@ -107,10 +105,50 @@ namespace mambapy
// Type made opaque at the top of this file
py::bind_vector<Request::item_list>(py_request, "ItemList");
py::class_<Request::Flags>(py_request, "Flags")
.def(
py::init(
[](bool keep_dependencies,
bool keep_user_specs,
bool force_reinstall,
bool allow_downgrade,
bool allow_uninstall,
bool strict_repo_priority) -> Request::Flags
{
return {
/* .keep_dependencies= */ keep_dependencies,
/* .keep_user_specs= */ keep_user_specs,
/* .force_reinstall= */ force_reinstall,
/* .allow_downgrade= */ allow_downgrade,
/* .allow_uninstall= */ allow_uninstall,
/* .strict_repo_priority= */ strict_repo_priority,
};
}
),
py::arg("keep_dependencies") = true,
py::arg("keep_user_specs") = true,
py::arg("force_reinstall") = false,
py::arg("allow_downgrade") = true,
py::arg("allow_uninstall") = true,
py::arg("strict_repo_priority") = true
)
.def_readwrite("keep_dependencies", &Request::Flags::keep_dependencies)
.def_readwrite("keep_user_specs", &Request::Flags::keep_user_specs)
.def_readwrite("force_reinstall", &Request::Flags::force_reinstall)
.def_readwrite("allow_downgrade", &Request::Flags::allow_downgrade)
.def_readwrite("allow_uninstall", &Request::Flags::allow_uninstall)
.def_readwrite("strict_repo_priority", &Request::Flags::strict_repo_priority)
.def("__copy__", &copy<Request::Flags>)
.def("__deepcopy__", &deepcopy<Request::Flags>, py::arg("memo"));
py_request
.def(
// Big copy unfortunately
py::init([](Request::item_list items) -> Request { return { std::move(items) }; })
py::init(
[](Request::Flags flags, Request::item_list items) -> Request {
return { std::move(flags), std::move(items) };
}
)
)
.def(py::init(
[](py::iterable items) -> Request
@ -124,6 +162,7 @@ namespace mambapy
return request;
}
))
.def_readwrite("flags", &Request::flags)
.def_readwrite("items", &Request::items)
.def("__copy__", &copy<Request>)
.def("__deepcopy__", &deepcopy<Request>, py::arg("memo"));

View File

@ -1,3 +1,4 @@
import random
import copy
import pytest
@ -65,3 +66,28 @@ def test_Request_Item_clean(Item, kwargs):
other = copy.deepcopy(itm)
assert other is not itm
assert other.clean_dependencies == itm.clean_dependencies
@pytest.mark.parametrize(
"attr",
[
"keep_dependencies",
"keep_user_specs",
"force_reinstall",
"allow_downgrade",
"allow_uninstall",
"strict_repo_priority",
],
)
def test_Request_Flags_boolean(attr):
Flags = libmambapy.solver.Request.Flags
for _ in range(10):
val = bool(random.randint(0, 1))
flags = Flags(**{attr: val})
assert getattr(flags, attr) == val
val = bool(random.randint(0, 1))
setattr(flags, attr, val)
assert getattr(flags, attr) == val