toga icon indicating copy to clipboard operation
toga copied to clipboard

implement lazy loading in toga_core

Open KRRT7 opened this issue 1 year ago • 8 comments

  • Fixes (partly) #2547

adds a lazy import mechanism using a module-level getattr function. This applies to:

  1. toga-core (in toga/init.py) Only

PR Checklist:

  • [ X] All new features have been tested
  • [ X] All new features have been documented
  • [X ] I have read the CONTRIBUTING.md file
  • [ X] I will abide by the code of conduct

KRRT7 avatar Jul 01 '24 09:07 KRRT7

this comes behind #2584 , it was very messy and would require lots of reverts, please see there for history and revelance.

KRRT7 avatar Jul 01 '24 09:07 KRRT7

The core of this looks good; a couple of minor cleanups flagged inline.

Thanks, the issues were resolved

KRRT7 avatar Jul 08 '24 07:07 KRRT7

This all looks good to me, but even performance improvements should have a test where possible. Since the tests are run in alphabetical order, the app tests are run first, so we could put a test in there which does the following:

  • Pick a widget module that isn't used elsewhere in the app tests, e.g. toga.widgets.button.
  • Assert that the module doesn't exist in sys.modules.
  • Access toga.Button.
  • Assert that the module now exists in sys.modules, and that toga.Button is toga.widgets.button.Button.

mhsmith avatar Jul 08 '24 16:07 mhsmith

I'd be a little wary of adding a test that depends on execution order - while default invocation of pytest will execute in alphabetical order, there's no guarantee tests will be executed in that order (especially if they're manually specified).

An explicit test that a widget such as Button has been imported correctly (whether by the test, or by running a Button test previously) is definitely called for - but I don't think the "from a clean state" requirement (i.e., that sys.modules was clean beforehand) is needed.

freakboy3742 avatar Jul 11 '24 08:07 freakboy3742

There should still be a test verifying that a clean import of toga doesn't import all the widgets. Otherwise, if that somehow started happening again in the future, we might not notice for a long time.

The test itself could create the clean slate by removing toga and toga.widgets.button from sys.modules, and restoring them afterwards. Then it wouldn't matter which order it ran in, and it could be placed somewhere more appropriate than the app directory.

mhsmith avatar Jul 12 '24 01:07 mhsmith

The test itself could create the clean slate by removing toga and toga.widgets.button from sys.modules, and restoring them afterwards. Then it wouldn't matter which order it ran in, and it could be placed somewhere more appropriate than the app directory.

True - although there's also the implementation cache of globals() that needs to be cleared.

That said - looking at the current implementation, the value is being set in globals(), but that cached value is never being used... as written, every import will fire the import machinery, and the value in globals() will never be used.

freakboy3742 avatar Jul 14 '24 23:07 freakboy3742

True - although there's also the implementation cache of globals() that needs to be cleared.

Every module object has its own globals, so a freshly-imported toga module will have nothing cached.

That said - looking at the current implementation, the value is being set in globals(), but that cached value is never being used

See "customizing module attribute access" – adding the value to globals allows it to be found "through the normal lookup", so __getattr__ will not be called with that name again.

mhsmith avatar Jul 15 '24 11:07 mhsmith

See "customizing module attribute access" – adding the value to globals allows it to be found "through the normal lookup", so __getattr__ will not be called with that name again.

Huh - my mental model has __getattr__ responsible for all module attribute lookup if it existed. If it's only used as a supplement to what is found in globals(), then I agree this isn't an issue.

freakboy3742 avatar Jul 17 '24 03:07 freakboy3742

🥳 🎉 thanks @mhsmith for completing my forgotten work

KRRT7 avatar Oct 28 '24 05:10 KRRT7