示例#1
0
def test_map_first_party_modules_to_addresses(rule_runner: RuleRunner) -> None:
    rule_runner.set_options(
        ["--source-root-patterns=['src/python', 'tests/python', 'build-support']"]
    )

    # Two modules belonging to the same target. We should generate subtargets for each file.
    rule_runner.create_files("src/python/project/util", ["dirutil.py", "tarutil.py"])
    rule_runner.add_to_build_file("src/python/project/util", "python_library()")

    # A module with two owners, meaning that neither should be resolved.
    rule_runner.create_file("src/python/two_owners.py")
    rule_runner.add_to_build_file("src/python", "python_library()")
    rule_runner.create_file("build-support/two_owners.py")
    rule_runner.add_to_build_file("build-support", "python_library()")

    # A package module. Because there's only one source file belonging to the target, we should
    # not generate subtargets.
    rule_runner.create_file("tests/python/project_test/demo_test/__init__.py")
    rule_runner.add_to_build_file("tests/python/project_test/demo_test", "python_library()")

    # A module with both an implementation and a type stub.
    rule_runner.create_files("src/python/stubs", ["stub.py", "stub.pyi"])
    rule_runner.add_to_build_file("src/python/stubs", "python_library()")

    # Check that plugin mappings work. Note that we duplicate one of the files with a normal
    # python_library(), which means neither the Protobuf nor Python targets should be used.
    rule_runner.create_files("src/python/protos", ["f1.proto", "f2.proto", "f2_pb2.py"])
    rule_runner.add_to_build_file(
        "src/python/protos",
        dedent(
            """\
            protobuf_library(name='protos')
            python_library(name='py')
            """
        ),
    )

    result = rule_runner.request(FirstPartyPythonModuleMapping, [])
    assert result == FirstPartyPythonModuleMapping(
        {
            "project.util.dirutil": (
                Address("src/python/project/util", relative_file_path="dirutil.py"),
            ),
            "project.util.tarutil": (
                Address("src/python/project/util", relative_file_path="tarutil.py"),
            ),
            "project_test.demo_test": (
                Address("tests/python/project_test/demo_test", relative_file_path="__init__.py"),
            ),
            "protos.f1_pb2": (
                Address("src/python/protos", relative_file_path="f1.proto", target_name="protos"),
            ),
            "stubs.stub": (
                Address("src/python/stubs", relative_file_path="stub.py"),
                Address("src/python/stubs", relative_file_path="stub.pyi"),
            ),
        }
    )
示例#2
0
def test_first_party_modules_mapping() -> None:
    util_addr = Address("src/python/util", relative_file_path="strutil.py")
    test_addr = Address("tests/python/project_test", relative_file_path="test.py")
    mapping = FirstPartyPythonModuleMapping(
        {"util.strutil": (util_addr,), "project_test.test": (test_addr,)}
    )
    assert mapping.addresses_for_module("util.strutil") == (util_addr,)
    assert mapping.addresses_for_module("util.strutil.ensure_text") == (util_addr,)
    assert not mapping.addresses_for_module("util")
    assert mapping.addresses_for_module("project_test.test") == (test_addr,)
    assert mapping.addresses_for_module("project_test.test.TestDemo") == (test_addr,)
    assert not mapping.addresses_for_module("project_test.test.TestDemo.method")
    assert not mapping.addresses_for_module("project_test")
    assert not mapping.addresses_for_module("project.test")
示例#3
0
def test_first_party_modules_mapping() -> None:
    root_addr = Address("", relative_file_path="root.py")
    util_addr = Address("src/python/util", relative_file_path="strutil.py")
    util_stubs_addr = Address("src/python/util",
                              relative_file_path="strutil.pyi")
    test_addr = Address("tests/python/project_test",
                        relative_file_path="test.py")
    mapping = FirstPartyPythonModuleMapping(
        mapping=FrozenDict({
            "root": (root_addr, ),
            "util.strutil": (util_addr, util_stubs_addr),
            "project_test.test": (test_addr, ),
        }),
        ambiguous_modules=FrozenDict({
            "ambiguous": (root_addr, util_addr),
            "util.ambiguous": (util_addr, test_addr)
        }),
    )

    def assert_addresses(
            mod: str, expected: tuple[tuple[Address, ...],
                                      tuple[Address, ...]]) -> None:
        assert mapping.addresses_for_module(mod) == expected

    unknown = ((), ())

    root = ((root_addr, ), ())
    assert_addresses("root", root)
    assert_addresses("root.func", root)
    assert_addresses("root.submodule.func", unknown)

    util = ((util_addr, util_stubs_addr), ())
    assert_addresses("util.strutil", util)
    assert_addresses("util.strutil.ensure_text", util)
    assert_addresses("util", unknown)

    test = ((test_addr, ), ())
    assert_addresses("project_test.test", test)
    assert_addresses("project_test.test.TestDemo", test)
    assert_addresses("project_test", unknown)
    assert_addresses("project.test", unknown)

    ambiguous = ((), (root_addr, util_addr))
    assert_addresses("ambiguous", ambiguous)
    assert_addresses("ambiguous.func", ambiguous)
    assert_addresses("ambiguous.submodule.func", unknown)

    util_ambiguous = ((), (util_addr, test_addr))
    assert_addresses("util.ambiguous", util_ambiguous)
    assert_addresses("util.ambiguous.Foo", util_ambiguous)
    assert_addresses("util.ambiguous.Foo.method", unknown)
示例#4
0
def test_map_first_party_modules_to_addresses(rule_runner: RuleRunner) -> None:
    rule_runner.set_options([
        "--source-root-patterns=['src/python', 'tests/python', 'build-support']"
    ])
    rule_runner.write_files({
        "src/python/project/util/dirutil.py":
        "",
        "src/python/project/util/tarutil.py":
        "",
        "src/python/project/util/BUILD":
        "python_sources()",
        # A module with two owners, meaning that neither should be resolved.
        "src/python/two_owners.py":
        "",
        "src/python/BUILD":
        "python_sources()",
        "build-support/two_owners.py":
        "",
        "build-support/BUILD":
        "python_sources()",
        # A module with two owners that are type stubs.
        "src/python/stub_ambiguity/f.pyi":
        "",
        "src/python/stub_ambiguity/BUILD":
        "python_sources()",
        "build-support/stub_ambiguity/f.pyi":
        "",
        "build-support/stub_ambiguity/BUILD":
        "python_sources()",
        # A package module.
        "tests/python/project_test/demo_test/__init__.py":
        "",
        "tests/python/project_test/demo_test/BUILD":
        "python_sources()",
        # A module with both an implementation and a type stub. Even though the module is the
        # same, we special-case it to be legal for both file targets to be inferred.
        "src/python/stubs/stub.py":
        "",
        "src/python/stubs/stub.pyi":
        "",
        "src/python/stubs/BUILD":
        "python_sources()",
        # Check that plugin mappings work. Note that we duplicate one of the files with a normal
        # python_sources(), which means neither the Protobuf nor Python targets should be used.
        "src/python/protos/f1.proto":
        "",
        "src/python/protos/f2.proto":
        "",
        "src/python/protos/f2_pb2.py":
        "",
        "src/python/protos/BUILD":
        dedent("""\
                protobuf_sources(name='protos')
                python_sources(name='py')
                """),
        # If a module is ambiguous within a particular implementation, which means that it's
        # not used in that implementation's final mapping, it should still trigger ambiguity
        # with another implementation. Here, we have ambiguity with the Protobuf targets, but
        # the Python file has no ambiguity with other Python files; the Protobuf ambiguity
        # needs to result in Python being ambiguous.
        "src/python/protos_ambiguous/f.proto":
        "",
        "src/python/protos_ambiguous/f_pb2.py":
        "",
        "src/python/protos_ambiguous/BUILD":
        dedent("""\
                protobuf_sources(name='protos1')
                protobuf_sources(name='protos2')
                python_sources(name='py')
                """),
    })

    result = rule_runner.request(FirstPartyPythonModuleMapping, [])
    assert result == FirstPartyPythonModuleMapping(
        mapping=FrozenDict({
            "project.util.dirutil":
            (Address("src/python/project/util",
                     relative_file_path="dirutil.py"), ),
            "project.util.tarutil":
            (Address("src/python/project/util",
                     relative_file_path="tarutil.py"), ),
            "project_test.demo_test":
            (Address("tests/python/project_test/demo_test",
                     relative_file_path="__init__.py"), ),
            "protos.f1_pb2": (Address("src/python/protos",
                                      relative_file_path="f1.proto",
                                      target_name="protos"), ),
            "stubs.stub": (
                Address("src/python/stubs", relative_file_path="stub.py"),
                Address("src/python/stubs", relative_file_path="stub.pyi"),
            ),
        }),
        ambiguous_modules=FrozenDict({
            "protos.f2_pb2": (
                Address("src/python/protos",
                        relative_file_path="f2.proto",
                        target_name="protos"),
                Address("src/python/protos",
                        relative_file_path="f2_pb2.py",
                        target_name="py"),
            ),
            "protos_ambiguous.f_pb2": (
                Address(
                    "src/python/protos_ambiguous",
                    relative_file_path="f.proto",
                    target_name="protos1",
                ),
                Address(
                    "src/python/protos_ambiguous",
                    relative_file_path="f.proto",
                    target_name="protos2",
                ),
                Address(
                    "src/python/protos_ambiguous",
                    relative_file_path="f_pb2.py",
                    target_name="py",
                ),
            ),
            "stub_ambiguity.f": (
                Address("build-support/stub_ambiguity",
                        relative_file_path="f.pyi"),
                Address("src/python/stub_ambiguity",
                        relative_file_path="f.pyi"),
            ),
            "two_owners": (
                Address("build-support", relative_file_path="two_owners.py"),
                Address("src/python", relative_file_path="two_owners.py"),
            ),
        }),
    )
示例#5
0
def test_first_party_modules_mapping() -> None:
    root_provider = ModuleProvider(Address("", relative_file_path="root.py"),
                                   ModuleProviderType.IMPL)
    util_provider = ModuleProvider(
        Address("src/python/util", relative_file_path="strutil.py"),
        ModuleProviderType.IMPL)
    util_stubs_provider = ModuleProvider(
        Address("src/python/util", relative_file_path="strutil.pyi"),
        ModuleProviderType.TYPE_STUB)
    test_provider = ModuleProvider(
        Address("tests/python/project_test", relative_file_path="test.py"),
        ModuleProviderType.IMPL)
    mapping = FirstPartyPythonModuleMapping(
        FrozenDict({
            "default":
            FrozenDict({
                "root": (root_provider, ),
                "util.strutil": (util_provider, util_stubs_provider),
                "project_test.test": (test_provider, ),
                "ambiguous": (root_provider, util_provider),
                "util.ambiguous": (util_provider, test_provider),
                "two_resolves": (root_provider, ),
            }),
            "another":
            FrozenDict({"two_resolves": (test_provider, )}),
        }))

    def assert_addresses(mod: str,
                         expected: tuple[ModuleProvider, ...],
                         *,
                         resolve: str | None = None) -> None:
        assert mapping.providers_for_module(mod, resolve=resolve) == expected

    assert_addresses("root", (root_provider, ))
    assert_addresses("root.func", (root_provider, ))
    assert_addresses("root.submodule.func", ())

    assert_addresses("util.strutil", (util_provider, util_stubs_provider))
    assert_addresses("util.strutil.ensure_text",
                     (util_provider, util_stubs_provider))
    assert_addresses("util", ())

    assert_addresses("project_test.test", (test_provider, ))
    assert_addresses("project_test.test.TestDemo", (test_provider, ))
    assert_addresses("project_test", ())
    assert_addresses("project.test", ())

    assert_addresses("ambiguous", (root_provider, util_provider))
    assert_addresses("ambiguous.func", (root_provider, util_provider))
    assert_addresses("ambiguous.submodule.func", ())

    assert_addresses("util.ambiguous", (util_provider, test_provider))
    assert_addresses("util.ambiguous.Foo", (util_provider, test_provider))
    assert_addresses("util.ambiguous.Foo.method", ())

    assert_addresses("two_resolves", (root_provider, test_provider),
                     resolve=None)
    assert_addresses("two_resolves.foo", (root_provider, test_provider),
                     resolve=None)
    assert_addresses("two_resolves.foo.bar", (), resolve=None)
    assert_addresses("two_resolves", (root_provider, ), resolve="default")
    assert_addresses("two_resolves", (test_provider, ), resolve="another")
示例#6
0
def test_map_first_party_modules_to_addresses(rule_runner: RuleRunner) -> None:
    rule_runner.set_options([
        "--source-root-patterns=['src/python', 'tests/python', 'build-support']",
        "--python-enable-resolves",
        "--python-resolves={'python-default': '', 'another-resolve': ''}",
    ])
    rule_runner.write_files({
        "src/python/project/util/dirutil.py":
        "",
        "src/python/project/util/tarutil.py":
        "",
        "src/python/project/util/BUILD":
        "python_sources(resolve='another-resolve')",
        # A module with multiple owners, including type stubs.
        "src/python/multiple_owners.py":
        "",
        "src/python/multiple_owners.pyi":
        "",
        "src/python/BUILD":
        "python_sources()",
        "build-support/multiple_owners.py":
        "",
        "build-support/BUILD":
        "python_sources()",
        # A package module.
        "tests/python/project_test/demo_test/__init__.py":
        "",
        "tests/python/project_test/demo_test/BUILD":
        "python_sources()",
        # Check that plugin mappings work. Note that we duplicate one of the files with a normal
        # python_source.
        "src/python/protos/f1.proto":
        "",
        "src/python/protos/f2.proto":
        "",
        "src/python/protos/f2_pb2.py":
        "",
        "src/python/protos/BUILD":
        dedent("""\
                protobuf_sources(name='protos')
                python_source(name='py', source="f2_pb2.py")
                """),
    })

    result = rule_runner.request(FirstPartyPythonModuleMapping, [])
    assert result == FirstPartyPythonModuleMapping(
        FrozenDict({
            "another-resolve":
            FrozenDict({
                "project.util.dirutil": (ModuleProvider(
                    Address("src/python/project/util",
                            relative_file_path="dirutil.py"),
                    ModuleProviderType.IMPL,
                ), ),
                "project.util.tarutil": (ModuleProvider(
                    Address("src/python/project/util",
                            relative_file_path="tarutil.py"),
                    ModuleProviderType.IMPL,
                ), ),
            }),
            "python-default":
            FrozenDict({
                "multiple_owners": (
                    ModuleProvider(
                        Address("build-support",
                                relative_file_path="multiple_owners.py"),
                        ModuleProviderType.IMPL,
                    ),
                    ModuleProvider(
                        Address("src/python",
                                relative_file_path="multiple_owners.py"),
                        ModuleProviderType.IMPL,
                    ),
                    ModuleProvider(
                        Address("src/python",
                                relative_file_path="multiple_owners.pyi"),
                        ModuleProviderType.TYPE_STUB,
                    ),
                ),
                "project_test.demo_test": (ModuleProvider(
                    Address(
                        "tests/python/project_test/demo_test",
                        relative_file_path="__init__.py",
                    ),
                    ModuleProviderType.IMPL,
                ), ),
                "protos.f1_pb2": (ModuleProvider(
                    Address(
                        "src/python/protos",
                        relative_file_path="f1.proto",
                        target_name="protos",
                    ),
                    ModuleProviderType.IMPL,
                ), ),
                "protos.f2_pb2": (
                    ModuleProvider(
                        Address("src/python/protos", target_name="py"),
                        ModuleProviderType.IMPL,
                    ),
                    ModuleProvider(
                        Address(
                            "src/python/protos",
                            relative_file_path="f2.proto",
                            target_name="protos",
                        ),
                        ModuleProviderType.IMPL,
                    ),
                ),
            }),
        }))
示例#7
0
def test_first_party_modules_mapping() -> None:
    root_addr = Address("", relative_file_path="root.py")
    util_addr = Address("src/python/util", relative_file_path="strutil.py")
    test_addr = Address("tests/python/project_test", relative_file_path="test.py")
    mapping = FirstPartyPythonModuleMapping(
        mapping=FrozenDict(
            {"root": (root_addr,), "util.strutil": (util_addr,), "project_test.test": (test_addr,)}
        ),
        ambiguous_modules=FrozenDict(
            {"ambiguous": (root_addr, util_addr), "util.ambiguous": (util_addr, test_addr)}
        ),
    )

    assert mapping.addresses_for_module("root") == ((root_addr,), ())
    assert mapping.addresses_for_module("root.func") == ((root_addr,), ())
    assert mapping.addresses_for_module("root.submodule.func") == ((), ())

    assert mapping.addresses_for_module("util.strutil") == ((util_addr,), ())
    assert mapping.addresses_for_module("util.strutil.ensure_text") == ((util_addr,), ())
    assert mapping.addresses_for_module("util") == ((), ())

    assert mapping.addresses_for_module("project_test.test") == ((test_addr,), ())
    assert mapping.addresses_for_module("project_test.test.TestDemo") == ((test_addr,), ())
    assert mapping.addresses_for_module("project_test.test.TestDemo.method") == ((), ())
    assert mapping.addresses_for_module("project_test") == ((), ())
    assert mapping.addresses_for_module("project.test") == ((), ())

    assert mapping.addresses_for_module("ambiguous") == ((), (root_addr, util_addr))
    assert mapping.addresses_for_module("ambiguous.func") == ((), (root_addr, util_addr))
    assert mapping.addresses_for_module("ambiguous.submodule.func") == ((), ())

    assert mapping.addresses_for_module("util.ambiguous") == ((), (util_addr, test_addr))
    assert mapping.addresses_for_module("util.ambiguous.Foo") == ((), (util_addr, test_addr))
    assert mapping.addresses_for_module("util.ambiguous.Foo.method") == ((), ())
示例#8
0
def test_map_first_party_modules_to_addresses(rule_runner: RuleRunner) -> None:
    rule_runner.set_options(
        ["--source-root-patterns=['src/python', 'tests/python', 'build-support']"]
    )

    # Two modules belonging to the same target. We should generate subtargets for each file.
    rule_runner.create_files("src/python/project/util", ["dirutil.py", "tarutil.py"])
    rule_runner.add_to_build_file("src/python/project/util", "python_library()")

    # A module with two owners, meaning that neither should be resolved.
    rule_runner.create_file("src/python/two_owners.py")
    rule_runner.add_to_build_file("src/python", "python_library()")
    rule_runner.create_file("build-support/two_owners.py")
    rule_runner.add_to_build_file("build-support", "python_library()")

    # A package module. Because there's only one source file belonging to the target, we should
    # not generate subtargets.
    rule_runner.create_file("tests/python/project_test/demo_test/__init__.py")
    rule_runner.add_to_build_file("tests/python/project_test/demo_test", "python_library()")

    # A module with both an implementation and a type stub. Even though the module is the same, we
    # special-case it to be legal for both file targets to be inferred.
    rule_runner.create_files("src/python/stubs", ["stub.py", "stub.pyi"])
    rule_runner.add_to_build_file("src/python/stubs", "python_library()")

    # Check that plugin mappings work. Note that we duplicate one of the files with a normal
    # python_library(), which means neither the Protobuf nor Python targets should be used.
    rule_runner.create_files("src/python/protos", ["f1.proto", "f2.proto", "f2_pb2.py"])
    rule_runner.add_to_build_file(
        "src/python/protos",
        dedent(
            """\
            protobuf_library(name='protos')
            python_library(name='py')
            """
        ),
    )

    # If a module is ambiguous within a particular implementation, which means that it's not used
    # in that implementation's final mapping, it should still trigger ambiguity with another
    # implementation. Here, we have ambiguity with the Protobuf targets, but the Python file has
    # no ambiguity with other Python files; the Protobuf ambiguity needs to result in Python
    # being ambiguous.
    rule_runner.create_files("src/python/protos_ambiguous", ["f.proto", "f_pb2.py"])
    rule_runner.add_to_build_file(
        "src/python/protos_ambiguous",
        dedent(
            """\
            protobuf_library(name='protos1')
            protobuf_library(name='protos2')
            python_library(name='py')
            """
        ),
    )

    result = rule_runner.request(FirstPartyPythonModuleMapping, [])
    assert result == FirstPartyPythonModuleMapping(
        mapping=FrozenDict(
            {
                "project.util.dirutil": (
                    Address("src/python/project/util", relative_file_path="dirutil.py"),
                ),
                "project.util.tarutil": (
                    Address("src/python/project/util", relative_file_path="tarutil.py"),
                ),
                "project_test.demo_test": (
                    Address(
                        "tests/python/project_test/demo_test", relative_file_path="__init__.py"
                    ),
                ),
                "protos.f1_pb2": (
                    Address(
                        "src/python/protos", relative_file_path="f1.proto", target_name="protos"
                    ),
                ),
                "stubs.stub": (
                    Address("src/python/stubs", relative_file_path="stub.py"),
                    Address("src/python/stubs", relative_file_path="stub.pyi"),
                ),
            }
        ),
        ambiguous_modules=FrozenDict(
            {
                "protos.f2_pb2": (
                    Address(
                        "src/python/protos", relative_file_path="f2.proto", target_name="protos"
                    ),
                    Address("src/python/protos", relative_file_path="f2_pb2.py", target_name="py"),
                ),
                "protos_ambiguous.f_pb2": (
                    Address(
                        "src/python/protos_ambiguous",
                        relative_file_path="f.proto",
                        target_name="protos1",
                    ),
                    Address(
                        "src/python/protos_ambiguous",
                        relative_file_path="f.proto",
                        target_name="protos2",
                    ),
                    Address(
                        "src/python/protos_ambiguous",
                        relative_file_path="f_pb2.py",
                        target_name="py",
                    ),
                ),
                "two_owners": (
                    Address("build-support", relative_file_path="two_owners.py"),
                    Address("src/python", relative_file_path="two_owners.py"),
                ),
            }
        ),
    )