Skip to content

Commit 8a23b22

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 7d02f3b commit 8a23b22

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
@@ -2243,3 +2243,55 @@ class SubclassedDataFrame(DataFrame):
22432243
@property
22442244
def _constructor(self):
22452245
return SubclassedDataFrame
2246+
2247+
2248+
@contextmanager
2249+
def patch(ob, attr, value):
2250+
"""Temporarily patch an attribute of an object.
2251+
2252+
Parameters
2253+
----------
2254+
ob : any
2255+
The object to patch. This must support attribute assignment for `attr`.
2256+
attr : str
2257+
The name of the attribute to patch.
2258+
value : any
2259+
The temporary attribute to assign.
2260+
2261+
Examples
2262+
--------
2263+
>>> class C(object):
2264+
... attribute = 'original'
2265+
...
2266+
>>> C.attribute
2267+
'original'
2268+
>>> with patch(C, 'attribute', 'patched'):
2269+
... in_context = C.attribute
2270+
...
2271+
>>> in_context
2272+
'patched'
2273+
>>> C.attribute # the value is reset when the context manager exists
2274+
'original'
2275+
2276+
Correctly replaces attribute when the manager exits with an exception.
2277+
>>> with patch(C, 'attribute', 'patched'):
2278+
... in_context = C.attribute
2279+
... raise ValueError()
2280+
Traceback (most recent call last):
2281+
...
2282+
ValueError
2283+
>>> in_context
2284+
'patched'
2285+
>>> C.attribute
2286+
'original'
2287+
"""
2288+
noattr = object() # mark that the attribute never existed
2289+
old = getattr(ob, attr, noattr)
2290+
setattr(ob, attr, value)
2291+
try:
2292+
yield
2293+
finally:
2294+
if old is noattr:
2295+
delattr(ob, attr)
2296+
else:
2297+
setattr(ob, attr, old)

0 commit comments

Comments
 (0)