Skip to content

Commit 98cc2fe

Browse files
committed
Add support of multiple personal word list files (multiple options -P/--pwl) (closes #5)
1 parent 1279d14 commit 98cc2fe

9 files changed

Lines changed: 101 additions & 19 deletions

File tree

ChangeLog.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
:lang: en
55

66

7+
== Version 3.0 (under dev)
8+
9+
* add support of multiple personal word list files (multiple options -P/--pwl) (issue #5)
10+
711
== Version 2.9 (2018-01-15)
812

913
* add option "-n" (or "--skip-noqa") to not check "noqa"-commented lines (issue #2, issue #7)

msgcheck/msgcheck.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,10 @@ def msgcheck_parser():
7676
parser.add_argument('-d', '--dicts',
7777
help='comma-separated list of extra dictionaries '
7878
'to use (in addition to file language)')
79-
parser.add_argument('-P', '--pwl',
80-
help='file with personal list of words used when '
81-
'checking spelling')
79+
parser.add_argument('-P', '--pwl', action='append',
80+
help='file(s) with personal list of words used when '
81+
'checking spelling (this option can be given multiple '
82+
'times)')
8283
parser.add_argument('-m', '--only-misspelled', action='store_true',
8384
help='display only misspelled words (no error, '
8485
'line number and translation)')

msgcheck/po.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import re
3030
import subprocess
3131
import sys
32+
import tempfile
3233

3334
# enchant module is optional, spelling is checked on demand
3435
# (argument -s/--spell)
@@ -42,6 +43,19 @@
4243
from . utils import count_lines, replace_formatters
4344

4445

46+
def build_temp_file_concat_files(filenames):
47+
"""Build a temporary file with concatenation of multiple files."""
48+
if not filenames:
49+
return None
50+
tmp_file = tempfile.NamedTemporaryFile()
51+
for filename in filenames:
52+
if not os.path.isfile(filename):
53+
raise IOError('file "{0}" not found'.format(filename))
54+
tmp_file.write(open(filename, 'rb').read())
55+
tmp_file.flush()
56+
return tmp_file
57+
58+
4559
class PoReport(object): # pylint: disable=too-few-public-methods
4660
"""A message in report (commonly an error in detected in gettext file)."""
4761

@@ -420,15 +434,11 @@ def set_check(self, check, state):
420434
if check in self.checks:
421435
self.checks[check] = bool(state)
422436

423-
def set_spelling_options(self, spelling, dicts, pwl):
437+
def set_spelling_options(self, spelling, dicts, pwl_files):
424438
"""Set spelling options."""
425439
self.spelling = spelling
426440
self.dicts = dicts
427-
self.pwl = pwl
428-
429-
# check if pwl file exists
430-
if pwl and not os.path.isfile(pwl):
431-
raise IOError('pwl file "{0}" not found'.format(pwl))
441+
self.pwl = build_temp_file_concat_files(pwl_files)
432442

433443
# build extra checkers with dicts
434444
self.extra_checkers = []
@@ -454,7 +464,7 @@ def _get_language_checker(self, po_file, reports):
454464
lang = po_file.props['language'] \
455465
if self.spelling == 'str' else 'en'
456466
try:
457-
_dict = DictWithPWL(lang, self.pwl)
467+
_dict = DictWithPWL(lang, self.pwl.name if self.pwl else None)
458468
checker.append(SpellChecker(_dict))
459469
except DictNotFoundError:
460470
reports.append(PoReport(

tests/fr_spelling_id.po

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,12 @@ msgstr ""
3636
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
3737

3838
#, c-format
39-
msgid "%.3fThsi is a test.\n"
40-
msgstr "%.3fCeci est un test.\n"
39+
msgid "%.3fThsi is a testone.\n"
40+
msgstr "%.3fCeci est un testone.\n"
41+
42+
#, c-format
43+
msgid "%.3fThis is a testtwo.\n"
44+
msgstr "%.3fCeci est un testtwo.\n"
4145

4246
msgid "Test 1"
4347
msgstr "Test 1"

tests/fr_spelling_str.po

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,12 @@ msgstr ""
3636
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
3737

3838
#, c-format
39-
msgid "%.3fThis is a test.\n"
40-
msgstr "%.3fCeci est un test.\n"
39+
msgid "%.3fThis is a testone.\n"
40+
msgstr "%.3fCeci est un testone.\n"
41+
42+
#, c-format
43+
msgid "%.3fThis is a testtwo.\n"
44+
msgstr "%.3fCeci est un testtwo.\n"
4145

4246
#, c-format
4347
msgid "%.3fThis is another test.\n"

tests/pwl.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/pwl1.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
testone

tests/pwl2.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
testtwo

tests/test_msgcheck.py

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,33 @@ def test_replace_formatters_python(self):
160160
def test_spelling_id(self):
161161
"""Test spelling on source messages (English) of gettext files."""
162162
po_check = PoCheck()
163-
po_check.set_spelling_options('id', None, local_path('pwl.txt'))
163+
pwl_files = [local_path('pwl1.txt')]
164+
po_check.set_spelling_options('id', None, pwl_files)
165+
result = po_check.check_files([local_path('fr_spelling_id.po')])
166+
167+
# be sure we have 1 file in result
168+
self.assertEqual(len(result), 1)
169+
170+
# the file has 2 spelling errors: "Thsi" and "errro"
171+
errors = result[0][1]
172+
self.assertEqual(len(errors), 3)
173+
for i, word in enumerate(('Thsi', 'testtwo', 'errro')):
174+
self.assertEqual(errors[i].idmsg, 'spelling-id')
175+
self.assertTrue(isinstance(errors[i].message, list))
176+
self.assertEqual(len(errors[i].message), 1)
177+
self.assertEqual(errors[i].message[0], word)
178+
179+
def test_spelling_id_multilpe_pwl(self):
180+
"""
181+
Test spelling on source messages (English) of gettext files
182+
using multiple personal word lists.
183+
"""
184+
po_check = PoCheck()
185+
pwl_files = [
186+
local_path('pwl1.txt'),
187+
local_path('pwl2.txt'),
188+
]
189+
po_check.set_spelling_options('id', None, pwl_files)
164190
result = po_check.check_files([local_path('fr_spelling_id.po')])
165191

166192
# be sure we have 1 file in result
@@ -178,7 +204,39 @@ def test_spelling_id(self):
178204
def test_spelling_str(self):
179205
"""Test spelling on translated messages of gettext files."""
180206
po_check = PoCheck()
181-
po_check.set_spelling_options('str', None, local_path('pwl.txt'))
207+
pwl_files = [local_path('pwl1.txt')]
208+
po_check.set_spelling_options('str', None, pwl_files)
209+
result = po_check.check_files([local_path('fr_spelling_str.po'),
210+
local_path('fr_language.po')])
211+
212+
# be sure we have 2 files in result
213+
self.assertEqual(len(result), 2)
214+
215+
# first file has 3 spelling errors: "CecX", "aabbcc" and "xxyyzz"
216+
errors = result[0][1]
217+
self.assertEqual(len(errors), 4)
218+
for i, word in enumerate(('testtwo', 'CecX', 'aabbcc', 'xxyyzz')):
219+
self.assertEqual(errors[i].idmsg, 'spelling-str')
220+
self.assertTrue(isinstance(errors[i].message, list))
221+
self.assertEqual(len(errors[i].message), 1)
222+
self.assertEqual(errors[i].message[0], word)
223+
224+
# second file has 1 error: dict/language "xyz" not found
225+
errors = result[1][1]
226+
self.assertEqual(len(errors), 1)
227+
self.assertEqual(errors[0].idmsg, 'dict')
228+
229+
def test_spelling_str_multiple_pwl(self):
230+
"""
231+
Test spelling on translated messages of gettext files
232+
using multiple personal word lists.
233+
"""
234+
po_check = PoCheck()
235+
pwl_files = [
236+
local_path('pwl1.txt'),
237+
local_path('pwl2.txt'),
238+
]
239+
po_check.set_spelling_options('str', None, pwl_files)
182240
result = po_check.check_files([local_path('fr_spelling_str.po'),
183241
local_path('fr_language.po')])
184242

@@ -209,8 +267,8 @@ def test_spelling_bad_pwl(self):
209267
"""Test spelling with a bad pwl option."""
210268
po_check = PoCheck()
211269
try:
212-
po_check.set_spelling_options('str', None,
213-
local_path('pwl_does_not_exist.txt'))
270+
pwl_files = [local_path('pwl_does_not_exist.txt')]
271+
po_check.set_spelling_options('str', None, pwl_files)
214272
except IOError:
215273
pass # this exception is expected
216274
else:

0 commit comments

Comments
 (0)