Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Work out how to test ehrQL's autocomplete behaviour #2339

Open
evansd opened this issue Dec 23, 2024 · 0 comments
Open

Work out how to test ehrQL's autocomplete behaviour #2339

evansd opened this issue Dec 23, 2024 · 0 comments

Comments

@evansd
Copy link
Contributor

evansd commented Dec 23, 2024

The below PR significantly extends the constructs in ehrQL which can be autocompleted by VSCode in its default configuration:

It already contains a manual test file at tests/autocomplete/autocomplete_definition.py which can be loaded in VSCode to examine the completions offered.

It would be very helpful to find an approach for testing this in an automated way. There are two sorts of test we'd like to run:

  1. Confirm that the constructs we expect to autocomplete do in fact autocomplete. This will allows us to refactor things here with confidence.
  2. Enforce that if we add new constructs to the query language (types, method, whatever) we either add an autocomplete test for them (and therefore whatever is needed to make that test pass) or we explicitly exclude them from being covered for autocomplete purposes.

Note that our specific target here is autocomplete in VSCode using the Pylance extension. Hopefully, by using standard Python type annotations to do this, we will end up improving the situation for other Language Servers and editors. But we aren't specifically targeting those with this work.

Mypy is not currently an option

Given that we are using standard type annotations, my first thought was that maybe we can use mypy to inspect the inferred types.

pip install mypy==1.14.0
mypy tests/autocomplete/autocomplete_definition.py

However, this resulted in 92 errors:

tests/autocomplete/autocomplete_definition.py:16: error: No overload variant of "__get__" of "Series" matches argument types "None", "type[patients]"  [call-overload]
tests/autocomplete/autocomplete_definition.py:16: note: Possible overload variants:
tests/autocomplete/autocomplete_definition.py:16: note:     def __get__(self, instance: PatientFrame, owner: Any) -> DatePatientSeries
tests/autocomplete/autocomplete_definition.py:16: note:     def __get__(self, instance: EventFrame, owner: Any) -> DateEventSeries
...
tests/autocomplete/autocomplete_definition.py:35: error: Missing positional argument "self" in call to "exists_for_patient" of "BaseFrame"  [call-arg]
...

And adding reveal_type(patients) produced:

tests/autocomplete/autocomplete_definition.py:19: note: Revealed type is "def (qm_node: Any) -> ehrql.tables.core.patients"

Almost certainly this is because we rely heavily on the @table class decorator, and it turns out mypy doesn't currently support this:

Testing against a Language Server

Therefore, I think we'll need to test this by running a language server instance and asking that to give us its inferred types and completions. It wouldn't be impossible for us to learn to speak LSP ourselves (it's just JSON over a socket) but there seems to be a Python LSP client specifically designed for this sort of thing: https://github.com/microsoft/multilspy

The actual language server used by VSCode, Pylance, is proprietary (perhaps a reason to be distrustful of VSCode becoming "the default editor"). It's almost certainly possible to make it run as a standalone LSP, and it may even be within the license terms if it's just for the purpose of ensuring behaviour within VSCode. But it's not straightforward.

Fortunately the type checker that powers Pylance, pyright is open-source. This comes with a basic language server which hopefully gives us enough to work with.

I got as far as installing it and starting it up but didn't manage to get any information out of it:

pip install nodejs-wheel
NPM_CONFIG_PREFIX="$VIRTUAL_ENV" npm install -g pyright
pyright-langserver --stdio
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant