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

        The ``func`` function namespace will contain the variable ``source``
        at render time. This will be the data source associated with the ``CDSView``
        that this filter is added to.

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

        The ``func`` function namespace will contain the variable ``source``
        at render time. This will be the data source associated with the ``CDSView``
        that this filter is added to.
        '''
        from bokeh.util.deprecation import deprecated
        deprecated("'from_py_func' is deprecated and will be removed in an eventual 2.0 release. "
                   "Use CustomJSFilter directly instead.")

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

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

        argspec = inspect.getargspec(func)

        default_names = argspec.args
        default_values = argspec.defaults or []

        if len(default_names) - len(default_values) != 0:
            raise ValueError("Function may only contain keyword arguments.")

        # should the following be all of the values need to be Models?
        if default_values and not any(isinstance(value, Model) for value in default_values):
            raise ValueError("Default value must be a plot object.")

        func_kwargs = dict(zip(default_names, default_values))
        code = pscript.py2js(func, 'filter') + 'return filter(%s);\n' % ', '.join(default_names)

        return cls(code=code, args=func_kwargs)