'Do encoding and canonicalization on a URL string'

def Canonicalize(loc):

    if (not loc):
        return loc
    narrow = encoder.NarrowText(loc, None)
    (scheme, netloc, path, query, frag) = urlparse.urlsplit(narrow)
    unr = '-._~'
    sub = "!$&'()*+,;="
    netloc = urllib.quote(netloc, ((unr + sub) + '%:@/[]'))
    path = urllib.quote(path, ((unr + sub) + '%:@/'))
    query = urllib.quote(query, ((unr + sub) + '%:@/?'))
    frag = urllib.quote(frag, ((unr + sub) + '%:@/?'))
    try:
        (ignore, widenetloc, ignore, ignore, ignore) = urlparse.urlsplit(loc)
        for c in widenetloc:
            if (c >= unichr(128)):
                netloc = widenetloc.encode(ENC_IDNA)
                netloc = urllib.quote(netloc, ((unr + sub) + '%:@/[]'))
                break
    except UnicodeError:
        pass
    except LookupError:
        output.Warn('An    International    Domain    Name    (IDN)    is    being    used,    but    this    version    of    Python    does    not    have    support    for    IDNA    encoding.        (IDNA    support    was    introduced    in    Python    2.3)        The    encoding    we    have    used    instead    is    wrong    and    will    probably    not    yield    valid    URLs.')
    bad_netloc = False
    if ('%' in netloc):
        bad_netloc = True
    narrow = urlparse.urlunsplit((scheme, netloc, path, query, frag))
    HEXDIG = '0123456789abcdefABCDEF'
    list = narrow.split('%')
    narrow = list[0]
    del list[0]
    for item in list:
        if ((len(item) >= 2) and (item[0] in HEXDIG) and (item[1] in HEXDIG)):
            narrow = ((narrow + '%') + item)
        else:
            narrow = ((narrow + '%25') + item)
    if bad_netloc:
        output.Warn(('Invalid    characters    in    the    host    or    domain    portion    of    a    URL:    ' + narrow))
    return narrow
