-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path_guidata_backends_shim.py
More file actions
134 lines (109 loc) · 4.19 KB
/
Copy path_guidata_backends_shim.py
File metadata and controls
134 lines (109 loc) · 4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# Copyright (c) DataLab Platform Developers, BSD 3-Clause License
# See LICENSE file for details
# @shim-registry: guidata-backends
"""Monkey-patch the released ``guidata`` to add the pluggable backend API.
The DataLab-Web team contributed a pluggable UI backend to guidata
(see ``guidata/dataset/backends.py``). Until a guidata release ships
with that change, this shim adds the same API on top of whichever
``guidata`` version ``micropip`` installed in Pyodide.
Idempotent — safe to import twice. When the installed guidata already
provides ``guidata.dataset.backends``, this module is a no-op.
"""
from __future__ import annotations
# This module shims a feature that newer ``guidata`` releases will ship
# natively (the ``guidata.dataset.backends`` registry). All the deferred
# imports and the ``DataSet._dlw_backend_patched_`` flag exist precisely
# so the patching is idempotent and reuses the upstream implementation
# when it becomes available.
# pylint: disable=import-outside-toplevel,protected-access,import-error
import sys
import types
from typing import Any, Callable
def _ensure_backends_module() -> Any:
try:
from guidata.dataset import backends # type: ignore[import-not-found]
return backends
except ImportError:
pass
mod = types.ModuleType("guidata.dataset.backends")
mod.__doc__ = "Pluggable UI backend registry (DataLab-Web shim)."
handlers: dict[str, Callable[..., Any]] = {}
def set_handler(name: str, handler: Callable[..., Any]) -> None:
handlers[name] = handler
def get_handler(name: str) -> Callable[..., Any] | None:
return handlers.get(name)
def has_handler(name: str) -> bool:
return name in handlers
def clear_handler(name: str) -> None:
handlers.pop(name, None)
def clear_all_handlers() -> None:
handlers.clear()
mod.set_handler = set_handler # type: ignore[attr-defined]
mod.get_handler = get_handler # type: ignore[attr-defined]
mod.has_handler = has_handler # type: ignore[attr-defined]
mod.clear_handler = clear_handler # type: ignore[attr-defined]
mod.clear_all_handlers = clear_all_handlers # type: ignore[attr-defined]
mod.__all__ = [ # type: ignore[attr-defined]
"set_handler",
"get_handler",
"has_handler",
"clear_handler",
"clear_all_handlers",
]
sys.modules["guidata.dataset.backends"] = mod
# Expose as attribute on the parent package too.
import guidata.dataset as _gds_pkg
setattr(_gds_pkg, "backends", mod)
return mod
def _patch_dataset_methods() -> None:
"""Wire the backend registry into :class:`DataSet.edit/view`."""
from guidata.dataset import datatypes
from guidata.dataset.backends import get_handler
DataSet = datatypes.DataSet
if getattr(DataSet, "_dlw_backend_patched_", False):
return
original_edit = DataSet.edit
def edit(self, parent=None, apply=None, wordwrap=True, size=None, object_name=None):
handler = get_handler("edit_dataset")
if handler is not None:
return handler(
self,
parent=parent,
apply=apply,
wordwrap=wordwrap,
size=size,
object_name=object_name,
)
return original_edit(
self,
parent=parent,
apply=apply,
wordwrap=wordwrap,
size=size,
object_name=object_name,
)
async def edit_async(
self, parent=None, apply=None, wordwrap=True, size=None, object_name=None
):
handler = get_handler("edit_dataset_async")
if handler is not None:
return await handler(
self,
parent=parent,
apply=apply,
wordwrap=wordwrap,
size=size,
object_name=object_name,
)
return self.edit(
parent=parent,
apply=apply,
wordwrap=wordwrap,
size=size,
object_name=object_name,
)
DataSet.edit = edit
DataSet.edit_async = edit_async
DataSet._dlw_backend_patched_ = True
_ensure_backends_module()
_patch_dataset_methods()