def urlencode(query):
    """Encode a sequence of two-element tuples or dictionary into a URL query string.

    This version is adapted from the standard library to understand operators in the
    pyesgf.search.constraints module.

    If the query arg is a sequence of two-element tuples, the order of the
    parameters in the output will match the order of parameters in the
    input.
    """

    if hasattr(query,"items"):
        # mapping objects
        query = query.items()
    else:
        # it's a bother at times that strings and string-like objects are
        # sequences...
        try:
            # non-sequence items should not work with len()
            # non-empty strings will fail this
            if len(query) and not isinstance(query[0], tuple):
                raise TypeError
            # zero-length sequences of all types will get here and succeed,
            # but that's a minor nit - since the original implementation
            # allowed empty dicts that type of behavior probably should be
            # preserved for consistency
        except TypeError:
            ty,va,tb = sys.exc_info()
            raise TypeError, "not a valid non-string sequence or mapping object", tb


    def append(k, v, tag, l):
        from .search.consts import OPERATOR_NEQ

        if tag == OPERATOR_NEQ:
            l.append('%s!=%s' % (k, v))
        elif tag is None:
            l.append('%s=%s' % (k, v))
        else:
            raise ValueError('Unknown operator tag %s' % tag)

    def strip_tag(v):
        if type(v) == tuple:
            tag, v = v
        else:
            tag = None
            
        return tag, v

    l = []
    for k, v in query:
        tag, v = strip_tag(v)
        k = quote_plus(str(k))
        if isinstance(v, str):
            v = quote_plus(v)
            append(k, v, tag, l)
        elif _is_unicode(v):
            # is there a reasonable way to convert to ASCII?
            # encode generates a string, but "replace" or "ignore"
            # lose information and "strict" can raise UnicodeError
            v = quote_plus(v.encode("ASCII","replace"))
            append(k, v, tag, l)
        else:
            try:
                # is this a sufficient test for sequence-ness?
                len(v)
            except __HOLE__:
                # not a sequence
                v = quote_plus(str(v))
                append(k, v, tag, l)
            else:
                # loop over the sequence
                for elt in v:
                    append(k, quote_plus(str(elt)), tag, l)
    return '&'.join(l)
dataset/ETHPy150Open stephenpascoe/esgf-pyclient/pyesgf/util.py/urlencode