我想通过在之前和之后运行带有附加代码的原始方法来修补方法。特别是,我pyfakefs
在内存文件系统中运行测试,但有时我想使用真实的文件系统,因为某些包无法在假文件系统上运行(pybedtools
在我的情况下)。
可能有简单的方法可以做到这一点,但经过多次尝试后我无法弄清楚。这可能吗?
仅举个例子,下面我正在尝试修补to_csv
熊猫。
import os
import tempfile
from unittest.mock import patch
import pandas as pd
from pyfakefs.fake_filesystem_unittest import Patcher
df_intervals = pd.DataFrame([
['1', 10, 20],
['20', 45, 55]],
columns=['chrom', 'start', 'end'])
with Patcher(use_known_patches=True) as patcher:
# As expecte writing to fake filesystem works
fname = tempfile.NamedTemporaryFile()
df_intervals.to_csv(fname.name)
assert not os.path.exists(fname.name)
assert patcher.fs.isfile(fname.name)
# But, how do I patch `to_csv` to write to the real filesystem? My failed attempts:
# Attempt 1
# TypeError: super(type, obj): obj must be an instance or subtype of type
class patched_DataFrame(pd.DataFrame):
def to_csv(self, fname):
print('Pausing fake file system')
patcher.pause()
super().to_csv(fname)
print('Resuming fake file system')
patcher.resume()
with patch.object(pd.core.generic.NDFrame, 'to_csv', new=patched_DataFrame.to_csv):
df_intervals.to_csv(fname.name)
# Attempt 2: TypeError: 'patched_DataFrame' object is not callable
with patch('pandas.core.frame.DataFrame', new_callable=patched_DataFrame):
df_intervals.to_csv(fname.name)
# Attempt 3: infinite recursion
def patched_to_csv(self, fname):
print('Pausing fake file system')
patcher.pause()
self.to_csv(fname)
print('Resuming fake file system')
patcher.resume()
with patch.object(pd.core.generic.NDFrame, 'to_csv', new=patched_to_csv):
df_intervals.to_csv(fname.name)