Mercurial > hgrepos > Python > libs > ConfigMix
changeset 166:b5ce9a8461bf
Use the filesystem encoding explicitely where appropriate.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Thu, 14 Mar 2019 01:35:16 +0100 |
| parents | 6ca90e80f4f4 |
| children | d8155c429171 |
| files | CHANGES.txt configmix/__init__.py configmix/compat.py configmix/ini.py configmix/json.py configmix/py.py doc/conf.py |
| diffstat | 7 files changed, 53 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/CHANGES.txt Thu Mar 14 00:21:30 2019 +0100 +++ b/CHANGES.txt Thu Mar 14 01:35:16 2019 +0100 @@ -1,7 +1,7 @@ .. -*- coding: utf-8; mode: rst; indent-tabs-mode: nil; -*- .. -.. Valid tags: breaking, feature, bugfix, test, doc +.. Valid tags: breaking, feature, bugfix, misc, test, doc .. .. _changelog: @@ -38,6 +38,11 @@ with ``__doc`` or ``__comment``. .. change:: + :tags: misc + + Use the filesystem encoding where appripriate. + + .. change:: :tags: doc Begin the documentation with `Sphinx <http://www.sphinx-doc.org>`_
--- a/configmix/__init__.py Thu Mar 14 00:21:30 2019 +0100 +++ b/configmix/__init__.py Thu Mar 14 01:35:16 2019 +0100 @@ -21,7 +21,7 @@ import copy -from .compat import u +from .compat import u, u2fs from .config import Configuration @@ -73,7 +73,7 @@ def _load_yaml(filename): from . import yaml - with open(filename, "rb") as yf: + with open(u2fs(filename), "rb") as yf: return yaml.safe_load(yf)
--- a/configmix/compat.py Thu Mar 14 00:21:30 2019 +0100 +++ b/configmix/compat.py Thu Mar 14 01:35:16 2019 +0100 @@ -10,13 +10,15 @@ from __future__ import division, absolute_import, print_function import sys +import os import locale __all__ = ["PY2", "text_to_native_os_str", "native_os_str_to_text", - "u"] + "u", + "u2fs"] PY2 = sys.version_info[0] <= 2 @@ -26,6 +28,9 @@ _OS_ENCODING = locale.getpreferredencoding() + _FS_ENCODING = sys.getfilesystemencoding() or _OS_ENCODING + + def text_to_native_os_str(s, encoding=None): if isinstance(s, unicode): return s.encode(encoding or _OS_ENCODING) @@ -43,6 +48,21 @@ else: return s.decode(encoding) + + def u2fs(s, force=False): + """Convert a text (Unicode) string to the filesystem encoding. + + .. note:: If `s` is already a byte string be permissive and + return `s` unchanged. + + """ + if isinstance(s, str): + return s + if not force and os.name in ("nt", "ce"): + # WinNT and CE have native Unicode support: nothing to convert + return s + return s.encode(_FS_ENCODING) + else: def text_to_native_os_str(s, encoding=None): @@ -52,8 +72,20 @@ def native_os_str_to_text(s, encoding=None): return s + def u(s, encoding="utf-8"): if isinstance(s, str): return s else: return s.decode(encoding) + + + def u2fs(s, force=False): + """Convert a text (Unicode) string to the filesystem encoding. + + .. note:: The filesystem encoding on Python 3 is a Unicode text + string. The function is a noop when called on Python 3. + + """ + assert isinstance(s, str) + return s
--- a/configmix/ini.py Thu Mar 14 00:21:30 2019 +0100 +++ b/configmix/ini.py Thu Mar 14 01:35:16 2019 +0100 @@ -32,7 +32,7 @@ except ImportError: DictImpl = dict -from .compat import PY2, u +from .compat import PY2, u, u2fs __all__ = ["INIConfigParser", "NoSectionError", "NoOptionError", @@ -50,16 +50,13 @@ _ConfigParserBase.__init__(self) if executable is None: executable = sys.argv[0] - if PY2: - if isinstance(filename, str): - filename = filename.decode(locale.getpreferredencoding()) - if isinstance(executable, str): - executable = executable.decode(locale.getpreferredencoding()) + filename = u(filename, locale.getpreferredencoding()) + executable = u(executable, locale.getpreferredencoding()) self.executable = os.path.normpath(os.path.abspath(executable)) if encoding is None: encoding = locale.getpreferredencoding() self.encoding = encoding - with io.open(filename, mode="rt", encoding=self.encoding) as cf: + with io.open(u2fs(filename), mode="rt", encoding=self.encoding) as cf: self.read_file(cf, filename) def optionxform(self, option): @@ -91,9 +88,7 @@ if hasattr(self, "filename"): raise RuntimeError("already initialized") filename = os.path.normpath(os.path.abspath(filename)) - if PY2: - if isinstance(filename, str): - filename = filename.decode(locale.getpreferredencoding()) + filename = u(filename, locale.getpreferredencoding()) self.set(None, u("self"), filename) self.set(None, u("here"), os.path.dirname(filename)) self.set(None, u("root"), os.path.dirname(self.executable))
--- a/configmix/json.py Thu Mar 14 00:21:30 2019 +0100 +++ b/configmix/json.py Thu Mar 14 01:35:16 2019 +0100 @@ -19,6 +19,8 @@ except ImportError: DictImpl = dict +from .compat import u2fs + __all__ = ["load"] @@ -39,7 +41,7 @@ """Load a single JSON file with name `filename` and encoding `encoding`. """ - with io.open(filename, mode="rt", encoding=encoding) as jsfp: + with io.open(u2fs(filename), mode="rt", encoding=encoding) as jsfp: # # The scanner (not to be changed yet) does only recognize decimal # integers yet.
--- a/configmix/py.py Thu Mar 14 00:21:30 2019 +0100 +++ b/configmix/py.py Thu Mar 14 01:35:16 2019 +0100 @@ -18,7 +18,7 @@ except ImportError: DictImpl = dict -from .compat import PY2 +from .compat import PY2, u2fs __all__ = ["load"] @@ -43,9 +43,7 @@ gcontext = DictImpl() lcontext = DictImpl() if PY2: - filename2 = filename.encode(locale.getpreferredencoding()) - if PY2: - execfile(filename2, gcontext, lcontext) + execfile(u2fs(filename, True), gcontext, lcontext) else: # "rb" mode allows Python to derive the encoding automatically with open(filename, "rb") as vf:
--- a/doc/conf.py Thu Mar 14 00:21:30 2019 +0100 +++ b/doc/conf.py Thu Mar 14 01:35:16 2019 +0100 @@ -211,7 +211,8 @@ # -- Options for changelog --------------------------------------------------- -changelog_inner_tag_sort = ['breaking', 'feature', 'bugfix', 'test', 'doc'] +changelog_inner_tag_sort = ['breaking', 'feature', 'bugfix', 'misc', + 'test', 'doc'] def setup(app):
