sitecustomize.py 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. '''Python AppImage hooks
  2. '''
  3. import atexit
  4. import os
  5. import sys
  6. _bin_at_start = os.listdir(sys.prefix + '/bin')
  7. '''Initial content of the bin/ directory
  8. '''
  9. def patch_pip_install():
  10. '''Change absolute shebangs to relative ones following a `pip` install
  11. '''
  12. if not 'pip' in sys.modules:
  13. return
  14. appdir = os.getenv('APPDIR')
  15. python_x_y = 'python{:}.{:}'.format(*sys.version_info[:2])
  16. if sys.prefix != '{:}/opt/{:}'.format(appdir, python_x_y):
  17. return
  18. args = sys.argv[1:]
  19. if 'install' in args:
  20. for exe in os.listdir(sys.prefix + '/bin'):
  21. path = os.path.join(sys.prefix, 'bin', exe)
  22. if (not os.path.isfile(path)) or (not os.access(path, os.X_OK)) or \
  23. exe.startswith('python') or os.path.islink(path) or \
  24. exe.endswith('.pyc') or exe.endswith('.pyo'):
  25. continue
  26. try:
  27. with open(path, 'r') as f:
  28. header = f.read(2)
  29. if header != '#!':
  30. continue
  31. content = f.read()
  32. except:
  33. continue
  34. shebang, body = content.split(os.linesep, 1)
  35. shebang = shebang.strip().split()
  36. executable = shebang.pop(0)
  37. if executable != sys.executable:
  38. head, altbody = body.split(os.linesep, 1)
  39. if head.startswith("'''exec' /"): # Patch for alt shebang
  40. body = altbody.split(os.linesep, 1)[1]
  41. executable = head.split()[1]
  42. if executable != sys.executable:
  43. continue
  44. else:
  45. continue
  46. relpath = os.path.relpath(
  47. sys.prefix + '/../../usr/bin/' + python_x_y,
  48. sys.prefix + '/bin')
  49. shebang.append('"$@"')
  50. cmd = (
  51. '"exec"',
  52. '"$(dirname $(readlink -f ${0}))/' + relpath + '"',
  53. '"$0"',
  54. ' '.join(shebang)
  55. )
  56. try:
  57. with open(path, 'w') as f:
  58. f.write('#! /bin/sh\n')
  59. f.write(' '.join(cmd) + '\n')
  60. f.write(body)
  61. except IOError:
  62. continue
  63. if exe in _bin_at_start:
  64. continue
  65. usr_dir = os.path.join(sys.prefix, '../../usr/bin')
  66. usr_exe = os.path.join(usr_dir, exe)
  67. if not os.path.exists(usr_exe):
  68. relpath = os.path.relpath(path, usr_dir)
  69. os.symlink(relpath, usr_exe)
  70. elif 'uninstall' in args:
  71. usr_dir = os.path.join(sys.prefix, '../../usr/bin')
  72. for exe in os.listdir(usr_dir):
  73. path = os.path.join(usr_dir, exe)
  74. if (not os.path.islink(path)) or \
  75. os.path.exists(os.path.realpath(path)):
  76. continue
  77. os.remove(path)
  78. if os.getenv('VIRTUAL_ENV') is None:
  79. atexit.register(patch_pip_install)
  80. else:
  81. del _bin_at_start
  82. del patch_pip_install