def evaluate(self, calculator, divide=False): # TODO bake this into the context and options "dicts", plus library func_name = normalize_var(self.func_name) argspec_node = self.argspec # Turn the pairs of arg tuples into *args and **kwargs # TODO unclear whether this is correct -- how does arg, kwarg, arg # work? args, kwargs = argspec_node.evaluate_call_args(calculator) argspec_len = len(args) + len(kwargs) # Translate variable names to Python identifiers # TODO what about duplicate kw names? should this happen in argspec? # how does that affect mixins? kwargs = dict((key.lstrip('$').replace('-', '_'), value) for key, value in kwargs.items()) # TODO merge this with the library funct = None try: funct = calculator.namespace.function(func_name, argspec_len) # @functions take a ns as first arg. TODO: Python functions possibly # should too if getattr(funct, '__name__', None) == '__call': funct = partial(funct, calculator.namespace) except KeyError: try: # DEVIATION: Fall back to single parameter funct = calculator.namespace.function(func_name, 1) args = [List(args, use_comma=True)] except KeyError: if not is_builtin_css_function(func_name): log.error("Function not found: %s:%s", func_name, argspec_len, extra={'stack': True}) if funct: ret = funct(*args, **kwargs) if not isinstance(ret, Value): raise TypeError("Expected Sass type as return value, got %r" % (ret, )) return ret # No matching function found, so render the computed values as a CSS # function call. Slurpy arguments are expanded and named arguments are # unsupported. if kwargs: raise TypeError( "The CSS function %s doesn't support keyword arguments." % (func_name, )) # TODO another candidate for a "function call" sass type rendered_args = [arg.render() for arg in args] return String(u"%s(%s)" % (func_name, u", ".join(rendered_args)), quotes=None)
def evaluate(self, calculator, divide=False): # TODO bake this into the context and options "dicts", plus library func_name = normalize_var(self.func_name) argspec_node = self.argspec # Turn the pairs of arg tuples into *args and **kwargs # TODO unclear whether this is correct -- how does arg, kwarg, arg # work? args, kwargs = argspec_node.evaluate_call_args(calculator) argspec_len = len(args) + len(kwargs) # Translate variable names to Python identifiers # TODO what about duplicate kw names? should this happen in argspec? # how does that affect mixins? kwargs = dict( (key.lstrip('$').replace('-', '_'), value) for key, value in kwargs.items()) # TODO merge this with the library funct = None try: funct = calculator.namespace.function(func_name, argspec_len) except KeyError: try: # DEVIATION: Fall back to single parameter funct = calculator.namespace.function(func_name, 1) args = [List(args, use_comma=True)] except KeyError: if not is_builtin_css_function(func_name): log.error("Function not found: %s:%s", func_name, argspec_len, extra={'stack': True}) if funct: if getattr(funct, '_pyscss_needs_namespace', False): # @functions and some Python functions take the namespace as an # extra first argument ret = funct(calculator.namespace, *args, **kwargs) else: ret = funct(*args, **kwargs) if not isinstance(ret, Value): raise TypeError("Expected Sass type as return value, got %r" % (ret,)) return ret # No matching function found, so render the computed values as a CSS # function call. Slurpy arguments are expanded and named arguments are # unsupported. if kwargs: raise TypeError("The CSS function %s doesn't support keyword arguments." % (func_name,)) # TODO another candidate for a "function call" sass type rendered_args = [arg.render() for arg in args] return String( "%s(%s)" % (func_name, ", ".join(rendered_args)), quotes=None)
def evaluate(self, calculator, divide=False): # TODO bake this into the context and options "dicts", plus library func_name = normalize_var(self.func_name) # Turn the pairs of arg tuples into *args and **kwargs # TODO unclear whether this is correct -- how does arg, kwarg, arg # work? args = [] kwargs = {} evald_argpairs = [] for var, expr in self.argspec.argpairs: value = expr.evaluate(calculator, divide=True) evald_argpairs.append((var, value)) if var is None: args.append(value) else: kwargs[var.lstrip('$').replace('-', '_')] = value num_args = len(self.argspec.argpairs) # TODO merge this with the library try: func = calculator.namespace.function(func_name, num_args) # @functions take a ns as first arg. TODO: Python functions possibly # should too if getattr(func, '__name__', None) == '__call': func = partial(func, calculator.namespace) except KeyError: if not is_builtin_css_function(func_name): log.error("Function not found: %s:%s", func_name, num_args, extra={'stack': True}) rendered_args = [] for var, value in evald_argpairs: rendered_value = value.render() if var is None: rendered_args.append(rendered_value) else: rendered_args.append("%s: %s" % (var, rendered_value)) return String(u"%s(%s)" % (func_name, u", ".join(rendered_args)), quotes=None) else: return func(*args, **kwargs)
def evaluate(self, calculator, divide=False): # TODO bake this into the context and options "dicts", plus library name = normalize_var(self.func_name) # Turn the pairs of arg tuples into *args and **kwargs # TODO unclear whether this is correct -- how does arg, kwarg, arg # work? args = [] kwargs = {} evald_argpairs = [] for var, expr in self.argspec.argpairs: value = expr.evaluate(calculator, divide=True) evald_argpairs.append((var, value)) if var is None: args.append(value) else: kwargs[ var.lstrip('$').replace('-', '_') ] = value num_args = len(self.argspec.argpairs) # TODO merge this with the library try: func = calculator.namespace.function(self.func_name, num_args) # @functions take a ns as first arg. TODO: Python functions possibly # should too if getattr(func, '__name__', None) == '__call': func = partial(func, calculator.namespace) except KeyError: if not is_builtin_css_function(self.func_name): # TODO log.warn, log.error, warning, exception? log.warn("no such function") rendered_args = [] for var, value in evald_argpairs: rendered_value = value.render() if var is None: rendered_args.append(rendered_value) else: rendered_args.append("%s: %s" % (var, rendered_value)) return String( u"%s(%s)" % (self.func_name, u", ".join(rendered_args)), quotes=None) else: return func(*args, **kwargs)