コード例 #1
0
ファイル: test_imports.py プロジェクト: skarzi/import-linter
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
コード例 #2
0
ファイル: layers.py プロジェクト: skarzi/import-linter
 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
コード例 #3
0
 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))
コード例 #4
0
ファイル: fields.py プロジェクト: joseph-zhong/import-linter
 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))
コード例 #5
0
    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
コード例 #6
0
ファイル: layers.py プロジェクト: joseph-zhong/import-linter
 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)
コード例 #7
0
ファイル: layers.py プロジェクト: joseph-zhong/import-linter
 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)
コード例 #8
0
ファイル: fields.py プロジェクト: joseph-zhong/import-linter
 def parse(self, raw_data: Union[str, List]) -> Module:
     return Module(StringField().parse(raw_data))
コード例 #9
0
    (
        ("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",
    (
        (
コード例 #10
0
ファイル: test_imports.py プロジェクト: skarzi/import-linter
 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>"
コード例 #11
0
ファイル: test_imports.py プロジェクト: skarzi/import-linter
 def test_object_representation(self):
     test_object = Module("new_module")
     assert repr(test_object) == "<Module: new_module>"
コード例 #12
0
ファイル: test_imports.py プロジェクト: skarzi/import-linter
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