diff --git a/sass.py b/sass.py index ebd336c6..23221ad1 100644 --- a/sass.py +++ b/sass.py @@ -22,7 +22,7 @@ import sys import warnings -from six import string_types, text_type +from six import string_types, text_type, PY2, PY3 from _sass import OUTPUT_STYLES, compile_filename, compile_string @@ -48,10 +48,20 @@ MODES = set(['string', 'filename', 'dirname']) +def to_native_s(s): + if isinstance(s, bytes) and PY3: # pragma: no cover (py3) + s = s.decode('UTF-8') + elif isinstance(s, text_type) and PY2: # pragma: no cover (py2) + s = s.encode('UTF-8') + return s + + class CompileError(ValueError): """The exception type that is raised by :func:`compile()`. It is a subtype of :exc:`exceptions.ValueError`. """ + def __init__(self, msg): + super(CompileError, self).__init__(to_native_s(msg)) def mkdirp(path): diff --git a/sasstests.py b/sasstests.py index ab705462..d9ce8ca8 100644 --- a/sasstests.py +++ b/sasstests.py @@ -13,6 +13,7 @@ import subprocess import sys import tempfile +import traceback import unittest import warnings @@ -914,7 +915,7 @@ def test_error(self): assert False, 'Expected to raise' except sass.CompileError as e: msg, = e.args - assert msg.decode('UTF-8').startswith( + assert msg.startswith( 'Error: Invalid CSS after ' ), msg return @@ -1182,7 +1183,7 @@ def assert_raises_compile_error(expected): with pytest.raises(sass.CompileError) as excinfo: yield msg, = excinfo.value.args - assert msg.decode('UTF-8') == expected, (msg, expected) + assert msg == expected, (msg, expected) class RegexMatcher(object): @@ -1417,3 +1418,17 @@ def test_map_with_map_key(self): ), 'a{content:baz}\n', ) + + +def test_stack_trace_formatting(): + try: + sass.compile(string=u'a{☃') + assert False, 'expected to raise CompileError' + except sass.CompileError: + tb = traceback.format_exc() + assert tb.endswith( + 'CompileError: Error: Invalid CSS after "a{☃": expected "{", was ""\n' + ' on line 1 of stdin\n' + '>> a{☃\n' + ' --^\n\n' + )