mirror of
https://github.com/python/cpython.git
synced 2025-09-30 12:21:51 +00:00
[3.6] bpo-30197: Enhance functions swap_attr() and swap_item() in test.support. (GH-1341) (#1345)
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.
(cherry picked from commit d1a1def7bf
)
This commit is contained in:
parent
e005dd9a6d
commit
712114b3f9
4 changed files with 46 additions and 13 deletions
|
@ -2105,12 +2105,15 @@ def swap_attr(obj, attr, new_val):
|
||||||
restoring the old value at the end of the block. If `attr` doesn't
|
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
|
exist on `obj`, it will be created and then deleted at the end of the
|
||||||
block.
|
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):
|
if hasattr(obj, attr):
|
||||||
real_val = getattr(obj, attr)
|
real_val = getattr(obj, attr)
|
||||||
setattr(obj, attr, new_val)
|
setattr(obj, attr, new_val)
|
||||||
try:
|
try:
|
||||||
yield
|
yield real_val
|
||||||
finally:
|
finally:
|
||||||
setattr(obj, attr, real_val)
|
setattr(obj, attr, real_val)
|
||||||
else:
|
else:
|
||||||
|
@ -2118,6 +2121,7 @@ def swap_attr(obj, attr, new_val):
|
||||||
try:
|
try:
|
||||||
yield
|
yield
|
||||||
finally:
|
finally:
|
||||||
|
if hasattr(obj, attr):
|
||||||
delattr(obj, attr)
|
delattr(obj, attr)
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
|
@ -2132,12 +2136,15 @@ def swap_item(obj, item, new_val):
|
||||||
restoring the old value at the end of the block. If `item` doesn't
|
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
|
exist on `obj`, it will be created and then deleted at the end of the
|
||||||
block.
|
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:
|
if item in obj:
|
||||||
real_val = obj[item]
|
real_val = obj[item]
|
||||||
obj[item] = new_val
|
obj[item] = new_val
|
||||||
try:
|
try:
|
||||||
yield
|
yield real_val
|
||||||
finally:
|
finally:
|
||||||
obj[item] = real_val
|
obj[item] = real_val
|
||||||
else:
|
else:
|
||||||
|
@ -2145,6 +2152,7 @@ def swap_item(obj, item, new_val):
|
||||||
try:
|
try:
|
||||||
yield
|
yield
|
||||||
finally:
|
finally:
|
||||||
|
if item in obj:
|
||||||
del obj[item]
|
del obj[item]
|
||||||
|
|
||||||
def strip_python_stderr(stderr):
|
def strip_python_stderr(stderr):
|
||||||
|
|
|
@ -282,17 +282,34 @@ class TestSupport(unittest.TestCase):
|
||||||
|
|
||||||
def test_swap_attr(self):
|
def test_swap_attr(self):
|
||||||
class Obj:
|
class Obj:
|
||||||
x = 1
|
pass
|
||||||
obj = Obj()
|
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(obj.x, 5)
|
||||||
|
self.assertEqual(x, 1)
|
||||||
self.assertEqual(obj.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):
|
def test_swap_item(self):
|
||||||
D = {"item":1}
|
D = {"x":1}
|
||||||
with support.swap_item(D, "item", 5):
|
with support.swap_item(D, "x", 5) as x:
|
||||||
self.assertEqual(D["item"], 5)
|
self.assertEqual(D["x"], 5)
|
||||||
self.assertEqual(D["item"], 1)
|
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:
|
class RefClass:
|
||||||
attribute1 = None
|
attribute1 = None
|
||||||
|
|
|
@ -273,13 +273,12 @@ class TestGetDefaultTempdir(BaseTestCase):
|
||||||
tempfile._get_default_tempdir()
|
tempfile._get_default_tempdir()
|
||||||
self.assertEqual(os.listdir(our_temp_directory), [])
|
self.assertEqual(os.listdir(our_temp_directory), [])
|
||||||
|
|
||||||
open = io.open
|
|
||||||
def bad_writer(*args, **kwargs):
|
def bad_writer(*args, **kwargs):
|
||||||
fp = open(*args, **kwargs)
|
fp = orig_open(*args, **kwargs)
|
||||||
fp.write = raise_OSError
|
fp.write = raise_OSError
|
||||||
return fp
|
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()
|
# test again with failing write()
|
||||||
with self.assertRaises(FileNotFoundError):
|
with self.assertRaises(FileNotFoundError):
|
||||||
tempfile._get_default_tempdir()
|
tempfile._get_default_tempdir()
|
||||||
|
|
|
@ -114,6 +114,15 @@ Documentation
|
||||||
|
|
||||||
- bpo-26985: Add missing info of code object in inspect documentation.
|
- bpo-26985: Add missing info of code object in inspect documentation.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
What's New in Python 3.6.1?
|
What's New in Python 3.6.1?
|
||||||
===========================
|
===========================
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue