From: David H. <dh...@vt...> - 2005-03-02 17:30:41
|
I am attempting to connect to a directory using SASL EXTERNAL with Python (my version, from Debian packages, is 2.1.3) and python-ldap-2.0.6. With both my code and the python-ldap-2.0.6/Demo/sasl_bind.py example, I get the following exception: Traceback (most recent call last): File "sasl_bind.py", line 69, in ? l.sasl_interactive_bind_s("", sasl_auth) File "/usr/lib/python2.1/site-packages/ldap/ldapobject.py", line 196, in sasl_interactive_bind_s return self._ldap_call(self._l.sasl_interactive_bind_s,who,auth,serverctrls,clientctrls ,sasl_flags) File "/usr/lib/python2.1/site-packages/ldap/ldapobject.py", line 94, in _ldap_call result = func(*args,**kwargs) TypeError: argument 5 must be impossible<bad format char>, not int Argument 5 is sasl_flags, which seems to be ldap.SASL_QUIET by default. The TypeError output changes when I send sasl_interactive_bind_s different values for the sasl_flags argument. python-ldap is linked against OpenLDAP-2.2.23 (compiled with SSL and SASL support), and ldap.TLS_AVAIL and ldap.SASL_AVAIL both have 1 as their value. The OpenLDAP tools work as expected. python-ldap works as expected when not using SASL. Has anyone seen similar errors? What can I try to fix these errors? Thanks for the help, dave |
From: Deepak G. <de...@ar...> - 2005-03-02 20:10:50
Attachments:
ldap_sasl_typerror_fix.patch
|
Hi, Dave! I've reproduced your bug, and I've attached a patch that fixes the problem. It might interest you to know that this bug doesn't affect more recent versions of Python, for what that's worth. :) The long answer: On Wed, 2005-03-02 at 12:30 -0500, David Hawes wrote: > Traceback (most recent call last): > File "sasl_bind.py", line 69, in ? > l.sasl_interactive_bind_s("", sasl_auth) > File "/usr/lib/python2.1/site-packages/ldap/ldapobject.py", line 196, in > sasl_interactive_bind_s return > self._ldap_call(self._l.sasl_interactive_bind_s,who,auth,serverctrls,clientctrls > ,sasl_flags) > File "/usr/lib/python2.1/site-packages/ldap/ldapobject.py", line > 94, in _ldap_call > result = func(*args,**kwargs) > TypeError: argument 5 must be impossible<bad format char>, not int Eek! This looks like a bug in the C code. The function that throws this error is PyArg_ParseTuple, a C function bundled with Python that takes Python objects and converts them to vanilla C-types. The offending bit looks to be lines 648-649 in LDAPObject.c: if (!PyArg_ParseTuple(args, "sOOOI", &who, &SASLObject, &serverctrls, &clientctrls, &sasl_flags )) return NULL; The 'sasl_flags' variable is declared as an unsigned int, but it looks like we're trying to convert it using the "I" flag, which is meant to convert longs. Replacing that "I" with "i" tells Python to convert that argument to an int (rather than a long), and it seems to do the trick. More info on these arcane conversion flags (for the curious): http://docs.python.org/api/arg-parsing.html Don't you just love C programming? :) The fix makes Python 2.1.3 work again, and the fix doesn't appear to break anything for more recent versions of Python (which, as I said, don't seem to suffer from the problem). Can you try the patch and let me know if it fixes things for you? Thanks, Dave! Cheers! deepak -- Deepak Giridharagopal Applied Research Laboratories University of Texas at Austin |
From: David H. <dh...@vt...> - 2005-03-02 20:28:44
|
Deepak, Thank you for the patch and the explanation--I was working my way towards that, but it would have taken a bit longer to poinpoint it... ;) The patch works perfectly and my SASL EXTERNAL bind works as expected. Thanks again for the help. dave On Wednesday 02 March 2005 15:11, Deepak Giridharagopal wrote: > Hi, Dave! > > I've reproduced your bug, and I've attached a patch that fixes the > problem. It might interest you to know that this bug doesn't affect more > recent versions of Python, for what that's worth. :) > > The long answer: > > On Wed, 2005-03-02 at 12:30 -0500, David Hawes wrote: > > Traceback (most recent call last): > > File "sasl_bind.py", line 69, in ? > > l.sasl_interactive_bind_s("", sasl_auth) > > File "/usr/lib/python2.1/site-packages/ldap/ldapobject.py", line 196, > > in sasl_interactive_bind_s return > > self._ldap_call(self._l.sasl_interactive_bind_s,who,auth,serverctrls,clie > >ntctrls ,sasl_flags) > > File "/usr/lib/python2.1/site-packages/ldap/ldapobject.py", line > > 94, in _ldap_call > > result = func(*args,**kwargs) > > TypeError: argument 5 must be impossible<bad format char>, not int > > Eek! This looks like a bug in the C code. The function that throws this > error is PyArg_ParseTuple, a C function bundled with Python that takes > Python objects and converts them to vanilla C-types. > > The offending bit looks to be lines 648-649 in LDAPObject.c: > > if (!PyArg_ParseTuple(args, "sOOOI", &who, &SASLObject, &serverctrls, > &clientctrls, &sasl_flags )) > return NULL; > > The 'sasl_flags' variable is declared as an unsigned int, but it looks > like we're trying to convert it using the "I" flag, which is meant to > convert longs. Replacing that "I" with "i" tells Python to convert that > argument to an int (rather than a long), and it seems to do the trick. > > More info on these arcane conversion flags (for the curious): > http://docs.python.org/api/arg-parsing.html > > Don't you just love C programming? :) > > The fix makes Python 2.1.3 work again, and the fix doesn't appear to > break anything for more recent versions of Python (which, as I said, > don't seem to suffer from the problem). > > Can you try the patch and let me know if it fixes things for you? > Thanks, Dave! > > Cheers! > deepak > > -- > Deepak Giridharagopal > Applied Research Laboratories > University of Texas at Austin |
From: Deepak G. <de...@ar...> - 2005-03-02 23:06:28
Attachments:
ldap_sasl_typerror_fix.patch
|
On Wed, 2005-03-02 at 14:11 -0600, Deepak Giridharagopal wrote: > The 'sasl_flags' variable is declared as an unsigned int, but it looks > like we're trying to convert it using the "I" flag, which is meant to > convert longs. Replacing that "I" with "i" tells Python to convert that > argument to an int (rather than a long), and it seems to do the trick. Upon further research, it looks like in Python 2.3 (and later) the "I" flag will *either* convert the argument to a long *or* an unsigned int. In previous versions of Python, "I" will attempt to always convert to a long (resulting in the TypeError). I guess this definitively solves the mystery as to why the bug doesn't occur in 2.3 and above... So I've (slightly) re-worked the patch to examine what version of Python is being used and react accordingly. Cheers! deepak -- Deepak Giridharagopal Applied Research Laboratories University of Texas at Austin |
From: <mi...@st...> - 2005-03-03 05:58:00
|
Deepak Giridharagopal wrote: > > Upon further research, it looks like in Python 2.3 (and later) the "I" > flag will *either* convert the argument to a long *or* an unsigned int. > In previous versions of Python, "I" will attempt to always convert to a > long (resulting in the TypeError). > [..] > So I've (slightly) re-worked the patch to examine what version of Python > is being used and react accordingly. No easy way to make it work without another #if ? Please commit your patch. Ciao, Michael. |
From: Deepak G. <de...@ar...> - 2005-03-03 20:07:40
Attachments:
ldap_sasl_typerror_fix.patch
|
On Thu, 2005-03-03 at 01:45 +0100, Michael Str=F6der wrote: > No easy way to make it work without another #if ? It took me a while to find it (I didn't know it existed!), but there is a function, Py_GetVersion, that will give you a version string (similar to sys.version). The third character is always the minor version number, so it looks like we can use that as an alternative to the #if. This patch is a little longer than the previous one, but it works just as well. Plus, this way we're doing a run-time check instead of a compile-time check. This will let people upgrade to Python 2.3+ without having to recompile python-ldap. I've attached the patch for posterity's sake, but I've gone ahead and commited the change to CVS. Good suggestion, Michael. :) Cheers! deepak -- Deepak Giridharagopal Applied Research Laboratories University of Texas at Austin |
From: <mi...@st...> - 2005-03-04 12:12:32
|
Deepak Giridharagopal wrote: > On Thu, 2005-03-03 at 01:45 +0100, Michael Ströder wrote: > >>No easy way to make it work without another #if ? > > It took me a while to find it (I didn't know it existed!), but there is > a function, Py_GetVersion, Sorry, I meant a solution without checking the Python version at all. > This patch is a little longer than the previous one, but it works just > as well. Plus, this way we're doing a run-time check instead of a > compile-time check. If we have to check the Python version a compile-time check would be the preferred solution (see below why). > This will let people upgrade to Python 2.3+ without > having to recompile python-ldap. Extension modules are not binary-compatible between media versions of Python. A module compiled for 2.2 cannot run under Python 2.3 without being rebuilt. Ciao, Michael. |
From: Deepak G. <de...@ar...> - 2005-03-04 18:29:09
Attachments:
ldap_sasl_typerror_fix.patch
|
On Fri, 2005-03-04 at 13:12 +0100, Michael Str=F6der wrote: > Extension modules are not binary-compatible between media versions of=20 > Python. A module compiled for 2.2 cannot run under Python 2.3 without=20 > being rebuilt. Hmmm, didn't realize that. I will now wave my magic wand and we'll all pretend I never sent out that last message. :) On Fri, 2005-03-04 at 14:29 +0100, Mauro Cicognini wrote:=20 > Moreover, reading the code it appears to me that checking just the mino= r=20 > version means that as written it will only work within the 2.x branch.=20 > Of course there's no telling what will happen in the time coming, so=20 > this point can be moot, but I would advise for checking the major=20 > version also. When Python 3000 comes out it will have python-ldap as part of the standard library and our work will be done! ;) Checking the major version is trivial to do; I just didn't include it as python-ldap won't work with 1.x (right?), and I assumed that Python 3.x will require some major structural changes in the entire codebase. I take your point, though. Does anyone have any objections to the attached patch, then? Cheers! deepak -- Deepak Giridharagopal Applied Research Laboratories University of Texas at Austin |
From: <mi...@st...> - 2005-03-04 19:15:09
|
Deepak Giridharagopal wrote: > On Fri, 2005-03-04 at 13:12 +0100, Michael Ströder wrote: > >>Extension modules are not binary-compatible between media versions of >>Python. A module compiled for 2.2 cannot run under Python 2.3 without >>being rebuilt. > > Hmmm, didn't realize that. I will now wave my magic wand and we'll all > pretend I never sent out that last message. :) Which message? ;-) > Does anyone have any objections to the attached patch, then? Seems to be perfect. Please commit. Ciao, Michael. |
From: Mauro C. <mci...@li...> - 2005-03-04 13:29:57
|
Deepak Giridharagopal wrote: >This patch is a little longer than the previous one, but it works just >as well. Plus, this way we're doing a run-time check instead of a >compile-time check. This will let people upgrade to Python 2.3+ without >having to recompile python-ldap. > This would be very well, and a Good Thing, although I beg to differ - on Windows a different version of the binaries will always be needed if changing minor version since extensions are linked to the Python DLL which is called python22.dll, python23.dll, python24.dll and so on. Moreover, reading the code it appears to me that checking just the minor version means that as written it will only work within the 2.x branch. Of course there's no telling what will happen in the time coming, so this point can be moot, but I would advise for checking the major version also. After all, there's still a sizable amount of old code around still using (actually, requiring!) Python 1.5.2... Anyway, thanks for the great work, it is doing us a lot of good. Mauro |