-
Notifications
You must be signed in to change notification settings - Fork 125
test: Extend the type checking of the ops-scenario tests #2235
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
base: main
Are you sure you want to change the base?
test: Extend the type checking of the ops-scenario tests #2235
Conversation
The class variable gets adjusted in the ruff fixes PR, but we can handle the merge conflict later.
The type: ignore should be able to go away when the storage class gets annotations, which is in another PR in this series. We can handle the merge then.
The class vars are being adjusted in another PR. We can handle the merge later.
The storage type ignore we should be able to remove after the other PRs are merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR extends type checking coverage to the ops-scenario test suite by adding type annotations to half of the test_e2e test files and configuring pyright to check them. The remaining files are explicitly excluded until a follow-up PR.
Key Changes
- Added type annotations to test functions, fixtures, and event handlers across 9 test files
- Updated pyright configuration to include testing/tests directory while excluding files not yet annotated
- Added necessary type narrowing assertions where types could be None
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| pyproject.toml | Added testing/tests to pyright includes and specified exclusions for unannotated files |
| test_storage.py | Added type annotations to fixtures and test functions; added type ignore comments for filesystem operations |
| test_status.py | Added EventBase import and return type annotations for all event handlers and test functions |
| test_secrets.py | Added comprehensive type annotations including Literal types for owner parameters and type narrowing assertions |
| test_rubbish_events.py | Added ClassVar annotations for class attributes and type annotations for test functions |
| test_relations.py | Moved StateValidationError import to errors module; added type annotations and cast operations for dynamic types |
| test_ports.py | Moved StateValidationError import to errors module; added return type annotations |
| test_pebble.py | Added TYPE_CHECKING block for LayerDict/ServiceDict; corrected period/timeout to string format; added type annotations throughout |
| test_manager.py | Moved AlreadyEmittedError import to errors module; added type annotations for fixtures and tests |
| test_juju_log.py | Added type annotations to fixtures and test functions |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Thanks for doing these. Out of interest, did you use a tool to help automate these? |
Not an agent, but I did use the tab-completion functionality in VS Code a reasonable amount. I find it's particularly useful when what you're doing is very repetitive like this was. Not sure if you remember or not, but I tried getting Copilot to do this work in the Gothenburg workshop (and then over the following days) and it did a terrible job. I still feel that an agent ought to be able to do this and that I probably just needed a different prompt or configuration, but I wasn't willing to spend more time on that with this ticket. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Yeah, I did remember. I was more curious about whether you'd used a mechanical tool like https://github.com/orsinium-labs/infer-types (have no idea whether it works or is any good). |
Ah, interesting. I wasn't aware of such tools, otherwise I probably would have given one a go :) |
| def mycharm(): | ||
| class MyCharm(CharmBase): | ||
| META = {'name': 'mycharm'} | ||
| META: dict[str, Any] = {'name': 'mycharm'} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the type annotations on the META and ACTIONS attributes get us anything right now tbh. Though why aren't we getting complaints about mutable class attributes needing ClassVar? If we do annotate these it should probably be Mapping[str, Any]. And we should investigate why we're not getting the ClassVar complaint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kind of superseded by lifting these to the top-level if we can do that, see other comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the ClassVar bit comes from ruff, not from pyright. There's overlap here with #2228
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah maybe that's where all the deja vu is coming from. Could we perhaps merge #2228 before working further on these then?
|
|
||
|
|
||
| def test_manager(mycharm): | ||
| def test_manager(mycharm: Any) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WDYT about lifting MyCharm and its META and ACTIONS attributes to the top-level like we did for canonical/grafana-agent-operator#355?
I guess this PR will need the -> None annotations stripped as well.
|
|
||
| @pytest.mark.parametrize('evt_name', ('rubbish', 'foo', 'bar')) | ||
| def test_rubbish_event_raises(mycharm: CharmBase, evt_name: str): | ||
| def test_rubbish_event_raises(mycharm: type[CharmBase], evt_name: str): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: why are we not changing CharmBase to ops.CharmBase in this file? Is it because it's covered by another PR?
P.S. I wonder if a type alias for type[ops.CharmBase] would be handy here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to avoid doing the change from from ops import CharmBase to import ops as much as possible to keep the size/scope down. I was originally just doing it when there was a new import needed (most often Framework). Then when I merged in the ruff PR there were a bunch of merge conflicts in most of the imports so I also simplified those.
I guess I could uniformly make this change, but I think it would probably be better as a separate PR, and it would be nice if it was after this one so I don't have to redo those changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 on leaving it for a separate PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 on leaving it for a separate PR
| return infos | ||
|
|
||
| def get_filesystem(self, ctx: Context) -> pathlib.Path: | ||
| def get_filesystem(self, ctx: Context[CharmBase]) -> pathlib.Path: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Has this become ctx: Context[Any] in the other PR?
testing/tests is added to the files that pyright should check, and the files that are left to do are added to the exclusion list.
Add type annotations to half of the test_e2e test files (the other half are in another PR, #2234).