Why SublimeREPL won't import a Python module o

2019-01-29 12:01发布

问题:

I'm using Sublime Text 3 build 3126 on Ubuntu Zesty with the SublimeREPL plugin.

I open a Python REPL with CTRL+SHIFT+P >> SublimeREPL: Python and send a file to REPL with CTRL+, , F and evertyhing works as long as I work on a single Python script file. As soon as I try to move some parts of my code to another module and import it in the main file, I get the nasty ImportError: No module named error.

Trying to open a text file located in the same directory with:

codecs.open('filename', encoding='utf-8')

results in:

 IOError: [Errno 2] No such file or directory: 'filename'

回答1:

Did you investigate whether there was a relation between the file/panel from where you opened SublimeREPL: Python and the output of print os.getcwd()? SublimeREPL initializes its cwd at its startup of the REPL. The cwd will stay for the entire lifetime of the REPL.

As you pointed out, the default cwd for SublimeREPL: Python is:

"cwd": "$file_path"

This means that starting SublimeREPL: Python with your cursor in a blank Sublime panel, results in /opt/sublime_text/ as the cwd. This could be considered undesired and confusing.

However, if you start SublimeREPL: Python while your cursor is in the .py file that you want to run, the REPL will use the folder of your current .py file as its cwd.

Personally I think this is the desired behaviour, but you have to know it before it becomes convenient.

If you change the settings for the cwd to:

"cwd": "$folder",

the above behaviour of the stays unchanged for cases where you're not using sublime-projects. When you do use a sublime-project, the python REPL cwd will be the main project folder, independent of the cursor location at REPL startup. This might be the desired behaviour if you have a python-driven project. However, if you are just using some python scripts in a bigger project, you probably don't want your main project folder to be the cwd in the python REPL.



回答2:

I spent a full day tearing my hair out while trying to find a solution to this problem.

First I thought there is some problem with $PYTHONPATH. I followed clues given in this (closed) issue on the SublimeREPL GitHub page: https://github.com/wuub/SublimeREPL/issues/355

And while the solution given by the plugin's author didn't work, adding the PYTHONPATH variable containing a path to my working directory to the extend_env key in Packages/SublimeREPL/config/Python/Main.sublime-menu solved the failing imports problem.

I thought I was golden, then I tried to read a text file in Python and got the IOError. Then it finally got to me that the wrong CWD (current working directory) was the culprit.

As the Python docs specify:

"When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:

  • the directory containing the input script (or the current directory).
  • PYTHONPATH (a list of directory names, with the same syntax as the
  • shell variable PATH). the installation-dependent default.

I tried import os and print os.getcwd() in the REPL promt and surely what I got was:

/opt/sublime_text/

So what I did? The solution was a simple change to a line in Packages/SublimeREPL/config/Python/Main.sublime-menu (in a section corresponding to the REPL I was using). From:

"cwd": "$file_path",

to:

"cwd": "$folder",

Now calling os.getcwd() resulted in a path to the directory containing the file I sent to SublimeREPL and everything worked. Why $file_path gives '/opt/sublime_text' rather than the path to a file is either a question to the plugin's author or some underlying quirk with my system.