Skip to content

Commit fce93b9

Browse files
committed
prevent duplicate plugin discovery on misconfigured pythons
for example, `venv`-virtualenvs on fedora have both `lib` and `lib64` on `sys.path` despite them being the same. this causes `importlib.metadata.distributions` to double-discover. ```console $ docker run --rm -t fedora:latest bash -c 'dnf install -qq -y python3 >& /dev/null && python3 -m venv venv && venv/bin/pip -qq install cfgv && venv/bin/python - <<< "from importlib.metadata import distributions; print(len([d for d in distributions() if d.name == '"'"'cfgv'"'"']))"' 2 ```
1 parent 3f4872a commit fce93b9

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

src/flake8/plugins/finder.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ def _flake8_plugins(
179179

180180

181181
def _find_importlib_plugins() -> Generator[Plugin, None, None]:
182+
# some misconfigured pythons (RHEL) have things on `sys.path` twice
183+
seen = set()
182184
for dist in importlib_metadata.distributions():
183185
# assigned to prevent continual reparsing
184186
eps = dist.entry_points
@@ -190,6 +192,11 @@ def _find_importlib_plugins() -> Generator[Plugin, None, None]:
190192
# assigned to prevent continual reparsing
191193
meta = dist.metadata
192194

195+
if meta["name"] in seen:
196+
continue
197+
else:
198+
seen.add(meta["name"])
199+
193200
if meta["name"] in BANNED_PLUGINS:
194201
LOG.warning(
195202
"%s plugin is obsolete in flake8>=%s",

tests/unit/plugins/finder_test.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,23 @@ def test_importlib_plugins(
361361
]
362362

363363

364+
def test_duplicate_dists(flake8_dist):
365+
# some poorly packaged pythons put lib and lib64 on sys.path resulting in
366+
# duplicates from `importlib.metadata.distributions`
367+
with mock.patch.object(
368+
importlib_metadata,
369+
"distributions",
370+
return_value=[
371+
flake8_dist,
372+
flake8_dist,
373+
],
374+
):
375+
ret = list(finder._find_importlib_plugins())
376+
377+
# we should not have duplicates
378+
assert len(ret) == len(set(ret))
379+
380+
364381
def test_find_local_plugins_nothing():
365382
cfg = configparser.RawConfigParser()
366383
assert set(finder._find_local_plugins(cfg)) == set()

0 commit comments

Comments
 (0)