demandimport: stop overriding __getattribute__()
Proxy __dict__ and __doc__ explicitly instead.
I'm not sure which is less evil, but this seems slightly simpler than hooking
all attribute accesses.
--- a/hgdemandimport/demandimportpy2.py Fri Apr 28 23:46:16 2017 +0900
+++ b/hgdemandimport/demandimportpy2.py Fri Apr 28 00:01:22 2017 +0900
@@ -153,9 +153,7 @@
def __call__(self, *args, **kwargs):
raise TypeError("%s object is not callable" % repr(self))
- def __getattribute__(self, attr):
- if attr in ('_data', '_extend', '_load', '_module', '_addref'):
- return object.__getattribute__(self, attr)
+ def __getattr__(self, attr):
self._load()
return getattr(self._module, attr)
@@ -163,6 +161,16 @@
self._load()
setattr(self._module, attr, val)
+ @property
+ def __dict__(self):
+ self._load()
+ return self._module.__dict__
+
+ @property
+ def __doc__(self):
+ self._load()
+ return self._module.__doc__
+
_pypy = '__pypy__' in sys.builtin_module_names
def _demandimport(name, globals=None, locals=None, fromlist=None, level=level):
--- a/tests/test-demandimport.py Fri Apr 28 23:46:16 2017 +0900
+++ b/tests/test-demandimport.py Fri Apr 28 00:01:22 2017 +0900
@@ -69,6 +69,17 @@
print("re.stderr =", f(re.stderr))
print("re =", f(re))
+# Test access to special attributes through demandmod proxy
+from mercurial import pvec as pvecproxy
+print("pvecproxy =", f(pvecproxy))
+print("pvecproxy.__doc__ = %r"
+ % (' '.join(pvecproxy.__doc__.split()[:3]) + ' ...'))
+print("pvecproxy.__name__ = %r" % pvecproxy.__name__)
+# __name__ must be accessible via __dict__ so the relative imports can be
+# resolved
+print("pvecproxy.__dict__['__name__'] = %r" % pvecproxy.__dict__['__name__'])
+print("pvecproxy =", f(pvecproxy))
+
import contextlib
print("contextlib =", f(contextlib))
try:
--- a/tests/test-demandimport.py.out Fri Apr 28 23:46:16 2017 +0900
+++ b/tests/test-demandimport.py.out Fri Apr 28 00:01:22 2017 +0900
@@ -18,6 +18,11 @@
re = <unloaded module 'sys'>
re.stderr = <open file '<whatever>', mode 'w' at 0x?>
re = <proxied module 'sys'>
+pvecproxy = <unloaded module 'pvec'>
+pvecproxy.__doc__ = 'A "pvec" is ...'
+pvecproxy.__name__ = 'mercurial.pvec'
+pvecproxy.__dict__['__name__'] = 'mercurial.pvec'
+pvecproxy = <proxied module 'pvec'>
contextlib = <unloaded module 'contextlib'>
contextlib.unknownattr = ImportError: cannot import name unknownattr
__import__('contextlib', ..., ['unknownattr']) = <module 'contextlib' from '?'>