blob: 749b79552dc33f1e5def942b1ed837becaec9e92 [file] [log] [blame]
# 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
try:
from django.core.files import locks
except ImportError:
locks = None
def get_modules_to_patch():
modules_to_patch = {}
if xlrd is not None:
modules_to_patch['xlrd'] = XLRDModule
if locks is not None:
modules_to_patch['django.core.files.locks'] = FakeLocks
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)
if locks is not None:
class FakeLocks:
"""django.core.files.locks uses low level OS functions, fake it."""
_locks_module = locks
def __init__(self, _):
pass
@staticmethod
def lock(f, flags):
return True
@staticmethod
def unlock(f):
return True
def __getattr__(self, name):
return getattr(self._locks_module, name)