Repository: pyinstaller/pyinstaller

Issue:
win32: multibyte path bootloader import issue with python2 
OS: windows 7/windows 10
Py: Python 2.7.13
Pyinstaller: Pyinstaller 3.3-dev 964547c

tl;dr the pyinstaller one-file failed to proper import during bootloader stage when the path involve multibyte character under win32 py2,

1. create a username with multibyte character, `許功蓋` is most suitable one for this as it contain special character

2. install some package that make bootloader do some import
`pip install pypiwin32`

3. sample script for pyinstaller to start with
`broken_py2_path.py`
```
# -*- coding: utf-8 -*-

import pywintypes

def main():
	pass
	
if __name__ == '__main__':
	main()
```

4. bundle it
`pyinstaller -F -d broken_py2_path.py`

5. execute `broken_py2_path.exe`

6. bam
```
E:\新增資料夾>broken_py2_path.exe
PyInstaller Bootloader 3.x
LOADER: executable is E:\?啣?鞈?憭閱broken_py2_path.exe
LOADER: homepath is E:\?啣?鞈?憭?
LOADER: _MEIPASS2 is NULL
LOADER: archivename is E:\?啣?鞈?憭閱broken_py2_path.exe
LOADER: Extracting binaries
LOADER: Executing self as child
LOADER: set _MEIPASS2 to C:\Users\閮勗??AppData\Local\Temp\_MEI143282
LOADER: Setting up to run child
LOADER: Creating child process
LOADER: Waiting for child process to finish...
PyInstaller Bootloader 3.x
LOADER: executable is E:\?啣?鞈?憭閱broken_py2_path.exe
LOADER: homepath is E:\?啣?鞈?憭?
LOADER: _MEIPASS2 is C:\Users\閮勗??AppData\Local\Temp\_MEI143282
LOADER: archivename is E:\?啣?鞈?憭閱broken_py2_path.exe
LOADER: SetDllDirectory(C:\Users\閮勗??AppData\Local\Temp\_MEI143282)
LOADER: Already in the child - running user's code.
LOADER: manifestpath: C:\Users\閮勗??AppData\Local\Temp\_MEI143282\broken_py2_path.exe.manifest
LOADER: Activation context created
LOADER: Activation context activated
LOADER: Python library: C:\Users\閮勗??AppData\Local\Temp\_MEI143282\python27.dll
LOADER: Loaded functions from Python library.
LOADER: Manipulating environment (sys.path, sys.prefix)
LOADER: sys.prefix is C:\Users\許功蓋\AppData\Local\Temp\_MEI14~1
LOADER: Setting runtime options
LOADER: Bootloader option: pyi-windows-manifest-filename broken_py2_path.exe.manifest
LOADER: Initializing python
LOADER: Overriding Python's sys.path
LOADER: Post-init sys.path is C:\Users\閮勗??AppData\Local\Temp\_MEI143282
LOADER: Setting sys.argv
LOADER: setting sys._MEIPASS
LOADER: importing modules from CArchive
LOADER: extracted struct
LOADER: callfunction returned...
LOADER: extracted pyimod01_os_path
LOADER: callfunction returned...
LOADER: extracted pyimod02_archive
LOADER: callfunction returned...
LOADER: extracted pyimod03_importers
LOADER: callfunction returned...
LOADER: Installing PYZ archive with Python modules.
LOADER: PYZ archive: out00-PYZ.pyz
LOADER: Running pyiboot01_bootstrap.py
LOADER: Running broken_py2_path.py
Traceback (most recent call last):
  File "broken_py2_path.py", line 3, in <module>
  File "d:\andcycle\documents\work\corelight\proj\poc\runtime\Lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 396, in load_module
  File "site-packages\win32\lib\pywintypes.py", line 124, in <module>
  File "site-packages\win32\lib\pywintypes.py", line 61, in __import_pywin32_system_module__
ImportError: Module 'pywintypes' isn't in frozen sys.path ['C:\\Users\\\xb3\\\xa5\\\xbb\\AppData\\Local\\Temp\\_MEI14~1']
Failed to execute script broken_py2_path
LOADER: OK.
LOADER: Cleaning up Python interpreter.
LOADER: Back to parent (RC: -1)
LOADER: Doing cleanup
LOADER: Freeing archive status for E:\?啣?鞈?憭閱broken_py2_path.exe

E:\新增資料夾>
```



Discussion:
there is some weird issue here
`in frozen sys.path ['C:\\Users\\\xb3\\\xa5\\\xbb\\AppData\\Local\\Temp\\_MEI14~1']`
should be
`in frozen sys.path ['C:\\Users\\\xb3\\\xa5\\\xbb\\\\AppData\\Local\\Temp\\_MEI14~1']`
why it's missing a `\\`

Resolving patch:
diff --git a/PyInstaller/loader/pyiboot01_bootstrap.py b/PyInstaller/loader/pyiboot01_bootstrap.py
--- a/PyInstaller/loader/pyiboot01_bootstrap.py
+++ b/PyInstaller/loader/pyiboot01_bootstrap.py
@@ -60,7 +60,12 @@
 # application.
 python_path = []
 for pth in sys.path:
-    python_path.append(os.path.abspath(pth))
+    if not os.path.isabs(pth):
+        # careful about using abspath with non-unicode path,
+        # it breaks multibyte character that contain slash under win32/Python 2
+        # TODO: Revert when dropping suport for is_py2.
+        pth = os.path.abspath(pth)
+    python_path.append(pth)
     sys.path = python_path
 
 


Test patch: