compat.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. """Stuff that differs in different Python versions and platform
  2. distributions."""
  3. import logging
  4. import os
  5. import sys
  6. __all__ = ["get_path_uid", "stdlib_pkgs", "WINDOWS"]
  7. logger = logging.getLogger(__name__)
  8. def has_tls() -> bool:
  9. try:
  10. import _ssl # noqa: F401 # ignore unused
  11. return True
  12. except ImportError:
  13. pass
  14. from pip._vendor.urllib3.util import IS_PYOPENSSL
  15. return IS_PYOPENSSL
  16. def get_path_uid(path: str) -> int:
  17. """
  18. Return path's uid.
  19. Does not follow symlinks:
  20. https://github.com/pypa/pip/pull/935#discussion_r5307003
  21. Placed this function in compat due to differences on AIX and
  22. Jython, that should eventually go away.
  23. :raises OSError: When path is a symlink or can't be read.
  24. """
  25. if hasattr(os, "O_NOFOLLOW"):
  26. fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW)
  27. file_uid = os.fstat(fd).st_uid
  28. os.close(fd)
  29. else: # AIX and Jython
  30. # WARNING: time of check vulnerability, but best we can do w/o NOFOLLOW
  31. if not os.path.islink(path):
  32. # older versions of Jython don't have `os.fstat`
  33. file_uid = os.stat(path).st_uid
  34. else:
  35. # raise OSError for parity with os.O_NOFOLLOW above
  36. raise OSError(f"{path} is a symlink; Will not return uid for symlinks")
  37. return file_uid
  38. # packages in the stdlib that may have installation metadata, but should not be
  39. # considered 'installed'. this theoretically could be determined based on
  40. # dist.location (py27:`sysconfig.get_paths()['stdlib']`,
  41. # py26:sysconfig.get_config_vars('LIBDEST')), but fear platform variation may
  42. # make this ineffective, so hard-coding
  43. stdlib_pkgs = {"python", "wsgiref", "argparse"}
  44. # windows detection, covers cpython and ironpython
  45. WINDOWS = sys.platform.startswith("win") or (sys.platform == "cli" and os.name == "nt")