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

REF: create a window singleton for access throughout superscore #115

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

tangkong
Copy link
Contributor

@tangkong tangkong commented Dec 11, 2024

Description

  • Makes Window a QtSingleton, and adds an access function for use throughout superscore ui widgets
    • Uses this singleton to access methods that were passed around manually in the past as optional arguments or set attributes. In particular
      • Open Page Slot: removed as an optional argument on all page widgets, only retrieved by the Window singleton. (since this argument has no meaning outside the context of the full application)
      • client: Added a backup access path via Window singleton, but also retained the init argument. This permits testing of widgets individually
  • These methods are gathered in a WindowLinker mixin class for convenience and de-duplication

I ended up treating these two differently, and am open to differing opinions here. Perhaps I should have left the existing open_page_slot optional arguments and treated it like I did the Client

Motivation and Context

We found that we were passing around information held by the window throughout our application. We also find ourselves wanting to open pages from other sub-pages, not just from the main window.

If we ever want to change the information passed from page to page, we'd end up having to change the signature of all those widgets. It's probably best to avoid this behavior

How Has This Been Tested?

By ensuring the tests still pass. The required arguments of the existing widgets haven't changed, in theory (as borne out by the tests)

Where Has This Been Documented?

This PR

Pre-merge checklist

  • Code works interactively
  • Code follows the style guide
  • Code contains descriptive docstrings, including context and API
  • New/changed functions and methods are covered in the test suite where possible
  • Test suite passes locally
  • Test suite passes on GitHub Actions
  • Ran docs/pre-release-notes.sh and created a pre-release documentation page
  • Pre-release docs include context, functional descriptions, and contributors as appropriate

@tangkong
Copy link
Contributor Author

tangkong commented Dec 11, 2024

perhaps there's also a world where we pull these methods up into a common core class, but I dislike how that obfuscates these very frequently used methods. (Is the de-duplication worth it? probably. can I get around circular imports again? 🤷 )

Edit: I can and I will

@tangkong tangkong force-pushed the ref_window_singleton branch from c6c6bbd to df13c6e Compare December 11, 2024 17:52
…e open_page_slot and client args from most child pages (non-Window)
Copy link
Member

@ZLLentz ZLLentz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm on board conceptually and the implementation looks good. I have some questions and specific things that confused me.

page.open_page_slot = MagicMock()
page.open_rbv_button.clicked.emit()
assert page.open_page_slot.called
with patch("superscore.widgets.page.entry.BaseParameterPage.open_page_slot",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test design question: when would you choose unittest.mock.patch over the pytest monkeypatch fixture and vice versa?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's not much of a difference most of the time. In this case I wanted to mock a property, and the first example I found was through unittest.mock. I've been using MagicMock and finding it very convenient, but it is some deep mystical magic

I should probably be better about sticking to one, but we have access to both.

superscore/widgets/__init__.py Outdated Show resolved Hide resolved
superscore/widgets/page/collection_builder.py Outdated Show resolved Hide resolved
if client is self._client:
return

self._client = client
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I notice that this allows different widgets to use different clients. Is this intended?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Within the context of the superscore app, this isn't something we expect to happen. We should only have one client for one superscore instance and all its child pages. I'm not particularly worried about a new client getting slipped into the superscore app, but this does provide that possibility

Personally, specifying this per widget lets me test widgets individually, free of needing to create a Window.

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

Successfully merging this pull request may close these issues.

2 participants