Sublime Forum

How to import classes from child directory in sublime plugin

#1

I want to have a directory structure like:

myplugin
  -lib
    -myplugin.py
    -file.py
    -another.py
  -tests
    -file_tests.py
    -another_tests.py 

I can’t make sublime recognize my plugin if it is in the child directory. That’s fine, I can keep the entry point in the root directory and import my other classes; however, I can’t make that work either. I’ve written the code and run my tests fine, like nosetest tests/ and everything passes - when sublime tries to load the package I get: ImportError: No module named 'lib'. I’m new to both sublime plugin development and Python, but basically, my plugin is like:

import sublime
import sublime_plugin
from lib.something import Something
from lib.something_else import SomethingElse
from lib.something_else_else import SomethingElseElse

class MyPluginCommand(sublime_plugin.TextCommand):
0 Likes

#2

Hi!

You need to add a __init__.py file in your lib folder.

Each time you want to import a py file from a folder, you need to create this __init__.py. It tells python that this is a package.

Warning: there is two underscore wrapping init.

EDIT: because of @OdatNurd answer:

do:

from .lib.something import Something

Notice the point in front of lib (it means here)

Matt

1 Like

#3

I posted an answer for this on your stack overflow question, but just to have the answer to the question also posted here for future searches:

Your problem is that the module name that you want to import needs to be qualified with the name of the package that it’s stored in. In terms of the code you gave above, the following would work, assuming that the plugin that the lib directory is stored in was named myplugin:

import sublime
import sublime_plugin
from myplugin.lib.something import Something
from myplugin.lib.something_else import SomethingElse
from myplugin.lib.something_else_else import SomethingElseElse

class MyPluginCommand(sublime_plugin.TextCommand):
2 Likes

#4

Thanks @OdatNurd, this did it.

1 Like

#5

What if your plugin name has spaces in it?

I just renamed mine to “Emacs Pro Essentials” so now what do I do?

(And yes, this is a rather urgent question … as I just found out the hard way I screwed up)

0 Likes

#6

Ah - well it looks like a relative import works fine.

Should have been more careful!

0 Likes

#7

@canoeberry, in general, you should name your plugins like they are python modules. If you don’t, you have to use relative imports. Python doesn’t allow things like spaces or - in module names.

2 Likes

#8

Yeah - I like plugin names with spaces. But I didn’t think through what it all meant until the errors came in.

But with relative imports, it seems fine. So is there anything wrong with relative imports?

Thanks.

0 Likes

#9

People just can call into your plugins from the outside because they can’t import it, but if that isn’t a concern, then you are fine.

0 Likes

#10

Since importing packages with hyphens or spaces is a limitation of Python’s syntax, you can still import them by directly using __import__, although less elegant.

It is generally recommended to name packages in PascalCase, especailly if they contain plugins.

Other than that, using relative imports where possible is always preferred, i.e. within your package.

Also note that ST2 and ST3 perform slightly different with importing, but as long as you only target ST3 (which you should), that doesn’t matter.

1 Like

#11

Funny, I always called this CamelCase… Maybe it’s the French way (which would be weird because case isn’t a French word)

What about importlib.import_module?

0 Likes

#12

Funny, I always called this CamelCase… Maybe it’s the French way (which would be weird because case isn’t a French word)

I believe it’s PascalCase and camelCase, depending on the case of the first letter.

3 Likes

#13

I also know it as TitleCase and camelCase, as @tom1 said, for when the first letter is small. I never bothered to look for an established standard, if one exists.

I assume importlib.import_module would also work, if you prefer that.

0 Likes