You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

locations.py 6.2 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. """Locations where we look for configs, install stuff, etc"""
  2. from __future__ import absolute_import
  3. import getpass
  4. import os
  5. import os.path
  6. import site
  7. import sys
  8. from distutils import sysconfig
  9. from distutils.command.install import install, SCHEME_KEYS # noqa
  10. from pip.compat import WINDOWS
  11. from pip.utils import appdirs
  12. # CA Bundle Locations
  13. CA_BUNDLE_PATHS = [
  14. # Debian/Ubuntu/Gentoo etc.
  15. "/etc/ssl/certs/ca-certificates.crt",
  16. # Fedora/RHEL
  17. "/etc/pki/tls/certs/ca-bundle.crt",
  18. # OpenSUSE
  19. "/etc/ssl/ca-bundle.pem",
  20. # OpenBSD
  21. "/etc/ssl/cert.pem",
  22. # FreeBSD/DragonFly
  23. "/usr/local/share/certs/ca-root-nss.crt",
  24. # Homebrew on OSX
  25. "/usr/local/etc/openssl/cert.pem",
  26. ]
  27. # Attempt to locate a CA Bundle that we can pass into requests, we have a list
  28. # of possible ones from various systems. If we cannot find one then we'll set
  29. # this to None so that we default to whatever requests is setup to handle.
  30. #
  31. # Note to Downstream: If you wish to disable this autodetection and simply use
  32. # whatever requests does (likely you've already patched
  33. # requests.certs.where()) then simply edit this line so
  34. # that it reads ``CA_BUNDLE_PATH = None``.
  35. CA_BUNDLE_PATH = next((x for x in CA_BUNDLE_PATHS if os.path.exists(x)), None)
  36. # Application Directories
  37. USER_CACHE_DIR = appdirs.user_cache_dir("pip")
  38. DELETE_MARKER_MESSAGE = '''\
  39. This file is placed here by pip to indicate the source was put
  40. here by pip.
  41. Once this package is successfully installed this source code will be
  42. deleted (unless you remove this file).
  43. '''
  44. PIP_DELETE_MARKER_FILENAME = 'pip-delete-this-directory.txt'
  45. def write_delete_marker_file(directory):
  46. """
  47. Write the pip delete marker file into this directory.
  48. """
  49. filepath = os.path.join(directory, PIP_DELETE_MARKER_FILENAME)
  50. with open(filepath, 'w') as marker_fp:
  51. marker_fp.write(DELETE_MARKER_MESSAGE)
  52. def running_under_virtualenv():
  53. """
  54. Return True if we're running inside a virtualenv, False otherwise.
  55. """
  56. if hasattr(sys, 'real_prefix'):
  57. return True
  58. elif sys.prefix != getattr(sys, "base_prefix", sys.prefix):
  59. return True
  60. return False
  61. def virtualenv_no_global():
  62. """
  63. Return True if in a venv and no system site packages.
  64. """
  65. # this mirrors the logic in virtualenv.py for locating the
  66. # no-global-site-packages.txt file
  67. site_mod_dir = os.path.dirname(os.path.abspath(site.__file__))
  68. no_global_file = os.path.join(site_mod_dir, 'no-global-site-packages.txt')
  69. if running_under_virtualenv() and os.path.isfile(no_global_file):
  70. return True
  71. def __get_username():
  72. """ Returns the effective username of the current process. """
  73. if WINDOWS:
  74. return getpass.getuser()
  75. import pwd
  76. return pwd.getpwuid(os.geteuid()).pw_name
  77. if running_under_virtualenv():
  78. src_prefix = os.path.join(sys.prefix, 'src')
  79. else:
  80. # FIXME: keep src in cwd for now (it is not a temporary folder)
  81. try:
  82. src_prefix = os.path.join(os.getcwd(), 'src')
  83. except OSError:
  84. # In case the current working directory has been renamed or deleted
  85. sys.exit(
  86. "The folder you are executing pip from can no longer be found."
  87. )
  88. # under Mac OS X + virtualenv sys.prefix is not properly resolved
  89. # it is something like /path/to/python/bin/..
  90. # Note: using realpath due to tmp dirs on OSX being symlinks
  91. src_prefix = os.path.abspath(src_prefix)
  92. # FIXME doesn't account for venv linked to global site-packages
  93. site_packages = sysconfig.get_python_lib()
  94. user_site = site.USER_SITE
  95. user_dir = os.path.expanduser('~')
  96. if WINDOWS:
  97. bin_py = os.path.join(sys.prefix, 'Scripts')
  98. bin_user = os.path.join(user_site, 'Scripts')
  99. # buildout uses 'bin' on Windows too?
  100. if not os.path.exists(bin_py):
  101. bin_py = os.path.join(sys.prefix, 'bin')
  102. bin_user = os.path.join(user_site, 'bin')
  103. config_basename = 'pip.ini'
  104. legacy_storage_dir = os.path.join(user_dir, 'pip')
  105. legacy_config_file = os.path.join(
  106. legacy_storage_dir,
  107. config_basename,
  108. )
  109. else:
  110. bin_py = os.path.join(sys.prefix, 'bin')
  111. bin_user = os.path.join(user_site, 'bin')
  112. config_basename = 'pip.conf'
  113. legacy_storage_dir = os.path.join(user_dir, '.pip')
  114. legacy_config_file = os.path.join(
  115. legacy_storage_dir,
  116. config_basename,
  117. )
  118. # Forcing to use /usr/local/bin for standard Mac OS X framework installs
  119. # Also log to ~/Library/Logs/ for use with the Console.app log viewer
  120. if sys.platform[:6] == 'darwin' and sys.prefix[:16] == '/System/Library/':
  121. bin_py = '/usr/local/bin'
  122. site_config_files = [
  123. os.path.join(path, config_basename)
  124. for path in appdirs.site_config_dirs('pip')
  125. ]
  126. def distutils_scheme(dist_name, user=False, home=None, root=None,
  127. isolated=False):
  128. """
  129. Return a distutils install scheme
  130. """
  131. from distutils.dist import Distribution
  132. scheme = {}
  133. if isolated:
  134. extra_dist_args = {"script_args": ["--no-user-cfg"]}
  135. else:
  136. extra_dist_args = {}
  137. dist_args = {'name': dist_name}
  138. dist_args.update(extra_dist_args)
  139. d = Distribution(dist_args)
  140. d.parse_config_files()
  141. i = d.get_command_obj('install', create=True)
  142. # NOTE: setting user or home has the side-effect of creating the home dir
  143. # or user base for installations during finalize_options()
  144. # ideally, we'd prefer a scheme class that has no side-effects.
  145. i.user = user or i.user
  146. if user:
  147. i.prefix = ""
  148. i.home = home or i.home
  149. i.root = root or i.root
  150. i.finalize_options()
  151. for key in SCHEME_KEYS:
  152. scheme[key] = getattr(i, 'install_' + key)
  153. if i.install_lib is not None:
  154. # install_lib takes precedence over purelib and platlib
  155. scheme.update(dict(purelib=i.install_lib, platlib=i.install_lib))
  156. if running_under_virtualenv():
  157. scheme['headers'] = os.path.join(
  158. sys.prefix,
  159. 'include',
  160. 'site',
  161. 'python' + sys.version[:3],
  162. dist_name,
  163. )
  164. if root is not None:
  165. scheme["headers"] = os.path.join(
  166. root,
  167. os.path.abspath(scheme["headers"])[1:],
  168. )
  169. return scheme