Skip to content

Commit e896603

Browse files
author
Joe Jevnik
committed
TST: adds pandas.util.testing.patch
This function temporarily replaces a an attribute on an object for the duration of some context manager. This is useful for patching methods to inject assertions or mock out expensive operations.
1 parent 84d7275 commit e896603

File tree

2 files changed

+54
-16
lines changed

2 files changed

+54
-16
lines changed

pandas/io/tests/test_packers.py

+2-16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import nose
22

3-
from contextlib import contextmanager
43
import os
54
import datetime
65
import numpy as np
@@ -16,7 +15,8 @@
1615
import pandas.util.testing as tm
1716
from pandas.util.testing import (ensure_clean, assert_index_equal,
1817
assert_series_equal,
19-
assert_frame_equal)
18+
assert_frame_equal,
19+
patch)
2020
from pandas.tests.test_panel import assert_panel_equal
2121

2222
import pandas
@@ -59,20 +59,6 @@ def check_arbitrary(a, b):
5959
assert(a == b)
6060

6161

62-
@contextmanager
63-
def patch(ob, attr, value):
64-
noattr = object() # mark that the attribute never existed
65-
old = getattr(ob, attr, noattr)
66-
setattr(ob, attr, value)
67-
try:
68-
yield
69-
finally:
70-
if old is noattr:
71-
delattr(ob, attr)
72-
else:
73-
setattr(ob, attr, old)
74-
75-
7662
class TestPackers(tm.TestCase):
7763

7864
def setUp(self):

pandas/util/testing.py

+52
Original file line numberDiff line numberDiff line change
@@ -2313,3 +2313,55 @@ class SubclassedDataFrame(DataFrame):
23132313
@property
23142314
def _constructor(self):
23152315
return SubclassedDataFrame
2316+
2317+
2318+
@contextmanager
2319+
def patch(ob, attr, value):
2320+
"""Temporarily patch an attribute of an object.
2321+
2322+
Parameters
2323+
----------
2324+
ob : any
2325+
The object to patch. This must support attribute assignment for `attr`.
2326+
attr : str
2327+
The name of the attribute to patch.
2328+
value : any
2329+
The temporary attribute to assign.
2330+
2331+
Examples
2332+
--------
2333+
>>> class C(object):
2334+
... attribute = 'original'
2335+
...
2336+
>>> C.attribute
2337+
'original'
2338+
>>> with patch(C, 'attribute', 'patched'):
2339+
... in_context = C.attribute
2340+
...
2341+
>>> in_context
2342+
'patched'
2343+
>>> C.attribute # the value is reset when the context manager exists
2344+
'original'
2345+
2346+
Correctly replaces attribute when the manager exits with an exception.
2347+
>>> with patch(C, 'attribute', 'patched'):
2348+
... in_context = C.attribute
2349+
... raise ValueError()
2350+
Traceback (most recent call last):
2351+
...
2352+
ValueError
2353+
>>> in_context
2354+
'patched'
2355+
>>> C.attribute
2356+
'original'
2357+
"""
2358+
noattr = object() # mark that the attribute never existed
2359+
old = getattr(ob, attr, noattr)
2360+
setattr(ob, attr, value)
2361+
try:
2362+
yield
2363+
finally:
2364+
if old is noattr:
2365+
delattr(ob, attr)
2366+
else:
2367+
setattr(ob, attr, old)

0 commit comments

Comments
 (0)