This sounds interesting but I’m a bit afraid of the quantity of code needed.
I think some part of the analysis could be done by Python type checking like mypy if we extend it with plugins.
For example get_dynamic_class_hook could be used to provide the proper type to pool.get and get_customize_class_mro_hook to return the “inherited” classes to the partial class of a module. I think it will prevent all the complexity of analyzing the AST.
Now I guess the language server may be helpful for “non-code” analysis like the depends or missing required attributes. But this part I guess could be simpler.
For the patched trytond, I have the feeling that it should be possible to construct the result class without the need to call Pool.init but just by looping on the registered class and construct the requested one only for a specific sets of modules.
You can use the trytond.modules tools, no need to re-implement everything.
I do not think it is needed because fields are accessors so indeed Model.__getattr__ could be replaced by something like Model.load. Anyway the type checker should not care as long as it can guess the type of each field.
I personally do not care much about these parts because we (should) have tests for that.
I do not think we have such calls in standard modules. But I think it may be good to find a way to forbid it because there is no way to guarantee that an model will be setup before another.