Home Download Buy Blog Forum Support

Trouble loading a Python library within my plugin

Trouble loading a Python library within my plugin

Postby Kevin Yank on Sun Jul 31, 2011 2:11 pm

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
    • My Package
      • my_command.py
      • chardet
        • __init__.py
        • big5freq.py

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

Code: Select all
import chardet


class MyCommandCommand(sublime_plugin.TextCommand):

  def run(self, edit):
    …
    decoded_content = content.decode(chardet.detect(content)['encoding'])


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

Code: Select all
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?
Kevin Yank
 
Posts: 18
Joined: Sat Jul 30, 2011 6:31 am

Re: Trouble loading a Python library within my plugin

Postby Kevin Yank on Mon Aug 01, 2011 1:50 am

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: Select all
cmd_folder = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(cmd_folder, 'chardet'))

import chardet
Kevin Yank
 
Posts: 18
Joined: Sat Jul 30, 2011 6:31 am

Re: Trouble loading a Python library within my plugin

Postby Kevin Yank on Wed Aug 03, 2011 12:34 pm

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: Select all
# 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()


I’d love to be able to do it with “from package import *”, but I can’t do that within a function.
Kevin Yank
 
Posts: 18
Joined: Sat Jul 30, 2011 6:31 am

Re: Trouble loading a Python library within my plugin

Postby Kevin Yank on Fri Aug 05, 2011 1:20 am

sublimator wrote:What do you mean?


This would be convenient to be able to do:
Code: Select all
# inside my_command.py plug-in file

def preemptive_imports():
    from chardet import *
preemptive_imports()


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

Using a separate module would work, though.
Kevin Yank
 
Posts: 18
Joined: Sat Jul 30, 2011 6:31 am


Return to Plugin Development

Who is online

Users browsing this forum: Yahoo [Bot] and 8 guests