pydeps icon indicating copy to clipboard operation
pydeps copied to clipboard

false detection of cyclic dependencies when using mypy

Open kurtgn opened this issue 6 years ago • 3 comments

Hi, first of all - thanks for the awesome tool, I've been looking for something like that for a while!

Now - a suggestion: we use this tool mostly when debugging circular dependencies in a huge project. However we also use mypy on the project, and the mypy way of typing looks like this:



# special system variable that evaluates to True only when typechecking
from typing import TYPE_CHECKING  
if TYPE_CHECKING: 
    from some_module import SomeModel

def function(model: 'SomeModel'):
    print(model.whatever)
  

So there you have it, a dependency used only for type checking that can be detected as a circular dependency (hence the if TYPE_CHECKING condition to make this work in regular Python).

So, is there a way to ignore such dependencies while building the dependency graph?

So far my only idea is to manually remove these import strings using a custom script, feed the code to pydeps and then bring the imports back :)

kurtgn avatar Feb 19 '19 10:02 kurtgn

You can globally remove the dependency on the command line by adding -x some_module or you can add it to a .pydeps file at the root of your project (check pydeps' own .pydeps file for syntax: https://github.com/thebjorn/pydeps/blob/master/.pydeps).

There is currently no way to only ignore some_module, but only for filename foo.py.

You can export the dependency graph as json with the --show-deps flag (it's a very simple format and it should be much easier to work with than removing/adding types to the source files), but there is unfortunately not a way to give a json dependency graph to pydeps for display..

thebjorn avatar Feb 19 '19 15:02 thebjorn

@thebjorn I think in cases where the imports under if TYPE_CHECKING are of the same package that we are trying to check, excluding it doesn't work. Is there any way to have pydeps not take into account imports under if TYPE_CHECKING?

skroth avatar Mar 15 '23 22:03 skroth

@skroth pydeps (and Python's modulefinder) doesn't do any semantic analysis, i.e. it only scans the .pyc files for opcodes related to imports, so unfortunately there is no way to check if-opcodes when they are generated(*).

(*) in Python I'm only aware of one case where the if is eliminated by the optimizer, and that is if <boolean-constant>:. This is py3+ only, since True and False became real constants in the language. Maybe that can solve your question (see https://discuss.python.org/t/moving-type-checking-out-of-typing-and-into-the-built-in-namespace/7870)

thebjorn avatar Mar 16 '23 10:03 thebjorn