__init__.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. """Stuff that differs in different Python versions and platform
  2. distributions."""
  3. from __future__ import absolute_import, division
  4. import os
  5. import imp
  6. import sys
  7. from pip._vendor.six import text_type
  8. try:
  9. from logging.config import dictConfig as logging_dictConfig
  10. except ImportError:
  11. from pip.compat.dictconfig import dictConfig as logging_dictConfig
  12. try:
  13. import ipaddress
  14. except ImportError:
  15. from pip._vendor import ipaddress
  16. __all__ = [
  17. "logging_dictConfig", "ipaddress", "uses_pycache", "console_to_str",
  18. "native_str", "get_path_uid", "stdlib_pkgs", "WINDOWS",
  19. ]
  20. uses_pycache = hasattr(imp, 'cache_from_source')
  21. if sys.version_info >= (3,):
  22. def console_to_str(s):
  23. try:
  24. return s.decode(sys.__stdout__.encoding)
  25. except UnicodeDecodeError:
  26. return s.decode('utf_8')
  27. def native_str(s, replace=False):
  28. if isinstance(s, bytes):
  29. return s.decode('utf-8', 'replace' if replace else 'strict')
  30. return s
  31. else:
  32. def console_to_str(s):
  33. return s
  34. def native_str(s, replace=False):
  35. # Replace is ignored -- unicode to UTF-8 can't fail
  36. if isinstance(s, text_type):
  37. return s.encode('utf-8')
  38. return s
  39. def total_seconds(td):
  40. if hasattr(td, "total_seconds"):
  41. return td.total_seconds()
  42. else:
  43. val = td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6
  44. return val / 10 ** 6
  45. def get_path_uid(path):
  46. """
  47. Return path's uid.
  48. Does not follow symlinks:
  49. https://github.com/pypa/pip/pull/935#discussion_r5307003
  50. Placed this function in compat due to differences on AIX and
  51. Jython, that should eventually go away.
  52. :raises OSError: When path is a symlink or can't be read.
  53. """
  54. if hasattr(os, 'O_NOFOLLOW'):
  55. fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW)
  56. file_uid = os.fstat(fd).st_uid
  57. os.close(fd)
  58. else: # AIX and Jython
  59. # WARNING: time of check vulnerabity, but best we can do w/o NOFOLLOW
  60. if not os.path.islink(path):
  61. # older versions of Jython don't have `os.fstat`
  62. file_uid = os.stat(path).st_uid
  63. else:
  64. # raise OSError for parity with os.O_NOFOLLOW above
  65. raise OSError(
  66. "%s is a symlink; Will not return uid for symlinks" % path
  67. )
  68. return file_uid
  69. # packages in the stdlib that may have installation metadata, but should not be
  70. # considered 'installed'. this theoretically could be determined based on
  71. # dist.location (py27:`sysconfig.get_paths()['stdlib']`,
  72. # py26:sysconfig.get_config_vars('LIBDEST')), but fear platform variation may
  73. # make this ineffective, so hard-coding
  74. stdlib_pkgs = ['python', 'wsgiref']
  75. if sys.version_info >= (2, 7):
  76. stdlib_pkgs.extend(['argparse'])
  77. # windows detection, covers cpython and ironpython
  78. WINDOWS = (sys.platform.startswith("win") or
  79. (sys.platform == 'cli' and os.name == 'nt'))