[pywin32-bugs] [ pywin32-Bugs-1379557 ] problem with pywin32 and unicode
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
From: SourceForge.net <no...@so...> - 2005-12-14 09:54:04
|
Bugs item #1379557, was opened at 2005-12-13 15:56 Message generated for change (Comment added) made by halon You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=551954&aid=1379557&group_id=78018 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: com Group: None Status: Open Resolution: None Priority: 5 Submitted By: Dieter Verfaillie (halon) Assigned to: Mark Hammond (mhammond) Summary: problem with pywin32 and unicode Initial Comment: I had a problem with the following code, pywin32 Build 205 and unicode. The following: <code, without error handling for easy reading...> # active_directory.find_user() eventualy # calls GetObject('LDAP://...') and # returns the result. account_in_ad = active_directory.find_user('DNFtest') # init canonicalName field account_in_ad.GetInfoEx(['canonicalName'], 0) # print canonicalName field print '[found]', account_in_ad.GetEx("canonicalName")[0] </code> sometimes resulted in the following: <trace> Traceback (most recent call last): File "C:\Python24\lib\site-packages\win32com\client\dynamic.py", line 293, in _make_method_ codeObject = compile(methodCode, "<COMObject %s>" % self._username_,"exec") UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 66: ordinal not in range(128) </trace> Playing around with print statements showed that the call to GetInfoEx() triggered the backtrace. Looking deeper, self._username_ on line 293 in the file win32com/client/dynamic.py contained the unicode value: LDAP://CN=DNFtest,OU=16 H-Coördinatie & Veiligheid,OU=Unit Placeholder,DC=workplace,DC=be Note the o with the trema. That together with pythons compile() builtin used on that same line not liking unicode at all for the filename parameter caused the backtrace. As the second parameter (filename) to the compile builtin doesn't really matter when the code to compile does not come from a file, changing line 293 from: codeObject = compile(methodCode, "<COMObject %s>" % self._username_,"exec") to: codeObject = compile(methodCode, "<COMObject %s>" % self._username_.encode('ascii','replace'),"exec") solves this problem. Testing this change does not seem to have negative effects to other(older) code, so, eeerhm, whoohoo? I haven't looked if there are any other places where compile() is used yet, and if there are, maybe it would be a good idea to do this everywere, as long as the code to compile does not come from a file? with kind regards, Dieter Verfaillie ---------------------------------------------------------------------- >Comment By: Dieter Verfaillie (halon) Date: 2005-12-14 10:54 Message: Logged In: YES user_id=894731 I reverted my change and tried again with your function, but it didn't work (same traceback occuring on the same place as my original report). After some debugging I found out that the userName value sometimes contains the LDAP:// querystring. So the function you gave me never encodes userName. It only does that if userName is None, calculating userName from IDispatch. So taking that in account and adding an else to the if "userName is None:" part works. Like so: def _GetGoodDispatchAndUserName(IDispatch,userName,clsctx): #print userName if userName is None: if type(IDispatch) == StringType: userName = IDispatch elif type(IDispatch) == UnicodeType: # We always want the name displayed to the user to be a string userName = IDispatch.encode("ascii", "replace") else: userName = "<unknown>" else: if type(userName) == UnicodeType: userName = userName.encode("ascii", "replace") return (_GetGoodDispatch(IDispatch, clsctx), userName) ---------------------------------------------------------------------- Comment By: Mark Hammond (mhammond) Date: 2005-12-13 23:10 Message: Logged In: YES user_id=14198 Could you please try a different fix for me? Try reverting your change, and change the following function: def _GetGoodDispatchAndUserName(IDispatch,userName,clsctx): if userName is None: if type(IDispatch) == StringType: userName = IDispatch elif type(IDispatch) == UnicodeType: # We always want the name displayed to the user to be a string userName = IDispatch.encode("ascii", "replace") else: userName = "<unknown>" return (_GetGoodDispatch(IDispatch, clsctx), userName) Note the special handling of Unicode that will not exist in your version. This change should have the same affect, but should prevent you seeing other edge cases with the similar error, as this should ensure _username_ is *always* a string (not only when passed to compile) Thanks ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=551954&aid=1379557&group_id=78018 |