summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Turner <9087854+AA-Turner@users.noreply.github.com>2023-10-10 13:40:08 (GMT)
committerGitHub <noreply@github.com>2023-10-10 13:40:08 (GMT)
commitf5edb56328b46f262b74a53343b8098a3934f761 (patch)
treefed13d22ab5ac81f469f4ee7f3a0a92f6cf06c96
parente24f9ae7035cfb4c11c4a5c2820121fc22463f8b (diff)
downloadcpython-f5edb56328b46f262b74a53343b8098a3934f761.zip
cpython-f5edb56328b46f262b74a53343b8098a3934f761.tar.gz
cpython-f5edb56328b46f262b74a53343b8098a3934f761.tar.bz2
GH-109408: Move the C file whitespace check from patchcheck to pre-commit (#109890)
Co-authored-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
-rw-r--r--.pre-commit-config.yaml15
-rwxr-xr-xTools/patchcheck/patchcheck.py88
-rwxr-xr-xTools/patchcheck/untabify.py10
3 files changed, 23 insertions, 90 deletions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index aabf1c5..9a27d30 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -32,6 +32,21 @@ repos:
types: [python]
exclude: '^(Lib/test/tokenizedata/|Tools/c-analyzer/cpython/_parser).*$'
+ - repo: local
+ hooks:
+ - id: c-file-whitespace
+ name: "Check C file whitespace"
+ entry: "python Tools/patchcheck/untabify.py"
+ language: "system"
+ types_or: ['c', 'c++']
+ # Don't check the style of vendored libraries
+ exclude: |
+ (?x)^(
+ Modules/_decimal/.*
+ | Modules/libmpdec/.*
+ | Modules/expat/.*
+ )$
+
- repo: https://github.com/sphinx-contrib/sphinx-lint
rev: v0.6.8
hooks:
diff --git a/Tools/patchcheck/patchcheck.py b/Tools/patchcheck/patchcheck.py
index 5f55e1b..66328c8 100755
--- a/Tools/patchcheck/patchcheck.py
+++ b/Tools/patchcheck/patchcheck.py
@@ -1,29 +1,15 @@
#!/usr/bin/env python3
"""Check proposed changes for common issues."""
-import re
import sys
-import shutil
import os.path
import subprocess
import sysconfig
-import untabify
-
-
def get_python_source_dir():
src_dir = sysconfig.get_config_var('abs_srcdir')
if not src_dir:
src_dir = sysconfig.get_config_var('srcdir')
return os.path.abspath(src_dir)
-
-
-# Excluded directories which are copies of external libraries:
-# don't check their coding style
-EXCLUDE_DIRS = [
- os.path.join('Modules', '_decimal', 'libmpdec'),
- os.path.join('Modules', 'expat'),
- os.path.join('Modules', 'zlib'),
- ]
SRCDIR = get_python_source_dir()
@@ -154,47 +140,8 @@ def changed_files(base_branch=None):
else:
sys.exit('need a git checkout to get modified files')
- filenames2 = []
- for filename in filenames:
- # Normalize the path to be able to match using .startswith()
- filename = os.path.normpath(filename)
- if any(filename.startswith(path) for path in EXCLUDE_DIRS):
- # Exclude the file
- continue
- filenames2.append(filename)
-
- return filenames2
-
-
-def report_modified_files(file_paths):
- count = len(file_paths)
- if count == 0:
- return n_files_str(count)
- else:
- lines = [f"{n_files_str(count)}:"]
- for path in file_paths:
- lines.append(f" {path}")
- return "\n".join(lines)
-
-
-#: Python files that have tabs by design:
-_PYTHON_FILES_WITH_TABS = frozenset({
- 'Tools/c-analyzer/cpython/_parser.py',
-})
-
-
-@status("Fixing C file whitespace", info=report_modified_files)
-def normalize_c_whitespace(file_paths):
- """Report if any C files """
- fixed = []
- for path in file_paths:
- abspath = os.path.join(SRCDIR, path)
- with open(abspath, 'r') as f:
- if '\t' not in f.read():
- continue
- untabify.process(abspath, 8, verbose=False)
- fixed.append(path)
- return fixed
+ # Normalize the path to be able to match using str.startswith()
+ return list(map(os.path.normpath, filenames))
@status("Docs modified", modal=True)
@@ -234,33 +181,12 @@ def regenerated_pyconfig_h_in(file_paths):
return "not needed"
-def ci(pull_request):
- if pull_request == 'false':
- print('Not a pull request; skipping')
- return
- base_branch = get_base_branch()
- file_paths = changed_files(base_branch)
- c_files = [fn for fn in file_paths if fn.endswith(('.c', '.h'))]
- fixed = []
- fixed.extend(normalize_c_whitespace(c_files))
- if not fixed:
- print('No whitespace issues found')
- else:
- count = len(fixed)
- print(f'Please fix the {n_files_str(count)} with whitespace issues')
- print('(on Unix you can run `make patchcheck` to make the fixes)')
- sys.exit(1)
-
-
def main():
base_branch = get_base_branch()
file_paths = changed_files(base_branch)
- c_files = [fn for fn in file_paths if fn.endswith(('.c', '.h'))]
doc_files = [fn for fn in file_paths if fn.startswith('Doc') and
fn.endswith(('.rst', '.inc'))]
misc_files = {p for p in file_paths if p.startswith('Misc')}
- # C rules enforcement.
- normalize_c_whitespace(c_files)
# Docs updated.
docs_modified(doc_files)
# Misc/ACKS changed.
@@ -283,12 +209,4 @@ def main():
if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser(description=__doc__)
- parser.add_argument('--ci',
- help='Perform pass/fail checks')
- args = parser.parse_args()
- if args.ci:
- ci(args.ci)
- else:
- main()
+ main()
diff --git a/Tools/patchcheck/untabify.py b/Tools/patchcheck/untabify.py
index 861c83c..5c9d120 100755
--- a/Tools/patchcheck/untabify.py
+++ b/Tools/patchcheck/untabify.py
@@ -21,8 +21,7 @@ def main():
if optname == '-t':
tabsize = int(optvalue)
- for filename in args:
- process(filename, tabsize)
+ return max(process(filename, tabsize) for filename in args)
def process(filename, tabsize, verbose=True):
@@ -32,10 +31,10 @@ def process(filename, tabsize, verbose=True):
encoding = f.encoding
except IOError as msg:
print("%r: I/O error: %s" % (filename, msg))
- return
+ return 2
newtext = text.expandtabs(tabsize)
if newtext == text:
- return
+ return 0
backup = filename + "~"
try:
os.unlink(backup)
@@ -49,7 +48,8 @@ def process(filename, tabsize, verbose=True):
f.write(newtext)
if verbose:
print(filename)
+ return 1
if __name__ == '__main__':
- main()
+ raise SystemExit(main())