Search code examples
pythonvisual-studio-codepycharmintellisense

How to enable IDE IntelliSense with dynamic imported python classes?


I have thousands of models in my package, each of them contains one class. Users can choose model they want to use by:

from myproject.type1.models.m1 import m1

Very inconvenient.

The subfolder looks like:

type1/
├── __init__.py
├── constant.py
├── decorator.py
├── models
│   ├── m1.py
│   ├── m2.py
│   ├── m3.py
...
│   ├── m999.py

So I write a module loader to load module dynamic:

class ModelLoader:
    def __init__(self, model_path):
        self.model_path = model_path
        self.models = {}

    def __getattribute__(self, __name: str) -> Any:
        try:
            return super().__getattribute__(__name)
        except AttributeError:
            if __name not in self.models:
                try:
                    model_file = import_module(self.model_path + "." + __name)
                    model = getattr(model_file, __name)
                    self.models[__name] = model
                    return model
                except ModuleNotFoundError:
                    raise AttributeError(f"Model {__name} not found")
            else:
                return self.models[__name]

With this, user can load module by just:

models = ModelLoader(__name__.rsplit(".", 1)[0] + ".models")
m1 = models.m1
m2 = models.m2

But this cause a problem.

Vscode or pycharm can not provide IntelliSense for m1 if it is imported by ModelLoader.

Intellisense works:

enter image description here

not work:

enter image description here

How can I let IDE know class ModelLoader have a member m1 and is defined in myproject.type1.models.m1?


I do not import all module in my package's __init__ since it will harm user experience, it takes about 30s to import all models.


Solution

  • You can try and generate a .pyi file based on the type1 directory.

    Pylance can use that to feed its static code analysis.