Sublime Forum

Dynamically loading classes inside a .sublime-package file

#1

When trying to dynamically load several (possibly unknown) classes using something like:

for i in os.listdir(os.path.join(os.path.dirname(__file__),'extensions')):
    if '.py' in i:
        i = os.path.basename(os.path.splitext(i)[0])
        import_module('Urtext.urtext.extensions.'+i)

I get an error like:

NotADirectoryError: [Errno 20] Not a directory: '/Users/username/Library/Application Support/Sublime Text/Installed Packages/Urtext.sublime-package/urtext/extensions

It looks like this kind of import will not work when bundled as a .sublime-package. Is there a recommended alternative?

0 Likes

#2

Packages that are installed are available directly as their name (i.e., don’t include it in the name of the module as you’re doing here).

For example, the Default package is stored in a Default.sublime-package file inside of the installation folder of Sublime; it contains a file named exec.py which contains a class named ExecCommand; one would import it as:

from Default.exec import ExecCommand

So here the import mechanism knows automagically to look inside of the Default.sublime-package file to find what it’s looking for.

For what you’re doing here you would need to change it slightly, since you’re not doing it at compile time. But the same thing holds. For example:

import imp
import sys

def reload(prefix, modules=[""]):
    prefix = "OverrideAudit.%s." % prefix

    for module in modules:
        module = (prefix + module).rstrip(".")
        if module in sys.modules:
            imp.reload(sys.modules[module])

reload("lib")
0 Likes

#3

Thank you for the clarification.
The error is being thrown at the first line, however:
for i in os.listdir(os.path.join(os.path.dirname(__file__),'extensions')):
This works when the package is in /Packages, but no such path exists when installed via Package Control. I’m trying to “autoload” a list of modules by filename from a specific location within the package. Is there a way to do this that I’m not seeing?

0 Likes

#4

Why not just import the modules?

0 Likes

#5

@rwols That is what I may end up doing for now. The autoload code is intended for a future feature to allow user-contributed classes to get added from an arbitrary (passed) path, without being specified using import.

0 Likes

#6

If you want to something like your code sample and have it work whether the package is packed or not, you need to use sublime.find_resources() to find all resources, filter the list to files that are in the package you want, and then use those names to construct the import.

0 Likes