Skip to content

Commit

Permalink
Merge branch 'codespell-project:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
polluks authored Jul 9, 2024
2 parents 1c63eae + f3d85db commit cae2fb9
Show file tree
Hide file tree
Showing 10 changed files with 1,473 additions and 24 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.coverage
.venv
build
dist
ld
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ repos:
- -d
- "{extends: relaxed, rules: {line-length: {max: 90}}}"
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.9
rev: v0.5.1
hooks:
- id: ruff
- id: ruff-format
Expand All @@ -79,7 +79,7 @@ repos:
hooks:
- id: validate-pyproject
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.10.0
rev: v1.10.1
hooks:
- id: mypy
args: ["--config-file", "pyproject.toml"]
Expand Down
17 changes: 17 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,23 @@ which is read using Python's
`configparser <https://docs.python.org/3/library/configparser.html#supported-ini-file-structure>`_.
For example, comments are possible using ``;`` or ``#`` as the first character.

Values in an INI file entry cannot start with a ``-`` character, so if you need to do this,
structure your entries like this:

.. code-block:: ini
[codespell]
dictionary = mydict,-
ignore-words = bar,-foo
instead of these invalid entries:

.. code-block:: ini
[codespell]
dictionary = -,mydict
ignore-words = -foo,bar
Codespell will also check in the current directory for a ``pyproject.toml``
(or a path can be specified via ``--toml <filename>``) file, and the
``[tool.codespell]`` entry will be used, but only if the tomli_ package
Expand Down
66 changes: 62 additions & 4 deletions codespell_lib/_codespell.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
Pattern,
Sequence,
Set,
TextIO,
Tuple,
)

Expand Down Expand Up @@ -201,11 +202,17 @@ def __str__(self) -> str:


class FileOpener:
def __init__(self, use_chardet: bool, quiet_level: int) -> None:
def __init__(
self,
use_chardet: bool,
quiet_level: int,
ignore_multiline_regex: Optional[Pattern[str]],
) -> None:
self.use_chardet = use_chardet
if use_chardet:
self.init_chardet()
self.quiet_level = quiet_level
self.ignore_multiline_regex = ignore_multiline_regex

def init_chardet(self) -> None:
try:
Expand Down Expand Up @@ -247,7 +254,7 @@ def open_with_chardet(self, filename: str) -> Tuple[List[str], str]:
)
raise
else:
lines = f.readlines()
lines = self.get_lines(f)
f.close()

return lines, f.encoding
Expand All @@ -262,7 +269,7 @@ def open_with_internal(self, filename: str) -> Tuple[List[str], str]:
print(f'WARNING: Trying next encoding "{encoding}"', file=sys.stderr)
with open(filename, encoding=encoding, newline="") as f:
try:
lines = f.readlines()
lines = self.get_lines(f)
except UnicodeDecodeError:
if not self.quiet_level & QuietLevels.ENCODING:
print(
Expand All @@ -279,6 +286,22 @@ def open_with_internal(self, filename: str) -> Tuple[List[str], str]:

return lines, encoding

def get_lines(self, f: TextIO) -> List[str]:
if self.ignore_multiline_regex:
text = f.read()
pos = 0
text2 = ""
for m in re.finditer(self.ignore_multiline_regex, text):
text2 += text[pos : m.start()]
# Replace with blank lines so line numbers are unchanged.
text2 += "\n" * m.group().count("\n")
pos = m.end()
text2 += text[pos:]
lines = text2.split("\n")
else:
lines = f.readlines()
return lines


# -.-:-.-:-.-:-.:-.-:-.-:-.-:-.-:-.:-.-:-.-:-.-:-.-:-.:-.-:-

Expand Down Expand Up @@ -411,6 +434,19 @@ def parse_options(
'e.g., "\\bmatch\\b". Defaults to '
"empty/disabled.",
)
parser.add_argument(
"--ignore-multiline-regex",
action="store",
type=str,
help="regular expression that is used to ignore "
"text that may span multi-line regions. "
"The regex is run with re.DOTALL. For example to "
"allow skipping of regions of Python code using "
"begin/end comments one could use: "
"--ignore-multiline-regex "
"'# codespell:ignore-begin *\\n.*# codespell:ignore-end *\\n'. "
"Defaults to empty/disabled.",
)
parser.add_argument(
"-I",
"--ignore-words",
Expand Down Expand Up @@ -501,11 +537,13 @@ def parse_options(
action="store",
type=int,
default=0,
choices=range(0, 4),
help="set interactive mode when writing changes:\n"
"- 0: no interactivity.\n"
"- 1: ask for confirmation.\n"
"- 2: ask user to choose one fix when more than one is available.\n"
"- 3: both 1 and 2",
metavar="MODE",
)

parser.add_argument(
Expand All @@ -514,6 +552,7 @@ def parse_options(
action="store",
type=int,
default=34,
choices=range(0, 64),
help="bitmask that allows suppressing messages:\n"
"- 0: print all messages.\n"
"- 1: disable warnings about wrong encoding.\n"
Expand All @@ -526,6 +565,7 @@ def parse_options(
"combined; e.g. use 3 for levels 1+2, 7 for "
"1+2+4, 23 for 1+2+4+16, etc. "
"The default mask is %(default)s.",
metavar="LEVEL",
)

parser.add_argument(
Expand Down Expand Up @@ -1111,6 +1151,20 @@ def main(*args: str) -> int:
else:
ignore_word_regex = None

if options.ignore_multiline_regex:
try:
ignore_multiline_regex = re.compile(
options.ignore_multiline_regex, re.DOTALL
)
except re.error as e:
return _usage_error(
parser,
f"ERROR: invalid --ignore-multiline-regex "
f'"{options.ignore_multiline_regex}" ({e})',
)
else:
ignore_multiline_regex = None

ignore_words, ignore_words_cased = parse_ignore_words_option(
options.ignore_words_list
)
Expand Down Expand Up @@ -1199,7 +1253,11 @@ def main(*args: str) -> int:
for exclude_file in exclude_files:
build_exclude_hashes(exclude_file, exclude_lines)

file_opener = FileOpener(options.hard_encoding_detection, options.quiet_level)
file_opener = FileOpener(
options.hard_encoding_detection,
options.quiet_level,
ignore_multiline_regex,
)

glob_match = GlobMatch(
flatten_clean_comma_separated_arguments(options.skip) if options.skip else []
Expand Down
Loading

0 comments on commit cae2fb9

Please sign in to comment.