##// END OF EJS Templates
pytype: use "$(hg root)" instead of `hg root` to make shellcheck happier
pytype: use "$(hg root)" instead of `hg root` to make shellcheck happier

File last commit:

r51822:18c8c189 default
r52199:46280260 default
Show More
urllibcompat.py
152 lines | 3.5 KiB | text/x-python | PythonLexer
Augie Fackler
urllibcompat: new library to help abstract out some python3 urllib2 stuff...
r34466 # urllibcompat.py - adapters to ease using urllib2 on Py2 and urllib on Py3
#
# Copyright 2017 Google, Inc.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
Gregory Szorc
urllibcompat: remove Python 2 support code...
r49751 import http.server
import urllib.error
import urllib.parse
import urllib.request
import urllib.response
Augie Fackler
urllibcompat: new library to help abstract out some python3 urllib2 stuff...
r34466 from . import pycompat
Augie Fackler
urllibcompat: move some adapters from pycompat to urllibcompat...
r34468 _sysstr = pycompat.sysstr
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
py3: use class X: instead of class X(object):...
r49801 class _pycompatstub:
Augie Fackler
urllibcompat: move some adapters from pycompat to urllibcompat...
r34468 def __init__(self):
self._aliases = {}
def _registeraliases(self, origin, items):
"""Add items that will be populated at the first access"""
items = map(_sysstr, items)
self._aliases.update(
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 (item.replace('_', '').lower(), (origin, item)) for item in items
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
urllibcompat: move some adapters from pycompat to urllibcompat...
r34468
def _registeralias(self, origin, attr, name):
"""Alias ``origin``.``attr`` as ``name``"""
self._aliases[_sysstr(name)] = (origin, _sysstr(attr))
def __getattr__(self, name):
try:
origin, item = self._aliases[name]
except KeyError:
raise AttributeError(name)
self.__dict__[name] = obj = getattr(origin, item)
return obj
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
urllibcompat: move some adapters from pycompat to urllibcompat...
r34468 httpserver = _pycompatstub()
urlreq = _pycompatstub()
urlerr = _pycompatstub()
Gregory Szorc
urllibcompat: remove Python 2 support code...
r49751 urlreq._registeraliases(
urllib.parse,
(
b"splitattr",
b"splitpasswd",
b"splitport",
b"splituser",
b"urlparse",
b"urlunparse",
),
)
urlreq._registeralias(urllib.parse, b"parse_qs", b"parseqs")
urlreq._registeralias(urllib.parse, b"parse_qsl", b"parseqsl")
urlreq._registeralias(urllib.parse, b"unquote_to_bytes", b"unquote")
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
urllibcompat: remove Python 2 support code...
r49751 urlreq._registeraliases(
urllib.request,
(
b"AbstractHTTPHandler",
b"BaseHandler",
b"build_opener",
b"FileHandler",
b"FTPHandler",
b"ftpwrapper",
b"HTTPHandler",
b"HTTPSHandler",
b"install_opener",
b"pathname2url",
b"HTTPBasicAuthHandler",
b"HTTPDigestAuthHandler",
b"HTTPPasswordMgrWithDefaultRealm",
b"ProxyHandler",
b"Request",
b"url2pathname",
b"urlopen",
),
)
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
urllibcompat: remove Python 2 support code...
r49751 urlreq._registeraliases(
urllib.response,
(
b"addclosehook",
b"addinfourl",
),
)
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
urllibcompat: remove Python 2 support code...
r49751 urlerr._registeraliases(
urllib.error,
(
b"HTTPError",
b"URLError",
),
)
httpserver._registeraliases(
http.server,
(
b"HTTPServer",
b"BaseHTTPRequestHandler",
b"SimpleHTTPRequestHandler",
b"CGIHTTPRequestHandler",
),
)
Matt Harbison
typing: disable import error warnings that are already handled...
r47543
Gregory Szorc
urllibcompat: remove Python 2 support code...
r49751 # urllib.parse.quote() accepts both str and bytes, decodes bytes
# (if necessary), and returns str. This is wonky. We provide a custom
# implementation that only accepts bytes and emits bytes.
def quote(s, safe='/'):
# bytestr has an __iter__ that emits characters. quote_from_bytes()
# does an iteration and expects ints. We coerce to bytes to appease it.
if isinstance(s, pycompat.bytestr):
s = bytes(s)
s = urllib.parse.quote_from_bytes(s, safe=safe)
return s.encode('ascii', 'strict')
# urllib.parse.urlencode() returns str. We use this function to make
# sure we return bytes.
def urlencode(query, doseq=False):
s = urllib.parse.urlencode(query, doseq=doseq)
return s.encode('ascii')
Augie Fackler
urllibcompat: new library to help abstract out some python3 urllib2 stuff...
r34466
Gregory Szorc
urllibcompat: remove Python 2 support code...
r49751 urlreq.quote = quote
urlreq.urlencode = urlencode
Augie Fackler
urllibcompat: new library to help abstract out some python3 urllib2 stuff...
r34466
Gregory Szorc
urllibcompat: remove Python 2 support code...
r49751 def getfullurl(req):
return req.full_url
def gethost(req):
return req.host
Augie Fackler
urllibcompat: new library to help abstract out some python3 urllib2 stuff...
r34466
Gregory Szorc
urllibcompat: remove Python 2 support code...
r49751
def getselector(req):
return req.selector
Augie Fackler
urllibcompat: new library to help abstract out some python3 urllib2 stuff...
r34466
Gregory Szorc
urllibcompat: remove Python 2 support code...
r49751 def getdata(req):
return req.data
Augie Fackler
urllibcompat: new library to help abstract out some python3 urllib2 stuff...
r34466
Gregory Szorc
urllibcompat: remove Python 2 support code...
r49751
def hasdata(req):
return req.data is not None