diff options
author | Ivan Levkivskyi <levkivskyi@gmail.com> | 2017-12-14 10:59:44 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-14 10:59:44 (GMT) |
commit | 5364b5cd7571f2dfa75acd37b388c14ac33fef73 (patch) | |
tree | 43b89bf162a571e979946d2d9dcfda82b4e0f4c8 /Lib | |
parent | 9e7c136ad8bc8e8eec50c2a8ae5ff02752f695a2 (diff) | |
download | cpython-5364b5cd7571f2dfa75acd37b388c14ac33fef73.zip cpython-5364b5cd7571f2dfa75acd37b388c14ac33fef73.tar.gz cpython-5364b5cd7571f2dfa75acd37b388c14ac33fef73.tar.bz2 |
bpo-32225: Implementation of PEP 562 (#4731)
Implement PEP 562: module __getattr__ and __dir__.
The implementation simply updates module_getattro and
module_dir.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/bad_getattr.py | 4 | ||||
-rw-r--r-- | Lib/test/bad_getattr2.py | 7 | ||||
-rw-r--r-- | Lib/test/bad_getattr3.py | 5 | ||||
-rw-r--r-- | Lib/test/good_getattr.py | 11 | ||||
-rw-r--r-- | Lib/test/test_module.py | 51 |
5 files changed, 78 insertions, 0 deletions
diff --git a/Lib/test/bad_getattr.py b/Lib/test/bad_getattr.py new file mode 100644 index 0000000..16f901b --- /dev/null +++ b/Lib/test/bad_getattr.py @@ -0,0 +1,4 @@ +x = 1 + +__getattr__ = "Surprise!" +__dir__ = "Surprise again!" diff --git a/Lib/test/bad_getattr2.py b/Lib/test/bad_getattr2.py new file mode 100644 index 0000000..0a52a53 --- /dev/null +++ b/Lib/test/bad_getattr2.py @@ -0,0 +1,7 @@ +def __getattr__(): + "Bad one" + +x = 1 + +def __dir__(bad_sig): + return [] diff --git a/Lib/test/bad_getattr3.py b/Lib/test/bad_getattr3.py new file mode 100644 index 0000000..0d5f926 --- /dev/null +++ b/Lib/test/bad_getattr3.py @@ -0,0 +1,5 @@ +def __getattr__(name): + if name != 'delgetattr': + raise AttributeError + del globals()['__getattr__'] + raise AttributeError diff --git a/Lib/test/good_getattr.py b/Lib/test/good_getattr.py new file mode 100644 index 0000000..7d27de6 --- /dev/null +++ b/Lib/test/good_getattr.py @@ -0,0 +1,11 @@ +x = 1 + +def __dir__(): + return ['a', 'b', 'c'] + +def __getattr__(name): + if name == "yolo": + raise AttributeError("Deprecated, use whatever instead") + return f"There is {name}" + +y = 2 diff --git a/Lib/test/test_module.py b/Lib/test/test_module.py index 6d0d594..efe9a8e 100644 --- a/Lib/test/test_module.py +++ b/Lib/test/test_module.py @@ -125,6 +125,57 @@ a = A(destroyed)""" gc_collect() self.assertIs(wr(), None) + def test_module_getattr(self): + import test.good_getattr as gga + from test.good_getattr import test + self.assertEqual(test, "There is test") + self.assertEqual(gga.x, 1) + self.assertEqual(gga.y, 2) + with self.assertRaisesRegex(AttributeError, + "Deprecated, use whatever instead"): + gga.yolo + self.assertEqual(gga.whatever, "There is whatever") + del sys.modules['test.good_getattr'] + + def test_module_getattr_errors(self): + import test.bad_getattr as bga + from test import bad_getattr2 + self.assertEqual(bga.x, 1) + self.assertEqual(bad_getattr2.x, 1) + with self.assertRaises(TypeError): + bga.nope + with self.assertRaises(TypeError): + bad_getattr2.nope + del sys.modules['test.bad_getattr'] + if 'test.bad_getattr2' in sys.modules: + del sys.modules['test.bad_getattr2'] + + def test_module_dir(self): + import test.good_getattr as gga + self.assertEqual(dir(gga), ['a', 'b', 'c']) + del sys.modules['test.good_getattr'] + + def test_module_dir_errors(self): + import test.bad_getattr as bga + from test import bad_getattr2 + with self.assertRaises(TypeError): + dir(bga) + with self.assertRaises(TypeError): + dir(bad_getattr2) + del sys.modules['test.bad_getattr'] + if 'test.bad_getattr2' in sys.modules: + del sys.modules['test.bad_getattr2'] + + def test_module_getattr_tricky(self): + from test import bad_getattr3 + # these lookups should not crash + with self.assertRaises(AttributeError): + bad_getattr3.one + with self.assertRaises(AttributeError): + bad_getattr3.delgetattr + if 'test.bad_getattr3' in sys.modules: + del sys.modules['test.bad_getattr3'] + def test_module_repr_minimal(self): # reprs when modules have no __file__, __name__, or __loader__ m = ModuleType('foo') |