Skip to content

Commit abec060

Browse files
authored
Merge pull request #1195 from bact/add-more-lint-rules
Add more lint rules and fix some
2 parents fc91b16 + f790a8a commit abec060

19 files changed

Lines changed: 160 additions & 204 deletions

File tree

.github/workflows/lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@ jobs:
2626
uses: astral-sh/ruff-action@v3
2727
with:
2828
src: "./pythainlp ./tests ./examples"
29-
args: check --fix --verbose --line-length 79 --select I,W,C901,W291,W293
29+
args: check --verbose --config pyproject.toml

pyproject.toml

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -287,18 +287,36 @@ source = ["pythainlp"]
287287

288288
# Ruff configuration
289289
[tool.ruff]
290-
line-length = 79
291290
indent-width = 4
291+
line-length = 79
292292
target-version = "py39"
293293

294294
[tool.ruff.format]
295-
quote-style = "double"
295+
docstring-code-format = true
296296
indent-style = "space"
297-
skip-magic-trailing-comma = false
298297
line-ending = "auto"
299-
docstring-code-format = true
298+
quote-style = "double"
299+
skip-magic-trailing-comma = false
300300

301-
[tool.ruff.lint.mccabe]
301+
[tool.ruff.lint]
302302
# Flag errors (`C901`) whenever the complexity level exceeds 5. Default is 10.
303303
# We should aim to gradually reduce this to 10.
304-
max-complexity = 38
304+
mccabe.max-complexity = 38
305+
select = [
306+
"E",
307+
"F",
308+
"I",
309+
"W",
310+
"S",
311+
"B028",
312+
"C901",
313+
"F401",
314+
"F811",
315+
"F841",
316+
"W291",
317+
"W293",
318+
]
319+
# Some rules are ignored for now; we can consider enabling them in the future.
320+
# F403 and F405 are ignored due to thai2fit/ulmfit module's star imports.
321+
# S101 is use of assert statement, should be an easy fix.
322+
extend-ignore = ["E402", "E501", "E722", "F403", "F405", "S101", "S202", "S301", "S310"]

pythainlp/augment/lm/phayathaibert.py

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ def __init__(self) -> None:
2020
)
2121

2222
self.tokenizer = AutoTokenizer.from_pretrained(_MODEL_NAME)
23-
self.model_for_masked_lm = AutoModelForMaskedLM.from_pretrained(
24-
_MODEL_NAME
25-
)
23+
self.model_for_masked_lm = AutoModelForMaskedLM.from_pretrained(_MODEL_NAME)
2624
self.model = pipeline(
2725
"fill-mask",
2826
tokenizer=self.tokenizer,
@@ -40,23 +38,22 @@ def generate(
4038
sample_txt = sample_text
4139
final_text = ""
4240

43-
for j in range(max_length):
44-
input = self.processor.preprocess(sample_txt)
41+
for _ in range(max_length):
42+
input_text = self.processor.preprocess(sample_txt)
4543
if sample:
46-
random_word_idx = random.randint(0, 4)
47-
output = self.model(input)[random_word_idx]["sequence"]
44+
# Non-cryptographic use, pseudo-random generator is acceptable here
45+
random_word_idx = random.randint(0, 4) # noqa: S311
46+
output = self.model(input_text)[random_word_idx]["sequence"]
4847
else:
49-
output = self.model(input)[word_rank]["sequence"]
48+
output = self.model(input_text)[word_rank]["sequence"]
5049
sample_txt = output + "<mask>"
5150
final_text = sample_txt
5251

5352
gen_txt = re.sub("<mask>", "", final_text)
5453

5554
return gen_txt
5655

57-
def augment(
58-
self, text: str, num_augs: int = 3, sample: bool = False
59-
) -> list[str]:
56+
def augment(self, text: str, num_augs: int = 3, sample: bool = False) -> list[str]:
6057
"""Text augmentation from PhayaThaiBERT
6158
6259
:param str text: Thai text
@@ -90,9 +87,7 @@ def augment(
9087
if num_augs <= MAX_NUM_AUGS:
9188
for rank in range(num_augs):
9289
gen_text = self.generate(text, rank, sample=sample)
93-
processed_text = re.sub(
94-
"<_>", " ", self.processor.preprocess(gen_text)
95-
)
90+
processed_text = re.sub("<_>", " ", self.processor.preprocess(gen_text))
9691
augment_list.append(processed_text)
9792
else:
9893
raise ValueError(

pythainlp/cli/tokenize.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
# SPDX-FileCopyrightText: 2016-2026 PyThaiNLP Project
22
# SPDX-FileType: SOURCE
33
# SPDX-License-Identifier: Apache-2.0
4-
"""Command line for PyThaiNLP's tokenizers.
5-
"""
4+
"""Command line for PyThaiNLP's tokenizers."""
65

76
import argparse
87

@@ -17,10 +16,10 @@
1716
)
1817
from pythainlp.tools import safe_print
1918

20-
DEFAULT_SENT_TOKEN_SEPARATOR = "@@"
21-
DEFAULT_SUBWORD_TOKEN_SEPARATOR = "/"
22-
DEFAULT_SYLLABLE_TOKEN_SEPARATOR = "~"
23-
DEFAULT_WORD_TOKEN_SEPARATOR = "|"
19+
DEFAULT_SENT_TOKEN_SEPARATOR = "@@" # noqa: S105
20+
DEFAULT_SUBWORD_TOKEN_SEPARATOR = "/" # noqa: S105
21+
DEFAULT_SYLLABLE_TOKEN_SEPARATOR = "~" # noqa: S105
22+
DEFAULT_WORD_TOKEN_SEPARATOR = "|" # noqa: S105
2423

2524

2625
class SubAppBase:

pythainlp/corpus/__init__.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,25 +71,23 @@
7171

7272

7373
def corpus_path() -> str:
74-
"""Get path where corpus files are kept locally.
75-
"""
74+
"""Get path where corpus files are kept locally."""
7675
return _CORPUS_PATH
7776

7877

7978
def corpus_db_url() -> str:
80-
"""Get remote URL of corpus catalog.
81-
"""
79+
"""Get remote URL of corpus catalog."""
8280
return _CORPUS_DB_URL
8381

8482

8583
def corpus_db_path() -> str:
86-
"""Get local path of corpus catalog.
87-
"""
84+
"""Get local path of corpus catalog."""
8885
return _CORPUS_DB_PATH
8986

90-
# DO NOT REORDER these pythainlp.corpus imports.
87+
88+
# DO NOT REORDER these pythainlp.corpus.core imports.
9189
# These imports must come before other pythainlp.corpus.* imports
92-
from pythainlp.corpus.core import (
90+
from pythainlp.corpus.core import ( # noqa: I001
9391
download,
9492
get_corpus,
9593
get_corpus_as_is,

pythainlp/corpus/core.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,8 @@ def _check_hash(dst: str, md5: str) -> None:
322322

323323
with open(get_full_data_path(dst), "rb") as f:
324324
content = f.read()
325-
file_md5 = hashlib.md5(content).hexdigest()
325+
# MD5 is insecure but sufficient here
326+
file_md5 = hashlib.md5(content).hexdigest() # noqa: S324
326327

327328
if md5 != file_md5:
328329
raise ValueError("Hash does not match expected.")

pythainlp/generate/core.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,15 @@ def gen_sentence(
7070
# output: 'แมวเวลานะนั้น'
7171
"""
7272
if not start_seq:
73-
start_seq = random.choice(self.word)
73+
# Non-cryptographic use, pseudo-random generator is acceptable here
74+
start_seq = random.choice(self.word) # noqa: S311
7475
rand_text = start_seq.lower()
7576
self._word_prob = {
7677
i: self.counts[i] / self.n
7778
for i in self.word
7879
if self.counts[i] / self.n >= prob
7980
}
80-
return self._next_word(
81-
rand_text, N, output_str, prob=prob, duplicate=duplicate
82-
)
81+
return self._next_word(rand_text, N, output_str, prob=prob, duplicate=duplicate)
8382

8483
def _next_word(
8584
self,
@@ -95,10 +94,11 @@ def _next_word(
9594
if N > len(word_list):
9695
N = len(word_list)
9796
for _ in range(N):
98-
w = random.choice(word_list)
97+
# Non-cryptographic use, pseudo-random generator is acceptable here
98+
w = random.choice(word_list) # noqa: S311
9999
if duplicate is False:
100100
while w in words:
101-
w = random.choice(word_list)
101+
w = random.choice(word_list) # noqa: S311
102102
words.append(w)
103103

104104
if output_str:
@@ -163,7 +163,8 @@ def gen_sentence(
163163
# output: 'แมวไม่ได้รับเชื้อมัน'
164164
"""
165165
if not start_seq:
166-
start_seq = random.choice(self.words)
166+
# Non-cryptographic use, pseudo-random generator is acceptable here
167+
start_seq = random.choice(self.words) # noqa: S311
167168
late_word = start_seq
168169
list_word = []
169170
list_word.append(start_seq)
@@ -181,7 +182,8 @@ def gen_sentence(
181182
p2 = [j for j in probs if j >= prob]
182183
if len(p2) == 0:
183184
break
184-
items = temp[probs.index(random.choice(p2))]
185+
# Non-cryptographic use, pseudo-random generator is acceptable here
186+
items = temp[probs.index(random.choice(p2))] # noqa: S311
185187
late_word = items[-1]
186188
list_word.append(late_word)
187189

@@ -252,7 +254,8 @@ def gen_sentence(
252254
# output: 'ยังทำตัวเป็นเซิร์ฟเวอร์คือ'
253255
"""
254256
if not start_seq:
255-
start_seq = random.choice(self.bi_keys)
257+
# Non-cryptographic use, pseudo-random generator is acceptable here
258+
start_seq = random.choice(self.bi_keys) # noqa: S311
256259
late_word = start_seq
257260
list_word = []
258261
list_word.append(start_seq)
@@ -270,7 +273,8 @@ def gen_sentence(
270273
p2 = [j for j in probs if j >= prob]
271274
if len(p2) == 0:
272275
break
273-
items = temp[probs.index(random.choice(p2))]
276+
# Non-cryptographic use, pseudo-random generator is acceptable here
277+
items = temp[probs.index(random.choice(p2))] # noqa: S311
274278
late_word = items[1:]
275279
list_word.append(late_word)
276280

pythainlp/generate/thai2fit.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ def gen_sentence(
110110
# output: 'แมว คุณหลวง '
111111
"""
112112
if not start_seq:
113-
start_seq = random.choice(list(thwiki_itos))
113+
# Non-cryptographic use, pseudo-random generator is acceptable here
114+
start_seq = random.choice(list(thwiki_itos)) # noqa: S311
114115
list_word = learn.predict(
115116
start_seq, N, temperature=0.8, min_p=prob, sep="-*-"
116117
).split("-*-")

pythainlp/generate/wangchanglm.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
class WangChanGLM:
1212
def __init__(self):
1313
self.exclude_pattern = re.compile(r"[^ก-๙]+")
14-
self.stop_token = "\n"
14+
self.stop_token = "\n" # noqa: S105
1515
self.PROMPT_DICT = {
1616
"prompt_input": (
1717
"<context>: {input}\n<human>: {instruction}\n<bot>: "

pythainlp/phayathaibert/core.py

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def __init__(self):
2929
self._TK_URL,
3030
self._TK_END,
3131
) = "<unk> <rep> <wrep> <url> </s>".split()
32-
self.SPACE_SPECIAL_TOKEN = "<_>"
32+
self.SPACE_SPECIAL_TOKEN = "<_>" # noqa: S105
3333

3434
def replace_url(self, text: str) -> str:
3535
"""Replace url in `text` with TK_URL (https://stackoverflow.com/a/6041965)
@@ -60,25 +60,13 @@ def rm_brackets(self, text: str) -> str:
6060
new_line = re.sub(r"\{[^a-zA-Z0-9ก-๙]+\}", "", new_line)
6161
new_line = re.sub(r"\[[^a-zA-Z0-9ก-๙]+\]", "", new_line)
6262
# artifiacts after (
63-
new_line = re.sub(
64-
r"(?<=\()[^a-zA-Z0-9ก-๙]+(?=[a-zA-Z0-9ก-๙])", "", new_line
65-
)
66-
new_line = re.sub(
67-
r"(?<=\{)[^a-zA-Z0-9ก-๙]+(?=[a-zA-Z0-9ก-๙])", "", new_line
68-
)
69-
new_line = re.sub(
70-
r"(?<=\[)[^a-zA-Z0-9ก-๙]+(?=[a-zA-Z0-9ก-๙])", "", new_line
71-
)
63+
new_line = re.sub(r"(?<=\()[^a-zA-Z0-9ก-๙]+(?=[a-zA-Z0-9ก-๙])", "", new_line)
64+
new_line = re.sub(r"(?<=\{)[^a-zA-Z0-9ก-๙]+(?=[a-zA-Z0-9ก-๙])", "", new_line)
65+
new_line = re.sub(r"(?<=\[)[^a-zA-Z0-9ก-๙]+(?=[a-zA-Z0-9ก-๙])", "", new_line)
7266
# artifacts before )
73-
new_line = re.sub(
74-
r"(?<=[a-zA-Z0-9ก-๙])[^a-zA-Z0-9ก-๙]+(?=\))", "", new_line
75-
)
76-
new_line = re.sub(
77-
r"(?<=[a-zA-Z0-9ก-๙])[^a-zA-Z0-9ก-๙]+(?=\})", "", new_line
78-
)
79-
new_line = re.sub(
80-
r"(?<=[a-zA-Z0-9ก-๙])[^a-zA-Z0-9ก-๙]+(?=\])", "", new_line
81-
)
67+
new_line = re.sub(r"(?<=[a-zA-Z0-9ก-๙])[^a-zA-Z0-9ก-๙]+(?=\))", "", new_line)
68+
new_line = re.sub(r"(?<=[a-zA-Z0-9ก-๙])[^a-zA-Z0-9ก-๙]+(?=\})", "", new_line)
69+
new_line = re.sub(r"(?<=[a-zA-Z0-9ก-๙])[^a-zA-Z0-9ก-๙]+(?=\])", "", new_line)
8270
return new_line
8371

8472
def replace_newlines(self, text: str) -> str:
@@ -103,7 +91,7 @@ def rm_useless_spaces(self, text: str) -> str:
10391
"""
10492
return re.sub(" {2,}", " ", text)
10593

106-
def replace_spaces(self, text: str, space_token: str = "<_>") -> str:
94+
def replace_spaces(self, text: str, space_token: str = "<_>") -> str: # noqa: S107
10795
"""Replace spaces with _
10896
:param str text: text to replace spaces
10997
:return: text where all spaces replaced with _
@@ -206,9 +194,7 @@ def __init__(self) -> None:
206194
)
207195

208196
self.tokenizer = AutoTokenizer.from_pretrained(_model_name)
209-
self.model_for_masked_lm = AutoModelForMaskedLM.from_pretrained(
210-
_model_name
211-
)
197+
self.model_for_masked_lm = AutoModelForMaskedLM.from_pretrained(_model_name)
212198
self.model = pipeline(
213199
"fill-mask",
214200
tokenizer=self.tokenizer,
@@ -223,15 +209,17 @@ def generate(
223209
max_length: int = 3,
224210
sample: bool = False,
225211
) -> str:
212+
"""Generate text from PhayaThaiBERT"""
226213
sample_txt = sample_text
227214
final_text = ""
228-
for j in range(max_length):
229-
input = self.processor.preprocess(sample_txt)
215+
for _ in range(max_length):
216+
input_text = self.processor.preprocess(sample_txt)
230217
if sample:
231-
random_word_idx = random.randint(0, 4)
232-
output = self.model(input)[random_word_idx]["sequence"]
218+
# Non-cryptographic use, pseudo-random generator is acceptable here
219+
random_word_idx = random.randint(0, 4) # noqa: S311
220+
output = self.model(input_text)[random_word_idx]["sequence"]
233221
else:
234-
output = self.model(input)[word_rank]["sequence"]
222+
output = self.model(input_text)[word_rank]["sequence"]
235223
sample_txt = output + "<mask>"
236224
final_text = sample_txt
237225

@@ -279,9 +267,7 @@ def augment(
279267
rank,
280268
sample=sample,
281269
)
282-
processed_text = re.sub(
283-
"<_>", " ", self.processor.preprocess(gen_text)
284-
)
270+
processed_text = re.sub("<_>", " ", self.processor.preprocess(gen_text))
285271
augment_list.append(processed_text)
286272
else:
287273
raise ValueError(
@@ -383,7 +369,8 @@ def get_ner(
383369
if pos:
384370
warnings.warn(
385371
"This model doesn't support output \
386-
postag and It doesn't output the postag."
372+
postag and It doesn't output the postag.",
373+
stacklevel=2,
387374
)
388375

389376
sample_output = []

0 commit comments

Comments
 (0)