forked from pytest-dev/pyfakefs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added partial support for pandas to work with pyfakefs
- support for read_csv and read_excel (with the default module) - see pytest-dev#531
- Loading branch information
1 parent
d543219
commit 520914f
Showing
8 changed files
with
230 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
""" | ||
Provides patches for some commonly used modules that enable them to work | ||
with pyfakefs. | ||
""" | ||
import sys | ||
|
||
try: | ||
import pandas.io.parsers as parsers | ||
except ImportError: | ||
parsers = None | ||
|
||
try: | ||
import xlrd | ||
except ImportError: | ||
xlrd = None | ||
|
||
|
||
def get_modules_to_patch(): | ||
modules_to_patch = {} | ||
if xlrd is not None: | ||
modules_to_patch['xlrd'] = XLRDModule | ||
return modules_to_patch | ||
|
||
|
||
def get_classes_to_patch(): | ||
classes_to_patch = {} | ||
if parsers is not None: | ||
classes_to_patch[ | ||
'TextFileReader' | ||
] = 'pandas.io.parsers' | ||
return classes_to_patch | ||
|
||
|
||
def get_fake_module_classes(): | ||
fake_module_classes = {} | ||
if parsers is not None: | ||
fake_module_classes[ | ||
'TextFileReader' | ||
] = FakeTextFileReader | ||
return fake_module_classes | ||
|
||
|
||
if xlrd is not None: | ||
class XLRDModule: | ||
"""Patches the xlrd module, which is used as the default Excel file | ||
reader by pandas. Disables using memory mapped files, which are | ||
implemented platform-specific on OS level.""" | ||
|
||
def __init__(self, _): | ||
self._xlrd_module = xlrd | ||
|
||
def open_workbook(self, filename=None, | ||
logfile=sys.stdout, | ||
verbosity=0, | ||
use_mmap=False, | ||
file_contents=None, | ||
encoding_override=None, | ||
formatting_info=False, | ||
on_demand=False, | ||
ragged_rows=False): | ||
return self._xlrd_module.open_workbook( | ||
filename, logfile, verbosity, False, file_contents, | ||
encoding_override, formatting_info, on_demand, ragged_rows) | ||
|
||
def __getattr__(self, name): | ||
"""Forwards any unfaked calls to the standard xlrd module.""" | ||
return getattr(self._xlrd_module, name) | ||
|
||
if parsers is not None: | ||
# we currently need to add fake modules for both the parser module and | ||
# the contained text reader - maybe this can be simplified | ||
|
||
class FakeTextFileReader: | ||
fake_parsers = None | ||
|
||
def __init__(self, filesystem): | ||
if self.fake_parsers is None: | ||
self.__class__.fake_parsers = ParsersModule(filesystem) | ||
|
||
def __call__(self, *args, **kwargs): | ||
return self.fake_parsers.TextFileReader(*args, **kwargs) | ||
|
||
def __getattr__(self, name): | ||
return getattr(self.fake_parsers.TextFileReader, name) | ||
|
||
class ParsersModule: | ||
def __init__(self, _): | ||
self._parsers_module = parsers | ||
|
||
class TextFileReader(parsers.TextFileReader): | ||
def __init__(self, *args, **kwargs): | ||
kwargs['engine'] = 'python' | ||
super().__init__(*args, **kwargs) | ||
|
||
def __getattr__(self, name): | ||
"""Forwards any unfaked calls to the standard xlrd module.""" | ||
return getattr(self._parsers_module, name) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
""" | ||
Provides patches for some commonly used modules that enable them to work | ||
with pyfakefs. | ||
""" | ||
import os | ||
|
||
from pyfakefs import fake_filesystem_unittest | ||
|
||
try: | ||
import pandas as pd | ||
except ImportError: | ||
pd = None | ||
|
||
try: | ||
import xlrd | ||
except ImportError: | ||
xlrd = None | ||
|
||
|
||
class TestPatchedPackages(fake_filesystem_unittest.TestCase): | ||
def setUp(self): | ||
self.setUpPyfakefs() | ||
|
||
if pd is not None: | ||
def test_load_csv(self): | ||
path = '/foo/bar.csv' | ||
self.fs.create_file(path, contents='1,2,3,4') | ||
df = pd.read_csv(path) | ||
assert (df.columns == ['1', '2', '3', '4']).all() | ||
|
||
if pd is not None and xlrd is not None: | ||
def test_load_excel(self): | ||
path = '/foo/bar.xlsx' | ||
src_path = os.path.dirname(os.path.abspath(__file__)) | ||
src_path = os.path.join(src_path, 'fixtures', 'excel_test.xlsx') | ||
# map the file into another location to be sure that | ||
# the real fs is not used | ||
self.fs.add_real_file(src_path, target_path=path) | ||
df = pd.read_excel(path) | ||
assert (df.columns == [1, 2, 3, 4]).all() |