summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/support/__init__.py16
-rw-r--r--Lib/test/test_support.py29
-rw-r--r--Lib/test/test_tempfile.py5
-rw-r--r--Misc/NEWS6
4 files changed, 43 insertions, 13 deletions
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index ed611c9..d8d599b 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -2119,12 +2119,15 @@ def swap_attr(obj, attr, new_val):
restoring the old value at the end of the block. If `attr` doesn't
exist on `obj`, it will be created and then deleted at the end of the
block.
+
+ The old value (or None if it doesn't exist) will be assigned to the
+ target of the "as" clause, if there is one.
"""
if hasattr(obj, attr):
real_val = getattr(obj, attr)
setattr(obj, attr, new_val)
try:
- yield
+ yield real_val
finally:
setattr(obj, attr, real_val)
else:
@@ -2132,7 +2135,8 @@ def swap_attr(obj, attr, new_val):
try:
yield
finally:
- delattr(obj, attr)
+ if hasattr(obj, attr):
+ delattr(obj, attr)
@contextlib.contextmanager
def swap_item(obj, item, new_val):
@@ -2146,12 +2150,15 @@ def swap_item(obj, item, new_val):
restoring the old value at the end of the block. If `item` doesn't
exist on `obj`, it will be created and then deleted at the end of the
block.
+
+ The old value (or None if it doesn't exist) will be assigned to the
+ target of the "as" clause, if there is one.
"""
if item in obj:
real_val = obj[item]
obj[item] = new_val
try:
- yield
+ yield real_val
finally:
obj[item] = real_val
else:
@@ -2159,7 +2166,8 @@ def swap_item(obj, item, new_val):
try:
yield
finally:
- del obj[item]
+ if item in obj:
+ del obj[item]
def strip_python_stderr(stderr):
"""Strip the stderr of a Python process from potential debug output
diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py
index 0dbe02e..1e6b2b5 100644
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -295,17 +295,34 @@ class TestSupport(unittest.TestCase):
def test_swap_attr(self):
class Obj:
- x = 1
+ pass
obj = Obj()
- with support.swap_attr(obj, "x", 5):
+ obj.x = 1
+ with support.swap_attr(obj, "x", 5) as x:
self.assertEqual(obj.x, 5)
+ self.assertEqual(x, 1)
self.assertEqual(obj.x, 1)
+ with support.swap_attr(obj, "y", 5) as y:
+ self.assertEqual(obj.y, 5)
+ self.assertIsNone(y)
+ self.assertFalse(hasattr(obj, 'y'))
+ with support.swap_attr(obj, "y", 5):
+ del obj.y
+ self.assertFalse(hasattr(obj, 'y'))
def test_swap_item(self):
- D = {"item":1}
- with support.swap_item(D, "item", 5):
- self.assertEqual(D["item"], 5)
- self.assertEqual(D["item"], 1)
+ D = {"x":1}
+ with support.swap_item(D, "x", 5) as x:
+ self.assertEqual(D["x"], 5)
+ self.assertEqual(x, 1)
+ self.assertEqual(D["x"], 1)
+ with support.swap_item(D, "y", 5) as y:
+ self.assertEqual(D["y"], 5)
+ self.assertIsNone(y)
+ self.assertNotIn("y", D)
+ with support.swap_item(D, "y", 5):
+ del D["y"]
+ self.assertNotIn("y", D)
class RefClass:
attribute1 = None
diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py
index 51df1ec..d0cf04b 100644
--- a/Lib/test/test_tempfile.py
+++ b/Lib/test/test_tempfile.py
@@ -273,13 +273,12 @@ class TestGetDefaultTempdir(BaseTestCase):
tempfile._get_default_tempdir()
self.assertEqual(os.listdir(our_temp_directory), [])
- open = io.open
def bad_writer(*args, **kwargs):
- fp = open(*args, **kwargs)
+ fp = orig_open(*args, **kwargs)
fp.write = raise_OSError
return fp
- with support.swap_attr(io, "open", bad_writer):
+ with support.swap_attr(io, "open", bad_writer) as orig_open:
# test again with failing write()
with self.assertRaises(FileNotFoundError):
tempfile._get_default_tempdir()
diff --git a/Misc/NEWS b/Misc/NEWS
index 71db0ee..026beff 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -1107,6 +1107,12 @@ Tools/Demos
Tests
-----
+- bpo-30197: Enhanced functions swap_attr() and swap_item() in the
+ test.support module. They now work when delete replaced attribute or item
+ inside the with statement. The old value of the attribute or item (or None
+ if it doesn't exist) now will be assigned to the target of the "as" clause,
+ if there is one.
+
- Issue #24932: Use proper command line parsing in _testembed
- Issue #28950: Disallow -j0 to be combined with -T/-l in regrtest