def canon_cred_wql(query: dict) -> dict:
    """
    Canonicalize WQL attribute marker and value keys for input to indy-sdk wallet credential filtration.
    Canonicalize comparison values to proper indy-sdk raw values as per raw().

    Raise BadWalletQuery for WQL mapping '$or' to non-list.

    :param query: WQL query
    :return: canonicalized WQL query dict
    """

    for k in [qk for qk in query]:  # copy: iteration alters query keys
        attr_match = re.match('attr::([^:]+)::(marker|value)$', k)
        if isinstance(query[k], dict):  # only subqueries are dicts: recurse
            query[k] = canon_cred_wql(query[k])
        if k == '$or':
            if not isinstance(query[k], list):
                raise BadWalletQuery('Bad WQL; $or value must be a list in {}'.format(json.dumps(query)))
            query[k] = [canon_cred_wql(subq) for subq in query[k]]
        if attr_match:
            qkey = 'attr::{}::{}'.format(canon(attr_match.group(1)), canon(attr_match.group(2)))
            query[qkey] = query.pop(k)
            tag_value = query[qkey]
            if isinstance(tag_value, dict) and len(tag_value) == 1:
                if '$in' in tag_value:
                    tag_value['$in'] = [raw(val) for val in tag_value.pop('$in')]
                else:
                    wql_op = set(tag_value.keys()).pop()  # $neq, $gt, $gte, etc.
                    tag_value[wql_op] = raw(tag_value[wql_op])
            else:  # equality
                query[qkey] = raw(query[qkey])

    return query
def canon_cred_wql ( query : dict ) -> dict : for k in [ qk for qk in query ] : attr_match = re . match ( 'attr::([^:]+)::(marker|value)$' , k ) if isinstance ( query [ k ] , dict ) : query [ k ] = canon_cred_wql ( query [ k ] ) if k == '$or' : if not isinstance ( query [ k ] , list ) : raise BadWalletQuery ( 'Bad WQL; $or value must be a list in {}' . format ( json . dumps ( query ) ) ) query [ k ] = [ canon_cred_wql ( subq ) for subq in query [ k ] ] if attr_match : qkey = 'attr::{}::{}' . format ( canon ( attr_match . group ( 1 ) ) , canon ( attr_match . group ( 2 ) ) ) query [ qkey ] = query . pop ( k ) tag_value = query [ qkey ] if isinstance ( tag_value , dict ) and len ( tag_value ) == 1 : if '$in' in tag_value : tag_value [ '$in' ] = [ raw ( val ) for val in tag_value . pop ( '$in' ) ] else : wql_op = set ( tag_value . keys ( ) ) . pop ( ) tag_value [ wql_op ] = raw ( tag_value [ wql_op ] ) else : query [ qkey ] = raw ( query [ qkey ] ) return query
Canonicalize WQL attribute marker and value keys for input to indy-sdk wallet credential filtration.
    Canonicalize comparison values to proper indy-sdk raw values as per raw().

    Raise BadWalletQuery for WQL mapping '$or' to non-list.

    :param query: WQL query
    :return: canonicalized WQL query dict