Skip to content

Autoimport

Actions Status Actions Status Coverage Status

Autoimport missing python libraries.

Throughout the development of a python program you continuously need to manage the python import statements either because you need one new object or because you no longer need it. This means that you need to stop writing whatever you were writing, go to the top of the file, create or remove the import statement and then resume coding.

This workflow break is annoying and almost always unnecessary. autoimport solves this problem if you execute it whenever you have an import error, for example by configuring your editor to run it when saving the file.

Installing

pip install autoimport

Usage

Imagine we've got the following source code:

import requests


def hello(names: Tuple[str]) -> None:
    for name in names:
        print(f"Hi {name}!")

os.getcwd()

It has the following import errors:

  • requests is imported but unused.
  • os and Tuple are needed but not imported.

After running autoimport the resulting source code will be:

import os
from typing import Tuple


def hello(names: Tuple[str]) -> None:
    for name in names:
        print(f"Hi {name}!")

os.getcwd()

autoimport can be used both as command line tool and as a library.

It can be parsed either an array of files and/or a directory.

A parsed directory will have autoimport be executed on all recursively found python files in said directory.

  • As a command line tool:

    $: autoimport file.py
    $: autoimport dir/
    
  • As a library:

    from autoimport import fix_files
    
    fix_files(['file.py', 'dir/'])
    

autoimport will add all dependencies at the top of the file, we suggest using isort and black afterwards to clean the file.

Features

Add missing imports

autoimport matches each of the missing import statements against the following objects:

  • The modules referenced in PYTHONPATH.
  • The typing library objects.
  • The common statements.

    Where some of the common statements are:

    * `BeautifulSoup` -> `from bs4 import BeautifulSoup`
    * `call` -> `from unittest.mock import call`
    * `CaptureFixture` -> `from _pytest.capture import CaptureFixture`
    * `CliRunner` -> `from click.testing import CliRunner`
    * `copyfile` -> `from shutil import copyfile`
    * `dedent` -> `from textwrap import dedent`
    * `LocalPath` -> `from py._path.local import LocalPath`
    * `LogCaptureFixture` -> `from _pytest.logging import LogCaptureFixture`
    * `Mock` -> `from unittest.mock import Mock`
    * `patch` -> `from unittest.mock import patch`
    * `StringIO` -> `from io import StringIO`
    * `TempdirFactory` -> `from _pytest.tmpdir import TempdirFactory`
    * `YAMLError` -> `from yaml import YAMLError`
    
  • The objects of the Python project you are developing, assuming you are executing the program in a directory of the project and you can import it.

It may not work if you use pip install -e .

Given that you execute autoimport inside a virtualenv where the package is installed with pip install -e ., when there is an import error in a file that is indexed in the package, autoimport won't be able to read the package contents as the import statement will fail. So it's a good idea to run autoimport from a virtualenv that has a stable version of the package we are developing.

Remove unused import statements

If an object is imported but unused, autoimport will remove the import statement.

Moving the imports to the top

There are going to be import cases that may not work, if you find one, please open an issue.

While we fix it you can write the import statement wherever you are in the file and the next time you run autoimport it will get moved to the top.

If you don't want a specific line to go to the top, add the # noqa: autoimport or # fmt: skip at the end. For example:

a = 1

from os import getcwd # noqa: autoimport

getcwd()

Configuration

autoimport uses the maison library to discover and read your project-local pyproject.toml file (if it exists). This file can be used to configure autoimport's behavior: the tool.autoimport.common_statements table in that file can be used to define a custom set of "common statements", overriding the default set of common statements mentioned above. For example:

# pyproject.toml

[tool.autoimport.common_statements]
"np" = "import numpy as np"
"FooBar" = "from baz_qux import FooBar"

It is also possible to specify a different path for this config file:

$: autoimport --config-file ~/.autoimport.toml file.py

If using the --config-file flag to specify a file that is named something other than pyproject.toml, the autoimport settings should not be nested under toplevel tool.autoimport keys.

# .autoimport.toml

[common_statements]
"np" = "import numpy as np"
"FooBar" = "from baz_qux import FooBar"

Furthermore, autoimport supports the use of a global configuration file, located at autoimport/config.toml under the xdg config home folder. For most users, this means that the file ~/.config/autoimport/config.toml, if it exists, will be loaded and used as configuration for autoimport. As before, do not write tool.autoimport at the toplevel; just specify your global autoimport settings directly.

The settings defined in the local pyproject.toml file (if found) or in the file specified by the --config-file flag (if given) will override the settings defined in the global autoimport/config.toml file.

References

As most open sourced programs, autoimport is standing on the shoulders of giants, namely:

autoflake
Inspiration of autoimport. Also used their code to interact with pyflakes.
Click
Used to create the command line interface.
Pytest
Testing framework, enhanced by the awesome pytest-cases library that made the parametrization of the tests a lovely experience.
Mypy
Python static type checker.
Flakeheaven
Python linter with lots of checks.
Black
Python formatter to keep a nice style without effort.
Autoimport
Python formatter to automatically fix wrong import statements.
isort
Python formatter to order the import statements.
PDM
Command line tool to manage the dependencies.
Mkdocs
To build this documentation site, with the Material theme.
Safety
To check the installed dependencies for known security vulnerabilities.
Bandit
To finds common security issues in Python code.
Yamlfix
YAML fixer.

Alternatives

If you like the idea but not how we solved the problem, take a look at this other solutions:

Contributing

For guidance on setting up a development environment, and how to make a contribution to autoimport, see Contributing to autoimport.


Last update: 2022-05-02