I agree that ldap_initialize() should
behave as it currently does, setting up the handle but not opening any
connections.

So this would need ldap_initialize() to defer calling ldap_start_tls().
I don't think that's what Pierangelo has in mind.

But that might actually be the simplest approach. ldap_initialize() can parse
the URL and set a flag in the LDAP* handle noting that StartTLS was requested.
On the next request, we can check to see if this flag is set and the current
request is not a StartTLS exop. If so, perform the exop first. Then clear the
flag and carry on.

Hmm, StartTLS implies/requires protocol version 3. It seems unfortunate
that ldap_initialize() wasn't made to default to version 3. Lacking a
change to that, what should happen if you use one of these URIs without
setting the version to 3?

The same thing that happens now if you try to call ldap_start_tls_s() without
setting the version to 3 (error).

Another valid point.

Well, I've changed the default for the protocol_version in python-ldap
to VERSION3 and no-one ever complained...

c) automatically change version, because confusing people is fun.

On some X.500 servers one can configure different charsets if LDAPv2 is
used...