Author: Ronan Lamy <[email protected]>
Branch: py3.7
Changeset: r97733:dff15039dbab
Date: 2019-10-06 15:05 +0000
http://bitbucket.org/pypy/pypy/changeset/dff15039dbab/
Log: Merged in Yannick_Jadoul/pypy/py3.7-pep562 (pull request #670)
Implementation of PEP 562, adding __getattr__ and __dir__ for
modules
diff --git a/pypy/interpreter/module.py b/pypy/interpreter/module.py
--- a/pypy/interpreter/module.py
+++ b/pypy/interpreter/module.py
@@ -134,6 +134,10 @@
except OperationError as e:
if not e.match(space, space.w_AttributeError):
raise
+ w_dict = self.w_dict
+ w_getattr = space.finditem(w_dict, space.newtext('__getattr__'))
+ if w_getattr is not None:
+ return space.call_function(w_getattr, w_attr)
w_name = space.finditem(self.w_dict, space.newtext('__name__'))
if w_name is None:
raise oefmt(space.w_AttributeError,
@@ -147,6 +151,9 @@
if not space.isinstance_w(w_dict, space.w_dict):
raise oefmt(space.w_TypeError, "%N.__dict__ is not a dictionary",
self)
+ w_dir = space.finditem(w_dict, space.newtext('__dir__'))
+ if w_dir is not None:
+ return space.call_function(w_dir)
return space.call_function(space.w_list, w_dict)
# These three methods are needed to implement '__class__' assignment
diff --git a/pypy/interpreter/test/test_module.py
b/pypy/interpreter/test/test_module.py
--- a/pypy/interpreter/test/test_module.py
+++ b/pypy/interpreter/test/test_module.py
@@ -262,3 +262,29 @@
raises(AttributeError, "del x.a")
raises(TypeError, "x.__class__ = X")
raises(TypeError, "sys.__class__ = XX")
+
+ def test_getattr_dir(self):
+ def __getattr__(name):
+ if name == 'y':
+ return 42
+ elif name == 'z':
+ return
+ raise AttributeError("No attribute '{}'".format(name))
+
+ def __dir__():
+ return ['x', 'y', 'z', 'w']
+
+ import sys
+ m = type(sys)('foo')
+ m.x = 'x'
+ m.__getattr__ = __getattr__
+ print(m.__dir__)
+ m.__dir__ = __dir__
+
+ assert m.x == 'x'
+ assert m.y == 42
+ assert m.z == None
+ excinfo = raises(AttributeError, 'm.w')
+ assert str(excinfo.value) == "No attribute 'w'"
+ print(dir(m))
+ assert dir(m) == sorted(['x', 'y', 'z', 'w'])
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit