Code Monkey home page Code Monkey logo

importfixer's Introduction

importfixer

This program adds and removes imports based on whats in use. It does not autodetect available libraries, but relies on a configuration definition.

The primary interface is through the importfixer command line tool, with help message:

usage: importfixer [-h] [-c CONFIG] [-d] [-o] [file] [output]

positional arguments:
  file                  Input file. Uses stdin if not provided
  output                Output file. Default prints to stdout

optional arguments:
  -h, --help            show this help message and exit
  -c CONFIG, --config CONFIG
                        Input config
  -d, --diff            Show difference
  -o, --overwrite       Overwrite input. Not compatible with <output>.

The config file defines the variables names that should always be understood as things to be imported. The configuration supports normal imports, aliases, and from imports, either with selections or in their entirety. That is an example configuration file showing the four types of definitions is:

os           # Simple import
numpy as np  # Alias
from scipy import optimize, linalg   # Import specific names from library/module
from typing import *   # Import any name from library module

Note that the configuration file is a simple text file with comments defining all the possible imports.

Given this configuration, the following input file:

import sys
import glob
from typing import Dict

def myfunc(arg: Dict) -> List:
  return list(arg.keys())

print(sys.argv)
print(os.getcwd())
print(linalg.cholesky(np.eye(6)))

would be rewritten as:

import sys
from typing import Dict, List
import os
from scipy import linalg
import numpy as np

def myfunc(arg: Dict) -> List:
  return list(arg.keys())

print(sys.argv)
print(os.getcwd())
print(linalg.cholesky(np.eye(6)))

Note that the ordering simply appends to the list of imports, in a way that will minimize differences, but is usually not ideal. These can be manually reordered before committing, or used in conjunction with isort to enforce a standard of import order and style.

API

In addition to the command line tool, the individual python functions can be used individually or as a whole:

def fiximports(content, config=None, filename=None):
    """
    Add and remove imports in a python file

    Args:
        content (str): The python code to analyze
        config (str or [str], optional): The configuration for this run. Can be a file
            with configuration data, or a list of entries. See project docs for details
            on format. Default is from ~/.importfixer.txt if available, and
            DEFAULT_CONFIG if not.
        filename (str, optional): Filename of content. Used for error messages

    Returns:
        str: The updated content with imports added and removed
    """

def add_import(content, name, filename=None):
    """
    Update contents with new import added

    Args:
        content (str): The python code
        name (str): The name of the imported module/object to be added
        filename (str, optional): Filename of content

    Returns:
        str - Updated content
    """

def remove_import(content, name, filename=None):
    """
    Update content with extraneous imports removed

    Args:
        content (str): The python code
        name (str): The name of the imported module/object to remove
        filename (str, optional): Filename of content

    Returns:
        str: Updated content
    """

Developing

In order to set up a development environment, first create a virtual environment (python -m venv env to create one in directory ./env), then activate it (source ./env/bin/activate), and then run ./setup-dev.sh. This will install the libraries required for development, set up the pre-commit hooks to enforce black and isort, and install the library as editable.

Once installed you should add tests defining the expected behavior, and then implement your update. Run pytest to run the automated tests.

Note that this project uses the black style enforcer, and isort to maintain imports.

Design Decisions

This is primarily intended to serve as a tool to run inside a text editor, since the fixes are relatively trivial but annoying when working. There are two particular choices to justify:

  1. Writing a new tool instead of using autoimport. This tool relies on automatically detecting available libraries rather than explicitly whitelisting them, and doesn't provide a way to generically import all names from a library, which is one of my main needs. The latter could be addressed in a pull request, but the former probably couldn't be. I'd rather whitelist the few libraries I use all the time and not be suprised by (e.g.) using a variable named "time" incorrectly and getting the error masked in the linter by the auto-importing tool.

  2. Using a configuration file in the home directory rather than pyproject.toml. This is because the tool is really a personal preference rather than something you specify on a per-project basis. Therefore a single config file in your home directory makes the most sense. Given that the entries are a list of strings, it made more sense to eliminate boilerplate and use a simple list.

importfixer's People

Contributors

btyoung avatar

Watchers

 avatar

importfixer's Issues

Removing import removes comment

Inputting the following code:

"""
docstring
"""
import numpy as np

# x = np.array([1, 2, 3])

will result in the output

"""
docstring
"""

When it should result in

"""
docstring
"""

# x = np.array([1, 2, 3])

Note that this is with or without text after the commented line. If the docstring is not present, the first input is not removed.

Command line option to fix specific import

The command line tool should accept an argument to accept a specific import. This would be used in an editor to highlight a word and add it via a hotkey. It should first look in the list, and then see if a library name is importable.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.