Skip to content

Commit

Permalink
Relax regex re. recognizing requirements.txt
Browse files Browse the repository at this point in the history
Zhihan found that the plotly project has some requirements files that
are not recognized by FawltyDeps, with names like requirements_abc.txt.

Using the underscore as a separator in the filename does not match our
regex, which requires a word boundary ("\b") around the "requirements"
string in the filename.

Fix our regex: There is no reason why the underscore separator should
disqualify this as a requirements file, and simplifying the regex to
".*requirements.*\.(txt|in)" is unlikely to introduce false positives
(files that should _not_ be recognized as requirements.txt files, but
now are).

Also add unit tests precisely for parsing filenames of dependency files
as I could not find another test case that tested exactly this.
  • Loading branch information
jherland committed Sep 27, 2023
1 parent 165027c commit 69a8b61
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
2 changes: 1 addition & 1 deletion fawltydeps/extract_declared_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ def first_applicable_parser(path: Path) -> Optional[ParserChoice]:
lambda path: path.name == "pyproject.toml", parse_pyproject_toml
),
ParserChoice.REQUIREMENTS_TXT: ParsingStrategy(
lambda path: re.compile(r".*\brequirements\b.*\.(txt|in)").match(path.name)
lambda path: re.compile(r".*requirements.*\.(txt|in)").match(path.name)
is not None,
parse_requirements_txt,
),
Expand Down
41 changes: 41 additions & 0 deletions tests/test_deps_parser_determination.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import logging
import shutil
from pathlib import Path

import pytest

from fawltydeps.extract_declared_dependencies import (
first_applicable_parser,
parse_source,
parse_sources,
validate_deps_source,
Expand All @@ -16,6 +18,45 @@

from .utils import assert_unordered_equivalence, collect_dep_names


@pytest.mark.parametrize(
["path", "expect_choice"],
[
pytest.param(Path(path), expect_choice, id=path)
for path, expect_choice in [
("requirements.txt", ParserChoice.REQUIREMENTS_TXT),
("setup.py", ParserChoice.SETUP_PY),
("setup.cfg", ParserChoice.SETUP_CFG),
("pyproject.toml", ParserChoice.PYPROJECT_TOML),
("anything_else", None),
("sub/requirements.txt", ParserChoice.REQUIREMENTS_TXT),
("sub/setup.py", ParserChoice.SETUP_PY),
("sub/setup.cfg", ParserChoice.SETUP_CFG),
("sub/pyproject.toml", ParserChoice.PYPROJECT_TOML),
("sub/anything_else", None),
("/abs/requirements.txt", ParserChoice.REQUIREMENTS_TXT),
("/abs/setup.py", ParserChoice.SETUP_PY),
("/abs/setup.cfg", ParserChoice.SETUP_CFG),
("/abs/pyproject.toml", ParserChoice.PYPROJECT_TOML),
("/abs/anything_else", None),
("requirements.txt/wat", None),
("setup.py/wat", None),
("setup.cfg/wat", None),
("pyproject.toml/wat", None),
("requirements-dev.txt", ParserChoice.REQUIREMENTS_TXT),
("test-requirements.txt", ParserChoice.REQUIREMENTS_TXT),
("extra-requirements-dev.txt", ParserChoice.REQUIREMENTS_TXT),
("abc_requirements.txt", ParserChoice.REQUIREMENTS_TXT),
("requirements_abc.txt", ParserChoice.REQUIREMENTS_TXT),
("more_requirements_stuff.txt", ParserChoice.REQUIREMENTS_TXT),
("evenrequirementsthis.txt", ParserChoice.REQUIREMENTS_TXT),
]
],
)
def test_first_applicable_parser(path, expect_choice):
assert first_applicable_parser(path) is expect_choice


PARSER_CHOICE_FILE_NAME_MATCH_GRID = {
ParserChoice.REQUIREMENTS_TXT: "requirements.txt",
ParserChoice.SETUP_PY: "setup.py",
Expand Down

0 comments on commit 69a8b61

Please sign in to comment.