It seems that Client.session() is not thread safe. There seems to be a race condition that means two concurrent calls can actually share the same underlying session.
Client.session() acquires self.lock and determines a free session id. It then releases the lock before calling self.channel(id) which acquires the lock again and allocates the id and creates the session.
If a second call to Client.session() happens in the moment the lock is released but before self.channel(id) reacquires it the second call will find the same free id and will then subsequently return the same session object from self.channel(id).