pyglove 0.4.5.dev202410100808__py3-none-any.whl → 0.4.5.dev202410110808__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyglove/core/__init__.py +1 -0
- pyglove/core/object_utils/__init__.py +2 -0
- pyglove/core/object_utils/formatting.py +16 -0
- pyglove/core/object_utils/formatting_test.py +9 -0
- pyglove/core/object_utils/value_location.py +246 -3
- pyglove/core/object_utils/value_location_test.py +363 -74
- pyglove/core/symbolic/base_test.py +5 -5
- pyglove/core/symbolic/diff.py +18 -13
- pyglove/core/symbolic/diff_test.py +30 -29
- pyglove/core/symbolic/ref_test.py +9 -9
- pyglove/core/views/base.py +2 -0
- pyglove/core/views/base_test.py +1 -1
- pyglove/core/views/html/base.py +43 -14
- pyglove/core/views/html/base_test.py +9 -0
- pyglove/core/views/html/tree_view.py +226 -164
- pyglove/core/views/html/tree_view_test.py +138 -42
- {pyglove-0.4.5.dev202410100808.dist-info → pyglove-0.4.5.dev202410110808.dist-info}/METADATA +1 -1
- {pyglove-0.4.5.dev202410100808.dist-info → pyglove-0.4.5.dev202410110808.dist-info}/RECORD +21 -21
- {pyglove-0.4.5.dev202410100808.dist-info → pyglove-0.4.5.dev202410110808.dist-info}/LICENSE +0 -0
- {pyglove-0.4.5.dev202410100808.dist-info → pyglove-0.4.5.dev202410110808.dist-info}/WHEEL +0 -0
- {pyglove-0.4.5.dev202410100808.dist-info → pyglove-0.4.5.dev202410110808.dist-info}/top_level.txt +0 -0
pyglove/core/symbolic/diff.py
CHANGED
@@ -13,7 +13,7 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
"""Symbolic differences."""
|
15
15
|
|
16
|
-
from typing import Any, Callable,
|
16
|
+
from typing import Any, Callable, List, Optional, Tuple, Union
|
17
17
|
|
18
18
|
from pyglove.core import object_utils
|
19
19
|
from pyglove.core import typing as pg_typing
|
@@ -196,25 +196,26 @@ class Diff(PureSymbolic, pg_object.Object):
|
|
196
196
|
view: html.HtmlTreeView,
|
197
197
|
parent: Any,
|
198
198
|
root_path: object_utils.KeyPath,
|
199
|
-
css_class: Optional[Sequence[str]] = None,
|
200
199
|
**kwargs
|
201
200
|
) -> html.Html:
|
202
|
-
del parent
|
203
|
-
user_specified_css_class = css_class or []
|
204
201
|
if not bool(self):
|
205
202
|
if self.value == Diff.MISSING:
|
206
203
|
root = html.Html.element(
|
207
204
|
'span',
|
208
205
|
# CSS class already defined in HtmlTreeView.
|
209
|
-
css_class=['diff_empty']
|
206
|
+
css_class=['diff_empty']
|
210
207
|
)
|
211
208
|
else:
|
212
209
|
# When there is no diff, but the same value needs to be displayed
|
213
210
|
# we simply return the value.
|
214
|
-
root =
|
215
|
-
|
216
|
-
|
217
|
-
|
211
|
+
root = html.Html.element(
|
212
|
+
'div',
|
213
|
+
[
|
214
|
+
view.content(
|
215
|
+
self.value, parent=parent, root_path=root_path, **kwargs,
|
216
|
+
)
|
217
|
+
],
|
218
|
+
css_class=['diff_left', 'diff_right']
|
218
219
|
)
|
219
220
|
elif self.is_leaf:
|
220
221
|
root = html.Html.element(
|
@@ -241,7 +242,7 @@ class Diff(PureSymbolic, pg_object.Object):
|
|
241
242
|
css_class=['diff_right'],
|
242
243
|
) if self.right != Diff.MISSING else None,
|
243
244
|
],
|
244
|
-
css_class=['diff_value']
|
245
|
+
css_class=['diff_value']
|
245
246
|
)
|
246
247
|
else:
|
247
248
|
assert isinstance(self.left, type)
|
@@ -279,10 +280,14 @@ class Diff(PureSymbolic, pg_object.Object):
|
|
279
280
|
],
|
280
281
|
css_class=[
|
281
282
|
'complex_value', view.css_class_name(self.left)
|
282
|
-
]
|
283
|
+
]
|
283
284
|
)
|
284
|
-
return root
|
285
|
+
return root
|
286
|
+
|
287
|
+
def _html_style(self) -> List[str]:
|
288
|
+
return [
|
285
289
|
"""
|
290
|
+
/* Diff styles. */
|
286
291
|
.diff .summary_title::after {
|
287
292
|
content: ' (diff)';
|
288
293
|
color: #aaa;
|
@@ -331,7 +336,7 @@ class Diff(PureSymbolic, pg_object.Object):
|
|
331
336
|
background-color: #ccffcc;
|
332
337
|
}
|
333
338
|
"""
|
334
|
-
|
339
|
+
]
|
335
340
|
|
336
341
|
|
337
342
|
# NOTE(daiyip): we add the symbolic attribute to Diff after its declaration
|
@@ -403,6 +403,26 @@ class DiffTest(unittest.TestCase):
|
|
403
403
|
color: darkred;
|
404
404
|
font-style: italic;
|
405
405
|
}
|
406
|
+
/* Value details styles. */
|
407
|
+
details.pyglove {
|
408
|
+
border: 1px solid #aaa;
|
409
|
+
border-radius: 4px;
|
410
|
+
padding: 0.5em 0.5em 0;
|
411
|
+
margin: 0.1em 0;
|
412
|
+
}
|
413
|
+
details.pyglove.special_value {
|
414
|
+
margin-bottom: 0.75em;
|
415
|
+
}
|
416
|
+
details.pyglove[open] {
|
417
|
+
padding: 0.5em 0.5em 0.5em;
|
418
|
+
}
|
419
|
+
.highlight {
|
420
|
+
background-color: Mark;
|
421
|
+
}
|
422
|
+
.lowlight {
|
423
|
+
opacity: 0.2;
|
424
|
+
}
|
425
|
+
/* Diff styles. */
|
406
426
|
.diff .summary_title::after {
|
407
427
|
content: ' (diff)';
|
408
428
|
color: #aaa;
|
@@ -450,25 +470,6 @@ class DiffTest(unittest.TestCase):
|
|
450
470
|
.diff_value .diff_right > details {
|
451
471
|
background-color: #ccffcc;
|
452
472
|
}
|
453
|
-
/* Value details styles. */
|
454
|
-
details.pyglove {
|
455
|
-
border: 1px solid #aaa;
|
456
|
-
border-radius: 4px;
|
457
|
-
padding: 0.5em 0.5em 0;
|
458
|
-
margin: 0.1em 0;
|
459
|
-
}
|
460
|
-
details.pyglove.special_value {
|
461
|
-
margin-bottom: 0.75em;
|
462
|
-
}
|
463
|
-
details.pyglove[open] {
|
464
|
-
padding: 0.5em 0.5em 0.5em;
|
465
|
-
}
|
466
|
-
.highlight {
|
467
|
-
background-color: Mark;
|
468
|
-
}
|
469
|
-
.lowlight {
|
470
|
-
opacity: 0.2;
|
471
|
-
}
|
472
473
|
</style>
|
473
474
|
"""
|
474
475
|
)
|
@@ -477,7 +478,7 @@ class DiffTest(unittest.TestCase):
|
|
477
478
|
assert_content(
|
478
479
|
pg_diff(1, 1).to_html(),
|
479
480
|
"""
|
480
|
-
<details open class="pyglove diff"><summary><div class="summary_title">Diff</div><span class="tooltip">No diff</span></summary><span class="diff_empty"></span></details>
|
481
|
+
<details open class="pyglove diff"><summary><div class="summary_title">Diff</div><span class="tooltip diff">No diff</span></summary><span class="diff_empty"></span></details>
|
481
482
|
"""
|
482
483
|
)
|
483
484
|
|
@@ -485,7 +486,7 @@ class DiffTest(unittest.TestCase):
|
|
485
486
|
assert_content(
|
486
487
|
pg_diff(1, 1, mode='both').to_html(),
|
487
488
|
"""
|
488
|
-
<span class="simple_value int
|
489
|
+
<div class="diff_left diff_right"><span class="simple_value int">1</span></div>
|
489
490
|
"""
|
490
491
|
)
|
491
492
|
# No diff complex value (diff only)
|
@@ -511,7 +512,7 @@ class DiffTest(unittest.TestCase):
|
|
511
512
|
enable_key_tooltip=False,
|
512
513
|
),
|
513
514
|
"""
|
514
|
-
<details open class="pyglove diff"><summary><div class="summary_title">Foo(...)</div></summary><div class="
|
515
|
+
<details open class="pyglove diff"><summary><div class="summary_title">Foo(...)</div></summary><div class="diff_left diff_right"><div class="complex_value foo"><table><tr><td><span class="object_key str">x</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">y</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">List(...)</div></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span></td><td><div><details class="pyglove foo"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key str">x</span></td><td><div><span class="simple_value int">2</span></div></td></tr><tr><td><span class="object_key str">y</span></td><td><div><span class="simple_value int">3</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr></table></div></div></details>
|
515
516
|
"""
|
516
517
|
)
|
517
518
|
|
@@ -530,7 +531,7 @@ class DiffTest(unittest.TestCase):
|
|
530
531
|
enable_key_tooltip=False,
|
531
532
|
),
|
532
533
|
"""
|
533
|
-
<details open class="pyglove diff"><summary><div class="summary_title">List</div></summary><div class="complex_value list"><table><tr><td><span class="object_key no_diff_key">0</span><span class="tooltip">[0]</span></td><td><span class="simple_value int
|
534
|
+
<details open class="pyglove diff"><summary><div class="summary_title">List</div></summary><div class="complex_value list"><table><tr><td><span class="object_key int no_diff_key">0</span><span class="tooltip key-path">[0]</span></td><td><div class="diff_left diff_right"><span class="simple_value int">0</span></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">[1]</span></td><td><div class="diff_value"><div class="diff_left"><span class="simple_value int">1</span></div><div class="diff_right"><span class="simple_value int">2</span></div></div></td></tr><tr><td><span class="object_key int">2</span><span class="tooltip key-path">[2]</span></td><td><div class="diff_value"><div class="diff_left"><span class="simple_value int">2</span></div></div></td></tr></table></div></details>
|
534
535
|
"""
|
535
536
|
)
|
536
537
|
|
@@ -541,7 +542,7 @@ class DiffTest(unittest.TestCase):
|
|
541
542
|
enable_key_tooltip=False,
|
542
543
|
),
|
543
544
|
"""
|
544
|
-
<details open class="pyglove diff"><summary><div class="summary_title">dict</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key no_diff_key">x</span><span class="tooltip">x</span></td><td><span class="simple_value int
|
545
|
+
<details open class="pyglove diff"><summary><div class="summary_title">dict</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str no_diff_key">x</span><span class="tooltip key-path">x</span></td><td><div class="diff_left diff_right"><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">y</span><span class="tooltip key-path">y</span></td><td><div class="diff_value"><div class="diff_left"><span class="simple_value int">2</span></div><div class="diff_right"><span class="simple_value int">3</span></div></div></td></tr><tr><td><span class="object_key str">z</span><span class="tooltip key-path">z</span></td><td><div class="diff_value"><div class="diff_left"><span class="simple_value int">3</span></div></div></td></tr><tr><td><span class="object_key str">w</span><span class="tooltip key-path">w</span></td><td><div class="diff_value"><div class="diff_right"><span class="simple_value int">4</span></div></div></td></tr></table></div></details>
|
545
546
|
"""
|
546
547
|
)
|
547
548
|
|
@@ -556,7 +557,7 @@ class DiffTest(unittest.TestCase):
|
|
556
557
|
enable_key_tooltip=False,
|
557
558
|
),
|
558
559
|
"""
|
559
|
-
<details open class="pyglove diff"><summary><div class="summary_title">Foo</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key">x</span><span class="tooltip">x</span></td><td><div class="diff_value"><div class="diff_left"><span class="simple_value int">2</span></div><div class="diff_right"><span class="simple_value int">1</span></div></div></td></tr><tr><td><span class="object_key">y</span><span class="tooltip">y</span></td><td><details class="pyglove diff"><summary><div class="summary_title">Foo</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key">x</span><span class="tooltip">y.x</span></td><td><div class="diff_value"><div class="diff_left"><span class="simple_value int">3</span></div><div class="diff_right"><span class="simple_value int">2</span></div></div></td></tr><tr><td><span class="object_key no_diff_key">y</span><span class="tooltip">y.y</span></td><td><span class="simple_value int
|
560
|
+
<details open class="pyglove diff"><summary><div class="summary_title">Foo</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key str">x</span><span class="tooltip key-path">x</span></td><td><div class="diff_value"><div class="diff_left"><span class="simple_value int">2</span></div><div class="diff_right"><span class="simple_value int">1</span></div></div></td></tr><tr><td><span class="object_key str">y</span><span class="tooltip key-path">y</span></td><td><details class="pyglove diff"><summary><div class="summary_title">Foo</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key str">x</span><span class="tooltip key-path">y.x</span></td><td><div class="diff_value"><div class="diff_left"><span class="simple_value int">3</span></div><div class="diff_right"><span class="simple_value int">2</span></div></div></td></tr><tr><td><span class="object_key str no_diff_key">y</span><span class="tooltip key-path">y.y</span></td><td><div class="diff_left diff_right"><span class="simple_value int">3</span></div></td></tr></table></div></details></td></tr></table></div></details>
|
560
561
|
"""
|
561
562
|
)
|
562
563
|
|
@@ -571,7 +572,7 @@ class DiffTest(unittest.TestCase):
|
|
571
572
|
enable_key_tooltip=False,
|
572
573
|
),
|
573
574
|
"""
|
574
|
-
<div class="diff_value"><div class="diff_left"><details class="pyglove foo"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key">x</span></td><td><span class="simple_value int">2</span></td></tr><tr><td><span class="object_key">y</span></td><td><details class="pyglove foo"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key">x</span></td><td><span class="simple_value int">3</span></td></tr><tr><td><span class="object_key">y</span></td><td><span class="simple_value int">3</span></td></tr></table></div></details></td></tr></table></div></details></div><div class="diff_right"><details class="pyglove bar"><summary><div class="summary_title">Bar(...)</div></summary><div class="complex_value bar"><table><tr><td><span class="object_key">x</span></td><td><span class="simple_value int">2</span></td></tr><tr><td><span class="object_key">y</span></td><td><details class="pyglove foo"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key">x</span></td><td><span class="simple_value int">3</span></td></tr><tr><td><span class="object_key">y</span></td><td><span class="simple_value int">3</span></td></tr></table></div></details></td></tr></table></div></details></div></div>
|
575
|
+
<div class="diff_value"><div class="diff_left"><details class="pyglove foo"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key str">x</span></td><td><div><span class="simple_value int">2</span></div></td></tr><tr><td><span class="object_key str">y</span></td><td><div><details class="pyglove foo"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key str">x</span></td><td><div><span class="simple_value int">3</span></div></td></tr><tr><td><span class="object_key str">y</span></td><td><div><span class="simple_value int">3</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div><div class="diff_right"><details class="pyglove bar"><summary><div class="summary_title">Bar(...)</div></summary><div class="complex_value bar"><table><tr><td><span class="object_key str">x</span></td><td><div><span class="simple_value int">2</span></div></td></tr><tr><td><span class="object_key str">y</span></td><td><div><details class="pyglove foo"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key str">x</span></td><td><div><span class="simple_value int">3</span></div></td></tr><tr><td><span class="object_key str">y</span></td><td><div><span class="simple_value int">3</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></div>
|
575
576
|
"""
|
576
577
|
)
|
577
578
|
|
@@ -586,7 +587,7 @@ class DiffTest(unittest.TestCase):
|
|
586
587
|
enable_key_tooltip=False,
|
587
588
|
),
|
588
589
|
"""
|
589
|
-
<details open class="pyglove diff"><summary><div class="summary_title">Foo | Bar</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key no_diff_key">x</span><span class="tooltip">x</span></td><td><span class="simple_value int
|
590
|
+
<details open class="pyglove diff"><summary><div class="summary_title">Foo | Bar</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key str no_diff_key">x</span><span class="tooltip key-path">x</span></td><td><div class="diff_left diff_right"><span class="simple_value int">2</span></div></td></tr><tr><td><span class="object_key str">y</span><span class="tooltip key-path">y</span></td><td><details class="pyglove diff"><summary><div class="summary_title">Foo | Bar</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key str no_diff_key">x</span><span class="tooltip key-path">y.x</span></td><td><div class="diff_left diff_right"><span class="simple_value int">3</span></div></td></tr><tr><td><span class="object_key str no_diff_key">y</span><span class="tooltip key-path">y.y</span></td><td><div class="diff_left diff_right"><span class="simple_value int">3</span></div></td></tr></table></div></details></td></tr></table></div></details>
|
590
591
|
"""
|
591
592
|
)
|
592
593
|
|
@@ -601,7 +602,7 @@ class DiffTest(unittest.TestCase):
|
|
601
602
|
enable_key_tooltip=False,
|
602
603
|
),
|
603
604
|
"""
|
604
|
-
<details open class="pyglove diff"><summary><div class="summary_title">Foo | Bar</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key">x</span><span class="tooltip">x</span></td><td><div class="diff_value"><div class="diff_left"><span class="simple_value int">2</span></div><div class="diff_right"><span class="simple_value int">3</span></div></div></td></tr><tr><td><span class="object_key">y</span><span class="tooltip">y</span></td><td><details class="pyglove diff"><summary><div class="summary_title">Foo | Bar</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key">x</span><span class="tooltip">y.x</span></td><td><div class="diff_value"><div class="diff_left"><span class="simple_value int">3</span></div><div class="diff_right"><span class="simple_value int">2</span></div></div></td></tr><tr><td><span class="object_key no_diff_key">y</span><span class="tooltip">y.y</span></td><td><span class="simple_value int
|
605
|
+
<details open class="pyglove diff"><summary><div class="summary_title">Foo | Bar</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key str">x</span><span class="tooltip key-path">x</span></td><td><div class="diff_value"><div class="diff_left"><span class="simple_value int">2</span></div><div class="diff_right"><span class="simple_value int">3</span></div></div></td></tr><tr><td><span class="object_key str">y</span><span class="tooltip key-path">y</span></td><td><details class="pyglove diff"><summary><div class="summary_title">Foo | Bar</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key str">x</span><span class="tooltip key-path">y.x</span></td><td><div class="diff_value"><div class="diff_left"><span class="simple_value int">3</span></div><div class="diff_right"><span class="simple_value int">2</span></div></div></td></tr><tr><td><span class="object_key str no_diff_key">y</span><span class="tooltip key-path">y.y</span></td><td><div class="diff_left diff_right"><span class="simple_value int">3</span></div></td></tr></table></div></details></td></tr></table></div></details>
|
605
606
|
"""
|
606
607
|
)
|
607
608
|
|
@@ -623,7 +624,7 @@ class DiffTest(unittest.TestCase):
|
|
623
624
|
uncollapse=['[0]', '[1].right', '[3].left.y'],
|
624
625
|
),
|
625
626
|
"""
|
626
|
-
<details open class="pyglove diff"><summary><div class="summary_title">List</div></summary><div class="complex_value list"><table><tr><td><span class="object_key no_diff_key">0</span><span class="tooltip">[0]</span></td><td><details open class="pyglove diff"><summary><div class="summary_title">Foo(...)</div></summary><div class="
|
627
|
+
<details open class="pyglove diff"><summary><div class="summary_title">List</div></summary><div class="complex_value list"><table><tr><td><span class="object_key int no_diff_key">0</span><span class="tooltip key-path">[0]</span></td><td><details open class="pyglove diff"><summary><div class="summary_title">Foo(...)</div></summary><div class="diff_left diff_right"><div class="complex_value foo"><table><tr><td><span class="object_key str">x</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">y</span></td><td><div><span class="simple_value int">2</span></div></td></tr></table></div></div></details></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">[1]</span></td><td><div class="diff_value"><div class="diff_left"><details class="pyglove foo"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key str">x</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">y</span></td><td><div><span class="simple_value int">2</span></div></td></tr></table></div></details></div><div class="diff_right"><details open class="pyglove bar"><summary><div class="summary_title">Bar(...)</div></summary><div class="complex_value bar"><table><tr><td><span class="object_key str">x</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">y</span></td><td><div><span class="simple_value int">2</span></div></td></tr></table></div></details></div></div></td></tr><tr><td><span class="object_key int">2</span><span class="tooltip key-path">[2]</span></td><td><div class="diff_value"><div class="diff_left"><span class="simple_value none-type">None</span></div><div class="diff_right"><details class="pyglove dict"><summary><div class="summary_title">Dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">x</span></td><td><div><span class="simple_value int">1</span></div></td></tr></table></div></details></div></div></td></tr><tr><td><span class="object_key int">3</span><span class="tooltip key-path">[3]</span></td><td><div class="diff_value"><div class="diff_left"><details open class="pyglove foo"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key str">x</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">y</span></td><td><div><details open class="pyglove foo"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key str">x</span></td><td><div><span class="simple_value int">2</span></div></td></tr><tr><td><span class="object_key str">y</span></td><td><div><span class="simple_value int">3</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div><div class="diff_right"><details class="pyglove list"><summary><div class="summary_title">List(...)</div></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">1</span></td><td><div><span class="simple_value int">2</span></div></td></tr></table></div></details></div></div></td></tr><tr><td><span class="object_key int">4</span><span class="tooltip key-path">[4]</span></td><td><div class="diff_value"><div class="diff_left"><details class="pyglove list"><summary><div class="summary_title">List(...)</div></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">Dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">x</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">y</span></td><td><div><span class="simple_value int">2</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div><div class="diff_right"><details class="pyglove foo"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key str">x</span></td><td><div><span class="simple_value int">2</span></div></td></tr><tr><td><span class="object_key str">y</span></td><td><div><details class="pyglove foo"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key str">x</span></td><td><div><span class="simple_value int">2</span></div></td></tr><tr><td><span class="object_key str">y</span></td><td><div><span class="simple_value int">4</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></div></td></tr><tr><td><span class="object_key int">5</span><span class="tooltip key-path">[5]</span></td><td><div class="diff_value"><div class="diff_right"><details class="pyglove list"><summary><div class="summary_title">List(...)</div></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">Dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">x</span></td><td><div><span class="simple_value int">3</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></div></td></tr></table></div></details>
|
627
628
|
"""
|
628
629
|
)
|
629
630
|
|
@@ -223,26 +223,26 @@ class RefTest(unittest.TestCase):
|
|
223
223
|
visibility: visible;
|
224
224
|
background-color: darkblue;
|
225
225
|
}
|
226
|
-
.
|
226
|
+
.object_key.str {
|
227
227
|
color: gray;
|
228
228
|
border: 1px solid lightgray;
|
229
229
|
background-color: ButtonFace;
|
230
230
|
border-radius: 0.2em;
|
231
231
|
padding: 0.3em;
|
232
232
|
}
|
233
|
-
.
|
233
|
+
.object_key.int::before{
|
234
|
+
content: '[';
|
235
|
+
}
|
236
|
+
.object_key.int::after{
|
237
|
+
content: ']';
|
238
|
+
}
|
239
|
+
.object_key.int{
|
234
240
|
border: 0;
|
235
241
|
color: lightgray;
|
236
242
|
background-color: transparent;
|
237
243
|
border-radius: 0;
|
238
244
|
padding: 0;
|
239
245
|
}
|
240
|
-
.complex_value.list .object_key::before{
|
241
|
-
content: '[';
|
242
|
-
}
|
243
|
-
.complex_value.list .object_key::after{
|
244
|
-
content: ']';
|
245
|
-
}
|
246
246
|
/* Simple value styles. */
|
247
247
|
.simple_value {
|
248
248
|
color: blue;
|
@@ -294,7 +294,7 @@ class RefTest(unittest.TestCase):
|
|
294
294
|
enable_key_tooltip=False,
|
295
295
|
),
|
296
296
|
"""
|
297
|
-
<details open class="pyglove foo"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key">x</span></td><td><details class="pyglove ref"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key">x</span></td><td><span class="simple_value int">1</span></td></tr></table></div></details></td></tr></table></div></details>
|
297
|
+
<details open class="pyglove foo"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key str">x</span></td><td><div><details class="pyglove ref"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo"><table><tr><td><span class="object_key str">x</span></td><td><div><span class="simple_value int">1</span></div></td></tr></table></div></details></div></td></tr></table></div></details>
|
298
298
|
"""
|
299
299
|
)
|
300
300
|
|
pyglove/core/views/base.py
CHANGED
@@ -131,6 +131,7 @@ import copy as copy_lib
|
|
131
131
|
import functools
|
132
132
|
import inspect
|
133
133
|
import io
|
134
|
+
import os
|
134
135
|
import types
|
135
136
|
from typing import Any, Callable, ContextManager, Dict, Iterator, Optional, Sequence, Set, Type, Union
|
136
137
|
|
@@ -330,6 +331,7 @@ class Content(object_utils.Formattable, metaclass=abc.ABCMeta):
|
|
330
331
|
|
331
332
|
def save(self, file: str, **kwargs):
|
332
333
|
"""Save content to a file."""
|
334
|
+
pg_io.mkdirs(os.path.dirname(file), exist_ok=True)
|
333
335
|
pg_io.writefile(file, self.to_str(**kwargs))
|
334
336
|
|
335
337
|
def __add__(self, other: WritableTypes) -> 'Content':
|
pyglove/core/views/base_test.py
CHANGED
@@ -209,7 +209,7 @@ class ContentTest(unittest.TestCase):
|
|
209
209
|
self.assertEqual(document.content, 'abcdefghijklmno')
|
210
210
|
|
211
211
|
def test_save(self):
|
212
|
-
filename = os.path.join(tempfile.gettempdir(), 'test_doc.txt')
|
212
|
+
filename = os.path.join(tempfile.gettempdir(), '1', 'test_doc.txt')
|
213
213
|
Document('abc', ref_links=['https://x/y.css']).save(filename)
|
214
214
|
self.assertTrue(pg_io.path_exists(filename))
|
215
215
|
self.assertEqual(pg_io.readfile(filename), 'link=https://x/y.css\nabc')
|
pyglove/core/views/html/base.py
CHANGED
@@ -18,12 +18,17 @@ import functools
|
|
18
18
|
import html as html_lib
|
19
19
|
import inspect
|
20
20
|
import typing
|
21
|
-
from typing import Any, Callable, Dict, Iterable, List, Optional, Union
|
21
|
+
from typing import Any, Callable, Dict, Iterable, List, Optional, Sequence, Union
|
22
22
|
|
23
23
|
from pyglove.core import object_utils
|
24
24
|
from pyglove.core import typing as pg_typing
|
25
25
|
from pyglove.core.views import base
|
26
26
|
|
27
|
+
NestableStr = Union[
|
28
|
+
str,
|
29
|
+
Sequence[Union[str, None, Sequence[Optional[str]]]],
|
30
|
+
None,
|
31
|
+
]
|
27
32
|
|
28
33
|
NodeFilter = base.NodeFilter
|
29
34
|
NodeColor = Callable[
|
@@ -280,7 +285,7 @@ class Html(base.Content):
|
|
280
285
|
inner_html: Optional[List[WritableTypes]] = None,
|
281
286
|
*,
|
282
287
|
options: Union[str, Iterable[str], None] = None,
|
283
|
-
css_class:
|
288
|
+
css_class: NestableStr = None,
|
284
289
|
style: Union[str, Dict[str, Any], None] = None,
|
285
290
|
**properties
|
286
291
|
) -> 'Html':
|
@@ -301,21 +306,12 @@ class Html(base.Content):
|
|
301
306
|
Returns:
|
302
307
|
The opening tag of an HTML element.
|
303
308
|
"""
|
304
|
-
def ws_join(items: Union[str, Iterable[str], None]) -> Optional[str]:
|
305
|
-
if isinstance(items, str):
|
306
|
-
return items
|
307
|
-
elif isinstance(items, list):
|
308
|
-
return ' '.join(s for s in items if s is not None)
|
309
|
-
else:
|
310
|
-
assert items is None, items
|
311
|
-
return None
|
312
|
-
|
313
309
|
s = cls()
|
314
310
|
|
315
311
|
# Write the open tag.
|
316
|
-
css_class =
|
312
|
+
css_class = cls.concate(css_class)
|
313
|
+
options = cls.concate(options)
|
317
314
|
style = cls.style_str(style)
|
318
|
-
options = ws_join(options)
|
319
315
|
s.write(
|
320
316
|
f'<{tag}',
|
321
317
|
f' {options}' if options else None,
|
@@ -353,9 +349,24 @@ class Html(base.Content):
|
|
353
349
|
s, shared_parts_only=True
|
354
350
|
)
|
355
351
|
|
352
|
+
@classmethod
|
353
|
+
def concate(
|
354
|
+
cls, nestable_str: NestableStr, separator: str = ' '
|
355
|
+
) -> Optional[str]:
|
356
|
+
"""Concates the string nodes in a nestable object."""
|
357
|
+
if isinstance(nestable_str, str):
|
358
|
+
return nestable_str
|
359
|
+
elif isinstance(nestable_str, list):
|
360
|
+
flattened = [cls.concate(s) for s in nestable_str]
|
361
|
+
flattened = [s for s in flattened if s is not None]
|
362
|
+
return separator.join(flattened) if flattened else None
|
363
|
+
else:
|
364
|
+
assert nestable_str is None, nestable_str
|
365
|
+
return None
|
366
|
+
|
356
367
|
@classmethod
|
357
368
|
def style_str(
|
358
|
-
cls, style: Union[str, Dict[str, Any], None]
|
369
|
+
cls, style: Union[str, Dict[str, Any], None],
|
359
370
|
) -> Optional[str]:
|
360
371
|
"""Gets a string representing an inline CSS style.
|
361
372
|
|
@@ -392,6 +403,24 @@ class HtmlView(base.View):
|
|
392
403
|
class Extension(base.View.Extension):
|
393
404
|
"""Base class for HtmlView extensions."""
|
394
405
|
|
406
|
+
def _html_style(self) -> List[str]:
|
407
|
+
"""Returns additional CSS style to add for this extension.
|
408
|
+
|
409
|
+
Subclasses can override this method to add additional CSS style to the
|
410
|
+
rendered HTML.
|
411
|
+
"""
|
412
|
+
return []
|
413
|
+
|
414
|
+
def _html_element_class(self) -> List[str]:
|
415
|
+
"""Returns the CSS classes for the rendered element for this node.
|
416
|
+
|
417
|
+
Subclasses can override this method to add CSS classes to the
|
418
|
+
rendered element of this object.
|
419
|
+
"""
|
420
|
+
return [
|
421
|
+
object_utils.camel_to_snake(self.__class__.__name__, '-')
|
422
|
+
]
|
423
|
+
|
395
424
|
def to_html(
|
396
425
|
self,
|
397
426
|
*,
|
@@ -696,6 +696,15 @@ class HtmlTest(TestCase):
|
|
696
696
|
self.assertEqual(Html.escape(Html('foo"bar')), Html('foo"bar'))
|
697
697
|
self.assertEqual(Html.escape(lambda: 'foo"bar'), 'foo"bar')
|
698
698
|
|
699
|
+
def test_concate(self):
|
700
|
+
self.assertIsNone(Html.concate(None))
|
701
|
+
self.assertIsNone(Html.concate([None, [None, [None, None]]]))
|
702
|
+
self.assertEqual(Html.concate('a'), 'a')
|
703
|
+
self.assertEqual(Html.concate(['a']), 'a')
|
704
|
+
self.assertEqual(Html.concate(['a', None, 'b']), 'a b')
|
705
|
+
self.assertEqual(
|
706
|
+
Html.concate(['a', 'b', [None, 'c', [None, 'd']]]), 'a b c d')
|
707
|
+
|
699
708
|
def test_element(self):
|
700
709
|
# Empty element.
|
701
710
|
self.assertEqual(Html.element('div').content, '<div></div>')
|