Merge branch 'remove-application-prelim-option-state' into 'master'

Remove application prelimary option state

See merge request pycqa/flake8!358
This commit is contained in:
Eric N. Vander Weele 2019-10-01 07:04:59 +00:00
commit b12839aec0
4 changed files with 59 additions and 41 deletions

View file

@ -28,12 +28,12 @@ def get_style_guide(**kwargs):
:class:`StyleGuide` :class:`StyleGuide`
""" """
application = app.Application() application = app.Application()
application.parse_preliminary_options_and_args([]) prelim_opts, prelim_args = application.parse_preliminary_options_and_args(
flake8.configure_logging( []
application.prelim_opts.verbose, application.prelim_opts.output_file
) )
application.make_config_finder() flake8.configure_logging(prelim_opts.verbose, prelim_opts.output_file)
application.find_plugins() application.make_config_finder(prelim_opts.append_config, prelim_args)
application.find_plugins(prelim_opts.config, prelim_opts.isolated)
application.register_plugin_options() application.register_plugin_options()
application.parse_configuration_and_cli([]) application.parse_configuration_and_cli([])
# We basically want application.initialize to be called but with these # We basically want application.initialize to be called but with these

View file

@ -5,7 +5,7 @@ import argparse
import logging import logging
import sys import sys
import time import time
from typing import Dict, List, Optional, Set from typing import Dict, List, Optional, Set, Tuple
import flake8 import flake8
from flake8 import checker from flake8 import checker
@ -51,13 +51,8 @@ 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:`argparse.Namespace` instance
self.prelim_opts = None # type: argparse.Namespace
#: The preliminary arguments parsed from CLI before plugins are loaded
self.prelim_args = None # type: List[str]
#: The instance of :class:`flake8.options.config.ConfigFileFinder` #: The instance of :class:`flake8.options.config.ConfigFileFinder`
self.config_finder = None self.config_finder = None # type: config.ConfigFileFinder
#: The :class:`flake8.options.config.LocalPlugins` found in config #: The :class:`flake8.options.config.LocalPlugins` found in config
self.local_plugins = None # type: config.LocalPlugins self.local_plugins = None # type: config.LocalPlugins
@ -98,7 +93,7 @@ class Application(object):
self.parsed_diff = {} # type: Dict[str, Set[int]] self.parsed_diff = {} # type: Dict[str, Set[int]]
def parse_preliminary_options_and_args(self, argv): def parse_preliminary_options_and_args(self, argv):
# type: (List[str]) -> None # type: (List[str]) -> Tuple[argparse.Namespace, List[str]]
"""Get preliminary options and args from CLI, pre-plugin-loading. """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 We need to know the values of a few standard options and args now, so
@ -108,10 +103,12 @@ class Application(object):
options; we ignore those for now, they'll be parsed later when we do options; we ignore those for now, they'll be parsed later when we do
real option parsing. real option parsing.
Sets self.prelim_opts and self.prelim_args.
:param list argv: :param list argv:
Command-line arguments passed in directly. Command-line arguments passed in directly.
:returns:
Populated namespace and list of remaining argument strings.
:rtype:
(argparse.Namespace, list)
""" """
# We haven't found or registered our plugins yet, so let's defer # We haven't found or registered our plugins yet, so let's defer
# printing the version until we aggregate options from config files # printing the version until we aggregate options from config files
@ -138,7 +135,7 @@ class Application(object):
opts, args = self.option_manager.parse_known_args(args) opts, args = self.option_manager.parse_known_args(args)
# parse_known_args includes unknown options as args # parse_known_args includes unknown options as args
args = [a for a in args if not a.startswith("-")] args = [a for a in args if not a.startswith("-")]
self.prelim_opts, self.prelim_args = opts, args return opts, args
def exit(self): def exit(self):
# type: () -> None # type: () -> None
@ -155,17 +152,22 @@ class Application(object):
(self.result_count > 0) or self.catastrophic_failure (self.result_count > 0) or self.catastrophic_failure
) )
def make_config_finder(self): def make_config_finder(self, append_config, args):
"""Make our ConfigFileFinder based on preliminary opts and args.""" # type: (List[str], List[str]) -> None
"""Make our ConfigFileFinder based on preliminary opts and args.
:param list append_config:
List of configuration files to be parsed for configuration.
:param list args:
The list of file arguments passed from the CLI.
"""
if self.config_finder is None: if self.config_finder is None:
self.config_finder = config.ConfigFileFinder( self.config_finder = config.ConfigFileFinder(
self.option_manager.program_name, self.option_manager.program_name, args, append_config
self.prelim_args,
self.prelim_opts.append_config,
) )
def find_plugins(self): def find_plugins(self, config_file, ignore_config_files):
# type: () -> None # type: (Optional[str], bool) -> None
"""Find and load the plugins for this application. """Find and load the plugins for this application.
If :attr:`check_plugins`, or :attr:`formatting_plugins` are ``None`` If :attr:`check_plugins`, or :attr:`formatting_plugins` are ``None``
@ -173,12 +175,17 @@ class Application(object):
instance. Given the expense of finding plugins (via :mod:`entrypoints`) instance. Given the expense of finding plugins (via :mod:`entrypoints`)
we want this to be idempotent and so only update those attributes if we want this to be idempotent and so only update those attributes if
they are ``None``. they are ``None``.
:param str config_file:
The optional configuraiton file to override all other configuration
files (i.e., the --config option).
:param bool ignore_config_files:
Determine whether to parse configuration files or not. (i.e., the
--isolated option).
""" """
if self.local_plugins is None: if self.local_plugins is None:
self.local_plugins = config.get_local_plugins( self.local_plugins = config.get_local_plugins(
self.config_finder, self.config_finder, config_file, ignore_config_files
self.prelim_opts.config,
self.prelim_opts.isolated,
) )
sys.path.extend(self.local_plugins.paths) sys.path.extend(self.local_plugins.paths)
@ -352,12 +359,12 @@ 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) prelim_opts, prelim_args = self.parse_preliminary_options_and_args(
flake8.configure_logging( argv
self.prelim_opts.verbose, self.prelim_opts.output_file
) )
self.make_config_finder() flake8.configure_logging(prelim_opts.verbose, prelim_opts.output_file)
self.find_plugins() self.make_config_finder(prelim_opts.append_config, prelim_args)
self.find_plugins(prelim_opts.config, prelim_opts.isolated)
self.register_plugin_options() self.register_plugin_options()
self.parse_configuration_and_cli(argv) self.parse_configuration_and_cli(argv)
self.make_formatter() self.make_formatter()

View file

@ -92,18 +92,18 @@ def test_returns_specified_plugin(application):
def test_prelim_opts_args(application): def test_prelim_opts_args(application):
"""Verify we get sensible prelim opts and args.""" """Verify we get sensible prelim opts and args."""
application.parse_preliminary_options_and_args( opts, args = application.parse_preliminary_options_and_args(
['flake8', '--foo', '--verbose', 'src', 'setup.py', '--statistics']) ['flake8', '--foo', '--verbose', 'src', 'setup.py', '--statistics'])
assert application.prelim_opts.statistics assert opts.statistics
assert application.prelim_opts.verbose assert opts.verbose
assert application.prelim_args == ['src', 'setup.py'] assert args == ['src', 'setup.py']
def test_prelim_opts_handles_empty(application): def test_prelim_opts_handles_empty(application):
"""Verify empty argv lists are handled correctly.""" """Verify empty argv lists are handled correctly."""
irrelevant_args = ['myexe', '/path/to/foo'] irrelevant_args = ['myexe', '/path/to/foo']
with mock.patch.object(sys, 'argv', irrelevant_args): with mock.patch.object(sys, 'argv', irrelevant_args):
application.parse_preliminary_options_and_args([]) opts, args = application.parse_preliminary_options_and_args([])
assert application.prelim_args == [] assert args == []

View file

@ -1,4 +1,6 @@
"""Tests for Flake8's legacy API.""" """Tests for Flake8's legacy API."""
import argparse
import mock import mock
import pytest import pytest
@ -8,17 +10,26 @@ 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."""
prelim_opts = argparse.Namespace(
append_config=[],
config=None,
isolated=False,
output_file=None,
verbose=0,
)
mockedapp = mock.Mock() mockedapp = mock.Mock()
mockedapp.prelim_opts.verbose = 0 mockedapp.parse_preliminary_options_and_args.return_value = (
mockedapp.prelim_opts.output_file = None prelim_opts,
[],
)
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.parse_preliminary_options_and_args.assert_called_once_with([])
mockedapp.make_config_finder.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(None, False)
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([])
mockedapp.make_formatter.assert_called_once_with() mockedapp.make_formatter.assert_called_once_with()