mirror of
https://github.com/PyCQA/flake8.git
synced 2026-04-09 22:34:17 +00:00
Merge pull request #1579 from asottile/forbid-invalid-plugin-codes
forbid invalid plugin prefixes in plugin loading
This commit is contained in:
commit
7e1e8b34af
2 changed files with 71 additions and 0 deletions
|
|
@ -1,7 +1,9 @@
|
||||||
"""Functions related to finding and loading plugins."""
|
"""Functions related to finding and loading plugins."""
|
||||||
import configparser
|
import configparser
|
||||||
import inspect
|
import inspect
|
||||||
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
@ -20,6 +22,8 @@ from flake8.exceptions import FailedToLoadPlugin
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
VALID_CODE = re.compile("^[A-Z]{1,3}[0-9]{0,3}$", re.ASCII)
|
||||||
|
|
||||||
FLAKE8_GROUPS = frozenset(("flake8.extension", "flake8.report"))
|
FLAKE8_GROUPS = frozenset(("flake8.extension", "flake8.report"))
|
||||||
|
|
||||||
BANNED_PLUGINS = {
|
BANNED_PLUGINS = {
|
||||||
|
|
@ -328,6 +332,13 @@ def _classify_plugins(
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError(f"what plugin type? {loaded}")
|
raise NotImplementedError(f"what plugin type? {loaded}")
|
||||||
|
|
||||||
|
for loaded in itertools.chain(tree, logical_line, physical_line):
|
||||||
|
if not VALID_CODE.match(loaded.entry_name):
|
||||||
|
raise ExecutionError(
|
||||||
|
f"plugin code for `{loaded.display_name}` does not match "
|
||||||
|
f"{VALID_CODE.pattern}"
|
||||||
|
)
|
||||||
|
|
||||||
return Plugins(
|
return Plugins(
|
||||||
checkers=Checkers(
|
checkers=Checkers(
|
||||||
tree=tree,
|
tree=tree,
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,37 @@ def _loaded(plugin=None, obj=None, parameters=None):
|
||||||
return finder.LoadedPlugin(plugin, obj, parameters)
|
return finder.LoadedPlugin(plugin, obj, parameters)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"s",
|
||||||
|
(
|
||||||
|
"E",
|
||||||
|
"E1",
|
||||||
|
"E123",
|
||||||
|
"ABC",
|
||||||
|
"ABC1",
|
||||||
|
"ABC123",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
def test_valid_plugin_prefixes(s):
|
||||||
|
assert finder.VALID_CODE.match(s)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"s",
|
||||||
|
(
|
||||||
|
"",
|
||||||
|
"A1234",
|
||||||
|
"ABCD",
|
||||||
|
"abc",
|
||||||
|
"a-b",
|
||||||
|
"☃",
|
||||||
|
"A𝟗",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
def test_invalid_plugin_prefixes(s):
|
||||||
|
assert finder.VALID_CODE.match(s) is None
|
||||||
|
|
||||||
|
|
||||||
def test_loaded_plugin_entry_name_vs_display_name():
|
def test_loaded_plugin_entry_name_vs_display_name():
|
||||||
loaded = _loaded(_plugin(package="package-name", ep=_ep(name="Q")))
|
loaded = _loaded(_plugin(package="package-name", ep=_ep(name="Q")))
|
||||||
assert loaded.entry_name == "Q"
|
assert loaded.entry_name == "Q"
|
||||||
|
|
@ -761,6 +792,35 @@ def test_classify_plugins_enable_a_disabled_plugin():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_classify_plugins_does_not_error_on_reporter_prefix():
|
||||||
|
# these are ok, don't check their name
|
||||||
|
plugin = _plugin(ep=_ep(name="report-er", group="flake8.report"))
|
||||||
|
loaded = _loaded(plugin=plugin)
|
||||||
|
|
||||||
|
opts = finder.PluginOptions.blank()
|
||||||
|
classified = finder._classify_plugins([loaded], opts)
|
||||||
|
|
||||||
|
assert classified == finder.Plugins(
|
||||||
|
checkers=finder.Checkers([], [], []),
|
||||||
|
reporters={"report-er": loaded},
|
||||||
|
disabled=[],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_classify_plugins_errors_on_incorrect_checker_name():
|
||||||
|
plugin = _plugin(ep=_ep(name="INVALID", group="flake8.extension"))
|
||||||
|
loaded = _loaded(plugin=plugin, parameters={"tree": True})
|
||||||
|
|
||||||
|
with pytest.raises(ExecutionError) as excinfo:
|
||||||
|
finder._classify_plugins([loaded], finder.PluginOptions.blank())
|
||||||
|
|
||||||
|
(msg,) = excinfo.value.args
|
||||||
|
assert msg == (
|
||||||
|
"plugin code for `local[INVALID]` "
|
||||||
|
"does not match ^[A-Z]{1,3}[0-9]{0,3}$"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("reset_sys")
|
@pytest.mark.usefixtures("reset_sys")
|
||||||
def test_load_plugins():
|
def test_load_plugins():
|
||||||
plugin = _plugin(ep=_ep(value="aplugin:ExtensionTestPlugin2"))
|
plugin = _plugin(ep=_ep(value="aplugin:ExtensionTestPlugin2"))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue