From 430915f81701dee7394e1e24609764711baf88ce Mon Sep 17 00:00:00 2001 From: Akos Kiss Date: Tue, 2 Oct 2018 13:31:42 +0200 Subject: [PATCH] Force utf-8 encoding when opening files The default `open(..., 'r')` may lead to errors when utf-8 encoded files are read on a platform with non-utf-8 default locale / preferred encoding. The `io` package allows to specify `encoding` for `open` in a Python 2 & 3-compatible way. --- chevron/main.py | 5 +++-- chevron/renderer.py | 4 +++- test_spec.py | 14 ++++++++++++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/chevron/main.py b/chevron/main.py index 649e776..35934ee 100755 --- a/chevron/main.py +++ b/chevron/main.py @@ -1,5 +1,6 @@ #!/usr/bin/python +import io import sys try: @@ -16,9 +17,9 @@ except (ValueError, SystemError): # python 2 def main(template, data={}, **kwargs): - with open(template, 'r') as template_file: + with io.open(template, 'r', encoding='utf-8') as template_file: if data != {}: - data_file = open(data, 'r') + data_file = io.open(data, 'r', encoding='utf-8') data = json.load(data_file) data_file.close() diff --git a/chevron/renderer.py b/chevron/renderer.py index 3944f99..e646094 100644 --- a/chevron/renderer.py +++ b/chevron/renderer.py @@ -1,5 +1,7 @@ # -*- coding: utf-8 -*- +import io + try: from .tokenizer import tokenize except (ValueError, SystemError): # python 2 @@ -91,7 +93,7 @@ def _get_partial(name, partials_dict, partials_path, partials_ext): try: # Maybe it's in the file system path = partials_path + '/' + name + '.' + partials_ext - with open(path, 'r') as partial: + with io.open(path, 'r', encoding='utf-8') as partial: return partial.read() except IOError: diff --git a/test_spec.py b/test_spec.py index 67d5ff5..627e911 100755 --- a/test_spec.py +++ b/test_spec.py @@ -4,9 +4,17 @@ import unittest import os import json +import io import chevron +import sys +if sys.version_info[0] == 3: + python3 = True +else: # python 2 + python3 = False + + SPECS_PATH = os.path.join('spec', 'specs') if os.path.exists(SPECS_PATH): SPECS = [path for path in os.listdir(SPECS_PATH) if path.endswith('.json')] @@ -35,7 +43,7 @@ def _test_case_from_path(json_path): obj['desc']) return test_case - with open(json_path, 'r') as f: + with io.open(json_path, 'r', encoding='utf-8') as f: yaml = json.load(f) # Generates a unit test for each test object @@ -124,8 +132,10 @@ class ExpandedCoverage(unittest.TestCase): result = chevron.main('tests/test.mustache', 'tests/data.json', partials_path='tests') - with open('tests/test.rendered', 'r') as f: + with io.open('tests/test.rendered', 'r', encoding='utf-8') as f: expected = f.read() + if not python3: + expected = expected.encode('utf-8') self.assertEqual(result, expected) -- 2.47.3