diff options
author | Andrew Haigh <hello@nelf.in> | 2021-09-25 02:02:12 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-24 18:02:12 +0200 |
commit | 087d77adcd8455dbbbf6b43631d93abb2d1c5d67 (patch) | |
tree | b98590d67b25c2db9bcfc29a4fe3ea7964b7bb6b /tests/regrtest_data | |
parent | 5124f5409f9d3e540318ece0f7899da4bf04dad2 (diff) | |
download | pylint-git-087d77adcd8455dbbbf6b43631d93abb2d1c5d67.tar.gz |
Fix loop in too-many-ancestors when an inheritance cycle is inferred (#5062)
* Add regression test for #4972 hang
* Fix loop in too-many-ancestors when an inheritance cycle is inferred
Ref #4972. If a class could be inferred as an ancestor of itself then
the implementation of _get_parents could get caught in an infinite loop,
forever adding itself to to_explore. This could be possible by
monkeypatching an ancestor after class definition like in the following
simplified example:
class Fake(module.Cls):
pass
module.Cls = Fake
Reproducing this is fairly tricky, but this integration test shows the
behaviour as of 1e675abcc2aa931421d7ce300908e734a93fd790:
#!/bin/sh
HERE=$(readlink -f .)
VENV=$HERE/venv-repro
PIP=$VENV/bin/pip
python -m venv "$VENV"
PYLINT=$VENV/bin/pylint
# assume running in pylint dir
$PIP install -e .
$PIP install flask
mkdir -p repro/flask/
touch repro/__init__.py
cat > repro/flask/__init__.py <<'EOF'
import flask
import repro.flask # self-import necessary
class Fake(flask.Flask):
pass
flask.Flask = Fake
EOF
echo +++ this is fine
$PYLINT --rcfile=/dev/null -- repro/flask/
echo +++ finished
echo +++ this loops forever
cd repro/; $PYLINT --rcfile=/dev/null -- flask/
echo +++ should not reach here
Diffstat (limited to 'tests/regrtest_data')
-rw-r--r-- | tests/regrtest_data/hang/pkg4972/__init__.py | 0 | ||||
-rw-r--r-- | tests/regrtest_data/hang/pkg4972/string/__init__.py | 7 |
2 files changed, 7 insertions, 0 deletions
diff --git a/tests/regrtest_data/hang/pkg4972/__init__.py b/tests/regrtest_data/hang/pkg4972/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/regrtest_data/hang/pkg4972/__init__.py diff --git a/tests/regrtest_data/hang/pkg4972/string/__init__.py b/tests/regrtest_data/hang/pkg4972/string/__init__.py new file mode 100644 index 000000000..4a77f25ac --- /dev/null +++ b/tests/regrtest_data/hang/pkg4972/string/__init__.py @@ -0,0 +1,7 @@ +import string +import pkg4972.string # self-import necessary + +class Fake(string.Formatter): + pass + +string.Formatter = Fake |