Development of an internal social media platform with personalised dashboards for students
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.

compat.py 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. """Compatibility wrappers for Py2/Py3."""
  2. import sys
  3. import os
  4. if sys.version_info[0] < 3:
  5. from UserDict import UserDict, IterableUserDict
  6. from urllib import quote
  7. from urllib import quote_plus
  8. from urllib import unquote as urllib_unquote
  9. from urllib import urlopen
  10. from urlparse import urlparse
  11. def unquote(uri):
  12. """Specialized unquote that uses UTF-8 for parsing."""
  13. uri = uri.encode('ascii')
  14. unquoted = urllib_unquote(uri)
  15. return unquoted.decode('utf-8')
  16. # Old-style of re-raising an exception is SyntaxError in Python 3,
  17. # so hide behind exec() so the Python 3 parser doesn't see it
  18. exec('''def reraise(exc_type, exc_value, exc_traceback):
  19. """Re-raise an exception given information from sys.exc_info()
  20. Note that unlike six.reraise, this does not support replacing the
  21. traceback. All arguments must come from a single sys.exc_info() call.
  22. """
  23. raise exc_type, exc_value, exc_traceback
  24. ''')
  25. else:
  26. from collections import UserDict
  27. IterableUserDict = UserDict
  28. from urllib.parse import quote, quote_plus, unquote, urlparse
  29. from urllib.request import urlopen
  30. def reraise(exc_type, exc_value, exc_traceback):
  31. """Re-raise an exception given information from sys.exc_info()
  32. Note that unlike six.reraise, this does not support replacing the
  33. traceback. All arguments must come from a single sys.exc_info() call.
  34. """
  35. # In Python 3, all exception info is contained in one object.
  36. raise exc_value
  37. try:
  38. from shutil import which
  39. except ImportError:
  40. # shutil.which() from Python 3.6
  41. # "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
  42. # 2011, 2012, 2013, 2014, 2015, 2016, 2017 Python Software Foundation;
  43. # All Rights Reserved"
  44. def which(cmd, mode=os.F_OK | os.X_OK, path=None):
  45. """Given a command, mode, and a PATH string, return the path which
  46. conforms to the given mode on the PATH, or None if there is no such
  47. file.
  48. `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result
  49. of os.environ.get("PATH"), or can be overridden with a custom search
  50. path.
  51. """
  52. # Check that a given file can be accessed with the correct mode.
  53. # Additionally check that `file` is not a directory, as on Windows
  54. # directories pass the os.access check.
  55. def _access_check(fn, mode):
  56. return (os.path.exists(fn) and os.access(fn, mode)
  57. and not os.path.isdir(fn))
  58. # If we're given a path with a directory part, look it up directly rather
  59. # than referring to PATH directories. This includes checking relative to the
  60. # current directory, e.g. ./script
  61. if os.path.dirname(cmd):
  62. if _access_check(cmd, mode):
  63. return cmd
  64. return None
  65. if path is None:
  66. path = os.environ.get("PATH", os.defpath)
  67. if not path:
  68. return None
  69. path = path.split(os.pathsep)
  70. if sys.platform == "win32":
  71. # The current directory takes precedence on Windows.
  72. if not os.curdir in path:
  73. path.insert(0, os.curdir)
  74. # PATHEXT is necessary to check on Windows.
  75. pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
  76. # See if the given file matches any of the expected path extensions.
  77. # This will allow us to short circuit when given "python.exe".
  78. # If it does match, only test that one, otherwise we have to try
  79. # others.
  80. if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
  81. files = [cmd]
  82. else:
  83. files = [cmd + ext for ext in pathext]
  84. else:
  85. # On other platforms you don't have things like PATHEXT to tell you
  86. # what file suffixes are executable, so just pass on cmd as-is.
  87. files = [cmd]
  88. seen = set()
  89. for dir in path:
  90. normdir = os.path.normcase(dir)
  91. if not normdir in seen:
  92. seen.add(normdir)
  93. for thefile in files:
  94. name = os.path.join(dir, thefile)
  95. if _access_check(name, mode):
  96. return name
  97. return None