taurus-org / taurus

Moved to https://gitlab.com/taurus-org/taurus
http://taurus-scada.org
43 stars 46 forks source link

Lazy plugin import #1090

Closed stanislaw55 closed 4 years ago

stanislaw55 commented 4 years ago

Hi Taurus Community

This should close #944

How does it work: During import, fake LazyModule object is created and put into sys.modules with proper name (of the actual plugin module) and reference to entry point. When attribute not present in this fake module is requested, __getattr__ is invoked. It then loads actual module and replaces fake module with actual one in sys.modules. It is done that way to avoid problems that may or may not occur. This tricks just has to work once for each plugin module. After that, attribute from plugin module is returned. That way actual module is present in sys.modules even if requested attribute name is wrong or attribute is not present.

Tested with taurus_pyqtgraph under Python 2.7

cpascual commented 4 years ago

Ok. With the latest changes it looks good to me. Now I need to actually test it.

By the way: would it be possible for me to get write permission to modify this branch? I would like to add some unit tests and I would need to do it via PR to this branch, which is a bit cumbersome. Usually there is an option when creating a PR to allow the integrators to modify the PR branch (checked by default) which I find quite useful to simplify the review process.

stanislaw55 commented 4 years ago

Hi @cpascual About permission: I do not know why but there's no checkbox or any option for me to check for allowing modifications into PR source branch by upstream repo maintainers. I search whole organisation and repository settings and I could not find anything to make it work. I'm truly sorry for the inconvenience but I do not know where to look for enabling it.

cpascual commented 4 years ago

I used this for testing, with only one plugin (taurus_pyqtgraph)

from time import time

t1 = time()
import taurus.qt.qtgui
t2 = time()
from taurus.qt.qtgui import tpg
t3 = time()
a = tpg.TaurusPlot
t4 = time()

print("total=", t4-t1)
print("partial=", t2-t1, t3-t2, t4-t3)

Without lazy import:

MainThread     INFO     2020-05-07 17:07:04,028 TaurusRootLogger: Plugin "taurus_pyqtgraph" loaded as "taurus.qt.qtgui.tpg"
total= 0.9116969108581543
partial= 0.9116919040679932 4.291534423828125e-06 7.152557373046875e-07

With lazy import, the total amount of time is similar, but we see that the loading of the plugin got delayed (as intended):

MainThread     INFO     2020-05-07 17:07:58,242 TaurusRootLogger: Plugin "taurus_pyqtgraph" lazy-loaded as "taurus.qt.qtgui.tpg"
total= 0.9149420261383057
partial= 0.7525215148925781 5.9604644775390625e-06 0.16241455078125