Open
Description
Bug description
The code is given in this repository.
The detection root cause is the Step
class definition. However, since we import the class first in the package's __init__.py
file, the import is not circular by Python's rules.
We found 2 ways to solve it.
- Reasonable solution - instead of import the base class from the package level, import directly from the containing module.
- Unclear solution - adding
__init__.py
at the repository root level. Not sure why this makes the issue disappear.
To summarize - there are 2 related issues here:
- The circular dependency detection is not accurate. Demonstrated by
make test
. - One of the mitigations to the issue is unexpected (if the issue is real, I wouldn't expect adding that file will resolve it).
To reproduce the issue and show the 2 resolutions work, simply run make verify_resolutions
in the repository.
Configuration
No response
Command used
pylint --recursive=y --disable=W,C0114,C0115,C0116,R0903 -s=n .
Pylint output
************* Module module1.derived
module1/derived.py:1:0: R0401: Cyclic import (module1 -> module1.derived) (cyclic-import)
Expected behavior
- Probably shouldn't identify as circular
- If identified as circular, unclear why adding
__init__.py
at the repository root make the issue disappear.
Pylint version
pylint 3.0.1
astroid 3.0.1
Python 3.11.6 (main, Oct 3 2023, 03:39:03) [GCC 10.2.1 20210110]
OS / Environment
Mac and Linux (both in a docker and in the host)
Additional dependencies
No response
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
Pierre-Sassoulas commentedon Oct 22, 2023
Thank you for the reproducer, it's hard to do anything with circular import otherwise :) my intuition would be something linked to import order (maybe similar to #6535?), but this definitely need investigations.
🚨(backend) fix pylint cyclic imports false positive
guyarad commentedon Oct 23, 2023
@Pierre-Sassoulas I'm not sure it's directly related.
pylint
is correct in the sense derived module is importing the base class from the__init__
file. And the init file also imports the derived class. But it works in runtime, because the base class import in the init file is before the derived import. The issue you linked seems to be misidentification of packages.Just to clarify, I don't especially mind that
pylint
identifies this as a circular, because as I mentioned, it technically is. The fact something works fine in runtime doesn't mean we have to produce code like that :)The point here is that adding an empty
__init__.py
file in the repository root solves - and that is really odd, and inconsistent. And that bothers me.Pierre-Sassoulas commentedon Oct 23, 2023
Ha, my bad, it's working as intended then. (Similar to #9124). Still need to fix the inconsistencies though.
guyarad commentedon Oct 30, 2023
@Pierre-Sassoulas from Python's perspective it's legal. So it should be ok. Anyway, I'm more bothered with the inconsistency of the detection and its resolution.