langfun 0.1.2.dev202501020804__py3-none-any.whl → 0.1.2.dev202501030804__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langfun
3
- Version: 0.1.2.dev202501020804
3
+ Version: 0.1.2.dev202501030804
4
4
  Summary: Langfun: Language as Functions.
5
5
  Home-page: https://github.com/google/langfun
6
6
  Author: Langfun Authors
@@ -1,5 +1,5 @@
1
1
  langfun/__init__.py,sha256=fhfPXpHN7GoGqixpFfqhQkYxFs_siP_LhbjZhd3lhio,2497
2
- langfun/core/__init__.py,sha256=xlvFTXc7IKUTs8aCFRFhzOLTmmeuhXgk9yx2InBLNiA,4937
2
+ langfun/core/__init__.py,sha256=oboXhlpA93wk4p1K52-tx0pbBt49r6Y1aCmiavBV03Y,4830
3
3
  langfun/core/component.py,sha256=HVrEoTL1Y01iqOHC3FYdbAOnffqfHHtGJXoK1vkdEwo,11583
4
4
  langfun/core/component_test.py,sha256=sG-T2wpvBfHqWGZE7sc4NayJj2aj5QFBzSwFiwrGEIc,10376
5
5
  langfun/core/concurrent.py,sha256=QMNYhB_PyjvVJtabMokpzotZRYvyE9iYu2QsgwDk7M4,29552
@@ -19,8 +19,6 @@ langfun/core/modality.py,sha256=K8pUGuMpfWcOtVcXC_OqVjro1-RhHF6ddQni61DuYzM,4166
19
19
  langfun/core/modality_test.py,sha256=7SwhixFME2Q1sIXRgJx97EZFiIyC31A9NVr6_nDtFv4,2441
20
20
  langfun/core/natural_language.py,sha256=3ynSnaYQnjE60LIPK5fyMgdIjubnPYZwzGq4rWPeloE,1177
21
21
  langfun/core/natural_language_test.py,sha256=LHGU_1ytbkGuSZQFIFP7vP3dBlcY4-A12fT6dbjUA0E,1424
22
- langfun/core/repr_utils.py,sha256=yyc2xeK8sKQOOLcxwIV9E50Wf-B0TjXrnS07tSx_ea8,6491
23
- langfun/core/repr_utils_test.py,sha256=ULG7gvgoyqQFWi0m6g2-E0GorNEr1nnZ0J_sZVQKz80,3036
24
22
  langfun/core/sampling.py,sha256=SCnS5PFJWNVxSKvSkSCNRUmruvScun8UcNN4gafuXcw,5866
25
23
  langfun/core/sampling_test.py,sha256=U7PANpMsl9E_pa4_Y4FzesSjcwg-u-LKHGCWSgv-8FY,3663
26
24
  langfun/core/subscription.py,sha256=euawEuSZP-BHydaT-AQpfYFL0m5pWPGcW0upFhrojqc,10930
@@ -51,22 +49,22 @@ langfun/core/coding/python/permissions_test.py,sha256=w5EDb8QxpxgJyZkojyzVWQvDfg
51
49
  langfun/core/eval/__init__.py,sha256=OEXr1ZRuvLuhJJfuQ1ZWQ-SvYzjyrtiAAEogYaB7E6o,1933
52
50
  langfun/core/eval/base.py,sha256=ajHUS_BdzBIDKEwAmMzne0lJi8HcDhPmyw_plO0p7G0,75814
53
51
  langfun/core/eval/base_test.py,sha256=-LsIV9DXlDal0EnOlaWpibJvfef0NbxtZAm0OH_abAE,27189
54
- langfun/core/eval/matching.py,sha256=UnjdM_ebPqXKJamY4lvL3AYxrMIz3LqkjRTnHJ5xsYc,9349
52
+ langfun/core/eval/matching.py,sha256=AVKkGoc-BaHEzgSBamaAk3194TgqckDe_dinpS6LrXI,9323
55
53
  langfun/core/eval/matching_test.py,sha256=QCoYEuf4b_1bkHqUCuRzKMbXHrV3AB2FCOBivo1stC4,5249
56
54
  langfun/core/eval/patching.py,sha256=R0s2eAd1m97exQt06dmUL0V_MBG0W2Hxg7fhNB7cXW0,3866
57
55
  langfun/core/eval/patching_test.py,sha256=8kCd54Egjju22FMgtJuxEsrXkW8ifs-UUBHtrCG1L6w,4775
58
- langfun/core/eval/scoring.py,sha256=B69IsIxiPs1xZcOBFIhZF70YmDue2Siik-CPL2bh33s,6254
56
+ langfun/core/eval/scoring.py,sha256=_DvnlgI1SdRVaOojao_AkV3pnenfCPOqyhvlg-Sw-5M,6322
59
57
  langfun/core/eval/scoring_test.py,sha256=O8olHbrUEg60gMxwOkWzKBJZpZoUlmVnBANX5Se2SXM,4546
60
58
  langfun/core/eval/v2/__init__.py,sha256=qoa6zKdFXOFyCX6vay6OdgPf1eUhYGoHYAxe35qECGk,1628
61
- langfun/core/eval/v2/checkpointing.py,sha256=5Koc9IM5OFAhLaO7sAZC979vEFxR8a_ssXcaqG_iVw0,10325
62
- langfun/core/eval/v2/checkpointing_test.py,sha256=i9qmEJk90kz6SB7OBGAHCogKVyazUZxAZlKXZt9hccI,4435
63
- langfun/core/eval/v2/eval_test_helper.py,sha256=pDpZTBnWRR5xjJv3Uy3NWEzArqlL8FTMOgeR4C53F5M,2348
64
- langfun/core/eval/v2/evaluation.py,sha256=NFBGAWw2BtW7H0zcoZhfWtz59Psra84eshJm73uAFwg,21807
65
- langfun/core/eval/v2/evaluation_test.py,sha256=GmV1TiqX1V15st2qpcGWooM5hudomQVjW5kajovGDvE,6231
66
- langfun/core/eval/v2/example.py,sha256=fURrvdNmMsVMqoEErcsmLmC6Xq3ny16dYsnLH8HVlcY,9626
67
- langfun/core/eval/v2/example_test.py,sha256=WcJmU7IQQXvjFia63mokySC4CqxzVL9Wso1sC5F0YK8,3032
68
- langfun/core/eval/v2/experiment.py,sha256=DuuqTJA0jmep-CM098MYutKkarLIcd1Do9P0W_HhdBg,29800
69
- langfun/core/eval/v2/experiment_test.py,sha256=zSMHYqC9cA0k61U71pCSYTAJ6yK2_b6Dml5btc-bKzQ,9133
59
+ langfun/core/eval/v2/checkpointing.py,sha256=u-MrnwQbm0T-BDcn9pPXs_FeKPzMYm1-pVos0DiTqgM,11769
60
+ langfun/core/eval/v2/checkpointing_test.py,sha256=R-R8SFzworuYnMmGGcvE9f4oiYkb8HMoZ0m4euF3pus,8466
61
+ langfun/core/eval/v2/eval_test_helper.py,sha256=A9w0FbRKieB3yym8x34kY24FfptHrp7m6_z3i8HXSFI,3922
62
+ langfun/core/eval/v2/evaluation.py,sha256=kARf0pG6SrpN__IMeFsw8DV_5mT_tl52pJrr6wIZdsw,22482
63
+ langfun/core/eval/v2/evaluation_test.py,sha256=0l0DqJTF8PZGA2Q1OlaF4YIax4ZhSk0ewOCvuVW1XAk,6658
64
+ langfun/core/eval/v2/example.py,sha256=4-LNr8Ke-fhaF6gyeXX4JMyw0s8YkVTC63pXZ-CXKrE,10144
65
+ langfun/core/eval/v2/example_test.py,sha256=1DNm6EuyZOq827DKvf3oTRVFkMNM_qTnLUpvOjpgz5I,3419
66
+ langfun/core/eval/v2/experiment.py,sha256=lKM3WQck1RWxYznMn1madZqI7w9rpOmu1O35q-KHSC4,32413
67
+ langfun/core/eval/v2/experiment_test.py,sha256=ToxYzQoAbnqzI8kkJH3nHF1vtrac_1yiNbxLS45jx9s,12931
70
68
  langfun/core/eval/v2/metric_values.py,sha256=_B905bC-jxrYPLSEcP2M8MaHZOVMz_bVrUw8YC4arCE,4660
71
69
  langfun/core/eval/v2/metric_values_test.py,sha256=ab2oF_HsIwrSy459108ggyjgefHSPn8UVILR4dRwx14,2634
72
70
  langfun/core/eval/v2/metrics.py,sha256=bl8i6u-ZHRBz4hAc3LzsZ2Dc7ZRQcuTYeUhhH-GxfF0,10628
@@ -75,12 +73,12 @@ langfun/core/eval/v2/progress.py,sha256=azZgssQgNdv3IgjKEaQBuGI5ucFDNbdi02P4z_nQ
75
73
  langfun/core/eval/v2/progress_test.py,sha256=YU7VHzmy5knPZwj9vpBN3rQQH2tukj9eKHkuBCI62h8,2540
76
74
  langfun/core/eval/v2/progress_tracking.py,sha256=l9fEkz4oP5McpZzf72Ua7PYm3lAWtRru7gRWNf8H0ms,6083
77
75
  langfun/core/eval/v2/progress_tracking_test.py,sha256=fouMVJkFJqHjbhQJngGLGCmA9x3n0dU4USI2dY163mg,2291
78
- langfun/core/eval/v2/reporting.py,sha256=qFxoxqQhNGxh1APg6-JVDlIfniGdty2Rh8aXQMc1aak,6612
79
- langfun/core/eval/v2/reporting_test.py,sha256=4nobW6pcaatiZh8u4xciexciaiZNDlDoJci157Wp_RI,1492
80
- langfun/core/eval/v2/runners.py,sha256=t6_yHAJ4HWufK4wvh_OntKcok2KquA5ARIHIk1vvEwc,15870
76
+ langfun/core/eval/v2/reporting.py,sha256=cf3jEJbaXKOiGm1UreA9USVGGIp6h8-7E6L3wi76L9I,7676
77
+ langfun/core/eval/v2/reporting_test.py,sha256=IiWLifDi_bV7fze_23lK8IfU5FE4YB3rXBE4jx4s2fw,5698
78
+ langfun/core/eval/v2/runners.py,sha256=DKEmSlGXjOXKWFdBhTpLy7tMsBHZHd1Brl3hWIngsSQ,15931
81
79
  langfun/core/eval/v2/runners_test.py,sha256=A37fKK2MvAVTiShsg_laluJzJ9AuAQn52k7HPbfD0Ks,11666
82
- langfun/core/llms/__init__.py,sha256=lWXKjGHv66ShG7AE_Bc4QM7SDTxJdfoQMn3PF0lr0sU,6461
83
- langfun/core/llms/anthropic.py,sha256=afKZmdiLcosS_UEBlB8WKyf1K-zeXgwtPAx6ofg2Gww,13989
80
+ langfun/core/llms/__init__.py,sha256=ePV13zQL8aLZjYj4YB4YC4xeK_nz0TBv7L2Bm10e3Cw,6574
81
+ langfun/core/llms/anthropic.py,sha256=a5MmnFsBA0CbfvwzXT1v_0fqLRMrhUNdh1tx6469PQ4,14357
84
82
  langfun/core/llms/anthropic_test.py,sha256=-2U4kc_pgBM7wqxu8RuxzyHPGww1EAWqKUvN4PW8Btw,8058
85
83
  langfun/core/llms/compositional.py,sha256=csW_FLlgL-tpeyCOTVvfUQkMa_zCN5Y2I-YbSNuK27U,2872
86
84
  langfun/core/llms/compositional_test.py,sha256=4eTnOer-DncRKGaIJW2ZQQMLnt5r2R0UIx_DYOvGAQo,2027
@@ -92,7 +90,7 @@ langfun/core/llms/groq.py,sha256=dCnR3eAECEKuKKAAj-PDTs8NRHl6CQPdf57m1f6a79U,103
92
90
  langfun/core/llms/groq_test.py,sha256=GYF_Qtq5S1H1TrKH38t6_lkdroqT7v-joYLDKnmS9e0,5274
93
91
  langfun/core/llms/llama_cpp.py,sha256=9tXQntSCDtjTF3bnyJrAPCr4N6wycy5nXYvp9uduygE,2843
94
92
  langfun/core/llms/llama_cpp_test.py,sha256=MWO_qaOeKjRniGjcaWPDScd7HPaIJemqUZoslrt4FPs,1806
95
- langfun/core/llms/openai.py,sha256=l49v6RubfInvV0iG114AymTKNogTX4u4N-UFCeSgIxw,20963
93
+ langfun/core/llms/openai.py,sha256=dLDVBB47nJ30XCwjJpAZMc55ZlZXB__PcfcICCRNuXQ,20995
96
94
  langfun/core/llms/openai_test.py,sha256=kOWa1nf-nJvtYY10REUw5wojh3ZgfU8tRaCZ8wUgJbA,16623
97
95
  langfun/core/llms/rest.py,sha256=sWbYUV8S3SuOg9giq7xwD-xDRfaF7NP_ig7bI52-Rj4,3442
98
96
  langfun/core/llms/rest_test.py,sha256=NZ3Nf0XQVpT9kLP5cBVo_yBHLI7vWTYhWQxYEJVMGs4,3472
@@ -148,8 +146,8 @@ langfun/core/templates/demonstration.py,sha256=vCrgYubdZM5Umqcgp8NUVGXgr4P_c-fik
148
146
  langfun/core/templates/demonstration_test.py,sha256=SafcDQ0WgI7pw05EmPI2S4v1t3ABKzup8jReCljHeK4,2162
149
147
  langfun/core/templates/selfplay.py,sha256=yhgrJbiYwq47TgzThmHrDQTF4nDrTI09CWGhuQPNv-s,2273
150
148
  langfun/core/templates/selfplay_test.py,sha256=Ot__1P1M8oJfoTp-M9-PQ6HUXqZKyMwvZ5f7yQ3yfyM,2326
151
- langfun-0.1.2.dev202501020804.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
152
- langfun-0.1.2.dev202501020804.dist-info/METADATA,sha256=yYxHZ0wLmkNF984y4_CTfkb3z7pzBvyEnTXDv-mQRg4,8281
153
- langfun-0.1.2.dev202501020804.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
154
- langfun-0.1.2.dev202501020804.dist-info/top_level.txt,sha256=RhlEkHxs1qtzmmtWSwYoLVJAc1YrbPtxQ52uh8Z9VvY,8
155
- langfun-0.1.2.dev202501020804.dist-info/RECORD,,
149
+ langfun-0.1.2.dev202501030804.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
150
+ langfun-0.1.2.dev202501030804.dist-info/METADATA,sha256=NHHnAue9xjnH1TBHqjSBdmY2jPVh-LFa0Uipe0_e_OE,8281
151
+ langfun-0.1.2.dev202501030804.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
152
+ langfun-0.1.2.dev202501030804.dist-info/top_level.txt,sha256=RhlEkHxs1qtzmmtWSwYoLVJAc1YrbPtxQ52uh8Z9VvY,8
153
+ langfun-0.1.2.dev202501030804.dist-info/RECORD,,
@@ -1,204 +0,0 @@
1
- # Copyright 2024 The Langfun Authors
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
- """Helpers for implementing _repr_xxx_ methods."""
15
-
16
- import collections
17
- import contextlib
18
- import html
19
- import io
20
- from typing import Any, Callable, Iterator
21
-
22
- from langfun.core import component
23
- import pyglove as pg
24
-
25
-
26
- class Html(pg.Object):
27
- """A HTML adapter for rendering."""
28
- content: str
29
-
30
- def _repr_html_(self) -> str:
31
- return self.content
32
-
33
-
34
- @contextlib.contextmanager
35
- def share_parts() -> Iterator[dict[str, int]]:
36
- """Context manager for defining the context (scope) of shared content.
37
-
38
- Under the context manager, call to `lf.write_shared` with the same content
39
- will be written only once. This is useful for writing shared content such as
40
- shared style and script sections in the HTML.
41
-
42
- Example:
43
- ```
44
- class Foo(pg.Object):
45
- def _repr_html_(self) -> str:
46
- s = io.StringIO()
47
- lf.repr_utils.write_shared_part(s, '<style>..</style>')
48
- lf.repr_utils.write_shared_part(s, '<script>..</script>')
49
- return s.getvalue()
50
-
51
- with lf.repr_utils.share_parts() as share_parts:
52
- # The <style> and <script> section will be written only once.
53
- lf.console.display(Foo())
54
- lf.console.display(Foo())
55
-
56
- # Assert that the shared content is attempted to be written twice.
57
- assert share_parts['<style>..</style>'] == 2
58
- ```
59
-
60
- Yields:
61
- A dictionary mapping the shared content to the number of times it is
62
- attempted to be written.
63
- """
64
- context = component.context_value(
65
- '__shared_parts__', collections.defaultdict(int)
66
- )
67
- with component.context(__shared_parts__=context):
68
- try:
69
- yield context
70
- finally:
71
- pass
72
-
73
-
74
- def write_maybe_shared(s: io.StringIO, content: str) -> bool:
75
- """Writes a maybe shared part to an string stream.
76
-
77
- Args:
78
- s: The string stream to write to.
79
- content: A maybe shared content to write.
80
-
81
- Returns:
82
- True if the content is written to the string. False if the content is
83
- already written under the same share context.
84
- """
85
- context = component.context_value('__shared_parts__', None)
86
- if context is None:
87
- s.write(content)
88
- return True
89
- written = content in context
90
- if not written:
91
- s.write(content)
92
- context[content] += 1
93
- return not written
94
-
95
-
96
- def html_repr(
97
- value: dict[str, Any],
98
- item_color: Callable[
99
- [str, str],
100
- tuple[
101
- str | None, # Label text color
102
- str | None, # Label background color
103
- str | None, # Value text color
104
- str | None, # Value background color
105
- ]
106
- ] | None = None # pylint: disable=bad-whitespace
107
- ) -> str:
108
- """Writes a list of key-value pairs to an string stream.
109
-
110
- Args:
111
- value: A value to be rendered in HTML.
112
- item_color: A function that takes the key and value and returns a tuple
113
- of four strings, the text color and background color of the label and
114
- value respectively. If None, a default color scheme will be used.
115
-
116
- Returns:
117
- The HTML representation of the value.
118
- """
119
- s = io.StringIO()
120
- s.write('<div style="padding-left: 20px; margin-top: 10px">')
121
- s.write('<table style="border-top: 1px solid #EEEEEE;">')
122
- item_color = item_color or (lambda k, v: (None, '#F1C40F', None, None))
123
-
124
- def maybe_html_format(v: Any, root_indent: int) -> str | None:
125
- del root_indent
126
- if hasattr(v, '_repr_html_'):
127
- return v._repr_html_() # pylint: disable=protected-access
128
- # Fall back to the default format.
129
- return None
130
-
131
- with (pg.str_format(custom_format=maybe_html_format),
132
- pg.repr_format(custom_format=maybe_html_format)):
133
- for k, v in pg.object_utils.flatten(value).items():
134
- if isinstance(v, pg.Ref):
135
- v = v.value
136
- if hasattr(v, '_repr_html_'):
137
- cs = v._repr_html_() # pylint: disable=protected-access
138
- else:
139
- cs = html.escape(v) if isinstance(v, str) else escape_quoted(str(v))
140
- cs = f'<span style="white-space: pre-wrap">{cs}</span>'
141
-
142
- key_color, key_bg_color, value_color, value_bg_color = item_color(k, v)
143
- key_span = html_round_text(
144
- k,
145
- text_color=key_color,
146
- background_color=key_bg_color,
147
- margin_bottom='0px'
148
- )
149
- value_color_style = f'color: {value_color};' if value_color else ''
150
- value_bg_color_style = (
151
- f'background-color: {value_bg_color};' if value_bg_color else ''
152
- )
153
- s.write(
154
- '<tr>'
155
- '<td style="padding: 5px; vertical-align: top; '
156
- f'border-bottom: 1px solid #EEEEEE">{key_span}</td>'
157
- '<td style="padding: 15px 5px 5px 5px; vertical-align: top; '
158
- 'border-bottom: 1px solid #EEEEEE;'
159
- f'{value_color_style}{value_bg_color_style}">{cs}</td></tr>'
160
- )
161
- s.write('</table></div>')
162
- return s.getvalue()
163
-
164
-
165
- def html_round_text(
166
- text: str,
167
- *,
168
- text_color: str = 'black',
169
- background_color: str = '#EEEEEE',
170
- display: str = 'inline-block',
171
- margin_top: str = '5px',
172
- margin_bottom: str = '5px',
173
- whitespace: str = 'pre-wrap') -> str:
174
- """Renders a HTML span with rounded corners."""
175
- color_style = f'color: {text_color};' if text_color else ''
176
- bg_color_style = (
177
- f'background-color: {background_color};' if background_color else ''
178
- )
179
- return (
180
- f'<span style="{color_style}{bg_color_style}'
181
- f'display:{display}; border-radius:10px; padding:5px; '
182
- f'margin-top: {margin_top}; margin-bottom: {margin_bottom}; '
183
- f'white-space: {whitespace}">{text}</span>'
184
- )
185
-
186
-
187
- def escape_quoted(s: str):
188
- """Escape quoted parts within a string."""
189
- r = io.StringIO()
190
- quote_char = None
191
- quote_start = -1
192
- for i, c in enumerate(s):
193
- if c in ('\'', '"'):
194
- if quote_char is None:
195
- quote_char = c
196
- quote_start = i
197
- elif quote_char == c:
198
- r.write(c)
199
- r.write(html.escape(s[quote_start + 1:i]))
200
- r.write(c)
201
- quote_char = None
202
- elif quote_char is None:
203
- r.write(c)
204
- return r.getvalue()
@@ -1,90 +0,0 @@
1
- # Copyright 2024 The Langfun Authors
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
- """Tests for langfun.core.repr_utils."""
15
-
16
- import io
17
- import unittest
18
-
19
- from langfun.core import repr_utils
20
- import pyglove as pg
21
-
22
-
23
- class SharingContentTest(unittest.TestCase):
24
-
25
- def test_sharing(self):
26
- s = io.StringIO()
27
-
28
- self.assertTrue(repr_utils.write_maybe_shared(s, '<hr>'))
29
- self.assertTrue(repr_utils.write_maybe_shared(s, '<hr>'))
30
-
31
- with repr_utils.share_parts() as ctx1:
32
- self.assertTrue(repr_utils.write_maybe_shared(s, '<style></style>'))
33
- self.assertFalse(repr_utils.write_maybe_shared(s, '<style></style>'))
34
-
35
- with repr_utils.share_parts() as ctx2:
36
- self.assertIs(ctx2, ctx1)
37
- self.assertFalse(repr_utils.write_maybe_shared(s, '<style></style>'))
38
- self.assertTrue(repr_utils.write_maybe_shared(s, '<style>a</style>'))
39
- self.assertFalse(repr_utils.write_maybe_shared(s, '<style>a</style>'))
40
- self.assertTrue(repr_utils.write_maybe_shared(s, '<style>b</style>'))
41
-
42
- with repr_utils.share_parts() as ctx3:
43
- self.assertIs(ctx3, ctx1)
44
- self.assertFalse(repr_utils.write_maybe_shared(s, '<style></style>'))
45
- self.assertFalse(repr_utils.write_maybe_shared(s, '<style>a</style>'))
46
- self.assertFalse(repr_utils.write_maybe_shared(s, '<style>a</style>'))
47
- self.assertFalse(repr_utils.write_maybe_shared(s, '<style>b</style>'))
48
-
49
- self.assertEqual(
50
- s.getvalue(),
51
- '<hr><hr><style></style><style>a</style><style>b</style>'
52
- )
53
- self.assertEqual(ctx1['<style></style>'], 4)
54
- self.assertEqual(ctx1['<style>b</style>'], 2)
55
- self.assertEqual(ctx1['<style>a</style>'], 4)
56
-
57
- def test_escape_quoted(self):
58
- self.assertEqual(
59
- repr_utils.escape_quoted(str('<a>')), '<a>'
60
- )
61
- self.assertEqual(
62
- repr_utils.escape_quoted('x=<a>, b="<a>"'),
63
- 'x=<a>, b="&lt;a&gt;"'
64
- )
65
-
66
- def test_html(self):
67
- html = repr_utils.Html('<div>foo</div>')
68
- self.assertEqual(html.content, '<div>foo</div>')
69
- self.assertEqual(html._repr_html_(), '<div>foo</div>')
70
-
71
- def test_html_repr(self):
72
- class Foo(pg.Object):
73
- x: int
74
-
75
- class Bar(pg.Object):
76
-
77
- def _repr_html_(self):
78
- return '<bar>'
79
-
80
- html = repr_utils.html_repr(
81
- {'foo': pg.Ref(Foo(1)), 'bar': Bar(), 'baz': '<lf_image>'}
82
- )
83
- self.assertIn('foo</span>', html)
84
- self.assertIn('<bar>', html)
85
- self.assertIn('&lt;lf_image&gt;', html)
86
- self.assertNotIn('Ref', html)
87
-
88
-
89
- if __name__ == '__main__':
90
- unittest.main()