Merge branch 'output_file_fix' into 'master'

Fix --output-file regression

Closes #637

See merge request pycqa/flake8!426
This commit is contained in:
Anthony Sottile 2020-05-12 01:34:47 +00:00
commit 88fab04d0b
5 changed files with 29 additions and 25 deletions

View file

@ -29,7 +29,7 @@ def get_style_guide(**kwargs):
:class:`StyleGuide` :class:`StyleGuide`
""" """
application = app.Application() application = app.Application()
prelim_opts, remaining_args = application.parse_preliminary_options([]) prelim_opts = application.parse_preliminary_options([])
flake8.configure_logging(prelim_opts.verbose, prelim_opts.output_file) flake8.configure_logging(prelim_opts.verbose, prelim_opts.output_file)
config_finder = config.ConfigFileFinder( config_finder = config.ConfigFileFinder(
application.program, application.program,
@ -40,9 +40,7 @@ def get_style_guide(**kwargs):
application.find_plugins(config_finder) application.find_plugins(config_finder)
application.register_plugin_options() application.register_plugin_options()
application.parse_configuration_and_cli( application.parse_configuration_and_cli(config_finder, [])
config_finder, remaining_args,
)
# We basically want application.initialize to be called but with these # We basically want application.initialize to be called but with these
# options set instead before we make our formatter, notifier, internal # options set instead before we make our formatter, notifier, internal
# style guide and file checker manager. # style guide and file checker manager.

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, Tuple from typing import Dict, List, Optional, Set
import flake8 import flake8
from flake8 import checker from flake8 import checker
@ -95,7 +95,7 @@ class Application(object):
self.parsed_diff = {} # type: Dict[str, Set[int]] self.parsed_diff = {} # type: Dict[str, Set[int]]
def parse_preliminary_options(self, argv): def parse_preliminary_options(self, argv):
# type: (List[str]) -> Tuple[argparse.Namespace, List[str]] # type: (List[str]) -> argparse.Namespace
"""Get preliminary options from the CLI, pre-plugin-loading. """Get preliminary options from the CLI, pre-plugin-loading.
We need to know the values of a few standard options so that we can We need to know the values of a few standard options so that we can
@ -112,7 +112,7 @@ class Application(object):
:rtype: :rtype:
(argparse.Namespace, list) (argparse.Namespace, list)
""" """
return self.prelim_arg_parser.parse_known_args(argv) return self.prelim_arg_parser.parse_known_args(argv)[0]
def exit(self): def exit(self):
# type: () -> None # type: () -> None
@ -312,7 +312,7 @@ 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.
prelim_opts, remaining_args = self.parse_preliminary_options(argv) prelim_opts = self.parse_preliminary_options(argv)
flake8.configure_logging(prelim_opts.verbose, prelim_opts.output_file) flake8.configure_logging(prelim_opts.verbose, prelim_opts.output_file)
config_finder = config.ConfigFileFinder( config_finder = config.ConfigFileFinder(
self.program, self.program,
@ -322,9 +322,7 @@ class Application(object):
) )
self.find_plugins(config_finder) self.find_plugins(config_finder)
self.register_plugin_options() self.register_plugin_options()
self.parse_configuration_and_cli( self.parse_configuration_and_cli(config_finder, argv)
config_finder, remaining_args,
)
self.make_formatter() self.make_formatter()
self.make_guide() self.make_guide()
self.make_file_checker_manager() self.make_file_checker_manager()

View file

@ -246,3 +246,17 @@ def test_file_not_found(tmpdir, capsys):
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert out.startswith("i-do-not-exist:0:1: E902") assert out.startswith("i-do-not-exist:0:1: E902")
assert err == "" assert err == ""
def test_output_file(tmpdir, capsys):
"""Ensure that --output-file is honored."""
tmpdir.join('t.py').write('import os\n')
with tmpdir.as_cwd():
_call_main(['t.py', '--output-file=f'], retv=1)
out, err = capsys.readouterr()
assert out == err == ""
expected = "t.py:1:1: F401 'os' imported but unused\n"
assert tmpdir.join('f').read() == expected

View file

@ -79,28 +79,22 @@ 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."""
opts, args = application.parse_preliminary_options( opts = application.parse_preliminary_options(
['--foo', '--verbose', 'src', 'setup.py', '--statistics', '--version']) ['--foo', '--verbose', 'src', 'setup.py', '--statistics', '--version'])
assert opts.verbose assert opts.verbose
assert args == ['--foo', 'src', 'setup.py', '--statistics', '--version']
def test_prelim_opts_ignore_help(application): def test_prelim_opts_ignore_help(application):
"""Verify -h/--help is not handled.""" """Verify -h/--help is not handled."""
# GIVEN # normally argparse would `SystemExit` on `--help`
application.parse_preliminary_options(['--help', '-h'])
# WHEN
_, args = application.parse_preliminary_options(['--help', '-h'])
# THEN
assert args == ['--help', '-h']
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'] # this would set `.verbose` but we validate that it does not
irrelevant_args = ['--verbose']
with mock.patch.object(sys, 'argv', irrelevant_args): with mock.patch.object(sys, 'argv', irrelevant_args):
opts, args = application.parse_preliminary_options([]) opts = application.parse_preliminary_options([])
assert not opts.verbose
assert args == []

View file

@ -19,7 +19,7 @@ def test_get_style_guide():
verbose=0, verbose=0,
) )
mockedapp = mock.Mock() mockedapp = mock.Mock()
mockedapp.parse_preliminary_options.return_value = (prelim_opts, []) mockedapp.parse_preliminary_options.return_value = prelim_opts
mockedapp.program = 'flake8' mockedapp.program = 'flake8'
with mock.patch('flake8.api.legacy.config.ConfigFileFinder') as mock_config_finder: # noqa: E501 with mock.patch('flake8.api.legacy.config.ConfigFileFinder') as mock_config_finder: # noqa: E501
config_finder = ConfigFileFinder(mockedapp.program) config_finder = ConfigFileFinder(mockedapp.program)