1import sys 2 3from typing import AnyStr 4from typing import List 5from typing import Optional 6from typing import Union 7 8import six.moves.urllib.parse as urllib_parse 9 10 11urlparse = urllib_parse 12 13 14try: # Python 2 15 long = long 16 unicode = unicode 17 basestring = basestring 18except NameError: # Python 3 19 long = int 20 unicode = str 21 basestring = str 22 23 24PY2 = sys.version_info[0] == 2 25PY34 = sys.version_info >= (3, 4) 26PY35 = sys.version_info >= (3, 5) 27PY36 = sys.version_info >= (3, 6) 28PY37 = sys.version_info >= (3, 7) 29 30WINDOWS = sys.platform == "win32" 31 32if PY2: 33 import pipes 34 35 shell_quote = pipes.quote 36else: 37 import shlex 38 39 shell_quote = shlex.quote 40 41if PY35: 42 from pathlib import Path # noqa 43else: 44 from pathlib2 import Path # noqa 45 46if not PY36: 47 from collections import OrderedDict # noqa 48else: 49 OrderedDict = dict 50 51 52try: 53 FileNotFoundError 54except NameError: 55 FileNotFoundError = IOError # noqa 56 57 58def decode( 59 string, encodings=None 60): # type: (Union[AnyStr, unicode], Optional[str]) -> Union[str, bytes] 61 if not PY2 and not isinstance(string, bytes): 62 return string 63 64 if PY2 and isinstance(string, unicode): 65 return string 66 67 encodings = encodings or ["utf-8", "latin1", "ascii"] 68 69 for encoding in encodings: 70 try: 71 return string.decode(encoding) 72 except (UnicodeEncodeError, UnicodeDecodeError): 73 pass 74 75 return string.decode(encodings[0], errors="ignore") 76 77 78def encode( 79 string, encodings=None 80): # type: (AnyStr, Optional[str]) -> Union[str, bytes] 81 if not PY2 and isinstance(string, bytes): 82 return string 83 84 if PY2 and isinstance(string, str): 85 return string 86 87 encodings = encodings or ["utf-8", "latin1", "ascii"] 88 89 for encoding in encodings: 90 try: 91 return string.encode(encoding) 92 except (UnicodeEncodeError, UnicodeDecodeError): 93 pass 94 95 return string.encode(encodings[0], errors="ignore") 96 97 98def to_str(string): # type: (AnyStr) -> str 99 if isinstance(string, str) or not isinstance(string, (unicode, bytes)): 100 return string 101 102 if PY2: 103 method = "encode" 104 else: 105 method = "decode" 106 107 encodings = ["utf-8", "latin1", "ascii"] 108 109 for encoding in encodings: 110 try: 111 return getattr(string, method)(encoding) 112 except (UnicodeEncodeError, UnicodeDecodeError): 113 pass 114 115 return getattr(string, method)(encodings[0], errors="ignore") 116 117 118def list_to_shell_command(cmd): # type: (List[str]) -> str 119 executable = cmd[0] 120 121 if " " in executable: 122 executable = '"{}"'.format(executable) 123 cmd[0] = executable 124 125 return " ".join(cmd) 126