public ImmutableMap<String, Function> call() throws Exception { // This creates a dependency between function and the client. // However, we need to know the load paths before we can do anything, so this is necessary. PythonUtils.initializePython(); Py.getSystemState().path.append(new PyString(file.getParentFile().getCanonicalPath())); PythonInterpreter interpreter = new PythonInterpreter(); try { interpreter.execfile(file.getCanonicalPath()); } catch (IOException e) { throw new LoadException(file, e); } catch (PyException e) { throw new LoadException(file, e); } PyStringMap map = (PyStringMap) interpreter.getLocals(); ImmutableMap.Builder<String, Function> builder = ImmutableMap.builder(); for (Object key : map.keys()) { Object o = map.get(Py.java2py(key)); if (o instanceof PyFunction) { String name = (String) key; Function f = new PythonFunction(name, (PyFunction) o); builder.put(name, f); } } return builder.build(); } });
/** * Determines if there is a function with the given name and the correct number of arguments * in the loaded script. */ public boolean hasFunction(String name, int argsCount) { PyStringMap locals = (PyStringMap)pinterp.getLocals(); if (locals.has_key(name)) { // great, there is some variable with this name PyObject obj = locals.get(new PyString(name)); if (obj.getClass() == PyFunction.class) { // great, it's a function PyFunction fnc = (PyFunction)obj; int aCount = ((PyTableCode)fnc.func_code).co_argcount; if (aCount == argsCount) { // great, it accepts correct number of arguments return true; } boolean varargs = ((PyTableCode)fnc.func_code).varargs; if (aCount < argsCount && varargs) { // great, it is variable arguments function return true; } } } return false; }
/** * Basic helper implementation of {@link #doDir}. It merges information * from jpkg {@link PyJavaPackage#clsSet} and {@link PyJavaPackage#__dict__}. */ protected PyList basicDoDir(PyJavaPackage jpkg, boolean instantiate, boolean exclpkgs) { PyStringMap dict = jpkg.__dict__; PyStringMap cls = jpkg.clsSet; if (!instantiate) { PyList ret = cls.keys(); PyList dictKeys = dict.keys(); for (PyObject name : dictKeys.asIterable()) { if (!cls.has_key(name)) { if (exclpkgs && dict.get(name) instanceof PyJavaPackage) continue; ret.append(name); } } return ret; } for (PyObject pyname : cls.keys().asIterable()) { if (!dict.has_key(pyname)) { String name = pyname.toString(); jpkg.addClass(name, Py.findClass(jpkg.__name__ + "." + name)); } } return dict.keys(); }