Commit 27d1785c authored by Daniel Brown's avatar Daniel Brown
Browse files

Merge branch 'develop' of git.ligo.org:finesse/finesse3 into develop

parents 81844aa8 22532ded
......@@ -15,7 +15,6 @@ stages:
image: quay.io/pypa/manylinux2014_x86_64
script:
- yum install -y suitesparse-devel
- ${PYBIN}/pip install -r requirements-build.txt
- ${PYBIN}/pip wheel . --no-deps -w wheelhouse
- auditwheel repair wheelhouse/*.whl
artifacts:
......@@ -53,7 +52,6 @@ build/manylinux/3.9:
# - conda activate ./.finesse-env
# - python --version
# - pip install delocate
# - pip install -r requirements-build.txt
# - pip wheel . --no-deps -w wheelhouse
# - delocate-wheel -v wheelhouse/*.whl
# artifacts:
......@@ -77,28 +75,38 @@ build/manylinux/3.9:
# - conda activate ./.finesse-env
# - python --version
# - pip install delocate
# - pip install -r requirements-build.txt
# - pip wheel . --no-deps -w wheelhouse
# - delocate-wheel -v wheelhouse/*.whl
# artifacts:
# paths:
# - wheelhouse
# Check the project builds with Conda on Linux, since it's a common way to develop
# Finesse (currently no tests get run).
build/linux/conda:
stage: build
image: igwn/base:conda
script:
# Create the environment using the definition file.
- conda env create -f environment.yml -p .finesse-env
- source activate ./.finesse-env # Needs to be "source", not "conda".
- python --version
# Simply check it can be imported.
- python -c "import finesse"
# A build with special flags set on Cython extensions to enable debugging.
build/debug:
build/linux/debug:
stage: build
image: python:3.9
needs: []
script:
- apt update
- apt install -y libsuitesparse-dev
- pip3 install -r requirements-build.txt
# Install editable mode so in-place pyx files are picked up by coverage.
- pip3 install -e .[dev]
# Build Cython extensions with coverage support.
- python3 setup.py --coverage build_ext --force --inplace
# Make a platform-specific wheel.
- python3 setup.py bdist_wheel -d wheelhouse
- pip3 install -e .
# Make a platform-specific wheel (with Cython coverage support)
- CYTHON_COVERAGE=1 CYTHON_DEBUG=1 pip3 wheel . --no-deps -w wheelhouse
artifacts:
paths:
- wheelhouse
......@@ -113,8 +121,9 @@ test/debian/3.8:
- build/manylinux/3.8
image: python:3.8
script:
- python3 scripts/extract_extra_requirements.py setup.cfg test > requirements-test.txt
- pip3 install -r requirements-test.txt
- pip3 install wheelhouse/finesse-*-cp38-cp38-*.manylinux2014_x86_64.whl
- pip3 install -f wheelhouse finesse
- pytest tests
test/debian/3.9:
......@@ -123,8 +132,9 @@ test/debian/3.9:
- build/manylinux/3.9
image: python:3.9
script:
- python3 scripts/extract_extra_requirements.py setup.cfg test > requirements-test.txt
- pip3 install -r requirements-test.txt
- pip3 install wheelhouse/finesse-*-cp39-cp39-*.manylinux2014_x86_64.whl
- pip3 install -f wheelhouse finesse
- pytest tests
# test/macosx/3.8:
......@@ -141,8 +151,9 @@ test/debian/3.9:
# - conda create -p .finesse-env python=3.8
# - conda activate ./.finesse-env
# - python --version
# - python scripts/extract_extra_requirements.py setup.cfg test > requirements-test.txt
# - pip install -r requirements-test.txt
# - pip install wheelhouse/finesse-*-cp38-cp38-macosx_10_9_x86_64.whl
# - pip install -f wheelhouse finesse
# - pytest tests
# test/macosx/3.9:
......@@ -159,8 +170,9 @@ test/debian/3.9:
# - conda create -p .finesse-env python=3.9
# - conda activate ./.finesse-env
# - python --version
# - python scripts/extract_extra_requirements.py setup.cfg test > requirements-test.txt
# - pip install -r requirements-test.txt
# - pip install wheelhouse/finesse-*-cp39-cp39-macosx_10_9_x86_64.whl
# - pip install -f wheelhouse finesse
# - pytest tests
# Test coverage report generation. The report is used to show coverage details in merge
......@@ -169,19 +181,17 @@ test/debian/3.9:
test/coverage:
stage: test
needs:
- build/debug
- build/linux/debug
image: python:3.9
script:
# Dependencies for the wheel provided by the debug build.
- apt update
- apt install -y libsuitesparse-dev
# Dependencies for running the tests. Cython is also required from the build
# dependencies for use by the pytest Cython coverage plugin.
# Dependencies for running the tests.
- python3 scripts/extract_extra_requirements.py setup.cfg test > requirements-test.txt
- pip3 install -r requirements-test.txt
- pip3 install -r requirements-build.txt
- pip3 install wheelhouse/finesse-*-cp39-cp39-linux_x86_64.whl
- pip3 install -f wheelhouse finesse
# Run all tests and generate Cobertura XML formatted coverage report.
- pytest --cov=finesse --cov-config=setup.cfg --cov-report=xml tests
- pytest --cov=finesse --cov-config=pyproject.toml --cov-report=xml tests
# Generate human readable coverage report.
- pycobertura show coverage.xml # Necessary so the GitLab CI regex picks up the total.
coverage: '/^TOTAL\s+.*\s+(\d+\.?\d*)%/' # Regex to allow GitLab to extract and display coverage.
......@@ -200,9 +210,10 @@ docs/html:
- build/manylinux/3.9
image: python:3.9
script:
- python scripts/extract_extra_requirements.py setup.cfg docs > requirements-doc.txt
- pip install -r requirements-doc.txt
# Sphinx autodoc needs to be able to import finesse and finesse_sphinx.
- pip install wheelhouse/finesse-*-cp39-cp39-*.manylinux2014_x86_64.whl
- pip install -f wheelhouse finesse
- cd docs
# Build HTML docs in single process mode. Can go back to "make html" when the
# EOFError is fixed in Sphinx. See #270.
......@@ -230,11 +241,11 @@ docs/pdf:
allow_failure: true
script:
- apt update
# NOTE: can remove `xindy` once Sphinx is updated beyond 3.5.1 (see https://github.com/sphinx-doc/sphinx/issues/8941).
- apt install -y texlive-latex-base librsvg2-bin xindy
- apt install -y texlive-latex-base librsvg2-bin
- python scripts/extract_extra_requirements.py setup.cfg docs > requirements-doc.txt
- pip install -r requirements-doc.txt
# Sphinx autodoc needs to be able to import finesse and finesse_sphinx.
- pip install wheelhouse/finesse-*-cp39-cp39-*.manylinux2014_x86_64.whl
- pip install -f wheelhouse finesse
- cd docs
- make latexpdf
- cd ..
......
# Detect number of threads to build with.
ifndef CPU_COUNT
NUM_THREADS = $(shell nproc || 1)
else
NUM_THREADS = $(CPU_COUNT)
endif
# Ideally we should use a packaging tool command like pip here instead of just `python
# setup.py build_ext` because calling `setup.py` directly does not respect PEP 517 and
# does not regenerate version.py when it's deleted (e.g. with a `make realclean`) and
# does not build in an isolated environment. Unfortunately the pip command is far
# slower, and rebuilds extensions even if nothing has changed, so for now we keep the
# `setup.py` command and instead just make sure that the build dependencies specified in
# `pyproject.toml` are present in the local environment, which seems to allow version.py
# to get rebuilt.
BUILD_CMD = python setup.py build_ext -j $(NUM_THREADS) --inplace
default:
python3 setup.py build_ext -j 4 --inplace
$(BUILD_CMD)
debug:
python3 setup.py --debug build_ext -j 4 --inplace
CYTHON_DEBUG=1 $(BUILD_CMD)
# Build Cython extensions with the CYTHON_TRACE flag enabled to allow coverage tracking.
coverage:
python3 setup.py --coverage build_ext -j 4 --force --inplace
CYTHON_COVERAGE=1 $(BUILD_CMD)
clean:
find . -name "*.so" -type f -delete
......
# Finesse3 Documentation Files
# Finesse 3 documentation
These directories contain the reStuctured Text (reST) files (`.rst` extension) making
up the documentation for the `finesse` package. The package `sphinx` is used for
building the documentation with all docstrings in the `finesse` code itself formatted
using the `numpydoc` style (see below).
## Building the documentation
The documentation can be built in several formats by running `make <format>`
where `<format>` can be, for example, `html` or `latex`. The built documentation
files will then be found in `build/` under the directory corresponding to the
format chosen.
### Requirements for the build process
The following components are required to build the documenation for the `finesse` package from this
directory:
- an up-to-date version of [Sphinx](http://www.sphinx-doc.org/en/master/),
- the [Sphinx Read the Docs theme](http://sphinx-rtd-theme.readthedocs.io/en/latest/),
- the [numpydoc extension](https://numpydoc.readthedocs.io/en/latest/install.html),
- the [sphinxcontrib-bibtex extension](http://sphinxcontrib-bibtex.readthedocs.io/en/latest/index.html),
- the [sphinxcontrib-katex extension](https://sphinxcontrib-katex.readthedocs.io/en/latest/index.html),
- and all the requirements for building the `cython` extensions in the `finesse` package (see
the README in the package root directory for information).
### Finding missing class method documentation
This directory contains a script `check_missing.py` which, when run, will show you which functions,
classes and class methods are currently missing from the `source/api` documentation files and so need
to be added. It will also notify of any public functions, classes andclass methods in the source code
which are missing docstrings.
## Writing `numpydoc` docstrings
To produce well formatted API documentation for Finesse, all module, class and function
docstrings will be written in the [numpydoc style](https://numpydoc.readthedocs.io/en/latest/format.html). If
you installed Python through Anaconda then you should already have the `numpydoc` extension installed, otherwise
run `pip install numpydoc` (or any other suitable package manager such as `conda` or `pacman`) to retrieve
it (note that building the documentation will fail without `numpydoc` installed).
These directories contain the reStuctured Text (reST) files (`.rst` extension) making up
the documentation for the `finesse` package. For information on how to build the
documentation, see the [existing
documentation](https://finesse.docs.ligo.org/finesse3/developer/documenting.html#building-the-documentation).
......@@ -146,8 +146,8 @@ try:
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
except ImportError:
print(
"Error: sphinx_rtd_theme not installed, run pip install sphinx_rtd_theme (or similar) to "
"acquire."
"Error: sphinx_rtd_theme not installed. Ensure you have installed the "
"dependencies required for building the documentation."
)
exit(-1)
......@@ -595,9 +595,12 @@ jupyter_execute_data_priority = [
# The URL template to use for links to the issue tracker.
finesse_issue_uri = "https://git.ligo.org/finesse/finesse3/-/issues/%d"
# The URL template to use for links to Finesse source code.
# The URL templates to use for links to Finesse source code.
# FIXME: figure out the current branch and insert it here instead of 'master', then the
# built links in the docs will link to the corresponding version's source code.
finesse_source_uri = (
# The URL to files within the project root.
finesse_source_root_uri = "https://git.ligo.org/finesse/finesse3/-/tree/master/%s"
# The URL to files within the `finesse` Python package.
finesse_source_package_uri = (
"https://git.ligo.org/finesse/finesse3/-/tree/master/src/finesse/%s"
)
......@@ -2,127 +2,128 @@
.. _requirements_guide:
Adding and modifying dependencies
*********************************
|Finesse| manages its dependencies via `pip <https://pip.pypa.io/en/stable/>`_ using
``requirements`` files. These files work in conjunction with the Conda ``environment``
file to allow ease-of-use through Conda environments, with a single set of requirements
held in the requirements files to allow other package management tools to be used if you
so wish.
There are four requirements files in total:
- `requirements.txt
<https://git.ligo.org/finesse/finesse3/-/blob/master/requirements.txt>`_ --- core
packages needed to run |Finesse|.
- `requirements-build.txt
<https://git.ligo.org/finesse/finesse3/-/blob/master/requirements-build.txt>`_ ---
packages required to build |Finesse| C extensions.
- `requirements-doc.txt
<https://git.ligo.org/finesse/finesse3/-/blob/master/requirements-doc.txt>`_ ---
packages required to build the documentation.
- `requirements-test.txt
<https://git.ligo.org/finesse/finesse3/-/blob/master/requirements-test.txt>`_ ---
packages required to run the |Finesse| test suite.
- `requirements-dev.txt
<https://git.ligo.org/finesse/finesse3/-/blob/master/requirements-dev.txt>`_ --- all
of the above plus some extra formatting and version control related packages for
working with |Finesse| source code.
In addition to the above requirements files, |Finesse| uses separate
``install_requires`` and ``extras_require`` keyword arguments in ``setup.py``. This is
based on following the best practices recommended in the `Python packaging guides
<https://packaging.python.org/discussions/install-requires-vs-requirements/>`_.
Adding a package to the requirements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The process outlined below should be adhered to when adding a package to any of the
requirements categories.
1. Identify the package needed and consider why it is needed in addition to the current
requirements. If it is a large package or involves many source code changes to
accommodate it, then submit an issue to the `Issue Tracker
<https://git.ligo.org/finesse/finesse3/issues>`_ before continuing.
2. Determine the minimum / maximum version of the package required to run the code that
you are adding / changing. You should verify that tests pass with the additional
package on your local machine - see :ref:`testing`.
3. Ascertain the category that the requirement falls under - i.e. if it is a package
needed for a new documentation feature then it should be added to the
``requirements-doc.txt`` file.
4. Add the package name *and pinned version* to the relevant requirements file. For
example, if the package is called ``foo`` and the version you want people to use is
``v1.1.0`` then add the line::
foo == 1.1.0
to the associated requirements file.
5. Add the package name *without the pinned version* to
a. the ``REQUIRES`` list in ``setup.py`` if it is a core package required to run
|Finesse| OR
b. the ``EXTRAS`` dict in ``setup.py`` if it is any other type of package.
Changing the pinned version of a requirement
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Follow the process below to modify the version of an existing requirement.
1. Identify the package version to modify and consider why you need to change the
required version. If it is a core package used frequently (e.g. ``NumPy``) then
submit an issue to the `Issue Tracker
<https://git.ligo.org/finesse/finesse3/issues>`_ before continuing.
2. Determine the version you want to change the requirement to. This can be a minimum
version, maximum version or pinned at some specific version number.
3. Find the package name in the correct requirements file and modify the version number
and condition to the value determined from the previous step. For example, if the
package is called ``foo`` and the current pinned version is ``v1.1.0`` then the line
in the requirements file will be::
foo == 1.1.0
If you want to change this to a minimum version of ``v1.3.0`` then this line should
be changed to::
foo >= 1.3.0
5. Verify that the test suites pass with the package version changed on your local
machine - see :ref:`testing` - before attempting to merge the changes.
Removing a required package
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Occasionally, we may want to remove a package from the requirements if it is no longer
used (typically when a better solution to some problem has been found using a new /
existing package). In this case, the process outlined here should be followed for
removing the package.
1. Identify the package to remove and consider why it should be removed. If it is a
large package or involves many source code changes to accommodate it, then submit an
issue to the `Issue Tracker <https://git.ligo.org/finesse/finesse3/issues>`_ before
continuing.
2. Ascertain the category that the requirement falls under - i.e. if it was a package
needed for a feature of |Finesse| itself then it should be removed from the
``requirements.txt`` file.
3. Remove the line containing the package name from the relevant requirements file.
4. Delete the line containing the package name from one of the following data structures
in ``setup.py``:
a. ``REQUIREMENTS`` if it is a core package required to run |Finesse|,
b. ``SETUP_REQUIREMENTS`` if it is a requirement only to build or install |Finesse|,
OR
c. ``EXTRA_REQUIREMENTS`` if it is an optional extra that should not be installed by
default.
5. Verify that the test suites pass with the package removed from your local machine -
see :ref:`testing` - before attempting to merge the changes.
Requirements for building, running and developing Finesse
=========================================================
|Finesse| requires Python 3.8 or higher. Python 3.8 is a hard requirement due to the use
of positional-only arguments, walrus operators, the use of
:class:`functools.singledispatchmethod` and the requirement for ``dict`` to be
reversible in the code.
|Finesse| additionally requires one system requirement:
- SuiteSparse 4.0 or higher
SuiteSparse is only required to build |Finesse|, not to run it. That means users using a
built |Finesse| distribution (e.g. a Conda package or bdist wheel) do not need to
install it manually, but if someone tries to install a source distribution they will.
Finally, |Finesse| depends on various other Python packages to be able to build and run,
discussed in the next section.
Python requirements in Finesse
------------------------------
**Source code:** :source:`setup.py </setup.py>`, :source:`setup.cfg </setup.cfg>`,
:source:`pyproject.toml </pyproject.toml>`
|Finesse|'s Python requirements are specified following the approach defined by
:pep:`517` (see below). The build backend is, for simplicity, currently set to
``setuptools.build_meta``, though this can be changed later if a tool offering more
useful features becomes available.
The ``setuptools.build_meta`` backend requires runtime requirements, i.e. those required
to be installed in the environment for |Finesse| to run, to be listed in ``setup.cfg``
and/or ``setup.py`` files in the project root. It's not strictly necessary to use *both*
files with ``setuptools`` (indeed it's now recommended to use only the declarative
``setup.cfg`` where possible), but because |Finesse| needs Cython extensions with
relatively complex configurations to be built by the backend it uses a ``setup.py`` to
define the required logic. It may be possible to remove ``setup.py`` later (see
:issue:`367`).
.. rubric:: PEP 517 build backend specification
PEP 517 introduces a standard way for Python packages to specify the tool to use to
perform the actual building of the project (their so-called build *backend*) and the
packages required in order to perform the build (the build *requirements*). This
information is specified in a standardized way in a ``pyproject.toml`` file included in
the project root.
The de-facto backend has traditionally been the ``distutils`` or ``setuptools`` packages
provided with Python itself, and indeed ``setuptools`` is the default used by pip if a
``pyproject.toml`` file cannot be located in the project. One of the purposes of PEP 517
is to allow other backends to be more easily used.
Users or higher level package managers such as Conda can then use a build *frontend*
(such as `pip <https://pip.pypa.io/en/stable/>`__ or `poetry
<https://python-poetry.org/>`__) to actually perform the retrieval and installation of
the project and its requirements, invoking the build backends specified for the project
and its dependencies.
.. note::
PEP 517 recommends (but does not strictly require) that build frontends by default
set up an isolated environment in which the backend can build the project. This means
that build requirements are installed in a temporary location used only for the
building of the package, then deleted when the newly built package is moved to the
user's environment and the temporary environment is removed. This behaviour is
usually beneficial because it helps to catch missing dependencies and removes the
need for build requirements (e.g. ``Cython``) to be available in the local
environment, but when debugging build issues it can be useful to switch this
behaviour off. In pip this can be done by adding the ``--no-build-isolation`` flag to
``pip install``. Note that you'll need to ensure the ``inplacebuild`` extras listed
in ``pyproject.toml`` are installed.
Version pinning
~~~~~~~~~~~~~~~
The versions of the |Finesse| runtime requirements are set by a compromise between the
desire to use the latest (and usually greatest) versions and the need to help package
managers include |Finesse| alongside other tools with their own, possibly conflicting,
requirements. It is therefore best to set only minimum required versions in
``setup.cfg``, leaving the maximum version open unless there are known
incompatibilities.
We rely on the regular running of the tests in the continuous integration pipeline to
catch issues created by the latest versions of requirements. In cases where a particular
dependency version is identified to cause problems with |Finesse|, it can be forbidden
in the version string for the respective dependency in ``setup.cfg`` (see next section).
It is also useful to leave a note next to the requirement to inform others (including
package maintainers, who may not be |Finesse| developers) why this is the case.
Modifying requirements
~~~~~~~~~~~~~~~~~~~~~~
Modification of requirements involves editing one or more files:
- Runtime requirements are listed within the ``install_requires`` key of the
``[options]`` section of ``setup.cfg``.
- Build requirements are defined in the ``requires`` key within the ``[build-system]``
section of ``pyproject.toml``.
- Extra requirements are defined in the ``[options.extras_require]`` section of
``setup.cfg`` and can be used to specify optional requirements for users or
developers. These are not installed by most frontends by default. The
``extras_require`` section contains keys and values representing groups of
requirements. For example, the key ``docs`` lists requirements for building the
documentation.
:pep:`508` specifies the format for requirements strings.
.. warning::
As described in a previous section, the *building* of |Finesse| usually takes place
in an isolated environment, so most build requirements these can be pinned in
``pyproject.toml`` to whatever version is desired without causing trouble elsewhere.
It is important, however, that at least the ``numpy`` and ``cython`` requirements are
set to the same versions in ``pyproject.toml`` and ``setup.cfg`` because parts of the
|Finesse| code are compiled and linked against the ``numpy`` C ABI. Using different
versions of ``numpy`` or ``cython`` for building and running |Finesse| frequently
results in numerous warnings issued by ``numpy``, or even errors. It's also very
useful from the point of view of debugging to maintain binary compatibility between
|Finesse| built in an isolated environment (i.e. via the full build process) and
in-place (e.g. via ``make``).
After modifying requirements, verify that the tests still pass and build process still
operates as expected.
......@@ -6,6 +6,8 @@
Contributing to the documentation
=================================
**Source code:** :source:`docs </docs>`
Here we describe the procedure through which to contribute to these |Finesse|
documentation pages and guidelines for conventions and styles to use. The documentation
is built with `Sphinx <http://sphinx-doc.org/>`_ and uses reStructured Text (reST) for
......@@ -148,8 +150,9 @@ various situations:
- `:kat:element:\`element_name\`` to create a link to a kat-script element,
- `:kat:analysis:\`analysis_name\`` to create a link to a kat-script analysis,
- `:issue:`123`` to create a link to an issue on the tracker,
- `:source:`script/compiler.py`` to create a link to a source code file (relative to
``/src/finesse/``).
- `:source:`path/to/script.py`` to create a link to a source code file relative to
the |Finesse| package root (i.e. ``/src/finesse/``), or `:source:`/path/to/script.py``
to create a link to a source code file relative to the project root.
An example of cross-referencing is shown below for the :meth:`.Model.path` method::
......@@ -351,8 +354,9 @@ The documentation can be built using the Makefile provided within the ``docs``
directory. Run ``make`` with no arguments to print a list of available output formats.
The most common output format is HTML, which can be produced with the command ``make
html``. Note that in order to compile the documentation certain extra dependencies are
required. These are automatically installed when the project is installed in ``dev``
mode, e.g. using ``pip install -e .[dev]``.
required. These are automatically installed when the project is installed in
:ref:`developer mode <how_to_contribute>`. If you wish to install just the dependencies
required for building the documentation, you can use e.g. ``pip install -e .[docs]``.
In order to build the PDF docs (using ``make latexpdf``), you must ensure that a
comprehensive LaTeX package (such as ``texlive``) and a program that provides the
......
......@@ -19,9 +19,9 @@ JupyterLab
Repository: https://git.ligo.org/finesse/katscript-jupyterlab
The JupyterLab extension is distributed in two places; via ``pip`` and ``npm``.
New versions should be published at both locations. You need to have `nodejs
<https://nodejs.org/en/>`_ installed to work with the extension.
The JupyterLab extension is distributed in two places; via pip and npm. New versions
should be published at both locations. You need to have `nodejs
<https://nodejs.org/en/>`__ installed to work with the extension.
pip
---
......@@ -66,7 +66,7 @@ Your update should then be immediately available from the JupyterLab extension m
Files published to https://npmjs.com are **permanent**; you cannot unpublish a
package more than 24 hours after it was published, so take care.
Visual Studio Code
==================
......@@ -149,6 +149,6 @@ Pygments
========
The Pygments extension is installed along with |Finesse| by defining the
``pygments.lexers`` entry point in :source:`setup.py <../../setup.py>`, so no further
``pygments.lexers`` entry point in :source:`setup.py </setup.py>`, so no further
packaging work needs to be done. The actual extension is defined in
:source:`script/highlighter.py`, and is described there.
.. include:: ../../defs.hrst
.. _dev_get_started:
Getting started with Finesse development
----------------------------------------
|Finesse| is an open source program where any contributions (of any size) from members
of the optical simulation community are welcome and encouraged.
The project is hosted on `<https://git.ligo.org/finesse/finesse3>`_.
Submitting a bug report
***********************
If you encounter a bug in the code or documentation, especially in a release version, do
not hesitate to submit an issue to the `Issue Tracker
<https://git.ligo.org/finesse/finesse3/issues>`_.
When reporting a bug, please include the following: