Index: PyObject.java =================================================================== RCS file: /cvsroot/jython/jython/org/python/core/PyObject.java,v retrieving revision 2.30 diff -u -r2.30 PyObject.java --- PyObject.java 6 Aug 2003 11:46:26 -0000 2.30 +++ PyObject.java 22 Feb 2004 02:43:54 -0000 @@ -1,6 +1,8 @@ // Copyright (c) Corporation for National Research Initiatives package org.python.core; +import java.util.ArrayList; + /** * All objects known to the Jython runtime system are represented * by an instance of the class PyObject or one of @@ -315,78 +317,104 @@ Py.NoKeywords); } - /** @deprecated **/ - public PyObject _callextra(PyObject[] args, String[] keywords, - PyObject starargs, PyObject kwargs) { - - int argslen = args.length; - int nstar = 0; - - String name = ""; - if (this instanceof PyFunction) - name = ((PyFunction) this).__name__ + "() "; - - if (kwargs != null) { - PyObject keys = kwargs.__findattr__("keys"); - if (keys == null) - throw Py.TypeError(name + "argument after ** must be " + - "a dictionary"); - for (int i = 0; i < keywords.length; i++) - if (kwargs.__finditem__(keywords[i]) != null) - throw Py.TypeError(name + "got multiple values for " + - "keyword argument '" + keywords[i] + - "'"); - argslen += kwargs.__len__(); - } - if (starargs != null) { - if (!(starargs instanceof PySequence || - starargs instanceof PyInstance)) - throw Py.TypeError(name + "argument after * must " + - "be a sequence"); - nstar = starargs.__len__(); - argslen += nstar; - } - - PyObject[] newargs = new PyObject[argslen]; - int argidx = args.length - keywords.length; - System.arraycopy(args, 0, newargs, 0, argidx); - - if (starargs != null) { - PyObject a; - for (int i = 0; (a = starargs.__finditem__(i)) != null && - i < nstar; i++) { - newargs[argidx++] = a; - } - } - System.arraycopy(args, args.length - keywords.length, - newargs, argidx, keywords.length); - argidx += keywords.length; - - if (kwargs != null) { - String[] newkeywords = - new String[keywords.length + kwargs.__len__()]; - System.arraycopy(keywords, 0, newkeywords, 0, keywords.length); - - PyObject keys = kwargs.invoke("keys"); - PyObject key; - for (int i = 0; (key = keys.__finditem__(i)) != null; i++) { - if (!(key instanceof PyString)) - throw Py.TypeError(name + - "keywords must be strings"); - newkeywords[keywords.length + i] = - ((PyString) key).internedString(); - newargs[argidx++] = kwargs.__finditem__(key); - } - keywords = newkeywords; - } - - if (newargs.length != argidx) { - args = new PyObject[argidx]; - System.arraycopy(newargs, 0, args, 0, argidx); - } else - args = newargs; - return __call__(args, keywords); - } + /** @deprecated **/ + /** this method normalizes all arguments into positional args and calls __call__ */ + public PyObject _callextra( + PyObject[] args, + String[] keywords, + PyObject starargs, + PyObject kwargs) + { + int argslen = args.length; + int nstar = 0; + + String name = ""; + if (this instanceof PyFunction) + name = ((PyFunction) this).__name__ + "() "; + + if (kwargs != null) { + PyObject keys = kwargs.__findattr__("keys"); + if (keys == null) + throw Py.TypeError( + name + "argument after ** must be " + "a dictionary"); + for (int i = 0; i < keywords.length; i++) + if (kwargs.__finditem__(keywords[i]) != null) + throw Py.TypeError( + name + + "got multiple values for " + + "keyword argument '" + + keywords[i] + + "'"); + argslen += kwargs.__len__(); + } + + ArrayList expandedStarargs = null; + if (starargs != null) { + PyObject i; // iterator + try { + i = starargs.__iter__(); + } catch (PyException e) { + if (e.type == Py.TypeError) { + throw Py.TypeError("argument after * must " + "be a sequence"); + } else { + throw e; + } + } + + expandedStarargs = new ArrayList(); + PyObject o; + while ((o = i.__iternext__()) != null) { + expandedStarargs.add(o); + } + argslen += expandedStarargs.size(); + } + + PyObject[] newargs = new PyObject[argslen]; + int argidx = args.length - keywords.length; + // copy normal args + System.arraycopy(args, 0, newargs, 0, argidx); + + // copy starargs + if (expandedStarargs != null) { + for (int i = 0; i < expandedStarargs.size(); i++) { + newargs[argidx++] = (PyObject)expandedStarargs.get(i); + } + } + + // copy keyword args + System.arraycopy( + args, + args.length - keywords.length, + newargs, + argidx, + keywords.length); + argidx += keywords.length; + + if (kwargs != null) { + String[] newkeywords = + new String[keywords.length + kwargs.__len__()]; + System.arraycopy(keywords, 0, newkeywords, 0, keywords.length); + + PyObject keys = kwargs.invoke("keys"); + PyObject key; + for (int i = 0;(key = keys.__finditem__(i)) != null; i++) { + if (!(key instanceof PyString)) + throw Py.TypeError(name + "keywords must be strings"); + newkeywords[keywords.length + i] = + ((PyString) key).internedString(); + newargs[argidx++] = kwargs.__finditem__(key); + } + keywords = newkeywords; + } + + if (newargs.length != argidx) { + args = new PyObject[argidx]; + System.arraycopy(newargs, 0, args, 0, argidx); + } else { + args = newargs; + } + return __call__(args, keywords); + }