[python-ldap] Yet another Python3 port

Raphaël Barrois raphael.barrois at m4x.org
Mon Nov 18 21:20:59 CET 2013


On Mon, 18 Nov 2013 08:58:36 -0500
"Rob McBroom" <mailinglist0 at skurfer.com> wrote:

> On 14 Nov 2013, at 4:57, Raphaël Barrois wrote:
> 
> > Does this port interest you?
> 
> Yes. I mean, sooner or later, we’re all going to have to be interested, right?
> 

Great!

Now, let's get to the actual porting issue on which I'd like to get some input.

The current python-ldap lib (without my fixes) uses only "str" (or "bytes")
internally — the calling code should perform the "unicode to utf-8" conversion
before sending anything, and the reverse when reading.

This is quite cumbersome for non-pure-ascii systems (e.g, outside the US), but
works not too bad for most commands where lookups, filters, etc. are pure ascii
and thus silently converted into utf-8 bytes (as requested per the LDAP RFCs).


With Python3, there is no auto-magic str/bytes conversion; we'll have to choose the behaviour regarding input *and* output:
1. Accept only Bytes, return only Bytes
2. Accept both Bytes and Text (with auto-magic cast, as in Py2), return Bytes (as in Py2)
2. Accept both Bytes and Text (with auto-magic cast, as in Py2), return Text
3. Accept only Text, return Text


All solutions are possible, the main issue is for users of the library.

Here is an example of the same Py2 snippet with the various options, on Py3:

>>> print(connection.search_st(filter=u"Raphaël Barrois".encode('utf-8'))[0]['givenName'][0].decode('utf-8'))
u"Raphaël Barrois"

Option 1:
---------
>>> print(connection.search_st(filter="Raphaël Barrois".encode('utf-8'))[0][b'givenName'][0].decode('utf-8'))
"Raphaël Barrois"
# NB: We'll have to put a 'b' in front of each attribute name...

Option 2:
---------
>>> print(connection.search_st(filter="Raphaël Barrois")[0][b'givenName'][0].decode('utf-8'))
"Raphaël Barrois"
# Asymmetrical: we send text, and get bytes
# We need to put a 'b' in front of each attribute name...

Option 3:
---------
>>> print(connection.search_st(filter="Raphaël Barrois")[0]['givenName'][0])
"Raphaël Barrois"
# Not backwards compatible with Py2, where we'd receive bytes

Option 4:
---------
>>> print(connection.search_st(filter="Raphaël Barrois")[0]['givenName'][0])
"Raphaël Barrois"



I personally find the 4th option the cleanest, but it would break compatibility with Py2.

What do you think?

-- 
Raphaël Barrois



More information about the python-ldap mailing list