langfun 0.1.2.dev202510160805__py3-none-any.whl → 0.1.2.dev202510170805__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.
Potentially problematic release.
This version of langfun might be problematic. Click here for more details.
- langfun/core/__init__.py +5 -1
- langfun/core/async_support.py +73 -3
- langfun/core/async_support_test.py +23 -0
- langfun/core/concurrent_test.py +8 -2
- langfun/core/eval/v2/progress_tracking_test.py +2 -2
- {langfun-0.1.2.dev202510160805.dist-info → langfun-0.1.2.dev202510170805.dist-info}/METADATA +3 -1
- {langfun-0.1.2.dev202510160805.dist-info → langfun-0.1.2.dev202510170805.dist-info}/RECORD +10 -10
- {langfun-0.1.2.dev202510160805.dist-info → langfun-0.1.2.dev202510170805.dist-info}/WHEEL +0 -0
- {langfun-0.1.2.dev202510160805.dist-info → langfun-0.1.2.dev202510170805.dist-info}/licenses/LICENSE +0 -0
- {langfun-0.1.2.dev202510160805.dist-info → langfun-0.1.2.dev202510170805.dist-info}/top_level.txt +0 -0
langfun/core/__init__.py
CHANGED
|
@@ -40,9 +40,13 @@ from langfun.core.component import context
|
|
|
40
40
|
as_context = context
|
|
41
41
|
use_context = context
|
|
42
42
|
|
|
43
|
-
#
|
|
43
|
+
# Support for async IO.
|
|
44
44
|
from langfun.core.async_support import invoke_async
|
|
45
45
|
|
|
46
|
+
# Adaptors for async function/context manager to sync versions.
|
|
47
|
+
from langfun.core.async_support import invoke_sync
|
|
48
|
+
from langfun.core.async_support import sync_context_manager
|
|
49
|
+
|
|
46
50
|
# Shortcut function for overriding components attributes, usually for
|
|
47
51
|
# override settings.
|
|
48
52
|
from langfun.core.component import use_settings
|
langfun/core/async_support.py
CHANGED
|
@@ -14,15 +14,85 @@
|
|
|
14
14
|
"""Utility for async IO in Langfun."""
|
|
15
15
|
|
|
16
16
|
import asyncio
|
|
17
|
-
|
|
17
|
+
import contextlib
|
|
18
|
+
from typing import Any, Awaitable, Callable, Iterator
|
|
19
|
+
import anyio
|
|
18
20
|
import pyglove as pg
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
async def invoke_async(
|
|
22
|
-
|
|
24
|
+
sync_callable: Callable[..., Any], *args, **kwargs
|
|
23
25
|
) -> Any:
|
|
24
26
|
"""Invokes a callable asynchronously with `lf.context` manager enabled."""
|
|
25
27
|
return await asyncio.to_thread(
|
|
26
28
|
# Enable `lf.context` manager for async calls.
|
|
27
|
-
pg.with_contextual_override(
|
|
29
|
+
pg.with_contextual_override(sync_callable), *args, **kwargs
|
|
28
30
|
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def invoke_sync(
|
|
34
|
+
async_callable: Callable[..., Awaitable[Any]],
|
|
35
|
+
*args,
|
|
36
|
+
**kwargs
|
|
37
|
+
) -> Any:
|
|
38
|
+
"""Invokes a async callable synchronously."""
|
|
39
|
+
async def _invoke():
|
|
40
|
+
return await async_callable(*args, **kwargs)
|
|
41
|
+
invoke_fn = pg.with_contextual_override(_invoke)
|
|
42
|
+
blocking_portal = pg.utils.thread_local_get('__blocking_portal__', None)
|
|
43
|
+
if blocking_portal is None:
|
|
44
|
+
return anyio.run(invoke_fn)
|
|
45
|
+
return blocking_portal.call(invoke_fn)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@contextlib.contextmanager
|
|
49
|
+
def sync_context_manager(
|
|
50
|
+
async_context_manager: contextlib.AbstractAsyncContextManager[Any]
|
|
51
|
+
) -> Iterator[Any]:
|
|
52
|
+
"""Adapts an async context manager to a sync context manager.
|
|
53
|
+
|
|
54
|
+
sync_context_manager installs a blocking portal in current thread to run the
|
|
55
|
+
async context manager in a blocking way. It's useful for running async code in
|
|
56
|
+
sync context managers, e.g. `sync_context_manager` can be nested and share the
|
|
57
|
+
same event loop.
|
|
58
|
+
|
|
59
|
+
Example:
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
@contextlib.asynccontextmanager
|
|
63
|
+
async def foo(x):
|
|
64
|
+
try:
|
|
65
|
+
yield x
|
|
66
|
+
finally:
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
with lf.sync_context_manager(foo(x)) as x
|
|
70
|
+
with lf.sync_context_manager(foo(y)) as y:
|
|
71
|
+
...
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
async_context_manager: The async context manager to adapt.
|
|
76
|
+
|
|
77
|
+
Yields:
|
|
78
|
+
The value yielded by the async context manager.
|
|
79
|
+
"""
|
|
80
|
+
blocking_portal = pg.utils.thread_local_get('__blocking_portal__', None)
|
|
81
|
+
portal_exit_stack = None
|
|
82
|
+
|
|
83
|
+
try:
|
|
84
|
+
if blocking_portal is None:
|
|
85
|
+
portal_exit_stack = contextlib.ExitStack()
|
|
86
|
+
blocking_portal = portal_exit_stack.enter_context(
|
|
87
|
+
anyio.from_thread.start_blocking_portal()
|
|
88
|
+
)
|
|
89
|
+
pg.utils.thread_local_set('__blocking_portal__', blocking_portal)
|
|
90
|
+
context_manager = blocking_portal.wrap_async_context_manager(
|
|
91
|
+
async_context_manager
|
|
92
|
+
)
|
|
93
|
+
with context_manager as value:
|
|
94
|
+
yield value
|
|
95
|
+
finally:
|
|
96
|
+
if portal_exit_stack is not None:
|
|
97
|
+
portal_exit_stack.close()
|
|
98
|
+
pg.utils.thread_local_del('__blocking_portal__')
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
import asyncio
|
|
16
|
+
import contextlib
|
|
16
17
|
import time
|
|
17
18
|
import unittest
|
|
18
19
|
|
|
@@ -34,6 +35,28 @@ class AsyncSupportTest(unittest.TestCase):
|
|
|
34
35
|
with pg.contextual_override(z=3):
|
|
35
36
|
self.assertEqual(asyncio.run(r), 6)
|
|
36
37
|
|
|
38
|
+
def test_invoke_sync(self):
|
|
39
|
+
@contextlib.asynccontextmanager
|
|
40
|
+
async def bar(x):
|
|
41
|
+
try:
|
|
42
|
+
yield x
|
|
43
|
+
finally:
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
async def foo(x, *, y):
|
|
47
|
+
time.sleep(2)
|
|
48
|
+
return x + y + pg.contextual_value('z', 0)
|
|
49
|
+
|
|
50
|
+
with pg.contextual_override(z=3):
|
|
51
|
+
with async_support.sync_context_manager(bar(1)) as x:
|
|
52
|
+
self.assertEqual(x, 1)
|
|
53
|
+
with async_support.sync_context_manager(bar(2)) as y:
|
|
54
|
+
self.assertEqual(y, 2)
|
|
55
|
+
self.assertEqual(async_support.invoke_sync(foo, 1, y=2), 6)
|
|
56
|
+
|
|
57
|
+
with pg.contextual_override(z=2):
|
|
58
|
+
self.assertEqual(async_support.invoke_sync(foo, 1, y=2), 5)
|
|
59
|
+
|
|
37
60
|
|
|
38
61
|
if __name__ == '__main__':
|
|
39
62
|
unittest.main()
|
langfun/core/concurrent_test.py
CHANGED
|
@@ -262,6 +262,7 @@ class ProgressControlTest(unittest.TestCase):
|
|
|
262
262
|
with contextlib.redirect_stderr(string_io):
|
|
263
263
|
ctrl.update(1)
|
|
264
264
|
ctrl.refresh()
|
|
265
|
+
sys.stderr.flush()
|
|
265
266
|
self.assertEqual(string_io.getvalue(), '')
|
|
266
267
|
concurrent.progress_bar = 'tqdm'
|
|
267
268
|
|
|
@@ -274,6 +275,7 @@ class ProgressControlTest(unittest.TestCase):
|
|
|
274
275
|
ctrl.set_status('bar')
|
|
275
276
|
ctrl.update(10)
|
|
276
277
|
ctrl.refresh()
|
|
278
|
+
sys.stderr.flush()
|
|
277
279
|
self.assertEqual(
|
|
278
280
|
string_io.getvalue(),
|
|
279
281
|
'\x1b[1m\x1b[31mfoo\x1b[0m: \x1b[34m10% (10/100)\x1b[0m : bar\n'
|
|
@@ -288,6 +290,7 @@ class ProgressControlTest(unittest.TestCase):
|
|
|
288
290
|
self.assertIsInstance(ctrl, concurrent._TqdmProgressControl)
|
|
289
291
|
ctrl.update(10)
|
|
290
292
|
ctrl.refresh()
|
|
293
|
+
sys.stderr.flush()
|
|
291
294
|
self.assertIn('10/100', string_io.getvalue())
|
|
292
295
|
|
|
293
296
|
tqdm = concurrent.tqdm
|
|
@@ -316,6 +319,7 @@ class ProgressBarTest(unittest.TestCase):
|
|
|
316
319
|
for _ in concurrent.concurrent_execute(fun, range(5)):
|
|
317
320
|
concurrent.ProgressBar.refresh()
|
|
318
321
|
concurrent.ProgressBar.uninstall(bar_id)
|
|
322
|
+
sys.stderr.flush()
|
|
319
323
|
output_str = string_io.getvalue()
|
|
320
324
|
self.assertIn('100%', output_str)
|
|
321
325
|
self.assertIn('5/5', output_str)
|
|
@@ -332,7 +336,7 @@ class ProgressBarTest(unittest.TestCase):
|
|
|
332
336
|
concurrent.ProgressBar.update(bar_id, 0, status=1)
|
|
333
337
|
concurrent.ProgressBar.uninstall(bar_id)
|
|
334
338
|
sys.stderr.flush()
|
|
335
|
-
|
|
339
|
+
time.sleep(1)
|
|
336
340
|
self.assertIn('1/4', string_io.getvalue())
|
|
337
341
|
# TODO(daiyip): Re-enable once flakiness is fixed.
|
|
338
342
|
# self.assertIn('2/4', string_io.getvalue())
|
|
@@ -564,7 +568,8 @@ class ConcurrentMapTest(unittest.TestCase):
|
|
|
564
568
|
fun, [1, 2, 3], timeout=1.5, max_workers=1, show_progress=True
|
|
565
569
|
)
|
|
566
570
|
], key=lambda x: x[0])
|
|
567
|
-
|
|
571
|
+
sys.stderr.flush()
|
|
572
|
+
|
|
568
573
|
self.assertEqual( # pylint: disable=g-generic-assert
|
|
569
574
|
output,
|
|
570
575
|
[
|
|
@@ -592,6 +597,7 @@ class ConcurrentMapTest(unittest.TestCase):
|
|
|
592
597
|
show_progress=bar_id, status_fn=lambda p: dict(x=1, y=1)
|
|
593
598
|
)
|
|
594
599
|
], key=lambda x: x[0])
|
|
600
|
+
sys.stderr.flush()
|
|
595
601
|
|
|
596
602
|
self.assertEqual( # pylint: disable=g-generic-assert
|
|
597
603
|
output,
|
|
@@ -50,7 +50,7 @@ class TqdmProgressTrackerTest(unittest.TestCase):
|
|
|
50
50
|
string_io = io.StringIO()
|
|
51
51
|
with contextlib.redirect_stderr(string_io):
|
|
52
52
|
_ = experiment.run(root_dir, 'new', plugins=[])
|
|
53
|
-
|
|
53
|
+
sys.stderr.flush()
|
|
54
54
|
self.assertIn('All: 100%', string_io.getvalue())
|
|
55
55
|
|
|
56
56
|
def test_with_example_ids(self):
|
|
@@ -61,7 +61,7 @@ class TqdmProgressTrackerTest(unittest.TestCase):
|
|
|
61
61
|
string_io = io.StringIO()
|
|
62
62
|
with contextlib.redirect_stderr(string_io):
|
|
63
63
|
_ = experiment.run(root_dir, 'new', example_ids=[1], plugins=[])
|
|
64
|
-
|
|
64
|
+
sys.stderr.flush()
|
|
65
65
|
self.assertIn('All: 100%', string_io.getvalue())
|
|
66
66
|
|
|
67
67
|
|
{langfun-0.1.2.dev202510160805.dist-info → langfun-0.1.2.dev202510170805.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langfun
|
|
3
|
-
Version: 0.1.2.
|
|
3
|
+
Version: 0.1.2.dev202510170805
|
|
4
4
|
Summary: Langfun: Language as Functions.
|
|
5
5
|
Home-page: https://github.com/google/langfun
|
|
6
6
|
Author: Langfun Authors
|
|
@@ -21,11 +21,13 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
21
21
|
Classifier: Topic :: Software Development :: Libraries
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
|
24
|
+
Requires-Dist: anyio>=4.7.0
|
|
24
25
|
Requires-Dist: jinja2>=3.1.2
|
|
25
26
|
Requires-Dist: puremagic>=1.20
|
|
26
27
|
Requires-Dist: pyglove>=0.4.5.dev202507140812
|
|
27
28
|
Requires-Dist: requests>=2.31.0
|
|
28
29
|
Provides-Extra: all
|
|
30
|
+
Requires-Dist: anyio>=4.7.0; extra == "all"
|
|
29
31
|
Requires-Dist: jinja2>=3.1.2; extra == "all"
|
|
30
32
|
Requires-Dist: puremagic>=1.20; extra == "all"
|
|
31
33
|
Requires-Dist: pyglove>=0.4.5.dev202507140812; extra == "all"
|
|
@@ -6,13 +6,13 @@ langfun/assistant/capabilities/gui/drawing.py,sha256=8wgol61P7HovLg5EaevRmDPXTFu
|
|
|
6
6
|
langfun/assistant/capabilities/gui/drawing_test.py,sha256=d6LQ1ctG78YRi58UVBdndwyEqTC_ITdk191oA3tASxM,3421
|
|
7
7
|
langfun/assistant/capabilities/gui/location.py,sha256=QYJlY5kUNEwiZFiPYRyFAO7bD2ez4jL5hYn1_AK1ulc,8643
|
|
8
8
|
langfun/assistant/capabilities/gui/location_test.py,sha256=pQUOH1sKuAwjTTYKu615RUnecc_lNrddfvkyxf9297w,9051
|
|
9
|
-
langfun/core/__init__.py,sha256=
|
|
10
|
-
langfun/core/async_support.py,sha256=
|
|
11
|
-
langfun/core/async_support_test.py,sha256=
|
|
9
|
+
langfun/core/__init__.py,sha256=GC4amBXybjSfYVrEQSLFb_KBhH75uD95GKkHNiJfwkY,5011
|
|
10
|
+
langfun/core/async_support.py,sha256=WF4sflm0Q-UHJ8lPtlEo9hSwqXqm1kfaAYVPTyVP3n0,3062
|
|
11
|
+
langfun/core/async_support_test.py,sha256=fMz1ulGrfUCuHp7RtYktuBwpbRN3kCBKnB4LFvaXSAA,1754
|
|
12
12
|
langfun/core/component.py,sha256=g1kQM0bryYYYWVDrSMnHfc74wIBbpfe5_B3s-UIP5GE,3028
|
|
13
13
|
langfun/core/component_test.py,sha256=0CxTgjAud3aj8wBauFhG2FHDqrxCTl4OI4gzQTad-40,9254
|
|
14
14
|
langfun/core/concurrent.py,sha256=zY-pXqlGqss_GI20tM1gXvyW8QepVPUuFNmutcIdhbI,32760
|
|
15
|
-
langfun/core/concurrent_test.py,sha256=
|
|
15
|
+
langfun/core/concurrent_test.py,sha256=KzXOlfR3i_-s_GKBLYrO5-ETCvHoFbFY2o9FEeOeXq4,17818
|
|
16
16
|
langfun/core/console.py,sha256=cLQEf84aDxItA9fStJV22xJch0TqFLNf9hLqwJ0RHmU,2652
|
|
17
17
|
langfun/core/console_test.py,sha256=pBOcuNMJdVELywvroptfcRtJMsegMm3wSlHAL2TdxVk,1679
|
|
18
18
|
langfun/core/langfunc.py,sha256=G50YgoVZ0y1GFw2ev41MlOqr6qa8YakbvNC0h_E0PiA,11140
|
|
@@ -85,7 +85,7 @@ langfun/core/eval/v2/metrics_test.py,sha256=LibZXvWEJDVRY-Mza_bQT-SbmbXCHUnFhL7Z
|
|
|
85
85
|
langfun/core/eval/v2/progress.py,sha256=azZgssQgNdv3IgjKEaQBuGI5ucFDNbdi02P4z_nQ8GE,10292
|
|
86
86
|
langfun/core/eval/v2/progress_test.py,sha256=YU7VHzmy5knPZwj9vpBN3rQQH2tukj9eKHkuBCI62h8,2540
|
|
87
87
|
langfun/core/eval/v2/progress_tracking.py,sha256=zNhNPGlnJnHELEfFpbTMCSXFn8d1IJ57OOYkfFaBFfM,6097
|
|
88
|
-
langfun/core/eval/v2/progress_tracking_test.py,sha256=
|
|
88
|
+
langfun/core/eval/v2/progress_tracking_test.py,sha256=MC7hD-KfxqSIwKK_BN7oGx7HA8O3_fY-Y3cYYAhZzxE,2343
|
|
89
89
|
langfun/core/eval/v2/reporting.py,sha256=yUIPCAMnp7InIzpv1DDWrcLO-75iiOUTpscj7smkfrA,8335
|
|
90
90
|
langfun/core/eval/v2/reporting_test.py,sha256=CMK-vwho8cNRJwlbkCqm_v5fykE7Y3V6SaIOCY0CDyA,5671
|
|
91
91
|
langfun/core/eval/v2/runners.py,sha256=bEniZDNu44AQgvqpwLsvBU4V_7WltAe-NPhYgIsLj1E,16848
|
|
@@ -181,8 +181,8 @@ langfun/env/event_handlers/event_logger.py,sha256=3dbPjBe53dBgntYHlyLlj_77hVecPS
|
|
|
181
181
|
langfun/env/event_handlers/event_logger_test.py,sha256=PGof3rPllNnyzs3Yp8kaOHLeTkVrzUgCJwlODTrVRKI,9111
|
|
182
182
|
langfun/env/event_handlers/metric_writer.py,sha256=NgJKsd6xWOtEd0IjYi7coGEaqGYkkPcDjXN9CQ3vxPU,18043
|
|
183
183
|
langfun/env/event_handlers/metric_writer_test.py,sha256=flRqK10wonhJk4idGD_8jjEjrfjgH0R-qcu-7Bj1G5s,5335
|
|
184
|
-
langfun-0.1.2.
|
|
185
|
-
langfun-0.1.2.
|
|
186
|
-
langfun-0.1.2.
|
|
187
|
-
langfun-0.1.2.
|
|
188
|
-
langfun-0.1.2.
|
|
184
|
+
langfun-0.1.2.dev202510170805.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
|
185
|
+
langfun-0.1.2.dev202510170805.dist-info/METADATA,sha256=3yLUnJv86dB7mQqbEn1zevGRwvvRZpKQjaNdF739BuY,7452
|
|
186
|
+
langfun-0.1.2.dev202510170805.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
187
|
+
langfun-0.1.2.dev202510170805.dist-info/top_level.txt,sha256=RhlEkHxs1qtzmmtWSwYoLVJAc1YrbPtxQ52uh8Z9VvY,8
|
|
188
|
+
langfun-0.1.2.dev202510170805.dist-info/RECORD,,
|
|
File without changes
|
{langfun-0.1.2.dev202510160805.dist-info → langfun-0.1.2.dev202510170805.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{langfun-0.1.2.dev202510160805.dist-info → langfun-0.1.2.dev202510170805.dist-info}/top_level.txt
RENAMED
|
File without changes
|