Skip to content

Commit 4151323

Browse files
committed
Fix coding error rise when non-ASCII chars passed
1 parent 8acbcf6 commit 4151323

File tree

5 files changed

+72
-4
lines changed

5 files changed

+72
-4
lines changed

docs/changes.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
Changelog
22
=========
33

4+
Version 0.4.1
5+
-------------
6+
7+
To be released.
8+
9+
- Fixed :exc:`UnicodeEncodeError` that rise when the input source contains
10+
any non-ASCII Unicode characters.
11+
12+
413
Version 0.4.0
514
-------------
615

sassc.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,10 @@ def main(argv=sys.argv, stdout=sys.stdout, stderr=sys.stderr):
147147
print(css, file=stdout)
148148
else:
149149
with open(args[1], 'w') as f:
150-
print(css, file=f)
150+
try:
151+
print(css, file=f)
152+
except UnicodeEncodeError:
153+
print(css.encode('utf-8'), file=f)
151154
if options.watch:
152155
print(filename, 'is just compiled to', args[1],
153156
file=stdout)

sasstests.py

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# -*- coding: utf-8 -*-
12
from __future__ import with_statement
23

34
import collections
@@ -9,7 +10,7 @@
910
import tempfile
1011
import unittest
1112

12-
from six import StringIO, b
13+
from six import StringIO, b, text_type
1314
from werkzeug.test import Client
1415
from werkzeug.wrappers import Response
1516

@@ -57,6 +58,13 @@
5758
color: green; }
5859
'''
5960

61+
D_EXPECTED_CSS = '''\
62+
body {
63+
background-color: green; }
64+
body a {
65+
font: '나눔고딕', sans-serif; }
66+
'''
67+
6068

6169
class SassTestCase(unittest.TestCase):
6270

@@ -141,6 +149,14 @@ def test_compile_string(self):
141149
a b {
142150
color: blue; }
143151
'''
152+
actual = sass.compile(string=u'a { color: blue; } /* 유니코드 */')
153+
self.assertEqual(
154+
u'''a {
155+
color: blue; }
156+
157+
/* 유니코드 */''',
158+
actual
159+
)
144160
self.assertRaises(sass.CompileError, sass.compile,
145161
string='a { b { color: blue; }')
146162
# sass.CompileError should be a subtype of ValueError
@@ -158,6 +174,11 @@ def test_compile_filename(self):
158174
assert actual == A_EXPECTED_CSS
159175
actual = sass.compile(filename='test/c.sass')
160176
assert actual == C_EXPECTED_CSS
177+
actual = sass.compile(filename='test/d.sass')
178+
if text_type is str:
179+
self.assertEqual(D_EXPECTED_CSS, actual)
180+
else:
181+
self.assertEqual(D_EXPECTED_CSS.decode('utf-8'), actual)
161182
self.assertRaises(IOError, sass.compile,
162183
filename='test/not-exist.sass')
163184
self.assertRaises(TypeError, sass.compile, filename=1234)
@@ -205,7 +226,7 @@ def test_builder_build_directory(self):
205226
css_path = os.path.join(temp_path, 'css')
206227
shutil.copytree('test', sass_path)
207228
result_files = build_directory(sass_path, css_path)
208-
assert len(result_files) == 3
229+
assert len(result_files) == 4
209230
assert result_files['a.sass'] == 'a.sass.css'
210231
with open(os.path.join(css_path, 'a.sass.css')) as f:
211232
css = f.read()
@@ -218,6 +239,10 @@ def test_builder_build_directory(self):
218239
with open(os.path.join(css_path, 'c.sass.css')) as f:
219240
css = f.read()
220241
assert css == C_EXPECTED_CSS
242+
assert result_files['d.sass'] == 'd.sass.css'
243+
with open(os.path.join(css_path, 'd.sass.css')) as f:
244+
css = f.read()
245+
self.assertEqual(D_EXPECTED_CSS, css)
221246
shutil.rmtree(temp_path)
222247

223248

@@ -345,6 +370,23 @@ def test_sassc_output(self):
345370
finally:
346371
os.remove(tmp)
347372

373+
def test_sassc_output_unicode(self):
374+
fd, tmp = tempfile.mkstemp('.css')
375+
try:
376+
os.close(fd)
377+
exit_code = sassc.main(['sassc', 'test/d.sass', tmp],
378+
self.out, self.err)
379+
self.assertEqual(0, exit_code)
380+
self.assertEqual('', self.err.getvalue())
381+
self.assertEqual('', self.out.getvalue())
382+
with open(tmp) as f:
383+
self.assertEqual(
384+
D_EXPECTED_CSS.strip(),
385+
f.read().strip()
386+
)
387+
finally:
388+
os.remove(tmp)
389+
348390
def test_sassc_source_map_without_css_filename(self):
349391
exit_code = sassc.main(['sassc', '-m', 'a.scss'], self.out, self.err)
350392
self.assertEqual(2, exit_code)

sassutils/builder.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ def build_directory(sass_path, css_path, _root_sass=None, _root_css=None):
5050
css_fullname = os.path.join(css_path, name) + '.css'
5151
css = compile(filename=sass_fullname, include_paths=[_root_sass])
5252
with open(css_fullname, 'w') as css_file:
53-
css_file.write(css)
53+
try:
54+
css_file.write(css)
55+
except UnicodeEncodeError:
56+
css_file.write(css.encode('utf-8'))
5457
result[os.path.relpath(sass_fullname, _root_sass)] = \
5558
os.path.relpath(css_fullname, _root_css)
5659
elif os.path.isdir(sass_fullname):

test/d.sass

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
@mixin mx {
3+
background-color: green;
4+
}
5+
6+
body {
7+
@include mx;
8+
a {
9+
font: '나눔고딕', sans-serif;
10+
}
11+
}

0 commit comments

Comments
 (0)