# Buggy code
def _lock_scan(self, scanid, oldlockid, newlockid):
    if oldlockid is not None:
        oldlockid = bson.Binary(oldlockid)
    if newlockid is not None:
        newlockid = bson.Binary(newlockid)
    scan = self.db[self.colname_scans].find_and_modify(
        {
            "_id": scanid,
            "lock": oldlockid,
        },
        {
            "$set": {"lock": newlockid},
        },
        full_response=True,
        fields={"target": False},
        new=True,
    )["value"]
    if "target_info" not in scan:
        target = self.get_scan_target(scanid)
        if target is not None:
            target_info = target.target.infos
            self.db[self.colname_scans].update(
                {"_id": scanid},
                {"$set": {"target_info": target_info}},
            )
            scan["target_info"] = target_info
    if scan is not None and scan["lock"] is not None:
        scan["lock"] = bytes(scan["lock"])
    return scan


# Traceback (TypeError)
root@ivreclient:~# ivre runscansagentdb --daemon
Traceback (most recent call last):
File "/usr/local/bin/ivre", line 78, in <module>
main()
File "/usr/local/bin/ivre", line 51, in main
tools.get_command(possible_commands[0])()
File "/usr/local/lib/python2.7/dist-packages/ivre/tools/runscansagentdb.py", line 231, in main
ivre.db.db.agent.feed_all(masterid)
File "/usr/local/lib/python2.7/dist-packages/ivre/db/__init__.py", line 1351, in feed_all
self.feed(masterid, scanid)
File "/usr/local/lib/python2.7/dist-packages/ivre/db/__init__.py", line 1354, in feed
scan = self.lock_scan(scanid)
File "/usr/local/lib/python2.7/dist-packages/ivre/db/__init__.py", line 1486, in lock_scan
scan = self._lock_scan(scanid, None, lockid.bytes)
File "/usr/local/lib/python2.7/dist-packages/ivre/db/mongo.py", line 3372, in _lock_scan
if "target_info" not in scan:
TypeError: argument of type 'NoneType' is not iterable

# Fixed code
def _lock_scan(self, scanid, oldlockid, newlockid):
    """Change lock for scanid from oldlockid to newlockid. Returns the new
    scan object on success, and raises a LockError on failure.

    """
    if oldlockid is not None:
        oldlockid = bson.Binary(oldlockid)
    if newlockid is not None:
        newlockid = bson.Binary(newlockid)
    scan = self.db[self.colname_scans].find_and_modify(
        {
            "_id": scanid,
            "lock": oldlockid,
        },
        {
            "$set": {"lock": newlockid, "pid": os.getpid()},
        },
        full_response=True,
        fields={"target": False},
        new=True,
    )["value"]
    if scan is None:
        if oldlockid is None:
            raise LockError("Cannot acquire lock for %r" % scanid)
        if newlockid is None:
            raise LockError("Cannot release lock for %r" % scanid)
        raise LockError(
            "Cannot change lock for %r from %r to %r" % (scanid, oldlockid, newlockid)
        )
    if "target_info" not in scan:
        target = self.get_scan_target(scanid)
        if target is not None:
            target_info = target.target.infos
            self.db[self.colname_scans].update(
                {"_id": scanid},
                {"$set": {"target_info": target_info}},
            )
            scan["target_info"] = target_info
    if scan["lock"] is not None:
        scan["lock"] = bytes(scan["lock"])
    return scan