Skip to content

misc doc improvements #409

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions docs/source/_exts/only_warn_on_broken_internal_refs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from docutils import nodes
from sphinx import addnodes
from sphinx.application import Sphinx
from sphinx.transforms.post_transforms import SphinxPostTransform
from sphinx.util import logging


logger = logging.getLogger(__name__)


def is_public_internal_ref_target(target: str) -> bool:
return target.startswith("idom.") and not target.rsplit(".", 1)[-1].startswith("_")


class OnlyWarnOnBrokenInternalRefs(SphinxPostTransform):
"""
Warns about broken cross-reference links, but only for idom.
This is very similar to the sphinx option ``nitpicky=True`` (see
:py:class:`sphinx.transforms.post_transforms.ReferencesResolver`), but there
is no way to restrict that option to a specific package.
"""

# this transform needs to happen before ReferencesResolver
default_priority = 5

def run(self) -> None:
for node in self.document.traverse(addnodes.pending_xref):
target = node["reftarget"]

if is_public_internal_ref_target(target):
# let the domain try to resolve the reference
found_ref = self.env.domains[node["refdomain"]].resolve_xref(
self.env,
node.get("refdoc", self.env.docname),
self.app.builder,
node["reftype"],
target,
node,
nodes.TextElement("", ""),
)

# warn if resolve_xref did not return or raised
if not found_ref:
logger.warning(
f"API link {target} is broken.", location=node, type="ref"
)


def setup(app: Sphinx) -> None:
app.add_post_transform(OnlyWarnOnBrokenInternalRefs)
6 changes: 3 additions & 3 deletions docs/source/architectural-patterns.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ As a result, IDOM was developed to help solve these problems.
Ecosystem Independence
----------------------

IDOM has a flexible set of :ref:`core abstractions <Core Concepts>` that allow it to
interface with its peers. At the time of writing Jupyter, Dash, and Bokeh (via Panel)
are supported, while Streamlit is in the works:
IDOM has a flexible set of :ref:`Core Abstractions` that allow it to interface with its
peers. At the time of writing Jupyter, Dash, and Bokeh (via Panel) are supported, while
Streamlit is in the works:

- idom-jupyter_ (try it now with Binder_)
- idom-dash_
Expand Down
1 change: 1 addition & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"patched_html_translator",
"widget_example",
"build_custom_js",
"only_warn_on_broken_internal_refs",
]

# Add any paths that contain templates here, relative to this directory.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
Core Concepts
=============

This section covers core features of IDOM that are used in making interactive
interfaces.
Core Abstractions
=================


Pure Components
Expand Down
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ IDOM
:hidden:
:caption: Advanced Topics

core-concepts
core-abstractions
javascript-components
architectural-patterns
specifications
Expand Down
7 changes: 3 additions & 4 deletions docs/source/life-cycle-hooks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,9 @@ use_ref

ref_container = use_ref(initial_value)

Returns a mutable :class:`~idom.core.hooks.Ref` object that has a single
:attr:`~idom.core.hooks.Ref.current` attribute that at first contains the
``initial_state``. The identity of the ``Ref`` object will be preserved for the lifetime
of the component.
Returns a mutable :class:`~idom.utils.Ref` object that has a single
:attr:`~idom.utils.Ref.current` attribute that at first contains the ``initial_state``.
The identity of the ``Ref`` object will be preserved for the lifetime of the component.

A ``Ref`` is most useful if you need to incur side effects since updating its
``.current`` attribute doesn't trigger a re-render of the component. You'll often use this
Expand Down
2 changes: 1 addition & 1 deletion docs/source/roadmap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Roadmap
they need purpose-built
`compiler plugins <https://github.com/idom-team/idom-react-component-cookiecutter/blob/1cc31b8690f84cb90dd861f2f47873b1d5711f74/%7B%7Bcookiecutter.repository_name%7D%7D/js/rollup.config.js>`__
that will convert imports of React to point to the location ``react.js`` will be
once the component has been loaded via :class:`~idom.client.module.Module`.
once the component has been loaded via ``idom.client.module.Module``

Ideally developers of custom components should be able to operate in isolation
without assuming anything about the environment they are running in. This has the
Expand Down
14 changes: 12 additions & 2 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,18 @@ def test_docs(session: Session) -> None:
"""Verify that the docs build and that doctests pass"""
install_requirements_file(session, "build-docs")
install_idom_dev(session, extras="all")
session.run("sphinx-build", "-T", "-b", "html", "docs/source", "docs/build")
session.run("sphinx-build", "-T", "-b", "doctest", "docs/source", "docs/build")
session.run(
"sphinx-build",
"-a", # re-write all output files
"-T", # show full tracebacks
"-W", # turn warnings into errors
"--keep-going", # complete the build, but still report warnings as errors
"-b",
"html",
"docs/source",
"docs/build",
)
session.run("sphinx-build", "-b", "doctest", "docs/source", "docs/build")


@nox.session
Expand Down
4 changes: 2 additions & 2 deletions src/idom/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
"""The location IDOM will use to store its client application

This directory **MUST** be treated as a black box. Downstream applications **MUST NOT**
assume anything about the structure of this directory see :mod:`idom.client.manage` for
a set of publically available APIs for working with the client.
assume anything about the structure of this directory see :mod:`idom.web.module` for a
set of publically available APIs for working with the client.
"""

IDOM_FEATURE_INDEX_AS_DEFAULT_KEY = _Option(
Expand Down
3 changes: 3 additions & 0 deletions src/idom/core/dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ async def dispatch_single_view(
send: SendCoroutine,
recv: RecvCoroutine,
) -> None:
"""Run a dispatch loop for a single view instance"""
with layout:
async with create_task_group() as task_group:
task_group.start_soon(_single_outgoing_loop, layout, send)
Expand All @@ -50,6 +51,7 @@ async def dispatch_single_view(
async def create_shared_view_dispatcher(
layout: Layout, run_forever: bool = False
) -> AsyncIterator[_SharedViewDispatcherFuture]:
"""Enter a dispatch context where all subsequent view instances share the same state"""
with layout:
(
dispatch_shared_view,
Expand Down Expand Up @@ -94,6 +96,7 @@ def dispatch_shared_view_soon(
def ensure_shared_view_dispatcher_future(
layout: Layout,
) -> Tuple[Future[None], SharedViewDispatcher]:
"""Ensure the future of a dispatcher created by :func:`create_shared_view_dispatcher`"""
dispatcher_future: Future[SharedViewDispatcher] = Future()

async def dispatch_shared_view_forever() -> None:
Expand Down
4 changes: 4 additions & 0 deletions src/idom/core/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class LayoutEvent(NamedTuple):


class Layout:
"""Responsible for "rendering" components. That is, turning them into VDOM."""

__slots__ = [
"root",
Expand Down Expand Up @@ -94,10 +95,12 @@ def __exit__(self, *exc: Any) -> None:
return None

def update(self, component: "AbstractComponent") -> None:
"""Schedule a re-render of a component in the layout"""
self._rendering_queue.put(component)
return None

async def dispatch(self, event: LayoutEvent) -> None:
"""Dispatch an event to the targeted handler"""
# It is possible for an element in the frontend to produce an event
# associated with a backend model that has been deleted. We only handle
# events if the element and the handler exist in the backend. Otherwise
Expand All @@ -115,6 +118,7 @@ async def dispatch(self, event: LayoutEvent) -> None:
)

async def render(self) -> LayoutUpdate:
"""Await the next available render. This will block until a component is updated"""
while True:
component = await self._rendering_queue.get()
if id(component) in self._model_state_by_component_id:
Expand Down
20 changes: 10 additions & 10 deletions src/idom/server/prefab.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ def multiview_server(
) -> Tuple[MultiViewMount, Server[_App]]:
"""Set up a server where views can be dynamically added.

In other words this allows the user to work with IDOM in an imperative manner.
Under the hood this uses the :func:`idom.widgets.common.multiview` function to
add the views on the fly.
In other words this allows the user to work with IDOM in an imperative manner. Under
the hood this uses the :func:`idom.widgets.multiview` function to add the views on
the fly.

Parameters:
server: The server type to start up as a daemon
Expand All @@ -93,8 +93,8 @@ def multiview_server(
app: Optionally provide a prexisting application to register to

Returns:
The server instance and a function for adding views.
See :func:`idom.widgets.common.multiview` for details.
The server instance and a function for adding views. See
:func:`idom.widgets.multiview` for details.
"""
mount, component = multiview()

Expand Down Expand Up @@ -123,9 +123,9 @@ def hotswap_server(
) -> Tuple[MountFunc, Server[_App]]:
"""Set up a server where views can be dynamically swapped out.

In other words this allows the user to work with IDOM in an imperative manner.
Under the hood this uses the :func:`idom.widgets.common.hotswap` function to
swap the views on the fly.
In other words this allows the user to work with IDOM in an imperative manner. Under
the hood this uses the :func:`idom.widgets.hotswap` function to swap the views on
the fly.

Parameters:
server: The server type to start up as a daemon
Expand All @@ -137,8 +137,8 @@ def hotswap_server(
sync_views: Whether to update all displays with newly mounted components

Returns:
The server instance and a function for swapping views.
See :func:`idom.widgets.common.hotswap` for details.
The server instance and a function for swapping views. See
:func:`idom.widgets.hotswap` for details.
"""
mount, component = hotswap(update_on_change=sync_views)

Expand Down
4 changes: 1 addition & 3 deletions src/idom/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ class Ref(Generic[_RefValue]):
incur side effects. Generally refs should be avoided if possible, but sometimes
they are required.

Attributes:
current: The present value.

Notes:
You can compare the contents for two ``Ref`` objects using the ``==`` operator.
"""
Expand All @@ -28,6 +25,7 @@ class Ref(Generic[_RefValue]):

def __init__(self, initial_value: _RefValue) -> None:
self.current = initial_value
"""The present value"""

def set_current(self, new: _RefValue) -> _RefValue:
"""Set the current value and return what is now the old value
Expand Down
2 changes: 1 addition & 1 deletion src/idom/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ def World():
Notebook where one might want multiple active views which can all be interacted
with at the same time.

Refer to :func:`idom.server.imperative_server_mount` for a reference usage.
See :func:`idom.server.prefab.multiview_server` for a reference usage.
"""
views: Dict[str, ComponentConstructor] = {}

Expand Down