ldaptor
ldaptor copied to clipboard
None is neither bytes nor unicode
I'm trying to set up the merger example and I don't know why default bindAddress=None is not working at https://github.com/twisted/ldaptor/blob/4e2b67798b75e0c2b364fc0d9fdf327b0f0ddca4/ldaptor/protocols/ldap/ldapconnector.py#L29
My code is (Python 2.7.14):
from twisted.internet import defer, reactor, protocol
from twisted.python import log
from ldaptor.config import LDAPConfig
from ldaptor.protocols.ldap.merger import MergedLDAPServer
from six.moves.queue import Queue
import sys
log.startLogging(sys.stderr)
configs = [LDAPConfig(serviceLocationOverrides={'dc=example,dc=com': ('some_host', 389)}),
LDAPConfig(serviceLocationOverrides={'dc=example.dc=org': ('other_host', 636)})]
use_tls = [False,True]
factory = protocol.ServerFactory()
factory.protocol = lambda: MergedLDAPServer(configs, use_tls)
reactor.listenTCP(8389, factory)
reactor.run()
And trace:
2018-01-18 21:36:59+0000 [-] Log opened.
2018-01-18 21:36:59+0000 [-] ServerFactory starting on 8389
2018-01-18 21:36:59+0000 [-] Starting factory <twisted.internet.protocol.ServerFactory instance at 0x7f991a0e7320>
2018-01-18 21:37:03+0000 [twisted.internet.protocol.ServerFactory] Unhandled Error
Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/twisted/python/log.py", line 86, in callWithContext
return context.call({ILogContext: newCtx}, func, *args, **kw)
File "/usr/local/lib/python2.7/site-packages/twisted/python/context.py", line 122, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/usr/local/lib/python2.7/site-packages/twisted/python/context.py", line 85, in callWithContext
return func(*args,**kw)
File "/usr/local/lib/python2.7/site-packages/twisted/internet/posixbase.py", line 614, in _doReadOrWrite
why = selectable.doRead()
--- <exception caught here> ---
File "/usr/local/lib/python2.7/site-packages/twisted/internet/tcp.py", line 1073, in doRead
protocol.makeConnection(transport)
File "/usr/local/lib/python2.7/site-packages/twisted/internet/protocol.py", line 510, in makeConnection
self.connectionMade()
File "/usr/local/lib/python2.7/site-packages/ldaptor/protocols/ldap/merger.py", line 88, in connectionMade
overrides=c.getServiceLocationOverrides())
File "/usr/local/lib/python2.7/site-packages/ldaptor/protocols/ldap/ldapconnector.py", line 113, in connect
bindAddress=bindAddress)
File "/usr/local/lib/python2.7/site-packages/ldaptor/protocols/ldap/ldapconnector.py", line 39, in __init__
connectFuncKwArgs={'bindAddress': bindAddress})
File "/usr/local/lib/python2.7/site-packages/twisted/names/srvconnect.py", line 77, in __init__
self.domain = nativeString(domain)
File "/usr/local/lib/python2.7/site-packages/twisted/python/compat.py", line 412, in nativeString
raise TypeError("%r is neither bytes nor unicode" % s)
exceptions.TypeError: None is neither bytes nor unicode
What version of Twisted are you running?
Hi @psi29a, thanks for replying.
root@7cfc500925db:~# pip list | grep Twisted
Twisted (17.9.0)
I realized thanks to your reply that I've been looking at master code which obviously differs from my site-package install. So, the error is raised at line 77 of twisted/names/srvconnect.py:
self.domain = nativeString(domain)
In merger.py an LDAPClientCreator is instantiated which uses an LDAPConnector that is a subclass of SRVConnector. My LDAPConnector code is the following:
class LDAPConnector(SRVConnector):
def __init__(self, reactor, dn, factory,
overrides=None, bindAddress=None):
if not isinstance(dn, distinguishedname.DistinguishedName):
dn = distinguishedname.DistinguishedName(stringValue=dn)
if overrides is None:
overrides={}
self.override = self._findOverRide(dn, overrides)
domain = dn.getDomainName()
SRVConnector.__init__(self, reactor,
'ldap', domain, factory,
connectFuncKwArgs={'bindAddress': bindAddress})
And master is:
class LDAPConnector(SRVConnector):
def __init__(self, reactor, dn, factory,
overrides=None, bindAddress=None):
if not isinstance(dn, distinguishedname.DistinguishedName):
dn = distinguishedname.DistinguishedName(stringValue=dn)
if overrides is None:
overrides = {}
self.override = self._findOverRide(dn, overrides)
domain = dn.getDomainName() or ''
SRVConnector.__init__(self, reactor,
'ldap', domain, factory,
connectFuncKwArgs={'bindAddress': bindAddress})
As you can see, domain variable in master code gets an empty string default and there's no error. I apologize for creating and issue and overlooking the version I was using. Thanks again for your guidance.
Hi, I fall on the same problem when I tried to run a code which worked on Ubuntu Xenial 16.04 (twisted 16.0.0) on Ubuntu Bionic 18.04 (twisted 17.9.0). Thanks to this report, I have a workaround. Could Ldaptor maintainers ask Ubuntu for upgrading the packaged version ? Ldaptor 0.0.43 is provided for many years now : https://launchpad.net/ldaptor/+packages ;) Thanks.
It looks like thats the bug I'm hitting in https://github.com/twisted/ldaptor/issues/113 However, I did not get what the workaround was and why it was broken in the first place (version 18.7.0 for twisted, and 16.0.0 for ldaptor).
Edit: I apologize I did not read carefully enough the diff between both versions, I guess I’ll either patch the released version or just avoid running known failing tests...