Skip to content

Improve submodule reloading#61

Merged
math2001 merged 1 commit intomath2001:masterfrom
deathaxe:pr/reload-submodules
Jan 18, 2020
Merged

Improve submodule reloading#61
math2001 merged 1 commit intomath2001:masterfrom
deathaxe:pr/reload-submodules

Conversation

@deathaxe
Copy link
Copy Markdown
Contributor

This commit provides a change to clear the sys.modules cache before
importing any local package/module. This causes python to reload all
modules as soon as the FileManager.py is reloaded/imported by ST.

It is to ensure fluent plugin updates even if global variables or
module names change.

Nothing else is needed to instantly update all submodules during
development but saving the FileManager.py

This strategy is used by A File Icon and GitGutter for instance.

@deathaxe deathaxe force-pushed the pr/reload-submodules branch from 1d05891 to 7adde96 Compare January 18, 2020 14:43
This commit provides a change to clear the sys.modules cache before
importing any local package/module. This causes python to reload all
modules as soon as the FileManager.py is reloaded/imported by ST.

It is to ensure fluent plugin updates even if global variables or
module names change.

Nothing else is needed to instantly update all submodules during
development but saving the FileManager.py

This strategy is used by `A File Icon` and `GitGutter` for instance.
@math2001
Copy link
Copy Markdown
Owner

Nice, I agree that reloading needed to be better in FileManager.

Though, is there an idiomatic way to reload FileManager.py for any python file I save that's within FileManager? Here's what I'm doing right now (with your system running):

import os
import sys
import imp
import sublime_plugin


def reload_filemanager(view):
    file_name = view.file_name()
    assert file_name is not None, "post save and file_name is None?"

    if "FileManager.FileManager" not in sys.modules:
        print("FileManager not loaded, no reloading")

    if not file_name.endswith(".py"):
        return

    filemanager_root = os.path.join(sublime.packages_path(), "FileManager")

    if filemanager_root not in file_name:
        return

    imp.reload(sys.modules["FileManager.FileManager"])


class Hooks(sublime_plugin.EventListener):
    def on_post_save(self, view):
        reload_filemanager(view)

Thoughts? imp is deprecated from >= 3.4, so I'll also document an alternate version for 3.8 (just use importlib instead) if you think this is good.

Neat PR once more ♥️

@math2001 math2001 merged commit cee37ad into math2001:master Jan 18, 2020
@deathaxe
Copy link
Copy Markdown
Contributor Author

I personally use the AutomaticPackageReloader to reload submodules during development instead of hacking around something new for each plugin.

I am not sure whether calling imp.reload() only is sufficient in all situations. You may end up in changes not being picked up correctly as python may still use old instances/references depending on module load order.

The trick with this PR is to clear the cache while ST is reloading the FileManager.py, so python reimports all submodules in the correct order to make sure all references are updated correctly.

Your hook would need to call sublime_plugin.reload_plugin() to make sure everything is updated well. This is what AutomaticPackageReloader does.

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