[PATCH 1 of 2] demandimport: avoid redundant module lookup

Gregory Szorc gregory.szorc at gmail.com
Sat Oct 3 18:43:31 UTC 2015


# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1443894998 25200
#      Sat Oct 03 10:56:38 2015 -0700
# Node ID faccbd648e42a08a491dc306b37fdd2886ed41cc
# Parent  97dc6ab42aad232c73180dee648685c26662230b
demandimport: avoid redundant module lookup

Previously, every attribute get and set was verifying self._module
was loaded and then was looking up self._module again. Avoid the
redundant attribute lookup by just returning the module instance from
_load.

This should have a positive impact on performance. However, I didn't
measure it.

diff --git a/mercurial/demandimport.py b/mercurial/demandimport.py
--- a/mercurial/demandimport.py
+++ b/mercurial/demandimport.py
@@ -78,9 +78,10 @@ class _demandmod(object):
     def _extend(self, name):
         """add to the list of submodules to load"""
         self._data[3].append(name)
     def _load(self):
-        if not self._module:
+        mod = self._module
+        if not mod:
             head, globals, locals, after, level = self._data
             mod = _hgextimport(_import, head, globals, locals, None, level)
             # load submodules
             def subload(mod, p):
@@ -99,8 +100,10 @@ class _demandmod(object):
             if locals and locals.get(head) == self:
                 locals[head] = mod
             object.__setattr__(self, "_module", mod)
 
+        return mod
+
     def __repr__(self):
         if self._module:
             return "<proxied module '%s'>" % self._data[0]
         return "<unloaded module '%s'>" % self._data[0]
@@ -108,13 +111,13 @@ class _demandmod(object):
         raise TypeError("%s object is not callable" % repr(self))
     def __getattribute__(self, attr):
         if attr in ('_data', '_extend', '_load', '_module'):
             return object.__getattribute__(self, attr)
-        self._load()
-        return getattr(self._module, attr)
+        mod = self._load()
+        return getattr(mod, attr)
     def __setattr__(self, attr, val):
-        self._load()
-        setattr(self._module, attr, val)
+        mod = self._load()
+        setattr(mod, attr, val)
 
 def _demandimport(name, globals=None, locals=None, fromlist=None, level=level):
     if not locals or name in ignore or fromlist == ('*',):
         # these cases we can't really delay


More information about the Mercurial-devel mailing list