def test_ignores_orphaned_python_files(): # Python files in directories that don't contain an __init__.py should not be discovered. module_finder = ModuleFinder() file_system = FakeFileSystem( contents=""" /path/to/mypackage/ __init__.py two/ __init__.py green.py noinitpackage/ green.py orphan/ __init__.py red.py """ ) result = module_finder.find_modules( package_name="mypackage", package_directory="/path/to/mypackage", file_system=file_system, ) expected_modules = { Module("mypackage"), Module("mypackage.two"), Module("mypackage.two.green"), } assert set(result) == expected_modules
def test_happy_path(): module_finder = ModuleFinder() file_system = FakeFileSystem( contents=""" /path/to/mypackage/ __init__.py not-a-python-file.txt .hidden foo/ __init__.py one.py two/ __init__.py green.py blue.py """ ) result = module_finder.find_modules( package_name="mypackage", package_directory="/path/to/mypackage", file_system=file_system, ) expected_modules = { Module("mypackage"), Module("mypackage.foo"), Module("mypackage.foo.one"), Module("mypackage.foo.two"), Module("mypackage.foo.two.green"), Module("mypackage.foo.two.blue"), } assert set(result) == expected_modules
def test_relative_from_imports(): all_modules = { Module("foo.one.blue"), Module("foo.one.green"), Module("foo.two.brown"), Module("foo.two.yellow"), Module("foo.three"), } file_system = FakeFileSystem( contents=""" /path/to/foo/ __init__.py one/ __init__.py blue.py green.py two/ __init__.py brown.py yellow.py three.py """, content_map={ "/path/to/foo/one/blue.py": """ from . import green from ..two import yellow from .. import three arbitrary_expression = 1 """ }, ) import_scanner = ImportScanner( modules_by_package_directory={"/path/to/foo": all_modules}, file_system=file_system, ) result = import_scanner.scan_for_imports(Module("foo.one.blue")) assert result == { DirectImport( importer=Module("foo.one.blue"), imported=Module("foo.one.green"), line_number=1, line_contents="from . import green", ), DirectImport( importer=Module("foo.one.blue"), imported=Module("foo.two.yellow"), line_number=2, line_contents="from ..two import yellow", ), DirectImport( importer=Module("foo.one.blue"), imported=Module("foo.three"), line_number=3, line_contents="from .. import three", ), }
def test_trims_to_known_modules(import_source): all_modules = { Module("foo"), Module("foo.one"), Module("foo.two"), Module("foo.two.yellow"), } file_system = FakeFileSystem( contents=""" /path/to/foo/ __init__.py one.py two/ __init__.py yellow.py """, content_map={"/path/to/foo/one.py": import_source}, ) import_scanner = ImportScanner( modules_by_package_directory={"/path/to/foo": all_modules}, file_system=file_system, ) result = import_scanner.scan_for_imports(Module("foo.one")) assert result == { DirectImport( importer=Module("foo.one"), imported=Module("foo.two.yellow"), line_number=1, line_contents=import_source, ) }
def test_trims_whitespace_from_start_of_line_contents(): all_modules = {Module("foo"), Module("foo.one"), Module("foo.two")} file_system = FakeFileSystem( contents=""" /path/to/foo/ __init__.py one.py two.py """, content_map={ "/path/to/foo/one.py": """ def my_function(): from . import two """ }, ) import_scanner = ImportScanner( modules_by_package_directory={"/path/to/foo": all_modules}, file_system=file_system, ) result = import_scanner.scan_for_imports(Module("foo.one")) assert result == { DirectImport( importer=Module("foo.one"), imported=Module("foo.two"), line_number=2, line_contents="from . import two", ) }
def test_ignores_hidden_directories(): module_finder = ModuleFinder() file_system = FakeFileSystem( contents=""" /path/to/mypackage/ __init__.py two/ __init__.py green.py .hidden/ green.py orphan/ __init__.py red.py """ ) result = module_finder.find_modules( package_name="mypackage", package_directory="/path/to/mypackage", file_system=file_system, ) expected_modules = { Module("mypackage"), Module("mypackage.two"), Module("mypackage.two.green"), } assert set(result) == expected_modules
def test_happy_path(self, include_external_packages): file_system = FakeFileSystem( contents=""" /path/to/mypackage/ __init__.py foo/ __init__.py one.py two/ __init__.py green.py blue.py """, content_map={ "/path/to/mypackage/foo/one.py": "import mypackage.foo.two.green", "/path/to/mypackage/foo/two/green.py": "import mypackage.foo.two.blue\n" "from external.subpackage import foobar\n" "import decimal", }, ) class FakePackageFinder(BaseFakePackageFinder): directory_map = {"mypackage": "/path/to/mypackage"} with override_settings(FILE_SYSTEM=file_system, PACKAGE_FINDER=FakePackageFinder()): graph = usecases.build_graph( "mypackage", include_external_packages=include_external_packages) expected_import_map = { "mypackage": set(), "mypackage.foo": set(), "mypackage.foo.one": {"mypackage.foo.two.green"}, "mypackage.foo.two": set(), "mypackage.foo.two.green": {"mypackage.foo.two.blue"}, "mypackage.foo.two.blue": set(), } if include_external_packages: expected_import_map["decimal"] = set() expected_import_map["external"] = set() expected_import_map["mypackage.foo.two.green"] |= { "external", "decimal" } assert set(expected_import_map.keys()) == graph.modules for importer, imported_modules in expected_import_map.items(): assert graph.find_modules_directly_imported_by( importer) == imported_modules # Check that the external packages are squashed modules. if include_external_packages: for module in ("external", "decimal"): with pytest.raises( ValueError, match="Cannot find children of a squashed module."): graph.find_children(module)
def test_walk(self): file_system = FakeFileSystem(""" /path/to/mypackage/ __init__.py foo/ __init__.py one.py two/ __init__.py green.py blue.py /anotherpackage/ another.txt """) assert [ ("/path/to/mypackage", ["foo"], ["__init__.py"]), ("/path/to/mypackage/foo", ["two"], ["__init__.py", "one.py"]), ("/path/to/mypackage/foo/two", [], ["__init__.py", "green.py", "blue.py"]), ] == list(file_system.walk("/path/to/mypackage"))
def test_trims_to_known_modules_within_init_file(): all_modules = { Module("foo"), Module("foo.one"), Module("foo.one.yellow"), Module("foo.one.blue"), Module("foo.one.blue.alpha"), } file_system = FakeFileSystem( contents=""" /path/to/foo/ __init__.py one/ __init__.py yellow.py blue/ __init__.py alpha.py """, content_map={ "/path/to/foo/one/__init__.py": "from .yellow import my_function", "/path/to/foo/one/blue/__init__.py": "from .alpha import my_function", }, ) import_scanner = ImportScanner( modules_by_package_directory={"/path/to/foo": all_modules}, file_system=file_system, ) result = import_scanner.scan_for_imports(Module("foo.one")) assert result == { DirectImport( importer=Module("foo.one"), imported=Module("foo.one.yellow"), line_number=1, line_contents="from .yellow import my_function", ) } result = import_scanner.scan_for_imports(Module("foo.one.blue")) assert result == { DirectImport( importer=Module("foo.one.blue"), imported=Module("foo.one.blue.alpha"), line_number=1, line_contents="from .alpha import my_function", ) }
def test_read(self, file_name, expected_contents): file_system = FakeFileSystem( contents=""" /path/to/mypackage/ readme.txt foo/ one.txt two/ green.txt """, content_map={ "/path/to/mypackage/readme.txt": "Lorem", "/path/to/mypackage/foo/one.txt": "Ipsum", "/path/to/mypackage/foo/two/blue.txt": "Dolor sic", }, ) if isinstance(expected_contents, type) and issubclass( expected_contents, Exception): with pytest.raises(expected_contents): file_system.read(file_name) else: assert expected_contents == file_system.read(file_name)
def test_dirnames_can_be_modified_in_place(self): """ From the os.walk docs: The caller can modify the dirnames list in-place (perhaps using del or slice assignment), and walk() will only recurse into the subdirectories whose names remain in dirnames; this can be used to prune the search, impose a specific order of visiting, or even to inform walk() about directories the caller creates or renames before it resumes walk() again. """ file_system = FakeFileSystem(""" /path/to/mypackage/ foo/ one.txt skipme/ two.txt dontskip/ three.txt bar/ four.txt """) expected_tuples = [ ("/path/to/mypackage", ["foo", "bar"], []), ("/path/to/mypackage/foo", ["skipme", "dontskip"], ["one.txt"]), ("/path/to/mypackage/foo/dontskip", [], ["three.txt"]), ("/path/to/mypackage/bar", [], ["four.txt"]), ] actual_tuples = [] for dirpath, dirs, files in file_system.walk("/path/to/mypackage"): # Ensure we make a copy of dirs (since we change it). actual_tuples.append((dirpath, copy(dirs), files)) if "skipme" in dirs: dirs.remove("skipme") continue assert expected_tuples == actual_tuples
def test_absolute_from_imports(include_external_packages, expected_result): all_modules = { Module("foo.one.blue"), Module("foo.one.green"), Module("foo.two.brown"), Module("foo.two.yellow"), Module("foo.three"), } file_system = FakeFileSystem( contents=""" /path/to/foo/ __init__.py one/ __init__.py blue.py green.py two/ __init__.py brown.py yellow.py three.py """, content_map={ "/path/to/foo/one/blue.py": """ from foo.one import green from foo.two import yellow from foo import three from external import one from external.two import blue arbitrary_expression = 1 """ }, ) import_scanner = ImportScanner( modules_by_package_directory={"/path/to/foo": all_modules}, file_system=file_system, include_external_packages=include_external_packages, ) result = import_scanner.scan_for_imports(Module("foo.one.blue")) assert expected_result == result
def test_absolute_imports(include_external_packages, expected_result): all_modules = {Module("foo.one"), Module("foo.two")} file_system = FakeFileSystem( content_map={ "/path/to/foo/one.py": """ import foo.two import externalone import externaltwo.subpackage arbitrary_expression = 1 """ }) import_scanner = ImportScanner( modules_by_package_directory={"/path/to/foo": all_modules}, file_system=file_system, include_external_packages=include_external_packages, ) result = import_scanner.scan_for_imports(Module("foo.one")) assert expected_result == result
def test_scans_multiple_packages(statement): foo_modules = {Module("foo"), Module("foo.one"), Module("foo.two")} bar_modules = {Module("bar"), Module("bar.green"), Module("bar.blue")} file_system = FakeFileSystem( content_map={ "/path/to/foo/one.py": f""" import foo.two {statement} import externalone arbitrary_expression = 1 """ }) import_scanner = ImportScanner( modules_by_package_directory={ "/path/to/foo": foo_modules, "/path/to/bar": bar_modules, }, file_system=file_system, ) result = import_scanner.scan_for_imports(Module("foo.one")) assert { DirectImport( importer=Module("foo.one"), imported=Module("foo.two"), line_number=1, line_contents="import foo.two", ), DirectImport( importer=Module("foo.one"), imported=Module("bar.blue"), line_number=2, line_contents=statement, ), } == result
def test_dirname(self): file_system = FakeFileSystem() assert "/path/to" == file_system.dirname("/path/to/file.txt")
def test_join(self): file_system = FakeFileSystem() assert "/path/to/mypackage/file.py" == file_system.join( "/path/to", "mypackage", "file.py")
def test_split(self): file_system = FakeFileSystem() assert ("/path/to/mypackage", "file.py") == file_system.split("/path/to/mypackage/file.py")
def test_empty_if_directory_does_not_exist(self): file_system = FakeFileSystem(""" /path/to/mypackage/ __init__.py """) assert [] == list(file_system.walk("/path/to/nonexistent/package"))