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.
- fabricatio/actions/article.py +27 -8
- fabricatio/actions/article_rag.py +152 -54
- fabricatio/capabilities/extract.py +6 -1
- fabricatio/config.py +1 -1
- fabricatio/decorators.py +27 -10
- fabricatio/models/extra/aricle_rag.py +15 -8
- fabricatio/models/extra/article_base.py +27 -8
- fabricatio/models/extra/article_main.py +9 -3
- fabricatio/models/extra/problem.py +3 -3
- fabricatio/models/generic.py +16 -25
- fabricatio/models/kwargs_types.py +1 -1
- fabricatio/rust.cp312-win_amd64.pyd +0 -0
- fabricatio/rust.pyi +131 -145
- fabricatio/utils.py +25 -6
- fabricatio-0.2.11.dev2.data/scripts/tdown.exe +0 -0
- {fabricatio-0.2.11.dev0.dist-info → fabricatio-0.2.11.dev2.dist-info}/METADATA +1 -1
- {fabricatio-0.2.11.dev0.dist-info → fabricatio-0.2.11.dev2.dist-info}/RECORD +19 -19
- fabricatio-0.2.11.dev0.data/scripts/tdown.exe +0 -0
- {fabricatio-0.2.11.dev0.dist-info → fabricatio-0.2.11.dev2.dist-info}/WHEEL +0 -0
- {fabricatio-0.2.11.dev0.dist-info → fabricatio-0.2.11.dev2.dist-info}/licenses/LICENSE +0 -0
@@ -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."""
|
fabricatio/models/generic.py
CHANGED
@@ -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
|
-
|
79
|
-
|
80
|
-
|
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
|
-
|
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
|
-
|
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):
|
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
|
-
|
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
|
-
|
255
|
-
|
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
|
-
|
348
|
-
|
349
|
-
|
334
|
+
Returns:
|
335
|
+
The string with each line prefixed by '// '.
|
336
|
+
"""
|
350
337
|
|
351
|
-
|
352
|
-
|
338
|
+
def uncomment(string: str) -> str:
|
339
|
+
"""Remove comment from the string.
|
353
340
|
|
354
|
-
|
355
|
-
|
356
|
-
field: Field name
|
341
|
+
Args:
|
342
|
+
string: The input string from which comments will be removed.
|
357
343
|
|
358
|
-
|
359
|
-
|
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
|
-
|
Binary file
|