mirror of https://github.com/mamba-org/mamba.git
Bind text_style and graphic params (#3266)
* Rename binding utils.hpp > bind_utils.hpp * Bind fmt::text_style * Change format type in Unsolvable explain message * Bind attributes * Bind GraphicsParams
This commit is contained in:
parent
b5195d96b0
commit
80f1e84d49
|
@ -26,7 +26,6 @@ namespace mamba
|
|||
/** Some action is unsafe or not trusted. */
|
||||
fmt::text_style unsafe;
|
||||
|
||||
|
||||
/** Reference to some input from the user. */
|
||||
fmt::text_style user;
|
||||
/** Input from the user was ignored or has no effect. */
|
||||
|
|
|
@ -50,11 +50,11 @@ namespace mamba::solver::libsolv
|
|||
auto explain_problems_to( //
|
||||
Database& pool,
|
||||
std::ostream& out,
|
||||
const Palette& palette
|
||||
const ProblemsMessageFormat& format
|
||||
) const -> std::ostream&;
|
||||
|
||||
[[nodiscard]] auto
|
||||
explain_problems(Database& pool, const Palette& palette) const -> std::string;
|
||||
explain_problems(Database& pool, const ProblemsMessageFormat& format) const -> std::string;
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -588,7 +588,14 @@ namespace mamba
|
|||
|
||||
if (auto* unsolvable = std::get_if<solver::libsolv::UnSolvable>(&outcome))
|
||||
{
|
||||
unsolvable->explain_problems_to(db, LOG_ERROR, ctx.graphics_params.palette);
|
||||
unsolvable->explain_problems_to(
|
||||
db,
|
||||
LOG_ERROR,
|
||||
{
|
||||
/* .unavailable= */ ctx.graphics_params.palette.failure,
|
||||
/* .available= */ ctx.graphics_params.palette.success,
|
||||
}
|
||||
);
|
||||
if (retry_clean_cache && !is_retry)
|
||||
{
|
||||
ctx.local_repodata_ttl = 2;
|
||||
|
|
|
@ -482,30 +482,26 @@ namespace mamba::solver::libsolv
|
|||
return ProblemsGraphCreator(Database::Impl::get(pool), *m_solver).problem_graph();
|
||||
}
|
||||
|
||||
auto
|
||||
UnSolvable::explain_problems_to(Database& pool, std::ostream& out, const Palette& palette) const
|
||||
-> std::ostream&
|
||||
auto UnSolvable::explain_problems_to(
|
||||
Database& pool,
|
||||
std::ostream& out,
|
||||
const ProblemsMessageFormat& format
|
||||
) const -> std::ostream&
|
||||
{
|
||||
out << "Could not solve for environment specs\n";
|
||||
const auto pbs = problems_graph(pool);
|
||||
const auto pbs_simplified = simplify_conflicts(pbs);
|
||||
const auto cp_pbs = CompressedProblemsGraph::from_problems_graph(pbs_simplified);
|
||||
print_problem_tree_msg(
|
||||
out,
|
||||
cp_pbs,
|
||||
{
|
||||
/* .unavailable= */ palette.failure,
|
||||
/* .available= */ palette.success,
|
||||
}
|
||||
);
|
||||
print_problem_tree_msg(out, cp_pbs, format);
|
||||
return out;
|
||||
}
|
||||
|
||||
auto UnSolvable::explain_problems(Database& pool, const Palette& palette) const -> std::string
|
||||
auto
|
||||
UnSolvable::explain_problems(Database& pool, const ProblemsMessageFormat& format) const -> std::string
|
||||
|
||||
{
|
||||
std::stringstream ss;
|
||||
explain_problems_to(pool, ss, palette);
|
||||
explain_problems_to(pool, ss, format);
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ pybind11_add_module(
|
|||
# All bindings used to live in a global module
|
||||
src/libmambapy/bindings/legacy.cpp
|
||||
# Submodules
|
||||
src/libmambapy/bindings/utils.cpp
|
||||
src/libmambapy/bindings/specs.cpp
|
||||
src/libmambapy/bindings/solver.cpp
|
||||
src/libmambapy/bindings/solver_libsolv.cpp
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# Import all submodules so that one can use them directly with `import libmambapy`
|
||||
import libmambapy.utils
|
||||
import libmambapy.version
|
||||
import libmambapy.specs
|
||||
import libmambapy.solver
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
//
|
||||
// The full license is in the file LICENSE, distributed with this software.
|
||||
|
||||
#ifndef LIBMAMBAPY_UTILS_HPP
|
||||
#define LIBMAMBAPY_UTILS_HPP
|
||||
#ifndef LIBMAMBAPY_BIND_UTILS_HPP
|
||||
#define LIBMAMBAPY_BIND_UTILS_HPP
|
||||
|
||||
#include <memory>
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
PYBIND11_MODULE(bindings, m)
|
||||
{
|
||||
mambapy::bind_submodule_utils(m.def_submodule("utils"));
|
||||
mambapy::bind_submodule_specs(m.def_submodule("specs"));
|
||||
auto solver_submodule = m.def_submodule("solver");
|
||||
mambapy::bind_submodule_solver(solver_submodule);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
namespace mambapy
|
||||
{
|
||||
void bind_submodule_utils(pybind11::module_ m);
|
||||
void bind_submodule_specs(pybind11::module_ m);
|
||||
void bind_submodule_solver(pybind11::module_ m);
|
||||
void bind_submodule_solver_libsolv(pybind11::module_ m);
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
#include "mamba/validation/tools.hpp"
|
||||
#include "mamba/validation/update_framework_v0_6.hpp"
|
||||
|
||||
#include "bind_utils.hpp"
|
||||
#include "bindings.hpp"
|
||||
#include "expected_caster.hpp"
|
||||
#include "flat_set_caster.hpp"
|
||||
#include "path_caster.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
|
@ -620,7 +620,25 @@ bind_submodule_impl(pybind11::module_ m)
|
|||
|
||||
py::class_<Palette>(m, "Palette")
|
||||
.def_static("no_color", &Palette::no_color)
|
||||
.def_static("terminal", &Palette::terminal);
|
||||
.def_static("terminal", &Palette::terminal)
|
||||
.def_readwrite("success", &Palette::success)
|
||||
.def_readwrite("failure", &Palette::failure)
|
||||
.def_readwrite("external", &Palette::external)
|
||||
.def_readwrite("shown", &Palette::shown)
|
||||
.def_readwrite("safe", &Palette::safe)
|
||||
.def_readwrite("unsafe", &Palette::unsafe)
|
||||
.def_readwrite("user", &Palette::user)
|
||||
.def_readwrite("ignored", &Palette::ignored)
|
||||
.def_readwrite("addition", &Palette::addition)
|
||||
.def_readwrite("deletion", &Palette::deletion)
|
||||
.def_readwrite("progress_bar_none", &Palette::progress_bar_none)
|
||||
.def_readwrite("progress_bar_downloaded", &Palette::progress_bar_downloaded)
|
||||
.def_readwrite("progress_bar_extracted", &Palette::progress_bar_extracted);
|
||||
|
||||
py::class_<Context::GraphicsParams>(m, "GraphicsParams")
|
||||
.def(py::init())
|
||||
.def_readwrite("no_progress_bars", &Context::GraphicsParams::no_progress_bars)
|
||||
.def_readwrite("palette", &Context::GraphicsParams::palette);
|
||||
|
||||
py::class_<Context, std::unique_ptr<Context, py::nodelete>> ctx(m, "Context");
|
||||
ctx //
|
||||
|
@ -641,6 +659,7 @@ bind_submodule_impl(pybind11::module_ m)
|
|||
}
|
||||
))
|
||||
.def_static("use_default_signal_handler", &Context::use_default_signal_handler)
|
||||
.def_readwrite("graphics_params", &Context::graphics_params)
|
||||
.def_readwrite("offline", &Context::offline)
|
||||
.def_readwrite("local_repodata_ttl", &Context::local_repodata_ttl)
|
||||
.def_readwrite("use_index_cache", &Context::use_index_cache)
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
#include "mamba/solver/request.hpp"
|
||||
#include "mamba/solver/solution.hpp"
|
||||
|
||||
#include "bind_utils.hpp"
|
||||
#include "bindings.hpp"
|
||||
#include "flat_set_caster.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace mamba::solver
|
||||
{
|
||||
|
@ -388,6 +388,31 @@ namespace mambapy
|
|||
)
|
||||
.def_static("simplify_conflicts", &solver::simplify_conflicts);
|
||||
|
||||
py::class_<ProblemsMessageFormat>(m, "ProblemsMessageFormat")
|
||||
.def(py::init<>())
|
||||
.def(
|
||||
py::init(
|
||||
[](fmt::text_style unavailable,
|
||||
fmt::text_style available,
|
||||
std::array<std::string_view, 4> indents) -> ProblemsMessageFormat
|
||||
{
|
||||
return {
|
||||
/* .unavailable= */ unavailable,
|
||||
/* .available= */ available,
|
||||
/* .indents= */ indents,
|
||||
};
|
||||
}
|
||||
),
|
||||
py::arg("unavailable"),
|
||||
py::arg("available"),
|
||||
py::arg("indents")
|
||||
)
|
||||
.def_readwrite("unavailable", &ProblemsMessageFormat::unavailable)
|
||||
.def_readwrite("available", &ProblemsMessageFormat::available)
|
||||
.def_readwrite("indents", &ProblemsMessageFormat::indents)
|
||||
.def("__copy__", ©<ProblemsMessageFormat>)
|
||||
.def("__deepcopy__", &deepcopy<ProblemsMessageFormat>, py::arg("memo"));
|
||||
|
||||
auto py_compressed_problems_graph = py::class_<CompressedProblemsGraph>(
|
||||
m,
|
||||
"CompressedProblemsGraph"
|
||||
|
@ -481,9 +506,6 @@ namespace mambapy
|
|||
return std::pair(g.nodes(), g.edges());
|
||||
}
|
||||
)
|
||||
.def(
|
||||
"tree_message",
|
||||
[](const CompressedProblemsGraph& self) { return problem_tree_msg(self); }
|
||||
);
|
||||
.def("tree_message", &problem_tree_msg, py::arg("format") = ProblemsMessageFormat());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,17 +8,16 @@
|
|||
#include <pybind11/operators.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
|
||||
#include "mamba/core/palette.hpp"
|
||||
#include "mamba/solver/libsolv/database.hpp"
|
||||
#include "mamba/solver/libsolv/parameters.hpp"
|
||||
#include "mamba/solver/libsolv/repo_info.hpp"
|
||||
#include "mamba/solver/libsolv/solver.hpp"
|
||||
#include "mamba/solver/libsolv/unsolvable.hpp"
|
||||
|
||||
#include "bind_utils.hpp"
|
||||
#include "bindings.hpp"
|
||||
#include "expected_caster.hpp"
|
||||
#include "path_caster.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace mambapy
|
||||
{
|
||||
|
@ -223,7 +222,7 @@ namespace mambapy
|
|||
"explain_problems",
|
||||
&UnSolvable::explain_problems,
|
||||
py::arg("database"),
|
||||
py::arg("palette")
|
||||
py::arg("format")
|
||||
);
|
||||
|
||||
constexpr auto solver_flags_v2_migrator = [](Solver&, py::args, py::kwargs) {
|
||||
|
|
|
@ -21,10 +21,10 @@
|
|||
#include "mamba/specs/version.hpp"
|
||||
#include "mamba/specs/version_spec.hpp"
|
||||
|
||||
#include "bind_utils.hpp"
|
||||
#include "bindings.hpp"
|
||||
#include "expected_caster.hpp"
|
||||
#include "flat_set_caster.hpp"
|
||||
#include "utils.hpp"
|
||||
#include "weakening_map_bind.hpp"
|
||||
|
||||
PYBIND11_MAKE_OPAQUE(mamba::specs::VersionPart);
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
// Copyright (c) 2024, 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.
|
||||
|
||||
#include <optional>
|
||||
#include <variant>
|
||||
|
||||
#include <fmt/color.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/stl_bind.h>
|
||||
|
||||
#include "bind_utils.hpp"
|
||||
|
||||
namespace mambapy
|
||||
{
|
||||
void bind_submodule_utils(pybind11::module_ m)
|
||||
{
|
||||
namespace py = pybind11;
|
||||
|
||||
py::enum_<fmt::emphasis>(m, "TextEmphasis")
|
||||
.value("Bold", fmt::emphasis::bold)
|
||||
.value("Faint", fmt::emphasis::faint)
|
||||
.value("Italic", fmt::emphasis::italic)
|
||||
.value("Underline", fmt::emphasis::underline)
|
||||
.value("Blink", fmt::emphasis::blink)
|
||||
.value("Reverse", fmt::emphasis::reverse)
|
||||
.value("Conceal", fmt::emphasis::conceal)
|
||||
.value("Strikethrough", fmt::emphasis::strikethrough)
|
||||
.def(py::init(&enum_from_str<fmt::emphasis>));
|
||||
py::implicitly_convertible<py::str, fmt::emphasis>();
|
||||
|
||||
py::enum_<fmt::terminal_color>(m, "TextTerminalColor")
|
||||
.value("Black", fmt::terminal_color::black)
|
||||
.value("Red", fmt::terminal_color::red)
|
||||
.value("Green", fmt::terminal_color::green)
|
||||
.value("Yellow", fmt::terminal_color::yellow)
|
||||
.value("Blue", fmt::terminal_color::blue)
|
||||
.value("Magenta", fmt::terminal_color::magenta)
|
||||
.value("Cyan", fmt::terminal_color::cyan)
|
||||
.value("White", fmt::terminal_color::white)
|
||||
.value("BrightBlack", fmt::terminal_color::bright_black)
|
||||
.value("BrightRed", fmt::terminal_color::bright_red)
|
||||
.value("BrightGreen", fmt::terminal_color::bright_green)
|
||||
.value("BrightYellow", fmt::terminal_color::bright_yellow)
|
||||
.value("BrightBlue", fmt::terminal_color::bright_blue)
|
||||
.value("BrightMagenta", fmt::terminal_color::bright_magenta)
|
||||
.value("BrightCyan", fmt::terminal_color::bright_cyan)
|
||||
.value("BrightWhite", fmt::terminal_color::bright_white)
|
||||
.def(py::init(&enum_from_str<fmt::terminal_color>));
|
||||
py::implicitly_convertible<py::str, fmt::terminal_color>();
|
||||
|
||||
py::class_<fmt::rgb>(m, "TextRGBColor")
|
||||
.def(py::init())
|
||||
.def(
|
||||
py::init<std::uint8_t, std::uint8_t, std::uint8_t>(),
|
||||
py::arg("red") = 0,
|
||||
py::arg("green") = 0,
|
||||
py::arg("blue") = 0
|
||||
)
|
||||
.def_readwrite("red", &fmt::rgb::r)
|
||||
.def_readwrite("green", &fmt::rgb::g)
|
||||
.def_readwrite("blue", &fmt::rgb::b)
|
||||
.def("__copy__", ©<fmt::rgb>)
|
||||
.def("__deepcopy__", &deepcopy<fmt::rgb>, py::arg("memo"));
|
||||
|
||||
using ColorType = std::variant<fmt::terminal_color, fmt::rgb>;
|
||||
py::class_<fmt::text_style>(m, "TextStyle")
|
||||
.def(py::init<>())
|
||||
.def(
|
||||
// We rely on ``std::optional`` and ``std::variant`` because
|
||||
// ``fmt::detail::color_type`` is semi-private and would lead to introducing
|
||||
// a new intermediary type.
|
||||
// The bitwise ``|`` syntax of fmt is also not Pythonic.
|
||||
// A more elegant option could be to implement a ``type_caster`` for ``color_type``.
|
||||
py::init(
|
||||
[](std::optional<ColorType> fg,
|
||||
std::optional<ColorType> bg,
|
||||
std::optional<fmt::emphasis> em) -> fmt::text_style
|
||||
{
|
||||
auto out = fmt::text_style();
|
||||
if (em)
|
||||
{
|
||||
out = fmt::text_style(em.value());
|
||||
}
|
||||
if (fg)
|
||||
{
|
||||
std::visit([&out](const auto& color) { out |= fmt::fg(color); }, fg.value());
|
||||
}
|
||||
if (bg)
|
||||
{
|
||||
std::visit([&out](const auto& color) { out |= fmt::bg(color); }, bg.value());
|
||||
}
|
||||
return out;
|
||||
}
|
||||
),
|
||||
py::arg("foreground") = std::nullopt,
|
||||
py::arg("background") = std::nullopt,
|
||||
py::arg("emphasis") = std::nullopt
|
||||
)
|
||||
.def_property_readonly(
|
||||
"foreground",
|
||||
[](const fmt::text_style& style) -> std::optional<ColorType>
|
||||
{
|
||||
if (!style.has_foreground())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto fg = style.get_foreground();
|
||||
if (fg.is_rgb)
|
||||
{
|
||||
return { { fmt::rgb(fg.value.rgb_color) } };
|
||||
}
|
||||
return { { static_cast<fmt::terminal_color>(fg.value.term_color) } };
|
||||
}
|
||||
)
|
||||
.def_property_readonly(
|
||||
"background",
|
||||
[](const fmt::text_style& style) -> std::optional<ColorType>
|
||||
{
|
||||
if (!style.has_background())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto bg = style.get_background();
|
||||
if (bg.is_rgb)
|
||||
{
|
||||
return { { fmt::rgb(bg.value.rgb_color) } };
|
||||
}
|
||||
return { { static_cast<fmt::terminal_color>(bg.value.term_color) } };
|
||||
}
|
||||
)
|
||||
.def_property_readonly(
|
||||
"emphasis",
|
||||
|
||||
[](const fmt::text_style& style) -> std::optional<fmt::emphasis>
|
||||
{
|
||||
if (!style.has_emphasis())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
return { style.get_emphasis() };
|
||||
}
|
||||
|
||||
)
|
||||
.def("__copy__", ©<fmt::text_style>)
|
||||
.def("__deepcopy__", &deepcopy<fmt::text_style>, py::arg("memo"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
# This file exists on its own rather than in `__init__.py` to make `import libmambapy.utils` work.
|
||||
from libmambapy.bindings.utils import * # noqa: F403
|
|
@ -221,6 +221,36 @@ def test_Solution():
|
|||
assert len(other.actions) == len(sol.actions)
|
||||
|
||||
|
||||
def test_ProblemsMessageFormat():
|
||||
ProblemsMessageFormat = libmambapy.solver.ProblemsMessageFormat
|
||||
|
||||
format = ProblemsMessageFormat()
|
||||
|
||||
format = ProblemsMessageFormat(
|
||||
available=libmambapy.utils.TextStyle(foreground="Green"),
|
||||
unavailable=libmambapy.utils.TextStyle(foreground="Red"),
|
||||
indents=["a", "b", "c", "d"],
|
||||
)
|
||||
|
||||
# Getters
|
||||
assert format.available.foreground == libmambapy.utils.TextTerminalColor.Green
|
||||
assert format.unavailable.foreground == libmambapy.utils.TextTerminalColor.Red
|
||||
assert format.indents == ["a", "b", "c", "d"]
|
||||
|
||||
# Setters
|
||||
format.available = libmambapy.utils.TextStyle(foreground="White")
|
||||
format.unavailable = libmambapy.utils.TextStyle(foreground="Black")
|
||||
format.indents = ["1", "2", "3", "4"]
|
||||
assert format.available.foreground == libmambapy.utils.TextTerminalColor.White
|
||||
assert format.unavailable.foreground == libmambapy.utils.TextTerminalColor.Black
|
||||
assert format.indents == ["1", "2", "3", "4"]
|
||||
|
||||
# Copy
|
||||
other = copy.deepcopy(format)
|
||||
assert other is not format
|
||||
assert other.indents == format.indents
|
||||
|
||||
|
||||
def test_ProblemsGraph():
|
||||
# Create a ProblemsGraph
|
||||
db = libmambapy.solver.libsolv.Database(libmambapy.specs.ChannelResolveParams())
|
||||
|
@ -278,7 +308,7 @@ def test_ProblemsGraph():
|
|||
nodes, edges = cp_pbg.graph()
|
||||
assert len(nodes) > 0
|
||||
assert len(edges) > 0
|
||||
assert "is not installable" in cp_pbg.tree_message()
|
||||
assert "is not installable" in cp_pbg.tree_message(libmambapy.solver.ProblemsMessageFormat())
|
||||
|
||||
|
||||
def test_CompressedProblemsGraph_NamedList():
|
||||
|
|
|
@ -278,7 +278,7 @@ def test_Solver_UnSolvable():
|
|||
assert isinstance(outcome.problems_to_str(db), str)
|
||||
assert isinstance(outcome.all_problems_to_str(db), str)
|
||||
assert "The following package could not be installed" in outcome.explain_problems(
|
||||
db, libmambapy.Palette.no_color()
|
||||
db, libmambapy.solver.ProblemsMessageFormat()
|
||||
)
|
||||
assert outcome.problems_graph(db).graph() is not None
|
||||
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
import copy
|
||||
|
||||
import pytest
|
||||
|
||||
import libmambapy
|
||||
|
||||
|
||||
def test_import_submodule():
|
||||
import libmambapy.utils as utils
|
||||
|
||||
# Dummy execution
|
||||
_p = utils.TextEmphasis
|
||||
|
||||
|
||||
def test_import_recursive():
|
||||
import libmambapy as mamba
|
||||
|
||||
# Dummy execution
|
||||
_p = mamba.utils.TextEmphasis
|
||||
|
||||
|
||||
def test_TextEmphasis():
|
||||
TextEmphasis = libmambapy.utils.TextEmphasis
|
||||
|
||||
assert TextEmphasis.Bold.name == "Bold"
|
||||
assert TextEmphasis.Faint.name == "Faint"
|
||||
assert TextEmphasis.Italic.name == "Italic"
|
||||
assert TextEmphasis.Underline.name == "Underline"
|
||||
assert TextEmphasis.Blink.name == "Blink"
|
||||
assert TextEmphasis.Reverse.name == "Reverse"
|
||||
assert TextEmphasis.Conceal.name == "Conceal"
|
||||
assert TextEmphasis.Strikethrough.name == "Strikethrough"
|
||||
|
||||
assert TextEmphasis("Italic") == TextEmphasis.Italic
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
# No parsing, explicit name
|
||||
TextEmphasis(" bold")
|
||||
|
||||
|
||||
def test_TextTerminalColor():
|
||||
TextTerminalColor = libmambapy.utils.TextTerminalColor
|
||||
|
||||
assert TextTerminalColor.Black.name == "Black"
|
||||
assert TextTerminalColor.Red.name == "Red"
|
||||
assert TextTerminalColor.Green.name == "Green"
|
||||
assert TextTerminalColor.Yellow.name == "Yellow"
|
||||
assert TextTerminalColor.Blue.name == "Blue"
|
||||
assert TextTerminalColor.Magenta.name == "Magenta"
|
||||
assert TextTerminalColor.Cyan.name == "Cyan"
|
||||
assert TextTerminalColor.White.name == "White"
|
||||
assert TextTerminalColor.BrightBlack.name == "BrightBlack"
|
||||
assert TextTerminalColor.BrightRed.name == "BrightRed"
|
||||
assert TextTerminalColor.BrightGreen.name == "BrightGreen"
|
||||
assert TextTerminalColor.BrightYellow.name == "BrightYellow"
|
||||
assert TextTerminalColor.BrightBlue.name == "BrightBlue"
|
||||
assert TextTerminalColor.BrightMagenta.name == "BrightMagenta"
|
||||
assert TextTerminalColor.BrightCyan.name == "BrightCyan"
|
||||
assert TextTerminalColor.BrightWhite.name == "BrightWhite"
|
||||
|
||||
assert TextTerminalColor("Red") == TextTerminalColor.Red
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
# No parsing, explicit name
|
||||
TextTerminalColor("red ")
|
||||
|
||||
|
||||
def test_TextRGBColor():
|
||||
TextRGBColor = libmambapy.utils.TextRGBColor
|
||||
|
||||
color = TextRGBColor(red=11, blue=33, green=22)
|
||||
|
||||
# Getters
|
||||
assert color.red == 11
|
||||
assert color.green == 22
|
||||
assert color.blue == 33
|
||||
|
||||
# Setters
|
||||
color.red = 1
|
||||
color.green = 2
|
||||
color.blue = 3
|
||||
assert color.red == 1
|
||||
assert color.green == 2
|
||||
assert color.blue == 3
|
||||
|
||||
# Copy
|
||||
other = copy.deepcopy(color)
|
||||
assert other is not color
|
||||
assert other.red == color.red
|
||||
|
||||
|
||||
def test_TextStyle():
|
||||
TextTerminalColor = libmambapy.utils.TextTerminalColor
|
||||
TextRGBColor = libmambapy.utils.TextRGBColor
|
||||
TextEmphasis = libmambapy.utils.TextEmphasis
|
||||
TextStyle = libmambapy.utils.TextStyle
|
||||
|
||||
style = TextStyle()
|
||||
assert style.foreground is None
|
||||
assert style.background is None
|
||||
assert style.emphasis is None
|
||||
|
||||
style = TextStyle(foreground="Red", background=TextRGBColor(red=123), emphasis="Underline")
|
||||
assert style.foreground == TextTerminalColor.Red
|
||||
assert style.background.red == 123
|
||||
assert style.emphasis == TextEmphasis.Underline
|
||||
|
||||
# Copy
|
||||
other = copy.deepcopy(style)
|
||||
assert other is not style
|
||||
assert other.emphasis == style.emphasis
|
Loading…
Reference in New Issue