pylint-dev / pylint

It's not just a linter that annoys you!
https://pylint.readthedocs.io/en/latest/
GNU General Public License v2.0
5.24k stars 1.12k forks source link

pyreverse problem for classes diagrams generation #7977

Open cyrduf opened 1 year ago

cyrduf commented 1 year ago

Bug description

I checked 2 cases of class diagrams and one of the 2 does not work:

case 1:

PyModbus3 imports

from pymodbus.client.sync import ModbusTcpClient as ModbusClient

class MyClass:

def init(self, name_1: str, name_2: str ....): """My Class .. versionadded:: 0.1 """ self.client_1 = ModbusClient(address_1, port_1) self.client_2 = ModbusClient(address_2, port_2) self.clients = {name_1: self.client_1, name_2: self.client_2}

case 2:

PyModbus3 imports

from pymodbus.client.sync import ModbusTcpClient as ModbusClient

class MyClass:

def init(self, name_1: str, name_2: str ....): """My Class .. versionadded:: 0.1 """ self.clients = {name_1: ModbusClient(address_1, port_1), name_dnr: ModbusClient(address_2, port_2)}

In case1 the graph of classes is correct and pymodbus.client.sync.ModbusTcpClient is shown associated to MyClass for client_1 and client_2

In case2 the graph of classes is NOT correct and pymodbus.client.sync.ModbusTcpClient is not detected associated to MyClass

=> Is it possible that if external classes are used in dict, the tool pyreverse is not detecting links ? => How to have these kind of links in diagrams ?

Configuration

No specific configuration

Command used

pyreverse -o svg -a2 -s2 -fALL -my -p MyClass MyClass

Pylint output

Given in description

Expected behavior

Given in description

Pylint version

pylint==2.15.9
python 3.8.12

OS / Environment

Linux Centos 7.9

Additional dependencies

pymodbus==2.5.3 pyModbusTCP==0.1.10

cyrduf commented 1 year ago

I checked another case of class diagrams that does not work: using @classmethod

PyModbus3 imports from pymodbus.client.sync import ModbusTcpClient as ModbusClient

class MyClass:

client_1 = None
client_2 = None

@classmethod
def run(cls, name_1: str, name_2: str ....):
"""My Class
.. versionadded:: 0.1
"""
    cls.client_1 = ModbusClient(address_1, port_1)
    cls.client_2 = ModbusClient(address_2, port_2)

In this case the graph of classes is NOT correct and pymodbus.client.sync.ModbusTcpClient is not detected associated to MyClass, as for the case2.

nickdrozd commented 11 months ago

Simple reproducer:

class A:
    pass

class B:
    def __init__(self):
        self.x = A()

class C:
    def __init__(self):
        self.x = {1: A()}

Pyreverse shows that A is associated to B. But it doesn't show that A is associated to C because it doesn't look inside C's dictionary.

Related to https://github.com/pylint-dev/pylint/issues/6737