Test and documentation utilities¶
- genno.core.computer.DEFAULT_WARN_ON_RESULT_TUPLE = False¶
Emit
FutureWarningfromComputer.add()whentupleis returned. This default value can be overridden withc.configure(config={"warn on result tuple": False}).
genno.testing¶
- genno.testing.add_dantzig(c: Computer)[source]¶
Add contents analogous to the ixmp Dantzig scenario.
- genno.testing.add_large_data(c: Computer, num_params, N_dims=6, N_data=0)[source]¶
Add nodes to c that return large-ish data.
The result is a matrix wherein the Cartesian product of all the keys is very large— about 2e17 elements for N_dim = 6—but the contents are very sparse. This can be handled by
SparseDataArray, but not byxarray.DataArraybacked bynumpy.ndarray.
- genno.testing.add_test_data(c: Computer)[source]¶
add_test_data()operating on a Computer, not an ixmp.Scenario.
- genno.testing.assert_logs(caplog, message_or_messages=None, at_level=None)[source]¶
Assert that message_or_messages appear in logs.
Use assert_logs as a context manager for a statement that is expected to trigger certain log messages. assert_logs checks that these messages are generated.
Derived from
ixmp.testing.assert_logs().Example
>>> def test_foo(caplog): ... with assert_logs(caplog, 'a message'): ... logging.getLogger(__name__).info('this is a message!')
- genno.testing.assert_qty_allclose(a, b, check_type: bool = True, check_attrs: bool = True, ignore_extra_coords: bool = False, **kwargs)[source]¶
Assert that objects a and b have numerically close values.
- Parameters:
check_type (
bool, optional) – Assert that a and b are bothQuantityinstances. IfFalse, the arguments are converted to Quantity.check_attrs (
bool, optional) – Also assert that check that attributes are identical.ignore_extra_coords (
bool, optional) – Ignore extra coords that are not dimensions. Only meaningful when Quantity isSparseDataArray.
- genno.testing.assert_qty_equal(a, b, check_type: bool = True, check_attrs: bool = True, ignore_extra_coords: bool = False, **kwargs)[source]¶
Assert that objects a and b are equal.
- Parameters:
check_type (
bool, optional) – Assert that a and b are bothQuantityinstances. IfFalse, the arguments are converted to Quantity.check_attrs (
bool, optional) – Also assert that check that attributes are identical.ignore_extra_coords (
bool, optional) – Ignore extra coords that are not dimensions. Only meaningful when Quantity isSparseDataArray.
- genno.testing.assert_units(qty: AnyQuantity, exp: str) None[source]¶
Assert that qty has units exp.
- genno.testing.get_test_quantity(key: Key) AnyQuantity[source]¶
Computation that returns test data.
- genno.testing.parametrize_copy_on_write(monkeypatch, request)[source]¶
Fixture to run tests with pandas copy-on-write either enabled or disabled.
- genno.testing.parametrize_quantity_class(request)[source]¶
Fixture to run tests twice, for both Quantity implementations.
- genno.testing.pytest_configure(config)[source]¶
Force iam-units to use a distinct cache for each worker.
Work arounds for:
- genno.testing.pytest_runtest_makereport(item, call)[source]¶
Pytest hook to unwrap
genno.ComputationError.This allows to “xfail” tests more precisely on the underlying exception, rather than the ComputationError which wraps it.
- genno.testing.raises_or_warns(value, *args, **kwargs) ContextManager[source]¶
Context manager for tests that
pytest.raises()orpytest.warns().If value is a context manager—such as returned by
pytest.raises(), it is used directly.Examples
@pytest.mark.parametrize( "input, output", (("FOO", 1), ("BAR", pytest.raises(ValueError))) ) def test_myfunc0(input, expected): with raises_or_warns(expected, DeprecationWarning, match="FOO"): assert expected == myfunc(input)
In this example:
myfunc("FOO")is expected to emitDeprecationWarningand return 1.myfunc("BAR")is expected to raiseValueErrorand issue no warning.
@pytest.mark.parametrize( "input, output", (("FOO", 1), ("BAR", pytest.raises(ValueError))) ) def test_myfunc1(input, expected): with raises_or_warns(expected, None): assert expected == myfunc(input)
In this example, no warnings are expected from
myfunc("FOO").
Testing Juypter notebooks.
Copied 2023-04-27 from the corresponding module in ixmp.
- genno.testing.jupyter.get_cell_output(nb, name_or_index, kind='data')[source]¶
Retrieve a cell from nb according to its metadata name_or_index:
The Jupyter notebook format allows specifying a document-wide unique ‘name’ metadata attribute for each cell:
https://nbformat.readthedocs.io/en/latest/format_description.html #cell-metadata
Return the cell matching name_or_index if
str; or the cell at theintindex; or raiseValueError.
- genno.testing.jupyter.run_notebook(nb_path, tmp_path, env=None, **kwargs)[source]¶
Execute a Jupyter notebook via
nbclientand collect output.- Parameters:
nb_path (
os.PathLike) – The notebook file to execute.tmp_path (
os.PathLike) – A directory in which to create temporary output.env (
collections.abc.Mapping, optional) – Execution environment fornbclient. Default:os.environ.kwargs –
Keyword arguments for
nbclient.NotebookClient. Defaults are set for:- ”allow_errors”
Default
False. IfTrue, the execution always succeeds, and cell output contains exception information rather than code outputs.- ”kernel_version”
Jupyter kernel to use. Default: either “python2” or “python3”, matching the current Python major version.
Warning
Any existing configuration for this kernel on the local system— such as an IPython start-up file—will be executed when the kernel starts. Code that enables GUI features can interfere with
run_notebook().- ”timeout”
in seconds; default 10.
- Returns:
nb (
nbformat.NotebookNode) – Parsed and executed notebook.errors (
list) – Any execution errors.
Sphinx extensions¶
Document instances of Operator¶
- class genno.compat.sphinx.autodoc_operator.OperatorDocumenter(directive: DocumenterBridge, name: str, indent: str = '')[source]¶
- genno.compat.sphinx.autodoc_operator.setup(app: sphinx.application.Sphinx) dict[source]¶
Configure
sphinx.ext.autodocto handleOperatoras functions.
Rewrite Sphinx references¶
To use this extension, add a setting reference_aliases in conf.py with content like the following:
# Mapping from expression → replacement.
# Order matters here; earlier entries are matched first.
reference_aliases = {
r"Quantity\.units": "genno.core.base.UnitsMixIn.units",
"KeyLike": ":data:`genno.core.key.KeyLike`",
"Quantity": "genno.core.attrseries.AttrSeries",
"AnyQuantity": ":data:`genno.core.quantity.AnyQuantity`",
#
# Many projects (including Sphinx itself!) do not have a py:module target in for the
# top-level module in objects.inv. Resolve these using :doc:`index` or similar for
# each project.
"dask$": ":std:doc:`dask:index`",
"pint$": ":std:doc:`pint <pint:index>`",
"plotnine$": ":class:`plotnine.ggplot`",
"pyarrow$": ":std:doc:`pyarrow <pyarrow:python/index>`",
"pyam$": ":std:doc:`pyam:index`",
"sphinx$": ":std:doc:`sphinx <sphinx:index>`",
}
In this dictionary, the keys are regular expressions matching part or all of the target of a Sphinx reference. The values are replacement content or entire references; using the latter, it is possible to transmute references from one category to another. For example, in:
from genno.types import AnyQuantity
def myfunc(q: "AnyQuantity") -> None: ...
…the string type annotation q: "AnyQuantity" is automatically converted by Sphinx to :py:class:`AnyQuantity`.
This will always fail, because AnyQuantity is a TypeAlias, not a class.
The reference_aliases entry above replaces this auto-generated reference with one that resolves correctly.
See also the comments in the example above about projects whose objects.inv lacks a target for the module itself.
Resolve missing references using aliased target names, domains, and/or types.
Expanded from and with thanks for https://stackoverflow.com/a/62301461.
- genno.compat.sphinx.rewrite_refs.apply_alias(config: Mapping[str, str], node) bool[source]¶
Apply config to node.
- genno.compat.sphinx.rewrite_refs.resolve_internal_aliases(app: sphinx.application.Sphinx, doctree)[source]¶
Handler for ‘doctree-read’ events.
- genno.compat.sphinx.rewrite_refs.resolve_intersphinx_aliases(app, env, node, contnode)[source]¶
Handler for ‘missing-reference’ (intersphinx) events.
- genno.compat.sphinx.rewrite_refs.setup(app: sphinx.application.Sphinx) dict[source]¶
Connect
rewrite_refsevent handlers.