Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e2ca62d

Browse files
committed
Make set_options a context manager too.
1 parent 58a75a4 commit e2ca62d

File tree

6 files changed

+77
-61
lines changed

6 files changed

+77
-61
lines changed

CHANGELOG.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ next
33

44
- Fixed support for macos backend on Matplotlib≥3.6.
55
- Support pdf MaxVersion up to 1.7 (if the underlying cairo supports it).
6+
- `set_options` can now be used as a context manager.
67

78
v0.5 (2022-08-18)
89
=================
@@ -69,7 +70,7 @@ v0.1 (2018-07-22)
6970

7071
- Integration with libraqm now occurs via dlopen() rather than being selected
7172
at compile-time.
72-
- Add `set_option`, `get_option` for controlling certain rendering parameters.
73+
- Add `set_options`, `get_options` for controlling some rendering parameters.
7374
- Various rendering and performance improvements.
7475
- On Travis, we now run Matplotlib's test suite with mplcairo patching the
7576
default Agg renderer.

examples/time_drawing_per_element.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ def main():
4949
Example usage:
5050
5151
$ python %(prog)s plot \\
52-
'{{"backend": "agg"}}' \\
53-
'{{"backend": "agg", "agg.path.chunksize": 1000}}' \\
54-
'{{"backend": "module://mplcairo.base", \\
55-
"lines.antialiased": __import__("mplcairo").antialias_t.FAST}}' \\
56-
'{{"backend": "module://mplcairo.base", \\
57-
"lines.antialiased": __import__("mplcairo").antialias_t.BEST}}'
52+
'{"backend": "agg"}' \\
53+
'{"backend": "agg", "agg.path.chunksize": 1000}' \\
54+
'{"backend": "module://mplcairo.base", \\
55+
"lines.antialiased": __import__("mplcairo").antialias_t.FAST}' \\
56+
'{"backend": "module://mplcairo.base", \\
57+
"lines.antialiased": __import__("mplcairo").antialias_t.BEST}'
5858
""")
5959

6060
parser.add_argument(

lib/mplcairo/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def _load_symbols():
3030
__all__ = [
3131
"antialias_t", "operator_t",
3232
"get_options", "set_options",
33-
"get_raw_buffer",
33+
"get_context", "get_raw_buffer",
3434
]
3535

3636

src/_mplcairo.cpp

Lines changed: 6 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,50 +1990,7 @@ PYBIND11_MODULE(_mplcairo, m)
19901990

19911991
// Export functions.
19921992
m.def(
1993-
"set_options", [](py::kwargs kwargs) -> void {
1994-
auto const& pop_option =
1995-
[&](std::string key, auto dummy) -> std::optional<decltype(dummy)> {
1996-
return
1997-
kwargs.attr("pop")(key, py::none())
1998-
.cast<std::optional<decltype(dummy)>>();
1999-
};
2000-
if (auto const& cairo_circles = pop_option("cairo_circles", bool{})) {
2001-
if (*cairo_circles) {
2002-
detail::UNIT_CIRCLE =
2003-
py::module::import("matplotlib.path").attr("Path")
2004-
.attr("unit_circle")();
2005-
} else {
2006-
Py_XDECREF(detail::UNIT_CIRCLE.release().ptr());
2007-
}
2008-
}
2009-
if (auto const& float_surface = pop_option("float_surface", bool{})) {
2010-
if (cairo_version() < CAIRO_VERSION_ENCODE(1, 17, 2)) {
2011-
throw std::invalid_argument{"float surfaces require cairo>=1.17.2"};
2012-
}
2013-
detail::FLOAT_SURFACE = *float_surface;
2014-
}
2015-
if (auto const& threads = pop_option("collection_threads", int{})) {
2016-
detail::COLLECTION_THREADS = *threads;
2017-
}
2018-
if (auto const& miter_limit = pop_option("miter_limit", double{})) {
2019-
detail::MITER_LIMIT = *miter_limit;
2020-
}
2021-
if (auto const& raqm = pop_option("raqm", bool{})) {
2022-
if (*raqm) {
2023-
load_raqm();
2024-
} else {
2025-
unload_raqm();
2026-
}
2027-
}
2028-
if (auto const& debug = pop_option("_debug", bool{})) {
2029-
detail::DEBUG = *debug;
2030-
}
2031-
if (py::bool_(kwargs)) {
2032-
throw std::runtime_error{
2033-
"unknown options passed to set_options: {}"_format(kwargs)
2034-
.cast<std::string>()};
2035-
}
2036-
}, R"__doc__(
1993+
"set_options", set_options, R"__doc__(
20371994
Set mplcairo options.
20381995
20391996
Note that the defaults below refer to the initial values of the options;
@@ -2043,6 +2000,10 @@ At import time, mplcairo will set the initial values of the options from the
20432000
``MPLCAIRO_<OPTION_NAME>`` environment variables (loading them as Python
20442001
literals), if any such variables are set.
20452002
2003+
This function can also be used as a context manager
2004+
(``with set_options(...): ...``). In that case, the original values of the
2005+
options will be restored when the context manager exits.
2006+
20462007
Parameters
20472008
----------
20482009
cairo_circles : bool, default: True
@@ -2078,15 +2039,7 @@ to PostScript levels 2 or 3 -- default: 3), or ``"1.1"``/``"1.2"`` (to restrict
20782039
to SVG 1.1 or 1.2 -- default: 1.1).
20792040
)__doc__");
20802041
m.def(
2081-
"get_options", [] {
2082-
return py::dict(
2083-
"cairo_circles"_a=bool(detail::UNIT_CIRCLE),
2084-
"collection_threads"_a=detail::COLLECTION_THREADS,
2085-
"float_surface"_a=detail::FLOAT_SURFACE,
2086-
"miter_limit"_a=detail::MITER_LIMIT,
2087-
"raqm"_a=has_raqm(),
2088-
"_debug"_a=detail::DEBUG);
2089-
}, R"__doc__(
2042+
"get_options", get_options, R"__doc__(
20902043
Get current mplcairo options. See `set_options` for a description of available
20912044
options.
20922045
)__doc__");

src/_util.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,66 @@ bool py_eq(py::object obj1, py::object obj2) {
108108
return py::module::import("operator").attr("eq")(obj1, obj2).cast<bool>();
109109
}
110110

111+
py::dict get_options()
112+
{
113+
return py::dict(
114+
"cairo_circles"_a=bool(detail::UNIT_CIRCLE),
115+
"collection_threads"_a=detail::COLLECTION_THREADS,
116+
"float_surface"_a=detail::FLOAT_SURFACE,
117+
"miter_limit"_a=detail::MITER_LIMIT,
118+
"raqm"_a=has_raqm(),
119+
"_debug"_a=detail::DEBUG);
120+
}
121+
122+
py::object set_options(py::kwargs kwargs)
123+
{
124+
auto estack = py::module::import("contextlib").attr("ExitStack")();
125+
estack.attr("callback")(py::cpp_function{set_options}, **get_options());
126+
auto const& pop_option =
127+
[&](std::string key, auto dummy) -> std::optional<decltype(dummy)> {
128+
return
129+
kwargs.attr("pop")(key, py::none())
130+
.cast<std::optional<decltype(dummy)>>();
131+
};
132+
if (auto const& cairo_circles = pop_option("cairo_circles", bool{})) {
133+
if (*cairo_circles) {
134+
detail::UNIT_CIRCLE =
135+
py::module::import("matplotlib.path").attr("Path")
136+
.attr("unit_circle")();
137+
} else {
138+
Py_XDECREF(detail::UNIT_CIRCLE.release().ptr());
139+
}
140+
}
141+
if (auto const& float_surface = pop_option("float_surface", bool{})) {
142+
if (*float_surface && cairo_version() < CAIRO_VERSION_ENCODE(1, 17, 2)) {
143+
throw std::invalid_argument{"float surfaces require cairo>=1.17.2"};
144+
}
145+
detail::FLOAT_SURFACE = *float_surface;
146+
}
147+
if (auto const& threads = pop_option("collection_threads", int{})) {
148+
detail::COLLECTION_THREADS = *threads;
149+
}
150+
if (auto const& miter_limit = pop_option("miter_limit", double{})) {
151+
detail::MITER_LIMIT = *miter_limit;
152+
}
153+
if (auto const& raqm = pop_option("raqm", bool{})) {
154+
if (*raqm) {
155+
load_raqm();
156+
} else {
157+
unload_raqm();
158+
}
159+
}
160+
if (auto const& debug = pop_option("_debug", bool{})) {
161+
detail::DEBUG = *debug;
162+
}
163+
if (py::bool_(kwargs)) {
164+
throw std::runtime_error{
165+
"unknown options passed to set_options: {}"_format(kwargs)
166+
.cast<std::string>()};
167+
}
168+
return estack;
169+
}
170+
111171
py::object rc_param(std::string key)
112172
{
113173
return py::reinterpret_borrow<py::object>( // Use a faster path.

src/_util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ struct GlyphsAndClusters {
157157

158158
py::object operator""_format(char const* fmt, std::size_t size);
159159
bool py_eq(py::object obj1, py::object obj2);
160+
py::dict get_options();
161+
py::object set_options(py::kwargs kwargs);
160162
py::object rc_param(std::string key);
161163
cairo_format_t get_cairo_format();
162164
rgba_t to_rgba(py::object color, std::optional<double> alpha = {});

0 commit comments

Comments
 (0)