diff --git a/pubs/uis.py b/pubs/uis.py index 47b973e..7298e77 100644 --- a/pubs/uis.py +++ b/pubs/uis.py @@ -85,7 +85,7 @@ class PrintUI(object): def handle_exception(self, exc): if self.debug: - raise exc + raise else: self.error(ustr(exc)) self.exit() diff --git a/tests/fake_env.py b/tests/fake_env.py index ef3db67..ccceb19 100644 --- a/tests/fake_env.py +++ b/tests/fake_env.py @@ -9,6 +9,16 @@ import dotdot from pyfakefs import (fake_filesystem, fake_filesystem_shutil, 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 import content, filebroker @@ -21,90 +31,23 @@ real_glob = glob 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' - -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): def __init__(self, fake_open): self.fake_open = fake_open - def open(self, *args, **kwargs): - # Forces binary mode for FakeFileOpen - args = list(args) - if len(args) > 1: - 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) + def open(self, file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True): + # encoding is ignored by pyfakefs + # https://github.com/jmcgeheeiv/pyfakefs/blob/master/pyfakefs/fake_filesystem.py#L2143 + return self.fake_open(file, mode=mode, buffering=buffering) + BytesIO = real_io.BytesIO StringIO = real_io.StringIO + def create_fake_fs(module_list): 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)) fake_path = fs['os'].path.join(fake_dir, filename) if real_os.path.isfile(real_path): - with real_open(real_path, 'rb') as f: - fs['fs'].CreateFile(fake_path, contents=f.read()) + _, ext = real_os.path.splitext(filename) + 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): fs['fs'].CreateDirectory(fake_path) copy_dir(fs, real_path, fake_path)