Recent ENBs have discussed two implicit graphs of import dependencies. Leo's fast pylint project, #3852, will likely sidestep such issues.
However, I laboriously calculated Leo's startup dependencies by hand. I'll present them here.
The level of a Leo file is:
- zero if the file imports no other Leo files.
- one more than the maximum level of all the Leo files otherwise.
Core files
Level 0: no imports at the top level.
leo.core.leoApp
leo.core.leoBridge
leo.core.leoColor
leo.core.leoFastRedraw
leo.core.leoGlobals
leo.core.leoImport
leo.core.leoPymacs
leo.core.leoQt
leo.core.leoTokens
leo.core.leoVersion
leo.core.signal_manager
leo.core.tracing_utils
Level 1: import only leoGlobals at the top level.
leo.core.leoAst
leo.core.leoCache
leo.core.leoChapters
leo.core.leoCompare
leo.core.leoDebugger
leo.core.leoExternalFiles
leo.core.leoFind
leo.core.leoHistory
leo.core.leoIPython
leo.core.leoKeys
leo.core.leoMarkup
leo.core.leoMenu
leo.core.leoNodes
leo.core.leoPersistence
leo.core.leoPlugins
leo.core.leoRope
leo.core.leoRst
leo.core.leoSessions
leo.core.leoShadow
leo.core.leoTips
leo.core.leoVim
Level 1: import only level 0 modules at the top level.
leo.core.leoBackground
from leo.core import leoGlobals as g
from leo.core.leoQt import QtCore
leo.core.leoColorizer
from leo.core import leoGlobals as g
from leo.core.leoColor import leo_color_database
from leo.core.leoQt import ...
leo.plugins.modScripting
from leo.core import leoGlobals as g
from leo.core import leoColor
from leo.core import leoGui
leo.core.leoPrinting
from leo.core import leoGlobals as g
from leo.core.leoQt import ...
leo.core.leoTest2
from leo.core import leoGlobals as g
from leo.core import leoApp
leo.core.runLeo
from leo.core import leoGlobals as g
from leo.core import leoApp
Level 2: import only level 0 or 1 modules at the top level.
leo.core.leoAtFile
from leo.core import leoGlobals as g
from leo.core import leoNodes
leo.core.leoBeautify
from leo.core import leoGlobals as g
from leo.core import leoAst
leo.core.leoCommands: # ctor instantiates all sub-commanders!
from leo.core import leoGlobals as g
from leo.core import leoNodes
leo.core.leoConfig
from leo.core import leoGlobals as g
from leo.plugins.mod_scripting import build_rclick_tree
leo.core.leoFileCommands
from leo.core import leoGlobals as g
from leo.core import leoNodes
Level 3: import only modules of levels 0, 1, or 2 at the top level.
leo.core.leoFrame
from leo.core import leoGlobals as g
from leo.core import leoColorizer
from leo.core import leoMenu
from leo.core import leoNodes
leo.core.leoserver
from leo.core.leoCommands import Commands as Cmdr
from leo.core.leoNodes import Position, VNode
from leo.core.leoGui import StringFindTabManager
from leo.core.leoExternalFiles import ExternalFilesController
leo.core.leoUndo
from leo.core import leoGlobals as g
from leo.core.leoFileCommands import FastRead
from leo.core.leoNodes import Position, VNode
Level 4: import only modules of levels 0, 1, 2, or 3 at the top level.
leo.core.leoGui
from leo.core import leoGlobals as g
from leo.core import leoFrame
leo.core.leoclient
from leo.core import leoGlobals as g
from leo.core import leoserver
Command files
Level 1: import only leoGlobals at the top level.
leo.commands.baseCommands
leo.commands.checkerCommands
leo.commands.editCommands
leo.commands.commanderHelpCommands
leo.commands.gotoCommands
Level 1: import only level 0 modules at the top level.
leo.commands.commanderFileCommands
from leo.core import leoGlobals as g
from leo.core import leoImport
Level 2: import only leoGlobals and leo.commands.baseCommands
leo.commands.bufferCommands
leo.commands.controlCommands
leo.commands.debugCommands
leo.commands.editCommands
leo.commands.helpCommands
leo.commands.keyCommands
leo.commands.killBufferCommands
leo.commands.rectangleCommands
leo.commands.spellCommands
Level 2: import only level 0 or 1 modules at the top level.
leo.commands.abbrevCommands
from leo.core import leoGlobals as g
from leo.core import leoNodes
from leo.commands.baseCommands import BaseEditCommandsClass
leo.commands.commanderOutlineCommands
from leo.core import leoGlobals as g
from leo.core import leoNodes
from leo.core import leoFileCommands
Level 3: import only modules of levels 0, 1, or 2 at the top level.
leo.commands.convertCommands
from leo.core import leoGlobals as g
from leo.core import leoBeautify
from leo.commands.baseCommands import BaseEditCommandsClass
leo.commands.editFileCommands
from leo.core import leoGlobals as g
from leo.core import leoCommands
from leo.commands.baseCommands import BaseEditCommandsClass
Summary
The tables above implicitly reveal Leo's import order during startup. Leo's Commands class imports all of Leo's sub-commanders when Leo creates the first commander.
Deferring the imports of sub-commanders breaks all potential circular imports. Devs should be aware of this design. It hasn't changed in decades.
Edward