| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 1 | ''' |
| 2 | This module was created to get information available in the interpreter, such as libraries, |
| 3 | paths, etc. |
| 4 | |
| 5 | what is what: |
| 6 | sys.builtin_module_names: contains the builtin modules embeeded in python (rigth now, we specify all manually). |
| 7 | sys.prefix: A string giving the site-specific directory prefix where the platform independent Python files are installed |
| 8 | |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 9 | format is something as |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 10 | EXECUTABLE:python.exe|libs@compiled_dlls$builtin_mods |
| 11 | |
| 12 | all internal are separated by | |
| 13 | ''' |
| 14 | import sys |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 15 | |
| 16 | try: |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 17 | import os.path |
| 18 | def fullyNormalizePath(path): |
| 19 | '''fixes the path so that the format of the path really reflects the directories in the system |
| 20 | ''' |
| 21 | return os.path.normpath(path) |
| 22 | join = os.path.join |
| 23 | except: # ImportError or AttributeError. |
| 24 | # See: http://stackoverflow.com/questions/10254353/error-while-installing-jython-for-pydev |
| 25 | def fullyNormalizePath(path): |
| 26 | '''fixes the path so that the format of the path really reflects the directories in the system |
| 27 | ''' |
| 28 | return path |
| 29 | |
| 30 | def join(a, b): |
| 31 | if a.endswith('/') or a.endswith('\\'): |
| 32 | return a + b |
| 33 | return a + '/' + b |
| 34 | |
| 35 | |
| 36 | IS_PYTHON_3K = 0 |
| 37 | |
| 38 | try: |
| 39 | if sys.version_info[0] == 3: |
| 40 | IS_PYTHON_3K = 1 |
| 41 | except: |
| 42 | # That's OK, not all versions of python have sys.version_info |
| 43 | pass |
| 44 | |
| 45 | try: |
| 46 | # Just check if False and True are defined (depends on version, not whether it's jython/python) |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 47 | False |
| 48 | True |
| 49 | except: |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 50 | exec ('True, False = 1,0') # An exec is used so that python 3k does not give a syntax error |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 51 | |
| 52 | if sys.platform == "cygwin": |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 53 | |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 54 | try: |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 55 | import ctypes # use from the system if available |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 56 | except ImportError: |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 57 | sys.path.append(join(sys.path[0], 'third_party/wrapped_for_pydev')) |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 58 | import ctypes |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 59 | |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 60 | def nativePath(path): |
| 61 | MAX_PATH = 512 # On cygwin NT, its 260 lately, but just need BIG ENOUGH buffer |
| 62 | '''Get the native form of the path, like c:\\Foo for /cygdrive/c/Foo''' |
| 63 | |
| 64 | retval = ctypes.create_string_buffer(MAX_PATH) |
| 65 | path = fullyNormalizePath(path) |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 66 | CCP_POSIX_TO_WIN_A = 0 |
| 67 | ctypes.cdll.cygwin1.cygwin_conv_path(CCP_POSIX_TO_WIN_A, path, retval, MAX_PATH) |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 68 | |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 69 | return retval.value |
| 70 | |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 71 | else: |
| 72 | def nativePath(path): |
| 73 | return fullyNormalizePath(path) |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 74 | |
| 75 | |
| 76 | |
| 77 | def __getfilesystemencoding(): |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 78 | ''' |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 79 | Note: there's a copy of this method in _pydev_filesystem_encoding.py |
| 80 | ''' |
| 81 | try: |
| 82 | ret = sys.getfilesystemencoding() |
| 83 | if not ret: |
| 84 | raise RuntimeError('Unable to get encoding.') |
| 85 | return ret |
| 86 | except: |
| 87 | try: |
| 88 | # Handle Jython |
| 89 | from java.lang import System |
| 90 | env = System.getProperty("os.name").lower() |
| 91 | if env.find('win') != -1: |
| 92 | return 'ISO-8859-1' # mbcs does not work on Jython, so, use a (hopefully) suitable replacement |
| 93 | return 'utf-8' |
| 94 | except: |
| 95 | pass |
| 96 | |
| 97 | # Only available from 2.3 onwards. |
| 98 | if sys.platform == 'win32': |
| 99 | return 'mbcs' |
| 100 | return 'utf-8' |
| 101 | |
| 102 | def getfilesystemencoding(): |
| 103 | try: |
| 104 | ret = __getfilesystemencoding() |
| 105 | |
| 106 | #Check if the encoding is actually there to be used! |
| 107 | if hasattr('', 'encode'): |
| 108 | ''.encode(ret) |
| 109 | if hasattr('', 'decode'): |
| 110 | ''.decode(ret) |
| 111 | |
| 112 | return ret |
| 113 | except: |
| 114 | return 'utf-8' |
| 115 | |
| 116 | file_system_encoding = getfilesystemencoding() |
| 117 | |
| 118 | def tounicode(s): |
| 119 | if hasattr(s, 'decode'): |
| 120 | # Depending on the platform variant we may have decode on string or not. |
| 121 | return s.decode(file_system_encoding) |
| 122 | return s |
| 123 | |
| 124 | def toutf8(s): |
| 125 | if hasattr(s, 'encode'): |
| 126 | return s.encode('utf-8') |
| 127 | return s |
| 128 | |
| 129 | def toasciimxl(s): |
| 130 | # output for xml without a declared encoding |
| 131 | |
| 132 | # As the output is xml, we have to encode chars (< and > are ok as they're not accepted in the filesystem name -- |
| 133 | # if it was allowed, we'd have to do things more selectively so that < and > don't get wrongly replaced). |
| 134 | s = s.replace("&", "&") |
| 135 | |
| 136 | try: |
| 137 | ret = s.encode('ascii', 'xmlcharrefreplace') |
| 138 | except: |
| 139 | # use workaround |
| 140 | ret = '' |
| 141 | for c in s: |
| 142 | try: |
| 143 | ret += c.encode('ascii') |
| 144 | except: |
| 145 | try: |
| 146 | # Python 2: unicode is a valid identifier |
| 147 | ret += unicode("&#%d;") % ord(c) |
| 148 | except: |
| 149 | # Python 3: a string is already unicode, so, just doing it directly should work. |
| 150 | ret += "&#%d;" % ord(c) |
| 151 | return ret |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 152 | |
| 153 | |
| 154 | if __name__ == '__main__': |
| 155 | try: |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 156 | # just give some time to get the reading threads attached (just in case) |
| 157 | import time |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 158 | time.sleep(0.1) |
| 159 | except: |
| 160 | pass |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 161 | |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 162 | try: |
| 163 | executable = nativePath(sys.executable) |
| 164 | except: |
| 165 | executable = sys.executable |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 166 | |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 167 | if sys.platform == "cygwin" and not executable.endswith('.exe'): |
| 168 | executable += '.exe' |
| 169 | |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 170 | |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 171 | try: |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 172 | major = str(sys.version_info[0]) |
| 173 | minor = str(sys.version_info[1]) |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 174 | except AttributeError: |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 175 | # older versions of python don't have version_info |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 176 | import string |
| 177 | s = string.split(sys.version, ' ')[0] |
| 178 | s = string.split(s, '.') |
| 179 | major = s[0] |
| 180 | minor = s[1] |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 181 | |
| 182 | s = tounicode('%s.%s') % (tounicode(major), tounicode(minor)) |
| 183 | |
| 184 | contents = [tounicode('<xml>')] |
| 185 | contents.append(tounicode('<version>%s</version>') % (tounicode(s),)) |
| 186 | |
| 187 | contents.append(tounicode('<executable>%s</executable>') % tounicode(executable)) |
| 188 | |
| 189 | # this is the new implementation to get the system folders |
| 190 | # (still need to check if it works in linux) |
| 191 | # (previously, we were getting the executable dir, but that is not always correct...) |
| 192 | prefix = tounicode(nativePath(sys.prefix)) |
| 193 | # print_ 'prefix is', prefix |
| 194 | |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 195 | |
| 196 | result = [] |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 197 | |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 198 | path_used = sys.path |
| 199 | try: |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 200 | path_used = path_used[1:] # Use a copy (and don't include the directory of this script as a path.) |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 201 | except: |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 202 | pass # just ignore it... |
| 203 | |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 204 | for p in path_used: |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 205 | p = tounicode(nativePath(p)) |
| 206 | |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 207 | try: |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 208 | import string # to be compatible with older versions |
| 209 | if string.find(p, prefix) == 0: # was startswith |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 210 | result.append((p, True)) |
| 211 | else: |
| 212 | result.append((p, False)) |
| 213 | except (ImportError, AttributeError): |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 214 | # python 3k also does not have it |
| 215 | # jython may not have it (depending on how are things configured) |
| 216 | if p.startswith(prefix): # was startswith |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 217 | result.append((p, True)) |
| 218 | else: |
| 219 | result.append((p, False)) |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 220 | |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 221 | for p, b in result: |
| 222 | if b: |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 223 | contents.append(tounicode('<lib path="ins">%s</lib>') % (p,)) |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 224 | else: |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 225 | contents.append(tounicode('<lib path="out">%s</lib>') % (p,)) |
| 226 | |
| 227 | # no compiled libs |
| 228 | # nor forced libs |
| 229 | |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 230 | for builtinMod in sys.builtin_module_names: |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 231 | contents.append(tounicode('<forced_lib>%s</forced_lib>') % tounicode(builtinMod)) |
| 232 | |
| 233 | |
| 234 | contents.append(tounicode('</xml>')) |
| 235 | unic = tounicode('\n').join(contents) |
| 236 | inasciixml = toasciimxl(unic) |
| 237 | if IS_PYTHON_3K: |
| 238 | # This is the 'official' way of writing binary output in Py3K (see: http://bugs.python.org/issue4571) |
| 239 | sys.stdout.buffer.write(inasciixml) |
| 240 | else: |
| 241 | sys.stdout.write(inasciixml) |
| 242 | |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 243 | try: |
| 244 | sys.stdout.flush() |
| 245 | sys.stderr.flush() |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 246 | # and give some time to let it read things (just in case) |
| 247 | import time |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 248 | time.sleep(0.1) |
| 249 | except: |
| 250 | pass |
| Tor Norbye | c667c1f | 2014-05-28 17:06:51 -0700 | [diff] [blame^] | 251 | |
| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame] | 252 | raise RuntimeError('Ok, this is so that it shows the output (ugly hack for some platforms, so that it releases the output).') |