Merge branch 'main' into empty-object-with-newline

This commit is contained in:
ascheucher-shopify-partner 2025-02-21 18:18:36 +01:00
commit a23cc57a37
44 changed files with 321 additions and 97 deletions

View file

@ -8,12 +8,12 @@ on:
jobs:
main-windows:
uses: asottile/workflows/.github/workflows/tox.yml@v1.5.0
uses: asottile/workflows/.github/workflows/tox.yml@v1.8.1
with:
env: '["py38"]'
env: '["py39"]'
os: windows-latest
main-linux:
uses: asottile/workflows/.github/workflows/tox.yml@v1.5.0
uses: asottile/workflows/.github/workflows/tox.yml@v1.8.1
with:
env: '["py38", "py39", "py310", "py311"]'
env: '["py39", "py310", "py311", "py312"]'
os: ubuntu-latest

View file

@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
@ -10,33 +10,32 @@ repos:
- id: name-tests-test
- id: requirements-txt-fixer
- repo: https://github.com/asottile/setup-cfg-fmt
rev: v2.4.0
rev: v2.7.0
hooks:
- id: setup-cfg-fmt
- repo: https://github.com/asottile/reorder-python-imports
rev: v3.10.0
rev: v3.14.0
hooks:
- id: reorder-python-imports
args: [--py38-plus, --add-import, 'from __future__ import annotations']
args: [--py39-plus, --add-import, 'from __future__ import annotations']
- repo: https://github.com/asottile/add-trailing-comma
rev: v3.0.1
rev: v3.1.0
hooks:
- id: add-trailing-comma
- repo: https://github.com/asottile/pyupgrade
rev: v3.10.1
rev: v3.19.1
hooks:
- id: pyupgrade
args: [--py38-plus]
- repo: https://github.com/pre-commit/mirrors-autopep8
rev: v2.0.2
args: [--py39-plus]
- repo: https://github.com/hhatto/autopep8
rev: v2.3.2
hooks:
- id: autopep8
- repo: https://github.com/PyCQA/flake8
rev: 6.1.0
rev: 7.1.2
hooks:
- id: flake8
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.4.1
rev: v1.15.0
hooks:
- id: mypy
additional_dependencies: [types-all]

View file

@ -3,7 +3,8 @@
description: prevents giant files from being committed.
entry: check-added-large-files
language: python
stages: [commit, push, manual]
stages: [pre-commit, pre-push, manual]
minimum_pre_commit_version: 3.2.0
- id: check-ast
name: check python ast
description: simply checks whether the files parse as valid python.
@ -39,7 +40,13 @@
entry: check-executables-have-shebangs
language: python
types: [text, executable]
stages: [commit, push, manual]
stages: [pre-commit, pre-push, manual]
minimum_pre_commit_version: 3.2.0
- id: check-illegal-windows-names
name: check illegal windows names
entry: Illegal Windows filenames detected
language: fail
files: '(?i)((^|/)(CON|PRN|AUX|NUL|COM[\d¹²³]|LPT[\d¹²³])(\.|/|$)|[<>:\"\\|?*\x00-\x1F]|/[^/]*[\.\s]/|[^/]*[\.\s]$)'
- id: check-json
name: check json
description: checks json files for parseable syntax.
@ -52,7 +59,8 @@
entry: check-shebang-scripts-are-executable
language: python
types: [text]
stages: [commit, push, manual]
stages: [pre-commit, pre-push, manual]
minimum_pre_commit_version: 3.2.0
- id: pretty-format-json
name: pretty format json
description: sets a standard for formatting json files.
@ -107,6 +115,7 @@
entry: destroyed-symlinks
language: python
types: [file]
stages: [pre-commit, pre-push, manual]
- id: detect-aws-credentials
name: detect aws credentials
description: detects *your* aws credentials from the aws cli credentials file.
@ -131,7 +140,8 @@
entry: end-of-file-fixer
language: python
types: [text]
stages: [commit, push, manual]
stages: [pre-commit, pre-push, manual]
minimum_pre_commit_version: 3.2.0
- id: file-contents-sorter
name: file contents sorter
description: sorts the lines in specified files (defaults to alphabetical). you must provide list of target files as input in your .pre-commit-config.yaml file.
@ -145,7 +155,7 @@
language: python
types: [text]
- id: fix-encoding-pragma
name: fix python encoding pragma
name: fix python encoding pragma (deprecated)
description: 'adds # -*- coding: utf-8 -*- to the top of python files.'
language: python
entry: fix-encoding-pragma
@ -198,4 +208,5 @@
entry: trailing-whitespace-fixer
language: python
types: [text]
stages: [commit, push, manual]
stages: [pre-commit, pre-push, manual]
minimum_pre_commit_version: 3.2.0

View file

@ -1,3 +1,65 @@
5.0.0 - 2024-10-05
==================
### Features
- `requirements-txt-fixer`: also remove `pkg_resources==...`.
- #850 PR by @ericfrederich.
- #1030 issue by @ericfrederich.
- `check-illegal-windows-names`: new hook!
- #1044 PR by @ericfrederich.
- #589 issue by @ericfrederich.
- #1049 PR by @Jeffrey-Lim.
- `pretty-format-json`: continue processing even if a file has a json error.
- #1039 PR by @amarvin.
- #1038 issue by @amarvin.
### Fixes
- `destroyed-symlinks`: set `stages` to `[pre-commit, pre-push, manual]`
- PR #1085 by @AdrianDC.
### Migrating
- pre-commit-hooks now requires `pre-commit>=3.2.0`.
- use non-deprecated names for `stages`.
- #1093 PR by @asottile.
4.6.0 - 2024-04-06
==================
### Features
- `requirements-txt-fixer`: remove duplicate packages.
- #1014 PR by @vhoulbreque-withings.
- #960 issue @csibe17.
### Migrating
- `fix-encoding-pragma`: deprecated -- will be removed in 5.0.0. use
[pyupgrade](https://github.com/asottile/pyupgrade) or some other tool.
- #1033 PR by @mxr.
- #1032 issue by @mxr.
4.5.0 - 2023-10-07
==================
### Features
- `requirements-txt-fixer`: also sort `constraints.txt` by default.
- #857 PR by @lev-blit.
- #830 issue by @PLPeeters.
- `debug-statements`: add `bpdb` debugger.
- #942 PR by @mwip.
- #941 issue by @mwip.
### Fixes
- `file-contents-sorter`: fix sorting an empty file.
- #944 PR by @RoelAdriaans.
- #935 issue by @paduszyk.
- `double-quote-string-fixer`: don't rewrite inside f-strings in 3.12+.
- #973 PR by @asottile.
- #971 issue by @XuehaiPan.
## Migrating
- now requires python >= 3.8.
- #926 PR by @asottile.
- #927 PR by @asottile.
4.4.0 - 2022-11-23
==================

View file

@ -15,7 +15,7 @@ Add this to your `.pre-commit-config.yaml`
```yaml
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0 # Use the ref you want to point at
rev: v5.0.0 # Use the ref you want to point at
hooks:
- id: trailing-whitespace
# - id: ...
@ -51,6 +51,9 @@ Checks for a common error of placing code before the docstring.
#### `check-executables-have-shebangs`
Checks that non-binary executables have a proper shebang.
#### `check-illegal-windows-names`
Check for files that cannot be created on Windows.
#### `check-json`
Attempts to load all json files to verify syntax.
@ -117,6 +120,7 @@ Makes sure files end in a newline and only a newline.
Sort the lines in specified files (defaults to alphabetical).
You must provide the target [`files`](https://pre-commit.com/#config-files) as input.
Note that this hook WILL remove blank lines and does NOT respect any comments.
All newlines will be converted to line feeds (`\n`).
The following arguments are available:
- `--ignore-case` - fold lower case to upper case characters.
@ -126,6 +130,9 @@ The following arguments are available:
removes UTF-8 byte order marker
#### `fix-encoding-pragma`
_Deprecated since py2 is EOL - use [pyupgrade](https://github.com/asottile/pyupgrade) instead._
Add `# -*- coding: utf-8 -*-` to the top of python files.
- To remove the coding pragma pass `--remove` (useful in a python3-only codebase)

View file

@ -4,7 +4,7 @@ import argparse
import math
import os
import subprocess
from typing import Sequence
from collections.abc import Sequence
from pre_commit_hooks.util import added_files
from pre_commit_hooks.util import zsplit
@ -46,7 +46,7 @@ def find_large_added_files(
filenames_filtered &= added_files()
for filename in filenames_filtered:
kb = int(math.ceil(os.stat(filename).st_size / 1024))
kb = math.ceil(os.stat(filename).st_size / 1024)
if kb > maxkb:
print(f'{filename} ({kb} KB) exceeds {maxkb} KB.')
retv = 1

View file

@ -5,7 +5,7 @@ import ast
import platform
import sys
import traceback
from typing import Sequence
from collections.abc import Sequence
def main(argv: Sequence[str] | None = None) -> int:

View file

@ -2,8 +2,8 @@ from __future__ import annotations
import argparse
import ast
from collections.abc import Sequence
from typing import NamedTuple
from typing import Sequence
BUILTIN_TYPES = {

View file

@ -1,7 +1,7 @@
from __future__ import annotations
import argparse
from typing import Sequence
from collections.abc import Sequence
def main(argv: Sequence[str] | None = None) -> int:

View file

@ -1,9 +1,9 @@
from __future__ import annotations
import argparse
from typing import Iterable
from typing import Iterator
from typing import Sequence
from collections.abc import Iterable
from collections.abc import Iterator
from collections.abc import Sequence
from pre_commit_hooks.util import added_files
from pre_commit_hooks.util import cmd_output

View file

@ -3,8 +3,8 @@ from __future__ import annotations
import argparse
import io
import tokenize
from collections.abc import Sequence
from tokenize import tokenize as tokenize_tokenize
from typing import Sequence
NON_CODE_TOKENS = frozenset((
tokenize.COMMENT, tokenize.ENDMARKER, tokenize.NEWLINE, tokenize.NL,

View file

@ -4,9 +4,9 @@ from __future__ import annotations
import argparse
import shlex
import sys
from typing import Generator
from collections.abc import Generator
from collections.abc import Sequence
from typing import NamedTuple
from typing import Sequence
from pre_commit_hooks.util import cmd_output
from pre_commit_hooks.util import zsplit
@ -35,7 +35,7 @@ class GitLsFile(NamedTuple):
filename: str
def git_ls_files(paths: Sequence[str]) -> Generator[GitLsFile, None, None]:
def git_ls_files(paths: Sequence[str]) -> Generator[GitLsFile]:
outs = cmd_output('git', 'ls-files', '-z', '--stage', '--', *paths)
for out in zsplit(outs):
metadata, filename = out.split('\t')

View file

@ -2,8 +2,8 @@ from __future__ import annotations
import argparse
import json
from collections.abc import Sequence
from typing import Any
from typing import Sequence
def raise_duplicate_keys(

View file

@ -2,7 +2,7 @@ from __future__ import annotations
import argparse
import os.path
from typing import Sequence
from collections.abc import Sequence
from pre_commit_hooks.util import cmd_output

View file

@ -4,7 +4,7 @@ from __future__ import annotations
import argparse
import shlex
import sys
from typing import Sequence
from collections.abc import Sequence
from pre_commit_hooks.check_executables_have_shebangs import EXECUTABLE_VALUES
from pre_commit_hooks.check_executables_have_shebangs import git_ls_files
@ -36,7 +36,7 @@ def _message(path: str) -> None:
f'`chmod +x {shlex.quote(path)}`\n'
f' If on Windows, you may also need to: '
f'`git add --chmod=+x {shlex.quote(path)}`\n'
f' If it not supposed to be executable, double-check its shebang '
f' If it is not supposed to be executable, double-check its shebang '
f'is wanted.\n',
file=sys.stderr,
)

View file

@ -2,7 +2,7 @@ from __future__ import annotations
import argparse
import os.path
from typing import Sequence
from collections.abc import Sequence
def main(argv: Sequence[str] | None = None) -> int:

View file

@ -2,7 +2,7 @@ from __future__ import annotations
import argparse
import sys
from typing import Sequence
from collections.abc import Sequence
if sys.version_info >= (3, 11): # pragma: >=3.11 cover
import tomllib

View file

@ -3,8 +3,8 @@ from __future__ import annotations
import argparse
import re
import sys
from typing import Pattern
from typing import Sequence
from collections.abc import Sequence
from re import Pattern
def _get_pattern(domain: str) -> Pattern[bytes]:

View file

@ -2,7 +2,7 @@ from __future__ import annotations
import argparse
import xml.sax.handler
from typing import Sequence
from collections.abc import Sequence
def main(argv: Sequence[str] | None = None) -> int:

View file

@ -1,17 +1,17 @@
from __future__ import annotations
import argparse
from collections.abc import Generator
from collections.abc import Sequence
from typing import Any
from typing import Generator
from typing import NamedTuple
from typing import Sequence
import ruamel.yaml
yaml = ruamel.yaml.YAML(typ='safe')
def _exhaust(gen: Generator[str, None, None]) -> None:
def _exhaust(gen: Generator[str]) -> None:
for _ in gen:
pass
@ -46,7 +46,7 @@ def main(argv: Sequence[str] | None = None) -> int:
'--unsafe', action='store_true',
help=(
'Instead of loading the files, simply parse them for syntax. '
'A syntax-only check enables extensions and unsafe contstructs '
'A syntax-only check enables extensions and unsafe constructs '
'which would otherwise be forbidden. Using this option removes '
'all guarantees of portability to other yaml implementations. '
'Implies --allow-multiple-documents'

View file

@ -3,8 +3,8 @@ from __future__ import annotations
import argparse
import ast
import traceback
from collections.abc import Sequence
from typing import NamedTuple
from typing import Sequence
DEBUG_STATEMENTS = {

View file

@ -3,7 +3,7 @@ from __future__ import annotations
import argparse
import shlex
import subprocess
from typing import Sequence
from collections.abc import Sequence
from pre_commit_hooks.util import cmd_output
from pre_commit_hooks.util import zsplit

View file

@ -3,8 +3,8 @@ from __future__ import annotations
import argparse
import configparser
import os
from collections.abc import Sequence
from typing import NamedTuple
from typing import Sequence
class BadFile(NamedTuple):

View file

@ -1,7 +1,7 @@
from __future__ import annotations
import argparse
from typing import Sequence
from collections.abc import Sequence
BLACKLIST = [
b'BEGIN RSA PRIVATE KEY',

View file

@ -2,8 +2,8 @@ from __future__ import annotations
import argparse
import os
from collections.abc import Sequence
from typing import IO
from typing import Sequence
def fix_file(file_obj: IO[bytes]) -> int:

View file

@ -12,11 +12,11 @@ conflicts and keep the file nicely ordered.
from __future__ import annotations
import argparse
from collections.abc import Iterable
from collections.abc import Sequence
from typing import Any
from typing import Callable
from typing import IO
from typing import Iterable
from typing import Sequence
PASS = 0
FAIL = 1
@ -54,18 +54,21 @@ def sort_file_contents(
def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='+', help='Files to sort')
parser.add_argument(
mutex = parser.add_mutually_exclusive_group(required=False)
mutex.add_argument(
'--ignore-case',
action='store_const',
const=bytes.lower,
default=None,
help='fold lower case to upper case characters',
)
parser.add_argument(
mutex.add_argument(
'--unique',
action='store_true',
help='ensure each line is unique',
)
args = parser.parse_args(argv)
retv = PASS

View file

@ -1,7 +1,7 @@
from __future__ import annotations
import argparse
from typing import Sequence
from collections.abc import Sequence
def main(argv: Sequence[str] | None = None) -> int:

View file

@ -1,9 +1,10 @@
from __future__ import annotations
import argparse
import sys
from collections.abc import Sequence
from typing import IO
from typing import NamedTuple
from typing import Sequence
DEFAULT_PRAGMA = b'# -*- coding: utf-8 -*-'
@ -107,6 +108,13 @@ def _normalize_pragma(pragma: str) -> bytes:
def main(argv: Sequence[str] | None = None) -> int:
print(
'warning: this hook is deprecated and will be removed in a future '
'release because py2 is EOL. instead, use '
'https://github.com/asottile/pyupgrade',
file=sys.stderr,
)
parser = argparse.ArgumentParser(
'Fixes the encoding pragma of python files',
)

View file

@ -2,7 +2,7 @@ from __future__ import annotations
import argparse
import os
from typing import Sequence
from collections.abc import Sequence
from pre_commit_hooks.util import cmd_output

View file

@ -2,7 +2,7 @@ from __future__ import annotations
import argparse
import collections
from typing import Sequence
from collections.abc import Sequence
CRLF = b'\r\n'

View file

@ -2,8 +2,8 @@ from __future__ import annotations
import argparse
import re
from collections.abc import Sequence
from typing import AbstractSet
from typing import Sequence
from pre_commit_hooks.util import CalledProcessError
from pre_commit_hooks.util import cmd_output

View file

@ -4,9 +4,9 @@ import argparse
import json
import re
import sys
from collections.abc import Mapping
from collections.abc import Sequence
from difflib import unified_diff
from typing import Mapping
from typing import Sequence
def _insert_linebreaks(json_str: str) -> str:
return re.sub(
@ -135,17 +135,22 @@ def main(argv: Sequence[str] | None = None) -> int:
f'Input File {json_file} is not a valid JSON, consider using '
f'check-json',
)
return 1
if contents != pretty_contents:
status = 1
if args.autofix:
_autofix(json_file, pretty_contents)
if args.empty_object_with_newline:
status = 0
else:
diff_output = get_diff(contents, pretty_contents, json_file)
sys.stdout.buffer.write(diff_output.encode())
else:
if contents != pretty_contents:
if args.autofix:
_autofix(json_file, pretty_contents)
if args.empty_object_with_newline:
status = 0
else:
diff_output = get_diff(
contents,
pretty_contents,
json_file
)
sys.stdout.buffer.write(diff_output.encode())
status = 1
return status

View file

@ -1,7 +1,7 @@
from __future__ import annotations
import sys
from typing import Sequence
from collections.abc import Sequence
def main(argv: Sequence[str] | None = None) -> int:

View file

@ -2,8 +2,8 @@ from __future__ import annotations
import argparse
import re
from collections.abc import Sequence
from typing import IO
from typing import Sequence
PASS = 0
@ -45,6 +45,11 @@ class Requirement:
elif requirement.value == b'\n':
return False
else:
# if 2 requirements have the same name, the one with comments
# needs to go first (so that when removing duplicates, the one
# with comments is kept)
if self.name == requirement.name:
return bool(self.comments) > bool(requirement.comments)
return self.name < requirement.name
def is_complete(self) -> bool:
@ -110,13 +115,20 @@ def fix_requirements(f: IO[bytes]) -> int:
# which is automatically added by broken pip package under Debian
requirements = [
req for req in requirements
if req.value != b'pkg-resources==0.0.0\n'
if req.value not in [
b'pkg-resources==0.0.0\n',
b'pkg_resources==0.0.0\n',
]
]
# sort the requirements and remove duplicates
prev = None
for requirement in sorted(requirements):
after.extend(requirement.comments)
assert requirement.value, requirement.value
after.append(requirement.value)
if prev is None or requirement.value != prev.value:
after.append(requirement.value)
prev = requirement
after.extend(rest)
after_string = b''.join(after)

View file

@ -20,7 +20,7 @@ complicated YAML files.
from __future__ import annotations
import argparse
from typing import Sequence
from collections.abc import Sequence
QUOTES = ["'", '"']

View file

@ -3,8 +3,15 @@ from __future__ import annotations
import argparse
import io
import re
import sys
import tokenize
from typing import Sequence
from collections.abc import Sequence
if sys.version_info >= (3, 12): # pragma: >=3.12 cover
FSTRING_START = tokenize.FSTRING_START
FSTRING_END = tokenize.FSTRING_END
else: # pragma: <3.12 cover
FSTRING_START = FSTRING_END = -1
START_QUOTE_RE = re.compile('^[a-zA-Z]*"')
@ -40,11 +47,17 @@ def fix_strings(filename: str) -> int:
# Basically a mutable string
splitcontents = list(contents)
fstring_depth = 0
# Iterate in reverse so the offsets are always correct
tokens_l = list(tokenize.generate_tokens(io.StringIO(contents).readline))
tokens = reversed(tokens_l)
for token_type, token_text, (srow, scol), (erow, ecol), _ in tokens:
if token_type == tokenize.STRING:
if token_type == FSTRING_START: # pragma: >=3.12 cover
fstring_depth += 1
elif token_type == FSTRING_END: # pragma: >=3.12 cover
fstring_depth -= 1
elif fstring_depth == 0 and token_type == tokenize.STRING:
new_text = handle_match(token_text)
splitcontents[
line_offsets[srow] + scol:

View file

@ -3,7 +3,7 @@ from __future__ import annotations
import argparse
import os.path
import re
from typing import Sequence
from collections.abc import Sequence
def main(argv: Sequence[str] | None = None) -> int:

View file

@ -2,7 +2,7 @@ from __future__ import annotations
import argparse
import os
from typing import Sequence
from collections.abc import Sequence
def _fix_file(

View file

@ -1,6 +1,6 @@
[metadata]
name = pre_commit_hooks
version = 4.4.0
version = 5.0.0
description = Some out-of-the-box hooks for pre-commit.
long_description = file: README.md
long_description_content_type = text/markdown
@ -21,7 +21,7 @@ packages = find:
install_requires =
ruamel.yaml>=0.15
tomli>=1.1.0;python_version<"3.11"
python_requires = >=3.8
python_requires = >=3.9
[options.packages.find]
exclude =

View file

@ -0,0 +1,63 @@
from __future__ import annotations
import os.path
import re
import pytest
from pre_commit_hooks.check_yaml import yaml
@pytest.fixture(scope='module')
def hook_re():
here = os.path.dirname(__file__)
with open(os.path.join(here, '..', '.pre-commit-hooks.yaml')) as f:
hook_defs = yaml.load(f)
hook, = (
hook
for hook in hook_defs
if hook['id'] == 'check-illegal-windows-names'
)
yield re.compile(hook['files'])
@pytest.mark.parametrize(
's',
(
pytest.param('aux.txt', id='with ext'),
pytest.param('aux', id='without ext'),
pytest.param('AuX.tXt', id='capitals'),
pytest.param('com7.dat', id='com with digit'),
pytest.param(':', id='bare colon'),
pytest.param('file:Zone.Identifier', id='mid colon'),
pytest.param('path/COM¹.json', id='com with superscript'),
pytest.param('dir/LPT³.toml', id='lpt with superscript'),
pytest.param('with < less than', id='with less than'),
pytest.param('Fast or Slow?.md', id='with question mark'),
pytest.param('with "double" quotes', id='with double quotes'),
pytest.param('with_null\x00byte', id='with null byte'),
pytest.param('ends_with.', id='ends with period'),
pytest.param('ends_with ', id='ends with space'),
pytest.param('ends_with\t', id='ends with tab'),
pytest.param('dir/ends./with.txt', id='directory ends with period'),
pytest.param('dir/ends /with.txt', id='directory ends with space'),
),
)
def test_check_illegal_windows_names_matches(hook_re, s):
assert hook_re.search(s)
@pytest.mark.parametrize(
's',
(
pytest.param('README.md', id='standard file'),
pytest.param('foo.aux', id='as ext'),
pytest.param('com.dat', id='com without digit'),
pytest.param('.python-version', id='starts with period'),
pytest.param(' pseudo nan', id='with spaces'),
pytest.param('!@#$%^&;=≤\'~`¡¿€🤗', id='with allowed characters'),
pytest.param('path.to/file.py', id='standard path'),
),
)
def test_check_illegal_windows_names_does_not_match(hook_re, s):
assert hook_re.search(s) is None

View file

@ -67,18 +67,6 @@ from pre_commit_hooks.file_contents_sorter import PASS
FAIL,
b'Fie\nFoe\nfee\nfum\n',
),
(
b'fee\nFie\nFoe\nfum\n',
['--unique', '--ignore-case'],
PASS,
b'fee\nFie\nFoe\nfum\n',
),
(
b'fee\nfee\nFie\nFoe\nfum\n',
['--unique', '--ignore-case'],
FAIL,
b'fee\nFie\nFoe\nfum\n',
),
),
)
def test_integration(input_s, argv, expected_retval, output, tmpdir):
@ -89,3 +77,24 @@ def test_integration(input_s, argv, expected_retval, output, tmpdir):
assert path.read_binary() == output
assert output_retval == expected_retval
@pytest.mark.parametrize(
('input_s', 'argv'),
(
(
b'fee\nFie\nFoe\nfum\n',
['--unique', '--ignore-case'],
),
(
b'fee\nfee\nFie\nFoe\nfum\n',
['--unique', '--ignore-case'],
),
),
)
def test_integration_invalid_args(input_s, argv, tmpdir):
path = tmpdir.join('file.txt')
path.write_binary(input_s)
with pytest.raises(SystemExit):
main([str(path)] + argv)

View file

@ -83,6 +83,24 @@ def test_autofix_main(tmpdir):
assert ret == 0
def test_invalid_main(tmpdir):
srcfile1 = tmpdir.join('not_valid_json.json')
srcfile1.write(
'{\n'
' // not json\n'
' "a": "b"\n'
'}',
)
srcfile2 = tmpdir.join('to_be_json_formatted.json')
srcfile2.write('{ "a": "b" }')
# it should have skipped the first file and formatted the second one
assert main(['--autofix', str(srcfile1), str(srcfile2)]) == 1
# confirm second file was formatted (shouldn't trigger linter again)
assert main([str(srcfile2)]) == 0
def test_orderfile_get_pretty_format():
ret = main((
'--top-keys=alist', get_resource_path('pretty_formatted_json.json'),

View file

@ -68,6 +68,12 @@ from pre_commit_hooks.requirements_txt_fixer import Requirement
b'f<=2\n'
b'g<2\n',
),
(b'a==1\nb==1\na==1\n', FAIL, b'a==1\nb==1\n'),
(
b'a==1\nb==1\n#comment about a\na==1\n',
FAIL,
b'#comment about a\na==1\nb==1\n',
),
(b'ocflib\nDjango\nPyMySQL\n', FAIL, b'Django\nocflib\nPyMySQL\n'),
(
b'-e git+ssh://git_url@tag#egg=ocflib\nDjango\nPyMySQL\n',
@ -76,6 +82,8 @@ from pre_commit_hooks.requirements_txt_fixer import Requirement
),
(b'bar\npkg-resources==0.0.0\nfoo\n', FAIL, b'bar\nfoo\n'),
(b'foo\npkg-resources==0.0.0\nbar\n', FAIL, b'bar\nfoo\n'),
(b'bar\npkg_resources==0.0.0\nfoo\n', FAIL, b'bar\nfoo\n'),
(b'foo\npkg_resources==0.0.0\nbar\n', FAIL, b'bar\nfoo\n'),
(
b'git+ssh://git_url@tag#egg=ocflib\nDjango\nijk\n',
FAIL,

View file

@ -37,6 +37,12 @@ TESTS = (
1,
),
('"foo""bar"', "'foo''bar'", 1),
pytest.param(
"f'hello{\"world\"}'",
"f'hello{\"world\"}'",
0,
id='ignore nested fstrings',
),
)