Skip to content

Commit

Permalink
Heuristic for project to module conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
arkq committed Nov 27, 2017
1 parent a3360c5 commit cdefc92
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 7 deletions.
33 changes: 26 additions & 7 deletions src/flake8_requirements/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@
STDLIB.update(STDLIB_PY3)


def project2module(project):
"""Convert project name into a module name."""
# Name unification in accordance with PEP 426.
project = project.lower().replace("-", "_")
if project.startswith("python_"):
# Remove conventional "python-" prefix.
project = project[7:]
return project


class ImportVisitor(ast.NodeVisitor):
"""Import statement visitor."""

Expand Down Expand Up @@ -183,19 +193,28 @@ def get_setup(self):
def run(self):
"""Run checker."""

def split(module):
"""Split module into submodules."""
return tuple(module.split("."))

def modcmp(mod1=(), mod2=()):
"""Compare import modules."""
return all(a == b for a, b in zip(mod1, mod2))

requirements = set()
mods_1st_party = set()
mods_3rd_party = set()

# Get 1st party modules (used for absolute imports).
mods_1st_party.add(
split(project2module(self.setup.keywords['name'])),
)

# Get module names based on requirements.
# Get 3rd party module names based on requirements.
for requirement in self.setup.get_requirements():
project = requirement.project_name.lower()
modules = [project.replace("-", "_")]
if project in KNOWN_3RD_PARTIES:
modules = KNOWN_3RD_PARTIES[project]
requirements.update(tuple(x.split(".")) for x in modules)
modules = [project2module(requirement.project_name)]
if modules[0] in KNOWN_3RD_PARTIES:
modules = KNOWN_3RD_PARTIES[modules[0]]
mods_3rd_party.update(split(x) for x in modules)

for node, module in ImportVisitor(self.tree).imports:
_module = module.split(".")
Expand Down
13 changes: 13 additions & 0 deletions test/test_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@


class SetupVisitorMock:
keywords = {
'name': "flake8-requires",
}

def get_requirements(self):
return parse_requirements((
"foo",
"bar",
"hyp-hen",
"python-boom",
"setuptools",
))

Expand Down Expand Up @@ -41,10 +46,18 @@ def test_stdlib_case(self):
"I900 'cprofile' not listed as a requirement",
)

def test_1st_party(self):
errors = check("import flake8_requires")
self.assertEqual(len(errors), 0)

def test_3rd_party(self):
errors = check("import foo\nfrom bar import Bar")
self.assertEqual(len(errors), 0)

def test_3rd_party_python_prefix(self):
errors = check("from boom import blast")
self.assertEqual(len(errors), 0)

def test_3rd_party_missing(self):
errors = check("import os\nfrom cat import Cat")
self.assertEqual(len(errors), 1)
Expand Down

0 comments on commit cdefc92

Please sign in to comment.