compat.py 1.9 KB

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