mirror of
https://github.com/pre-commit/pre-commit-hooks.git
synced 2026-03-29 10:16:52 +00:00
implemented a basic double quote string fixer
This commit is contained in:
parent
5fe82b3a37
commit
12f02dfeb8
6 changed files with 154 additions and 1 deletions
|
|
@ -36,6 +36,7 @@ Add this to your `.pre-commit-config.yaml`
|
|||
- `name-tests-test` - Assert that files in tests/ end in _test.py
|
||||
- `pyflakes` - Run pyflakes on your python files
|
||||
- `requirements-txt-fixer` - Sorts entries in requirements.txt
|
||||
- `double-quote-string-fixer` - This hook replaces double quoted strings with single quoted strings
|
||||
- `trailing-whitespace` - Trims trailing whitespace.
|
||||
|
||||
### As a standalone package
|
||||
|
|
|
|||
|
|
@ -79,6 +79,12 @@
|
|||
entry: requirements-txt-fixer
|
||||
language: python
|
||||
files: requirements.*\.txt$
|
||||
- id: double-quote-string-fixer
|
||||
name: Fix double quoted strings
|
||||
description: This hook replaces double quoted strings with single quoted strings
|
||||
entry: double-quote-string-fixer
|
||||
language: python
|
||||
files: \.py$
|
||||
- id: trailing-whitespace
|
||||
name: Trim Trailing Whitespace
|
||||
description: This hook trims trailing whitespace.
|
||||
|
|
|
|||
65
pre_commit_hooks/string_fixer.py
Normal file
65
pre_commit_hooks/string_fixer.py
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import argparse
|
||||
import re
|
||||
import tokenize
|
||||
|
||||
|
||||
double_quote_starts = tuple(s for s in tokenize.single_quoted if '"' in s)
|
||||
compiled_tokenize_string = re.compile(tokenize.String)
|
||||
|
||||
|
||||
def handle_match(m):
|
||||
string = m.group(0)
|
||||
|
||||
for double_quote_start in double_quote_starts:
|
||||
if string.startswith(double_quote_start):
|
||||
meat = string[len(double_quote_start):-1]
|
||||
if '"' in meat or "'" in meat:
|
||||
break
|
||||
return (
|
||||
double_quote_start.replace('"', "'") +
|
||||
string[len(double_quote_start):-1] +
|
||||
"'"
|
||||
)
|
||||
return string
|
||||
|
||||
|
||||
def fix_strings(filename):
|
||||
return_value = 0
|
||||
|
||||
lines = []
|
||||
|
||||
with open(filename, 'r') as read_handle:
|
||||
for line in read_handle:
|
||||
if '"""' in line:
|
||||
# Docstrings are hard, fuck it
|
||||
lines.append(line)
|
||||
else:
|
||||
result = re.sub(compiled_tokenize_string, handle_match, line)
|
||||
lines.append(result)
|
||||
return_value |= int(result != line)
|
||||
|
||||
with open(filename, 'w') as write_handle:
|
||||
for line in lines:
|
||||
write_handle.write(line)
|
||||
|
||||
return return_value
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('filenames', nargs='*', help='Filenames to fix')
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
retv = 0
|
||||
|
||||
for filename in args.filenames:
|
||||
return_value = fix_strings(filename)
|
||||
if return_value != 0:
|
||||
print('Fixing strings in {0}'.format(filename))
|
||||
retv |= return_value
|
||||
|
||||
return retv
|
||||
1
setup.py
1
setup.py
|
|
@ -46,6 +46,7 @@ setup(
|
|||
'debug-statement-hook = pre_commit_hooks.debug_statement_hook:debug_statement_hook',
|
||||
'end-of-file-fixer = pre_commit_hooks.end_of_file_fixer:end_of_file_fixer',
|
||||
'name-tests-test = pre_commit_hooks.tests_should_end_in_test:validate_files',
|
||||
'double-quote-string-fixer = pre_commit_hooks.string_fixer:main',
|
||||
'requirements-txt-fixer = pre_commit_hooks.requirements_txt_fixer:fix_requirements_txt',
|
||||
'trailing-whitespace-fixer = pre_commit_hooks.trailing_whitespace_fixer:fix_trailing_whitespace',
|
||||
],
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ TESTS = (
|
|||
('', 0, ''),
|
||||
# Acceptable
|
||||
('"foo"', 0, ''),
|
||||
# Docstrin after code
|
||||
# Docstring after code
|
||||
(
|
||||
'from __future__ import unicode_literals\n'
|
||||
'"foo"\n',
|
||||
|
|
|
|||
80
tests/string_fixer_test.py
Normal file
80
tests/string_fixer_test.py
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import pytest
|
||||
|
||||
from pre_commit_hooks.string_fixer import main
|
||||
|
||||
TESTS = (
|
||||
# Base cases
|
||||
(
|
||||
"''",
|
||||
"''",
|
||||
0
|
||||
),
|
||||
(
|
||||
'""',
|
||||
"''",
|
||||
1
|
||||
),
|
||||
(
|
||||
r'"\'"',
|
||||
r'"\'"',
|
||||
0
|
||||
),
|
||||
(
|
||||
r'"\""',
|
||||
r'"\""',
|
||||
0
|
||||
),
|
||||
(
|
||||
r"'\"\"'",
|
||||
r"'\"\"'",
|
||||
0
|
||||
),
|
||||
# String somewhere in the line
|
||||
(
|
||||
'x = "foo"',
|
||||
"x = 'foo'",
|
||||
1
|
||||
),
|
||||
# Test escaped characters
|
||||
(
|
||||
r'"\'"',
|
||||
r'"\'"',
|
||||
0
|
||||
),
|
||||
# Docstring
|
||||
(
|
||||
'""" Foo """',
|
||||
'""" Foo """',
|
||||
0
|
||||
),
|
||||
# Fuck it, won't even try to fix
|
||||
(
|
||||
"""
|
||||
x = " \\n
|
||||
foo \\n
|
||||
"\n
|
||||
""",
|
||||
"""
|
||||
x = " \\n
|
||||
foo \\n
|
||||
"\n
|
||||
""",
|
||||
0
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('input_s', 'expected_output', 'expected_retval'), TESTS)
|
||||
def test_rewrite(input_s, expected_output, expected_retval, tmpdir):
|
||||
tmpfile = tmpdir.join('file.txt')
|
||||
|
||||
with open(tmpfile.strpath, 'w') as f:
|
||||
f.write(input_s)
|
||||
|
||||
retval = main([tmpfile.strpath])
|
||||
assert tmpfile.read() == expected_output
|
||||
assert retval == expected_retval
|
||||
Loading…
Add table
Add a link
Reference in a new issue