xpra icon
Bug tracker and wiki

Opened 15 months ago

Closed 5 months ago

#1173 closed defect (fixed)

Python win32 path encoding problems

Reported by: Jan Prikryl Owned by: Jan Prikryl
Priority: critical Milestone: 1.0
Component: core Version: 0.16.x
Keywords: python win32 path encoding Cc:

Description

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

Attachments (1)

app_dir_bug_workaround.py (1.7 KB) - added by Jan Prikryl 15 months ago.

Download all attachments as: .zip

Change History (5)

comment:1 Changed 15 months ago by Antoine Martin

Owner: changed from Antoine Martin to Jan Prikryl

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?

comment:2 Changed 15 months ago by 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

Changed 15 months ago by Jan Prikryl

Attachment: app_dir_bug_workaround.py added

comment:3 Changed 15 months ago by 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.

comment:4 Changed 5 months ago by Antoine Martin

Milestone: 1.0
Resolution: fixed
Status: newclosed

Not heard back.

Note: See TracTickets for help on using tickets.