fabricatio 0.2.8.dev3__cp312-cp312-manylinux_2_34_x86_64.whl → 0.2.8.dev4__cp312-cp312-manylinux_2_34_x86_64.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/_rust.cpython-312-x86_64-linux-gnu.so +0 -0
- fabricatio/actions/article.py +60 -85
- fabricatio/actions/article_rag.py +54 -43
- fabricatio/capabilities/censor.py +87 -0
- fabricatio/capabilities/check.py +126 -29
- fabricatio/capabilities/correct.py +142 -99
- fabricatio/capabilities/rating.py +61 -13
- fabricatio/config.py +9 -3
- fabricatio/models/action.py +4 -5
- fabricatio/models/adv_kwargs_types.py +25 -0
- fabricatio/models/extra/advanced_judge.py +5 -2
- fabricatio/models/extra/article_base.py +3 -20
- fabricatio/models/extra/article_main.py +2 -3
- fabricatio/models/extra/patches.py +7 -0
- fabricatio/models/extra/problem.py +41 -8
- fabricatio/models/extra/rule.py +2 -4
- fabricatio/models/generic.py +45 -6
- fabricatio/models/kwargs_types.py +23 -17
- fabricatio/models/usages.py +11 -16
- fabricatio/parser.py +7 -8
- fabricatio-0.2.8.dev4.data/scripts/tdown +0 -0
- {fabricatio-0.2.8.dev3.dist-info → fabricatio-0.2.8.dev4.dist-info}/METADATA +1 -1
- {fabricatio-0.2.8.dev3.dist-info → fabricatio-0.2.8.dev4.dist-info}/RECORD +25 -22
- fabricatio-0.2.8.dev3.data/scripts/tdown +0 -0
- {fabricatio-0.2.8.dev3.dist-info → fabricatio-0.2.8.dev4.dist-info}/WHEEL +0 -0
- {fabricatio-0.2.8.dev3.dist-info → fabricatio-0.2.8.dev4.dist-info}/licenses/LICENSE +0 -0
Binary file
|
fabricatio/actions/article.py
CHANGED
@@ -5,21 +5,24 @@ from pathlib import Path
|
|
5
5
|
from typing import Any, Callable, List, Optional
|
6
6
|
|
7
7
|
from fabricatio._rust import BibManager
|
8
|
-
from fabricatio.capabilities.
|
8
|
+
from fabricatio.capabilities.censor import Censor
|
9
|
+
from fabricatio.capabilities.correct import Correct
|
10
|
+
from fabricatio.capabilities.propose import Propose
|
9
11
|
from fabricatio.fs import safe_text_read
|
10
12
|
from fabricatio.journal import logger
|
11
13
|
from fabricatio.models.action import Action
|
12
|
-
from fabricatio.models.extra.article_base import
|
14
|
+
from fabricatio.models.extra.article_base import ArticleRefSequencePatch
|
13
15
|
from fabricatio.models.extra.article_essence import ArticleEssence
|
14
16
|
from fabricatio.models.extra.article_main import Article
|
15
17
|
from fabricatio.models.extra.article_outline import ArticleOutline
|
16
18
|
from fabricatio.models.extra.article_proposal import ArticleProposal
|
19
|
+
from fabricatio.models.extra.rule import RuleSet
|
17
20
|
from fabricatio.models.task import Task
|
18
21
|
from fabricatio.utils import ok
|
19
22
|
from more_itertools import filter_map
|
20
23
|
|
21
24
|
|
22
|
-
class ExtractArticleEssence(Action):
|
25
|
+
class ExtractArticleEssence(Action, Propose):
|
23
26
|
"""Extract the essence of article(s) in text format from the paths specified in the task dependencies.
|
24
27
|
|
25
28
|
Notes:
|
@@ -47,11 +50,11 @@ class ExtractArticleEssence(Action):
|
|
47
50
|
out = []
|
48
51
|
|
49
52
|
for ess in await self.propose(
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
53
|
+
ArticleEssence,
|
54
|
+
[
|
55
|
+
f"{c}\n\n\nBased the provided academic article above, you need to extract the essence from it."
|
56
|
+
for c in contents
|
57
|
+
],
|
55
58
|
):
|
56
59
|
if ess is None:
|
57
60
|
logger.warning("Could not extract article essence")
|
@@ -91,7 +94,7 @@ class FixArticleEssence(Action):
|
|
91
94
|
return out
|
92
95
|
|
93
96
|
|
94
|
-
class GenerateArticleProposal(Action):
|
97
|
+
class GenerateArticleProposal(Action, Propose):
|
95
98
|
"""Generate an outline for the article based on the extracted essence."""
|
96
99
|
|
97
100
|
output_key: str = "article_proposal"
|
@@ -133,7 +136,7 @@ class GenerateArticleProposal(Action):
|
|
133
136
|
return proposal
|
134
137
|
|
135
138
|
|
136
|
-
class GenerateInitialOutline(Action):
|
139
|
+
class GenerateInitialOutline(Action, Propose):
|
137
140
|
"""Generate the initial article outline based on the article proposal."""
|
138
141
|
|
139
142
|
output_key: str = "initial_article_outline"
|
@@ -153,38 +156,29 @@ class GenerateInitialOutline(Action):
|
|
153
156
|
).update_ref(article_proposal)
|
154
157
|
|
155
158
|
|
156
|
-
class FixIntrospectedErrors(Action):
|
159
|
+
class FixIntrospectedErrors(Action, Censor):
|
157
160
|
"""Fix introspected errors in the article outline."""
|
158
161
|
|
159
162
|
output_key: str = "introspected_errors_fixed_outline"
|
160
163
|
"""The key of the output data."""
|
161
164
|
|
165
|
+
ruleset: Optional[RuleSet] = None
|
166
|
+
"""The ruleset to use to fix the introspected errors."""
|
167
|
+
|
162
168
|
async def _execute(
|
163
169
|
self,
|
164
170
|
article_outline: ArticleOutline,
|
165
|
-
|
171
|
+
ruleset: Optional[RuleSet] = None,
|
166
172
|
**_,
|
167
173
|
) -> Optional[ArticleOutline]:
|
168
|
-
introspect_manual = ok(
|
169
|
-
await self.draft_rating_manual(
|
170
|
-
topic=(
|
171
|
-
intro_topic
|
172
|
-
:= "Fix the error in the article outline, make sure there is no more error in the article outline."
|
173
|
-
),
|
174
|
-
),
|
175
|
-
"Could not generate the rating manual.",
|
176
|
-
)
|
177
|
-
|
178
174
|
while pack := article_outline.find_introspected():
|
179
175
|
component, err = ok(pack)
|
180
176
|
logger.warning(f"Found introspected error: {err}")
|
181
177
|
corrected = ok(
|
182
|
-
await self.
|
178
|
+
await self.censor_obj(
|
183
179
|
component,
|
184
|
-
|
185
|
-
|
186
|
-
rating_manual=introspect_manual,
|
187
|
-
supervisor_check=supervisor_check,
|
180
|
+
ruleset=ok(ruleset or self.ruleset, "No ruleset provided"),
|
181
|
+
reference=f"# Original Article Outline\n{article_outline.display()}\n# Some Basic errors found from `{component.title}` that need to be fixed\n{err}",
|
188
182
|
),
|
189
183
|
"Could not correct the component.",
|
190
184
|
)
|
@@ -193,38 +187,29 @@ class FixIntrospectedErrors(Action):
|
|
193
187
|
return article_outline
|
194
188
|
|
195
189
|
|
196
|
-
class FixIllegalReferences(Action):
|
190
|
+
class FixIllegalReferences(Action, Censor):
|
197
191
|
"""Fix illegal references in the article outline."""
|
198
192
|
|
199
193
|
output_key: str = "illegal_references_fixed_outline"
|
200
194
|
"""The key of the output data."""
|
201
195
|
|
196
|
+
ruleset: Optional[RuleSet] = None
|
197
|
+
"""Ruleset to use to fix the illegal references."""
|
198
|
+
|
202
199
|
async def _execute(
|
203
200
|
self,
|
204
201
|
article_outline: ArticleOutline,
|
205
|
-
|
202
|
+
ruleset: Optional[RuleSet] = None,
|
206
203
|
**_,
|
207
204
|
) -> Optional[ArticleOutline]:
|
208
|
-
ref_manual = ok(
|
209
|
-
await self.draft_rating_manual(
|
210
|
-
topic=(
|
211
|
-
ref_topic
|
212
|
-
:= "Fix the internal referring error, make sure there is no more `ArticleRef` pointing to a non-existing article component."
|
213
|
-
),
|
214
|
-
),
|
215
|
-
"Could not generate the rating manual.",
|
216
|
-
)
|
217
|
-
|
218
205
|
while pack := article_outline.find_illegal_ref(gather_identical=True):
|
219
206
|
refs, err = ok(pack)
|
220
207
|
logger.warning(f"Found illegal referring error: {err}")
|
221
208
|
corrected_ref = ok(
|
222
|
-
await self.
|
209
|
+
await self.censor_obj(
|
223
210
|
refs[0], # pyright: ignore [reportIndexIssue]
|
224
|
-
|
225
|
-
|
226
|
-
rating_manual=ref_manual,
|
227
|
-
supervisor_check=supervisor_check,
|
211
|
+
ruleset=ok(ruleset or self.ruleset, "No ruleset provided"),
|
212
|
+
reference=f"# Original Article Outline\n{article_outline.display()}\n# Some Basic errors found that need to be fixed\n{err}",
|
228
213
|
)
|
229
214
|
)
|
230
215
|
for ref in refs:
|
@@ -233,43 +218,40 @@ class FixIllegalReferences(Action):
|
|
233
218
|
return article_outline.update_ref(article_outline)
|
234
219
|
|
235
220
|
|
236
|
-
class TweakOutlineForwardRef(Action,
|
221
|
+
class TweakOutlineForwardRef(Action, Censor):
|
237
222
|
"""Tweak the forward references in the article outline.
|
238
223
|
|
239
224
|
Ensures that the conclusions of the current chapter effectively support the analysis of subsequent chapters.
|
240
225
|
"""
|
241
226
|
|
242
227
|
output_key: str = "article_outline_fw_ref_checked"
|
228
|
+
ruleset: Optional[RuleSet] = None
|
229
|
+
"""Ruleset to use to fix the illegal references."""
|
243
230
|
|
244
|
-
async def _execute(
|
231
|
+
async def _execute(
|
232
|
+
self, article_outline: ArticleOutline, ruleset: Optional[RuleSet] = None, **cxt
|
233
|
+
) -> ArticleOutline:
|
245
234
|
return await self._inner(
|
246
235
|
article_outline,
|
247
|
-
|
248
|
-
topic="Ensure conclusions support the analysis of subsequent chapters, sections or subsections.",
|
236
|
+
ruleset=ok(ruleset or self.ruleset, "No ruleset provided"),
|
249
237
|
field_name="support_to",
|
250
238
|
)
|
251
239
|
|
252
|
-
async def _inner(
|
253
|
-
self, article_outline: ArticleOutline, supervisor_check: bool, topic: str, field_name: str
|
254
|
-
) -> ArticleOutline:
|
255
|
-
tweak_support_to_manual = ok(
|
256
|
-
await self.draft_rating_manual(topic),
|
257
|
-
"Could not generate the rating manual.",
|
258
|
-
)
|
240
|
+
async def _inner(self, article_outline: ArticleOutline, ruleset: RuleSet, field_name: str) -> ArticleOutline:
|
259
241
|
for a in article_outline.iter_dfs():
|
260
|
-
if await self.evidently_judge(
|
242
|
+
if judge := await self.evidently_judge(
|
261
243
|
f"{article_outline.as_prompt()}\n\n{a.display()}\n"
|
262
244
|
f"Does the `{a.__class__.__name__}`'s `{field_name}` field need to be extended or tweaked?"
|
263
245
|
):
|
264
|
-
patch =
|
246
|
+
patch = ArticleRefSequencePatch.default()
|
265
247
|
patch.tweaked = getattr(a, field_name)
|
266
248
|
|
267
|
-
await self.
|
249
|
+
await self.censor_obj_inplace(
|
268
250
|
patch,
|
269
|
-
|
270
|
-
reference=f"{article_outline.as_prompt()}\
|
271
|
-
|
272
|
-
|
251
|
+
ruleset=ruleset,
|
252
|
+
reference=f"{article_outline.as_prompt()}\n"
|
253
|
+
f"The Article component titled `{a.title}` whose `{field_name}` field needs to be extended or tweaked.\n"
|
254
|
+
f"# Judgement\n{judge.display()}",
|
273
255
|
)
|
274
256
|
return article_outline
|
275
257
|
|
@@ -281,44 +263,41 @@ class TweakOutlineBackwardRef(TweakOutlineForwardRef):
|
|
281
263
|
"""
|
282
264
|
|
283
265
|
output_key: str = "article_outline_bw_ref_checked"
|
266
|
+
ruleset: Optional[RuleSet] = None
|
284
267
|
|
285
|
-
async def _execute(
|
268
|
+
async def _execute(
|
269
|
+
self, article_outline: ArticleOutline, ruleset: Optional[RuleSet] = None, **cxt
|
270
|
+
) -> ArticleOutline:
|
286
271
|
return await self._inner(
|
287
272
|
article_outline,
|
288
|
-
|
289
|
-
topic="Ensure the dependencies of the current chapter are neither abused nor missing.",
|
273
|
+
ruleset=ok(ruleset or self.ruleset, "No ruleset provided"),
|
290
274
|
field_name="depend_on",
|
291
275
|
)
|
292
276
|
|
293
277
|
|
294
|
-
class GenerateArticle(Action):
|
278
|
+
class GenerateArticle(Action, Censor):
|
295
279
|
"""Generate the article based on the outline."""
|
296
280
|
|
297
281
|
output_key: str = "article"
|
298
282
|
"""The key of the output data."""
|
283
|
+
ruleset: Optional[RuleSet] = None
|
299
284
|
|
300
285
|
async def _execute(
|
301
286
|
self,
|
302
287
|
article_outline: ArticleOutline,
|
303
|
-
|
288
|
+
ruleset: Optional[RuleSet] = None,
|
304
289
|
**_,
|
305
290
|
) -> Optional[Article]:
|
306
291
|
article: Article = Article.from_outline(ok(article_outline, "Article outline not specified.")).update_ref(
|
307
292
|
article_outline
|
308
293
|
)
|
309
294
|
|
310
|
-
write_para_manual = ok(
|
311
|
-
await self.draft_rating_manual(w_topic := "write the following paragraph in the subsection.")
|
312
|
-
)
|
313
|
-
|
314
295
|
await gather(
|
315
296
|
*[
|
316
|
-
self.
|
297
|
+
self.censor_obj_inplace(
|
317
298
|
subsec,
|
299
|
+
ruleset=ok(ruleset or self.ruleset, "No ruleset provided"),
|
318
300
|
reference=f"# Original Article Outline\n{article_outline.display()}\n# Error Need to be fixed\n{err}",
|
319
|
-
topic=w_topic,
|
320
|
-
rating_manual=write_para_manual,
|
321
|
-
supervisor_check=supervisor_check,
|
322
301
|
)
|
323
302
|
for _, __, subsec in article.iter_subsections()
|
324
303
|
if (err := subsec.introspect())
|
@@ -329,18 +308,16 @@ class GenerateArticle(Action):
|
|
329
308
|
return article
|
330
309
|
|
331
310
|
|
332
|
-
class CorrectProposal(Action):
|
311
|
+
class CorrectProposal(Action, Censor):
|
333
312
|
"""Correct the proposal of the article."""
|
334
313
|
|
335
314
|
output_key: str = "corrected_proposal"
|
336
315
|
|
337
316
|
async def _execute(self, article_proposal: ArticleProposal, **_) -> Any:
|
338
|
-
|
339
|
-
article_proposal
|
340
|
-
)
|
317
|
+
raise NotImplementedError("Not implemented.")
|
341
318
|
|
342
319
|
|
343
|
-
class CorrectOutline(Action):
|
320
|
+
class CorrectOutline(Action, Correct):
|
344
321
|
"""Correct the outline of the article."""
|
345
322
|
|
346
323
|
output_key: str = "corrected_outline"
|
@@ -351,12 +328,10 @@ class CorrectOutline(Action):
|
|
351
328
|
article_outline: ArticleOutline,
|
352
329
|
**_,
|
353
330
|
) -> ArticleOutline:
|
354
|
-
|
355
|
-
article_outline
|
356
|
-
)
|
331
|
+
raise NotImplementedError("Not implemented.")
|
357
332
|
|
358
333
|
|
359
|
-
class CorrectArticle(Action):
|
334
|
+
class CorrectArticle(Action, Correct):
|
360
335
|
"""Correct the article based on the outline."""
|
361
336
|
|
362
337
|
output_key: str = "corrected_article"
|
@@ -368,4 +343,4 @@ class CorrectArticle(Action):
|
|
368
343
|
article_outline: ArticleOutline,
|
369
344
|
**_,
|
370
345
|
) -> Article:
|
371
|
-
|
346
|
+
raise NotImplementedError("Not implemented.")
|
@@ -1,73 +1,86 @@
|
|
1
1
|
"""A module for writing articles using RAG (Retrieval-Augmented Generation) capabilities."""
|
2
2
|
|
3
3
|
from asyncio import gather
|
4
|
-
from typing import
|
4
|
+
from typing import Optional
|
5
5
|
|
6
|
+
from fabricatio.capabilities.censor import Censor
|
6
7
|
from fabricatio.capabilities.rag import RAG
|
7
8
|
from fabricatio.models.action import Action
|
8
|
-
from fabricatio.models.extra.article_main import Article,
|
9
|
+
from fabricatio.models.extra.article_main import Article, ArticleParagraphSequencePatch, ArticleSubsection
|
10
|
+
from fabricatio.models.extra.rule import RuleSet
|
9
11
|
from fabricatio.utils import ok
|
10
12
|
|
11
13
|
|
12
|
-
class TweakArticleRAG(Action, RAG):
|
13
|
-
"""Write an article based on the provided outline.
|
14
|
+
class TweakArticleRAG(Action, RAG, Censor):
|
15
|
+
"""Write an article based on the provided outline.
|
16
|
+
|
17
|
+
This class inherits from `Action`, `RAG`, and `Censor` to provide capabilities for writing and refining articles
|
18
|
+
using Retrieval-Augmented Generation (RAG) techniques. It processes an article outline, enhances subsections by
|
19
|
+
searching for related references, and applies censoring rules to ensure compliance with the provided ruleset.
|
20
|
+
|
21
|
+
Attributes:
|
22
|
+
output_key (str): The key used to store the output of the action.
|
23
|
+
ruleset (Optional[RuleSet]): The ruleset to be used for censoring the article.
|
24
|
+
"""
|
14
25
|
|
15
26
|
output_key: str = "rag_tweaked_article"
|
27
|
+
"""The key used to store the output of the action."""
|
28
|
+
|
29
|
+
ruleset: Optional[RuleSet] = None
|
30
|
+
"""The ruleset to be used for censoring the article."""
|
16
31
|
|
17
32
|
async def _execute(
|
18
33
|
self,
|
19
34
|
article: Article,
|
20
35
|
collection_name: str = "article_essence",
|
21
|
-
|
22
|
-
"Use correct citation format based on author count. Cite using author surnames and year:"
|
23
|
-
"For 3+ authors: 'Author1, Author2 et al. (YYYY)'"
|
24
|
-
"For 2 authors: 'Author1 & Author2 (YYYY)'"
|
25
|
-
"Single author: 'Author1 (YYYY)'"
|
26
|
-
"Multiple citations: 'Author1 (YYYY), Author2 (YYYY)'"
|
27
|
-
"Prioritize formulas from reference highlights."
|
28
|
-
"Specify authors/years only."
|
29
|
-
"You can create numeric citation numbers for article whose `bibtex_cite_key` is 'wangWind2024' by using notation like `#cite(<wangWind2024>)`."
|
30
|
-
"Paragraphs must exceed 2-3 sentences",
|
31
|
-
supervisor_check: bool = False,
|
36
|
+
ruleset: Optional[RuleSet] = None,
|
32
37
|
parallel: bool = False,
|
33
38
|
**cxt,
|
34
39
|
) -> Optional[Article]:
|
35
|
-
"""Write an article based on the provided outline.
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
"""Write an article based on the provided outline.
|
41
|
+
|
42
|
+
This method processes the article outline, either in parallel or sequentially, by enhancing each subsection
|
43
|
+
with relevant references and applying censoring rules.
|
44
|
+
|
45
|
+
Args:
|
46
|
+
article (Article): The article to be processed.
|
47
|
+
collection_name (str): The name of the collection to view for processing.
|
48
|
+
ruleset (Optional[RuleSet]): The ruleset to apply for censoring. If not provided, the class's ruleset is used.
|
49
|
+
parallel (bool): If True, process subsections in parallel. Otherwise, process them sequentially.
|
50
|
+
**cxt: Additional context parameters.
|
44
51
|
|
45
|
-
|
52
|
+
Returns:
|
53
|
+
Optional[Article]: The processed article with enhanced subsections and applied censoring rules.
|
54
|
+
"""
|
46
55
|
self.view(collection_name)
|
47
56
|
|
48
57
|
if parallel:
|
49
58
|
await gather(
|
50
59
|
*[
|
51
|
-
self._inner(article, subsec,
|
60
|
+
self._inner(article, subsec, ok(ruleset or self.ruleset, "No ruleset provided!"))
|
52
61
|
for _, __, subsec in article.iter_subsections()
|
53
62
|
],
|
54
63
|
return_exceptions=True,
|
55
64
|
)
|
56
65
|
else:
|
57
66
|
for _, __, subsec in article.iter_subsections():
|
58
|
-
await self._inner(article, subsec,
|
59
|
-
|
67
|
+
await self._inner(article, subsec, ok(ruleset or self.ruleset, "No ruleset provided!"))
|
60
68
|
return article
|
61
69
|
|
62
|
-
async def _inner(
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
70
|
+
async def _inner(self, article: Article, subsec: ArticleSubsection, ruleset: RuleSet) -> None:
|
71
|
+
"""Enhance a subsection of the article with references and apply censoring rules.
|
72
|
+
|
73
|
+
This method refines the query for the subsection, retrieves related references, and applies censoring rules
|
74
|
+
to the subsection's paragraphs.
|
75
|
+
|
76
|
+
Args:
|
77
|
+
article (Article): The article containing the subsection.
|
78
|
+
subsec (ArticleSubsection): The subsection to be enhanced.
|
79
|
+
ruleset (RuleSet): The ruleset to apply for censoring.
|
80
|
+
|
81
|
+
Returns:
|
82
|
+
None
|
83
|
+
"""
|
71
84
|
refind_q = ok(
|
72
85
|
await self.arefined_query(
|
73
86
|
f"{article.referenced.as_prompt()}\n"
|
@@ -78,12 +91,10 @@ class TweakArticleRAG(Action, RAG):
|
|
78
91
|
f"prioritizing both original article language and English usage",
|
79
92
|
)
|
80
93
|
)
|
81
|
-
patch =
|
94
|
+
patch = ArticleParagraphSequencePatch.default()
|
82
95
|
patch.tweaked = subsec.paragraphs
|
83
|
-
await self.
|
96
|
+
await self.censor_obj_inplace(
|
84
97
|
patch,
|
85
|
-
|
86
|
-
|
87
|
-
rating_manual=tweak_manual,
|
88
|
-
supervisor_check=supervisor_check,
|
98
|
+
ruleset=ruleset,
|
99
|
+
reference=await self.aretrieve_compact(refind_q, final_limit=30),
|
89
100
|
)
|
@@ -0,0 +1,87 @@
|
|
1
|
+
"""Module for censoring objects and strings based on provided rulesets.
|
2
|
+
|
3
|
+
This module includes the Censor class which inherits from both Correct and Check classes.
|
4
|
+
It provides methods to censor objects and strings by first checking them against a ruleset and then correcting them if necessary.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from typing import Optional, Unpack
|
8
|
+
|
9
|
+
from fabricatio.capabilities.check import Check
|
10
|
+
from fabricatio.capabilities.correct import Correct
|
11
|
+
from fabricatio.models.extra.rule import RuleSet
|
12
|
+
from fabricatio.models.generic import ProposedUpdateAble, SketchedAble
|
13
|
+
from fabricatio.models.kwargs_types import ReferencedKwargs
|
14
|
+
from fabricatio.utils import override_kwargs
|
15
|
+
|
16
|
+
|
17
|
+
class Censor(Correct, Check):
|
18
|
+
"""Class to censor objects and strings based on provided rulesets.
|
19
|
+
|
20
|
+
Inherits from both Correct and Check classes.
|
21
|
+
Provides methods to censor objects and strings by first checking them against a ruleset and then correcting them if necessary.
|
22
|
+
"""
|
23
|
+
|
24
|
+
async def censor_obj[M: SketchedAble](
|
25
|
+
self, obj: M, ruleset: RuleSet, **kwargs: Unpack[ReferencedKwargs[M]]
|
26
|
+
) -> Optional[M]:
|
27
|
+
"""Censors an object based on the provided ruleset.
|
28
|
+
|
29
|
+
Args:
|
30
|
+
obj (M): The object to be censored.
|
31
|
+
ruleset (RuleSet): The ruleset to apply for censoring.
|
32
|
+
**kwargs: Additional keyword arguments to be passed to the check and correct methods.
|
33
|
+
|
34
|
+
Returns:
|
35
|
+
Optional[M]: The censored object if corrections were made, otherwise None.
|
36
|
+
|
37
|
+
Note:
|
38
|
+
This method first checks the object against the ruleset and then corrects it if necessary.
|
39
|
+
"""
|
40
|
+
imp = await self.check_obj(obj, ruleset, **override_kwargs(kwargs, default=None))
|
41
|
+
if imp is None:
|
42
|
+
return imp
|
43
|
+
return await self.correct_obj(obj, imp, **kwargs)
|
44
|
+
|
45
|
+
async def censor_string(
|
46
|
+
self, input_text: str, ruleset: RuleSet, **kwargs: Unpack[ReferencedKwargs[str]]
|
47
|
+
) -> Optional[str]:
|
48
|
+
"""Censors a string based on the provided ruleset.
|
49
|
+
|
50
|
+
Args:
|
51
|
+
input_text (str): The string to be censored.
|
52
|
+
ruleset (RuleSet): The ruleset to apply for censoring.
|
53
|
+
**kwargs: Additional keyword arguments to be passed to the check and correct methods.
|
54
|
+
|
55
|
+
Returns:
|
56
|
+
Optional[str]: The censored string if corrections were made, otherwise None.
|
57
|
+
|
58
|
+
Note:
|
59
|
+
This method first checks the string against the ruleset and then corrects it if necessary.
|
60
|
+
"""
|
61
|
+
imp = await self.check_string(input_text, ruleset, **override_kwargs(kwargs, default=None))
|
62
|
+
if imp is None:
|
63
|
+
return imp
|
64
|
+
return await self.correct_string(input_text, imp, **kwargs)
|
65
|
+
|
66
|
+
async def censor_obj_inplace[M: ProposedUpdateAble](
|
67
|
+
self, obj: M, ruleset: RuleSet, **kwargs: Unpack[ReferencedKwargs[M]]
|
68
|
+
) -> Optional[M]:
|
69
|
+
"""Censors an object in-place based on the provided ruleset.
|
70
|
+
|
71
|
+
This method modifies the object directly if corrections are needed.
|
72
|
+
|
73
|
+
Args:
|
74
|
+
obj (M): The object to be censored.
|
75
|
+
ruleset (RuleSet): The ruleset to apply for censoring.
|
76
|
+
**kwargs: Additional keyword arguments to be passed to the check and correct methods.
|
77
|
+
|
78
|
+
Returns:
|
79
|
+
Optional[M]: The censored object if corrections were made, otherwise None.
|
80
|
+
|
81
|
+
Note:
|
82
|
+
This method first checks the object against the ruleset and then corrects it in-place if necessary.
|
83
|
+
"""
|
84
|
+
imp = await self.check_obj(obj, ruleset, **override_kwargs(kwargs, default=None))
|
85
|
+
if imp is None:
|
86
|
+
return imp
|
87
|
+
return await self.correct_obj_inplace(obj, improvement=imp, **kwargs)
|