fabricatio 0.2.11.dev0__cp312-cp312-win_amd64.whl → 0.2.11.dev2__cp312-cp312-win_amd64.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.
@@ -3,12 +3,11 @@
3
3
  from itertools import chain
4
4
  from typing import Any, List, Optional, Self, Tuple, Unpack
5
5
 
6
- from pydantic import Field
7
- from rich import print as r_print
8
-
9
6
  from fabricatio.journal import logger
10
7
  from fabricatio.models.generic import SketchedAble, WithBriefing
11
8
  from fabricatio.utils import ask_edit
9
+ from pydantic import Field
10
+ from rich import print as r_print
12
11
 
13
12
 
14
13
  class Problem(SketchedAble, WithBriefing):
@@ -74,6 +73,7 @@ class ProblemSolutions(SketchedAble):
74
73
  return len(self.solutions) > 0
75
74
 
76
75
  async def edit_problem(self) -> Self:
76
+ """Interactively edit the problem description."""
77
77
  from questionary import text
78
78
 
79
79
  """Interactively edit the problem description."""
@@ -6,7 +6,13 @@ from pathlib import Path
6
6
  from typing import Any, Callable, Dict, Iterable, List, Mapping, Optional, Self, Type, Union, final, overload
7
7
 
8
8
  import ujson
9
+ from fabricatio.config import configs
10
+ from fabricatio.fs.readers import safe_text_read
11
+ from fabricatio.journal import logger
12
+ from fabricatio.parser import JsonCapture
9
13
  from fabricatio.rust import blake3_hash, detect_language
14
+ from fabricatio.rust_instances import TEMPLATE_MANAGER
15
+ from fabricatio.utils import ok
10
16
  from litellm.utils import token_counter
11
17
  from pydantic import (
12
18
  BaseModel,
@@ -21,13 +27,6 @@ from pydantic import (
21
27
  )
22
28
  from pydantic.json_schema import GenerateJsonSchema, JsonSchemaValue
23
29
 
24
- from fabricatio.config import configs
25
- from fabricatio.fs.readers import safe_text_read
26
- from fabricatio.journal import logger
27
- from fabricatio.parser import JsonCapture
28
- from fabricatio.rust_instances import TEMPLATE_MANAGER
29
- from fabricatio.utils import ok
30
-
31
30
 
32
31
  class Base(BaseModel):
33
32
  """Base class for all models with Pydantic configuration.
@@ -75,9 +74,9 @@ class Display(Base):
75
74
  str: Combined display output with boundary markers
76
75
  """
77
76
  return (
78
- "--- Start of Extra Info Sequence ---"
79
- + "\n".join(d.compact() if compact else d.display() for d in seq)
80
- + "--- End of Extra Info Sequence ---"
77
+ "--- Start of Extra Info Sequence ---"
78
+ + "\n".join(d.compact() if compact else d.display() for d in seq)
79
+ + "--- End of Extra Info Sequence ---"
81
80
  )
82
81
 
83
82
 
@@ -179,16 +178,13 @@ class WithRef[T](Base):
179
178
  )
180
179
 
181
180
  @overload
182
- def update_ref[S: WithRef](self: S, reference: T) -> S:
183
- ...
181
+ def update_ref[S: WithRef](self: S, reference: T) -> S: ...
184
182
 
185
183
  @overload
186
- def update_ref[S: WithRef](self: S, reference: "WithRef[T]") -> S:
187
- ...
184
+ def update_ref[S: WithRef](self: S, reference: "WithRef[T]") -> S: ...
188
185
 
189
186
  @overload
190
- def update_ref[S: WithRef](self: S, reference: None = None) -> S:
191
- ...
187
+ def update_ref[S: WithRef](self: S, reference: None = None) -> S: ...
192
188
 
193
189
  def update_ref[S: WithRef](self: S, reference: Union[T, "WithRef[T]", None] = None) -> S: # noqa: PYI019
194
190
  """Update the reference of the object.
@@ -472,9 +468,8 @@ class WithFormatedJsonSchema(Base):
472
468
  str: The JSON schema of the model in a formatted string.
473
469
  """
474
470
  return ujson.dumps(
475
- cls.model_json_schema(schema_generator=UnsortGenerate),
476
- option=ujson.OPT_INDENT_2,
477
- ).decode()
471
+ cls.model_json_schema(schema_generator=UnsortGenerate), indent=2, ensure_ascii=False, sort_keys=False
472
+ )
478
473
 
479
474
 
480
475
  class CreateJsonObjPrompt(WithFormatedJsonSchema):
@@ -884,15 +879,11 @@ class Patch[T](ProposedAble):
884
879
  # copy the desc info of each corresponding fields from `ref_cls`
885
880
  for field_name in [f for f in cls.model_fields if f in ref_cls.model_fields]:
886
881
  my_schema["properties"][field_name]["description"] = (
887
- ref_cls.model_fields[field_name].description or my_schema["properties"][field_name][
888
- "description"]
882
+ ref_cls.model_fields[field_name].description or my_schema["properties"][field_name]["description"]
889
883
  )
890
884
  my_schema["description"] = ref_cls.__doc__
891
885
 
892
- return ujson.dumps(
893
- my_schema,
894
- option=ujson.OPT_INDENT_2,
895
- ).decode()
886
+ return ujson.dumps(my_schema, indent=2, ensure_ascii=False, sort_keys=False)
896
887
 
897
888
 
898
889
  class SequencePatch[T](ProposedUpdateAble):
@@ -68,7 +68,7 @@ class ValidateKwargs[T](GenerateKwargs, total=False):
68
68
 
69
69
  default: Optional[T]
70
70
  max_validations: int
71
-
71
+
72
72
 
73
73
 
74
74
  class CompositeScoreKwargs(ValidateKwargs[List[Dict[str, float]]], total=False):
Binary file
fabricatio/rust.pyi CHANGED
@@ -14,7 +14,6 @@ Key Features:
14
14
  from pathlib import Path
15
15
  from typing import Any, Dict, List, Optional, overload
16
16
 
17
-
18
17
  class TemplateManager:
19
18
  """Template rendering engine using Handlebars templates.
20
19
 
@@ -25,7 +24,7 @@ class TemplateManager:
25
24
  """
26
25
 
27
26
  def __init__(
28
- self, template_dirs: List[Path], suffix: Optional[str] = None, active_loading: Optional[bool] = None
27
+ self, template_dirs: List[Path], suffix: Optional[str] = None, active_loading: Optional[bool] = None
29
28
  ) -> None:
30
29
  """Initialize the template manager.
31
30
 
@@ -56,46 +55,145 @@ class TemplateManager:
56
55
  """
57
56
 
58
57
  @overload
59
- def render_template(self, name: str, data: Dict[str, Any]) -> str:
60
- ...
61
-
58
+ def render_template(self, name: str, data: Dict[str, Any]) -> str: ...
62
59
  @overload
63
- def render_template(self, name: str, data: List[Dict[str, Any]]) -> List[str]:
64
- ...
65
-
60
+ def render_template(self, name: str, data: List[Dict[str, Any]]) -> List[str]: ...
66
61
  def render_template(self, name: str, data: Dict[str, Any] | List[Dict[str, Any]]) -> str | List[str]:
67
62
  """Render a template with context data.
68
-
63
+
69
64
  Args:
70
65
  name: Template name (without extension)
71
66
  data: Context dictionary or list of dictionaries to provide variables to the template
72
-
67
+
73
68
  Returns:
74
69
  Rendered template content as string or list of strings
75
-
70
+
76
71
  Raises:
77
72
  RuntimeError: If template rendering fails
78
73
  """
79
74
 
80
75
  @overload
81
- def render_template_raw(self, template: str, data: Dict[str, Any]) -> str:
82
- ...
83
-
76
+ def render_template_raw(self, template: str, data: Dict[str, Any]) -> str: ...
84
77
  @overload
85
- def render_template_raw(self, template: str, data: List[Dict[str, Any]]) -> List[str]:
86
- ...
87
-
78
+ def render_template_raw(self, template: str, data: List[Dict[str, Any]]) -> List[str]: ...
88
79
  def render_template_raw(self, template: str, data: Dict[str, Any] | List[Dict[str, Any]]) -> str | List[str]:
89
80
  """Render a template with context data.
90
-
81
+
91
82
  Args:
92
83
  template: The template string
93
84
  data: Context dictionary or list of dictionaries to provide variables to the template
94
-
85
+
95
86
  Returns:
96
87
  Rendered template content as string or list of strings
97
88
  """
98
89
 
90
+ class BibManager:
91
+ """BibTeX bibliography manager for parsing and querying citation data."""
92
+
93
+ def __init__(self, path: str) -> None:
94
+ """Initialize the bibliography manager.
95
+
96
+ Args:
97
+ path: Path to BibTeX (.bib) file to load
98
+
99
+ Raises:
100
+ RuntimeError: If file cannot be read or parsed
101
+ """
102
+
103
+ def get_cite_key_by_title(self, title: str) -> Optional[str]:
104
+ """Find citation key by exact title match.
105
+
106
+ Args:
107
+ title: Full title to search for (case-insensitive)
108
+
109
+ Returns:
110
+ Citation key if exact match found, None otherwise
111
+ """
112
+
113
+ def get_cite_key_by_title_fuzzy(self, title: str) -> Optional[str]:
114
+ """Find citation key by fuzzy title match.
115
+
116
+ Args:
117
+ title: Search term to find in bibliography entries
118
+
119
+ Returns:
120
+ Citation key of best matching entry, or None if no good match
121
+ """
122
+
123
+ def get_cite_key_fuzzy(self, query: str) -> Optional[str]:
124
+ """Find best matching citation using fuzzy text search.
125
+
126
+ Args:
127
+ query: Search term to find in bibliography entries
128
+
129
+ Returns:
130
+ Citation key of best matching entry, or None if no good match
131
+
132
+ Notes:
133
+ Uses nucleo_matcher for high-quality fuzzy text searching
134
+ See: https://crates.io/crates/nucleo-matcher
135
+ """
136
+
137
+ def list_titles(self, is_verbatim: Optional[bool] = False) -> List[str]:
138
+ """List all titles in the bibliography.
139
+
140
+ Args:
141
+ is_verbatim: Whether to return verbatim titles (without formatting)
142
+
143
+ Returns:
144
+ List of all titles in the bibliography
145
+ """
146
+
147
+ def get_author_by_key(self, key: str) -> Optional[List[str]]:
148
+ """Retrieve authors by citation key.
149
+
150
+ Args:
151
+ key: Citation key
152
+
153
+ Returns:
154
+ List of authors if found, None otherwise
155
+ """
156
+
157
+ def get_year_by_key(self, key: str) -> Optional[int]:
158
+ """Retrieve the publication year by citation key.
159
+
160
+ Args:
161
+ key: Citation key
162
+
163
+ Returns:
164
+ Publication year if found, None otherwise
165
+ """
166
+
167
+ def get_abstract_by_key(self, key: str) -> Optional[str]:
168
+ """Retrieve the abstract by citation key.
169
+
170
+ Args:
171
+ key: Citation key
172
+
173
+ Returns:
174
+ Abstract if found, None otherwise
175
+ """
176
+
177
+ def get_title_by_key(self, key: str) -> Optional[str]:
178
+ """Retrieve the title by citation key.
179
+
180
+ Args:
181
+ key: Citation key
182
+
183
+ Returns:
184
+ Title if found, None otherwise
185
+ """
186
+
187
+ def get_field_by_key(self, key: str, field: str) -> Optional[str]:
188
+ """Retrieve a specific field by citation key.
189
+
190
+ Args:
191
+ key: Citation key
192
+ field: Field name
193
+
194
+ Returns:
195
+ Field value if found, None otherwise
196
+ """
99
197
 
100
198
  def blake3_hash(content: bytes) -> str:
101
199
  """Calculate the BLAKE3 cryptographic hash of data.
@@ -107,11 +205,9 @@ def blake3_hash(content: bytes) -> str:
107
205
  Hex-encoded BLAKE3 hash string
108
206
  """
109
207
 
110
-
111
208
  def detect_language(string: str) -> str:
112
209
  """Detect the language of a given string."""
113
210
 
114
-
115
211
  def split_word_bounds(string: str) -> List[str]:
116
212
  """Split the string into words based on word boundaries.
117
213
 
@@ -122,7 +218,6 @@ def split_word_bounds(string: str) -> List[str]:
122
218
  A list of words extracted from the string.
123
219
  """
124
220
 
125
-
126
221
  def split_sentence_bounds(string: str) -> List[str]:
127
222
  """Split the string into sentences based on sentence boundaries.
128
223
 
@@ -133,7 +228,6 @@ def split_sentence_bounds(string: str) -> List[str]:
133
228
  A list of sentences extracted from the string.
134
229
  """
135
230
 
136
-
137
231
  def split_into_chunks(string: str, max_chunk_size: int, max_overlapping_rate: float = 0.3) -> List[str]:
138
232
  """Split the string into chunks of a specified size.
139
233
 
@@ -146,7 +240,6 @@ def split_into_chunks(string: str, max_chunk_size: int, max_overlapping_rate: fl
146
240
  A list of chunks extracted from the string.
147
241
  """
148
242
 
149
-
150
243
  def word_count(string: str) -> int:
151
244
  """Count the number of words in the string.
152
245
 
@@ -157,67 +250,51 @@ def word_count(string: str) -> int:
157
250
  The number of words in the string.
158
251
  """
159
252
 
160
-
161
253
  def is_chinese(string: str) -> bool:
162
254
  """Check if the given string is in Chinese."""
163
255
 
164
-
165
256
  def is_english(string: str) -> bool:
166
257
  """Check if the given string is in English."""
167
258
 
168
-
169
259
  def is_japanese(string: str) -> bool:
170
260
  """Check if the given string is in Japanese."""
171
261
 
172
-
173
262
  def is_korean(string: str) -> bool:
174
263
  """Check if the given string is in Korean."""
175
264
 
176
-
177
265
  def is_arabic(string: str) -> bool:
178
266
  """Check if the given string is in Arabic."""
179
267
 
180
-
181
268
  def is_russian(string: str) -> bool:
182
269
  """Check if the given string is in Russian."""
183
270
 
184
-
185
271
  def is_german(string: str) -> bool:
186
272
  """Check if the given string is in German."""
187
273
 
188
-
189
274
  def is_french(string: str) -> bool:
190
275
  """Check if the given string is in French."""
191
276
 
192
-
193
277
  def is_hindi(string: str) -> bool:
194
278
  """Check if the given string is in Hindi."""
195
279
 
196
-
197
280
  def is_italian(string: str) -> bool:
198
281
  """Check if the given string is in Italian."""
199
282
 
200
-
201
283
  def is_dutch(string: str) -> bool:
202
284
  """Check if the given string is in Dutch."""
203
285
 
204
-
205
286
  def is_portuguese(string: str) -> bool:
206
287
  """Check if the given string is in Portuguese."""
207
288
 
208
-
209
289
  def is_swedish(string: str) -> bool:
210
290
  """Check if the given string is in Swedish."""
211
291
 
212
-
213
292
  def is_turkish(string: str) -> bool:
214
293
  """Check if the given string is in Turkish."""
215
294
 
216
-
217
295
  def is_vietnamese(string: str) -> bool:
218
296
  """Check if the given string is in Vietnamese."""
219
297
 
220
-
221
298
  def tex_to_typst(string: str) -> str:
222
299
  """Convert TeX to Typst.
223
300
 
@@ -228,7 +305,6 @@ def tex_to_typst(string: str) -> str:
228
305
  The converted Typst string.
229
306
  """
230
307
 
231
-
232
308
  def convert_all_inline_tex(string: str) -> str:
233
309
  """Convert all inline TeX code in the string.
234
310
 
@@ -239,7 +315,6 @@ def convert_all_inline_tex(string: str) -> str:
239
315
  The converted string with inline TeX code replaced.
240
316
  """
241
317
 
242
-
243
318
  def convert_all_block_tex(string: str) -> str:
244
319
  """Convert all block TeX code in the string.
245
320
 
@@ -250,111 +325,22 @@ def convert_all_block_tex(string: str) -> str:
250
325
  The converted string with block TeX code replaced.
251
326
  """
252
327
 
328
+ def comment(string: str) -> str:
329
+ """Add comment to the string.
253
330
 
254
- class BibManager:
255
- """BibTeX bibliography manager for parsing and querying citation data."""
256
-
257
- def __init__(self, path: str) -> None:
258
- """Initialize the bibliography manager.
259
-
260
- Args:
261
- path: Path to BibTeX (.bib) file to load
262
-
263
- Raises:
264
- RuntimeError: If file cannot be read or parsed
265
- """
266
-
267
- def get_cite_key_by_title(self, title: str) -> Optional[str]:
268
- """Find citation key by exact title match.
269
-
270
- Args:
271
- title: Full title to search for (case-insensitive)
272
-
273
- Returns:
274
- Citation key if exact match found, None otherwise
275
- """
276
-
277
- def get_cite_key_by_title_fuzzy(self, title: str) -> Optional[str]:
278
- """Find citation key by fuzzy title match.
279
-
280
- Args:
281
- title: Search term to find in bibliography entries
282
-
283
- Returns:
284
- Citation key of best matching entry, or None if no good match
285
- """
286
-
287
- def get_cite_key_fuzzy(self, query: str) -> Optional[str]:
288
- """Find best matching citation using fuzzy text search.
289
-
290
- Args:
291
- query: Search term to find in bibliography entries
292
-
293
- Returns:
294
- Citation key of best matching entry, or None if no good match
295
-
296
- Notes:
297
- Uses nucleo_matcher for high-quality fuzzy text searching
298
- See: https://crates.io/crates/nucleo-matcher
299
- """
300
-
301
- def list_titles(self, is_verbatim: Optional[bool] = False) -> List[str]:
302
- """List all titles in the bibliography.
303
-
304
- Args:
305
- is_verbatim: Whether to return verbatim titles (without formatting)
306
-
307
- Returns:
308
- List of all titles in the bibliography
309
- """
310
-
311
- def get_author_by_key(self, key: str) -> Optional[List[str]]:
312
- """Retrieve authors by citation key.
313
-
314
- Args:
315
- key: Citation key
316
-
317
- Returns:
318
- List of authors if found, None otherwise
319
- """
320
-
321
- def get_year_by_key(self, key: str) -> Optional[int]:
322
- """Retrieve the publication year by citation key.
323
-
324
- Args:
325
- key: Citation key
326
-
327
- Returns:
328
- Publication year if found, None otherwise
329
- """
330
-
331
- def get_abstract_by_key(self, key: str) -> Optional[str]:
332
- """Retrieve the abstract by citation key.
333
-
334
- Args:
335
- key: Citation key
336
-
337
- Returns:
338
- Abstract if found, None otherwise
339
- """
340
-
341
- def get_title_by_key(self, key: str) -> Optional[str]:
342
- """Retrieve the title by citation key.
343
-
344
- Args:
345
- key: Citation key
331
+ Args:
332
+ string: The input string to which comments will be added.
346
333
 
347
- Returns:
348
- Title if found, None otherwise
349
- """
334
+ Returns:
335
+ The string with each line prefixed by '// '.
336
+ """
350
337
 
351
- def get_field_by_key(self, key: str, field: str) -> Optional[str]:
352
- """Retrieve a specific field by citation key.
338
+ def uncomment(string: str) -> str:
339
+ """Remove comment from the string.
353
340
 
354
- Args:
355
- key: Citation key
356
- field: Field name
341
+ Args:
342
+ string: The input string from which comments will be removed.
357
343
 
358
- Returns:
359
- Field value if found, None otherwise
360
- """
344
+ Returns:
345
+ The string with comments (lines starting with '// ' or '//') removed.
346
+ """
fabricatio/utils.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """A collection of utility functions for the fabricatio package."""
2
2
 
3
- from typing import Any, Dict, List, Mapping, Optional
3
+ from typing import Any, Dict, List, Mapping, Optional, overload
4
4
 
5
5
  from fabricatio.decorators import precheck_package
6
6
 
@@ -8,9 +8,7 @@ from fabricatio.decorators import precheck_package
8
8
  @precheck_package(
9
9
  "questionary", "'questionary' is required to run this function. Have you installed `fabricatio[qa]`?."
10
10
  )
11
- async def ask_edit(
12
- text_seq: List[str],
13
- ) -> List[str]:
11
+ async def ask_edit(text_seq: List[str]) -> List[str]:
14
12
  """Asks the user to edit a list of texts.
15
13
 
16
14
  Args:
@@ -30,6 +28,29 @@ async def ask_edit(
30
28
  return res
31
29
 
32
30
 
31
+ @overload
32
+ async def ask_retain[V](candidates: List[str]) -> List[str]: ...
33
+
34
+
35
+ @overload
36
+ async def ask_retain[V](candidates: List[str], value_mapping: List[V]) -> List[V]: ...
37
+
38
+
39
+ @precheck_package(
40
+ "questionary", "'questionary' is required to run this function. Have you installed `fabricatio[qa]`?."
41
+ )
42
+ async def ask_retain[V](candidates: List[str], value_mapping: Optional[List[V]] = None) -> List[str] | List[V]:
43
+ """Asks the user to retain a list of candidates."""
44
+ from questionary import Choice, checkbox
45
+
46
+ return await checkbox(
47
+ "Please choose those that should be retained.",
48
+ choices=[Choice(p, value=p, checked=True) for p in candidates]
49
+ if value_mapping is None
50
+ else [Choice(p, value=v) for p, v in zip(candidates, value_mapping, strict=True)],
51
+ ).ask_async()
52
+
53
+
33
54
  def override_kwargs(kwargs: Mapping[str, Any], **overrides) -> Dict[str, Any]:
34
55
  """Override the values in kwargs with the provided overrides."""
35
56
  new_kwargs = dict(kwargs.items())
@@ -71,5 +92,3 @@ def wrapp_in_block(string: str, title: str, style: str = "-") -> str:
71
92
  str: The wrapped string.
72
93
  """
73
94
  return f"--- Start of {title} ---\n{string}\n--- End of {title} ---".replace("-", style)
74
-
75
-
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fabricatio
3
- Version: 0.2.11.dev0
3
+ Version: 0.2.11.dev2
4
4
  Classifier: License :: OSI Approved :: MIT License
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: Programming Language :: Python :: 3.12