forked from mirrors/gecko-dev
		
	This was done with |mach vendor python| followed by a manual backout of changes to unrelated packages. Differential Revision: https://phabricator.services.mozilla.com/D5532 --HG-- extra : moz-landing-system : lando
		
			
				
	
	
		
			121 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from __future__ import absolute_import, print_function, unicode_literals
 | 
						|
 | 
						|
import math
 | 
						|
from .shared import string, to_str, fromNow, JSONTemplateError
 | 
						|
 | 
						|
 | 
						|
class BuiltinError(JSONTemplateError):
 | 
						|
    pass
 | 
						|
 | 
						|
 | 
						|
def build(context):
 | 
						|
    builtins = {}
 | 
						|
 | 
						|
    def builtin(name, variadic=None, argument_tests=None, minArgs=None):
 | 
						|
        def wrap(fn):
 | 
						|
            def bad(reason=None):
 | 
						|
                raise BuiltinError(
 | 
						|
                    (reason or 'invalid arguments to builtin: {}').format(name))
 | 
						|
            if variadic:
 | 
						|
                def invoke(*args):
 | 
						|
                    if minArgs:
 | 
						|
                        if len(args) < minArgs:
 | 
						|
                            bad("too few arguments to {}")
 | 
						|
                    for arg in args:
 | 
						|
                        if not variadic(arg):
 | 
						|
                            bad()
 | 
						|
                    return fn(*args)
 | 
						|
 | 
						|
            elif argument_tests:
 | 
						|
                def invoke(*args):
 | 
						|
                    if len(args) != len(argument_tests):
 | 
						|
                        bad()
 | 
						|
                    for t, arg in zip(argument_tests, args):
 | 
						|
                        if not t(arg):
 | 
						|
                            bad()
 | 
						|
                    return fn(*args)
 | 
						|
 | 
						|
            else:
 | 
						|
                def invoke(*args):
 | 
						|
                    return fn(*args)
 | 
						|
 | 
						|
            builtins[name] = invoke
 | 
						|
            return fn
 | 
						|
        return wrap
 | 
						|
 | 
						|
    def is_number(v):
 | 
						|
        return isinstance(v, (int, float)) and not isinstance(v, bool)
 | 
						|
 | 
						|
    def is_string(v):
 | 
						|
        return isinstance(v, string)
 | 
						|
 | 
						|
    def is_string_or_array(v):
 | 
						|
        return isinstance(v, (string, list))
 | 
						|
 | 
						|
    def anything_except_array(v):
 | 
						|
        return isinstance(v, (string, int, float, bool)) or v is None
 | 
						|
 | 
						|
    def anything(v):
 | 
						|
        return isinstance(v, (string, int, float, list, dict)) or v is None or callable(v)
 | 
						|
 | 
						|
    # ---
 | 
						|
 | 
						|
    builtin('min', variadic=is_number, minArgs=1)(min)
 | 
						|
    builtin('max', variadic=is_number, minArgs=1)(max)
 | 
						|
    builtin('sqrt', argument_tests=[is_number])(math.sqrt)
 | 
						|
    builtin('abs', argument_tests=[is_number])(abs)
 | 
						|
 | 
						|
    @builtin('ceil', argument_tests=[is_number])
 | 
						|
    def ceil(v):
 | 
						|
        return int(math.ceil(v))
 | 
						|
 | 
						|
    @builtin('floor', argument_tests=[is_number])
 | 
						|
    def floor(v):
 | 
						|
        return int(math.floor(v))
 | 
						|
 | 
						|
    @builtin('lowercase', argument_tests=[is_string])
 | 
						|
    def lowercase(v):
 | 
						|
        return v.lower()
 | 
						|
 | 
						|
    @builtin('uppercase', argument_tests=[is_string])
 | 
						|
    def lowercase(v):
 | 
						|
        return v.upper()
 | 
						|
 | 
						|
    builtin('len', argument_tests=[is_string_or_array])(len)
 | 
						|
    builtin('str', argument_tests=[anything_except_array])(to_str)
 | 
						|
    builtin('number', variadic=is_string, minArgs=1)(float)
 | 
						|
 | 
						|
    @builtin('strip', argument_tests=[is_string])
 | 
						|
    def strip(s):
 | 
						|
        return s.strip()
 | 
						|
 | 
						|
    @builtin('rstrip', argument_tests=[is_string])
 | 
						|
    def rstrip(s):
 | 
						|
        return s.rstrip()
 | 
						|
 | 
						|
    @builtin('lstrip', argument_tests=[is_string])
 | 
						|
    def lstrip(s):
 | 
						|
        return s.lstrip()
 | 
						|
 | 
						|
    @builtin('fromNow', variadic=is_string, minArgs=1)
 | 
						|
    def fromNow_builtin(offset, reference=None):
 | 
						|
        return fromNow(offset, reference or context.get('now'))
 | 
						|
 | 
						|
    @builtin('typeof', argument_tests=[anything])
 | 
						|
    def typeof(v):
 | 
						|
        if isinstance(v, bool):
 | 
						|
            return 'boolean'
 | 
						|
        elif isinstance(v, string):
 | 
						|
            return 'string'
 | 
						|
        elif isinstance(v, (int, float)):
 | 
						|
            return 'number'
 | 
						|
        elif isinstance(v, list):
 | 
						|
            return 'array'
 | 
						|
        elif isinstance(v, dict):
 | 
						|
            return 'object'
 | 
						|
        elif v is None:
 | 
						|
            return None
 | 
						|
        elif callable(v):
 | 
						|
            return 'function'
 | 
						|
 | 
						|
    return builtins
 |