Problem with OpenLDAP 2.2: Macro add_int_r() in constants.c?!?
David Leonard
d at adaptive-enterprises.com.au
Thu Mar 11 07:20:12 CET 2004
Michael
The reason for having l_ldap_result convert from int to string, was purely
that it made the returned tuple easier to inspect visually.
Also, the reason for the introduction of 'same-named' symbols
(ldap.RES_BIND="RES_BIND") is to catch typos (cf the __slots__ hack, or
X11's resource string constants starting with 'XtN'). The forward and
reverse dictionaries are artifacts of this strange system.
You are right that removing the translation and changing the 'constants' to
numbers would break anyone's code that used string literals.
I have no idea why OpenLDAP2.2 breaks it now.
An alternate (and more high-level) approach would be to create a Result
class, and have l_ldap_result return instances of Result (instead of a
tuple). Using __getitem__ you could make it backward-compatible with the
extant tuples. Also, using __repr__ you could have Result instances make
sense when printed interactively. Then, because there is no need to have
special strings in the result, you could change all the RES_ constants to be
integers and that would much better match ldap.h. Backward-compat with
people's code that used string literals would still be a problem, but
wouldn't be hard to fix. Further, with this instance-instead-of-tuple
approach, an opportunity arises for metaclasses and mixins etc. It could
make OO-zealots very happy :)
d
----- Original Message -----
From: "Michael Ströder" <michael at stroeder.com>
To: <python-ldap-dev at lists.sourceforge.net>
Sent: Thursday, March 11, 2004 3:57 AM
Subject: Problem with OpenLDAP 2.2: Macro add_int_r() in constants.c?!?
> HI!
>
> David, please take note of this!
>
> What was the rationale of having this macro in constants.c?
> What are "reversibles" in this context?
>
> #define add_int_r(d, name) \
> { \
> long v = LDAP_##name; \
> PyObject *i = PyInt_FromLong( v ); \
> PyObject *s = PyString_FromString( #name ); \
> PyDict_SetItem( d, s, s ); \
> PyDict_SetItem( reverse, i, s ); \
> PyDict_SetItem( forward, s, i ); \
> Py_DECREF(i); \
> Py_DECREF(s); \
> /* printf("%s -> %ld\n", #name, v ); */ \
> }
>
> [..]
>
> /* reversibles */
>
> zero = PyInt_FromLong( 0 );
> PyDict_SetItem( reverse, zero, Py_None );
> Py_DECREF( zero );
>
> add_int_r(d,RES_BIND);
> add_int_r(d,RES_SEARCH_ENTRY);
> add_int_r(d,RES_SEARCH_RESULT);
> add_int_r(d,RES_MODIFY);
> add_int_r(d,RES_ADD);
> add_int_r(d,RES_DELETE);
> add_int_r(d,RES_MODRDN);
> add_int_r(d,RES_COMPARE);
> add_int(d,RES_ANY);
>
> add_int_r(d,RES_SEARCH_REFERENCE);
> add_int_r(d,RES_EXTENDED);
> add_int_r(d,RES_UNSOLICITED);
>
> It seems to map some integers from ldap.h to strings with the constant's
> name. For some unknown reason this does not work with OpenLDAP 2.2 libs
> anymore. E.g. there are integers returned by l_ldap_result() as result
type
> and this breaks ldap.async or other code which trys to evaluate the result
> type as string.
>
> I have a working solution without add_int_r() which might be
> backward-compatible if one strictly uses constants. This looks like a good
> compromise for me.
>
> Any comments?
>
> Ciao, Michael.
>
>
>
More information about the python-ldap
mailing list