Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Permit to disable cyclic-import when importing inside a function #850

Closed
pde opened this issue Mar 15, 2016 · 13 comments
Closed

Permit to disable cyclic-import when importing inside a function #850

pde opened this issue Mar 15, 2016 · 13 comments
Labels
Bug 🪲 Hacktoberfest Help wanted 🙏 Outside help would be appreciated, good for new contributors High priority Issue with more than 10 reactions Needs specification 🔐 Accepted as a potential improvement, and needs to specify edge cases, message names, etc.

Comments

@pde
Copy link

pde commented Mar 15, 2016

If two modules import from each other, but one of them only imports the other within functions and other non-global scopes, Python is happy. But pylint still errors on such cyclic imports, and in fact won't accept a module-scoped disable directive, so cyclic import detection has to be disabled for the entire project.

Here's an example from this PR: certbot/certbot#2649 :

git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
git checkout split-cli
vim .pylintrc # remove the disable cyclic-import
tools/venv.sh
venv/bin/pylint --rcfile=.pylintrc letsencrypt/cli.py letsencrypt/main.py
************* Module letsencrypt.main
R:  1, 0: Cyclic import (letsencrypt.cli -> letsencrypt.main) (cyclic-import)
...
@The-Compiler
Copy link
Contributor

I think the checker itself is working as intended - cyclic imports can be problematic even when they don't break right away (like when using from-imports instead, or on older Python versions - for example, 3.5 can handle some cyclic imports 3.4 can't).

That being said, I disabled it myself too because it was too noisy. Then again, it only complaining when Python complains anyways would be somewhat pointless.

Maybe as a middle ground, cyclic-import shouldn't get emitted when an import is inside a function, as then clearly the developer is aware they're working around a circular import? Let's see what @PCManticore thinks.

@PCManticore
Copy link
Contributor

I think it makes sense not to emit the error in case one of the imports is inside a function scope, as @The-Compiler already said. Sometimes getting rid of cyclic imports is impossible, requiring redesigning the entire project (as we already have this problem in astroid for example). That being said, I'll probably work on a patch in this weekend, if no one else wants to do it.

@sthenault
Copy link
Contributor

IMHO we should always warn about cyclic import and let the user explicitly
deactivate it rather than adding a specific rule.
Le 18 mars 2016 12:47, "Claudiu Popa" notifications@github.com a écrit :

I think it makes sense not to emit the error in case one of the imports is
inside a function scope, as @The-Compiler
https://github.com/The-Compiler already said. Sometimes getting rid of
cyclic imports is impossible, requiring redesigning the entire project (as
we already have this problem in astroid for example). That being said, I'll
probably work on a patch in this weekend, if no one else wants to do it.


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
#850 (comment)

@PCManticore
Copy link
Contributor

True, but at least they should have some control over disabling the error in a more granular way. My initial thought is to have a flag that can control if the users want to not warn about cyclic-import if one of the imports is protected by a function scope, defaulting to false, so with the same behaviour as now.

@sthenault
Copy link
Contributor

another idea would be that "# disable: cyclic-import" would make the
matched imports unconsidered the cycle computation, breaking cycle if any.

On Fri, Mar 18, 2016 at 7:13 PM, Claudiu Popa notifications@github.com
wrote:

True, but at least they should have some control over disabling the error
in a more granular way. My initial thought is to have a flag that can
control if the users want to not warn about cyclic-import if one of the
imports is protected by a function scope, defaulting to false, so with the
same behaviour as now.


You are receiving this because you commented.
Reply to this email directly or view it on GitHub
#850 (comment)

Sylvain

@rogalski
Copy link
Contributor

Discussion looks like a duplicate of #59, with exception of function-scope imports.

@actionless
Copy link

mb it could be two different warnings, cyclic-import and cyclic-import-from-function ?

@ParasJain-dev
Copy link

ParasJain-dev commented Dec 28, 2020

@PCManticore Is this issue fixed?
We are still getting this issue in pylint==1.9.*

@Pierre-Sassoulas Pierre-Sassoulas changed the title Pylint detects imaginary cyclic imports Permit to disable cyclic-import when importing inside a function Aug 4, 2021
@Pierre-Sassoulas Pierre-Sassoulas added the Help wanted 🙏 Outside help would be appreciated, good for new contributors label Aug 4, 2021
@Pierre-Sassoulas Pierre-Sassoulas added the Needs specification 🔐 Accepted as a potential improvement, and needs to specify edge cases, message names, etc. label Jul 4, 2022
@Pierre-Sassoulas
Copy link
Member

I think the suggestion from sthenault to break cycle on # pylint: disable=cyclic-import is elegant and probably the right way to do this.

hussainweb added a commit to axelerant/axl-template that referenced this issue Oct 24, 2022
Fixing this would require a restructure and there is no simple way to workaround the error, even though this seems to be a legitimate use case of a cyclic import. I found some discussion in an open issue related to this at pylint-dev/pylint#850.
@Pierre-Sassoulas Pierre-Sassoulas added the High priority Issue with more than 10 reactions label Nov 19, 2022
@clavedeluna
Copy link
Collaborator

I think the suggestion from sthenault to break cycle on # pylint: disable=cyclic-import is elegant and probably the right way to do this.

@Pierre-Sassoulas I think I can try to work on this but I don't think I understand this implementation suggestion. What does it mean to break cycle in this context? Maybe a test case would help.

@Pierre-Sassoulas
Copy link
Member

In the algorithm to detect cyclic import we follow the "cycle" of import (https://github.com/PyCQA/pylint/blob/2ae0e98454c28e2aaf1c892655f34eb8d19772d7/pylint/graph.py#L181), if at some point an import is done in a context where cyclic-import is disabled, then we should not take this import into account in the algorithm. We'll need to be able to tell that cyclic import is disabled in a context, which might not be easy (the right place is probably when we generate the graph itself in https://github.com/PyCQA/pylint/blob/2ae0e98454c28e2aaf1c892655f34eb8d19772d7/pylint/checkers/imports.py#L476).

@clavedeluna
Copy link
Collaborator

clavedeluna commented Dec 23, 2022

I'm trying to come up with a test case but I think the local disabling is actually working as intended? Try this:

a.py

from b import bye

def hello():
    print("hello")

b.py

def bye():
    print("bye")
    from a import hello

pylint a.py b.py

....
b.py:1:0: R0401: Cyclic import (a -> b) (cyclic-import)

if b.py is updated to

def bye():
    print("bye")
    from a import hello  # pylint: disable=cyclic-import

The cyclic-import warning is gone, which is what we want? Can someone confirm I didn't incorrectly do this? @Pierre-Sassoulas any thoughts?

@jacobtylerwalls
Copy link
Member

Yes, getting function level disables to work for cyclic-import was fixed in pylint 1.7 in 2017, see #59.

#6983 (marked as dupe) also discusses whether to enable disabling cyclic-import at the module level, but since that's not discussed on this thread, I think we should close as completed.

jpivarski added a commit to scikit-hep/ragged that referenced this issue Dec 30, 2023
jpivarski added a commit to scikit-hep/ragged that referenced this issue Dec 30, 2023
* feat: elementwise functions (mappers)

* abs

* acos, acosh

* Give up on versioned submodules; it makes typing difficult.

* Give up on versioned submodules; it makes typing difficult.

* Give up on versioned submodules; it makes typing difficult.

* Also checking function values.

* atan, atan2, atanh, bitwise_and, bitwise_invert

* bitwise_shift_left, bitwise_or, bitwise_shift_right, bitwise_xor, ceil

* Use 'numpy.array_api' to test these functions.

* conj, cos, cosh, divide, equal

* exp, expm1, floor, floor_divide

* greater, greater_equal, imag

* isfinite, isinf, isnan, less, less_equal, log, log1p, log2, log10, logaddexp, logical_and, logical_not, logical_or, logical_xor

* multiply, negative, not_equal, positive, pow, real, remainder, round

* sign, sin, sinh, square, sqrt, subtract, tan, tanh, trunc; finished all of the free elementwise functions

* Implemented all elementwise dunder methods on 'array', too.

* pylint in CI is tripping up on pylint-dev/pylint#850.

* Also test all of the in-place dunder methods.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug 🪲 Hacktoberfest Help wanted 🙏 Outside help would be appreciated, good for new contributors High priority Issue with more than 10 reactions Needs specification 🔐 Accepted as a potential improvement, and needs to specify edge cases, message names, etc.
Projects
None yet
Development

No branches or pull requests

10 participants