Simplified fake_env code
1. Removed the unicode wrapper around fake_env io 2. Overrided pyfakefs cStringIO with StringIO (Python 2.x) 3. copy_dir will copy file in binary file to the fake filesystem *unless* they are bib, yaml, txt or md files 4. ui.handle_exception() conserve traceback Numerous unicode subtelties required diving into pyfakefs and configobj source code. Unicode on Python 2.x is the worst.
This commit is contained in:
parent
a7012f532d
commit
9ad6d8db25
@ -85,7 +85,7 @@ class PrintUI(object):
|
|||||||
|
|
||||||
def handle_exception(self, exc):
|
def handle_exception(self, exc):
|
||||||
if self.debug:
|
if self.debug:
|
||||||
raise exc
|
raise
|
||||||
else:
|
else:
|
||||||
self.error(ustr(exc))
|
self.error(ustr(exc))
|
||||||
self.exit()
|
self.exit()
|
||||||
|
@ -9,6 +9,16 @@ import dotdot
|
|||||||
from pyfakefs import (fake_filesystem, fake_filesystem_shutil,
|
from pyfakefs import (fake_filesystem, fake_filesystem_shutil,
|
||||||
fake_filesystem_glob)
|
fake_filesystem_glob)
|
||||||
|
|
||||||
|
# pyfakefs uses cStringIO under Python 2.x, which does not accept arbitrary unicode strings
|
||||||
|
# (see https://docs.python.org/2/library/stringio.html#module-cStringIO)
|
||||||
|
# io.StringIO does not accept `str`, so we're left with the StringIO module
|
||||||
|
# PS: this nonsense explains why Python 3.x was created.
|
||||||
|
try:
|
||||||
|
import StringIO
|
||||||
|
fake_filesystem.io = StringIO
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
from pubs.p3 import input, _fake_stdio, _get_fake_stdio_ucontent
|
from pubs.p3 import input, _fake_stdio, _get_fake_stdio_ucontent
|
||||||
from pubs import content, filebroker
|
from pubs import content, filebroker
|
||||||
|
|
||||||
@ -21,90 +31,23 @@ real_glob = glob
|
|||||||
real_io = io
|
real_io = io
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# def _mod_list():
|
|
||||||
# ml = []
|
|
||||||
# import pubs
|
|
||||||
# for importer, modname, ispkg in pkgutil.walk_packages(
|
|
||||||
# path=pubs.__path__,
|
|
||||||
# prefix=pubs.__name__ + '.',
|
|
||||||
# onerror=lambda x: None):
|
|
||||||
# # HACK to not load textnote
|
|
||||||
# if not modname.startswith('pubs.plugs.texnote'):
|
|
||||||
# ml.append((modname, __import__(modname, fromlist='dummy')))
|
|
||||||
# return ml
|
|
||||||
|
|
||||||
|
|
||||||
ENCODING = 'utf8'
|
ENCODING = 'utf8'
|
||||||
|
|
||||||
|
|
||||||
class UnicodeStringIOWrapper(object):
|
|
||||||
"""This is a hack because fake_filesystem does not provide mock of io.
|
|
||||||
"""
|
|
||||||
|
|
||||||
override = ['read', 'readline', 'readlines', 'write', 'writelines']
|
|
||||||
|
|
||||||
def __init__(self, strio):
|
|
||||||
self._strio = strio # The real StringIO
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
|
||||||
if name in UnicodeStringIOWrapper.override:
|
|
||||||
return object.__getattribute__(self, name)
|
|
||||||
else:
|
|
||||||
return self._strio.__getattribute__(name)
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
for l in self.readlines():
|
|
||||||
yield l
|
|
||||||
|
|
||||||
def read(self, *args):
|
|
||||||
return self._strio.read(*args).decode(ENCODING)
|
|
||||||
|
|
||||||
def readline(self, *args):
|
|
||||||
return self._strio.readline(*args).decode(ENCODING)
|
|
||||||
|
|
||||||
def readlines(self, *args):
|
|
||||||
return [l.decode(ENCODING) for l in self._strio.readlines(*args)]
|
|
||||||
|
|
||||||
def write(self, data):
|
|
||||||
self._strio.write(data.encode(ENCODING))
|
|
||||||
|
|
||||||
def writelines(self, data):
|
|
||||||
self._strio.write([l.encode(ENCODING) for l in data])
|
|
||||||
|
|
||||||
def __enter__(self):
|
|
||||||
self._strio.__enter__()
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __exit__(self, *args):
|
|
||||||
return self._strio.__exit__(*args)
|
|
||||||
|
|
||||||
|
|
||||||
def _force_binary_mode(mode):
|
|
||||||
if 'b' in mode:
|
|
||||||
return mode # python 2 fix.
|
|
||||||
# raise ValueError('Open should not happen in binary mode.')
|
|
||||||
return mode + 'b'
|
|
||||||
|
|
||||||
|
|
||||||
class FakeIO(object):
|
class FakeIO(object):
|
||||||
|
|
||||||
def __init__(self, fake_open):
|
def __init__(self, fake_open):
|
||||||
self.fake_open = fake_open
|
self.fake_open = fake_open
|
||||||
|
|
||||||
def open(self, *args, **kwargs):
|
def open(self, file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True):
|
||||||
# Forces binary mode for FakeFileOpen
|
# encoding is ignored by pyfakefs
|
||||||
args = list(args)
|
# https://github.com/jmcgeheeiv/pyfakefs/blob/master/pyfakefs/fake_filesystem.py#L2143
|
||||||
if len(args) > 1:
|
return self.fake_open(file, mode=mode, buffering=buffering)
|
||||||
args[1] = _force_binary_mode(args[1])
|
|
||||||
else:
|
|
||||||
kwargs['mode'] = _force_binary_mode(kwargs.get('mode', 'r'))
|
|
||||||
fakefs_stringio = self.fake_open.Call(*args, **kwargs)
|
|
||||||
return UnicodeStringIOWrapper(fakefs_stringio)
|
|
||||||
|
|
||||||
BytesIO = real_io.BytesIO
|
BytesIO = real_io.BytesIO
|
||||||
StringIO = real_io.StringIO
|
StringIO = real_io.StringIO
|
||||||
|
|
||||||
|
|
||||||
def create_fake_fs(module_list):
|
def create_fake_fs(module_list):
|
||||||
|
|
||||||
fake_fs = fake_filesystem.FakeFilesystem()
|
fake_fs = fake_filesystem.FakeFilesystem()
|
||||||
@ -162,8 +105,14 @@ def copy_dir(fs, real_dir, fake_dir = None):
|
|||||||
real_path = os.path.abspath(real_os.path.join(real_dir, filename))
|
real_path = os.path.abspath(real_os.path.join(real_dir, filename))
|
||||||
fake_path = fs['os'].path.join(fake_dir, filename)
|
fake_path = fs['os'].path.join(fake_dir, filename)
|
||||||
if real_os.path.isfile(real_path):
|
if real_os.path.isfile(real_path):
|
||||||
with real_open(real_path, 'rb') as f:
|
_, ext = real_os.path.splitext(filename)
|
||||||
fs['fs'].CreateFile(fake_path, contents=f.read())
|
if ext in ['.yaml', '.bib', '.txt', '.md']:
|
||||||
|
with real_io.open(real_path, 'r', encoding='utf-8') as f:
|
||||||
|
fs['fs'].CreateFile(fake_path, contents=f.read())
|
||||||
|
else:
|
||||||
|
with real_io.open(real_path, 'rb') as f:
|
||||||
|
fs['fs'].CreateFile(fake_path, contents=f.read())
|
||||||
|
|
||||||
if real_os.path.isdir(real_path):
|
if real_os.path.isdir(real_path):
|
||||||
fs['fs'].CreateDirectory(fake_path)
|
fs['fs'].CreateDirectory(fake_path)
|
||||||
copy_dir(fs, real_path, fake_path)
|
copy_dir(fs, real_path, fake_path)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user