Skip to content

Commit 9b785ee

Browse files
Options that expect a file should accept lists of files too
The rationale is that these options readily accept multiple files from the command line, because they can be specified multiple times. However, duplicate option keys are invalid in an INI config file. The alternative is to accept multiple values for each occurrence of an option key.
1 parent 6774b1a commit 9b785ee

File tree

1 file changed

+28
-23
lines changed

1 file changed

+28
-23
lines changed

codespell_lib/_codespell.py

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,9 @@ def parse_options(
339339
"-D",
340340
"--dictionary",
341341
action="append",
342-
help="custom dictionary file that contains spelling "
343-
"corrections. If this flag is not specified or "
344-
'equals "-" then the default dictionary is used. '
345-
"This option can be specified multiple times.",
342+
help="comma-separated list of custom dictionary files that "
343+
"contain spelling corrections. If this flag is not specified "
344+
'or equals "-" then the default dictionary is used.',
346345
)
347346
builtin_opts = "\n- ".join(
348347
[""] + [f"{d[0]!r} {d[1]}" for d in _builtin_dictionaries]
@@ -372,26 +371,26 @@ def parse_options(
372371
"-I",
373372
"--ignore-words",
374373
action="append",
375-
metavar="FILE",
376-
help="file that contains words that will be ignored "
377-
"by codespell. File must contain 1 word per line."
378-
" Words are case sensitive based on how they are "
379-
"written in the dictionary file",
374+
metavar="FILES",
375+
help="comma-separated list of files that contain "
376+
"words to be ignored by codespell. Files must contain "
377+
"1 word per line. Words are case sensitive based on "
378+
"how they are written in the dictionary file.",
380379
)
381380
parser.add_argument(
382381
"-L",
383382
"--ignore-words-list",
384383
action="append",
385384
metavar="WORDS",
386-
help="comma separated list of words to be ignored "
385+
help="comma-separated list of words to be ignored "
387386
"by codespell. Words are case sensitive based on "
388-
"how they are written in the dictionary file",
387+
"how they are written in the dictionary file.",
389388
)
390389
parser.add_argument(
391390
"--uri-ignore-words-list",
392391
action="append",
393392
metavar="WORDS",
394-
help="comma separated list of words to be ignored "
393+
help="comma-separated list of words to be ignored "
395394
"by codespell in URIs and emails only. Words are "
396395
"case sensitive based on how they are written in "
397396
'the dictionary file. If set to "*", all '
@@ -443,11 +442,13 @@ def parse_options(
443442
parser.add_argument(
444443
"-x",
445444
"--exclude-file",
445+
action="append",
446446
type=str,
447-
metavar="FILE",
448-
help="ignore whole lines that match those "
449-
"in the file FILE. The lines in FILE "
450-
"should match the to-be-excluded lines exactly",
447+
metavar="FILES",
448+
help="ignore whole lines that match those in "
449+
"the comma-separated list of files EXCLUDE. "
450+
"The lines in these files should match the "
451+
"to-be-excluded lines exactly",
451452
)
452453

453454
parser.add_argument(
@@ -984,6 +985,12 @@ def parse_file(
984985
return bad_count
985986

986987

988+
def flatten_comma_separated_arguments(
989+
arguments: List(str),
990+
) -> List(str):
991+
return [item for argument in arguments for item in argument.split(",")]
992+
993+
987994
def _script_main() -> int:
988995
"""Wrap to main() for setuptools."""
989996
return main(*sys.argv[1:])
@@ -1028,8 +1035,8 @@ def main(*args: str) -> int:
10281035
else:
10291036
ignore_word_regex = None
10301037

1031-
ignore_words_files = options.ignore_words or []
10321038
ignore_words = parse_ignore_words_option(options.ignore_words_list)
1039+
ignore_words_files = flatten_comma_separated_arguments(options.ignore_words)
10331040
for ignore_words_file in ignore_words_files:
10341041
if not os.path.isfile(ignore_words_file):
10351042
print(
@@ -1052,10 +1059,7 @@ def main(*args: str) -> int:
10521059
return EX_USAGE
10531060
uri_ignore_words = parse_ignore_words_option(options.uri_ignore_words_list)
10541061

1055-
if options.dictionary:
1056-
dictionaries = options.dictionary
1057-
else:
1058-
dictionaries = ["-"]
1062+
dictionaries = flatten_comma_separated_arguments(options.dictionary) or ["-"]
10591063
use_dictionaries = []
10601064
for dictionary in dictionaries:
10611065
if dictionary == "-":
@@ -1118,8 +1122,9 @@ def main(*args: str) -> int:
11181122
context = (context_before, context_after)
11191123

11201124
exclude_lines: Set[str] = set()
1121-
if options.exclude_file:
1122-
build_exclude_hashes(options.exclude_file, exclude_lines)
1125+
exclude_files = flatten_comma_separated_arguments(options.exclude_file)
1126+
for exclude_file in exclude_files:
1127+
build_exclude_hashes(exclude_file, exclude_lines)
11231128

11241129
file_opener = FileOpener(options.hard_encoding_detection, options.quiet_level)
11251130

0 commit comments

Comments
 (0)