# Path: pre_commit_hooks/check_docstring_first.py
# def check_docstring_first(src: bytes, filename: str = '<unknown>') -> int:
#     """Returns nonzero if the source has what looks like a docstring that is
#     not at the beginning of the source.
# 
#     A string will be considered a docstring if it is a STRING token with a
#     col offset of 0.
#     """
#     found_docstring_line = None
#     found_code_line = None
# 
#     tok_gen = tokenize_tokenize(io.BytesIO(src).readline)
#     for tok_type, _, (sline, scol), _, _ in tok_gen:
#         # Looks like a docstring!
#         if tok_type == tokenize.STRING and scol == 0:
#             if found_docstring_line is not None:
#                 print(
#                     f'{filename}:{sline} Multiple module docstrings '
#                     f'(first docstring on line {found_docstring_line}).',
#                 )
#                 return 1
#             elif found_code_line is not None:
#                 print(
#                     f'{filename}:{sline} Module docstring appears after code '
#                     f'(code seen on line {found_code_line}).',
#                 )
#                 return 1
#             else:
#                 found_docstring_line = sline
#         elif tok_type not in NON_CODE_TOKENS and found_code_line is None:
#             found_code_line = sline
# 
#     return 0
# 
# Path: pre_commit_hooks/check_docstring_first.py
# def main(argv: Sequence[str] | None = None) -> int:
#     parser = argparse.ArgumentParser()
#     parser.add_argument('filenames', nargs='*')
#     args = parser.parse_args(argv)
# 
#     retv = 0
# 
#     for filename in args.filenames:
#         with open(filename, 'rb') as f:
#             contents = f.read()
#         retv |= check_docstring_first(contents, filename=filename)
# 
#     return retv


import pytest
from pre_commit_hooks.check_docstring_first import check_docstring_first
from pre_commit_hooks.check_docstring_first import main
    ),
    # Test multiple lines of code above
    (
        b'import os\n'
        b'import sys\n'
        b'"docstring"\n',
        1,
        '{filename}:3 Module docstring appears after code '
        '(code seen on line 1).\n',
    ),
    # String literals in expressions are ok.
    (b'x = "foo"\n', 0, ''),
)


all_tests = pytest.mark.parametrize(
    ('contents', 'expected', 'expected_out'), TESTS,
)


@all_tests
def test_unit(capsys, contents, expected, expected_out):
    assert check_docstring_first(contents) == expected
    assert capsys.readouterr()[0] == expected_out.format(filename='<unknown>')


@all_tests
def test_integration(tmpdir, capsys, contents, expected, expected_out):
    f = tmpdir.join('test.py')
    f.write_binary(contents)

# Path: pre_commit_hooks/check_docstring_first.py
# def check_docstring_first(src: bytes, filename: str = '<unknown>') -> int:
#     """Returns nonzero if the source has what looks like a docstring that is
#     not at the beginning of the source.
# 
#     A string will be considered a docstring if it is a STRING token with a
#     col offset of 0.
#     """
#     found_docstring_line = None
#     found_code_line = None
# 
#     tok_gen = tokenize_tokenize(io.BytesIO(src).readline)
#     for tok_type, _, (sline, scol), _, _ in tok_gen:
#         # Looks like a docstring!
#         if tok_type == tokenize.STRING and scol == 0:
#             if found_docstring_line is not None:
#                 print(
#                     f'{filename}:{sline} Multiple module docstrings '
#                     f'(first docstring on line {found_docstring_line}).',
#                 )
#                 return 1
#             elif found_code_line is not None:
#                 print(
#                     f'{filename}:{sline} Module docstring appears after code '
#                     f'(code seen on line {found_code_line}).',
#                 )
#                 return 1
#             else:
#                 found_docstring_line = sline
#         elif tok_type not in NON_CODE_TOKENS and found_code_line is None:
#             found_code_line = sline
# 
#     return 0
# 
# Path: pre_commit_hooks/check_docstring_first.py
# def main(argv: Sequence[str] | None = None) -> int:
#     parser = argparse.ArgumentParser()
#     parser.add_argument('filenames', nargs='*')
#     args = parser.parse_args(argv)
# 
#     retv = 0
# 
#     for filename in args.filenames:
#         with open(filename, 'rb') as f:
#             contents = f.read()
#         retv |= check_docstring_first(contents, filename=filename)
# 
#     return retv


# Path: tests/check_docstring_first_test.py
import pytest
from pre_commit_hooks.check_docstring_first import check_docstring_first
from pre_commit_hooks.check_docstring_first import main

    ),
    # Test multiple lines of code above
    (
        b'import os\n'
        b'import sys\n'
        b'"docstring"\n',
        1,
        '{filename}:3 Module docstring appears after code '
        '(code seen on line 1).\n',
    ),
    # String literals in expressions are ok.
    (b'x = "foo"\n', 0, ''),
)


all_tests = pytest.mark.parametrize(
    ('contents', 'expected', 'expected_out'), TESTS,
)


@all_tests
def test_unit(capsys, contents, expected, expected_out):
    assert check_docstring_first(contents) == expected
    assert capsys.readouterr()[0] == expected_out.format(filename='<unknown>')


@all_tests
def test_integration(tmpdir, capsys, contents, expected, expected_out):
    f = tmpdir.join('test.py')
    f.write_binary(contents)

    assert main([str(f)]) == expected