blob: 103253e62600e4def3dc2e2d72501d2fa1a369b6 [file] [log] [blame]
Tor Norbye3a2425a2013-11-04 10:16:08 -08001'''
2This module was created to get information available in the interpreter, such as libraries,
3paths, etc.
4
5what is what:
6sys.builtin_module_names: contains the builtin modules embeeded in python (rigth now, we specify all manually).
7sys.prefix: A string giving the site-specific directory prefix where the platform independent Python files are installed
8
Tor Norbyec667c1f2014-05-28 17:06:51 -07009format is something as
Tor Norbye3a2425a2013-11-04 10:16:08 -080010EXECUTABLE:python.exe|libs@compiled_dlls$builtin_mods
11
12all internal are separated by |
13'''
14import sys
Tor Norbye3a2425a2013-11-04 10:16:08 -080015
16try:
Tor Norbyec667c1f2014-05-28 17:06:51 -070017 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
23except: # 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
36IS_PYTHON_3K = 0
37
38try:
39 if sys.version_info[0] == 3:
40 IS_PYTHON_3K = 1
41except:
42 # That's OK, not all versions of python have sys.version_info
43 pass
44
45try:
46 # Just check if False and True are defined (depends on version, not whether it's jython/python)
Tor Norbye3a2425a2013-11-04 10:16:08 -080047 False
48 True
49except:
Tor Norbyec667c1f2014-05-28 17:06:51 -070050 exec ('True, False = 1,0') # An exec is used so that python 3k does not give a syntax error
Tor Norbye3a2425a2013-11-04 10:16:08 -080051
52if sys.platform == "cygwin":
Tor Norbyec667c1f2014-05-28 17:06:51 -070053
Tor Norbye3a2425a2013-11-04 10:16:08 -080054 try:
Tor Norbyec667c1f2014-05-28 17:06:51 -070055 import ctypes # use from the system if available
Tor Norbye3a2425a2013-11-04 10:16:08 -080056 except ImportError:
Tor Norbyec667c1f2014-05-28 17:06:51 -070057 sys.path.append(join(sys.path[0], 'third_party/wrapped_for_pydev'))
Tor Norbye3a2425a2013-11-04 10:16:08 -080058 import ctypes
Tor Norbyec667c1f2014-05-28 17:06:51 -070059
Tor Norbye3a2425a2013-11-04 10:16:08 -080060 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 Norbyec667c1f2014-05-28 17:06:51 -070066 CCP_POSIX_TO_WIN_A = 0
67 ctypes.cdll.cygwin1.cygwin_conv_path(CCP_POSIX_TO_WIN_A, path, retval, MAX_PATH)
Tor Norbye3a2425a2013-11-04 10:16:08 -080068
Tor Norbyec667c1f2014-05-28 17:06:51 -070069 return retval.value
70
Tor Norbye3a2425a2013-11-04 10:16:08 -080071else:
72 def nativePath(path):
73 return fullyNormalizePath(path)
Tor Norbyec667c1f2014-05-28 17:06:51 -070074
75
76
77def __getfilesystemencoding():
Tor Norbye3a2425a2013-11-04 10:16:08 -080078 '''
Tor Norbyec667c1f2014-05-28 17:06:51 -070079 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
102def 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
116file_system_encoding = getfilesystemencoding()
117
118def 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
124def toutf8(s):
125 if hasattr(s, 'encode'):
126 return s.encode('utf-8')
127 return s
128
129def 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("&", "&amp;")
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 Norbye3a2425a2013-11-04 10:16:08 -0800152
153
154if __name__ == '__main__':
155 try:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700156 # just give some time to get the reading threads attached (just in case)
157 import time
Tor Norbye3a2425a2013-11-04 10:16:08 -0800158 time.sleep(0.1)
159 except:
160 pass
Tor Norbyec667c1f2014-05-28 17:06:51 -0700161
Tor Norbye3a2425a2013-11-04 10:16:08 -0800162 try:
163 executable = nativePath(sys.executable)
164 except:
165 executable = sys.executable
Tor Norbyec667c1f2014-05-28 17:06:51 -0700166
Tor Norbye3a2425a2013-11-04 10:16:08 -0800167 if sys.platform == "cygwin" and not executable.endswith('.exe'):
168 executable += '.exe'
169
Tor Norbyec667c1f2014-05-28 17:06:51 -0700170
Tor Norbye3a2425a2013-11-04 10:16:08 -0800171 try:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700172 major = str(sys.version_info[0])
173 minor = str(sys.version_info[1])
Tor Norbye3a2425a2013-11-04 10:16:08 -0800174 except AttributeError:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700175 # older versions of python don't have version_info
Tor Norbye3a2425a2013-11-04 10:16:08 -0800176 import string
177 s = string.split(sys.version, ' ')[0]
178 s = string.split(s, '.')
179 major = s[0]
180 minor = s[1]
Tor Norbyec667c1f2014-05-28 17:06:51 -0700181
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 Norbye3a2425a2013-11-04 10:16:08 -0800195
196 result = []
Tor Norbyec667c1f2014-05-28 17:06:51 -0700197
Tor Norbye3a2425a2013-11-04 10:16:08 -0800198 path_used = sys.path
199 try:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700200 path_used = path_used[1:] # Use a copy (and don't include the directory of this script as a path.)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800201 except:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700202 pass # just ignore it...
203
Tor Norbye3a2425a2013-11-04 10:16:08 -0800204 for p in path_used:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700205 p = tounicode(nativePath(p))
206
Tor Norbye3a2425a2013-11-04 10:16:08 -0800207 try:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700208 import string # to be compatible with older versions
209 if string.find(p, prefix) == 0: # was startswith
Tor Norbye3a2425a2013-11-04 10:16:08 -0800210 result.append((p, True))
211 else:
212 result.append((p, False))
213 except (ImportError, AttributeError):
Tor Norbyec667c1f2014-05-28 17:06:51 -0700214 # 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 Norbye3a2425a2013-11-04 10:16:08 -0800217 result.append((p, True))
218 else:
219 result.append((p, False))
Tor Norbyec667c1f2014-05-28 17:06:51 -0700220
Tor Norbye3a2425a2013-11-04 10:16:08 -0800221 for p, b in result:
222 if b:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700223 contents.append(tounicode('<lib path="ins">%s</lib>') % (p,))
Tor Norbye3a2425a2013-11-04 10:16:08 -0800224 else:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700225 contents.append(tounicode('<lib path="out">%s</lib>') % (p,))
226
227 # no compiled libs
228 # nor forced libs
229
Tor Norbye3a2425a2013-11-04 10:16:08 -0800230 for builtinMod in sys.builtin_module_names:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700231 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 Norbye3a2425a2013-11-04 10:16:08 -0800243 try:
244 sys.stdout.flush()
245 sys.stderr.flush()
Tor Norbyec667c1f2014-05-28 17:06:51 -0700246 # and give some time to let it read things (just in case)
247 import time
Tor Norbye3a2425a2013-11-04 10:16:08 -0800248 time.sleep(0.1)
249 except:
250 pass
Tor Norbyec667c1f2014-05-28 17:06:51 -0700251
Tor Norbye3a2425a2013-11-04 10:16:08 -0800252 raise RuntimeError('Ok, this is so that it shows the output (ugly hack for some platforms, so that it releases the output).')