Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pre-commit configuration #2459

Merged
merged 14 commits into from
Dec 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/codespell-private.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ jobs:
flake8-annotation:
runs-on: ubuntu-latest
steps:
- name: Setup python
uses: actions/setup-python@v4
with:
python-version: 3.x
- uses: actions/checkout@v3
- name: Install codespell dependencies
run: pip install -e ".[dev]"
- name: Flake8 with annotations
uses: TrueBrain/actions-flake8@v2
111 changes: 111 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
---
files: ^(.*\.(py|json|md|sh|yaml|cfg|txt))$
exclude: ^(\.[^/]*cache/.*)$
repos:
- repo: https://github.com/executablebooks/mdformat
# Do this before other tools "fixing" the line endings
rev: 0.7.16
hooks:
- id: mdformat
name: Format Markdown
entry: mdformat # Executable to run, with fixed options
language: python
types: [markdown]
args: [--wrap, '75', --number]
additional_dependencies:
- mdformat-toc
- mdformat-beautysh
# -mdformat-shfmt
# -mdformat-tables
- mdformat-config
- mdformat-black
- mdformat-web
- mdformat-gfm
- repo: https://github.com/asottile/pyupgrade
rev: v3.3.1
hooks:
- id: pyupgrade
args: [--py37-plus]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: no-commit-to-branch
args: [--branch, main]
- id: check-yaml
args: [--unsafe]
- id: debug-statements
- id: end-of-file-fixer
- id: trailing-whitespace
- id: check-json
- id: mixed-line-ending
- id: check-builtin-literals
- id: check-ast
- id: check-merge-conflict
- id: check-executables-have-shebangs
- id: check-shebang-scripts-are-executable
- id: check-docstring-first
- id: fix-byte-order-marker
- id: check-case-conflict
- id: check-toml
- repo: https://github.com/adrienverge/yamllint.git
rev: v1.28.0
hooks:
- id: yamllint
args:
- --no-warnings
- -d
- '{extends: relaxed, rules: {line-length: {max: 90}}}'
- repo: https://github.com/psf/black
rev: 22.10.0
hooks:
- id: black
- repo: https://github.com/Lucas-C/pre-commit-hooks-bandit
rev: v1.0.6
hooks:
- id: python-bandit-vulnerability-check
- repo: https://github.com/PyCQA/autoflake
rev: v2.0.0
hooks:
- id: autoflake
- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
hooks:
- id: flake8
additional_dependencies:
- flake8-pyproject>=1.2.2
- flake8-bugbear>=22.7.1
- flake8-comprehensions>=3.10.0
- flake8-2020>=1.7.0
- mccabe>=0.7.0
- pycodestyle>=2.9.1
- pyflakes>=2.5.0
- repo: https://github.com/PyCQA/isort
rev: 5.10.1
hooks:
- id: isort
- repo: https://github.com/codespell-project/codespell
rev: v2.2.2
hooks:
- id: codespell
args: [--toml, pyproject-codespell.precommit-toml]
additional_dependencies:
- tomli
- repo: https://github.com/pre-commit/mirrors-pylint
rev: v3.0.0a5
hooks:
- id: pylint
additional_dependencies:
- chardet
- pytest
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.991
hooks:
- id: mypy
args: [--no-warn-unused-ignores, --config-file, pyproject.toml, --disable-error-code,
import]
additional_dependencies:
- chardet
- pytest
- pytest-cov
- pytest-dependency
- types-chardet
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ exclude .git-blame-ignore-revs
exclude example example/* snap snap/* tools tools/*
exclude Makefile
exclude codespell.1.include
exclude pyproject-codespell.precommit-toml
40 changes: 22 additions & 18 deletions codespell_lib/_codespell.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ def parse_options(
"This option can be specified multiple times.",
)
builtin_opts = "\n- ".join(
[""] + ["%r %s" % (d[0], d[1]) for d in _builtin_dictionaries]
[""] + [f"{d[0]!r} {d[1]}" for d in _builtin_dictionaries]
)
parser.add_argument(
"--builtin",
Expand Down Expand Up @@ -693,7 +693,7 @@ def ask_for_word_fix(
r = ""
fixword = fix_case(wrongword, misspelling.data)
while not r:
print("%s\t%s ==> %s (Y/n) " % (line, wrongword, fixword), end="")
print(f"{line}\t{wrongword} ==> {fixword} (Y/n) ", end="")
r = sys.stdin.readline().strip().upper()
if not r:
r = "Y"
Expand Down Expand Up @@ -743,7 +743,7 @@ def print_context(
# context = (context_before, context_after)
for i in range(index - context[0], index + context[1] + 1):
if 0 <= i < len(lines):
print("%s %s" % (">" if i == index else ":", lines[i].rstrip()))
print("{} {}".format(">" if i == index else ":", lines[i].rstrip()))


def extract_words(
Expand Down Expand Up @@ -806,14 +806,14 @@ def parse_file(
if summary and fix:
summary.update(lword)

cfilename = "%s%s%s" % (colors.FILE, filename, colors.DISABLE)
cwrongword = "%s%s%s" % (colors.WWORD, word, colors.DISABLE)
crightword = "%s%s%s" % (colors.FWORD, fixword, colors.DISABLE)
cfilename = f"{colors.FILE}{filename}{colors.DISABLE}"
cwrongword = f"{colors.WWORD}{word}{colors.DISABLE}"
crightword = f"{colors.FWORD}{fixword}{colors.DISABLE}"

if misspellings[lword].reason:
if options.quiet_level & QuietLevels.DISABLED_FIXES:
continue
creason = " | %s%s%s" % (
creason = " | {}{}{}".format(
colors.FILE,
misspellings[lword].reason,
colors.DISABLE,
Expand Down Expand Up @@ -843,7 +843,7 @@ def parse_file(
try:
text = is_text_file(filename)
except PermissionError as e:
print("WARNING: %s: %s" % (e.strerror, filename), file=sys.stderr)
print(f"WARNING: {e.strerror}: {filename}", file=sys.stderr)
return bad_count
except OSError:
return bad_count
Expand Down Expand Up @@ -917,16 +917,16 @@ def parse_file(
):
continue

cfilename = "%s%s%s" % (colors.FILE, filename, colors.DISABLE)
cfilename = f"{colors.FILE}{filename}{colors.DISABLE}"
cline = "%s%d%s" % (colors.FILE, i + 1, colors.DISABLE)
cwrongword = "%s%s%s" % (colors.WWORD, word, colors.DISABLE)
crightword = "%s%s%s" % (colors.FWORD, fixword, colors.DISABLE)
cwrongword = f"{colors.WWORD}{word}{colors.DISABLE}"
crightword = f"{colors.FWORD}{fixword}{colors.DISABLE}"

if misspellings[lword].reason:
if options.quiet_level & QuietLevels.DISABLED_FIXES:
continue

creason = " | %s%s%s" % (
creason = " | {}{}{}".format(
colors.FILE,
misspellings[lword].reason,
colors.DISABLE,
Expand Down Expand Up @@ -976,7 +976,7 @@ def parse_file(
else:
if not options.quiet_level & QuietLevels.FIXES:
print(
"%sFIXED:%s %s" % (colors.FWORD, colors.DISABLE, filename),
f"{colors.FWORD}FIXED:{colors.DISABLE} {filename}",
file=sys.stderr,
)
with open(filename, "w", encoding=encoding, newline="") as f:
Expand Down Expand Up @@ -1010,7 +1010,7 @@ def main(*args: str) -> int:
try:
word_regex = re.compile(word_regex)
except re.error as err:
print('ERROR: invalid --regex "%s" (%s)' % (word_regex, err), file=sys.stderr)
print(f'ERROR: invalid --regex "{word_regex}" ({err})', file=sys.stderr)
parser.print_help()
return EX_USAGE

Expand All @@ -1019,7 +1019,9 @@ def main(*args: str) -> int:
ignore_word_regex = re.compile(options.ignore_regex)
except re.error as err:
print(
'ERROR: invalid --ignore-regex "%s" (%s)' % (options.ignore_regex, err),
'ERROR: invalid --ignore-regex "{}" ({})'.format(
options.ignore_regex, err
),
file=sys.stderr,
)
parser.print_help()
Expand All @@ -1044,7 +1046,8 @@ def main(*args: str) -> int:
uri_regex = re.compile(uri_regex)
except re.error as err:
print(
'ERROR: invalid --uri-regex "%s" (%s)' % (uri_regex, err), file=sys.stderr
f'ERROR: invalid --uri-regex "{uri_regex}" ({err})',
file=sys.stderr,
)
parser.print_help()
return EX_USAGE
Expand All @@ -1063,12 +1066,13 @@ def main(*args: str) -> int:
for builtin in _builtin_dictionaries:
if builtin[0] == u:
use_dictionaries.append(
os.path.join(_data_root, "dictionary%s.txt" % (builtin[2],))
os.path.join(_data_root, f"dictionary{builtin[2]}.txt")
)
break
else:
print(
"ERROR: Unknown builtin dictionary: %s" % (u,), file=sys.stderr
f"ERROR: Unknown builtin dictionary: {u}",
file=sys.stderr,
)
parser.print_help()
return EX_USAGE
Expand Down
47 changes: 32 additions & 15 deletions codespell_lib/tests/test_dictionary.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,14 @@ def _check_aspell(
spellers[lang].check(phrase.encode(spellers[lang].ConfigKeys()["encoding"][1]))
for lang in languages
)
end = "be in aspell dictionaries (%s) for dictionary %s" % (
end = "be in aspell dictionaries ({}) for dictionary {}".format(
", ".join(languages),
fname,
)
if in_aspell: # should be an error in aspell
assert this_in_aspell, "%s should %s" % (msg, end)
assert this_in_aspell, f"{msg} should {end}"
else: # shouldn't be
assert not this_in_aspell, "%s should not %s" % (msg, end)
assert not this_in_aspell, f"{msg} should not {end}"


whitespace = re.compile(r"\s")
Expand All @@ -118,15 +118,18 @@ def _check_err_rep(
) -> None:
assert whitespace.search(err) is None, "error %r has whitespace" % err
assert "," not in err, "error %r has a comma" % err
assert len(rep) > 0, "error %s: correction %r must be non-empty" % (err, rep)
assert len(rep) > 0, f"error {err}: correction {rep!r} must be non-empty"
assert not start_whitespace.match(
rep
), "error %s: correction %r cannot start with whitespace" % (err, rep)
_check_aspell(err, "error %r" % (err,), in_aspell[0], fname, languages[0])
prefix = "error %s: correction %r" % (err, rep)
), f"error {err}: correction {rep!r} cannot start with whitespace"
_check_aspell(err, f"error {err!r}", in_aspell[0], fname, languages[0])
prefix = f"error {err}: correction {rep!r}"
for (regex, msg) in [
(start_comma, "%s starts with a comma"),
(whitespace_comma, "%s contains a whitespace character followed by a comma"),
(
whitespace_comma,
"%s contains a whitespace character followed by a comma",
),
(
comma_whitespaces,
"%s contains a comma followed by multiple whitespace characters",
Expand All @@ -144,9 +147,13 @@ def _check_err_rep(
reps = [r.strip() for r in rep.split(",")]
reps = [r for r in reps if len(r)]
for r in reps:
assert err != r.lower(), "error %r corrects to itself amongst others" % (err,)
assert err != r.lower(), f"error {err!r} corrects to itself amongst others"
_check_aspell(
r, "error %s: correction %r" % (err, r), in_aspell[1], fname, languages[1]
r,
f"error {err}: correction {r!r}",
in_aspell[1],
fname,
languages[1],
)

# aspell dictionary is case sensitive, so pass the original case into there
Expand Down Expand Up @@ -180,7 +187,11 @@ def test_error_checking(err: str, rep: str, match: str) -> None:
"""Test that our error checking works."""
with pytest.raises(AssertionError, match=match):
_check_err_rep(
err, rep, (None, None), "dummy", (supported_languages, supported_languages)
err,
rep,
(None, None),
"dummy",
(supported_languages, supported_languages),
)


Expand All @@ -205,7 +216,13 @@ def test_error_checking(err: str, rep: str, match: str) -> None:
("a", "bar back", None, False, "should not be in aspell"),
("a", "bar back Wednesday", None, False, "should not be in aspell"),
# Second multi-word, both parts
("a", "bar back, abcdef uvwxyz, bar,", None, True, "should be in aspell"),
(
"a",
"bar back, abcdef uvwxyz, bar,",
None,
True,
"should be in aspell",
),
(
"a",
"abcdef uvwxyz, bar back, ghijkl,",
Expand Down Expand Up @@ -263,7 +280,7 @@ def test_dictionary_looping(
for line in fid:
err, rep = line.split("->")
err = err.lower()
assert err not in this_err_dict, "error %r already exists in %s" % (
assert err not in this_err_dict, "error {!r} already exists in {}".format(
err,
short_fname,
)
Expand All @@ -286,7 +303,7 @@ def test_dictionary_looping(
for err in this_err_dict:
assert (
err not in other_err_dict
), "error %r in dictionary %s already exists in dictionary %s" % (
), "error {!r} in dictionary {} already exists in dictionary {}".format(
err,
short_fname,
other_fname,
Expand All @@ -297,7 +314,7 @@ def test_dictionary_looping(
for err in this_err_dict:
assert (
err not in other_err_dict
), "error %r in dictionary %s already exists in dictionary %s" % (
), "error {!r} in dictionary {} already exists in dictionary {}".format(
err,
short_fname,
other_fname,
Expand Down
7 changes: 7 additions & 0 deletions pyproject-codespell.precommit-toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[tool.codespell]
#builtin = ["clear","rare","informal","usage","code","names"]
builtin = "clear,rare,informal,usage,code,names"
#ignore-words-list = ["uint"]
ignore-words-list = "uint"
#skip=[ "./.*","codespell_lib/data/*","codespell_lib/tests/*"]
skip="./.*,codespell_lib/data/*,codespell_lib/tests/*"
Loading