@accessReadOnly
    def getTroveInfo(self, authToken, clientVersion, infoType, troveList):
        # infoType should be valid
        if infoType not in trove.TroveInfo.streamDict.keys():
            raise errors.RepositoryError("Unknown trove infoType requested", infoType)

        self.log(2, infoType, troveList)

        # by default we should mark all troves with insuficient permission
        ## disabled for now until we deal with protocol compatibility issues
        ## for insufficient permission
        ##ret = [ (-2, '') ] * len(troveList)
        ret = [ (-1, '') ] * len(troveList)
        # check permissions using the batch interface
        cu = self.db.cursor()
        permList = self.auth.batchCheck(authToken, troveList, cu = cu)
        if True not in permList:
            # we got no permissions, shortcircuit all of them as missing
            return ret
        if False in permList:
            # drop troves for which we have no permissions to avoid busy work
            cu.execute("delete from tmpNVF where idx in (%s)" % (",".join(
                "%d" % i for i,perm in enumerate(permList) if not perm)))
            self.db.analyze("tmpNVF")
        # get the data doing a full scan of tmpNVF
        cu.execute("""
        SELECT tmpNVF.idx, TroveInfo.data
        FROM tmpNVF
        JOIN Items ON tmpNVF.name = Items.item
        JOIN Versions ON tmpNVF.version = Versions.version
        JOIN Flavors ON tmpNVF.flavor = Flavors.flavor
        JOIN Instances ON
            Items.itemId = Instances.itemId AND
            Versions.versionId = Instances.versionId AND
            Flavors.flavorId = Instances.flavorId
        LEFT JOIN TroveInfo ON
            Instances.instanceId = TroveInfo.instanceId
            AND TroveInfo.infoType = ?
        """, infoType)
        for i, data in cu:
            data = cu.frombinary(data)
            if data is None:
                ret[i] = (0, '') # value missing
                continue

            # else, we have a value we need to return
            if (infoType == trove._TROVEINFO_TAG_METADATA and
                clientVersion <= 64):
                # ugly, but just instantiates a metadata object
                md = trove.TroveInfo.streamDict[
                                 trove._TROVEINFO_TAG_METADATA][1]()

                md.thaw(data)
                data = md.freeze(skipSet = trove.TroveInfo._newMetadataItems)

            ret[i] = (1, base64.encodestring(data))
        return ret
we return tuples (present, data) to aid netclient in making its decoding decisions
dataset/ETHPy150Open sassoftware/conary/conary/repository/netrepos/netserver.py/NetworkRepositoryServer.getTroveInfo