Whole file
pre-commit/pre-commit-hooks
The author described this change as “Handle crlf endings in fix-encoding-pragma”. It counts as a record because the checks below fail on the code as it stood at 45fc394c1 and pass on 79a1b2676, with nothing else changed between the two runs.
Projectpre-commit/pre-commit-hooks
Fix saved2019-05-15
Sharing licenceMIT · LICENSE
Change size+11 −13
What the code was meant to do, written into the code itself as a save note
Handle crlf endings in fix-encoding-pragma
The change
| 9 | 9 | from typing import Sequence | |
| 10 | 10 | from typing import Union | |
| 11 | 11 | ||
| 12 | - | DEFAULT_PRAGMA = b'# -*- coding: utf-8 -*-\n' | |
| 12 | + | DEFAULT_PRAGMA = b'# -*- coding: utf-8 -*-' | |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | 15 | def has_coding(line): # type: (bytes) -> bool | |
| 16 | 16 | if not line.strip(): | |
| 17 | 17 | return False | |
| 18 | 18 | return ( | |
| 19 | - | line.lstrip()[0:1] == b'#' and ( | |
| 19 | + | line.lstrip()[:1] == b'#' and ( | |
| 20 | 20 | b'unicode' in line or | |
| 21 | 21 | b'encoding' in line or | |
| 22 | 22 | b'coding:' in line or | |
| ⋯ | |||
| 26 | 26 | ||
| 27 | 27 | ||
| 28 | 28 | class ExpectedContents(collections.namedtuple( | |
| 29 | - | 'ExpectedContents', ('shebang', 'rest', 'pragma_status'), | |
| 29 | + | 'ExpectedContents', ('shebang', 'rest', 'pragma_status', 'ending'), | |
| 30 | 30 | )): | |
| 31 | 31 | """ | |
| 32 | 32 | pragma_status: | |
| ⋯ | |||
| 47 | 47 | ||
| 48 | 48 | def _get_expected_contents(first_line, second_line, rest, expected_pragma): | |
| 49 | 49 | # type: (bytes, bytes, bytes, bytes) -> ExpectedContents | |
| 50 | + | ending = b'\r\n' if first_line.endswith(b'\r\n') else b'\n' | |
| 51 | + | ||
| 50 | 52 | if first_line.startswith(b'#!'): | |
| 51 | 53 | shebang = first_line | |
| 52 | 54 | potential_coding = second_line | |
| ⋯ | |||
| 55 | 57 | potential_coding = first_line | |
| 56 | 58 | rest = second_line + rest | |
| 57 | 59 | ||
| 58 | - | if potential_coding == expected_pragma: | |
| 60 | + | if potential_coding.rstrip(b'\r\n') == expected_pragma: | |
| 59 | 61 | pragma_status = True # type: Optional[bool] | |
| 60 | 62 | elif has_coding(potential_coding): | |
| 61 | 63 | pragma_status = None | |
| ⋯ | |||
| 64 | 66 | rest = potential_coding + rest | |
| 65 | 67 | ||
| 66 | 68 | return ExpectedContents( | |
| 67 | - | shebang=shebang, rest=rest, pragma_status=pragma_status, | |
| 69 | + | shebang=shebang, rest=rest, pragma_status=pragma_status, ending=ending, | |
| 68 | 70 | ) | |
| 69 | 71 | ||
| 70 | 72 | ||
| ⋯ | |||
| 93 | 95 | f.truncate() | |
| 94 | 96 | f.write(expected.shebang) | |
| 95 | 97 | if not remove: | |
| 96 | - | f.write(expected_pragma) | |
| 98 | + | f.write(expected_pragma + expected.ending) | |
| 97 | 99 | f.write(expected.rest) | |
| 98 | 100 | ||
| 99 | 101 | return 1 | |
| ⋯ | |||
| 102 | 104 | def _normalize_pragma(pragma): # type: (Union[bytes, str]) -> bytes | |
| 103 | 105 | if not isinstance(pragma, bytes): | |
| 104 | 106 | pragma = pragma.encode('UTF-8') | |
| 105 | - | return pragma.rstrip() + b'\n' | |
| 106 | - | ||
| 107 | - | ||
| 108 | - | def _to_disp(pragma): # type: (bytes) -> str | |
| 109 | - | return pragma.decode().rstrip() | |
| 107 | + | return pragma.rstrip() | |
| 110 | 108 | ||
| 111 | 109 | ||
| 112 | 110 | def main(argv=None): # type: (Optional[Sequence[str]]) -> int | |
| ⋯ | |||
| 117 | 115 | parser.add_argument( | |
| 118 | 116 | '--pragma', default=DEFAULT_PRAGMA, type=_normalize_pragma, | |
| 119 | 117 | help='The encoding pragma to use. Default: {}'.format( | |
| 120 | - | _to_disp(DEFAULT_PRAGMA), | |
| 118 | + | DEFAULT_PRAGMA.decode(), | |
| 121 | 119 | ), | |
| 122 | 120 | ) | |
| 123 | 121 | parser.add_argument( | |
| ⋯ | |||
| 141 | 139 | retv |= file_ret | |
| 142 | 140 | if file_ret: | |
| 143 | 141 | print(fmt.format( | |
| 144 | - | pragma=_to_disp(args.pragma), filename=filename, | |
| 142 | + | pragma=args.pragma.decode(), filename=filename, | |
| 145 | 143 | )) | |
| 146 | 144 | ||
| 147 | 145 | return retv | |
The check that tells the two apart
fail→pass·tests/fix_encoding_pragma_test.py::test_crfl_adds
fail→pass·tests/fix_encoding_pragma_test.py::test_crlf_ok
Check file tests/fix_encoding_pragma_test.py, taken without changes from the fix and copied onto the older code, so the exact same check runs against both versions.
Origin and history
The code before it45fc394c19e208123b8e9ec3f584c7ae3adef8c4
Broken version dated2019-05-08
Modulepre_commit_hooks.fix_encoding_pragma
Units changedExpectedContents, _get_expected_contents, _normalize_pragma, fix_encoding_pragma, has_coding, main
Fingerprint23781025350f30a8
Checked2026-08-18 by goldset/0.1
Every field above is generated by our program. None of it is written by hand.
Other bugs found in pre-commit/pre-commit-hooks
- 2024-04-20Continues processing JSONs even if hook fails (fixes #1038)
- 2020-09-27Fix #518, provide --enforce-all option to check_added_large_files
- 2020-07-30Fix parsing of git output with unusual characters
- 2019-10-25fix-whitespace: Added test for custom charsets
- 2017-09-27Fix mixed-line-endings --fix=... when whole file is a different ending
- 2017-06-25Fix bug with the file-contents-sorter hook when processing file that does not end in a newline