Skip to content

Commit c6a5e01

Browse files
committed
gyb: force I/O in UTF-8
We would rely on the system encoding, which if unspecified would fall back to `C` treating the encoding as ASCII. This fails with unicode data in Python3. Thanks to @tbkka for the brilliant idea of forcing the encoding when reading the file. This improves the test pass rate on Linux with Python 3.
1 parent 994edab commit c6a5e01

File tree

1 file changed

+22
-11
lines changed

1 file changed

+22
-11
lines changed

utils/gyb.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from __future__ import print_function
66

7+
import io
78
import os
89
import re
910
import sys
@@ -13,7 +14,7 @@
1314

1415

1516
try:
16-
from cStringIO import StringIO
17+
from StringIO import StringIO
1718
except ImportError:
1819
from io import StringIO
1920

@@ -401,7 +402,7 @@ def __init__(self, filename, template=None):
401402
if sys.platform == 'win32':
402403
self.filename = self.filename.replace('\\', '/')
403404
if template is None:
404-
with open(filename) as f:
405+
with io.open(filename, encoding='utf-8') as f:
405406
self.template = f.read()
406407
else:
407408
self.template = template
@@ -736,8 +737,10 @@ def execute(self, context):
736737
result_string = None
737738
if isinstance(result, Number) and not isinstance(result, Integral):
738739
result_string = repr(result)
739-
else:
740+
elif isinstance(result, Integral):
740741
result_string = str(result)
742+
else:
743+
result_string = StringIO(result).read()
741744
context.append_text(
742745
result_string, self.filename, self.start_line_number)
743746

@@ -803,7 +806,7 @@ def expand(filename, line_directive=_default_line_directive, **local_bindings):
803806
>>> f.close()
804807
>>> os.remove(f.name)
805808
"""
806-
with open(filename) as f:
809+
with io.open(filename, encoding='utf-8') as f:
807810
t = parse_template(filename, f.read())
808811
d = os.getcwd()
809812
os.chdir(os.path.dirname(os.path.abspath(filename)))
@@ -1208,12 +1211,12 @@ def succ(a):
12081211
help='''Bindings to be set in the template's execution context''')
12091212

12101213
parser.add_argument(
1211-
'file', type=argparse.FileType(),
1214+
'file', type=str,
12121215
help='Path to GYB template file (defaults to stdin)', nargs='?',
1213-
default=sys.stdin)
1216+
default='-')
12141217
parser.add_argument(
1215-
'-o', dest='target', type=argparse.FileType('w'),
1216-
help='Output file (defaults to stdout)', default=sys.stdout)
1218+
'-o', dest='target', type=str,
1219+
help='Output file (defaults to stdout)', default='-')
12171220
parser.add_argument(
12181221
'--test', action='store_true',
12191222
default=False, help='Run a self-test')
@@ -1245,15 +1248,23 @@ def succ(a):
12451248
sys.exit(1)
12461249

12471250
bindings = dict(x.split('=', 1) for x in args.defines)
1248-
ast = parse_template(args.file.name, args.file.read())
1251+
if args.file == '-':
1252+
ast = parse_template('stdin', sys.stdin.read())
1253+
else:
1254+
with io.open(args.file, 'r', encoding='utf-8') as f:
1255+
ast = parse_template(args.file, f.read())
12491256
if args.dump:
12501257
print(ast)
12511258
# Allow the template to open files and import .py files relative to its own
12521259
# directory
1253-
os.chdir(os.path.dirname(os.path.abspath(args.file.name)))
1260+
os.chdir(os.path.dirname(os.path.abspath(args.file)))
12541261
sys.path = ['.'] + sys.path
12551262

1256-
args.target.write(execute_template(ast, args.line_directive, **bindings))
1263+
if args.target == '-':
1264+
sys.stdout.write(execute_template(ast, args.line_directive, **bindings))
1265+
else:
1266+
with io.open(args.target, 'w', encoding='utf-8', newline='\n') as f:
1267+
f.write(execute_template(ast, args.line_directive, **bindings))
12571268

12581269

12591270
if __name__ == '__main__':

0 commit comments

Comments
 (0)