Xpra: Ticket #1173: Python win32 path encoding problems

Xpra will not start for me on Windows 7 x64 if my user profile resides in a directory that contains accented characters.

Example:

Installing Xpra on a machine where my user profile resides in C:\Users\Jan Přikryl results in

Traceback (most recent call last):
  File "xpra_launcher", line 4, in <module>
  File "xpra\platform\__init__.pyc", line 23, in init
  File "xpra\platform\win32\__init__.pyc", line 252, in do_init
  File "xpra\platform\win32\paths.pyc", line 99, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf8 in position 823: ordinal not in range(128)

while using the same version on another machine where the profile resides in C:\Users\Prikryl works (in this respect).

My guess is that the problems are caused by incorrect encoding of accented path strings in xpra.platform.win32.paths module -- the crash is caused by xpra\platform\win32\__init__.py calling

  from paths import _get_data_dir

but I am unable to locate the line 99 in the Xpra repository (the only tag I see is 0.16.x and at this tag the line 99 of paths.py contains else:).

The output of Version_info.exe:

Build:
* local_modifications              : 0
* revision                         : 12203
* version                          : 0.16.3
Platform:
* architecture                     : 32bit, WindowsPE
* machine                          : AMD64
* name                             : Microsoft Windows 7
* platform                         : Windows-7-6.1.7601-SP1
* processor                        : Intel64 Family 6 Model 30 Stepping 5, GenuineIntel
* release                          : 7
* sys                              : win32
Host:
* byteorder                        : little
* hostname                         : k611-407c
* pid                              : 2068
* python.bits                      : 32
* python.full_version              : 2.7.11 (v2.7.11:6d1b6a68f775, Dec  5 2015, 20:32:19) [MSC v.1500 32 bit (Intel)]
* python.version                   : 2.7.11
* pywin32.version                  : 220
* wmi.version                      : 1.4.9


Mon, 18 Apr 2016 09:04:15 GMT - Antoine Martin: owner changed

I believe the problem comes from this line:

APP_DIR = os.path.dirname(unicode(sys.executable, sys.getfilesystemencoding()))

If you have a python interpreter installed, can you suggest a reliable way of getting the correct value we can use?


Mon, 18 Apr 2016 15:21:08 GMT - Jan Prikryl:

Antoine,

the suggested problem line

APP_DIR = os.path.dirname(unicode(sys.executable, sys.getfilesystemencoding()))

does yield the correct APP_DIR value C:\Devel\Xpra in Python 2.7.x (or at lest 2.7.8 and 2.7.11) and would crash a Python 3.x interpreter.

I have done a bit of additional testing and I have been able to pinpoint the problem to the contents of PATH environment variable. In my case, the variable contains a string with accented characters:

Path=[...];C:\Users\Jan Přikryl\Documents\Devel\DLLs\x64

replacing it with

Path=[...];C:\Users\JANPIK~1\Documents\Devel\DLLs\x64

allows Xpra client to start.

So, the line that triggers the error is

os.environ['PATH'] = APP_DIR + ';' + os.environ['PATH']

which sounds logical, as in my original report the offending character is at position 843 which suggests that the offending string has to be at least this long.

The above line is okay for Python 3, but for Python 2 it has to read

os.environ['PATH'] = APP_DIR.encode('utf8') + os.pathsep + os.environ['PATH']

My suggestion would be to replace the relevat part of paths.py with

# If the interpreter version is at least 3.0.x ...
if sys.version_info >= (3,0):
  # Python 3.x version
  APP_DIR = os.path.dirname(sys.executable)
else:
  # Python 2.x version
  APP_DIR = os.path.dirname(unicode(sys.executable, sys.getfilesystemencoding()))
sys.path.insert(0, APP_DIR)
os.chdir(APP_DIR)
# Extend the executbale search path so that we can easily load DLLs with ctypes
if sys.version_info >= (3,0):
  # Python 3.x version
  os.environ['PATH'] = APP_DIR + os.pathsep + os.environ['PATH']
else:
  # Python 2.x version
  os.environ['PATH'] = APP_DIR.encode('utf8') + os.pathsep + os.environ['PATH']

BTW, tests for Python interpreter version should be IMO based on sys.version_info.

The attached demo file demonstrates the fix and has been tested in Python 2.7.8 and Python 3.4.3.

-- jan


Mon, 18 Apr 2016 15:21:45 GMT - Jan Prikryl: attachment set


Tue, 19 Apr 2016 03:00:15 GMT - Antoine Martin:

Thanks: applied in r12433, backported to v0.17.x in r12435 (will be included in 0.17.0, probably later today)

Also switched to using version_info in r12434 for trunk. I also prefer this form over the plain "version" string, but it is used inconsistently in the codebase..

Please close if this works for you.


Tue, 21 Feb 2017 12:40:26 GMT - Antoine Martin: status changed; resolution, milestone set

Not heard back.


Sat, 19 Jan 2019 08:56:07 GMT - totaamwin32:

Similar problem in #2096.


Sat, 23 Jan 2021 05:16:57 GMT - migration script:

this ticket has been moved to: https://github.com/Xpra-org/xpra/issues/1173