-
Notifications
You must be signed in to change notification settings - Fork 950
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add weakref with opt in automatic widget deletion using 'enable_weakr…
…eference'.
- Loading branch information
Alan Fleming
committed
May 26, 2024
1 parent
4690a5d
commit 448c76d
Showing
4 changed files
with
347 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 72 additions & 20 deletions
92
python/ipywidgets/ipywidgets/widgets/tests/test_widget_box.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,85 @@ | ||
# Copyright (c) Jupyter Development Team. | ||
# Distributed under the terms of the Modified BSD License. | ||
|
||
from unittest import TestCase | ||
import gc | ||
import weakref | ||
|
||
import pytest | ||
from traitlets import TraitError | ||
|
||
import ipywidgets as widgets | ||
|
||
|
||
class TestBox(TestCase): | ||
def test_box_construction(): | ||
box = widgets.Box() | ||
assert box.get_state()["children"] == [] | ||
|
||
def test_construction(self): | ||
box = widgets.Box() | ||
assert box.get_state()['children'] == [] | ||
|
||
def test_construction_with_children(self): | ||
html = widgets.HTML('some html') | ||
slider = widgets.IntSlider() | ||
box = widgets.Box([html, slider]) | ||
children_state = box.get_state()['children'] | ||
assert children_state == [ | ||
widgets.widget._widget_to_json(html, None), | ||
widgets.widget._widget_to_json(slider, None), | ||
] | ||
def test_box_construction_with_children(): | ||
html = widgets.HTML("some html") | ||
slider = widgets.IntSlider() | ||
box = widgets.Box([html, slider]) | ||
children_state = box.get_state()["children"] | ||
assert children_state == [ | ||
widgets.widget._widget_to_json(html, None), | ||
widgets.widget._widget_to_json(slider, None), | ||
] | ||
|
||
def test_construction_style(self): | ||
box = widgets.Box(box_style='warning') | ||
assert box.get_state()['box_style'] == 'warning' | ||
|
||
def test_construction_invalid_style(self): | ||
with self.assertRaises(TraitError): | ||
widgets.Box(box_style='invalid') | ||
def test_box_construction_style(): | ||
box = widgets.Box(box_style="warning") | ||
assert box.get_state()["box_style"] == "warning" | ||
|
||
|
||
def test_construction_invalid_style(): | ||
with pytest.raises(TraitError): | ||
widgets.Box(box_style="invalid") | ||
|
||
|
||
def test_box_validate_mode(): | ||
slider = widgets.IntSlider() | ||
closed_button = widgets.Button() | ||
closed_button.close() | ||
with pytest.raises(TraitError, match="Invalid or closed items found.*"): | ||
widgets.Box( | ||
children=[closed_button, slider, "Not a widget"] | ||
) | ||
box = widgets.Box( | ||
children=[closed_button, slider, "Not a widget"], | ||
validate_mode="log_error", | ||
) | ||
assert len (box.children) == 1, "Invalid items should be dropped." | ||
assert slider in box.children | ||
|
||
box.validate_mode = "raise" | ||
with pytest.raises(TraitError): | ||
box.children += ("Not a widget", closed_button) | ||
|
||
|
||
def test_box_gc(): | ||
widgets.VBox._active_widgets | ||
widgets.enable_weakreference() | ||
# Test Box gc collected and children lifecycle managed. | ||
try: | ||
deleted = False | ||
|
||
class TestButton(widgets.Button): | ||
def my_click(self, b): | ||
pass | ||
|
||
button = TestButton(description="button") | ||
button.on_click(button.my_click) | ||
|
||
b = widgets.VBox(children=[button]) | ||
|
||
def on_delete(): | ||
nonlocal deleted | ||
deleted = True | ||
|
||
weakref.finalize(b, on_delete) | ||
del b | ||
gc.collect() | ||
assert deleted | ||
widgets.VBox._active_widgets | ||
finally: | ||
widgets.disable_weakreference() |
Oops, something went wrong.