leo-editor/leo-editor — pull request #26 by SegundoBob (2014-05-14 20:20:21+00:00)
Title: Python 3, Leo-Editor script, sys.path[0] is binary string causes imports...

... to fail

With Python 3 before executing a script, Leo-Editor puts a binary str at position 0 in sys.path causing many imports in the script to fail.

This bug applies to all scripts: @script, Ctrl-B, ...

This bug does not apply to Python 2.

The following are typical error messages that this bug causes to be displayed in the log pane:

File "/home/ldi/tmp/leoScript.py", line 8, in
from leo_lib import lib_leo01
File "", line 2214, in _find_and_load
File "", line 2199, in _find_and_load_unlocked
File "", line 2141, in _find_spec
File "", line 1917, in find_spec
File "", line 1891, in _get_spec
File "", line 2026, in find_spec
File "", line 53, in _path_join
File "", line 53, in
TypeError: Type str doesn't support the buffer API
--------------------
line 52: self._parent = parent
* line 53: self.setText('UNL Type: {0}'.format(
line 54: UnlType.T2Name[self._parent.unlType]))
line 55: self.connect(self, QtCore.SIGNAL('clicked()'),
---- end of Error messages ----

Ignore the lines begininng line 52. These are a red herring. They have nothing to do with the error. In fact, they are not an error at all.

The real problem is that the import failed because Leo-Editor put a directory specification in binary at the beginning of sys.path. This was a mistaken attempt to make Python 3 happy, but all the entries in sys.path should be str Unicode not bytes.

The error message is a bit misleading:

TypeError: Type str doesn't support the buffer API

A str is usually Unicode, but in this case the problem is that the str has type binary.

The bug is hit whenever import tries to look for a file-to-import in the directory from which the Leo-Editor file was loaded. I don't know all the conditions that can cause this, but attempting to import a file that resides in the directory from which the Leo-Editor file was loaded will do it; and attempting to import a non-existent file will do it.

The fix is a one-liner:

This fix works for both Python 2 and Python 3.