Sublime Forum

Trouble loading a Python library within my plugin

#1

My plugin (currently a single command) needs to make use of the chardet Python library. I have therefore put a copy of the chardet module in a subdirectory of my package:

  • Packages[list]]My Package[list]]my_command.py
  • chardet[list]*]init.py
  • big5freq.py

/:m][/list:u]/:m][/list:u]/*:m][/list:u]

Now, inside my_command.py, I import and attempt to use chardet:

[code]import chardet


class MyCommandCommand(sublime_plugin.TextCommand):

def run(self, edit):

decoded_content = content.decode(chardet.detect(content)‘encoding’])[/code]

When Sublime Text 2’s Python attempts to run chardet.detect, it fails with this error:

Traceback (most recent call last): File "./sublime_plugin.py", line 255, in run_ File "./lookup_with_google_and_link.py", line 79, in run File "./lookup_with_google_and_link.py", line 50, in get_link_with_title File "./chardet/__init__.py", line 21, in detect ImportError: No module named universaldetector

The universaldetector.py file exists in the chardet directory. I can see that Python is creating a init.pyc file for init.py, but no .pyc files for any of the other files under chardet.

If I open my system Python interpreter in my My Package directory, I can import and use chardet.detect without incident.

Any idea what could be causing this?

0 Likes

#2

This seems like a hack that shouldn’t be necessary, but I’ve fixed the problem by adding the module’s directory to the system path before importing it:

[code]cmd_folder = os.path.dirname(os.path.abspath(file))
sys.path.append(os.path.join(cmd_folder, ‘chardet’))

import chardet[/code]

0 Likes

#3

I see, thank you! That’s quite a pitfall!

So if I understand correctly, the correct workaround here would be for my plugin to pre-emptively import every module in the library package to guarantee that it will be already loaded when the time comes.

For large libraries, this could create a huge amount of namespace pollution if these imports were performed at the top level of the plug-in module. I’m thinking of performing the imports inside a function. Would you agree this is probably a “best practice” approach for Sublime Text 2 plug-ins?

[code]# inside the my_command.py plug-in file

def preemptive_imports():
“”" needed to ensure access to these classes later, due to the way ST2 loads plug-in modules “”"
from chardet import big5freq, big5prober, chardistribution …

preemptive_imports()[/code]

I’d love to be able to do it with “from package import *”, but I can’t do that within a function.

0 Likes

#4

This would be convenient to be able to do:[code]# inside my_command.py plug-in file

def preemptive_imports():
from chardet import *
preemptive_imports()[/code]

But Python doesn’t permit “import *” within a function.

Using a separate module would work, though.

0 Likes