diff --git a/src/flake8/main/application.py b/src/flake8/main/application.py index c7a9741..febe6c7 100644 --- a/src/flake8/main/application.py +++ b/src/flake8/main/application.py @@ -68,7 +68,7 @@ class Application(object): except ValueError: pass - preliminary_opts, _ = self.option_manager.parse_args(args) + 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) diff --git a/src/flake8/options/manager.py b/src/flake8/options/manager.py index f9d9e26..58d8b2d 100644 --- a/src/flake8/options/manager.py +++ b/src/flake8/options/manager.py @@ -261,15 +261,49 @@ class OptionManager(object): plugin_version_format ) + def _normalize(self, options): + for option in self.options: + old_value = getattr(options, option.dest) + setattr(options, option.dest, option.normalize(old_value)) + def parse_args(self, args=None, values=None): """Simple proxy to calling the OptionParser's parse_args method.""" self.generate_epilog() self.update_version_string() options, xargs = self.parser.parse_args(args, values) - for option in self.options: - old_value = getattr(options, option.dest) - setattr(options, option.dest, option.normalize(old_value)) + self._normalize(options) + return options, xargs + def parse_known_args(self, args=None, values=None): + """Parse only the known arguments from the argument values. + + Replicate a little argparse behaviour while we're still on + optparse. + """ + self.generate_epilog() + self.update_version_string() + # Taken from optparse.OptionParser.parse_args + rargs = self.parser._get_args(args) + if values is None: + values = self.parser.get_default_values() + + self.parser.rargs = rargs + self.parser.largs = largs = [] + self.parser.values = values + + while rargs: + # NOTE(sigmavirus24): If we only care about *known* options, then + # we should just shift the bad option over to the largs list and + # carry on. + # Unfortunately, we need to rely on a private method here. + try: + self.parser._process_args(largs, rargs, values) + except (optparse.BadOptionError, optparse.OptionValueError) as err: + self.parser.largs.append(err.opt_str) + + args = largs + rargs + options, xargs = self.parser.check_values(values, args) + self._normalize(options) return options, xargs def register_plugin(self, name, version): diff --git a/tests/unit/test_option_manager.py b/tests/unit/test_option_manager.py index 6f6cb17..661b445 100644 --- a/tests/unit/test_option_manager.py +++ b/tests/unit/test_option_manager.py @@ -2,6 +2,7 @@ import optparse import os +import mock import pytest from flake8 import utils @@ -194,3 +195,11 @@ def test_extend_default_ignore(optmanager): assert optmanager.extended_default_ignore == set(['T100', 'T101', 'T102']) + + +def test_parse_known_args(optmanager): + """Verify we ignore unknown options.""" + with mock.patch('sys.exit') as sysexit: + optmanager.parse_known_args(['--max-complexity', '5']) + + assert sysexit.called is False