Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1""" 

2@file 

3@brief Patch the distribution to make it portable 

4""" 

5from __future__ import print_function 

6 

7import os 

8import re 

9 

10 

11class ShebangException(Exception): 

12 """ 

13 exception raised when the shebang is not correct 

14 """ 

15 pass 

16 

17 

18def win_patch_paths(folder, path_to_python="", fLOG=print): 

19 """ 

20 Paths are absolute when they are installed in all scripts *.exe*, 

21 we replaced them either by an empty string (``path_to_python == ""``) 

22 or the current folder. 

23 

24 @param folder folder where to find the executable 

25 @param path_to_python new python path (replace by) 

26 @param fLOG logging function 

27 @return list of tuple ('exe or py', 'modified file') 

28 

29 See `Create a portable Python with Pip on Windows <http://www.clemens-sielaff.com/create-a-portable-python-with-pip-on-windows/>`_ 

30 The first three parameters can be environment variables. 

31 They will be replaced by their values. 

32 """ 

33 if folder in os.environ: 

34 folder = os.environ[folder] 

35 if path_to_python not in (None, "") and path_to_python in os.environ: 

36 path_to_python = os.environ[path_to_python] 

37 if path_to_python is None: 

38 exe = os.path.join(folder, "python.exe") 

39 if os.path.exists(exe): 

40 path_to_python = os.path.absapth(folder) 

41 else: 

42 exe = os.path.join(folder, "..", "python.exe") 

43 path_to_python = os.path.normpath( 

44 os.path.abspath(os.path.join(folder, ".."))) 

45 

46 files = os.listdir(folder) 

47 

48 if len(path_to_python) > 0 and not path_to_python.endswith("\\"): 

49 path_to_python += "\\" 

50 

51 pattern = "([#][!]((([A-Za-z][:])?[/\\\\]?[-a-zA-Z0-9_.]+[/\\\\])*?)(pythonw?[.]exe))" 

52 reg_exe = re.compile(pattern, re.IGNORECASE) 

53 breg_exe = re.compile(bytes(pattern, encoding="ascii"), re.IGNORECASE) 

54 g_path_to_python = path_to_python.replace("\\", "\\\\") 

55 bg_path_to_python = bytes(g_path_to_python, encoding="ascii") 

56 b1 = bytes("#!", encoding="ascii") 

57 b2 = bytes("\\5", encoding="ascii") 

58 

59 operations = [] 

60 for file in files: 

61 full = os.path.join(folder, file) 

62 if os.path.isfile(full): 

63 ext = os.path.splitext(full)[-1] 

64 

65 if ext in {".py", ""}: 

66 with open(full, "r") as f: 

67 content = f.read() 

68 new_content = reg_exe.sub( 

69 "#!" + g_path_to_python + "\\5", content) 

70 if new_content != content: 

71 fLOG("[pymy] update ", full) 

72 operations.append(("update", full)) 

73 with open(full, "w") as f: 

74 f.write(new_content) 

75 

76 elif ext == ".exe": 

77 with open(full, "rb") as f: 

78 content = f.read() 

79 new_content = breg_exe.sub( 

80 b1 + bg_path_to_python + b2, content) 

81 if new_content != content: 

82 fLOG("[win_patch_paths] update ", full) 

83 operations.append(("update", full)) 

84 try: 

85 with open(full, "wb") as f: 

86 f.write(new_content) 

87 except PermissionError as e: 

88 with open(full + ".replace", "wb") as f: 

89 f.write(new_content) 

90 mes = ("unable to overwrite '{0}', it will have to be manually done, " + 

91 "another file was created with .replace as an extension").format( 

92 full) 

93 raise Exception(mes) from e 

94 else: 

95 pass 

96 

97 return operations