Fix fake_env, fix configparser issues, uniform 'open'.

- Update fake_env for compatibility with io.
- Uniform open (through _my_open in content).
- Fix read issue for config (although still using SafeConfigParser that
  is deprecated in py3).
main
Olivier Mangin 11 years ago
parent d758df2ac9
commit 136b8f83dc

@ -1,10 +1,9 @@
import os
import collections
from .p3 import configparser
from . import content
from .p3 import configparser, _read_config
from .content import system_path, check_file
from .content import check_file, _open
# constant stuff (DFT = DEFAULT)
@ -64,17 +63,15 @@ class Config(object):
_config = self
def load(self, path=DFT_CONFIG_PATH):
if not content.check_file(path, fail=False):
if not check_file(path, fail=False):
raise IOError(("The configuration file {} does not exist."
" Did you run 'pubs init' ?").format(path))
with open(content.system_path(path), 'r') as f:
read = self._cfg.readfp(f)
# if len(read) == 0:
# raise IOError("Syntax error in {} config file. Aborting.".format(path))
with _open(path, 'r') as f:
_read_config(self._cfg, f)
return self
def save(self, path=DFT_CONFIG_PATH):
with open(content.system_path(path), 'w') as f:
with _open(path, 'w') as f:
self._cfg.write(f)
def __setattr__(self, name, value):

@ -43,6 +43,10 @@ def system_path(path):
return os.path.abspath(os.path.expanduser(path))
def _open(path, mode):
return io.open(system_path(path), mode, encoding=ENCODING)
def check_file(path, fail=True):
syspath = system_path(path)
return (_check_system_path_exists(syspath, fail=fail)
@ -57,14 +61,14 @@ def check_directory(path, fail=True):
def read_file(filepath):
check_file(filepath)
with io.open(system_path(filepath), 'r', encoding=ENCODING) as f:
with _open(filepath, 'r') as f:
content = f.read()
return content
def write_file(filepath, data):
check_directory(os.path.dirname(filepath))
with io.open(system_path(filepath), 'w', encoding=ENCODING) as f:
with _open(filepath, 'w') as f:
f.write(data)

@ -1,25 +1,29 @@
import io
import sys
if sys.version_info[0] == 2:
import ConfigParser as configparser
_read_config = configparser.SafeConfigParser.readfp
input = raw_input
ustr = unicode
uchr = unichr
from urlparse import urlparse
from urllib2 import urlopen
from httplib import HTTPConnection
file = None
_fake_stdio = io.BytesIO # Only for tests to capture std{out,err}
else:
import configparser
_read_config = configparser.SafeConfigParser.read_file
ustr = str
uchr = chr
file = None
from urllib.parse import urlparse
from urllib.request import urlopen
from http.client import HTTPConnection
_fake_stdio = io.StringIO # Only for tests to capture std{out,err}
configparser = configparser
input = input
file = file
def isbasestr(obj):

@ -2,6 +2,7 @@ import copy
from dateutil.parser import parse as datetime_parse
from . import bibstruct
from .p3 import ustr
DEFAULT_META = {'docfile': None, 'tags': set()}
@ -11,7 +12,7 @@ def _clean_metadata(metadata):
meta = copy.deepcopy(DEFAULT_META)
meta.update(metadata or {}) # handles None metadata
meta['tags'] = set(meta.get('tags', [])) # tags should be a set
if 'added' in meta and isinstance(meta['added'], basestring):
if 'added' in meta and isinstance(meta['added'], ustr):
meta['added'] = datetime_parse(meta['added'])
return meta

@ -4,7 +4,6 @@ import sys
from .beets_ui import _encoding, input_
from .content import editor_input
from .p3 import ustr
from . import color
# package-shared ui that can be accessed using :
@ -39,10 +38,7 @@ class UI:
is not in the terminal's encoding's character set, just silently
replaces it.
"""
txt = [s.encode(self.encoding, 'replace')
if isinstance(s, ustr) else s
for s in strings]
print(' '.join(txt))
print(' '.join(strings).encode(self.encoding, 'replace'))
def input_choice(self, options, option_chars, default=None, question=''):
"""Ask the user to chose between a set of options. The iser is asked

@ -2,6 +2,7 @@
from setuptools import setup, find_packages
setup(name='pubs',
version='4',
author='Fabien Benureau, Olivier Mangin, Jonathan Grizou',
@ -10,5 +11,5 @@ setup(name='pubs',
description='research papers manager',
requires=['pyyaml', 'bibtexparser', 'dateutil'],
packages=find_packages(),
scripts=['pubs/pubs']
scripts=['pubs/pubs'],
)

@ -10,14 +10,13 @@ import fake_filesystem
import fake_filesystem_shutil
import fake_filesystem_glob
from pubs.p3 import input
from pubs.p3 import input, _fake_stdio
from pubs import content, filebroker
# code for fake fs
real_os = os
real_open = open
real_file = file
real_shutil = shutil
real_glob = glob
real_io = io
@ -41,7 +40,7 @@ ENCODING = 'utf8'
class UnicodeStringIOWrapper(object):
"""This is a hack because fake_filesystem does not provied mock of io.
"""This is a hack because fake_filesystem does not provide mock of io.
"""
override = ['read', 'readline', 'readlines', 'write', 'writelines']
@ -55,6 +54,10 @@ class UnicodeStringIOWrapper(object):
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)
@ -78,13 +81,24 @@ class UnicodeStringIOWrapper(object):
return self._strio.__exit__(*args)
def _force_binary_mode(mode):
if 'b' in mode:
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 python3 mode for FakeFileOpen
# 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)
@ -100,8 +114,6 @@ def create_fake_fs(module_list):
fake_fs.CreateDirectory(fake_os.path.expanduser('~'))
__builtins__.update({'open': fake_open, 'file': fake_open})
sys.modules['os'] = fake_os
sys.modules['shutil'] = fake_shutil
sys.modules['glob'] = fake_glob
@ -111,7 +123,7 @@ def create_fake_fs(module_list):
md.os = fake_os
md.shutil = fake_shutil
md.open = fake_open
md.file = fake_open
md.file = None
md.io = fake_io
return {'fs': fake_fs,
@ -125,10 +137,8 @@ def create_fake_fs(module_list):
def unset_fake_fs(module_list):
try:
__builtins__.open = real_open
__builtins__.file = real_file
except AttributeError:
__builtins__['open'] = real_open
__builtins__['file'] = real_file
sys.modules['os'] = real_os
sys.modules['shutil'] = real_shutil
@ -139,7 +149,6 @@ def unset_fake_fs(module_list):
md.os = real_os
md.shutil = real_shutil
md.open = real_open
md.file = real_file
md.io = real_io
@ -163,8 +172,8 @@ def copy_dir(fs, real_dir, fake_dir = None):
def redirect(f):
def newf(*args, **kwargs):
old_stderr, old_stdout = sys.stderr, sys.stdout
stdout = io.BytesIO()
stderr = io.BytesIO()
stdout = _fake_stdio()
stderr = _fake_stdio()
sys.stdout, sys.stderr = stdout, stderr
try:
return f(*args, **kwargs), stdout, stderr
@ -190,7 +199,7 @@ class FakeInput():
Then :
input() returns 'yes'
input() returns 'no'
input() raise IndexError
input() raises IndexError
"""
def __init__(self, inputs, module_list=tuple()):

@ -34,7 +34,6 @@ class TestEnDecode(unittest.TestCase):
data = decoder.encode_metadata(dummy_metadata)
self.assertIsInstance(data, ustr)
def test_endecode_bibtex(self):
decoder = endecoder.EnDecoder()
entry = decoder.decode_bibdata(bibtex_raw0)

@ -29,11 +29,11 @@ class TestFileBroker(fake_env.TestFakeFs):
fake_env.copy_dir(self.fs, os.path.join(os.path.dirname(__file__), 'testrepo'), 'testrepo')
fb = filebroker.FileBroker('testrepo', create = True)
with open('testrepo/bib/Page99.bib', 'r') as f:
self.assertEqual(fb.pull_bibfile('Page99'), f.read())
bib_content = content.read_file('testrepo/bib/Page99.bib')
self.assertEqual(fb.pull_bibfile('Page99'), bib_content)
with open('testrepo/meta/Page99.yaml', 'r') as f:
self.assertEqual(fb.pull_metafile('Page99'), f.read())
meta_content = content.read_file('testrepo/meta/Page99.yaml')
self.assertEqual(fb.pull_metafile('Page99'), meta_content)
def test_errors(self):

@ -66,12 +66,12 @@ class CommandTestCase(unittest.TestCase):
In the latter case, the command is :
1. a string reprensenting the command to execute
2. the user inputs to feed to the command during execution
3. the output excpected, verified with assertEqual
3. the output expected, verified with assertEqual
"""
outs = []
for cmd in cmds:
if hasattr(cmd, '__iter__'):
if not isinstance(cmd, p3.ustr):
if len(cmd) == 2:
input = fake_env.FakeInput(cmd[1], [content, uis, beets_ui, p3])
input.as_global()
@ -293,6 +293,7 @@ class TestUsecase(DataCommandTestCase):
print(self.fs['os'].listdir(docdir))
self.assertNotIn('turing-mind-1950.pdf', self.fs['os'].listdir(docdir))
def test_tag_list(self):
correct = [b'Initializing pubs in /paper_first\n',
b'',

Loading…
Cancel
Save