Dynamic class methods code completion

I have a context class, which is something like a state object for multiple API clients.

I’ll provide a simplified example of it:

class Context:
    def api_client1(self) -> APIClient1:
         return APIClient1(self)

    def api_client2(self) -> APIClient2:
        return APIClient2(self)

Now I want to dynamically add more API clients which can register via entry points.

I do something like this:

for name,client_class in clients_from_entrypoints():
    setattr(Context, name, lambda self: client_class(self))

This works absolutely fine, but it doesn’t have code completion.

For example:

c = Context()
c.<TAB>

Will only show api_client1 and api_client2, but not these that were added through entry points.

Is it even remotely possible to have code completion for it? Or are there better ways to do this with more discoverability?

It depends on how an editor’s completion mechanism works. IDLE gets completions from a live objects. This is a bit awkward since too many people will not read the doc that tells them this, but it will do what you want if you know. In particular, suppose you edit a file that defines or imports Context, sets more attributes as you describe, and creates an instance. Run the file. Then instance completion will show the added attributes, both in Shell and the editor. (No is needed if you wait the user-configered time, which I set to be very short.) I tested this with a simplified example.

Thanks for the reply, and yes, sorry, should’ve mentioned it. It works in IDLE, but this is not the place where these API clients will be primarily be used.

These API clients will be used to create other applications/services, so the autocompletion will need to happen in an IDE like VS Code, PyCharm et al.

But it seems like they only check the AST (at least what I saw in the codebase of jedi and rope), which can’t evaluate the entry points.

I guess there is no way (even a tiny possibility) to make it discoverable, right?

IDLE is the only IDE I use (and help maintain).