Skip to content

Commit

Permalink
Fixed issue when unable to get filesystem encoding.
Browse files Browse the repository at this point in the history
  • Loading branch information
fabioz committed Aug 9, 2012
1 parent a9ccd31 commit b03d938
Showing 1 changed file with 30 additions and 28 deletions.
58 changes: 30 additions & 28 deletions plugins/org.python.pydev/pysrc/interpreterInfo.py
Expand Up @@ -26,11 +26,11 @@ def fullyNormalizePath(path):
'''fixes the path so that the format of the path really reflects the directories in the system '''fixes the path so that the format of the path really reflects the directories in the system
''' '''
return path return path

def join(a, b): def join(a, b):
if a.endswith('/') or a.endswith('\\'): if a.endswith('/') or a.endswith('\\'):
return a + b return a + b
return a+'/'+b return a + '/' + b




IS_PYTHON_3K = 0 IS_PYTHON_3K = 0
Expand All @@ -48,17 +48,17 @@ def join(a, b):
True True
except: except:
exec ('True, False = 1,0') #An exec is used so that python 3k does not give a syntax error exec ('True, False = 1,0') #An exec is used so that python 3k does not give a syntax error

import time import time


if sys.platform == "cygwin": if sys.platform == "cygwin":

try: try:
import ctypes #use from the system if available import ctypes #use from the system if available
except ImportError: except ImportError:
sys.path.append(join(sys.path[0], 'third_party/wrapped_for_pydev')) sys.path.append(join(sys.path[0], 'third_party/wrapped_for_pydev'))
import ctypes import ctypes

def nativePath(path): def nativePath(path):
MAX_PATH = 512 # On cygwin NT, its 260 lately, but just need BIG ENOUGH buffer MAX_PATH = 512 # On cygwin NT, its 260 lately, but just need BIG ENOUGH buffer
'''Get the native form of the path, like c:\\Foo for /cygdrive/c/Foo''' '''Get the native form of the path, like c:\\Foo for /cygdrive/c/Foo'''
Expand All @@ -67,7 +67,7 @@ def nativePath(path):
path = fullyNormalizePath(path) path = fullyNormalizePath(path)
ctypes.cdll.cygwin1.cygwin_conv_to_win32_path(path, retval) #@UndefinedVariable ctypes.cdll.cygwin1.cygwin_conv_to_win32_path(path, retval) #@UndefinedVariable
return retval.value return retval.value

else: else:
def nativePath(path): def nativePath(path):
return fullyNormalizePath(path) return fullyNormalizePath(path)
Expand All @@ -76,43 +76,45 @@ def nativePath(path):


def getfilesystemencoding(): def getfilesystemencoding():
try: try:
return sys.getfilesystemencoding() ret = sys.getfilesystemencoding()

This comment has been minimized.

Copy link
@jim02762

jim02762 Aug 13, 2012

Might not be a bad idea to actually return the value!

This comment has been minimized.

Copy link
@fabioz

fabioz Aug 13, 2012

Author Contributor

duh

This comment has been minimized.

Copy link
@nadersoliman

nadersoliman Aug 13, 2012

@jim02762 -- problem is on a tested configuration eclipse-juno, aptana plugin, windows7 when configuring ironpython sys.getfilesystemencoding() returns None
sys.getfilesystemencoding() has some reported problems so no harm of one extra check to make sure things don't get bad

This comment has been minimized.

Copy link
@jim02762

jim02762 Aug 13, 2012

There's no harm with doing an extra check but if ret != None then you need to "return ret". As it stands now, if sys.getfilesystemencoding actually works then getfilesystemencoding() returns nothing, so file_system_encoding == None, so the decode in tounicode() fails, which prevents adding a Python an interpreter!

This comment has been minimized.

Copy link
@nadersoliman

nadersoliman Aug 13, 2012

good point, but ret = sys.getfilesystemencoding() is the last value and will be returned by default if it was not None otherwise the raise statement and except block will get kicked in

yet, your point is good though for readability :)

if not ret: raise RuntimeError('')
return ret

to make it more obvious

This comment has been minimized.

Copy link
@fabioz

fabioz Aug 13, 2012

Author Contributor

Actually, an empty string is not a valid encoding (that's why the check didn't explicitly check for None)

This comment has been minimized.

Copy link
@jim02762

jim02762 Aug 13, 2012

Where will it be returned? Python, unlike Perl, doesn't return the value of the last expression ... does it??? It sure doesn't seem to be under my Linux system's Python 2.7. The return is required or I get:

[20] jimc@zach> python -u /home/jimc/eclipse/plugins/org.python.pydev_2.7.0.2012080923/pysrc/interpreterInfo.py
Traceback (most recent call last):
File "/home/jimc/eclipse/plugins/org.python.pydev_2.7.0.2012080923/pysrc/interpreterInfo.py", line 130, in
s = tounicode('%s.%s') % (tounicode(major), tounicode(minor))
File "/home/jimc/eclipse/plugins/org.python.pydev_2.7.0.2012080923/pysrc/interpreterInfo.py", line 94, in tounicode
return s.decode(file_system_encoding)
TypeError: decode() argument 1 must be string, not None

This comment has been minimized.

Copy link
@fabioz

fabioz Aug 13, 2012

Author Contributor

This comment has been minimized.

Copy link
@nadersoliman

nadersoliman Aug 13, 2012

Thanks @fabioz & @jim02762 it looks great now :)

if not ret:
raise RuntimeError('Unable to get encoding.')
except: except:
#Only available from 2.3 onwards. #Only available from 2.3 onwards.
if sys.platform == 'win32': if sys.platform == 'win32':
return 'mbcs' return 'mbcs'
return 'utf-8' return 'utf-8'

file_system_encoding = getfilesystemencoding() file_system_encoding = getfilesystemencoding()


def tounicode(s): def tounicode(s):
if hasattr(s, 'decode'): if hasattr(s, 'decode'):
#Depending on the platform variant we may have decode on string or not. #Depending on the platform variant we may have decode on string or not.
return s.decode(file_system_encoding) return s.decode(file_system_encoding)
return s return s

def toutf8(s): def toutf8(s):
if hasattr(s, 'encode'): if hasattr(s, 'encode'):
return s.encode('utf-8') return s.encode('utf-8')
return s return s



if __name__ == '__main__': if __name__ == '__main__':
try: try:
#just give some time to get the reading threads attached (just in case) #just give some time to get the reading threads attached (just in case)
time.sleep(0.1) time.sleep(0.1)
except: except:
pass pass

try: try:
executable = nativePath(sys.executable) executable = nativePath(sys.executable)
except: except:
executable = sys.executable executable = sys.executable

if sys.platform == "cygwin" and not executable.endswith('.exe'): if sys.platform == "cygwin" and not executable.endswith('.exe'):
executable += '.exe' executable += '.exe'



try: try:
major = str(sys.version_info[0]) major = str(sys.version_info[0])
minor = str(sys.version_info[1]) minor = str(sys.version_info[1])
Expand All @@ -123,32 +125,32 @@ def toutf8(s):
s = string.split(s, '.') s = string.split(s, '.')
major = s[0] major = s[0]
minor = s[1] minor = s[1]

s = tounicode('%s.%s') % (tounicode(major), tounicode(minor)) s = tounicode('%s.%s') % (tounicode(major), tounicode(minor))

contents = [tounicode('<xml>')] contents = [tounicode('<xml>')]
contents.append(tounicode('<version>%s</version>') % (tounicode(s),)) contents.append(tounicode('<version>%s</version>') % (tounicode(s),))

contents.append(tounicode('<executable>%s</executable>') % tounicode(executable)) contents.append(tounicode('<executable>%s</executable>') % tounicode(executable))

#this is the new implementation to get the system folders #this is the new implementation to get the system folders
#(still need to check if it works in linux) #(still need to check if it works in linux)
#(previously, we were getting the executable dir, but that is not always correct...) #(previously, we were getting the executable dir, but that is not always correct...)
prefix = tounicode(nativePath(sys.prefix)) prefix = tounicode(nativePath(sys.prefix))
#print_ 'prefix is', prefix #print_ 'prefix is', prefix



result = [] result = []

path_used = sys.path path_used = sys.path
try: try:
path_used = path_used[:] #Use a copy. path_used = path_used[:] #Use a copy.
except: except:
pass #just ignore it... pass #just ignore it...

for p in path_used: for p in path_used:
p = tounicode(nativePath(p)) p = tounicode(nativePath(p))

try: try:
import string #to be compatible with older versions import string #to be compatible with older versions
if string.find(p, prefix) == 0: #was startswith if string.find(p, prefix) == 0: #was startswith
Expand All @@ -162,20 +164,20 @@ def toutf8(s):
result.append((p, True)) result.append((p, True))
else: else:
result.append((p, False)) result.append((p, False))

for p, b in result: for p, b in result:
if b: if b:
contents.append(tounicode('<lib path="ins">%s</lib>') % (p,)) contents.append(tounicode('<lib path="ins">%s</lib>') % (p,))
else: else:
contents.append(tounicode('<lib path="out">%s</lib>') % (p,)) contents.append(tounicode('<lib path="out">%s</lib>') % (p,))

#no compiled libs #no compiled libs
#nor forced libs #nor forced libs

for builtinMod in sys.builtin_module_names: for builtinMod in sys.builtin_module_names:
contents.append(tounicode('<forced_lib>%s</forced_lib>') % tounicode(builtinMod)) contents.append(tounicode('<forced_lib>%s</forced_lib>') % tounicode(builtinMod))


contents.append(tounicode('</xml>')) contents.append(tounicode('</xml>'))
unic = tounicode('\n').join(contents) unic = tounicode('\n').join(contents)
inutf8 = toutf8(unic) inutf8 = toutf8(unic)
Expand All @@ -184,13 +186,13 @@ def toutf8(s):
sys.stdout.buffer.write(inutf8) sys.stdout.buffer.write(inutf8)
else: else:
sys.stdout.write(inutf8) sys.stdout.write(inutf8)

try: try:
sys.stdout.flush() sys.stdout.flush()
sys.stderr.flush() sys.stderr.flush()
#and give some time to let it read things (just in case) #and give some time to let it read things (just in case)
time.sleep(0.1) time.sleep(0.1)
except: except:
pass pass

raise RuntimeError('Ok, this is so that it shows the output (ugly hack for some platforms, so that it releases the output).') raise RuntimeError('Ok, this is so that it shows the output (ugly hack for some platforms, so that it releases the output).')

0 comments on commit b03d938

Please sign in to comment.