class TestDirectImport: def test_object_representation(self): test_object = DirectImport( importer=Module("mypackage.foo"), imported=Module("mypackage.bar"), ) assert repr(test_object) == "<DirectImport: mypackage.foo -> mypackage.bar>" @pytest.mark.parametrize( ("test_object", "expected_string"), [ ( DirectImport(importer=Module("mypackage.foo"), imported=Module("mypackage.bar")), "mypackage.foo -> mypackage.bar", ), ( DirectImport( importer=Module("mypackage.foo"), imported=Module("mypackage.bar"), line_number=10, ), "mypackage.foo -> mypackage.bar (l. 10)", ), ], ) def test_string_object_representation(self, test_object, expected_string): assert str(test_object) == expected_string
def _pop_direct_imports(cls, higher_layer_package, lower_layer_package, graph): import_details_list = [] lower_layer_modules = {lower_layer_package.name} | graph.find_descendants( lower_layer_package.name ) for lower_layer_module in lower_layer_modules: imported_modules = graph.find_modules_directly_imported_by(lower_layer_module) for imported_module in imported_modules: if Module(imported_module) == higher_layer_package or Module( imported_module ).is_descendant_of(higher_layer_package): import_details = graph.get_import_details( importer=lower_layer_module, imported=imported_module ) if not import_details: # get_import_details may not return any imports (for example if an import # has been added without metadata. If nothing is returned, we still want # to add some details about the import to the list. import_details = [ { "importer": lower_layer_module, "imported": imported_module, "line_number": "?", "line_contents": "", } ] import_details_list.append(import_details) graph.remove_import(importer=lower_layer_module, imported=imported_module) return import_details_list
def parse(self, raw_data: Union[str, List]) -> DirectImport: string = StringField().parse(raw_data) importer, _, imported = string.partition(" -> ") if not (importer and imported): raise ValidationError( 'Must be in the form "package.importer -> package.imported".') return DirectImport(importer=Module(importer), imported=Module(imported))
def parse(self, raw_data: Union[str, List]) -> DirectImport: string = StringField().parse(raw_data) match = self.DIRECT_IMPORT_STRING_REGEX.match(string) if not match: raise ValidationError( 'Must be in the form "package.importer -> package.imported".') importer, imported = match.groups() return DirectImport(importer=Module(importer), imported=Module(imported))
def _segments_to_collapsed_chains(cls, graph, segments, importer: Module, imported: Module): collapsed_chains = [] for segment in segments: head_imports = [] imported_module = segment[0]["imported"] candidate_modules = sorted( graph.find_modules_that_directly_import(imported_module)) for module in [ m for m in candidate_modules if Module(m) == importer or Module(m).is_descendant_of(importer) ]: import_details_list = graph.get_import_details( importer=module, imported=imported_module) line_numbers = tuple( set(j["line_number"] for j in import_details_list)) head_imports.append({ "importer": module, "imported": imported_module, "line_numbers": line_numbers }) tail_imports = [] importer_module = segment[-1]["importer"] candidate_modules = sorted( graph.find_modules_directly_imported_by(importer_module)) for module in [ m for m in candidate_modules if Module(m) == imported or Module(m).is_descendant_of(imported) ]: import_details_list = graph.get_import_details( importer=importer_module, imported=module) line_numbers = tuple( set(j["line_number"] for j in import_details_list)) tail_imports.append({ "importer": importer_module, "imported": module, "line_numbers": line_numbers }) collapsed_chains.append({ "chain": [head_imports[0]] + segment[1:-1] + [tail_imports[0]], "extra_firsts": head_imports[1:], "extra_lasts": tail_imports[1:], }) return collapsed_chains
def _module_from_layer(self, layer: Layer, container: Optional[str] = None) -> Module: if container: name = ".".join([container, layer.name]) else: name = layer.name return Module(name)
def _validate_containers(self, graph: ImportGraph) -> None: root_package_names = self.session_options["root_packages"] for container in self.containers: # type: ignore if Module(container).root_package_name not in root_package_names: if len(root_package_names) == 1: root_package_name = root_package_names[0] error_message = ( f"Invalid container '{container}': a container must either be a " f"subpackage of {root_package_name}, or {root_package_name} itself." ) else: packages_string = ", ".join(root_package_names) error_message = ( f"Invalid container '{container}': a container must either be a root " f"package, or a subpackage of one of them. " f"(The root packages are: {packages_string}.)") raise ValueError(error_message) self._check_all_layers_exist_for_container(container, graph)
def parse(self, raw_data: Union[str, List]) -> Module: return Module(StringField().parse(raw_data))
( ("Hello, world!", "Hello, world!"), ( ["one", "two", "three"], ValidationError("Expected a single value, got multiple values."), ), ), ) class TestStringField(BaseFieldTest): field_class = StringField @pytest.mark.parametrize( "raw_data, expected_value", ( ("mypackage.foo.bar", Module("mypackage.foo.bar")), ( ["one", "two", "three"], ValidationError("Expected a single value, got multiple values."), ), # TODO - test that it belongs in the root package. ), ) class TestModuleField(BaseFieldTest): field_class = ModuleField @pytest.mark.parametrize( "raw_data, expected_value", ( (
def test_object_representation(self): test_object = DirectImport( importer=Module("mypackage.foo"), imported=Module("mypackage.bar"), ) assert repr(test_object) == "<DirectImport: mypackage.foo -> mypackage.bar>"
def test_object_representation(self): test_object = Module("new_module") assert repr(test_object) == "<Module: new_module>"
class TestModule: def test_object_representation(self): test_object = Module("new_module") assert repr(test_object) == "<Module: new_module>" @pytest.mark.parametrize( ("first_object", "second_object", "expected_bool"), [ (Module("first"), Module("second"), False), (Module("same"), Module("same"), True), (Module("different"), "different", False), ], ) def test_equal_magic_method(self, first_object, second_object, expected_bool): comparison_result = first_object == second_object assert comparison_result is expected_bool @pytest.mark.parametrize( ("module", "expected_parent", "exception"), [ (Module("parent.child"), Module("parent"), does_not_raise()), (Module("child"), Module(""), pytest.raises(ValueError)), ], ) def test_parent(self, module, expected_parent, exception): with exception: assert module.parent == expected_parent @pytest.mark.parametrize( ("child", "parent", "expected_bool"), [ (Module("parent.child"), Module("parent"), True), (Module("grandparent.parent.child"), Module("grandparent"), False), (Module("first_child"), Module("second_child"), False), ], ) def test_is_child_of(self, child, parent, expected_bool): assert child.is_child_of(parent) is expected_bool