Skip to content

Module isort.setuptools_commands

None

None

View Source
import glob

import os

import sys

from typing import Any, Dict, Iterator, List

from warnings import warn

import setuptools  # type: ignore

from . import api

from .settings import DEFAULT_CONFIG

class ISortCommand(setuptools.Command):  # type: ignore

    """The :class:`ISortCommand` class is used by setuptools to perform

    imports checks on registered modules.

    """

    description = "Run isort on modules registered in setuptools"

    user_options: List[Any] = []

    def initialize_options(self) -> None:

        default_settings = vars(DEFAULT_CONFIG).copy()

        for key, value in default_settings.items():

            setattr(self, key, value)

    def finalize_options(self) -> None:

        """Get options from config files."""

        self.arguments: Dict[str, Any] = {}  # skipcq: PYL-W0201

        self.arguments["settings_path"] = os.getcwd()

    def distribution_files(self) -> Iterator[str]:

        """Find distribution packages."""

        # This is verbatim from flake8

        if self.distribution.packages:  # pragma: no cover

            package_dirs = self.distribution.package_dir or {}

            for package in self.distribution.packages:

                pkg_dir = package

                if package in package_dirs:

                    pkg_dir = package_dirs[package]

                elif "" in package_dirs:  # pragma: no cover

                    pkg_dir = package_dirs[""] + os.path.sep + pkg_dir

                yield pkg_dir.replace(".", os.path.sep)

        if self.distribution.py_modules:

            for filename in self.distribution.py_modules:

                yield "%s.py" % filename

        # Don't miss the setup.py file itself

        yield "setup.py"

    def run(self) -> None:

        arguments = self.arguments

        wrong_sorted_files = False

        for path in self.distribution_files():

            for python_file in glob.iglob(os.path.join(path, "*.py")):

                try:

                    if not api.check_file(python_file, **arguments):

                        wrong_sorted_files = True  # pragma: no cover

                except OSError as error:  # pragma: no cover

                    warn(f"Unable to parse file {python_file} due to {error}")

        if wrong_sorted_files:

            sys.exit(1)  # pragma: no cover

Classes

ISortCommand

class ISortCommand(
    dist,
    **kw
)
View Source
class ISortCommand(setuptools.Command):  # type: ignore

    """The :class:`ISortCommand` class is used by setuptools to perform

    imports checks on registered modules.

    """

    description = "Run isort on modules registered in setuptools"

    user_options: List[Any] = []

    def initialize_options(self) -> None:

        default_settings = vars(DEFAULT_CONFIG).copy()

        for key, value in default_settings.items():

            setattr(self, key, value)

    def finalize_options(self) -> None:

        """Get options from config files."""

        self.arguments: Dict[str, Any] = {}  # skipcq: PYL-W0201

        self.arguments["settings_path"] = os.getcwd()

    def distribution_files(self) -> Iterator[str]:

        """Find distribution packages."""

        # This is verbatim from flake8

        if self.distribution.packages:  # pragma: no cover

            package_dirs = self.distribution.package_dir or {}

            for package in self.distribution.packages:

                pkg_dir = package

                if package in package_dirs:

                    pkg_dir = package_dirs[package]

                elif "" in package_dirs:  # pragma: no cover

                    pkg_dir = package_dirs[""] + os.path.sep + pkg_dir

                yield pkg_dir.replace(".", os.path.sep)

        if self.distribution.py_modules:

            for filename in self.distribution.py_modules:

                yield "%s.py" % filename

        # Don't miss the setup.py file itself

        yield "setup.py"

    def run(self) -> None:

        arguments = self.arguments

        wrong_sorted_files = False

        for path in self.distribution_files():

            for python_file in glob.iglob(os.path.join(path, "*.py")):

                try:

                    if not api.check_file(python_file, **arguments):

                        wrong_sorted_files = True  # pragma: no cover

                except OSError as error:  # pragma: no cover

                    warn(f"Unable to parse file {python_file} due to {error}")

        if wrong_sorted_files:

            sys.exit(1)  # pragma: no cover

Ancestors (in MRO)

  • setuptools.Command
  • distutils.cmd.Command

Class variables

command_consumes_arguments
description
sub_commands
user_options

Methods

announce

def announce(
    self,
    msg,
    level=10
)
View Source
    def announce(self, msg, level=logging.DEBUG):

        log.log(level, msg)

copy_file

def copy_file(
    self,
    infile,
    outfile,
    preserve_mode=1,
    preserve_times=1,
    link=None,
    level=1
)

Copy a file respecting verbose, dry-run and force flags. (The

former two default to whatever is in the Distribution object, and the latter defaults to false for commands that don't define it.)

View Source
    def copy_file(

        self, infile, outfile, preserve_mode=1, preserve_times=1, link=None, level=1

    ):

        """Copy a file respecting verbose, dry-run and force flags.  (The

        former two default to whatever is in the Distribution object, and

        the latter defaults to false for commands that don't define it.)"""

        return file_util.copy_file(

            infile,

            outfile,

            preserve_mode,

            preserve_times,

            not self.force,

            link,

            dry_run=self.dry_run,

        )

copy_tree

def copy_tree(
    self,
    infile,
    outfile,
    preserve_mode=1,
    preserve_times=1,
    preserve_symlinks=0,
    level=1
)

Copy an entire directory tree respecting verbose, dry-run,

and force flags.

View Source
    def copy_tree(

        self,

        infile,

        outfile,

        preserve_mode=1,

        preserve_times=1,

        preserve_symlinks=0,

        level=1,

    ):

        """Copy an entire directory tree respecting verbose, dry-run,

        and force flags.

        """

        return dir_util.copy_tree(

            infile,

            outfile,

            preserve_mode,

            preserve_times,

            preserve_symlinks,

            not self.force,

            dry_run=self.dry_run,

        )

debug_print

def debug_print(
    self,
    msg
)

Print 'msg' to stdout if the global DEBUG (taken from the

DISTUTILS_DEBUG environment variable) flag is true.

View Source
    def debug_print(self, msg):

        """Print 'msg' to stdout if the global DEBUG (taken from the

        DISTUTILS_DEBUG environment variable) flag is true.

        """

        from distutils.debug import DEBUG

        if DEBUG:

            print(msg)

            sys.stdout.flush()

distribution_files

def distribution_files(
    self
) -> Iterator[str]

Find distribution packages.

View Source
    def distribution_files(self) -> Iterator[str]:

        """Find distribution packages."""

        # This is verbatim from flake8

        if self.distribution.packages:  # pragma: no cover

            package_dirs = self.distribution.package_dir or {}

            for package in self.distribution.packages:

                pkg_dir = package

                if package in package_dirs:

                    pkg_dir = package_dirs[package]

                elif "" in package_dirs:  # pragma: no cover

                    pkg_dir = package_dirs[""] + os.path.sep + pkg_dir

                yield pkg_dir.replace(".", os.path.sep)

        if self.distribution.py_modules:

            for filename in self.distribution.py_modules:

                yield "%s.py" % filename

        # Don't miss the setup.py file itself

        yield "setup.py"

dump_options

def dump_options(
    self,
    header=None,
    indent=''
)
View Source
    def dump_options(self, header=None, indent=""):

        from distutils.fancy_getopt import longopt_xlate

        if header is None:

            header = "command options for '%s':" % self.get_command_name()

        self.announce(indent + header, level=logging.INFO)

        indent = indent + "  "

        for (option, _, _) in self.user_options:

            option = option.translate(longopt_xlate)

            if option[-1] == "=":

                option = option[:-1]

            value = getattr(self, option)

            self.announce(indent + "{} = {}".format(option, value), level=logging.INFO)

ensure_dirname

def ensure_dirname(
    self,
    option
)
View Source
    def ensure_dirname(self, option):

        self._ensure_tested_string(

            option,

            os.path.isdir,

            "directory name",

            "'%s' does not exist or is not a directory",

        )

ensure_filename

def ensure_filename(
    self,
    option
)

Ensure that 'option' is the name of an existing file.

View Source
    def ensure_filename(self, option):

        """Ensure that 'option' is the name of an existing file."""

        self._ensure_tested_string(

            option, os.path.isfile, "filename", "'%s' does not exist or is not a file"

        )

ensure_finalized

def ensure_finalized(
    self
)
View Source
    def ensure_finalized(self):

        if not self.finalized:

            self.finalize_options()

        self.finalized = 1

ensure_string

def ensure_string(
    self,
    option,
    default=None
)

Ensure that 'option' is a string; if not defined, set it to

'default'.

View Source
    def ensure_string(self, option, default=None):

        """Ensure that 'option' is a string; if not defined, set it to

        'default'.

        """

        self._ensure_stringlike(option, "string", default)

ensure_string_list

def ensure_string_list(
    self,
    option
)

Ensure that 'option' is a list of strings. If 'option' is

currently a string, we split it either on /,\s*/ or /\s+/, so "foo bar baz", "foo,bar,baz", and "foo, bar baz" all become ["foo", "bar", "baz"].

.. TODO: This method seems to be similar to the one in distutils.cmd Probably it is just here for backward compatibility with old Python versions?

View Source
    def ensure_string_list(self, option):

        r"""Ensure that 'option' is a list of strings.  If 'option' is

        currently a string, we split it either on /,\s*/ or /\s+/, so

        "foo bar baz", "foo,bar,baz", and "foo,   bar baz" all become

        ["foo", "bar", "baz"].

        ..

           TODO: This method seems to be similar to the one in ``distutils.cmd``

           Probably it is just here for backward compatibility with old Python versions?

        :meta private:

        """

        val = getattr(self, option)

        if val is None:

            return

        elif isinstance(val, str):

            setattr(self, option, re.split(r',\s*|\s+', val))

        else:

            if isinstance(val, list):

                ok = all(isinstance(v, str) for v in val)

            else:

                ok = False

            if not ok:

                raise DistutilsOptionError(

                    "'%s' must be a list of strings (got %r)" % (option, val)

                )

execute

def execute(
    self,
    func,
    args,
    msg=None,
    level=1
)
View Source
    def execute(self, func, args, msg=None, level=1):

        util.execute(func, args, msg, dry_run=self.dry_run)

finalize_options

def finalize_options(
    self
) -> None

Get options from config files.

View Source
    def finalize_options(self) -> None:

        """Get options from config files."""

        self.arguments: Dict[str, Any] = {}  # skipcq: PYL-W0201

        self.arguments["settings_path"] = os.getcwd()

get_command_name

def get_command_name(
    self
)
View Source
    def get_command_name(self):

        if hasattr(self, 'command_name'):

            return self.command_name

        else:

            return self.__class__.__name__

get_finalized_command

def get_finalized_command(
    self,
    command,
    create=1
)

Wrapper around Distribution's 'get_command_obj()' method: find

(create if necessary and 'create' is true) the command object for 'command', call its 'ensure_finalized()' method, and return the finalized command object.

View Source
    def get_finalized_command(self, command, create=1):

        """Wrapper around Distribution's 'get_command_obj()' method: find

        (create if necessary and 'create' is true) the command object for

        'command', call its 'ensure_finalized()' method, and return the

        finalized command object.

        """

        cmd_obj = self.distribution.get_command_obj(command, create)

        cmd_obj.ensure_finalized()

        return cmd_obj

get_sub_commands

def get_sub_commands(
    self
)

Determine the sub-commands that are relevant in the current

distribution (ie., that need to be run). This is based on the 'sub_commands' class attribute: each tuple in that list may include a method that we call to determine if the subcommand needs to be run for the current distribution. Return a list of command names.

View Source
    def get_sub_commands(self):

        """Determine the sub-commands that are relevant in the current

        distribution (ie., that need to be run).  This is based on the

        'sub_commands' class attribute: each tuple in that list may include

        a method that we call to determine if the subcommand needs to be

        run for the current distribution.  Return a list of command names.

        """

        commands = []

        for (cmd_name, method) in self.sub_commands:

            if method is None or method(self):

                commands.append(cmd_name)

        return commands

initialize_options

def initialize_options(
    self
) -> None

Set default values for all the options that this command

supports. Note that these defaults may be overridden by other commands, by the setup script, by config files, or by the command-line. Thus, this is not the place to code dependencies between options; generally, 'initialize_options()' implementations are just a bunch of "self.foo = None" assignments.

This method must be implemented by all command classes.

View Source
    def initialize_options(self) -> None:

        default_settings = vars(DEFAULT_CONFIG).copy()

        for key, value in default_settings.items():

            setattr(self, key, value)

make_archive

def make_archive(
    self,
    base_name,
    format,
    root_dir=None,
    base_dir=None,
    owner=None,
    group=None
)
View Source
    def make_archive(

        self, base_name, format, root_dir=None, base_dir=None, owner=None, group=None

    ):

        return archive_util.make_archive(

            base_name,

            format,

            root_dir,

            base_dir,

            dry_run=self.dry_run,

            owner=owner,

            group=group,

        )

make_file

def make_file(
    self,
    infiles,
    outfile,
    func,
    args,
    exec_msg=None,
    skip_msg=None,
    level=1
)

Special case of 'execute()' for operations that process one or

more input files and generate one output file. Works just like 'execute()', except the operation is skipped and a different message printed if 'outfile' already exists and is newer than all files listed in 'infiles'. If the command defined 'self.force', and it is true, then the command is unconditionally run -- does no timestamp checks.

View Source
    def make_file(

        self, infiles, outfile, func, args, exec_msg=None, skip_msg=None, level=1

    ):

        """Special case of 'execute()' for operations that process one or

        more input files and generate one output file.  Works just like

        'execute()', except the operation is skipped and a different

        message printed if 'outfile' already exists and is newer than all

        files listed in 'infiles'.  If the command defined 'self.force',

        and it is true, then the command is unconditionally run -- does no

        timestamp checks.

        """

        if skip_msg is None:

            skip_msg = "skipping %s (inputs unchanged)" % outfile

        # Allow 'infiles' to be a single string

        if isinstance(infiles, str):

            infiles = (infiles,)

        elif not isinstance(infiles, (list, tuple)):

            raise TypeError("'infiles' must be a string, or a list or tuple of strings")

        if exec_msg is None:

            exec_msg = "generating {} from {}".format(outfile, ', '.join(infiles))

        # If 'outfile' must be regenerated (either because it doesn't

        # exist, is out-of-date, or the 'force' flag is true) then

        # perform the action that presumably regenerates it

        if self.force or dep_util.newer_group(infiles, outfile):

            self.execute(func, args, exec_msg, level)

        # Otherwise, print the "skip" message

        else:

            log.debug(skip_msg)

mkpath

def mkpath(
    self,
    name,
    mode=511
)
View Source
    def mkpath(self, name, mode=0o777):

        dir_util.mkpath(name, mode, dry_run=self.dry_run)

move_file

def move_file(
    self,
    src,
    dst,
    level=1
)

Move a file respecting dry-run flag.

View Source
    def move_file(self, src, dst, level=1):

        """Move a file respecting dry-run flag."""

        return file_util.move_file(src, dst, dry_run=self.dry_run)

reinitialize_command

def reinitialize_command(
    self,
    command,
    reinit_subcommands=0,
    **kw
)
View Source
    def reinitialize_command(self, command, reinit_subcommands=0, **kw):

        cmd = _Command.reinitialize_command(self, command, reinit_subcommands)

        vars(cmd).update(kw)

        return cmd

run

def run(
    self
) -> None

A command's raison d'etre: carry out the action it exists to

perform, controlled by the options initialized in 'initialize_options()', customized by other commands, the setup script, the command-line, and config files, and finalized in 'finalize_options()'. All terminal output and filesystem interaction should be done by 'run()'.

This method must be implemented by all command classes.

View Source
    def run(self) -> None:

        arguments = self.arguments

        wrong_sorted_files = False

        for path in self.distribution_files():

            for python_file in glob.iglob(os.path.join(path, "*.py")):

                try:

                    if not api.check_file(python_file, **arguments):

                        wrong_sorted_files = True  # pragma: no cover

                except OSError as error:  # pragma: no cover

                    warn(f"Unable to parse file {python_file} due to {error}")

        if wrong_sorted_files:

            sys.exit(1)  # pragma: no cover

run_command

def run_command(
    self,
    command
)

Run some other command: uses the 'run_command()' method of

Distribution, which creates and finalizes the command object if necessary and then invokes its 'run()' method.

View Source
    def run_command(self, command):

        """Run some other command: uses the 'run_command()' method of

        Distribution, which creates and finalizes the command object if

        necessary and then invokes its 'run()' method.

        """

        self.distribution.run_command(command)

set_undefined_options

def set_undefined_options(
    self,
    src_cmd,
    *option_pairs
)

Set the values of any "undefined" options from corresponding

option values in some other command object. "Undefined" here means "is None", which is the convention used to indicate that an option has not been changed between 'initialize_options()' and 'finalize_options()'. Usually called from 'finalize_options()' for options that depend on some other command rather than another option of the same command. 'src_cmd' is the other command from which option values will be taken (a command object will be created for it if necessary); the remaining arguments are '(src_option,dst_option)' tuples which mean "take the value of 'src_option' in the 'src_cmd' command object, and copy it to 'dst_option' in the current command object".

View Source
    def set_undefined_options(self, src_cmd, *option_pairs):

        """Set the values of any "undefined" options from corresponding

        option values in some other command object.  "Undefined" here means

        "is None", which is the convention used to indicate that an option

        has not been changed between 'initialize_options()' and

        'finalize_options()'.  Usually called from 'finalize_options()' for

        options that depend on some other command rather than another

        option of the same command.  'src_cmd' is the other command from

        which option values will be taken (a command object will be created

        for it if necessary); the remaining arguments are

        '(src_option,dst_option)' tuples which mean "take the value of

        'src_option' in the 'src_cmd' command object, and copy it to

        'dst_option' in the current command object".

        """

        # Option_pairs: list of (src_option, dst_option) tuples

        src_cmd_obj = self.distribution.get_command_obj(src_cmd)

        src_cmd_obj.ensure_finalized()

        for (src_option, dst_option) in option_pairs:

            if getattr(self, dst_option) is None:

                setattr(self, dst_option, getattr(src_cmd_obj, src_option))

spawn

def spawn(
    self,
    cmd,
    search_path=1,
    level=1
)

Spawn an external command respecting dry-run flag.

View Source
    def spawn(self, cmd, search_path=1, level=1):

        """Spawn an external command respecting dry-run flag."""

        from distutils.spawn import spawn

        spawn(cmd, search_path, dry_run=self.dry_run)

warn

def warn(
    self,
    msg
)
View Source
    def warn(self, msg):

        log.warning("warning: %s: %s\n", self.get_command_name(), msg)