langfun 0.1.2.dev202412050804__py3-none-any.whl → 0.1.2.dev202412070804__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.
@@ -16,7 +16,7 @@
16
16
  import functools
17
17
  import inspect
18
18
  import re
19
- from typing import Any, Callable, Optional, Tuple
19
+ from typing import Any, Callable, Literal, Optional, Tuple
20
20
 
21
21
  from langfun.core import language_model
22
22
  from langfun.core import template
@@ -25,7 +25,7 @@ from langfun.core.structured import prompting
25
25
  import pyglove as pg
26
26
 
27
27
 
28
- def unittest_gen(signature, lm, num_retries=10):
28
+ def unittest_gen(signature, lm, num_retries=1):
29
29
  """Generates unit tests for a python function signature."""
30
30
 
31
31
  class UnitTest(pg.Object):
@@ -78,10 +78,13 @@ def _function_gen(
78
78
  func: Callable[..., Any],
79
79
  signature: str,
80
80
  lm: language_model.LanguageModel,
81
- num_retries: int = 10,
81
+ num_retries: int = 1,
82
82
  unittest: Optional[
83
- Callable[[Callable[..., Any]], None] | list[Tuple[Any, Any]]
83
+ Callable[[Callable[..., Any]], None]
84
+ | list[Tuple[Any, Any]]
85
+ | Literal["auto"]
84
86
  ] = None,
87
+ unittest_num_retries: int = 1,
85
88
  ):
86
89
  """Generates a python function with LLM and verify its quality with unit testing."""
87
90
 
@@ -131,9 +134,11 @@ def _function_gen(
131
134
  """
132
135
 
133
136
  unittest_examples = None
134
- if unittest is None:
135
- unittest_examples = unittest_gen(signature, lm=lm)
136
- elif not callable(unittest):
137
+ if unittest == "auto":
138
+ unittest_examples = unittest_gen(
139
+ signature, lm=lm, num_retries=unittest_num_retries
140
+ )
141
+ elif isinstance(unittest, list):
137
142
  unittest_examples = unittest
138
143
 
139
144
  for _ in range(num_retries):
@@ -145,11 +150,16 @@ def _function_gen(
145
150
 
146
151
  # Check whether the sigantures are the same.
147
152
  if inspect.signature(f) != inspect.signature(func):
153
+ pg.logging.warning(
154
+ "Signature mismatch. Expected: %s, Actual: %s",
155
+ inspect.signature(func),
156
+ inspect.signature(f),
157
+ )
148
158
  continue
149
159
 
150
160
  if callable(unittest):
151
161
  unittest(f)
152
- else:
162
+ elif unittest_examples:
153
163
  unittest_with_test_cases(f, unittest_examples)
154
164
 
155
165
  return f, source_code
@@ -172,10 +182,13 @@ def _process_signature(signature):
172
182
  def function_gen(
173
183
  lm: language_model.LanguageModel,
174
184
  cache_filename: str | None = None,
175
- num_retries: int = 10,
185
+ num_retries: int = 1,
176
186
  unittest: Optional[
177
- Callable[[Callable[..., Any]], None] | list[Tuple[Any, Any]]
187
+ Callable[[Callable[..., Any]], None]
188
+ | list[Tuple[Any, Any]]
189
+ | Literal["auto"]
178
190
  ] = None,
191
+ unittest_num_retries: int = 1,
179
192
  ):
180
193
  """A decorator for automating function generation using a language model.
181
194
 
@@ -192,9 +205,12 @@ def function_gen(
192
205
  make to generate a suitable function implementation.
193
206
  unittest: This optional parameter enables the definition of custom unit
194
207
  tests. You can either provide a list of test cases as tuples of inputs
195
- and outputs, or a function that throws an error if a test fails. If left
196
- as None (the default setting), the LLM will automatically create the
197
- unit test cases.
208
+ and outputs, or a function that throws an error if a test fails, or let
209
+ LLM automatically create the unit test cases. If a generated function is
210
+ and returned, it should pass all the unittests.
211
+ unittest_num_retries: If unittest is set to "auto", this parameter
212
+ specifies the number of times the LLM's attempts to generate unit test
213
+ cases.
198
214
 
199
215
  Returns:
200
216
  The implemented function object.
@@ -226,7 +242,12 @@ def function_gen(
226
242
  return func.__function__(*args, **kwargs)
227
243
 
228
244
  func.__function__, func.__source_code__ = _function_gen(
229
- func, signature, lm, num_retries=num_retries, unittest=unittest
245
+ func,
246
+ signature,
247
+ lm,
248
+ num_retries=num_retries,
249
+ unittest=unittest,
250
+ unittest_num_retries=unittest_num_retries,
230
251
  )
231
252
  if func.__function__ is None:
232
253
  raise ValueError(f"Function generation failed. Signature:\n{signature}")
@@ -63,6 +63,42 @@ class FunctionGenerationTest(unittest.TestCase):
63
63
 
64
64
  lm = fake.StaticSequence([unittest_lm_response, function_gen_lm_response])
65
65
 
66
+ @function_generation.function_gen(lm=lm, unittest='auto')
67
+ def linear_search(items, target): # pylint: disable=unused-argument
68
+ """Performs a linear search on a list to find a target value.
69
+
70
+ Args:
71
+ items (list): The list to search within.
72
+ target: The value to search for.
73
+
74
+ Returns:
75
+ int: The index of the target value if found, otherwise -1.
76
+ """
77
+
78
+ self.assertEqual(linear_search(['a', 'b', 'c'], 'c'), 2)
79
+ self.assertEqual(linear_search.source(), function_gen_lm_response)
80
+
81
+ def test_generate_function_without_unittest(self):
82
+ function_gen_lm_response = inspect.cleandoc("""
83
+ def linear_search(items, target):
84
+ \"\"\"
85
+ Performs a linear search on a list to find a target value.
86
+
87
+ Args:
88
+ items (list): The list to search within.
89
+ target: The value to search for.
90
+
91
+ Returns:
92
+ int: The index of the target value if found, otherwise -1.
93
+ \"\"\"
94
+ for i, item in enumerate(items):
95
+ if item == target:
96
+ return i
97
+ return -1
98
+ """)
99
+
100
+ lm = fake.StaticSequence([function_gen_lm_response])
101
+
66
102
  @function_generation.function_gen(lm=lm)
67
103
  def linear_search(items, target): # pylint: disable=unused-argument
68
104
  """Performs a linear search on a list to find a target value.
@@ -258,7 +294,9 @@ class FunctionGenerationTest(unittest.TestCase):
258
294
  cache_file = os.path.join(cache_file_dir, 'cache_file.json')
259
295
 
260
296
  @function_generation.function_gen(
261
- lm=lm, unittest=_unittest_fn, cache_filename=cache_file
297
+ lm=lm,
298
+ unittest=_unittest_fn,
299
+ cache_filename=cache_file,
262
300
  )
263
301
  def linear_search(items, target): # pylint: disable=unused-argument
264
302
  """Performs a linear search on a list to find a target value.
@@ -310,7 +348,9 @@ class FunctionGenerationTest(unittest.TestCase):
310
348
 
311
349
  custom_unittest = _unittest_fn
312
350
 
313
- @function_generation.function_gen(lm=lm, unittest=custom_unittest)
351
+ @function_generation.function_gen(
352
+ lm=lm, unittest=custom_unittest, num_retries=2
353
+ )
314
354
  def linear_search(items, target): # pylint: disable=unused-argument
315
355
  """Performs a linear search on a list to find a target value.
316
356
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langfun
3
- Version: 0.1.2.dev202412050804
3
+ Version: 0.1.2.dev202412070804
4
4
  Summary: Langfun: Language as Functions.
5
5
  Home-page: https://github.com/google/langfun
6
6
  Author: Langfun Authors
@@ -123,8 +123,8 @@ langfun/core/structured/completion.py,sha256=cS2PjG7sqzDu5x0xoTk8RmNcoeX55iVwH38
123
123
  langfun/core/structured/completion_test.py,sha256=lendf6nPsNfAmd5A7k3v_HS2At9F_jjbKBcV7OEt94o,19310
124
124
  langfun/core/structured/description.py,sha256=SXW4MJvshFjbR-0gw6rE21o6WXq12UlRXawvDBXMZFA,5211
125
125
  langfun/core/structured/description_test.py,sha256=UtZGjSFUaQ6130t1E5tcL7ODu0xIefkapb53TbnqsK8,7362
126
- langfun/core/structured/function_generation.py,sha256=pFgS3vcRAWiuFBol2x5Eeip3XqoudONsOpeJpWyjT3s,7479
127
- langfun/core/structured/function_generation_test.py,sha256=ZJI-aaGgWWszn92u7h5IZ9Pl70N2DgAGGJrIxPzsvwg,10065
126
+ langfun/core/structured/function_generation.py,sha256=gOV5B4KXzN6ng1P1QtZ8aOAEQB8eAbgwWGj57tnzWJY,8159
127
+ langfun/core/structured/function_generation_test.py,sha256=1OtstouOYyYOd_gmZtL8RRbh-FcYGEvBNju6lNrJrOA,11331
128
128
  langfun/core/structured/mapping.py,sha256=vLKH79UT-j0qkQdvqlQBO7SkXXuM-yr2Idm8_HH8qwM,13649
129
129
  langfun/core/structured/mapping_test.py,sha256=bHm2ZCXBITq_G8Lvw_olFHeUUc4s_lGXZm9v9JhoPB4,9630
130
130
  langfun/core/structured/parsing.py,sha256=D58wBWOC6r6DCJNychCDkiHPrsy1XJfBDCDDZtug00k,11765
@@ -148,8 +148,8 @@ langfun/core/templates/demonstration.py,sha256=vCrgYubdZM5Umqcgp8NUVGXgr4P_c-fik
148
148
  langfun/core/templates/demonstration_test.py,sha256=SafcDQ0WgI7pw05EmPI2S4v1t3ABKzup8jReCljHeK4,2162
149
149
  langfun/core/templates/selfplay.py,sha256=yhgrJbiYwq47TgzThmHrDQTF4nDrTI09CWGhuQPNv-s,2273
150
150
  langfun/core/templates/selfplay_test.py,sha256=Ot__1P1M8oJfoTp-M9-PQ6HUXqZKyMwvZ5f7yQ3yfyM,2326
151
- langfun-0.1.2.dev202412050804.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
152
- langfun-0.1.2.dev202412050804.dist-info/METADATA,sha256=8ZkJgyA-BfFziFIsZ96fuJkEf9wyf9bci5BoWx8X0Xk,8281
153
- langfun-0.1.2.dev202412050804.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
154
- langfun-0.1.2.dev202412050804.dist-info/top_level.txt,sha256=RhlEkHxs1qtzmmtWSwYoLVJAc1YrbPtxQ52uh8Z9VvY,8
155
- langfun-0.1.2.dev202412050804.dist-info/RECORD,,
151
+ langfun-0.1.2.dev202412070804.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
152
+ langfun-0.1.2.dev202412070804.dist-info/METADATA,sha256=Ao9kzm8AFw7749nP7p_m3k41rVcBBzG8_QuMnLLN9_U,8281
153
+ langfun-0.1.2.dev202412070804.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
154
+ langfun-0.1.2.dev202412070804.dist-info/top_level.txt,sha256=RhlEkHxs1qtzmmtWSwYoLVJAc1YrbPtxQ52uh8Z9VvY,8
155
+ langfun-0.1.2.dev202412070804.dist-info/RECORD,,