Fix bug for plugins using extend_default_ignore

Since Flake8 3.0 we've had the ability for plugins to use
`extend_default_ignore` to register codes they want disabled by default.
This, however, was a permanent disabling unfortunately. Our code didn't
have a way of understanding that this new set of `ignore` codes was
actually the 'default' set for that run. Much like the
extended_select_list, we now attach extended_ignore_list to be able to
confidently determine if the ignore we get in the DecisionEngine is
actually the Default Ignore list and what plugins what us to ignore by
default.

Refs https://github.com/PyCQA/pep8-naming/pull/157
This commit is contained in:
Ian Stapleton Cordasco 2021-04-15 09:12:25 -05:00
parent 992bb77d22
commit 2bb0308363
No known key found for this signature in database
GPG key ID: 656D3395E4A9791A
4 changed files with 405 additions and 177 deletions

View file

@ -48,6 +48,10 @@ def aggregate_options(
# Extend the default ignore value with the extended default ignore list,
# registered by plugins.
extended_default_ignore = manager.extended_default_ignore.copy()
# Let's store our extended default ignore for use by the decision engine
default_values.extended_default_ignore = (
manager.extended_default_ignore.copy()
)
LOG.debug(
"Extended default ignore list: %s", list(extended_default_ignore)
)

View file

@ -177,7 +177,9 @@ class DecisionEngine:
reverse=True,
)
)
self.using_default_ignore = set(self.ignored) == set(defaults.IGNORE)
self.using_default_ignore = set(self.ignored) == set(
defaults.IGNORE
).union(options.extended_default_ignore)
self.using_default_select = set(self.selected) == set(defaults.SELECT)
def _in_all_selected(self, code: str) -> bool:

View file

@ -9,72 +9,86 @@ from flake8 import style_guide
def create_options(**kwargs):
"""Create and return an instance of argparse.Namespace."""
kwargs.setdefault('select', [])
kwargs.setdefault('extended_default_select', [])
kwargs.setdefault('extend_select', [])
kwargs.setdefault('ignore', [])
kwargs.setdefault('extend_ignore', [])
kwargs.setdefault('disable_noqa', False)
kwargs.setdefault('enable_extensions', [])
kwargs.setdefault("select", [])
kwargs.setdefault("extended_default_ignore", [])
kwargs.setdefault("extended_default_select", [])
kwargs.setdefault("extend_select", [])
kwargs.setdefault("ignore", [])
kwargs.setdefault("extend_ignore", [])
kwargs.setdefault("disable_noqa", False)
kwargs.setdefault("enable_extensions", [])
return argparse.Namespace(**kwargs)
@pytest.mark.parametrize('ignore_list,extend_ignore,error_code', [
(['E111', 'E121'], [], 'E111'),
(['E111', 'E121'], [], 'E121'),
(['E111'], ['E121'], 'E121'),
(['E11', 'E12'], [], 'E121'),
(['E2', 'E12'], [], 'E121'),
(['E2', 'E12'], [], 'E211'),
(['E2', 'E3'], ['E12'], 'E211'),
])
@pytest.mark.parametrize(
"ignore_list,extend_ignore,error_code",
[
(["E111", "E121"], [], "E111"),
(["E111", "E121"], [], "E121"),
(["E111"], ["E121"], "E121"),
(["E11", "E12"], [], "E121"),
(["E2", "E12"], [], "E121"),
(["E2", "E12"], [], "E211"),
(["E2", "E3"], ["E12"], "E211"),
],
)
def test_was_ignored_ignores_errors(ignore_list, extend_ignore, error_code):
"""Verify we detect users explicitly ignoring an error."""
decider = style_guide.DecisionEngine(
create_options(ignore=ignore_list, extend_ignore=extend_ignore))
create_options(ignore=ignore_list, extend_ignore=extend_ignore)
)
assert decider.was_ignored(error_code) is style_guide.Ignored.Explicitly
@pytest.mark.parametrize('ignore_list,extend_ignore,error_code', [
(['E111', 'E121'], [], 'E112'),
(['E111', 'E121'], [], 'E122'),
(['E11', 'E12'], ['E121'], 'W121'),
(['E2', 'E12'], [], 'E112'),
(['E2', 'E12'], [], 'E111'),
(['E2', 'E12'], ['W11', 'E3'], 'E111'),
])
def test_was_ignored_implicitly_selects_errors(ignore_list, extend_ignore,
error_code):
@pytest.mark.parametrize(
"ignore_list,extend_ignore,error_code",
[
(["E111", "E121"], [], "E112"),
(["E111", "E121"], [], "E122"),
(["E11", "E12"], ["E121"], "W121"),
(["E2", "E12"], [], "E112"),
(["E2", "E12"], [], "E111"),
(["E2", "E12"], ["W11", "E3"], "E111"),
],
)
def test_was_ignored_implicitly_selects_errors(
ignore_list, extend_ignore, error_code
):
"""Verify we detect users does not explicitly ignore an error."""
decider = style_guide.DecisionEngine(
create_options(ignore=ignore_list, extend_ignore=extend_ignore))
create_options(ignore=ignore_list, extend_ignore=extend_ignore)
)
assert decider.was_ignored(error_code) is style_guide.Selected.Implicitly
@pytest.mark.parametrize(
'select_list,extend_select,enable_extensions,error_code', [
(['E111', 'E121'], [], [], 'E111'),
(['E111', 'E121'], [], [], 'E121'),
(['E11', 'E12'], [], [], 'E121'),
(['E2', 'E12'], [], [], 'E121'),
(['E2', 'E12'], [], [], 'E211'),
(['E1'], ['E2'], [], 'E211'),
(['E1'], [], ['E2'], 'E211'),
([], ['E2'], [], 'E211'),
([], [], ['E2'], 'E211'),
(['E1'], ['E2'], [], 'E211'),
(['E111'], ['E121'], ['E2'], 'E121'),
]
"select_list,extend_select,enable_extensions,error_code",
[
(["E111", "E121"], [], [], "E111"),
(["E111", "E121"], [], [], "E121"),
(["E11", "E12"], [], [], "E121"),
(["E2", "E12"], [], [], "E121"),
(["E2", "E12"], [], [], "E211"),
(["E1"], ["E2"], [], "E211"),
(["E1"], [], ["E2"], "E211"),
([], ["E2"], [], "E211"),
([], [], ["E2"], "E211"),
(["E1"], ["E2"], [], "E211"),
(["E111"], ["E121"], ["E2"], "E121"),
],
)
def test_was_selected_selects_errors(select_list, extend_select,
enable_extensions, error_code):
def test_was_selected_selects_errors(
select_list, extend_select, enable_extensions, error_code
):
"""Verify we detect users explicitly selecting an error."""
decider = style_guide.DecisionEngine(
options=create_options(select=select_list,
extend_select=extend_select,
enable_extensions=enable_extensions),
options=create_options(
select=select_list,
extend_select=extend_select,
enable_extensions=enable_extensions,
),
)
assert decider.was_selected(error_code) is style_guide.Selected.Explicitly
@ -82,24 +96,27 @@ def test_was_selected_selects_errors(select_list, extend_select,
def test_was_selected_implicitly_selects_errors():
"""Verify we detect users implicitly selecting an error."""
error_code = 'E121'
error_code = "E121"
decider = style_guide.DecisionEngine(
create_options(
select=[],
extended_default_select=['E'],
extended_default_select=["E"],
),
)
assert decider.was_selected(error_code) is style_guide.Selected.Implicitly
@pytest.mark.parametrize('select_list,error_code', [
(['E111', 'E121'], 'E112'),
(['E111', 'E121'], 'E122'),
(['E11', 'E12'], 'E132'),
(['E2', 'E12'], 'E321'),
(['E2', 'E12'], 'E410'),
])
@pytest.mark.parametrize(
"select_list,error_code",
[
(["E111", "E121"], "E112"),
(["E111", "E121"], "E122"),
(["E11", "E12"], "E132"),
(["E2", "E12"], "E321"),
(["E2", "E12"], "E410"),
],
)
def test_was_selected_excludes_errors(select_list, error_code):
"""Verify we detect users implicitly excludes an error."""
decider = style_guide.DecisionEngine(create_options(select=select_list))
@ -108,100 +125,285 @@ def test_was_selected_excludes_errors(select_list, error_code):
@pytest.mark.parametrize(
'select_list,ignore_list,extend_ignore,error_code,expected', [
(['E111', 'E121'], [], [], 'E111', style_guide.Decision.Selected),
(['E111', 'E121'], [], [], 'E112', style_guide.Decision.Ignored),
(['E111', 'E121'], [], [], 'E121', style_guide.Decision.Selected),
(['E111', 'E121'], [], [], 'E122', style_guide.Decision.Ignored),
(['E11', 'E12'], [], [], 'E132', style_guide.Decision.Ignored),
(['E2', 'E12'], [], [], 'E321', style_guide.Decision.Ignored),
(['E2', 'E12'], [], [], 'E410', style_guide.Decision.Ignored),
(['E11', 'E121'], ['E1'], [], 'E112', style_guide.Decision.Selected),
(['E11', 'E121'], [], ['E1'], 'E112', style_guide.Decision.Selected),
(['E111', 'E121'], ['E2'], ['E3'], 'E122',
style_guide.Decision.Ignored),
(['E11', 'E12'], ['E13'], [], 'E132', style_guide.Decision.Ignored),
(['E1', 'E3'], ['E32'], [], 'E321', style_guide.Decision.Ignored),
([], ['E2', 'E12'], [], 'E410', style_guide.Decision.Ignored),
(['E4'], ['E2', 'E12', 'E41'], [], 'E410',
style_guide.Decision.Ignored),
(['E41'], ['E2', 'E12', 'E4'], [], 'E410',
style_guide.Decision.Selected),
(['E'], ['F'], [], 'E410', style_guide.Decision.Selected),
(['F'], [], [], 'E410', style_guide.Decision.Ignored),
(['E'], defaults.IGNORE, [], 'E126', style_guide.Decision.Selected),
(['W'], defaults.IGNORE, [], 'E126', style_guide.Decision.Ignored),
(['E'], defaults.IGNORE, [], 'W391', style_guide.Decision.Ignored),
(['E', 'W'], ['E13'], [], 'E131', style_guide.Decision.Ignored),
(defaults.SELECT, ['E13'], [], 'E131', style_guide.Decision.Ignored),
(defaults.SELECT, defaults.IGNORE, ['W391'], 'E126',
style_guide.Decision.Ignored),
(defaults.SELECT, defaults.IGNORE, [], 'W391',
style_guide.Decision.Selected),
]
"select_list,ignore_list,extend_ignore,error_code,expected",
[
(["E111", "E121"], [], [], "E111", style_guide.Decision.Selected),
(["E111", "E121"], [], [], "E112", style_guide.Decision.Ignored),
(["E111", "E121"], [], [], "E121", style_guide.Decision.Selected),
(["E111", "E121"], [], [], "E122", style_guide.Decision.Ignored),
(["E11", "E12"], [], [], "E132", style_guide.Decision.Ignored),
(["E2", "E12"], [], [], "E321", style_guide.Decision.Ignored),
(["E2", "E12"], [], [], "E410", style_guide.Decision.Ignored),
(["E11", "E121"], ["E1"], [], "E112", style_guide.Decision.Selected),
(["E11", "E121"], [], ["E1"], "E112", style_guide.Decision.Selected),
(
["E111", "E121"],
["E2"],
["E3"],
"E122",
style_guide.Decision.Ignored,
),
(["E11", "E12"], ["E13"], [], "E132", style_guide.Decision.Ignored),
(["E1", "E3"], ["E32"], [], "E321", style_guide.Decision.Ignored),
([], ["E2", "E12"], [], "E410", style_guide.Decision.Ignored),
(
["E4"],
["E2", "E12", "E41"],
[],
"E410",
style_guide.Decision.Ignored,
),
(
["E41"],
["E2", "E12", "E4"],
[],
"E410",
style_guide.Decision.Selected,
),
(["E"], ["F"], [], "E410", style_guide.Decision.Selected),
(["F"], [], [], "E410", style_guide.Decision.Ignored),
(["E"], defaults.IGNORE, [], "E126", style_guide.Decision.Selected),
(["W"], defaults.IGNORE, [], "E126", style_guide.Decision.Ignored),
(["E"], defaults.IGNORE, [], "W391", style_guide.Decision.Ignored),
(["E", "W"], ["E13"], [], "E131", style_guide.Decision.Ignored),
(defaults.SELECT, ["E13"], [], "E131", style_guide.Decision.Ignored),
(
defaults.SELECT,
defaults.IGNORE,
["W391"],
"E126",
style_guide.Decision.Ignored,
),
(
defaults.SELECT,
defaults.IGNORE,
[],
"W391",
style_guide.Decision.Selected,
),
],
)
def test_decision_for(select_list, ignore_list, extend_ignore, error_code,
expected):
def test_decision_for(
select_list, ignore_list, extend_ignore, error_code, expected
):
"""Verify we decide when to report an error."""
decider = style_guide.DecisionEngine(
create_options(select=select_list,
ignore=ignore_list,
extend_ignore=extend_ignore))
create_options(
select=select_list,
ignore=ignore_list,
extend_ignore=extend_ignore,
)
)
assert decider.decision_for(error_code) is expected
@pytest.mark.parametrize(
'select,ignore,extended_default_select,'
'enabled_extensions,error_code,expected', [
(defaults.SELECT, [], ['I1'], [], 'I100',
style_guide.Decision.Selected),
(defaults.SELECT, [], ['I1'], [], 'I201',
style_guide.Decision.Ignored),
(defaults.SELECT, ['I2'], ['I1'], [], 'I101',
style_guide.Decision.Selected),
(defaults.SELECT, ['I2'], ['I1'], [], 'I201',
style_guide.Decision.Ignored),
(defaults.SELECT, ['I1'], ['I10'], [], 'I101',
style_guide.Decision.Selected),
(defaults.SELECT, ['I10'], ['I1'], [], 'I101',
style_guide.Decision.Ignored),
(defaults.SELECT, [], [], ['U4'], 'U401',
style_guide.Decision.Selected),
(defaults.SELECT, ['U401'], [], ['U4'], 'U401',
style_guide.Decision.Ignored),
(defaults.SELECT, ['U401'], [], ['U4'], 'U402',
style_guide.Decision.Selected),
(['E', 'W'], ['E13'], [], [], 'E131', style_guide.Decision.Ignored),
(['E', 'W'], ['E13'], [], [], 'E126', style_guide.Decision.Selected),
(['E2'], ['E21'], [], [], 'E221', style_guide.Decision.Selected),
(['E2'], ['E21'], [], [], 'E212', style_guide.Decision.Ignored),
(['F', 'W'], ['C90'], ['I1'], [], 'C901',
style_guide.Decision.Ignored),
(['E', 'W'], ['C'], [], [], 'E131',
style_guide.Decision.Selected),
(defaults.SELECT, defaults.IGNORE, [], ['I'], 'I101',
style_guide.Decision.Selected),
(defaults.SELECT, defaults.IGNORE, ['G'], ['I'], 'G101',
style_guide.Decision.Selected),
(defaults.SELECT, ['G1'], ['G'], ['I'], 'G101',
style_guide.Decision.Ignored),
(defaults.SELECT, ['E126'], [], ['I'], 'I101',
style_guide.Decision.Selected),
(['E', 'W'], defaults.IGNORE, ['I'], [], 'I101',
style_guide.Decision.Ignored),
"select,ignore,extended_default_ignore,extended_default_select,"
"enabled_extensions,error_code,expected",
[
(
defaults.SELECT,
[],
[],
["I1"],
[],
"I100",
style_guide.Decision.Selected,
),
(
defaults.SELECT,
[],
[],
["I1"],
[],
"I201",
style_guide.Decision.Ignored,
),
(
defaults.SELECT,
["I2"],
[],
["I1"],
[],
"I101",
style_guide.Decision.Selected,
),
(
defaults.SELECT,
["I2"],
[],
["I1"],
[],
"I201",
style_guide.Decision.Ignored,
),
(
defaults.SELECT,
["I1"],
[],
["I10"],
[],
"I101",
style_guide.Decision.Selected,
),
(
defaults.SELECT,
["I10"],
[],
["I1"],
[],
"I101",
style_guide.Decision.Ignored,
),
(
defaults.SELECT,
[],
[],
[],
["U4"],
"U401",
style_guide.Decision.Selected,
),
(
defaults.SELECT,
["U401"],
[],
[],
["U4"],
"U401",
style_guide.Decision.Ignored,
),
(
defaults.SELECT,
["U401"],
[],
[],
["U4"],
"U402",
style_guide.Decision.Selected,
),
(
["E", "W"],
["E13"],
[],
[],
[],
"E131",
style_guide.Decision.Ignored,
),
(
["E", "W"],
["E13"],
[],
[],
[],
"E126",
style_guide.Decision.Selected,
),
(["E2"], ["E21"], [], [], [], "E221", style_guide.Decision.Selected),
(["E2"], ["E21"], [], [], [], "E212", style_guide.Decision.Ignored),
(
["F", "W"],
["C90"],
[],
["I1"],
[],
"C901",
style_guide.Decision.Ignored,
),
(
["E", "W"],
["C"],
[],
[],
[],
"E131",
style_guide.Decision.Selected,
),
(
defaults.SELECT,
defaults.IGNORE,
[],
[],
["I"],
"I101",
style_guide.Decision.Selected,
),
(
defaults.SELECT,
defaults.IGNORE,
[],
["G"],
["I"],
"G101",
style_guide.Decision.Selected,
),
(
defaults.SELECT,
["G1"],
[],
["G"],
["I"],
"G101",
style_guide.Decision.Ignored,
),
(
defaults.SELECT,
["E126"],
[],
[],
["I"],
"I101",
style_guide.Decision.Selected,
),
(
["E", "W"],
defaults.IGNORE,
[],
["I"],
[],
"I101",
style_guide.Decision.Ignored,
),
(
["E", "W", "I101"],
defaults.IGNORE + ("I101",),
["I101"],
[],
[],
"I101",
style_guide.Decision.Selected,
),
(
["E", "W"],
defaults.IGNORE + ("I101",),
["I101"],
[],
[],
"I101",
style_guide.Decision.Ignored,
),
# TODO(sigmavirus24) Figure out how to exercise the final catch-all
# return statement
]
],
)
def test_more_specific_decision_for_logic(
select, ignore, extended_default_select,
enabled_extensions, error_code, expected):
select,
ignore,
extended_default_ignore,
extended_default_select,
enabled_extensions,
error_code,
expected,
):
"""Verify the logic of DecisionEngine.more_specific_decision_for."""
decider = style_guide.DecisionEngine(
create_options(
select=select, ignore=ignore,
select=select,
ignore=ignore,
extended_default_select=extended_default_select,
extended_default_ignore=extended_default_ignore,
enable_extensions=enabled_extensions,
),
)

View file

@ -12,14 +12,15 @@ from flake8.formatting import base
def create_options(**kwargs):
"""Create and return an instance of argparse.Namespace."""
kwargs.setdefault('select', [])
kwargs.setdefault('extended_default_select', [])
kwargs.setdefault('extend_select', [])
kwargs.setdefault('ignore', [])
kwargs.setdefault('extend_ignore', [])
kwargs.setdefault('disable_noqa', False)
kwargs.setdefault('enable_extensions', [])
kwargs.setdefault('per_file_ignores', [])
kwargs.setdefault("select", [])
kwargs.setdefault("extended_default_select", [])
kwargs.setdefault("extended_default_ignore", [])
kwargs.setdefault("extend_select", [])
kwargs.setdefault("ignore", [])
kwargs.setdefault("extend_ignore", [])
kwargs.setdefault("disable_noqa", False)
kwargs.setdefault("enable_extensions", [])
kwargs.setdefault("per_file_ignores", [])
return argparse.Namespace(**kwargs)
@ -27,13 +28,13 @@ def test_handle_error_does_not_raise_type_errors():
"""Verify that we handle our inputs better."""
formatter = mock.create_autospec(base.BaseFormatter, instance=True)
guide = style_guide.StyleGuide(
create_options(select=['T111'], ignore=[]),
create_options(select=["T111"], ignore=[]),
formatter=formatter,
stats=statistics.Statistics(),
)
assert 1 == guide.handle_error(
'T111', 'file.py', 1, None, 'error found', 'a = 1'
"T111", "file.py", 1, None, "error found", "a = 1"
)
@ -54,13 +55,16 @@ PER_FILE_IGNORES_UNPARSED = [
]
@pytest.mark.parametrize('style_guide_file,filename,expected', [
("first_file.py", "first_file.py", True),
("first_file.py", "second_file.py", False),
("sub_dir/*.py", "first_file.py", False),
("sub_dir/*.py", "sub_dir/file.py", True),
("sub_dir/*.py", "other_dir/file.py", False),
])
@pytest.mark.parametrize(
"style_guide_file,filename,expected",
[
("first_file.py", "first_file.py", True),
("first_file.py", "second_file.py", False),
("sub_dir/*.py", "first_file.py", False),
("sub_dir/*.py", "sub_dir/file.py", True),
("sub_dir/*.py", "other_dir/file.py", False),
],
)
def test_style_guide_applies_to(style_guide_file, filename, expected):
"""Verify that we match a file to its style guide."""
formatter = mock.create_autospec(base.BaseFormatter, instance=True)
@ -69,7 +73,8 @@ def test_style_guide_applies_to(style_guide_file, filename, expected):
options,
formatter=formatter,
stats=statistics.Statistics(),
filename=style_guide_file)
filename=style_guide_file,
)
assert guide.applies_to(filename) is expected
@ -80,41 +85,56 @@ def test_style_guide_manager_pre_file_ignores_parsing():
guide = style_guide.StyleGuideManager(options, formatter=formatter)
assert len(guide.style_guides) == 5
expected = [
utils.normalize_path(p) for p in [
"first_file.py", "second_file.py", "third_file.py", "sub_dir/*",
utils.normalize_path(p)
for p in [
"first_file.py",
"second_file.py",
"third_file.py",
"sub_dir/*",
]
]
assert expected == [g.filename for g in guide.style_guides[1:]]
@pytest.mark.parametrize('ignores,violation,filename,handle_error_return', [
(['E1', 'E2'], 'F401', 'first_file.py', 1),
(['E1', 'E2'], 'E121', 'first_file.py', 0),
(['E1', 'E2'], 'F401', 'second_file.py', 0),
(['E1', 'E2'], 'F401', 'third_file.py', 1),
(['E1', 'E2'], 'E311', 'third_file.py', 0),
(['E1', 'E2'], 'F401', 'sub_dir/file.py', 0),
])
def test_style_guide_manager_pre_file_ignores(ignores, violation, filename,
handle_error_return):
@pytest.mark.parametrize(
"ignores,violation,filename,handle_error_return",
[
(["E1", "E2"], "F401", "first_file.py", 1),
(["E1", "E2"], "E121", "first_file.py", 0),
(["E1", "E2"], "F401", "second_file.py", 0),
(["E1", "E2"], "F401", "third_file.py", 1),
(["E1", "E2"], "E311", "third_file.py", 0),
(["E1", "E2"], "F401", "sub_dir/file.py", 0),
],
)
def test_style_guide_manager_pre_file_ignores(
ignores, violation, filename, handle_error_return
):
"""Verify how the StyleGuideManager creates a default style guide."""
formatter = mock.create_autospec(base.BaseFormatter, instance=True)
options = create_options(ignore=ignores,
select=['E', 'F', 'W'],
per_file_ignores=PER_FILE_IGNORES_UNPARSED)
options = create_options(
ignore=ignores,
select=["E", "F", "W"],
per_file_ignores=PER_FILE_IGNORES_UNPARSED,
)
guide = style_guide.StyleGuideManager(options, formatter=formatter)
assert (guide.handle_error(violation, filename, 1, 1, "Fake text")
== handle_error_return)
assert (
guide.handle_error(violation, filename, 1, 1, "Fake text")
== handle_error_return
)
@pytest.mark.parametrize('filename,expected', [
('first_file.py', utils.normalize_path('first_file.py')),
('second_file.py', utils.normalize_path('second_file.py')),
('third_file.py', utils.normalize_path('third_file.py')),
('fourth_file.py', None),
('sub_dir/__init__.py', utils.normalize_path('sub_dir/*')),
('other_dir/__init__.py', None),
])
@pytest.mark.parametrize(
"filename,expected",
[
("first_file.py", utils.normalize_path("first_file.py")),
("second_file.py", utils.normalize_path("second_file.py")),
("third_file.py", utils.normalize_path("third_file.py")),
("fourth_file.py", None),
("sub_dir/__init__.py", utils.normalize_path("sub_dir/*")),
("other_dir/__init__.py", None),
],
)
def test_style_guide_manager_style_guide_for(filename, expected):
"""Verify the style guide selection function."""
formatter = mock.create_autospec(base.BaseFormatter, instance=True)