mirror of
https://github.com/PyCQA/flake8.git
synced 2026-04-11 07:14:18 +00:00
parent
6df26ffd57
commit
4e58068657
15 changed files with 391 additions and 133 deletions
|
|
@ -6,6 +6,7 @@ In 3.0 we no longer have an "engine" module but we maintain the API from it.
|
||||||
import logging
|
import logging
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
|
import flake8
|
||||||
from flake8.formatting import base as formatter
|
from flake8.formatting import base as formatter
|
||||||
from flake8.main import application as app
|
from flake8.main import application as app
|
||||||
|
|
||||||
|
|
@ -26,6 +27,10 @@ def get_style_guide(**kwargs):
|
||||||
:class:`StyleGuide`
|
:class:`StyleGuide`
|
||||||
"""
|
"""
|
||||||
application = app.Application()
|
application = app.Application()
|
||||||
|
application.parse_preliminary_options_and_args([])
|
||||||
|
flake8.configure_logging(
|
||||||
|
application.prelim_opts.verbose, application.prelim_opts.output_file)
|
||||||
|
application.make_config_finder()
|
||||||
application.find_plugins()
|
application.find_plugins()
|
||||||
application.register_plugin_options()
|
application.register_plugin_options()
|
||||||
application.parse_configuration_and_cli([])
|
application.parse_configuration_and_cli([])
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import sys
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import flake8
|
import flake8
|
||||||
|
|
@ -12,7 +11,7 @@ from flake8 import exceptions
|
||||||
from flake8 import style_guide
|
from flake8 import style_guide
|
||||||
from flake8 import utils
|
from flake8 import utils
|
||||||
from flake8.main import options
|
from flake8.main import options
|
||||||
from flake8.options import aggregator
|
from flake8.options import aggregator, config
|
||||||
from flake8.options import manager
|
from flake8.options import manager
|
||||||
from flake8.plugins import manager as plugin_manager
|
from flake8.plugins import manager as plugin_manager
|
||||||
|
|
||||||
|
|
@ -45,34 +44,16 @@ class Application(object):
|
||||||
prog='flake8', version=flake8.__version__
|
prog='flake8', version=flake8.__version__
|
||||||
)
|
)
|
||||||
options.register_default_options(self.option_manager)
|
options.register_default_options(self.option_manager)
|
||||||
|
#: The preliminary options parsed from CLI before plugins are loaded,
|
||||||
|
#: into a :class:`optparse.Values` instance
|
||||||
|
self.prelim_opts = None
|
||||||
|
#: The preliminary arguments parsed from CLI before plugins are loaded
|
||||||
|
self.prelim_args = None
|
||||||
|
#: The instance of :class:`flake8.options.config.ConfigFileFinder`
|
||||||
|
self.config_finder = None
|
||||||
|
|
||||||
# We haven't found or registered our plugins yet, so let's defer
|
#: The :class:`flake8.options.config.LocalPlugins` found in config
|
||||||
# printing the version until we aggregate options from config files
|
self.local_plugins = None
|
||||||
# and the command-line. First, let's clone our arguments on the CLI,
|
|
||||||
# then we'll attempt to remove ``--version`` so that we can avoid
|
|
||||||
# triggering the "version" action in optparse. If it's not there, we
|
|
||||||
# do not need to worry and we can continue. If it is, we successfully
|
|
||||||
# defer printing the version until just a little bit later.
|
|
||||||
# Similarly we have to defer printing the help text until later.
|
|
||||||
args = sys.argv[:]
|
|
||||||
try:
|
|
||||||
args.remove('--version')
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
args.remove('--help')
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
args.remove('-h')
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
preliminary_opts, _ = self.option_manager.parse_known_args(args)
|
|
||||||
# Set the verbosity of the program
|
|
||||||
flake8.configure_logging(preliminary_opts.verbose,
|
|
||||||
preliminary_opts.output_file)
|
|
||||||
|
|
||||||
#: The instance of :class:`flake8.plugins.manager.Checkers`
|
#: The instance of :class:`flake8.plugins.manager.Checkers`
|
||||||
self.check_plugins = None
|
self.check_plugins = None
|
||||||
#: The instance of :class:`flake8.plugins.manager.Listeners`
|
#: The instance of :class:`flake8.plugins.manager.Listeners`
|
||||||
|
|
@ -111,6 +92,48 @@ class Application(object):
|
||||||
#: The parsed diff information
|
#: The parsed diff information
|
||||||
self.parsed_diff = {}
|
self.parsed_diff = {}
|
||||||
|
|
||||||
|
def parse_preliminary_options_and_args(self, argv):
|
||||||
|
"""Get preliminary options and args from CLI, pre-plugin-loading.
|
||||||
|
|
||||||
|
We need to know the values of a few standard options and args now, so
|
||||||
|
that we can find config files and configure logging.
|
||||||
|
|
||||||
|
Since plugins aren't loaded yet, there may be some as-yet-unknown
|
||||||
|
options; we ignore those for now, they'll be parsed later when we do
|
||||||
|
real option parsing.
|
||||||
|
|
||||||
|
Sets self.prelim_opts and self.prelim_args.
|
||||||
|
|
||||||
|
:param list argv:
|
||||||
|
Command-line arguments passed in directly.
|
||||||
|
"""
|
||||||
|
# We haven't found or registered our plugins yet, so let's defer
|
||||||
|
# printing the version until we aggregate options from config files
|
||||||
|
# and the command-line. First, let's clone our arguments on the CLI,
|
||||||
|
# then we'll attempt to remove ``--version`` so that we can avoid
|
||||||
|
# triggering the "version" action in optparse. If it's not there, we
|
||||||
|
# do not need to worry and we can continue. If it is, we successfully
|
||||||
|
# defer printing the version until just a little bit later.
|
||||||
|
# Similarly we have to defer printing the help text until later.
|
||||||
|
args = argv[:]
|
||||||
|
try:
|
||||||
|
args.remove('--version')
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
args.remove('--help')
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
args.remove('-h')
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
opts, args = self.option_manager.parse_known_args(args)
|
||||||
|
# parse_known_args includes unknown options as args; get rid of them
|
||||||
|
args = [a for a in args if not a.startswith('-')]
|
||||||
|
self.prelim_opts, self.prelim_args = opts, args
|
||||||
|
|
||||||
def exit(self):
|
def exit(self):
|
||||||
# type: () -> NoneType
|
# type: () -> NoneType
|
||||||
"""Handle finalization and exiting the program.
|
"""Handle finalization and exiting the program.
|
||||||
|
|
@ -125,6 +148,17 @@ class Application(object):
|
||||||
raise SystemExit((self.result_count > 0) or
|
raise SystemExit((self.result_count > 0) or
|
||||||
self.catastrophic_failure)
|
self.catastrophic_failure)
|
||||||
|
|
||||||
|
def make_config_finder(self):
|
||||||
|
"""Make our ConfigFileFinder based on preliminary opts and args."""
|
||||||
|
if self.config_finder is None:
|
||||||
|
extra_config_files = utils.normalize_paths(
|
||||||
|
self.prelim_opts.append_config)
|
||||||
|
self.config_finder = config.ConfigFileFinder(
|
||||||
|
self.option_manager.program_name,
|
||||||
|
self.prelim_args,
|
||||||
|
extra_config_files,
|
||||||
|
)
|
||||||
|
|
||||||
def find_plugins(self):
|
def find_plugins(self):
|
||||||
# type: () -> NoneType
|
# type: () -> NoneType
|
||||||
"""Find and load the plugins for this application.
|
"""Find and load the plugins for this application.
|
||||||
|
|
@ -135,14 +169,23 @@ class Application(object):
|
||||||
of finding plugins (via :mod:`pkg_resources`) we want this to be
|
of finding plugins (via :mod:`pkg_resources`) we want this to be
|
||||||
idempotent and so only update those attributes if they are ``None``.
|
idempotent and so only update those attributes if they are ``None``.
|
||||||
"""
|
"""
|
||||||
|
if self.local_plugins is None:
|
||||||
|
self.local_plugins = config.get_local_plugins(
|
||||||
|
self.config_finder,
|
||||||
|
self.prelim_opts.config,
|
||||||
|
self.prelim_opts.isolated,
|
||||||
|
)
|
||||||
|
|
||||||
if self.check_plugins is None:
|
if self.check_plugins is None:
|
||||||
self.check_plugins = plugin_manager.Checkers()
|
self.check_plugins = plugin_manager.Checkers(
|
||||||
|
self.local_plugins.extension)
|
||||||
|
|
||||||
if self.listening_plugins is None:
|
if self.listening_plugins is None:
|
||||||
self.listening_plugins = plugin_manager.Listeners()
|
self.listening_plugins = plugin_manager.Listeners()
|
||||||
|
|
||||||
if self.formatting_plugins is None:
|
if self.formatting_plugins is None:
|
||||||
self.formatting_plugins = plugin_manager.ReportFormatters()
|
self.formatting_plugins = plugin_manager.ReportFormatters(
|
||||||
|
self.local_plugins.report)
|
||||||
|
|
||||||
self.check_plugins.load_plugins()
|
self.check_plugins.load_plugins()
|
||||||
self.listening_plugins.load_plugins()
|
self.listening_plugins.load_plugins()
|
||||||
|
|
@ -165,7 +208,7 @@ class Application(object):
|
||||||
"""
|
"""
|
||||||
if self.options is None and self.args is None:
|
if self.options is None and self.args is None:
|
||||||
self.options, self.args = aggregator.aggregate_options(
|
self.options, self.args = aggregator.aggregate_options(
|
||||||
self.option_manager, argv
|
self.option_manager, self.config_finder, argv
|
||||||
)
|
)
|
||||||
|
|
||||||
self.running_against_diff = self.options.diff
|
self.running_against_diff = self.options.diff
|
||||||
|
|
@ -314,6 +357,10 @@ class Application(object):
|
||||||
"""
|
"""
|
||||||
# NOTE(sigmavirus24): When updating this, make sure you also update
|
# NOTE(sigmavirus24): When updating this, make sure you also update
|
||||||
# our legacy API calls to these same methods.
|
# our legacy API calls to these same methods.
|
||||||
|
self.parse_preliminary_options_and_args(argv)
|
||||||
|
flake8.configure_logging(
|
||||||
|
self.prelim_opts.verbose, self.prelim_opts.output_file)
|
||||||
|
self.make_config_finder()
|
||||||
self.find_plugins()
|
self.find_plugins()
|
||||||
self.register_plugin_options()
|
self.register_plugin_options()
|
||||||
self.parse_configuration_and_cli(argv)
|
self.parse_configuration_and_cli(argv)
|
||||||
|
|
|
||||||
|
|
@ -5,17 +5,18 @@ applies the user-specified command-line configuration on top of it.
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from flake8 import utils
|
|
||||||
from flake8.options import config
|
from flake8.options import config
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def aggregate_options(manager, arglist=None, values=None):
|
def aggregate_options(manager, config_finder, arglist=None, values=None):
|
||||||
"""Aggregate and merge CLI and config file options.
|
"""Aggregate and merge CLI and config file options.
|
||||||
|
|
||||||
:param flake8.option.manager.OptionManager manager:
|
:param flake8.options.manager.OptionManager manager:
|
||||||
The instance of the OptionManager that we're presently using.
|
The instance of the OptionManager that we're presently using.
|
||||||
|
:param flake8.options.config.ConfigFileFinder config_finder:
|
||||||
|
The config file finder to use.
|
||||||
:param list arglist:
|
:param list arglist:
|
||||||
The list of arguments to pass to ``manager.parse_args``. In most cases
|
The list of arguments to pass to ``manager.parse_args``. In most cases
|
||||||
this will be None so ``parse_args`` uses ``sys.argv``. This is mostly
|
this will be None so ``parse_args`` uses ``sys.argv``. This is mostly
|
||||||
|
|
@ -32,14 +33,12 @@ def aggregate_options(manager, arglist=None, values=None):
|
||||||
default_values, _ = manager.parse_args([], values=values)
|
default_values, _ = manager.parse_args([], values=values)
|
||||||
# Get original CLI values so we can find additional config file paths and
|
# Get original CLI values so we can find additional config file paths and
|
||||||
# see if --config was specified.
|
# see if --config was specified.
|
||||||
original_values, original_args = manager.parse_args(arglist)
|
original_values, _ = manager.parse_args(arglist)
|
||||||
extra_config_files = utils.normalize_paths(original_values.append_config)
|
|
||||||
|
|
||||||
# Make our new configuration file mergerator
|
# Make our new configuration file mergerator
|
||||||
config_parser = config.MergedConfigParser(
|
config_parser = config.MergedConfigParser(
|
||||||
option_manager=manager,
|
option_manager=manager,
|
||||||
extra_config_files=extra_config_files,
|
config_finder=config_finder,
|
||||||
args=original_args,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Get the parsed config
|
# Get the parsed config
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
"""Config handling logic for Flake8."""
|
"""Config handling logic for Flake8."""
|
||||||
|
import collections
|
||||||
import configparser
|
import configparser
|
||||||
import logging
|
import logging
|
||||||
import os.path
|
import os.path
|
||||||
|
|
@ -49,6 +50,11 @@ class ConfigFileFinder(object):
|
||||||
args = ['.']
|
args = ['.']
|
||||||
self.parent = self.tail = os.path.abspath(os.path.commonprefix(args))
|
self.parent = self.tail = os.path.abspath(os.path.commonprefix(args))
|
||||||
|
|
||||||
|
# caches to avoid double-reading config files
|
||||||
|
self._local_configs = None
|
||||||
|
self._user_config = None
|
||||||
|
self._cli_configs = {}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _read_config(files):
|
def _read_config(files):
|
||||||
config = configparser.RawConfigParser()
|
config = configparser.RawConfigParser()
|
||||||
|
|
@ -63,10 +69,12 @@ class ConfigFileFinder(object):
|
||||||
|
|
||||||
def cli_config(self, files):
|
def cli_config(self, files):
|
||||||
"""Read and parse the config file specified on the command-line."""
|
"""Read and parse the config file specified on the command-line."""
|
||||||
config, found_files = self._read_config(files)
|
if files not in self._cli_configs:
|
||||||
if found_files:
|
config, found_files = self._read_config(files)
|
||||||
LOG.debug('Found cli configuration files: %s', found_files)
|
if found_files:
|
||||||
return config
|
LOG.debug('Found cli configuration files: %s', found_files)
|
||||||
|
self._cli_configs[files] = config
|
||||||
|
return self._cli_configs[files]
|
||||||
|
|
||||||
def generate_possible_local_files(self):
|
def generate_possible_local_files(self):
|
||||||
"""Find and generate all local config files."""
|
"""Find and generate all local config files."""
|
||||||
|
|
@ -104,10 +112,12 @@ class ConfigFileFinder(object):
|
||||||
|
|
||||||
def local_configs(self):
|
def local_configs(self):
|
||||||
"""Parse all local config files into one config object."""
|
"""Parse all local config files into one config object."""
|
||||||
config, found_files = self._read_config(self.local_config_files())
|
if self._local_configs is None:
|
||||||
if found_files:
|
config, found_files = self._read_config(self.local_config_files())
|
||||||
LOG.debug('Found local configuration files: %s', found_files)
|
if found_files:
|
||||||
return config
|
LOG.debug('Found local configuration files: %s', found_files)
|
||||||
|
self._local_configs = config
|
||||||
|
return self._local_configs
|
||||||
|
|
||||||
def user_config_file(self):
|
def user_config_file(self):
|
||||||
"""Find the user-level config file."""
|
"""Find the user-level config file."""
|
||||||
|
|
@ -117,10 +127,12 @@ class ConfigFileFinder(object):
|
||||||
|
|
||||||
def user_config(self):
|
def user_config(self):
|
||||||
"""Parse the user config file into a config object."""
|
"""Parse the user config file into a config object."""
|
||||||
config, found_files = self._read_config(self.user_config_file())
|
if self._user_config is None:
|
||||||
if found_files:
|
config, found_files = self._read_config(self.user_config_file())
|
||||||
LOG.debug('Found user configuration files: %s', found_files)
|
if found_files:
|
||||||
return config
|
LOG.debug('Found user configuration files: %s', found_files)
|
||||||
|
self._user_config = config
|
||||||
|
return self._user_config
|
||||||
|
|
||||||
|
|
||||||
class MergedConfigParser(object):
|
class MergedConfigParser(object):
|
||||||
|
|
@ -138,30 +150,23 @@ class MergedConfigParser(object):
|
||||||
#: :meth:`~configparser.RawConfigParser.getbool` method.
|
#: :meth:`~configparser.RawConfigParser.getbool` method.
|
||||||
GETBOOL_ACTIONS = {'store_true', 'store_false'}
|
GETBOOL_ACTIONS = {'store_true', 'store_false'}
|
||||||
|
|
||||||
def __init__(self, option_manager, extra_config_files=None, args=None):
|
def __init__(self, option_manager, config_finder):
|
||||||
"""Initialize the MergedConfigParser instance.
|
"""Initialize the MergedConfigParser instance.
|
||||||
|
|
||||||
:param flake8.option.manager.OptionManager option_manager:
|
:param flake8.options.manager.OptionManager option_manager:
|
||||||
Initialized OptionManager.
|
Initialized OptionManager.
|
||||||
:param list extra_config_files:
|
:param flake8.options.config.ConfigFileFinder config_finder:
|
||||||
List of extra config files to parse.
|
Initialized ConfigFileFinder.
|
||||||
:params list args:
|
|
||||||
The extra parsed arguments from the command-line.
|
|
||||||
"""
|
"""
|
||||||
#: Our instance of flake8.options.manager.OptionManager
|
#: Our instance of flake8.options.manager.OptionManager
|
||||||
self.option_manager = option_manager
|
self.option_manager = option_manager
|
||||||
#: The prog value for the cli parser
|
#: The prog value for the cli parser
|
||||||
self.program_name = option_manager.program_name
|
self.program_name = option_manager.program_name
|
||||||
#: Parsed extra arguments
|
|
||||||
self.args = args
|
|
||||||
#: Mapping of configuration option names to
|
#: Mapping of configuration option names to
|
||||||
#: :class:`~flake8.options.manager.Option` instances
|
#: :class:`~flake8.options.manager.Option` instances
|
||||||
self.config_options = option_manager.config_options_dict
|
self.config_options = option_manager.config_options_dict
|
||||||
#: List of extra config files
|
|
||||||
self.extra_config_files = extra_config_files or []
|
|
||||||
#: Our instance of our :class:`~ConfigFileFinder`
|
#: Our instance of our :class:`~ConfigFileFinder`
|
||||||
self.config_finder = ConfigFileFinder(self.program_name, self.args,
|
self.config_finder = config_finder
|
||||||
self.extra_config_files)
|
|
||||||
|
|
||||||
def _normalize_value(self, option, value):
|
def _normalize_value(self, option, value):
|
||||||
final_value = option.normalize(
|
final_value = option.normalize(
|
||||||
|
|
@ -280,3 +285,49 @@ class MergedConfigParser(object):
|
||||||
return self.parse_cli_config(cli_config)
|
return self.parse_cli_config(cli_config)
|
||||||
|
|
||||||
return self.merge_user_and_local_config()
|
return self.merge_user_and_local_config()
|
||||||
|
|
||||||
|
|
||||||
|
def get_local_plugins(config_finder, cli_config=None, isolated=False):
|
||||||
|
"""Get local plugins lists from config files.
|
||||||
|
|
||||||
|
:param flake8.options.config.ConfigFileFinder config_finder:
|
||||||
|
The config file finder to use.
|
||||||
|
:param str cli_config:
|
||||||
|
Value of --config when specified at the command-line. Overrides
|
||||||
|
all other config files.
|
||||||
|
:param bool isolated:
|
||||||
|
Determines if we should parse configuration files at all or not.
|
||||||
|
If running in isolated mode, we ignore all configuration files
|
||||||
|
:returns:
|
||||||
|
LocalPlugins namedtuple containing two lists of plugin strings,
|
||||||
|
one for extension (checker) plugins and one for report plugins.
|
||||||
|
:rtype:
|
||||||
|
flake8.options.config.LocalPlugins
|
||||||
|
"""
|
||||||
|
local_plugins = LocalPlugins(extension=[], report=[])
|
||||||
|
if isolated:
|
||||||
|
LOG.debug('Refusing to look for local plugins in configuration'
|
||||||
|
'files due to user-requested isolation')
|
||||||
|
return local_plugins
|
||||||
|
|
||||||
|
if cli_config:
|
||||||
|
LOG.debug('Reading local plugins only from "%s" specified via '
|
||||||
|
'--config by the user', cli_config)
|
||||||
|
configs = [config_finder.cli_config(cli_config)]
|
||||||
|
else:
|
||||||
|
configs = [
|
||||||
|
config_finder.user_config(),
|
||||||
|
config_finder.local_configs(),
|
||||||
|
]
|
||||||
|
|
||||||
|
section = '%s:local-plugins' % config_finder.program_name
|
||||||
|
for config in configs:
|
||||||
|
for plugin_type in ['extension', 'report']:
|
||||||
|
if config.has_option(section, plugin_type):
|
||||||
|
getattr(local_plugins, plugin_type).extend(
|
||||||
|
config.get(section, plugin_type).strip().splitlines()
|
||||||
|
)
|
||||||
|
return local_plugins
|
||||||
|
|
||||||
|
|
||||||
|
LocalPlugins = collections.namedtuple('LocalPlugins', 'extension report')
|
||||||
|
|
|
||||||
|
|
@ -236,11 +236,14 @@ class Plugin(object):
|
||||||
class PluginManager(object): # pylint: disable=too-few-public-methods
|
class PluginManager(object): # pylint: disable=too-few-public-methods
|
||||||
"""Find and manage plugins consistently."""
|
"""Find and manage plugins consistently."""
|
||||||
|
|
||||||
def __init__(self, namespace, verify_requirements=False):
|
def __init__(self, namespace,
|
||||||
|
local_plugins=None, verify_requirements=False):
|
||||||
"""Initialize the manager.
|
"""Initialize the manager.
|
||||||
|
|
||||||
:param str namespace:
|
:param str namespace:
|
||||||
Namespace of the plugins to manage, e.g., 'flake8.extension'.
|
Namespace of the plugins to manage, e.g., 'flake8.extension'.
|
||||||
|
:param list local_plugins:
|
||||||
|
Plugins from config (as "X = path.to:Plugin" strings).
|
||||||
:param bool verify_requirements:
|
:param bool verify_requirements:
|
||||||
Whether or not to make setuptools verify that the requirements for
|
Whether or not to make setuptools verify that the requirements for
|
||||||
the plugin are satisfied.
|
the plugin are satisfied.
|
||||||
|
|
@ -249,15 +252,34 @@ class PluginManager(object): # pylint: disable=too-few-public-methods
|
||||||
self.verify_requirements = verify_requirements
|
self.verify_requirements = verify_requirements
|
||||||
self.plugins = {}
|
self.plugins = {}
|
||||||
self.names = []
|
self.names = []
|
||||||
self._load_all_plugins()
|
self._load_local_plugins(local_plugins or [])
|
||||||
|
self._load_entrypoint_plugins()
|
||||||
|
|
||||||
def _load_all_plugins(self):
|
def _load_local_plugins(self, local_plugins):
|
||||||
|
"""Load local plugins from config.
|
||||||
|
|
||||||
|
:param list local_plugins:
|
||||||
|
Plugins from config (as "X = path.to:Plugin" strings).
|
||||||
|
"""
|
||||||
|
for plugin_str in local_plugins:
|
||||||
|
entry_point = pkg_resources.EntryPoint.parse(plugin_str)
|
||||||
|
self._load_plugin_from_entrypoint(entry_point)
|
||||||
|
|
||||||
|
def _load_entrypoint_plugins(self):
|
||||||
LOG.info('Loading entry-points for "%s".', self.namespace)
|
LOG.info('Loading entry-points for "%s".', self.namespace)
|
||||||
for entry_point in pkg_resources.iter_entry_points(self.namespace):
|
for entry_point in pkg_resources.iter_entry_points(self.namespace):
|
||||||
name = entry_point.name
|
self._load_plugin_from_entrypoint(entry_point)
|
||||||
self.plugins[name] = Plugin(name, entry_point)
|
|
||||||
self.names.append(name)
|
def _load_plugin_from_entrypoint(self, entry_point):
|
||||||
LOG.debug('Loaded %r for plugin "%s".', self.plugins[name], name)
|
"""Load a plugin from a setuptools EntryPoint.
|
||||||
|
|
||||||
|
:param EntryPoint entry_point:
|
||||||
|
EntryPoint to load plugin from.
|
||||||
|
"""
|
||||||
|
name = entry_point.name
|
||||||
|
self.plugins[name] = Plugin(name, entry_point)
|
||||||
|
self.names.append(name)
|
||||||
|
LOG.debug('Loaded %r for plugin "%s".', self.plugins[name], name)
|
||||||
|
|
||||||
def map(self, func, *args, **kwargs):
|
def map(self, func, *args, **kwargs):
|
||||||
r"""Call ``func`` with the plugin and \*args and \**kwargs after.
|
r"""Call ``func`` with the plugin and \*args and \**kwargs after.
|
||||||
|
|
@ -329,9 +351,14 @@ class PluginTypeManager(object):
|
||||||
|
|
||||||
namespace = None
|
namespace = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, local_plugins=None):
|
||||||
"""Initialize the plugin type's manager."""
|
"""Initialize the plugin type's manager.
|
||||||
self.manager = PluginManager(self.namespace)
|
|
||||||
|
:param list local_plugins:
|
||||||
|
Plugins from config file instead of entry-points
|
||||||
|
"""
|
||||||
|
self.manager = PluginManager(
|
||||||
|
self.namespace, local_plugins=local_plugins)
|
||||||
self.plugins_loaded = False
|
self.plugins_loaded = False
|
||||||
|
|
||||||
def __contains__(self, name):
|
def __contains__(self, name):
|
||||||
|
|
@ -436,7 +463,7 @@ class NotifierBuilderMixin(object): # pylint: disable=too-few-public-methods
|
||||||
|
|
||||||
|
|
||||||
class Checkers(PluginTypeManager):
|
class Checkers(PluginTypeManager):
|
||||||
"""All of the checkers registered through entry-ponits."""
|
"""All of the checkers registered through entry-points or config."""
|
||||||
|
|
||||||
namespace = 'flake8.extension'
|
namespace = 'flake8.extension'
|
||||||
|
|
||||||
|
|
@ -515,12 +542,12 @@ class Checkers(PluginTypeManager):
|
||||||
|
|
||||||
|
|
||||||
class Listeners(PluginTypeManager, NotifierBuilderMixin):
|
class Listeners(PluginTypeManager, NotifierBuilderMixin):
|
||||||
"""All of the listeners registered through entry-points."""
|
"""All of the listeners registered through entry-points or config."""
|
||||||
|
|
||||||
namespace = 'flake8.listen'
|
namespace = 'flake8.listen'
|
||||||
|
|
||||||
|
|
||||||
class ReportFormatters(PluginTypeManager):
|
class ReportFormatters(PluginTypeManager):
|
||||||
"""All of the report formatters registered through entry-points."""
|
"""All of the report formatters registered through entry-points/config."""
|
||||||
|
|
||||||
namespace = 'flake8.report'
|
namespace = 'flake8.report'
|
||||||
|
|
|
||||||
10
tests/fixtures/config_files/README.rst
vendored
10
tests/fixtures/config_files/README.rst
vendored
|
|
@ -1,11 +1,11 @@
|
||||||
About this directory
|
About this directory
|
||||||
====================
|
====================
|
||||||
|
|
||||||
The files in this directory are test fixtures for unit and integration tests.
|
The files in this directory are test fixtures for unit and integration tests.
|
||||||
Their purpose is described below. Please note the list of file names that can
|
Their purpose is described below. Please note the list of file names that can
|
||||||
not be created as they are already used by tests.
|
not be created as they are already used by tests.
|
||||||
|
|
||||||
New fixtures are preferred over updating existing features unless existing
|
New fixtures are preferred over updating existing features unless existing
|
||||||
tests will fail.
|
tests will fail.
|
||||||
|
|
||||||
Files that should not be created
|
Files that should not be created
|
||||||
|
|
@ -26,6 +26,10 @@ Purposes of existing fixtures
|
||||||
This should be used when providing config files that would have been found
|
This should be used when providing config files that would have been found
|
||||||
by looking for config files in the current working project directory.
|
by looking for config files in the current working project directory.
|
||||||
|
|
||||||
|
``tests/fixtures/config_files/local-plugin.ini``
|
||||||
|
|
||||||
|
This is for testing configuring a plugin via flake8 config file instead of
|
||||||
|
setuptools entry-point.
|
||||||
|
|
||||||
``tests/fixtures/config_files/no-flake8-section.ini``
|
``tests/fixtures/config_files/no-flake8-section.ini``
|
||||||
|
|
||||||
|
|
|
||||||
5
tests/fixtures/config_files/local-plugin.ini
vendored
Normal file
5
tests/fixtures/config_files/local-plugin.ini
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
[flake8:local-plugins]
|
||||||
|
extension =
|
||||||
|
XE = test_plugins:ExtensionTestPlugin
|
||||||
|
report =
|
||||||
|
XR = test_plugins:ReportTestPlugin
|
||||||
|
|
@ -5,6 +5,7 @@ import pytest
|
||||||
|
|
||||||
from flake8.main import options
|
from flake8.main import options
|
||||||
from flake8.options import aggregator
|
from flake8.options import aggregator
|
||||||
|
from flake8.options import config
|
||||||
from flake8.options import manager
|
from flake8.options import manager
|
||||||
|
|
||||||
CLI_SPECIFIED_CONFIG = 'tests/fixtures/config_files/cli-specified.ini'
|
CLI_SPECIFIED_CONFIG = 'tests/fixtures/config_files/cli-specified.ini'
|
||||||
|
|
@ -25,7 +26,9 @@ def test_aggregate_options_with_config(optmanager):
|
||||||
"""Verify we aggregate options and config values appropriately."""
|
"""Verify we aggregate options and config values appropriately."""
|
||||||
arguments = ['flake8', '--config', CLI_SPECIFIED_CONFIG, '--select',
|
arguments = ['flake8', '--config', CLI_SPECIFIED_CONFIG, '--select',
|
||||||
'E11,E34,E402,W,F', '--exclude', 'tests/*']
|
'E11,E34,E402,W,F', '--exclude', 'tests/*']
|
||||||
options, args = aggregator.aggregate_options(optmanager, arguments)
|
config_finder = config.ConfigFileFinder('flake8', arguments, [])
|
||||||
|
options, args = aggregator.aggregate_options(
|
||||||
|
optmanager, config_finder, arguments)
|
||||||
|
|
||||||
assert options.config == CLI_SPECIFIED_CONFIG
|
assert options.config == CLI_SPECIFIED_CONFIG
|
||||||
assert options.select == ['E11', 'E34', 'E402', 'W', 'F']
|
assert options.select == ['E11', 'E34', 'E402', 'W', 'F']
|
||||||
|
|
@ -37,8 +40,10 @@ def test_aggregate_options_when_isolated(optmanager):
|
||||||
"""Verify we aggregate options and config values appropriately."""
|
"""Verify we aggregate options and config values appropriately."""
|
||||||
arguments = ['flake8', '--isolated', '--select', 'E11,E34,E402,W,F',
|
arguments = ['flake8', '--isolated', '--select', 'E11,E34,E402,W,F',
|
||||||
'--exclude', 'tests/*']
|
'--exclude', 'tests/*']
|
||||||
|
config_finder = config.ConfigFileFinder('flake8', arguments, [])
|
||||||
optmanager.extend_default_ignore(['E8'])
|
optmanager.extend_default_ignore(['E8'])
|
||||||
options, args = aggregator.aggregate_options(optmanager, arguments)
|
options, args = aggregator.aggregate_options(
|
||||||
|
optmanager, config_finder, arguments)
|
||||||
|
|
||||||
assert options.isolated is True
|
assert options.isolated is True
|
||||||
assert options.select == ['E11', 'E34', 'E402', 'W', 'F']
|
assert options.select == ['E11', 'E34', 'E402', 'W', 'F']
|
||||||
|
|
|
||||||
58
tests/integration/test_plugins.py
Normal file
58
tests/integration/test_plugins.py
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
"""Integration tests for plugin loading."""
|
||||||
|
from flake8.main import application
|
||||||
|
|
||||||
|
|
||||||
|
LOCAL_PLUGIN_CONFIG = 'tests/fixtures/config_files/local-plugin.ini'
|
||||||
|
|
||||||
|
|
||||||
|
class ExtensionTestPlugin(object):
|
||||||
|
"""Extension test plugin."""
|
||||||
|
|
||||||
|
name = 'ExtensionTestPlugin'
|
||||||
|
version = '1.0.0'
|
||||||
|
|
||||||
|
def __init__(self, tree):
|
||||||
|
"""Construct an instance of test plugin."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
"""Do nothing."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_options(cls, parser):
|
||||||
|
"""Register options."""
|
||||||
|
parser.add_option('--anopt')
|
||||||
|
|
||||||
|
|
||||||
|
class ReportTestPlugin(object):
|
||||||
|
"""Report test plugin."""
|
||||||
|
|
||||||
|
name = 'ReportTestPlugin'
|
||||||
|
version = '1.0.0'
|
||||||
|
|
||||||
|
def __init__(self, tree):
|
||||||
|
"""Construct an instance of test plugin."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
"""Do nothing."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def test_enable_local_plugin_from_config():
|
||||||
|
"""App can load a local plugin from config file."""
|
||||||
|
app = application.Application()
|
||||||
|
app.initialize(['flake8', '--config', LOCAL_PLUGIN_CONFIG])
|
||||||
|
|
||||||
|
assert app.check_plugins['XE'].plugin is ExtensionTestPlugin
|
||||||
|
assert app.formatting_plugins['XR'].plugin is ReportTestPlugin
|
||||||
|
|
||||||
|
|
||||||
|
def test_local_plugin_can_add_option():
|
||||||
|
"""A local plugin can add a CLI option."""
|
||||||
|
app = application.Application()
|
||||||
|
app.initialize(
|
||||||
|
['flake8', '--config', LOCAL_PLUGIN_CONFIG, '--anopt', 'foo'])
|
||||||
|
|
||||||
|
assert app.options.anopt == 'foo'
|
||||||
|
|
@ -39,6 +39,18 @@ def test_cli_config():
|
||||||
assert parsed_config.has_section('flake8')
|
assert parsed_config.has_section('flake8')
|
||||||
|
|
||||||
|
|
||||||
|
def test_cli_config_double_read():
|
||||||
|
"""Second request for CLI config is cached."""
|
||||||
|
finder = config.ConfigFileFinder('flake8', None, [])
|
||||||
|
|
||||||
|
parsed_config = finder.cli_config(CLI_SPECIFIED_FILEPATH)
|
||||||
|
boom = Exception("second request for CLI config not cached")
|
||||||
|
with mock.patch.object(finder, '_read_config', side_effect=boom):
|
||||||
|
parsed_config_2 = finder.cli_config(CLI_SPECIFIED_FILEPATH)
|
||||||
|
|
||||||
|
assert parsed_config is parsed_config_2
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('args,expected', [
|
@pytest.mark.parametrize('args,expected', [
|
||||||
# No arguments, common prefix of abspath('.')
|
# No arguments, common prefix of abspath('.')
|
||||||
([],
|
([],
|
||||||
|
|
@ -105,6 +117,18 @@ def test_local_configs():
|
||||||
assert isinstance(finder.local_configs(), configparser.RawConfigParser)
|
assert isinstance(finder.local_configs(), configparser.RawConfigParser)
|
||||||
|
|
||||||
|
|
||||||
|
def test_local_configs_double_read():
|
||||||
|
"""Second request for local configs is cached."""
|
||||||
|
finder = config.ConfigFileFinder('flake8', None, [])
|
||||||
|
|
||||||
|
first_read = finder.local_configs()
|
||||||
|
boom = Exception("second request for local configs not cached")
|
||||||
|
with mock.patch.object(finder, '_read_config', side_effect=boom):
|
||||||
|
second_read = finder.local_configs()
|
||||||
|
|
||||||
|
assert first_read is second_read
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('files', [
|
@pytest.mark.parametrize('files', [
|
||||||
[BROKEN_CONFIG_PATH],
|
[BROKEN_CONFIG_PATH],
|
||||||
[CLI_SPECIFIED_FILEPATH, BROKEN_CONFIG_PATH],
|
[CLI_SPECIFIED_FILEPATH, BROKEN_CONFIG_PATH],
|
||||||
|
|
|
||||||
38
tests/unit/test_get_local_plugins.py
Normal file
38
tests/unit/test_get_local_plugins.py
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
"""Tests for get_local_plugins."""
|
||||||
|
import mock
|
||||||
|
|
||||||
|
from flake8.options import config
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_local_plugins_respects_isolated():
|
||||||
|
"""Verify behaviour of get_local_plugins with isolated=True."""
|
||||||
|
config_finder = mock.MagicMock()
|
||||||
|
|
||||||
|
local_plugins = config.get_local_plugins(config_finder, isolated=True)
|
||||||
|
|
||||||
|
assert local_plugins.extension == []
|
||||||
|
assert local_plugins.report == []
|
||||||
|
assert config_finder.local_configs.called is False
|
||||||
|
assert config_finder.user_config.called is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_local_plugins_uses_cli_config():
|
||||||
|
"""Verify behaviour of get_local_plugins with a specified config."""
|
||||||
|
config_finder = mock.MagicMock()
|
||||||
|
|
||||||
|
config.get_local_plugins(config_finder, cli_config='foo.ini')
|
||||||
|
|
||||||
|
config_finder.cli_config.assert_called_once_with('foo.ini')
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_local_plugins():
|
||||||
|
"""Verify get_local_plugins returns expected plugins."""
|
||||||
|
config_fixture_path = 'tests/fixtures/config_files/local-plugin.ini'
|
||||||
|
config_finder = config.ConfigFileFinder('flake8', [], [])
|
||||||
|
|
||||||
|
with mock.patch.object(config_finder, 'local_config_files') as localcfs:
|
||||||
|
localcfs.return_value = [config_fixture_path]
|
||||||
|
local_plugins = config.get_local_plugins(config_finder)
|
||||||
|
|
||||||
|
assert local_plugins.extension == ['XE = test_plugins:ExtensionTestPlugin']
|
||||||
|
assert local_plugins.report == ['XR = test_plugins:ReportTestPlugin']
|
||||||
|
|
@ -9,11 +9,15 @@ from flake8.formatting import base as formatter
|
||||||
def test_get_style_guide():
|
def test_get_style_guide():
|
||||||
"""Verify the methods called on our internal Application."""
|
"""Verify the methods called on our internal Application."""
|
||||||
mockedapp = mock.Mock()
|
mockedapp = mock.Mock()
|
||||||
|
mockedapp.prelim_opts.verbose = 0
|
||||||
|
mockedapp.prelim_opts.output_file = None
|
||||||
with mock.patch('flake8.main.application.Application') as Application:
|
with mock.patch('flake8.main.application.Application') as Application:
|
||||||
Application.return_value = mockedapp
|
Application.return_value = mockedapp
|
||||||
style_guide = api.get_style_guide()
|
style_guide = api.get_style_guide()
|
||||||
|
|
||||||
Application.assert_called_once_with()
|
Application.assert_called_once_with()
|
||||||
|
mockedapp.parse_preliminary_options_and_args.assert_called_once_with([])
|
||||||
|
mockedapp.make_config_finder.assert_called_once_with()
|
||||||
mockedapp.find_plugins.assert_called_once_with()
|
mockedapp.find_plugins.assert_called_once_with()
|
||||||
mockedapp.register_plugin_options.assert_called_once_with()
|
mockedapp.register_plugin_options.assert_called_once_with()
|
||||||
mockedapp.parse_configuration_and_cli.assert_called_once_with([])
|
mockedapp.parse_configuration_and_cli.assert_called_once_with([])
|
||||||
|
|
|
||||||
|
|
@ -14,33 +14,13 @@ def optmanager():
|
||||||
return manager.OptionManager(prog='flake8', version='3.0.0a1')
|
return manager.OptionManager(prog='flake8', version='3.0.0a1')
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('args,extra_config_files', [
|
@pytest.fixture
|
||||||
(None, None),
|
def config_finder():
|
||||||
(None, []),
|
"""Generate a simple ConfigFileFinder."""
|
||||||
(None, ['foo.ini']),
|
return config.ConfigFileFinder('flake8', [], [])
|
||||||
('flake8/', []),
|
|
||||||
('flake8/', ['foo.ini']),
|
|
||||||
])
|
|
||||||
def test_creates_its_own_config_file_finder(args, extra_config_files,
|
|
||||||
optmanager):
|
|
||||||
"""Verify we create a ConfigFileFinder correctly."""
|
|
||||||
class_path = 'flake8.options.config.ConfigFileFinder'
|
|
||||||
with mock.patch(class_path) as ConfigFileFinder:
|
|
||||||
parser = config.MergedConfigParser(
|
|
||||||
option_manager=optmanager,
|
|
||||||
extra_config_files=extra_config_files,
|
|
||||||
args=args,
|
|
||||||
)
|
|
||||||
|
|
||||||
assert parser.program_name == 'flake8'
|
|
||||||
ConfigFileFinder.assert_called_once_with(
|
|
||||||
'flake8',
|
|
||||||
args,
|
|
||||||
extra_config_files or [],
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_parse_cli_config(optmanager):
|
def test_parse_cli_config(optmanager, config_finder):
|
||||||
"""Parse the specified config file as a cli config file."""
|
"""Parse the specified config file as a cli config file."""
|
||||||
optmanager.add_option('--exclude', parse_from_config=True,
|
optmanager.add_option('--exclude', parse_from_config=True,
|
||||||
comma_separated_list=True,
|
comma_separated_list=True,
|
||||||
|
|
@ -51,7 +31,7 @@ def test_parse_cli_config(optmanager):
|
||||||
action='count')
|
action='count')
|
||||||
optmanager.add_option('--quiet', parse_from_config=True,
|
optmanager.add_option('--quiet', parse_from_config=True,
|
||||||
action='count')
|
action='count')
|
||||||
parser = config.MergedConfigParser(optmanager)
|
parser = config.MergedConfigParser(optmanager, config_finder)
|
||||||
|
|
||||||
parsed_config = parser.parse_cli_config(
|
parsed_config = parser.parse_cli_config(
|
||||||
'tests/fixtures/config_files/cli-specified.ini'
|
'tests/fixtures/config_files/cli-specified.ini'
|
||||||
|
|
@ -72,15 +52,16 @@ def test_parse_cli_config(optmanager):
|
||||||
('tests/fixtures/config_files/cli-specified.ini', True),
|
('tests/fixtures/config_files/cli-specified.ini', True),
|
||||||
('tests/fixtures/config_files/no-flake8-section.ini', False),
|
('tests/fixtures/config_files/no-flake8-section.ini', False),
|
||||||
])
|
])
|
||||||
def test_is_configured_by(filename, is_configured_by, optmanager):
|
def test_is_configured_by(
|
||||||
|
filename, is_configured_by, optmanager, config_finder):
|
||||||
"""Verify the behaviour of the is_configured_by method."""
|
"""Verify the behaviour of the is_configured_by method."""
|
||||||
parsed_config, _ = config.ConfigFileFinder._read_config(filename)
|
parsed_config, _ = config.ConfigFileFinder._read_config(filename)
|
||||||
parser = config.MergedConfigParser(optmanager)
|
parser = config.MergedConfigParser(optmanager, config_finder)
|
||||||
|
|
||||||
assert parser.is_configured_by(parsed_config) is is_configured_by
|
assert parser.is_configured_by(parsed_config) is is_configured_by
|
||||||
|
|
||||||
|
|
||||||
def test_parse_user_config(optmanager):
|
def test_parse_user_config(optmanager, config_finder):
|
||||||
"""Verify parsing of user config files."""
|
"""Verify parsing of user config files."""
|
||||||
optmanager.add_option('--exclude', parse_from_config=True,
|
optmanager.add_option('--exclude', parse_from_config=True,
|
||||||
comma_separated_list=True,
|
comma_separated_list=True,
|
||||||
|
|
@ -91,7 +72,7 @@ def test_parse_user_config(optmanager):
|
||||||
action='count')
|
action='count')
|
||||||
optmanager.add_option('--quiet', parse_from_config=True,
|
optmanager.add_option('--quiet', parse_from_config=True,
|
||||||
action='count')
|
action='count')
|
||||||
parser = config.MergedConfigParser(optmanager)
|
parser = config.MergedConfigParser(optmanager, config_finder)
|
||||||
|
|
||||||
with mock.patch.object(parser.config_finder, 'user_config_file') as usercf:
|
with mock.patch.object(parser.config_finder, 'user_config_file') as usercf:
|
||||||
usercf.return_value = 'tests/fixtures/config_files/cli-specified.ini'
|
usercf.return_value = 'tests/fixtures/config_files/cli-specified.ini'
|
||||||
|
|
@ -109,7 +90,7 @@ def test_parse_user_config(optmanager):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_parse_local_config(optmanager):
|
def test_parse_local_config(optmanager, config_finder):
|
||||||
"""Verify parsing of local config files."""
|
"""Verify parsing of local config files."""
|
||||||
optmanager.add_option('--exclude', parse_from_config=True,
|
optmanager.add_option('--exclude', parse_from_config=True,
|
||||||
comma_separated_list=True,
|
comma_separated_list=True,
|
||||||
|
|
@ -120,8 +101,7 @@ def test_parse_local_config(optmanager):
|
||||||
action='count')
|
action='count')
|
||||||
optmanager.add_option('--quiet', parse_from_config=True,
|
optmanager.add_option('--quiet', parse_from_config=True,
|
||||||
action='count')
|
action='count')
|
||||||
parser = config.MergedConfigParser(optmanager)
|
parser = config.MergedConfigParser(optmanager, config_finder)
|
||||||
config_finder = parser.config_finder
|
|
||||||
|
|
||||||
with mock.patch.object(config_finder, 'local_config_files') as localcfs:
|
with mock.patch.object(config_finder, 'local_config_files') as localcfs:
|
||||||
localcfs.return_value = [
|
localcfs.return_value = [
|
||||||
|
|
@ -141,7 +121,7 @@ def test_parse_local_config(optmanager):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_merge_user_and_local_config(optmanager):
|
def test_merge_user_and_local_config(optmanager, config_finder):
|
||||||
"""Verify merging of parsed user and local config files."""
|
"""Verify merging of parsed user and local config files."""
|
||||||
optmanager.add_option('--exclude', parse_from_config=True,
|
optmanager.add_option('--exclude', parse_from_config=True,
|
||||||
comma_separated_list=True,
|
comma_separated_list=True,
|
||||||
|
|
@ -150,8 +130,7 @@ def test_merge_user_and_local_config(optmanager):
|
||||||
comma_separated_list=True)
|
comma_separated_list=True)
|
||||||
optmanager.add_option('--select', parse_from_config=True,
|
optmanager.add_option('--select', parse_from_config=True,
|
||||||
comma_separated_list=True)
|
comma_separated_list=True)
|
||||||
parser = config.MergedConfigParser(optmanager)
|
parser = config.MergedConfigParser(optmanager, config_finder)
|
||||||
config_finder = parser.config_finder
|
|
||||||
|
|
||||||
with mock.patch.object(config_finder, 'local_config_files') as localcfs:
|
with mock.patch.object(config_finder, 'local_config_files') as localcfs:
|
||||||
localcfs.return_value = [
|
localcfs.return_value = [
|
||||||
|
|
@ -172,23 +151,23 @@ def test_merge_user_and_local_config(optmanager):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.options.config.ConfigFileFinder')
|
def test_parse_isolates_config(optmanager):
|
||||||
def test_parse_isolates_config(ConfigFileManager, optmanager):
|
|
||||||
"""Verify behaviour of the parse method with isolated=True."""
|
"""Verify behaviour of the parse method with isolated=True."""
|
||||||
parser = config.MergedConfigParser(optmanager)
|
config_finder = mock.MagicMock()
|
||||||
|
parser = config.MergedConfigParser(optmanager, config_finder)
|
||||||
|
|
||||||
assert parser.parse(isolated=True) == {}
|
assert parser.parse(isolated=True) == {}
|
||||||
assert parser.config_finder.local_configs.called is False
|
assert config_finder.local_configs.called is False
|
||||||
assert parser.config_finder.user_config.called is False
|
assert config_finder.user_config.called is False
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.options.config.ConfigFileFinder')
|
def test_parse_uses_cli_config(optmanager):
|
||||||
def test_parse_uses_cli_config(ConfigFileManager, optmanager):
|
|
||||||
"""Verify behaviour of the parse method with a specified config."""
|
"""Verify behaviour of the parse method with a specified config."""
|
||||||
parser = config.MergedConfigParser(optmanager)
|
config_finder = mock.MagicMock()
|
||||||
|
parser = config.MergedConfigParser(optmanager, config_finder)
|
||||||
|
|
||||||
parser.parse(cli_config='foo.ini')
|
parser.parse(cli_config='foo.ini')
|
||||||
parser.config_finder.cli_config.assert_called_once_with('foo.ini')
|
config_finder.cli_config.assert_called_once_with('foo.ini')
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('config_fixture_path', [
|
@pytest.mark.parametrize('config_fixture_path', [
|
||||||
|
|
@ -196,7 +175,8 @@ def test_parse_uses_cli_config(ConfigFileManager, optmanager):
|
||||||
'tests/fixtures/config_files/cli-specified-with-inline-comments.ini',
|
'tests/fixtures/config_files/cli-specified-with-inline-comments.ini',
|
||||||
'tests/fixtures/config_files/cli-specified-without-inline-comments.ini',
|
'tests/fixtures/config_files/cli-specified-without-inline-comments.ini',
|
||||||
])
|
])
|
||||||
def test_parsed_configs_are_equivalent(optmanager, config_fixture_path):
|
def test_parsed_configs_are_equivalent(
|
||||||
|
optmanager, config_finder, config_fixture_path):
|
||||||
"""Verify the each file matches the expected parsed output.
|
"""Verify the each file matches the expected parsed output.
|
||||||
|
|
||||||
This is used to ensure our documented behaviour does not regress.
|
This is used to ensure our documented behaviour does not regress.
|
||||||
|
|
@ -206,8 +186,7 @@ def test_parsed_configs_are_equivalent(optmanager, config_fixture_path):
|
||||||
normalize_paths=True)
|
normalize_paths=True)
|
||||||
optmanager.add_option('--ignore', parse_from_config=True,
|
optmanager.add_option('--ignore', parse_from_config=True,
|
||||||
comma_separated_list=True)
|
comma_separated_list=True)
|
||||||
parser = config.MergedConfigParser(optmanager)
|
parser = config.MergedConfigParser(optmanager, config_finder)
|
||||||
config_finder = parser.config_finder
|
|
||||||
|
|
||||||
with mock.patch.object(config_finder, 'local_config_files') as localcfs:
|
with mock.patch.object(config_finder, 'local_config_files') as localcfs:
|
||||||
localcfs.return_value = [config_fixture_path]
|
localcfs.return_value = [config_fixture_path]
|
||||||
|
|
@ -227,7 +206,8 @@ def test_parsed_configs_are_equivalent(optmanager, config_fixture_path):
|
||||||
@pytest.mark.parametrize('config_file', [
|
@pytest.mark.parametrize('config_file', [
|
||||||
'tests/fixtures/config_files/config-with-hyphenated-options.ini'
|
'tests/fixtures/config_files/config-with-hyphenated-options.ini'
|
||||||
])
|
])
|
||||||
def test_parsed_hyphenated_and_underscored_names(optmanager, config_file):
|
def test_parsed_hyphenated_and_underscored_names(
|
||||||
|
optmanager, config_finder, config_file):
|
||||||
"""Verify we find hyphenated option names as well as underscored.
|
"""Verify we find hyphenated option names as well as underscored.
|
||||||
|
|
||||||
This tests for options like --max-line-length and --enable-extensions
|
This tests for options like --max-line-length and --enable-extensions
|
||||||
|
|
@ -238,8 +218,7 @@ def test_parsed_hyphenated_and_underscored_names(optmanager, config_file):
|
||||||
type='int')
|
type='int')
|
||||||
optmanager.add_option('--enable-extensions', parse_from_config=True,
|
optmanager.add_option('--enable-extensions', parse_from_config=True,
|
||||||
comma_separated_list=True)
|
comma_separated_list=True)
|
||||||
parser = config.MergedConfigParser(optmanager)
|
parser = config.MergedConfigParser(optmanager, config_finder)
|
||||||
config_finder = parser.config_finder
|
|
||||||
|
|
||||||
with mock.patch.object(config_finder, 'local_config_files') as localcfs:
|
with mock.patch.object(config_finder, 'local_config_files') as localcfs:
|
||||||
localcfs.return_value = [config_file]
|
localcfs.return_value = [config_file]
|
||||||
|
|
|
||||||
|
|
@ -48,3 +48,15 @@ def test_handles_mapping_functions_across_plugins(iter_entry_points):
|
||||||
plugins = [plugin_mgr.plugins[name] for name in plugin_mgr.names]
|
plugins = [plugin_mgr.plugins[name] for name in plugin_mgr.names]
|
||||||
|
|
||||||
assert list(plugin_mgr.map(lambda x: x)) == plugins
|
assert list(plugin_mgr.map(lambda x: x)) == plugins
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch('pkg_resources.iter_entry_points')
|
||||||
|
def test_local_plugins(iter_entry_points):
|
||||||
|
"""Verify PluginManager can load given local plugins."""
|
||||||
|
iter_entry_points.return_value = []
|
||||||
|
plugin_mgr = manager.PluginManager(
|
||||||
|
namespace='testing.pkg_resources',
|
||||||
|
local_plugins=['X = path.to:Plugin']
|
||||||
|
)
|
||||||
|
|
||||||
|
assert plugin_mgr.plugins['X'].entry_point.module_name == 'path.to'
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ def test_instantiates_a_manager(PluginManager):
|
||||||
"""Verify we create a PluginManager on instantiation."""
|
"""Verify we create a PluginManager on instantiation."""
|
||||||
FakeTestType()
|
FakeTestType()
|
||||||
|
|
||||||
PluginManager.assert_called_once_with(TEST_NAMESPACE)
|
PluginManager.assert_called_once_with(TEST_NAMESPACE, local_plugins=None)
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.plugins.manager.PluginManager')
|
@mock.patch('flake8.plugins.manager.PluginManager')
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue