Ejemplo n.º 1
0
def test_dotted_path_annotation_local_type_def(
    python_version, import_collision_policy, expected_import, comment, remove_type
):
    content = '''
class serializers:
    # why would you do this
    pass

def no_op(arg1):
    """
    Args:
        arg1 (serializers.Serializer): blah
    """
    pass
'''

    if comment:
        comment = f"{comment}\n    "

    docstring_type = "" if remove_type else " (serializers.Serializer)"

    expected = f'''{expected_import}
class serializers:
    # why would you do this
    pass

def no_op(arg1):
    {comment}"""
    Args:
        arg1{docstring_type}: blah
    """
    pass
'''

    with tempfile.NamedTemporaryFile(suffix=".py") as f:
        with open(f.name, "w") as fw:
            fw.write(content)

        test_settings = override_settings(
            PYTHON_VERSION=python_version,
            ALLOW_UNTYPED_ARGS=False,
            REQUIRE_RETURN_TYPE=False,
            IMPORT_COLLISION_POLICY=import_collision_policy,
            UNPATHED_TYPE_POLICY=UnpathedTypePolicy.FAIL,
        )
        inject.clear_and_configure(configuration_factory(test_settings))

        annotate(
            f.name, in_process=True, interactive=False, write=True, silent=True,
        )

        with open(f.name, "r") as fr:
            annotated = fr.read()

    assert annotated == expected
Ejemplo n.º 2
0
def test_decorated_function():
    content = '''
@whatever(param=val)
def decorated(arg1):
    """
    Args:
        arg1 (Tuple[str, ...]): blah

    Returns:
        Tuple[int, ...]: blah
    """
    return tuple(
        int(arg) for arg in arg1
    )
'''

    expected = '''from typing import Tuple


@whatever(param=val)
def decorated(arg1):
    # type: (Tuple[str, ...]) -> Tuple[int, ...]
    """
    Args:
        arg1: blah

    Returns:
        blah
    """
    return tuple(
        int(arg) for arg in arg1
    )
'''

    with tempfile.NamedTemporaryFile(suffix=".py") as f:
        with open(f.name, "w") as fw:
            fw.write(content)

        test_settings = override_settings(
            ALLOW_UNTYPED_ARGS=False,
            REQUIRE_RETURN_TYPE=False,
            IMPORT_COLLISION_POLICY=ImportCollisionPolicy.IMPORT,
            UNPATHED_TYPE_POLICY=UnpathedTypePolicy.FAIL,
        )
        inject.clear_and_configure(configuration_factory(test_settings))

        annotate(
            f.name, in_process=True, interactive=False, write=True, silent=True,
        )

        with open(f.name, "r") as fr:
            annotated = fr.read()

    assert annotated == expected
Ejemplo n.º 3
0
def test_require_return_type(require_return_type):
    """
    NOTE: here is an example of a function where omitting the "Returns"
    block from the docstring and setting `REQUIRE_RETURN_TYPE=False` will
    give the wrong result (...an argument for `REQUIRE_RETURN_TYPE=True`)
    TODO: I don't know if there is any check for return statements we can
    do via Bowler?
    """
    content = '''
def identity(arg1):
    """
    Args:
        arg1 (Tuple[str, ...]): blah
    """
    return arg1
'''

    if not require_return_type:
        expected = '''from typing import Tuple


def identity(arg1):
    # type: (Tuple[str, ...]) -> None
    """
    Args:
        arg1: blah
    """
    return arg1
'''
    else:
        expected = content

    with tempfile.NamedTemporaryFile(suffix=".py") as f:
        with open(f.name, "w") as fw:
            fw.write(content)

        test_settings = override_settings(
            ALLOW_UNTYPED_ARGS=False,
            REQUIRE_RETURN_TYPE=require_return_type,
            IMPORT_COLLISION_POLICY=ImportCollisionPolicy.IMPORT,
            UNPATHED_TYPE_POLICY=UnpathedTypePolicy.FAIL,
        )
        inject.clear_and_configure(configuration_factory(test_settings))

        annotate(
            f.name, in_process=True, interactive=False, write=True, silent=True,
        )

        with open(f.name, "r") as fr:
            annotated = fr.read()

    assert annotated == expected
Ejemplo n.º 4
0
def test_staticmethod():
    """
    First arg *is* annotatable
    """
    content = '''
class SomeClass:
    @staticmethod
    def method(obj, whatever):
        """
        Args:
            obj (object)
            whatever (Any)
        """
        pass
'''

    expected = '''from typing import Any


class SomeClass:
    @staticmethod
    def method(obj, whatever):
        # type: (object, Any) -> None
        """
        Args:
            obj
            whatever
        """
        pass
'''

    with tempfile.NamedTemporaryFile(suffix=".py") as f:
        with open(f.name, "w") as fw:
            fw.write(content)

        test_settings = override_settings(
            ALLOW_UNTYPED_ARGS=False,
            REQUIRE_RETURN_TYPE=False,
            IMPORT_COLLISION_POLICY=ImportCollisionPolicy.IMPORT,
            UNPATHED_TYPE_POLICY=UnpathedTypePolicy.FAIL,
        )
        inject.clear_and_configure(configuration_factory(test_settings))

        annotate(
            f.name, in_process=True, interactive=False, write=True, silent=True,
        )

        with open(f.name, "r") as fr:
            annotated = fr.read()

    assert annotated == expected
Ejemplo n.º 5
0
def test_allow_untyped_args(allow_untyped_args):
    content = '''
def identity(arg1):
    """
    Args:
        arg1: blah

    Returns:
        Tuple[str, ...]: blah
    """
    return arg1
'''

    if allow_untyped_args:
        expected = '''from typing import Tuple


def identity(arg1):
    # type: (...) -> Tuple[str, ...]
    """
    Args:
        arg1: blah

    Returns:
        blah
    """
    return arg1
'''
    else:
        expected = content

    with tempfile.NamedTemporaryFile(suffix=".py") as f:
        with open(f.name, "w") as fw:
            fw.write(content)

        test_settings = override_settings(
            ALLOW_UNTYPED_ARGS=allow_untyped_args,
            REQUIRE_RETURN_TYPE=False,
            IMPORT_COLLISION_POLICY=ImportCollisionPolicy.IMPORT,
            UNPATHED_TYPE_POLICY=UnpathedTypePolicy.FAIL,
        )
        inject.clear_and_configure(configuration_factory(test_settings))

        annotate(
            f.name, in_process=True, interactive=False, write=True, silent=True,
        )

        with open(f.name, "r") as fr:
            annotated = fr.read()

    assert annotated == expected
Ejemplo n.º 6
0
def test_yields_generator():
    content = '''
def generator(arg1):
    """
    Args:
        arg1 (Iterable[int]): blah

    Yields:
        int: blah
    """
    for val in arg1:
        yield val
'''

    expected = '''from typing import Generator, Iterable


def generator(arg1):
    # type: (Iterable[int]) -> Generator[int, None, None]
    """
    Args:
        arg1: blah

    Yields:
        blah
    """
    for val in arg1:
        yield val
'''

    with tempfile.NamedTemporaryFile(suffix=".py") as f:
        with open(f.name, "w") as fw:
            fw.write(content)

        test_settings = override_settings(
            ALLOW_UNTYPED_ARGS=False,
            REQUIRE_RETURN_TYPE=False,
            IMPORT_COLLISION_POLICY=ImportCollisionPolicy.IMPORT,
            UNPATHED_TYPE_POLICY=UnpathedTypePolicy.FAIL,
        )
        inject.clear_and_configure(configuration_factory(test_settings))

        annotate(
            f.name, in_process=True, interactive=False, write=True, silent=True,
        )

        with open(f.name, "r") as fr:
            annotated = fr.read()

    assert annotated == expected
Ejemplo n.º 7
0
def test_dotted_path_decorator():
    # NOTE: this example is an instance method, so first arg is not annotatable
    content = '''
class SomeClass:
    @some_package.decorator
    def method(cls, obj):
        """
        Args:
            obj (object)

        Returns:
            int
        """
        return 1
'''

    expected = '''
class SomeClass:
    @some_package.decorator
    def method(cls, obj):
        # type: (object) -> int
        """
        Args:
            obj
        """
        return 1
'''

    with tempfile.NamedTemporaryFile(suffix=".py") as f:
        with open(f.name, "w") as fw:
            fw.write(content)

        test_settings = override_settings(
            ALLOW_UNTYPED_ARGS=False,
            REQUIRE_RETURN_TYPE=False,
            IMPORT_COLLISION_POLICY=ImportCollisionPolicy.IMPORT,
            UNPATHED_TYPE_POLICY=UnpathedTypePolicy.FAIL,
        )
        inject.clear_and_configure(configuration_factory(test_settings))

        annotate(
            f.name, in_process=True, interactive=False, write=True, silent=True,
        )

        with open(f.name, "r") as fr:
            annotated = fr.read()

    assert annotated == expected
Ejemplo n.º 8
0
def test_returns_none(python_version):
    content = '''
def no_op(arg1):
    """
    Args:
        arg1 (Tuple[str, ...]): blah

    Returns:
        None
    """
    pass
'''

    # "Returns" block omitted since there was no description
    expected = '''from typing import Tuple


def no_op(arg1):
    # type: (Tuple[str, ...]) -> None
    """
    Args:
        arg1: blah
    """
    pass
'''

    with tempfile.NamedTemporaryFile(suffix=".py") as f:
        with open(f.name, "w") as fw:
            fw.write(content)

        test_settings = override_settings(
            PYTHON_VERSION=python_version,
            ALLOW_UNTYPED_ARGS=False,
            REQUIRE_RETURN_TYPE=True,
            IMPORT_COLLISION_POLICY=ImportCollisionPolicy.IMPORT,
            UNPATHED_TYPE_POLICY=UnpathedTypePolicy.FAIL,
        )
        inject.clear_and_configure(configuration_factory(test_settings))

        annotate(
            f.name, in_process=True, interactive=False, write=True, silent=True,
        )

        with open(f.name, "r") as fr:
            annotated = fr.read()

    assert annotated == expected
Ejemplo n.º 9
0
def test_handle_splat_args():
    content = '''
def no_op(arg1, *args, **kwargs):
    """
    Args:
        arg1 (str): blah
        *args (int)
        **kwargs (Tuple[bool, ...])
    """
    return
'''

    expected = '''from typing import Tuple


def no_op(arg1, *args, **kwargs):
    # type: (str, *int, **Tuple[bool, ...]) -> None
    """
    Args:
        arg1: blah
        *args
        **kwargs
    """
    return
'''

    with tempfile.NamedTemporaryFile(suffix=".py") as f:
        with open(f.name, "w") as fw:
            fw.write(content)

        test_settings = override_settings(
            ALLOW_UNTYPED_ARGS=False,
            REQUIRE_RETURN_TYPE=False,
            IMPORT_COLLISION_POLICY=ImportCollisionPolicy.IMPORT,
            UNPATHED_TYPE_POLICY=UnpathedTypePolicy.FAIL,
        )
        inject.clear_and_configure(configuration_factory(test_settings))

        annotate(
            f.name, in_process=True, interactive=False, write=True, silent=True,
        )

        with open(f.name, "r") as fr:
            annotated = fr.read()

    assert annotated == expected
Ejemplo n.º 10
0
def test_allow_missing_args_section_no_args_func(allow_untyped_args):
    """
    If func has no args but 'Returns' is given then we should be
    able to annotate it.
    """
    content = '''
def identity():
    """
    Returns:
        Tuple[str, ...]: blah
    """
    return arg1
'''

    expected = '''from typing import Tuple


def identity():
    # type: () -> Tuple[str, ...]
    """
    Returns:
        blah
    """
    return arg1
'''

    with tempfile.NamedTemporaryFile(suffix=".py") as f:
        with open(f.name, "w") as fw:
            fw.write(content)

        test_settings = override_settings(
            ALLOW_UNTYPED_ARGS=allow_untyped_args,
            REQUIRE_RETURN_TYPE=False,
            IMPORT_COLLISION_POLICY=ImportCollisionPolicy.IMPORT,
            UNPATHED_TYPE_POLICY=UnpathedTypePolicy.FAIL,
        )
        inject.clear_and_configure(configuration_factory(test_settings))

        annotate(
            f.name, in_process=True, interactive=False, write=True, silent=True,
        )

        with open(f.name, "r") as fr:
            annotated = fr.read()

    assert annotated == expected
Ejemplo n.º 11
0
def test_property():
    """
    First arg is not annotatable
    """
    content = '''
class SomeClass:
    @property
    def method(obj):
        """
        Returns:
            int
        """
        return 1
'''

    expected = '''
class SomeClass:
    @property
    def method(obj):
        # type: () -> int
        """
        """
        return 1
'''

    with tempfile.NamedTemporaryFile(suffix=".py") as f:
        with open(f.name, "w") as fw:
            fw.write(content)

        test_settings = override_settings(
            ALLOW_UNTYPED_ARGS=False,
            REQUIRE_RETURN_TYPE=False,
            IMPORT_COLLISION_POLICY=ImportCollisionPolicy.IMPORT,
            UNPATHED_TYPE_POLICY=UnpathedTypePolicy.FAIL,
        )
        inject.clear_and_configure(configuration_factory(test_settings))

        annotate(
            f.name, in_process=True, interactive=False, write=True, silent=True,
        )

        with open(f.name, "r") as fr:
            annotated = fr.read()

    assert annotated == expected
Ejemplo n.º 12
0
def test_package_imports(python_version, import_line, arg_type):
    content = f'''{import_line}

def no_op(arg1):
    """
    Args:
        arg1 ({arg_type}): blah
    """
    pass
'''

    expected = f'''{import_line}

def no_op(arg1):
    # type: ({arg_type}) -> None
    """
    Args:
        arg1: blah
    """
    pass
'''

    with tempfile.NamedTemporaryFile(suffix=".py") as f:
        with open(f.name, "w") as fw:
            fw.write(content)

        test_settings = override_settings(
            PYTHON_VERSION=python_version,
            ALLOW_UNTYPED_ARGS=False,
            REQUIRE_RETURN_TYPE=False,
            IMPORT_COLLISION_POLICY=ImportCollisionPolicy.IMPORT,
            UNPATHED_TYPE_POLICY=UnpathedTypePolicy.FAIL,
        )
        inject.clear_and_configure(configuration_factory(test_settings))

        annotate(
            f.name, in_process=True, interactive=False, write=True, silent=True,
        )

        with open(f.name, "r") as fr:
            annotated = fr.read()

    assert annotated == expected
Ejemplo n.º 13
0
def test_arg_annotation_signature_mismatch(signature, arg_annotations):
    annotations = "\n".join(
        f"        {name} ({type_}): {description}"
        for name, (type_, description) in arg_annotations.items()
    )
    content = f'''
def no_op({signature}):
    """
    Args:
{annotations}
    """
    pass
'''

    # in all cases we should not have annotated
    expected = content

    with tempfile.NamedTemporaryFile(suffix=".py") as f:
        with open(f.name, "w") as fw:
            fw.write(content)

        test_settings = override_settings(
            ALLOW_UNTYPED_ARGS=True,
            REQUIRE_RETURN_TYPE=False,
            IMPORT_COLLISION_POLICY=ImportCollisionPolicy.IMPORT,
            UNPATHED_TYPE_POLICY=UnpathedTypePolicy.FAIL,
        )
        inject.clear_and_configure(configuration_factory(test_settings))

        annotate(
            f.name, in_process=True, interactive=False, write=True, silent=True,
        )

        with open(f.name, "r") as fr:
            annotated = fr.read()

    assert annotated == expected
def test_fully_typed(
    import_collision_policy: ImportCollisionPolicy,
    unpathed_type_policy: UnpathedTypePolicy,
    type_and_imports: Tuple[DocType, Dict[str, ImportT]],
    settings,
):
    (type_name, type_map, import_map), imports = type_and_imports
    note(f"{type_and_imports}")
    note(f"import_collision_policy: {import_collision_policy}")
    note(f"unpathed_type_policy: {unpathed_type_policy}")
    assert type_map.keys() >= imports.keys()

    expect_annotated = True
    expected_import_strategy = {}
    class_defs_needed = set()
    for name, import_t in imports.items():
        type_def, type_src = type_map[name]
        if isinstance(import_t, NonAmbiguousImport):
            if import_t.import_type is ImportType.FROM_PKG_IMPORT_NAME:
                expected_import_strategy[name] = ImportStrategy.USE_EXISTING
            elif import_t.import_type is ImportType.PACKAGE_ONLY:
                expected_import_strategy[
                    name] = ImportStrategy.USE_EXISTING_DOTTED
            else:
                raise TypeError(import_t.import_type)
        elif isinstance(import_t, AmbiguousImport):
            if import_t.ambiguity is Ambiguity.NAME_CLASH:
                expected_import_strategy[name] = ImportStrategy.ADD_DOTTED
            else:
                if import_collision_policy is ImportCollisionPolicy.FAIL:
                    expect_annotated = False
                elif import_collision_policy is ImportCollisionPolicy.IMPORT:
                    if import_t.ambiguity is Ambiguity.STAR_IMPORT:
                        expected_import_strategy[
                            name] = ImportStrategy.ADD_FROM
                    elif import_t.ambiguity is Ambiguity.RELATIVE_IMPORT:
                        expected_import_strategy[
                            name] = ImportStrategy.ADD_DOTTED
                    else:
                        raise TypeError(import_t.ambiguity)
                else:
                    expected_import_strategy[
                        name] = ImportStrategy.USE_EXISTING
        elif isinstance(import_t, NoImport):
            if import_t is NoImport.NOT_NEEDED:
                expected_import_strategy[name] = ImportStrategy.USE_EXISTING
            elif import_t is NoImport.LOCAL_CLS:
                if type_def is TypeDef.DOTTED_PATH:
                    if import_collision_policy is ImportCollisionPolicy.FAIL:
                        expect_annotated = False
                    expected_import_strategy[name] = (
                        ImportStrategy.ADD_DOTTED if
                        import_collision_policy is ImportCollisionPolicy.IMPORT
                        else ImportStrategy.USE_EXISTING)
                else:
                    expected_import_strategy[
                        name] = ImportStrategy.USE_EXISTING
                class_defs_needed.add(name.rsplit(".", 1)[-1])
            elif import_t is NoImport.MISSING:
                if type_def is TypeDef.DOTTED_PATH:
                    expected_import_strategy[name] = ImportStrategy.ADD_FROM
                elif type_src is TypeSrc.TYPING:
                    expected_import_strategy[name] = ImportStrategy.ADD_FROM
                elif type_src is TypeSrc.USER:
                    if unpathed_type_policy is UnpathedTypePolicy.FAIL:
                        expect_annotated = False
                    expected_import_strategy[
                        name] = ImportStrategy.USE_EXISTING
                else:
                    # builtin / non-type
                    expected_import_strategy[
                        name] = ImportStrategy.USE_EXISTING
            else:
                raise TypeError(import_t)
        else:
            raise TypeError(import_t)

    note(f"expect_annotated: {expect_annotated}")
    note(f"expected_import_strategy: {expected_import_strategy}")

    import_lines = "\n".join(i.import_statement for i in imports.values()
                             if not isinstance(i, NoImport))

    class_defs = "\n\n\n".join(f"""
class {cls_name}(object):
    pass""" for cls_name in class_defs_needed)

    funcdef = f'''
def identity(arg1):
    """
    Args:
        arg1 ({type_name}): blah

    Returns:
        {type_name}: blah
    """
    return arg1
'''

    content = "\n\n".join(var for var in (import_lines, class_defs, funcdef)
                          if var)
    note(content)

    NO_ADD_STRATEGIES = {
        ImportStrategy.USE_EXISTING,
        ImportStrategy.USE_EXISTING_DOTTED,
    }
    if expect_annotated:
        # add imports expected to have been added
        imports_to_add = []
        for name, strategy in expected_import_strategy.items():
            if strategy in NO_ADD_STRATEGIES:
                continue
            package, module = import_map[name]
            if strategy is ImportStrategy.ADD_FROM:
                imports_to_add.append(f"from {package} import {module}")
            elif strategy is ImportStrategy.ADD_DOTTED:
                imports_to_add.append(f"import {package}")

        atom = type_atom.parse(type_name)
        annotated_type_name = atom.to_annotation(expected_import_strategy)

        added_imports = "\n".join(imports_to_add)
    else:
        added_imports = ""

    if expect_annotated:
        funcdef = f'''
def identity(arg1):
    # type: ({annotated_type_name}) -> {annotated_type_name}
    """
    Args:
        arg1: blah

    Returns:
        blah
    """
    return arg1
'''

    if added_imports:
        if import_lines:
            import_lines = f"{import_lines}\n{added_imports}"
        else:
            import_lines = added_imports

    expected = "\n\n".join(var for var in (import_lines, class_defs, funcdef)
                           if var)
    note(expected)

    with tempfile.NamedTemporaryFile(suffix=".py") as f:
        with open(f.name, "w") as fw:
            fw.write(content)

        test_settings = settings.copy(deep=True)
        test_settings.ALLOW_UNTYPED_ARGS = False
        test_settings.REQUIRE_RETURN_TYPE = False
        test_settings.IMPORT_COLLISION_POLICY = import_collision_policy
        test_settings.UNPATHED_TYPE_POLICY = unpathed_type_policy

        inject.clear_and_configure(configuration_factory(test_settings))

        annotate(
            f.name,
            in_process=True,
            interactive=False,
            write=True,
            silent=True,
        )

        with open(f.name, "r") as fr:
            annotated = fr.read()

    assert annotated == expected
Ejemplo n.º 15
0
def test_py3_syntax():
    content = '''
class OtherClass(object):
    raise ValueError("WTF python 2")


def one(arg2):
    """
    Args:
        arg2 (str): blah

    Returns:
        my.module.SomeClass[str]: blah
    """
    try:
        SomeClass([])
    except TypeError as e:
        pass
    return SomeClass(arg2)


def two(arg1):
    """
    Args:
        arg1 (Tuple[str, ...]): blah

    Returns:
        Tuple[my.module.SomeClass[str], ...]: blah
    """
    print("print function with kwarg", end='end')
    return tuple(
        one(arg) for arg in arg1
    )
'''

    expected = '''from my.module import SomeClass
from typing import Tuple


class OtherClass(object):
    raise ValueError("WTF python 2")


def one(arg2):
    # type: (str) -> SomeClass[str]
    """
    Args:
        arg2: blah

    Returns:
        blah
    """
    try:
        SomeClass([])
    except TypeError as e:
        pass
    return SomeClass(arg2)


def two(arg1):
    # type: (Tuple[str, ...]) -> Tuple[SomeClass[str], ...]
    """
    Args:
        arg1: blah

    Returns:
        blah
    """
    print("print function with kwarg", end='end')
    return tuple(
        one(arg) for arg in arg1
    )
'''

    with tempfile.NamedTemporaryFile(suffix=".py") as f:
        with open(f.name, "w") as fw:
            fw.write(content)

        test_settings = override_settings(
            PYTHON_VERSION="3.6",
            ALLOW_UNTYPED_ARGS=False,
            REQUIRE_RETURN_TYPE=False,
            IMPORT_COLLISION_POLICY=ImportCollisionPolicy.IMPORT,
            UNPATHED_TYPE_POLICY=UnpathedTypePolicy.FAIL,
        )
        inject.clear_and_configure(configuration_factory(test_settings))

        annotate(
            f.name, in_process=True, interactive=False, write=True, silent=True,
        )

        with open(f.name, "r") as fr:
            annotated = fr.read()

    assert annotated == expected
Ejemplo n.º 16
0
def test_arg_annotation_signature_validate(signature, arg_annotations):
    annotations = "\n".join(
        f"        {name} ({type_}): {description}"
        for name, (type_, description) in arg_annotations.items()
    )
    content = f'''
def no_op({signature}):
    """
    Args:
{annotations}
    """
    pass
'''

    def splatify(name, type_):
        if name.startswith("**"):
            return f"**{type_}"
        elif name.startswith("*"):
            return f"*{type_}"
        else:
            return type_

    # I guess this is an 'oracle' i.e. an alternate implementation (meh)
    stripped_annotations = "\n".join(
        f"        {name}: {description}"
        for name, (_, description) in arg_annotations.items()
    )
    str_types = ", ".join(
        splatify(name, type_) for name, (type_, _) in arg_annotations.items()
    )
    type_comment = f"# type: ({str_types}) -> None"

    # only builtin types in examples, no imports needed
    expected = f'''
def no_op({signature}):
    {type_comment}
    """
    Args:
{stripped_annotations}
    """
    pass
'''

    with tempfile.NamedTemporaryFile(suffix=".py") as f:
        with open(f.name, "w") as fw:
            fw.write(content)

        test_settings = override_settings(
            PYTHON_VERSION="3.8",  # keyword-only args
            ALLOW_UNTYPED_ARGS=True,
            REQUIRE_RETURN_TYPE=False,
            IMPORT_COLLISION_POLICY=ImportCollisionPolicy.IMPORT,
            UNPATHED_TYPE_POLICY=UnpathedTypePolicy.FAIL,
        )
        inject.clear_and_configure(configuration_factory(test_settings))

        annotate(
            f.name, in_process=True, interactive=False, write=True, silent=True,
        )

        with open(f.name, "r") as fr:
            annotated = fr.read()

    assert annotated == expected