Create a ``CustomJSHover`` instance from a Python functions. The
        function is translated to JavaScript using PScript.

        The python functions must have no positional arguments. It is
        possible to pass Bokeh models (e.g. a ``ColumnDataSource``) as keyword
        arguments to the functions.

        The ``code`` function namespace will contain the variable ``value``
        (the untransformed value) at render time as well as ``format`` and
        ``special_vars`` as described in the class description.

        Args:
            code (function) : a scalar function to transform a single ``value``

        Returns:
            CustomJSHover

def from_py_func(cls, code):
        ''' Create a ``CustomJSHover`` instance from a Python functions. The
        function is translated to JavaScript using PScript.

        The python functions must have no positional arguments. It is
        possible to pass Bokeh models (e.g. a ``ColumnDataSource``) as keyword
        arguments to the functions.

        The ``code`` function namespace will contain the variable ``value``
        (the untransformed value) at render time as well as ``format`` and
        ``special_vars`` as described in the class description.

        Args:
            code (function) : a scalar function to transform a single ``value``

        Returns:
            CustomJSHover

        '''
        from bokeh.util.deprecation import deprecated
        deprecated("'from_py_func' is deprecated and will be removed in an eventual 2.0 release. "
                   "Use CustomJSHover directly instead.")

        if not isinstance(code, FunctionType):
            raise ValueError('CustomJSHover.from_py_func only accepts function objects.')

        pscript = import_required('pscript',
                                  'To use Python functions for CustomJSHover, you need PScript ' +
                                  '("conda install -c conda-forge pscript" or "pip install pscript")')

        def pscript_compile(code):
            sig = signature(code)

            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))

            # Wrap the code attr in a function named `code` and call it
            # with arguments that match the `args` attr
            code = pscript.py2js(code, 'transformer') + 'return transformer(%s);\n' % ', '.join(all_names)
            return code, func_kwargs

        jsfunc, func_kwargs = pscript_compile(code)

        return cls(code=jsfunc, args=func_kwargs)