diff --git a/docs/conf.py b/docs/conf.py index 3a5d9960b..a10824bda 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,11 +21,13 @@ from importlib.metadata import distribution from pathlib import Path from urllib.parse import urlparse, urlunparse +import logging from jinja2.filters import FILTERS from sphinx_gallery import scrapers from sphinx_gallery.sorting import ExampleTitleSortKey from sphinx.highlighting import lexers +from sphinx.util import logging as sphinx_logging from packaging.version import parse as parse_version from pygments.lexers import TOMLLexer @@ -226,6 +228,7 @@ def get_supported_python_versions(project_name): '.jupyter_cache', 'jupyter_execute', 'plugins/_*.md', + 'plugins/building_a_plugin/_layer_data_guide.md', 'gallery/index.rst', ] @@ -305,6 +308,40 @@ def add_google_calendar_secrets(app, docname, source): if docname == 'community/meeting_schedule': source[0] = source[0].replace('{API_KEY}', GOOGLE_CALENDAR_API_KEY) +class FilterSphinxWarnings(logging.Filter): + """Filter 'duplicate object description' warnings. + + These warnings are a result of autosummary limitations when we have + Attributes and Properties in a class sharing the same name. + + The warnings are not useful - they don't result in any missing documentation + or rendering issues, so we can safely ignore them. + + """ + def __init__(self, app): + self.app = app + super().__init__() + + def filter(self, record: logging.LogRecord) -> bool: + msg = record.getMessage() + + filter_out = ( + "duplicate object description", + ) + + if msg.strip().startswith(filter_out): + return False + return True + +def qt_docstrings(app, what, name, obj, options, lines): + """Only show first line of Qt threading docstrings. + + Avoids syntax errors since the Qt threading docstrings are written in + Markdown, and injected into rst docstring automatically. + """ + if "WorkerBase" in name: + if len(lines) > 0: + del lines[1:] def setup(app): """Set up docs build. @@ -313,11 +350,21 @@ def setup(app): files found for document when generating the gallery * Rewrites github anchors to be comparable * Adds google calendar api key to meetings schedule page + * Filters out 'duplicate object description' Sphinx warnings + * Cleans out Qt threading docstrings """ app.registry.source_suffix.pop(".ipynb", None) app.connect('source-read', add_google_calendar_secrets) app.connect('linkcheck-process-uri', rewrite_github_anchor) + app.connect('autodoc-process-docstring', qt_docstrings) + logger = logging.getLogger("sphinx") + + warning_handler, *_ = [ + h for h in logger.handlers + if isinstance(h, sphinx_logging.WarningStreamHandler) + ] + warning_handler.filters.insert(0, FilterSphinxWarnings(app)) def get_attributes(item, obj, modulename): diff --git a/docs/developers/architecture/app_model.md b/docs/developers/architecture/app_model.md index 0fc48d9ea..7e450f169 100644 --- a/docs/developers/architecture/app_model.md +++ b/docs/developers/architecture/app_model.md @@ -37,7 +37,7 @@ Currently, the primary purpose of the `app` is to compose the following [commands](app-model-commands) (the actual callable objects) that have been registered with the application. Accessible via `app.commands`. * {class}`~app_model.registries.MenusRegistry`: maintains all of the - [menus and submenus](appp-model-menus) that have been registered with the application. + [menus and submenus](app-model-menus) that have been registered with the application. Accessible via `app.menus`. * {class}`~app_model.registries.KeyBindingsRegistry`: maintains the association between a [KeyBinding](app-model-keybindings) and a command ID in the diff --git a/docs/naps/9-multiple-canvases.md b/docs/naps/9-multiple-canvases.md index 1aaad7399..31726dbd0 100644 --- a/docs/naps/9-multiple-canvases.md +++ b/docs/naps/9-multiple-canvases.md @@ -75,7 +75,7 @@ Providing native support in napari would allow developers to more easily create * There will be no possibility of a viewer with no canvases. * Users shall be able to add, remove, and (maybe[^maybe-rearrange]) rearrange canvases. -[^maybe-rearrange]: Exact UI/UX may is yet to be decided, see [UI Architecture](#UI-Design-and-Architecture) for some discussion. +[^maybe-rearrange]: Exact UI/UX may is yet to be decided, see [UI Architecture](#ui-design-and-architecture) for some discussion. ### Design Considerations & Decisions Part of this design document is intended to capture the desired behavior and prevent scope creep. At the extreme “multiple canvases” can be achieved with “multiple viewers”. Therefore we need to draw a line somewhere to differentiate a “canvas” from a “viewer”. [^napari-lite] @@ -96,10 +96,9 @@ In addition to maintaining the model-view-controller (MVC) architecture of napar ### Architecture napari architecture is based on the MVC pattern. The model layer comprises a `ViewerModel` and a list of Layer models (subclasses of a base `Layer`). There are seven layer types, each with a corresponding view type. Currently models and views are paired 1:1, and the correlation is stored in a map (`layer_to_visual`) on the `VispyCanvas`. Figure 1 shows the class relationships for the base model types and the Image layer types (for brevity - other layer types have similar connectivity). -```{image} _static/multicanvas-napari-architecture-today.png ---- -name: fig-1 ---- +```{figure} _static/multicanvas-napari-architecture-today.png +:name: nap-9-fig-1 + Fig. 1: napari architecture today. ``` @@ -119,10 +118,9 @@ Figure 2 shows proposed changes (in orange) to the architecture to support multi * Callbacks (interaction, events) will need to be specifically connected to individual `CanvasModel` objects where relevant (dims, camera) rather than the `ViewerModel`. -```{image} _static/multicanvas-napari-architecture-tomorrow.png ---- -name: fig-2 ---- +```{figure} _static/multicanvas-napari-architecture-tomorrow.png +:name: nap-9-fig-2 + Fig. 2: napari architecture tomorrow, with proposed changes from this NAP highlighted in orange. ``` @@ -165,7 +163,7 @@ Slice state for each layer is currently stored on the Layer model. Again, see [N > [name=Ashley A] ### UI Design and Architecture -Specific UI design and architecture remains to be determined. This will be explored as part of step 4 in the [Implementation Plan](#Implementation). UI design needs additional refinement and exploration, and this is expected to continue after basic/core implementation propsed in this NAP is complete. UI changes may also be described in a separate NAP along with a discussion of convenience functions and affordances for common operations. Some placeholder or experimental code will be used in the meantime as a prototype implementation. +Specific UI design and architecture remains to be determined. This will be explored as part of step 4 in the [Implementation Plan](#implementation). UI design needs additional refinement and exploration, and this is expected to continue after basic/core implementation propsed in this NAP is complete. UI changes may also be described in a separate NAP along with a discussion of convenience functions and affordances for common operations. Some placeholder or experimental code will be used in the meantime as a prototype implementation. Some open questions here are (for example): * Should each canvas also have visible dims sliders, or can we keep one set of dims sliders that changes based on the active (selected) canvas? @@ -221,7 +219,7 @@ See other image viewers for examples for multiple canvases (mostly demonstrating * Update main widget as `ViewerModel` “active” canvas changes, storing additional canvases and swapping them out as necessary 4. Update `QtViewer` to show multiple canvases simultaneously - * This is exploratory work at the moment, see [UI Architecture](#UI-Design-and-Architecture) section below + * This is exploratory work at the moment, see [UI Architecture](#ui-design-and-architecture) section below [^async-only]: Depending on the timeline and prototype implementation, it may be acceptable/preferable for multi-canvas feature to rely on (currently experimental) async slicing ([see NAP-4](https://napari.org/stable/naps/4-async-slicing.html)). diff --git a/docs/release/release_0_4_19.md b/docs/release/release_0_4_19.md index 6ee78300a..5a8bbd3a9 100644 --- a/docs/release/release_0_4_19.md +++ b/docs/release/release_0_4_19.md @@ -69,7 +69,7 @@ labels_layer = viewer.add_labels( ) ``` -See the ["Deprecations" section below](#Deprecations) for more information on +See the ["Deprecations" section below](#deprecations) for more information on the new API. ([#6542](https://github.com/napari/napari/pull/6542)) ### More on colormaps! diff --git a/docs/tutorials/processing/dask.md b/docs/tutorials/processing/dask.md index 730c6fecd..f5318418b 100644 --- a/docs/tutorials/processing/dask.md +++ b/docs/tutorials/processing/dask.md @@ -205,7 +205,7 @@ directory. The dataset is 3.69 GB unzipped. ``` While we could use plain `dask` through `delayed`, as we have shown above, we -will [make our lives easier](make-your-life-easier-with-dask-image) here and use +will [make our lives easier](#make-your-life-easier-with-dask-image) here and use `dask-image`. Using [dask_image.imread](https://image.dask.org/en/latest/dask_image.imread.html#module-dask_image.imread), @@ -326,4 +326,3 @@ ready to show you the result on demand! - [Documentation on dask.delayed](https://docs.dask.org/en/latest/delayed.html) - [Dask working notes on dask-image](https://blog.dask.org/2019/06/20/load-image-data) - [Dask working notes on image processing with `dask.array.map_blocks`](https://blog.dask.org/2019/08/09/image-itk) -- [](brain_dataset_tutorial.md) diff --git a/requirements.txt b/requirements.txt index 2fa4cb8c0..857e139b3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,5 +10,5 @@ sphinx_autodoc_typehints==1.12.0 myst-nb napari-sphinx-theme>=0.3.0 matplotlib -lxml[html_clean] +lxml_html_clean imageio-ffmpeg