Kronuz/pyScss

ZeroDivisionError when evaluating linear-gradient()

matyasrichter opened this issue · 1 comments

When parsing a file which contains the following expression:

$color_whisper_approx: #f5f4f9;
$color_athens_gray_approx: #eceaf3;

...

.panel-heading {
	...
	background-image: linear-gradient(to bottom, $color_whisper_approx 0, $color_athens_gray_approx 100%);
        ...
}

the package raises a ZeroDivisionError. Here's the traceback:

$ python -m scss < admin/css/main.scss

Traceback (most recent call last):
  File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/__main__.py", line 3, in <module>
    scss.tool.main()
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/tool.py", line 145, in main
    do_build(options, args)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/tool.py", line 193, in do_build
    output = css.compile(source_files=source_files)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/legacy.py", line 189, in compile
    compiled = compiler.call_and_catch_errors(compilation.run)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/compiler.py", line 176, in call_and_catch_errors
    return f(*args, **kwargs)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/compiler.py", line 296, in run
    self.manage_children(rule, scope=None)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/compiler.py", line 349, in manage_children
    self._manage_children_impl(rule, scope)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/compiler.py", line 398, in _manage_children_impl
    self._nest_rules(rule, scope, block)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/compiler.py", line 1203, in _nest_rules
    self.manage_children(new_rule, scope)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/compiler.py", line 349, in manage_children
    self._manage_children_impl(rule, scope)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/compiler.py", line 383, in _manage_children_impl
    self._get_properties(rule, scope, block)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/compiler.py", line 1090, in _get_properties
    value = calculator.calculate(raw_value)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/calculator.py", line 116, in calculate
    result = self.evaluate_expression(expression, divide=divide)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/calculator.py", line 143, in evaluate_expression
    six.reraise(SassEvaluationError, SassEvaluationError(e, expression=expr), sys.exc_info()[2])
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/calculator.py", line 141, in evaluate_expression
    return ast.evaluate(self, divide=divide)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/ast.py", line 230, in evaluate
    ret = funct(*args, **kwargs)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/extension/compass/gradients.py", line 317, in linear_gradient
    color_stops = __color_stops(False, *color_stops)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/extension/compass/gradients.py", line 73, in __color_stops
    stops = [_s / max_stops if _s and not _s.is_simple_unit('%') else _s for _s in stops]
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/types.py", line 408, in __div__
    amount = self.value / other.value
  File "/usr/lib/python2.7/fractions.py", line 362, in forward
    return monomorphic_operator(a, b)
  File "/usr/lib/python2.7/fractions.py", line 412, in _div
    a.denominator * b.numerator)
  File "/usr/lib/python2.7/fractions.py", line 162, in __new__
    raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
scss.errors.SassEvaluationError: Error evaluating expression:
    linear-gradient(to bottom, $color_whisper_approx 0, $color_athens_gray_approx 100%)

on line 3227 of /home/matyas/code/work/projects/project/project/static/<stdin>
Traceback:
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/calculator.py", line 141, in evaluate_expression
    return ast.evaluate(self, divide=divide)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/ast.py", line 230, in evaluate
    ret = funct(*args, **kwargs)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/extension/compass/gradients.py", line 317, in linear_gradient
    color_stops = __color_stops(False, *color_stops)
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/extension/compass/gradients.py", line 73, in __color_stops
    stops = [_s / max_stops if _s and not _s.is_simple_unit('%') else _s for _s in stops]
  File "/home/matyas/.virtualenvs/project/lib/python2.7/site-packages/scss/types.py", line 408, in __div__
    amount = self.value / other.value
  File "/usr/lib/python2.7/fractions.py", line 362, in forward
    return monomorphic_operator(a, b)
  File "/usr/lib/python2.7/fractions.py", line 412, in _div
    a.denominator * b.numerator)
  File "/usr/lib/python2.7/fractions.py", line 162, in __new__
    raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
ZeroDivisionError: Fraction(0, 0)

The line is however perfectly valid CSS, it passes the W3 CSS Validator just fine.

Interestingly enough, compiling the line manually produces the desired output:

Python 2.7.18 (default, Apr 23 2020, 22:32:06) 
[GCC 9.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from scss import Compiler
>>> Compiler().compile_string("$color_whisper_approx: #f5f4f9; $color_athens_gray_approx: #eceaf3; .panel-heading { background-image: linear-gradient(to bottom, $color_whisper_approx 0, $color_athens_gray_approx 100%); }")
u'.panel-heading {\n  background-image: linear-gradient(to bottom, #f5f4f9 0, #eceaf3 100%); }\n'

Am I doing something wrong? Could this perhaps be a Python 2.7 issue?

This can be fixed by adding a unit to the "0":

background-image: linear-gradient(to bottom, $color_whisper_approx 0%, $color_athens_gray_approx 100%);

compiles just fine.