Tryton Language Server

I spent a few days during the past year playing around with Pygls, and used some free time during holiday season to make a Language Server for Tryton

You can find it here.

It requires python 3.11 and a little patch on trytond to be able to get a useable Pool without a database, but it works and provides some features that I think are already useful:

  • depends / extras_depend -aware analysis
  • Detection of unknown attributes in python / view files when guessing the model is possible
  • Completion of fields / methods

Let me know what you think about this :slight_smile:

3 Likes

It looks great to me!

Although I use neovim, configuration of lspconfig did not work in my laptop (it seems I should upgrade nodejs…).

But we’ll try to take a look on how to configure it with VS Code which is what most of my collegues use.

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.

I agree, that’s a lot of code :frowning: . Unfortunately with this approach I do not see how it could be significantly reduced.

I did not spend a lot of time investigating this approach. It seemed to me that doing so would also need a lot of work to :

  • Reimplement the dependency resolution
  • Work-around the __getattr__ overrides
  • All the custom things of Tryton (like you said, depends, but also xml, completion, etc…).

We would still have to call the __setup__ / __post_setup__ (which may call Pool()) methods to have the final version of the models, so reusing init seemed simpler in the end.

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.