diff options
| author | Ian Cordasco <graffatcolmingov@gmail.com> | 2016-02-14 13:41:33 -0600 |
|---|---|---|
| committer | Ian Cordasco <graffatcolmingov@gmail.com> | 2016-02-14 13:41:33 -0600 |
| commit | a8aac5609290764e4ec0fb667203c3b13d1ef673 (patch) | |
| tree | 6cbbd1a50b97172ecb65eccd63990c6fa27ab4ef | |
| parent | 388db0d8116d9a69ffb34ebc0766ac6468a02b42 (diff) | |
| download | flake8-bug/121.tar.gz | |
Update setuptools command option normalizationbug/121
We were very naively "normalizing" options parsed and provided by
setuptools. This updates our handling to store the Option instance
from optparse so we can inspect the type, action, and option name for
more intelligent option normalization.
Closes #121
| -rw-r--r-- | flake8/main.py | 6 | ||||
| -rw-r--r-- | flake8/tests/test_util.py | 114 | ||||
| -rw-r--r-- | flake8/util.py | 24 |
3 files changed, 93 insertions, 51 deletions
diff --git a/flake8/main.py b/flake8/main.py index 297618a..570b318 100644 --- a/flake8/main.py +++ b/flake8/main.py @@ -93,18 +93,18 @@ class Flake8Command(setuptools.Command): for opt in parser.option_list: cmd_name = opt._long_opts[0][2:] option_name = cmd_name.replace('-', '_') - self.option_to_cmds[option_name] = cmd_name + self.option_to_cmds[option_name] = opt setattr(self, option_name, None) def finalize_options(self): self.options_dict = {} - for (option_name, cmd_name) in self.option_to_cmds.items(): + for (option_name, opt) in self.option_to_cmds.items(): if option_name in ['help', 'verbose']: continue value = getattr(self, option_name) if value is None: continue - value = option_normalizer(value) + value = option_normalizer(value, opt, option_name) # Check if there's any values that need to be fixed. if option_name == "include" and isinstance(value, str): value = re.findall('[^,;\s]+', value) diff --git a/flake8/tests/test_util.py b/flake8/tests/test_util.py index 32a1d44..bfbc660 100644 --- a/flake8/tests/test_util.py +++ b/flake8/tests/test_util.py @@ -1,85 +1,119 @@ +import optparse import unittest from flake8.util import option_normalizer -class TestOptionSerializer(unittest.TestCase): +class TestOptionSerializerParsesTrue(unittest.TestCase): + + def setUp(self): + self.option = optparse.Option('--foo', action='store_true') + self.option_name = 'fake_option' def test_1_is_true(self): - option = option_normalizer('1') - self.assertTrue(option) + value = option_normalizer('1', self.option, self.option_name) + self.assertTrue(value) def test_T_is_true(self): - option = option_normalizer('T') - self.assertTrue(option) + value = option_normalizer('T', self.option, self.option_name) + self.assertTrue(value) def test_TRUE_is_true(self): - option = option_normalizer('TRUE') - self.assertTrue(option, True) + value = option_normalizer('TRUE', self.option, self.option_name) + self.assertTrue(value, True) def test_ON_is_true(self): - option = option_normalizer('ON') - self.assertTrue(option) + value = option_normalizer('ON', self.option, self.option_name) + self.assertTrue(value) def test_t_is_true(self): - option = option_normalizer('t') - self.assertTrue(option) + value = option_normalizer('t', self.option, self.option_name) + self.assertTrue(value) def test_true_is_true(self): - option = option_normalizer('true') - self.assertTrue(option) + value = option_normalizer('true', self.option, self.option_name) + self.assertTrue(value) def test_on_is_true(self): - option = option_normalizer('on') - self.assertTrue(option) + value = option_normalizer('on', self.option, self.option_name) + self.assertTrue(value) + + +class TestOptionSerializerParsesFalse(unittest.TestCase): + + def setUp(self): + self.option = optparse.Option('--foo', action='store_true') + self.option_name = 'fake_option' def test_0_is_false(self): - option = option_normalizer('0') - self.assertFalse(option) + value = option_normalizer('0', self.option, self.option_name) + self.assertFalse(value) def test_F_is_false(self): - option = option_normalizer('F') - self.assertFalse(option) + value = option_normalizer('F', self.option, self.option_name) + self.assertFalse(value) def test_FALSE_is_false(self): - option = option_normalizer('FALSE') - self.assertFalse(option) + value = option_normalizer('FALSE', self.option, self.option_name) + self.assertFalse(value) def test_OFF_is_false(self): - option = option_normalizer('OFF') - self.assertFalse(option) + value = option_normalizer('OFF', self.option, self.option_name) + self.assertFalse(value) def test_f_is_false(self): - option = option_normalizer('f') - self.assertFalse(option) + value = option_normalizer('f', self.option, self.option_name) + self.assertFalse(value) def test_false_is_false(self): - option = option_normalizer('false') - self.assertFalse(option) + value = option_normalizer('false', self.option, self.option_name) + self.assertFalse(value) def test_off_is_false(self): - option = option_normalizer('off') - self.assertFalse(option) + value = option_normalizer('off', self.option, self.option_name) + self.assertFalse(value) + - def test_parses_lists(self): - answer = ['F401', 'F402', 'F403', 'F404'] +class TestOptionSerializerParsesLists(unittest.TestCase): - option = option_normalizer('F401,F402,F403,F404') - self.assertEqual(option, answer) + def setUp(self): + self.option = optparse.Option('--select') + self.option_name = 'select' + self.answer = ['F401', 'F402', 'F403', 'F404'] - option = option_normalizer('F401 ,F402 ,F403 ,F404') - self.assertEqual(option, answer) + def test_parses_simple_comma_separated_lists(self): + value = option_normalizer('F401,F402,F403,F404', self.option, + self.option_name) + self.assertEqual(value, self.answer) - option = option_normalizer('F401, F402, F403, F404') - self.assertEqual(option, answer) + def test_parses_less_simple_comma_separated_lists(self): + value = option_normalizer('F401 ,F402 ,F403 ,F404', self.option, + self.option_name) + self.assertEqual(value, self.answer) - option = option_normalizer('''\ + value = option_normalizer('F401, F402, F403, F404', self.option, + self.option_name) + self.assertEqual(value, self.answer) + + def test_parses_comma_separated_lists_with_newlines(self): + value = option_normalizer('''\ F401, F402, F403, F404, - ''') - self.assertEqual(option, answer) + ''', self.option, self.option_name) + self.assertEqual(value, self.answer) + + +class TestOptionSerializerParsesInts(unittest.TestCase): + + def setUp(self): + self.option = optparse.Option('--max-complexity', type='int') + self.option_name = 'max_complexity' + + def test_parses_an_int(self): + value = option_normalizer('2', self.option, self.option_name) + self.assertEqual(value, 2) if __name__ == '__main__': diff --git a/flake8/util.py b/flake8/util.py index da33f42..4e2c0d3 100644 --- a/flake8/util.py +++ b/flake8/util.py @@ -57,13 +57,21 @@ def force_disable_jobs(styleguide): return is_windows() or is_using_stdin(styleguide.paths) -def option_normalizer(value): - if str(value).upper() in ('1', 'T', 'TRUE', 'ON'): - value = True - if str(value).upper() in ('0', 'F', 'FALSE', 'OFF'): - value = False - - if isinstance(value, str): - value = [opt.strip() for opt in value.split(',') if opt.strip()] +INT_TYPES = ('int', 'count') +BOOL_TYPES = ('store_true', 'store_false') +LIST_OPTIONS = ('select', 'ignore', 'exclude', 'enable_extensions') + + +def option_normalizer(value, option, option_name): + if option.action in BOOL_TYPES: + if str(value).upper() in ('1', 'T', 'TRUE', 'ON'): + value = True + if str(value).upper() in ('0', 'F', 'FALSE', 'OFF'): + value = False + elif option.type in INT_TYPES: + value = int(value) + elif option_name in LIST_OPTIONS: + if isinstance(value, str): + value = [opt.strip() for opt in value.split(',') if opt.strip()] return value |
