First time here? Check out the FAQ!
1

Autocompletion on classes with __getattr__

Hi! I would like to improve the autocompletion support for one of my libraries with type annotations.

The library is a database wrapper. For each table there is a dataset class in Python and the dataset instances allow to access the column values via __getattr__.

For autocompletion in the debugger, Wing is calling __dir__() and __getattr__(), but that does obviously work only for instances.

When I add a type annotation to a method, it seems that Wing does only autocomplete the attribute and method names that are available from static source code analysis. Is there a way to tell Wing which dynamic attributes a class will have and maybe even their data types?

Dietmar Schwertberger's avatar
11
Dietmar Schwertberger
asked 2024-07-18 14:43:57 -0600
edit flag offensive 0 remove flag close merge delete

Comments

add a comment see more comments

1 Answer

1

One approach is always to run to a breakpoint with the results you expect and then write / edit code. Unit tests can be a good way to quickly and repeatedly run the debugger to a certain point.

If you want to use type hints to inform Wing's static analyzer what the attributes are, you probably need to define new classes. For example, if the generic results retrieval looks something like (note that this is made-up, untested code) --

class Results:
  def getsourcefilename(self) -> str:
    ...

def getresults(filename) -> Results:
  ...

And your results have a name and an address fields, you could do something like:

class MyResults(Results):
  name: str
  address: str

def dosomething(filename: str) -> MyResults:
  results: MyResults
  results = getresults(filename)

  ... # Do something with results

The above should be enough for Wing to add the attributes to the autocomplete popup, but the MyResults class won't be used at runtime and other type checkers (mypy, pytype, ....) will probably complain about it. This might be better (though the details probably depend on the library that you use) --

def dosomething(filename: str) -> MyResults:
  results: MyResults
  results = getresults(filename) # type: ignore
  results.__class__ = MyResults # type: ignore

  ... # Do something with results
Wingware Support's avatar
4.2k
Wingware Support
answered 2024-07-19 11:33:37 -0600
edit flag offensive 0 remove flag delete link

Comments

Thanks. I think I will write a script that modifies the library to add annotated properties. It's not really dynamic, but good enough as the databases don't change that often.

Dietmar Schwertberger's avatar Dietmar Schwertberger (2024-07-20 08:32:36 -0600) edit
add a comment see more comments

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account. This space is reserved only for answers. If you would like to engage in a discussion, please instead post a comment under the question or an answer that you would like to discuss.

Add Answer