[PATCH V2] pycompat: delay loading modules registered to stub
Augie Fackler
raf at durin42.com
Wed Aug 17 09:19:47 EDT 2016
On Mon, Aug 15, 2016 at 07:06:20PM +0900, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya at tcha.org>
> # Date 1471153584 -32400
> # Sun Aug 14 14:46:24 2016 +0900
> # Node ID 66bb317ce352edbc47c07d2b7f7553232aeb6723
> # Parent 0cb2d4db308b97e8fe7faa8d45a47b228037f230
> pycompat: delay loading modules registered to stub
Queued, thanks
>
> Replacement _pycompatstub is designed to be compatible with our demandimporter.
> try-except is replaced by version comparison because ImportError will no longer
> be raised immediately.
>
> diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py
> --- a/mercurial/pycompat.py
> +++ b/mercurial/pycompat.py
> @@ -34,30 +34,32 @@ empty = _queue.Empty
> queue = _queue.Queue
>
> class _pycompatstub(object):
> - pass
> -
> -def _alias(alias, origin, items):
> - """ populate a _pycompatstub
> + def __init__(self):
> + self._aliases = {}
>
> - copies items from origin to alias
> - """
> - for item in items:
> + def _registeraliases(self, origin, items):
> + """Add items that will be populated at the first access"""
> + self._aliases.update((item.replace('_', '').lower(), (origin, item))
> + for item in items)
> +
> + def __getattr__(self, name):
> try:
> - lcase = item.replace('_', '').lower()
> - setattr(alias, lcase, getattr(origin, item))
> - except AttributeError:
> - pass
> + origin, item = self._aliases[name]
> + except KeyError:
> + raise AttributeError(name)
> + self.__dict__[name] = obj = getattr(origin, item)
> + return obj
>
> httpserver = _pycompatstub()
> urlreq = _pycompatstub()
> urlerr = _pycompatstub()
> -try:
> +if sys.version_info[0] < 3:
> import BaseHTTPServer
> import CGIHTTPServer
> import SimpleHTTPServer
> import urllib2
> import urllib
> - _alias(urlreq, urllib, (
> + urlreq._registeraliases(urllib, (
> "addclosehook",
> "addinfourl",
> "ftpwrapper",
> @@ -71,7 +73,7 @@ try:
> "url2pathname",
> "urlencode",
> ))
> - _alias(urlreq, urllib2, (
> + urlreq._registeraliases(urllib2, (
> "AbstractHTTPHandler",
> "BaseHandler",
> "build_opener",
> @@ -87,24 +89,24 @@ try:
> "Request",
> "urlopen",
> ))
> - _alias(urlerr, urllib2, (
> + urlerr._registeraliases(urllib2, (
> "HTTPError",
> "URLError",
> ))
> - _alias(httpserver, BaseHTTPServer, (
> + httpserver._registeraliases(BaseHTTPServer, (
> "HTTPServer",
> "BaseHTTPRequestHandler",
> ))
> - _alias(httpserver, SimpleHTTPServer, (
> + httpserver._registeraliases(SimpleHTTPServer, (
> "SimpleHTTPRequestHandler",
> ))
> - _alias(httpserver, CGIHTTPServer, (
> + httpserver._registeraliases(CGIHTTPServer, (
> "CGIHTTPRequestHandler",
> ))
>
> -except ImportError:
> +else:
> import urllib.request
> - _alias(urlreq, urllib.request, (
> + urlreq._registeraliases(urllib.request, (
> "AbstractHTTPHandler",
> "addclosehook",
> "addinfourl",
> @@ -132,12 +134,12 @@ except ImportError:
> "urlopen",
> ))
> import urllib.error
> - _alias(urlerr, urllib.error, (
> + urlerr._registeraliases(urllib.error, (
> "HTTPError",
> "URLError",
> ))
> import http.server
> - _alias(httpserver, http.server, (
> + httpserver._registeraliases(http.server, (
> "HTTPServer",
> "BaseHTTPRequestHandler",
> "SimpleHTTPRequestHandler",
> diff --git a/tests/test-check-py3-compat.t b/tests/test-check-py3-compat.t
> --- a/tests/test-check-py3-compat.t
> +++ b/tests/test-check-py3-compat.t
> @@ -122,24 +122,22 @@
> mercurial/hook.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> mercurial/httpconnection.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> mercurial/httppeer.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> - mercurial/keepalive.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> - mercurial/localrepo.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> - mercurial/lock.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> - mercurial/mail.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> - mercurial/manifest.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> - mercurial/match.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> - mercurial/mdiff.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> - mercurial/merge.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> - mercurial/minirst.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> - mercurial/namespaces.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> - mercurial/obsolete.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> - mercurial/patch.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> - mercurial/pathutil.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> - mercurial/peer.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> - mercurial/pure/mpatch.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> - mercurial/pure/parsers.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> - mercurial/pushkey.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> - mercurial/pvec.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> + mercurial/keepalive.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> + mercurial/localrepo.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> + mercurial/lock.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> + mercurial/mail.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> + mercurial/manifest.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> + mercurial/match.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> + mercurial/mdiff.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> + mercurial/merge.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> + mercurial/minirst.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> + mercurial/namespaces.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> + mercurial/obsolete.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> + mercurial/patch.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> + mercurial/pathutil.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> + mercurial/peer.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> + mercurial/pushkey.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> + mercurial/pvec.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> mercurial/registrar.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> mercurial/repair.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> mercurial/repoview.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> @@ -168,6 +166,6 @@
> mercurial/verify.py: error importing: <TypeError> attribute name must be string, not 'bytes' (error at mdiff.py:*) (glob)
> mercurial/win32.py: error importing module: <ImportError> No module named 'msvcrt' (line *) (glob)
> mercurial/windows.py: error importing module: <ImportError> No module named 'msvcrt' (line *) (glob)
> - mercurial/wireproto.py: error importing module: <TypeError> a bytes-like object is required, not 'str' (line *) (glob)
> + mercurial/wireproto.py: error importing module: <TypeError> unorderable types: str() >= tuple() (line *) (glob)
>
> #endif
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
More information about the Mercurial-devel
mailing list