Skip to content

Commit ccb1dac

Browse files
authored
fix: revert watchfiles to optional-dependency (#118)
1 parent 517c45a commit ccb1dac

File tree

8 files changed

+49
-10
lines changed

8 files changed

+49
-10
lines changed

.changeset/itchy-dolphins-kick.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
"anywidget": patch
2+
"anywidget": minor
33
---
44

55
fix: replace deprecated `ipykernel.comm.Comm` with `comm` module

.changeset/sixty-mirrors-buy.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"anywidget": patch
3+
---
4+
5+
fix: revert `watchfiles` to optional-dependency

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Learn more in
2525
may be installed with `pip`:
2626

2727
```bash
28-
pip install anywidget
28+
pip install "anywidget[dev]"
2929
```
3030

3131
It is also available on

anywidget/_util.py

+22-3
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,27 @@ def get_repr_metadata() -> dict:
164164
return {_WIDGET_MIME_TYPE: {"colab": {"custom_widget_manager": {"url": url}}}}
165165

166166

167+
def _should_start_thread(path: pathlib.Path) -> bool:
168+
if "site-packages" in path.parts:
169+
# file is inside site-packages, likely not a local development install
170+
return False
171+
172+
try:
173+
import watchfiles # noqa: F401
174+
except ImportError:
175+
import warnings
176+
177+
warnings.warn(
178+
"anywidget: Live-reloading feature is disabled."
179+
" To enable, please install the 'watchfiles' package.",
180+
stacklevel=2,
181+
)
182+
183+
return False
184+
185+
return True
186+
187+
167188
def try_file_contents(x: Any) -> FileContents | None:
168189
"""Try to coerce x into a FileContents object."""
169190
if not isinstance(x, (str, pathlib.Path)):
@@ -175,11 +196,9 @@ def try_file_contents(x: Any) -> FileContents | None:
175196
with contextlib.suppress(OSError):
176197
maybe_path = pathlib.Path(maybe_path).resolve().absolute()
177198
if maybe_path.is_file():
178-
# Start a watch thread if file is outside of site-packages
179-
# (i.e., likely a development install)
180199
return FileContents(
181200
path=maybe_path,
182-
start_thread="site-packages" not in maybe_path.parts,
201+
start_thread=_should_start_thread(maybe_path),
183202
)
184203

185204
return None

docs/src/pages/blog/anywidget-02.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ _TL;DR: **anywidget** v0.2 brings modern web development to Jupyter. You can now
1313
use a **file path** to enable **anywidget**'s integrated Hot Module Replacement (HMR):_
1414

1515
```sh
16-
pip install --upgrade anywidget
16+
pip install --upgrade "anywidget[dev]"
1717
```
1818

1919
```python
@@ -193,7 +193,7 @@ to allow for the special JSX syntax (e.g., `<App />`).
193193
To start using **anywidget** v0.2, upgrade your package using pip:
194194

195195
```sh
196-
pip install --upgrade anywidget
196+
pip install --upgrade "anywidget[dev]"
197197
```
198198

199199
I encourage you to explore the new features in **anywidget** v0.2 and experience the

docs/src/pages/en/getting-started.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ ecosystem, allowing your widget to run automatically in **Jupyter Notebooks**,
2828
## Example
2929

3030
```
31-
pip install anywidget
31+
pip install "anywidget[dev]"
3232
```
3333

3434
```python

pyproject.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ dependencies = [
1717
"importlib-metadata ; python_version < '3.8'",
1818
"typing-extensions>=4.2.0",
1919
"psygnal>=0.8.1",
20-
"watchfiles>=0.18.0",
2120
]
2221

2322
[project.optional-dependencies]
@@ -29,7 +28,8 @@ test = [
2928
"ruff",
3029
]
3130
dev = [
32-
"comm",
31+
"comm>=0.1.0",
32+
"watchfiles>=0.18.0",
3333
]
3434

3535
[project.urls]

tests/test_utils.py

+15
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,18 @@ def test_try_file_contents(tmp_path: pathlib.Path):
120120
file_contents = try_file_contents(bar)
121121
assert isinstance(file_contents, FileContents)
122122
assert file_contents._background_thread is None
123+
124+
125+
def test_try_file_contents_warns(
126+
monkeypatch: pytest.MonkeyPatch, tmp_path: pathlib.Path
127+
):
128+
monkeypatch.setitem(sys.modules, "watchfiles", None)
129+
130+
foo = tmp_path / "foo.txt"
131+
foo.write_text("foo")
132+
133+
with pytest.warns(UserWarning, match="anywidget:"):
134+
file_contents = try_file_contents(foo)
135+
136+
assert isinstance(file_contents, FileContents)
137+
assert file_contents._background_thread is None

0 commit comments

Comments
 (0)