'Create a CustomJSTransform instance from a pair of Python
functions. The function is translated to JavaScript using PyScript.
The python functions must have no positional arguments. It\'s
possible to pass Bokeh models (e.g. a ColumnDataSource) as keyword
arguments to the functions.
The ``func`` function namespace will contain the variable ``x`` (the
untransformed value) at render time. The ``v_func`` function namespace
will contain the variable ``xs`` (the untransformed vector) at render
time.
.. warning::
The vectorized function, ``v_func``, must return an array of the
same length as the input ``xs`` array.
Example:
.. code-block:: python
def transform():
from flexx.pyscript.stubs import Math
return Math.cos(x)
def v_transform():
from flexx.pyscript.stubs import Math
return [Math.cos(x) for x in xs]
customjs_transform = CustomJSTransform.from_py_func(transform, v_transform)
Args:
func (function) : a scalar function to transform a single ``x`` value
v_func (function) : a vectorized function to transform a vector ``xs``
Returns:
CustomJSTransform'

@classmethod
def from_py_func(cls, func, v_func):

    if ((not isinstance(func, FunctionType)) or (not isinstance(v_func, FunctionType))):
        raise ValueError('CustomJSTransform.from_py_func    only    accepts    function    objects.')
    pyscript = import_required('flexx.pyscript', dedent('                                                                To    use    Python    functions    for    CustomJSTransform,    you    need    Flexx\n                                                                \'("conda    install    -c    bokeh    flexx"    or    "pip    install    flexx")'))
    def pyscript_compile(func):
        sig = signature(func)
        (all_names, default_values) = get_param_info(sig)
        if ((len(all_names) - len(default_values)) != 0):
            raise ValueError('Function    may    only    contain    keyword    arguments.')
        if (default_values and (not any([isinstance(value, Model) for value in default_values]))):
            raise ValueError('Default    value    must    be    a    Bokeh    Model.')
        func_kwargs = dict(zip(all_names, default_values))
        code = (pyscript.py2js(func, 'transformer') + ('return    transformer(%s);\n' % ',    '.join(all_names)))
        return (code, func_kwargs)
    (jsfunc, func_kwargs) = pyscript_compile(func)
    (v_jsfunc, v_func_kwargs) = pyscript_compile(v_func)
    func_kwargs.update(v_func_kwargs)
    return cls(func=jsfunc, v_func=v_jsfunc, args=func_kwargs)
