0001: // Copyright (c) Corporation for National Research Initiatives
0002: package org.python.core;
0003:
0004: import java.io.ByteArrayOutputStream;
0005: import java.io.File;
0006: import java.io.FileOutputStream;
0007: import java.io.InputStream;
0008: import java.io.ObjectStreamException;
0009: import java.io.OutputStream;
0010: import java.io.PrintStream;
0011: import java.io.Serializable;
0012: import java.io.StreamCorruptedException;
0013: import java.io.Writer;
0014: import java.lang.reflect.InvocationTargetException;
0015:
0016: import org.python.compiler.Module;
0017: import org.python.core.adapter.ClassicPyObjectAdapter;
0018: import org.python.core.adapter.ExtensiblePyObjectAdapter;
0019: import org.python.parser.ast.modType;
0020:
0021: public final class Py {
0022: static boolean frozen;
0023: static String frozenPackage = null;
0024: private final static Object PRESENT = new Object();
0025: static java.util.Hashtable frozenModules;
0026:
0027: static boolean initialized;
0028:
0029: static class SingletonResolver implements Serializable {
0030: private String which;
0031:
0032: SingletonResolver(String which) {
0033: this .which = which;
0034: }
0035:
0036: private Object readResolve() throws ObjectStreamException {
0037: if (which.equals("None")) {
0038: return Py.None;
0039: } else if (which.equals("Ellipsis")) {
0040: return Py.Ellipsis;
0041: } else if (which.equals("NotImplemented")) {
0042: return Py.NotImplemented;
0043: }
0044: throw new StreamCorruptedException("unknown singleton: "
0045: + which);
0046: }
0047: }
0048:
0049: /* Holds the singleton None and Ellipsis objects */
0050: /** The singleton None Python object **/
0051: public static PyObject None;
0052:
0053: /** The singleton Ellipsis Python object - written as ... when indexing */
0054: public static PyObject Ellipsis;
0055:
0056: /** The singleton NotImplemented Python object. Used in rich comparison */
0057: public static PyObject NotImplemented;
0058:
0059: /** A zero-length array of Strings to pass to functions that
0060: don't have any keyword arguments **/
0061: public static String[] NoKeywords;
0062:
0063: /** A zero-length array of PyObject's to pass to functions that
0064: expect zero-arguments **/
0065: public static PyObject[] EmptyObjects;
0066:
0067: /** A tuple with zero elements **/
0068: public static PyTuple EmptyTuple;
0069:
0070: /** The Python integer 0 - also used as false **/
0071: public static PyInteger Zero;
0072:
0073: /** The Python integer 1 - also used as true **/
0074: public static PyInteger One;
0075:
0076: /** A zero-length Python string **/
0077: public static PyString EmptyString;
0078:
0079: /** A Python string containing '\n' **/
0080: public static PyString Newline;
0081:
0082: /** A Python string containing ' ' **/
0083: public static PyString Space;
0084:
0085: /** A unique object to indicate no conversion is possible
0086: in __tojava__ methods **/
0087: public static Object NoConversion;
0088:
0089: public static PyObject OSError;
0090: public static PyObject NotImplementedError;
0091: public static PyObject EnvironmentError;
0092:
0093: /* The standard Python exceptions */
0094: public static PyObject OverflowError;
0095:
0096: public static PyException OverflowError(String message) {
0097: return new PyException(Py.OverflowError, message);
0098: }
0099:
0100: public static PyObject RuntimeError;
0101:
0102: public static PyException RuntimeError(String message) {
0103: return new PyException(Py.RuntimeError, message);
0104: }
0105:
0106: public static PyObject KeyboardInterrupt;
0107: /*public static PyException KeyboardInterrupt(String message) {
0108: return new PyException(Py.KeyboardInterrupt, message);
0109: }*/
0110:
0111: public static PyObject FloatingPointError;
0112:
0113: public static PyException FloatingPointError(String message) {
0114: return new PyException(Py.FloatingPointError, message);
0115: }
0116:
0117: public static PyObject SyntaxError;
0118:
0119: public static PyException SyntaxError(String message) {
0120: return new PyException(Py.SyntaxError, message);
0121: }
0122:
0123: public static PyObject IndentationError;
0124: public static PyObject TabError;
0125:
0126: public static PyObject AttributeError;
0127:
0128: public static PyException AttributeError(String message) {
0129: return new PyException(Py.AttributeError, message);
0130: }
0131:
0132: public static PyObject IOError;
0133:
0134: public static PyException IOError(java.io.IOException ioe) {
0135: //System.err.println("ioe: "+ioe);
0136: //ioe.printStackTrace();
0137: String message = ioe.getMessage();
0138: if (ioe instanceof java.io.FileNotFoundException) {
0139: message = "File not found - " + message;
0140: }
0141: return new PyException(Py.IOError, message);
0142: }
0143:
0144: public static PyException IOError(String message) {
0145: //System.err.println("sioe: "+message);
0146: return new PyException(Py.IOError, message);
0147: }
0148:
0149: public static PyObject KeyError;
0150:
0151: public static PyException KeyError(String message) {
0152: return new PyException(Py.KeyError, message);
0153: }
0154:
0155: public static PyObject AssertionError;
0156:
0157: public static PyException AssertionError(String message) {
0158: return new PyException(Py.AssertionError, message);
0159: }
0160:
0161: public static PyObject TypeError;
0162:
0163: public static PyException TypeError(String message) {
0164: return new PyException(Py.TypeError, message);
0165: }
0166:
0167: public static PyObject ReferenceError;
0168:
0169: public static PyException ReferenceError(String message) {
0170: return new PyException(Py.ReferenceError, message);
0171: }
0172:
0173: public static PyObject SystemError;
0174:
0175: public static PyException SystemError(String message) {
0176: return new PyException(Py.SystemError, message);
0177: }
0178:
0179: public static PyObject IndexError;
0180:
0181: public static PyException IndexError(String message) {
0182: return new PyException(Py.IndexError, message);
0183: }
0184:
0185: public static PyObject ZeroDivisionError;
0186:
0187: public static PyException ZeroDivisionError(String message) {
0188: return new PyException(Py.ZeroDivisionError, message);
0189: }
0190:
0191: public static PyObject NameError;
0192:
0193: public static PyException NameError(String message) {
0194: return new PyException(Py.NameError, message);
0195: }
0196:
0197: public static PyObject UnboundLocalError;
0198:
0199: public static PyException UnboundLocalError(String message) {
0200: return new PyException(Py.UnboundLocalError, message);
0201: }
0202:
0203: public static PyObject SystemExit;
0204:
0205: /*public static PyException SystemExit(String message) {
0206: return new PyException(Py.SystemExit, message);
0207: }*/
0208: static void maybeSystemExit(PyException exc) {
0209: //System.err.println("maybeSystemExit: " + exc.type.toString());
0210: if (Py.matchException(exc, Py.SystemExit)) {
0211: PyObject value = exc.value;
0212: //System.err.println("exiting: "+value.getClass().getName());
0213: if (value instanceof PyInstance) {
0214: PyObject tmp = value.__findattr__("code");
0215: if (tmp != null)
0216: value = tmp;
0217: }
0218: Py.getSystemState().callExitFunc();
0219: if (value instanceof PyInteger) {
0220: System.exit(((PyInteger) value).getValue());
0221: } else {
0222: if (value != Py.None) {
0223: try {
0224: Py.println(value);
0225: System.exit(1);
0226: } catch (Throwable t0) {
0227: }
0228: }
0229: System.exit(0);
0230: }
0231: }
0232: }
0233:
0234: public static PyObject StopIteration;
0235:
0236: public static PyException StopIteration(String message) {
0237: return new PyException(Py.StopIteration, message);
0238: }
0239:
0240: public static PyObject ImportError;
0241:
0242: public static PyException ImportError(String message) {
0243: return new PyException(Py.ImportError, message);
0244: }
0245:
0246: public static PyObject ValueError;
0247:
0248: public static PyException ValueError(String message) {
0249: return new PyException(Py.ValueError, message);
0250: }
0251:
0252: public static PyObject UnicodeError;
0253:
0254: public static PyException UnicodeError(String message) {
0255: return new PyException(Py.UnicodeError, message);
0256: }
0257:
0258: public static PyObject EOFError;
0259:
0260: public static PyException EOFError(String message) {
0261: return new PyException(Py.EOFError, message);
0262: }
0263:
0264: public static PyObject MemoryError;
0265:
0266: public static void memory_error(OutOfMemoryError t) {
0267: if (Options.showJavaExceptions) {
0268: t.printStackTrace();
0269: }
0270: // this logic would allow to re-enable the old behavior when it makes sense,
0271: // or better offer a hook?
0272: // try {
0273: // byte[] alloc = new byte[(512*1024)];
0274: // } catch(OutOfMemoryError oome) {
0275: // System.err.println("Out Of Memory");
0276: // System.err.println("You might want to try the -mx flag to increase heap size.");
0277: // System.exit(-1);
0278: // }
0279: }
0280:
0281: public static PyException MemoryError(String message) {
0282: return new PyException(Py.MemoryError, message);
0283: }
0284:
0285: public static PyObject ArithmeticError;
0286: public static PyObject LookupError;
0287: public static PyObject StandardError;
0288: public static PyObject Exception;
0289:
0290: public static PyObject Warning;
0291:
0292: public static void Warning(String message) {
0293: warning(Warning, message);
0294: }
0295:
0296: public static PyObject UserWarning;
0297:
0298: public static void UserWarning(String message) {
0299: warning(UserWarning, message);
0300: }
0301:
0302: public static PyObject DeprecationWarning;
0303:
0304: public static void DeprecationWarning(String message) {
0305: warning(DeprecationWarning, message);
0306: }
0307:
0308: public static PyObject SyntaxWarning;
0309:
0310: public static void SyntaxWarning(String message) {
0311: warning(SyntaxWarning, message);
0312: }
0313:
0314: public static PyObject OverflowWarning;
0315:
0316: public static void OverflowWarning(String message) {
0317: warning(OverflowWarning, message);
0318: }
0319:
0320: public static PyObject RuntimeWarning;
0321:
0322: public static void RuntimeWarning(String message) {
0323: warning(RuntimeWarning, message);
0324: }
0325:
0326: private static PyObject warnings_mod;
0327:
0328: private static PyObject importWarnings() {
0329: if (warnings_mod != null)
0330: return warnings_mod;
0331: PyObject mod;
0332: try {
0333: mod = __builtin__.__import__("warnings");
0334: } catch (PyException e) {
0335: if (matchException(e, ImportError)) {
0336: return null;
0337: }
0338: throw e;
0339: }
0340: warnings_mod = mod;
0341: return mod;
0342: }
0343:
0344: private static String warn_hcategory(PyObject category) {
0345: PyObject name = category.__findattr__("__name__");
0346: if (name != null)
0347: return "[" + name + "]";
0348: return "[warning]";
0349: }
0350:
0351: public static void warning(PyObject category, String message) {
0352: PyObject func = null;
0353: PyObject mod = importWarnings();
0354: if (mod != null)
0355: func = mod.__getattr__("warn");
0356: if (func == null) {
0357: System.err.println(warn_hcategory(category) + ": "
0358: + message);
0359: return;
0360: } else {
0361: func.__call__(Py.newString(message), category);
0362: }
0363: }
0364:
0365: public static void warning(PyObject category, String message,
0366: String filename, int lineno, String module,
0367: PyObject registry) {
0368: PyObject func = null;
0369: PyObject mod = importWarnings();
0370: if (mod != null)
0371: func = mod.__getattr__("warn_explicit");
0372: if (func == null) {
0373: System.err.println(filename + ":" + lineno + ":"
0374: + warn_hcategory(category) + ": " + message);
0375: return;
0376: } else {
0377: func.__call__(new PyObject[] { Py.newString(message),
0378: category, Py.newString(filename),
0379: Py.newInteger(lineno),
0380: (module == null) ? Py.None : Py.newString(module),
0381: registry }, Py.NoKeywords);
0382: }
0383: }
0384:
0385: public static PyObject JavaError;
0386:
0387: public static PyException JavaError(Throwable t) {
0388: if (t instanceof PyException) {
0389: return (PyException) t;
0390: } else if (t instanceof InvocationTargetException) {
0391: return JavaError(((InvocationTargetException) t)
0392: .getTargetException());
0393: } else if (t instanceof OutOfMemoryError) {
0394: memory_error((OutOfMemoryError) t);
0395: }
0396: PyJavaInstance exc = new PyJavaInstance(t);
0397: return new PyException(exc.instclass, exc);
0398: }
0399:
0400: // Don't allow any constructors. Class only provides static methods.
0401: private Py() {
0402: ;
0403: }
0404:
0405: /** @deprecated **/
0406: //public static InterpreterState interp;
0407: /**
0408: Convert a given <code>PyObject</code> to an instance of a Java class.
0409: Identical to <code>o.__tojava__(c)</code> except that it will
0410: raise a <code>TypeError</code> if the conversion fails.
0411:
0412: @param o the <code>PyObject</code> to convert.
0413: @param c the class to convert it to.
0414: **/
0415: public static Object tojava(PyObject o, Class c) {
0416: Object obj = o.__tojava__(c);
0417: if (obj == Py.NoConversion) {
0418: throw Py.TypeError("can't convert " + o.__repr__() + " to "
0419: + c.getName());
0420: }
0421: return obj;
0422: }
0423:
0424: // ??pending: was @deprecated but is actually used by proxie code.
0425: // Can get rid of it?
0426: public static Object tojava(PyObject o, String s) {
0427: Class c = findClass(s);
0428: if (c == null)
0429: throw Py.TypeError("can't convert to: " + s);
0430: return tojava(o, c); // prev:Class.forName
0431: }
0432:
0433: /* Helper functions for PyProxy's */
0434:
0435: /** @deprecated * */
0436: public static PyObject jfindattr(PyProxy proxy, String name) {
0437: PyInstance o = proxy._getPyInstance();
0438: if (o == null) {
0439: proxy.__initProxy__(new Object[0]);
0440: o = proxy._getPyInstance();
0441: }
0442: PyObject ret = o.__jfindattr__(name);
0443: if (ret == null)
0444: return null;
0445:
0446: // Set the current system state to match proxy -- usually
0447: // this is a waste of time :-(
0448: Py.setSystemState(proxy._getPySystemState());
0449: return ret;
0450: }
0451:
0452: /** @deprecated * */
0453: public static PyObject jgetattr(PyProxy proxy, String name) {
0454: PyInstance o = proxy._getPyInstance();
0455: if (o == null) {
0456: proxy.__initProxy__(new Object[0]);
0457: o = proxy._getPyInstance();
0458: }
0459: PyObject ret = o.__jfindattr__(name);
0460: if (ret == null)
0461: throw Py.AttributeError("abstract method \"" + name
0462: + "\" not implemented");
0463: // Set the current system state to match proxy -- usually this is a
0464: // waste of time :-(
0465: Py.setSystemState(proxy._getPySystemState());
0466: return ret;
0467: }
0468:
0469: /* Convenience methods to create new constants without using "new" */
0470: private static PyInteger[] integerCache = null;
0471:
0472: public static final PyInteger newInteger(int i) {
0473: if (integerCache == null) {
0474: integerCache = new PyInteger[1000];
0475: for (int j = -100; j < 900; j++) {
0476: integerCache[j + 100] = new PyInteger(j);
0477: }
0478: }
0479: if (i >= -100 && i < 900) {
0480: return integerCache[i + 100];
0481: } else {
0482: return new PyInteger(i);
0483: }
0484: }
0485:
0486: public static PyObject newInteger(long i) {
0487: if (i < Integer.MIN_VALUE || i > Integer.MAX_VALUE)
0488: return new PyLong(i);
0489: else
0490: return newInteger((int) i);
0491: }
0492:
0493: public static PyLong newLong(String s) {
0494: return new PyLong(s);
0495: }
0496:
0497: public static PyLong newLong(java.math.BigInteger i) {
0498: return new PyLong(i);
0499: }
0500:
0501: public static PyLong newLong(int i) {
0502: return new PyLong(i);
0503: }
0504:
0505: public static PyComplex newImaginary(double v) {
0506: return new PyComplex(0, v);
0507: }
0508:
0509: public static PyFloat newFloat(float v) {
0510: return new PyFloat((double) v);
0511: }
0512:
0513: public static PyFloat newFloat(double v) {
0514: return new PyFloat(v);
0515: }
0516:
0517: public static PyString newString(char c) {
0518: return makeCharacter(c);
0519: }
0520:
0521: public static PyString newString(String s) {
0522: return new PyString(s);
0523: }
0524:
0525: public static PyUnicode newUnicode(char c) {
0526: return (PyUnicode) makeCharacter(c, true);
0527: }
0528:
0529: public static PyUnicode newUnicode(String s) {
0530: return new PyUnicode(s);
0531: }
0532:
0533: public static PyInteger newBoolean(boolean t) {
0534: return t ? Py.One : Py.Zero;
0535: }
0536:
0537: // nested scopes:
0538: // String[] cellvars,String[] freevars,int npurecell & int moreflags
0539:
0540: public static PyCode newCode(int argcount, String varnames[],
0541: String filename, String name, boolean args,
0542: boolean keywords, PyFunctionTable funcs, int func_id,
0543: String[] cellvars, String[] freevars, int npurecell,
0544: int moreflags) {
0545: return new PyTableCode(argcount, varnames, filename, name, 0,
0546: args, keywords, funcs, func_id, cellvars, freevars,
0547: npurecell, moreflags);
0548: }
0549:
0550: public static PyCode newCode(int argcount, String varnames[],
0551: String filename, String name, int firstlineno,
0552: boolean args, boolean keywords, PyFunctionTable funcs,
0553: int func_id, String[] cellvars, String[] freevars,
0554: int npurecell, int moreflags)
0555:
0556: {
0557: return new PyTableCode(argcount, varnames, filename, name,
0558: firstlineno, args, keywords, funcs, func_id, cellvars,
0559: freevars, npurecell, moreflags);
0560: }
0561:
0562: // --
0563:
0564: public static PyCode newCode(int argcount, String varnames[],
0565: String filename, String name, boolean args,
0566: boolean keywords, PyFunctionTable funcs, int func_id) {
0567: return new PyTableCode(argcount, varnames, filename, name, 0,
0568: args, keywords, funcs, func_id);
0569: }
0570:
0571: public static PyCode newCode(int argcount, String varnames[],
0572: String filename, String name, int firstlineno,
0573: boolean args, boolean keywords, PyFunctionTable funcs,
0574: int func_id) {
0575: return new PyTableCode(argcount, varnames, filename, name,
0576: firstlineno, args, keywords, funcs, func_id);
0577: }
0578:
0579: public static PyCode newJavaCode(Class cls, String name) {
0580: return new JavaCode(newJavaFunc(cls, name));
0581: }
0582:
0583: public static PyObject newJavaFunc(Class cls, String name) {
0584: try {
0585: java.lang.reflect.Method m = cls.getMethod(name,
0586: new Class[] { PyObject[].class, String[].class });
0587: return new JavaFunc(m);
0588: } catch (NoSuchMethodException e) {
0589: throw Py.JavaError(e);
0590: }
0591: }
0592:
0593: private static PyObject initExc(String name, PyObject exceptions,
0594: PyObject dict) {
0595: PyObject tmp = exceptions.__getattr__(name);
0596: dict.__setitem__(name, tmp);
0597: return tmp;
0598: }
0599:
0600: static void initClassExceptions(PyObject dict) {
0601: PyObject exc = imp.load("exceptions");
0602:
0603: Exception = initExc("Exception", exc, dict);
0604: SystemExit = initExc("SystemExit", exc, dict);
0605: StopIteration = initExc("StopIteration", exc, dict);
0606: StandardError = initExc("StandardError", exc, dict);
0607: KeyboardInterrupt = initExc("KeyboardInterrupt", exc, dict);
0608: ImportError = initExc("ImportError", exc, dict);
0609: EnvironmentError = initExc("EnvironmentError", exc, dict);
0610: IOError = initExc("IOError", exc, dict);
0611: OSError = initExc("OSError", exc, dict);
0612: EOFError = initExc("EOFError", exc, dict);
0613: RuntimeError = initExc("RuntimeError", exc, dict);
0614: NotImplementedError = initExc("NotImplementedError", exc, dict);
0615: NameError = initExc("NameError", exc, dict);
0616: UnboundLocalError = initExc("UnboundLocalError", exc, dict);
0617: AttributeError = initExc("AttributeError", exc, dict);
0618: SyntaxError = initExc("SyntaxError", exc, dict);
0619: IndentationError = initExc("IndentationError", exc, dict);
0620: TabError = initExc("TabError", exc, dict);
0621: TypeError = initExc("TypeError", exc, dict);
0622: AssertionError = initExc("AssertionError", exc, dict);
0623: LookupError = initExc("LookupError", exc, dict);
0624: IndexError = initExc("IndexError", exc, dict);
0625: KeyError = initExc("KeyError", exc, dict);
0626: ArithmeticError = initExc("ArithmeticError", exc, dict);
0627: OverflowError = initExc("OverflowError", exc, dict);
0628: ZeroDivisionError = initExc("ZeroDivisionError", exc, dict);
0629: FloatingPointError = initExc("FloatingPointError", exc, dict);
0630: ValueError = initExc("ValueError", exc, dict);
0631: UnicodeError = initExc("UnicodeError", exc, dict);
0632: ReferenceError = initExc("ReferenceError", exc, dict);
0633: SystemError = initExc("SystemError", exc, dict);
0634: MemoryError = initExc("MemoryError", exc, dict);
0635: Warning = initExc("Warning", exc, dict);
0636: UserWarning = initExc("UserWarning", exc, dict);
0637: DeprecationWarning = initExc("DeprecationWarning", exc, dict);
0638: SyntaxWarning = initExc("SyntaxWarning", exc, dict);
0639: OverflowWarning = initExc("OverflowWarning", exc, dict);
0640: RuntimeWarning = initExc("RuntimeWarning", exc, dict);
0641:
0642: // Pre-initialize the PyJavaClass for OutOfMemoryError so when we need
0643: // it it creating the pieces for it won't cause an additional out of
0644: // memory error. Fix for bug #1654484
0645: PyJavaClass.lookup(java.lang.OutOfMemoryError.class);
0646: }
0647:
0648: public static PySystemState defaultSystemState;
0649:
0650: // This is a hack to get initializations to work in proper order
0651: public static synchronized boolean initPython() {
0652: PySystemState.initialize();
0653: return true;
0654: }
0655:
0656: public static Class relFindClass(Class home, String name) {
0657: try {
0658: ClassLoader loader = home.getClassLoader();
0659: if (loader != null)
0660: return loader.loadClass(name);
0661: else
0662: return Class.forName(name);
0663: } catch (ClassNotFoundException exc) {
0664: return null;
0665: } catch (Throwable t) {
0666: throw Py.JavaError(t);
0667: }
0668: }
0669:
0670: private static boolean secEnv = false;
0671:
0672: public static Class findClass(String name) {
0673: try {
0674: ClassLoader classLoader = Py.getSystemState()
0675: .getClassLoader();
0676: if (classLoader != null)
0677: return classLoader.loadClass(name);
0678:
0679: if (!secEnv) {
0680: try {
0681: classLoader = imp.getSyspathJavaLoader();
0682: } catch (SecurityException e) {
0683: secEnv = true;
0684: }
0685: if (classLoader != null) {
0686: return classLoader.loadClass(name);
0687: }
0688: }
0689:
0690: return Class.forName(name);
0691:
0692: } catch (ClassNotFoundException e) {
0693: // e.printStackTrace();
0694: return null;
0695: } catch (IllegalArgumentException e) {
0696: // e.printStackTrace();
0697: return null;
0698: } catch (NoClassDefFoundError e) {
0699: // e.printStackTrace();
0700: return null;
0701: }
0702: }
0703:
0704: public static Class findClassEx(String name, String reason) {
0705: try {
0706: ClassLoader classLoader = Py.getSystemState()
0707: .getClassLoader();
0708: if (classLoader != null) {
0709: writeDebug("import", "trying " + name + " as " + reason
0710: + " in classLoader");
0711: return classLoader.loadClass(name);
0712: }
0713:
0714: if (!secEnv) {
0715: try {
0716: classLoader = imp.getSyspathJavaLoader();
0717: } catch (SecurityException e) {
0718: secEnv = true;
0719: }
0720: if (classLoader != null) {
0721: writeDebug("import", "trying " + name + " as "
0722: + reason + " in syspath loader");
0723: return classLoader.loadClass(name);
0724: }
0725: }
0726:
0727: writeDebug("import", "trying " + name + " as " + reason
0728: + " in Class.forName");
0729: return Class.forName(name);
0730: } catch (ClassNotFoundException e) {
0731: return null;
0732: } catch (IllegalArgumentException e) {
0733: throw JavaError(e);
0734: } catch (LinkageError e) {
0735: throw JavaError(e);
0736: }
0737: }
0738:
0739: private static void setArgv(String arg0, String[] args) {
0740: PyObject argv[] = new PyObject[args.length + 1];
0741: argv[0] = new PyString(arg0);
0742: for (int i = 1; i < argv.length; i++)
0743: argv[i] = new PyString(args[i - 1]);
0744: Py.getSystemState().argv = new PyList(argv);
0745: }
0746:
0747: private static boolean propertiesInitialized = false;
0748:
0749: private static synchronized void initProperties(String[] args,
0750: String[] packages, String[] props, String frozenPackage,
0751: String[] modules, ClassLoader classLoader) {
0752: if (!propertiesInitialized) {
0753: propertiesInitialized = true;
0754:
0755: if (frozenPackage != null) {
0756: Py.frozen = true;
0757: if (frozenPackage.length() > 0)
0758: Py.frozenPackage = frozenPackage;
0759: }
0760:
0761: java.util.Properties sprops;
0762: try {
0763: sprops = new java.util.Properties(System
0764: .getProperties());
0765: } catch (Throwable t) {
0766: sprops = new java.util.Properties();
0767: }
0768:
0769: if (props != null) {
0770: for (int i = 0; i < props.length; i += 2) {
0771: sprops.put(props[i], props[i + 1]);
0772: }
0773: }
0774: //System.err.println("sprops: "+sprops);
0775:
0776: if (args == null)
0777: args = new String[0];
0778: PySystemState.initialize(sprops, null, args, classLoader);
0779: }
0780:
0781: if (modules != null) {
0782: if (frozenModules == null)
0783: frozenModules = new java.util.Hashtable();
0784:
0785: // System.err.println("modules: "); // ?? dbg
0786: for (int i = 0; i < modules.length; i++) {
0787: String modname = modules[i];
0788: // System.err.print(modname + " "); // ?? dbg
0789: frozenModules.put(modname, PRESENT);
0790: // py pkgs are potentially java pkgs too.
0791: if (modname.endsWith(".__init__")) {
0792: String jpkg = modname.substring(0,
0793: modname.length() - 9);
0794: PySystemState.add_package(jpkg);
0795: // System.err.print(":j "); // ?? dbg
0796: }
0797: }
0798: // System.out.println(); // ?? dbg
0799: }
0800:
0801: if (packages != null) {
0802: for (int i = 0; i < packages.length; i += 2) {
0803: PySystemState.add_package(packages[i], packages[i + 1]);
0804: }
0805: }
0806: }
0807:
0808: public static void initProxy(PyProxy proxy, String module,
0809: String pyclass, Object[] args, String[] packages,
0810: String[] props, boolean frozen) {
0811: initProxy(proxy, module, pyclass, args, packages, props, null,
0812: null);
0813: }
0814:
0815: public static void initProxy(PyProxy proxy, String module,
0816: String pyclass, Object[] args, String[] packages,
0817: String[] props, String frozenPackage, String[] modules) {
0818: initProperties(null, packages, props, frozenPackage, modules,
0819: proxy.getClass().getClassLoader());
0820:
0821: if (proxy._getPyInstance() != null)
0822: return;
0823:
0824: ThreadState ts = getThreadState();
0825: PyInstance instance = ts.getInitializingProxy();
0826: if (instance != null) {
0827: if (instance.javaProxy != null)
0828: throw Py.TypeError("Proxy instance reused");
0829: instance.javaProxy = proxy;
0830: proxy._setPyInstance(instance);
0831: proxy._setPySystemState(ts.systemState);
0832: return;
0833: }
0834:
0835: //System.out.println("path: "+sys.path.__str__());
0836: PyObject mod;
0837: // ??pending: findClass or should avoid sys.path loading?
0838: Class modClass = Py.findClass(module + "$_PyInner");
0839: if (modClass != null) {
0840: //System.err.println("found as class: "+modClass);
0841: PyCode code = null;
0842: try {
0843: code = ((PyRunnable) modClass.newInstance()).getMain();
0844: } catch (Throwable t) {
0845: throw Py.JavaError(t);
0846: }
0847: mod = imp.createFromCode(module, code);
0848: } else {
0849: mod = imp.importName(module.intern(), false);
0850: //System.err.println("found as mod: "+mod);
0851: }
0852: PyClass pyc = (PyClass) mod.__getattr__(pyclass.intern());
0853:
0854: instance = new PyInstance(pyc);
0855: instance.javaProxy = proxy;
0856: proxy._setPyInstance(instance);
0857: proxy._setPySystemState(ts.systemState);
0858:
0859: PyObject[] pargs;
0860: if (args == null || args.length == 0) {
0861: pargs = Py.EmptyObjects;
0862: } else {
0863: pargs = new PyObject[args.length];
0864: for (int i = 0; i < args.length; i++)
0865: pargs[i] = Py.java2py(args[i]);
0866: }
0867: instance.__init__(pargs, Py.NoKeywords);
0868: }
0869:
0870: public static void initRunnable(String module, PyObject dict) {
0871: Class mainClass = null;
0872: try {
0873: // ??pending: should use Py.findClass?
0874: mainClass = Class.forName(module);
0875: } catch (ClassNotFoundException exc) {
0876: System.err.println("Error running main. Can't find: "
0877: + module);
0878: System.exit(-1);
0879: }
0880: PyCode code = null;
0881: try {
0882: code = ((PyRunnable) mainClass.newInstance()).getMain();
0883: } catch (Throwable t) {
0884: System.err.println("Invalid class (runnable): " + module
0885: + "$py");
0886: System.exit(-1);
0887: }
0888: Py.runCode(code, dict, dict);
0889: }
0890:
0891: /**
0892: * Initializes a default PythonInterpreter and runs the code from
0893: * {@link PyRunnable#getMain} as __main__
0894: *
0895: * Called by the code generated in {@link Module#addMain()}
0896: */
0897: public static void runMain(PyRunnable main, String[] args)
0898: throws Exception {
0899: initProperties(args, null, null, null, null, main.getClass()
0900: .getClassLoader());
0901: try {
0902: imp.createFromCode("__main__", main.getMain());
0903: } catch (PyException e) {
0904: Py.getSystemState().callExitFunc();
0905: if (Py.matchException(e, Py.SystemExit))
0906: return;
0907: throw e;
0908: }
0909: Py.getSystemState().callExitFunc();
0910: }
0911:
0912: public static void runMain(Class mainClass, String[] args,
0913: String[] packages, String[] props, String frozenPackage,
0914: String[] modules) throws Exception {
0915: //System.err.println("main: "+module);
0916:
0917: initProperties(args, packages, props, frozenPackage, modules,
0918: mainClass.getClassLoader());
0919:
0920: try {
0921: PyCode code = null;
0922: try {
0923: code = ((PyRunnable) mainClass.newInstance()).getMain();
0924: } catch (Throwable t) {
0925: System.err.println("Invalid class: "
0926: + mainClass.getName() + "$py");
0927: System.exit(-1);
0928: }
0929: PyObject mod = imp.createFromCode("__main__", code);
0930: } catch (PyException e) {
0931: Py.getSystemState().callExitFunc();
0932: if (Py.matchException(e, Py.SystemExit))
0933: return;
0934: throw e;
0935: }
0936: Py.getSystemState().callExitFunc();
0937: }
0938:
0939: //XXX: this needs review to make sure we are cutting out all of the Java
0940: // exceptions.
0941: private static String getStackTrace(Throwable javaError) {
0942: ByteArrayOutputStream buf = new ByteArrayOutputStream();
0943: javaError.printStackTrace(new PrintStream(buf));
0944:
0945: String str = buf.toString();
0946: int index = -1;
0947: if (index == -1)
0948: index = str
0949: .indexOf("at org.python.core.PyReflectedConstructor.__call__");
0950: if (index == -1)
0951: index = str
0952: .indexOf("at org.python.core.PyReflectedFunction.__call__");
0953: if (index == -1)
0954: index = str
0955: .indexOf("at org/python/core/PyReflectedConstructor.__call__");
0956: if (index == -1)
0957: index = str
0958: .indexOf("at org/python/core/PyReflectedFunction.__call__");
0959:
0960: if (index != -1)
0961: index = str.lastIndexOf("\n", index);
0962:
0963: int index0 = str.indexOf("\n");
0964:
0965: if (index >= index0)
0966: str = str.substring(index0 + 1, index + 1);
0967:
0968: return str;
0969: }
0970:
0971: /* Display a PyException and stack trace */
0972: public static void printException(Throwable t) {
0973: printException(t, null, null);
0974: }
0975:
0976: public static void printException(Throwable t, PyFrame f) {
0977: printException(t, f, null);
0978: }
0979:
0980: public static synchronized void printException(Throwable t,
0981: PyFrame f, PyObject file) {
0982: //System.err.println("printingException: "+t+", "+file);
0983: StdoutWrapper stderr = Py.stderr;
0984:
0985: if (file != null) {
0986: stderr = new FixedFileWrapper(file);
0987: }
0988:
0989: if (Options.showJavaExceptions) {
0990: stderr.println("Java Traceback:");
0991: java.io.CharArrayWriter buf = new java.io.CharArrayWriter();
0992: if (t instanceof PyException) {
0993: ((PyException) t)
0994: .super __printStackTrace(new java.io.PrintWriter(
0995: buf));
0996: } else {
0997: t.printStackTrace(new java.io.PrintWriter(buf));
0998: }
0999: stderr.print(buf.toString());
1000: }
1001:
1002: PyException exc = Py.JavaError(t);
1003:
1004: maybeSystemExit(exc);
1005:
1006: setException(exc, f);
1007:
1008: ThreadState ts = getThreadState();
1009:
1010: ts.systemState.last_value = exc.value;
1011: ts.systemState.last_type = exc.type;
1012: ts.systemState.last_traceback = exc.traceback;
1013:
1014: PyObject exceptHook = ts.systemState.__findattr__("excepthook");
1015: if (exceptHook != null) {
1016: try {
1017: exceptHook.__call__(exc.type, exc.value, exc.traceback);
1018: } catch (PyException exc2) {
1019: stderr.println("Error in sys.excepthook:");
1020: displayException(exc2.type, exc2.value, exc2.traceback,
1021: file);
1022: stderr.println();
1023: stderr.println("Original exception was:");
1024: displayException(exc.type, exc.value, exc.traceback,
1025: file);
1026: }
1027: } else {
1028: stderr.println("sys.excepthook is missing");
1029: displayException(exc.type, exc.value, exc.traceback, file);
1030: }
1031:
1032: ts.exception = null;
1033: }
1034:
1035: public static void displayException(PyObject type, PyObject value,
1036: PyObject tb, PyObject file) {
1037: StdoutWrapper stderr = Py.stderr;
1038: if (file != null) {
1039: stderr = new FixedFileWrapper(file);
1040: }
1041:
1042: if (tb instanceof PyTraceback)
1043: stderr.print(((PyTraceback) tb).dumpStack());
1044: if (__builtin__.isinstance(value, (PyClass) Py.SyntaxError)) {
1045: stderr.println(" File \"" + value.__findattr__("filename")
1046: + "\", line " + value.__findattr__("lineno"));
1047: PyObject text = value.__findattr__("text");
1048: if (text != Py.None && text.__len__() != 0) {
1049: stderr.println("\t" + text);
1050: String space = "\t";
1051: int col = ((PyInteger) value.__findattr__("offset")
1052: .__int__()).getValue();
1053: for (int j = 1; j < col; j++)
1054: space = space + " ";
1055: stderr.println(space + "^");
1056: }
1057: }
1058:
1059: if (value instanceof PyJavaInstance) {
1060: Object javaError = value.__tojava__(Throwable.class);
1061:
1062: if (javaError != null && javaError != Py.NoConversion) {
1063: stderr.println(getStackTrace((Throwable) javaError));
1064: }
1065: }
1066: stderr.println(formatException(type, value, tb));
1067: }
1068:
1069: static String formatException(PyObject type, PyObject value,
1070: PyObject tb) {
1071: StringBuffer buf = new StringBuffer();
1072:
1073: PyObject typeName;
1074: if (type instanceof PyClass) {
1075: buf.append(((PyClass) type).__name__);
1076: } else {
1077: buf.append(type.__str__());
1078: }
1079: if (value != Py.None) {
1080: buf.append(": ");
1081: if (__builtin__.isinstance(value, (PyClass) Py.SyntaxError)) {
1082: buf.append(value.__getitem__(0).__str__());
1083: } else {
1084: buf.append(value.__str__());
1085: }
1086: }
1087: return buf.toString();
1088: }
1089:
1090: /* Equivalent to Python's assert statement */
1091: public static void assert_(PyObject test, PyObject message) {
1092: if (!test.__nonzero__()) {
1093: throw new PyException(Py.AssertionError, message);
1094: }
1095: }
1096:
1097: public static void assert_(PyObject test) {
1098: assert_(test, Py.None);
1099: }
1100:
1101: /* Helpers to implement finally clauses */
1102: public static void addTraceback(Throwable t, PyFrame frame) {
1103: PyException e = Py.JavaError(t);
1104:
1105: //Add another traceback object to the exception if needed
1106: if (e.traceback.tb_frame != frame) {
1107: e.traceback = new PyTraceback(e.traceback);
1108: }
1109: }
1110:
1111: /* Helpers to implement except clauses */
1112: public static PyException setException(Throwable t, PyFrame frame) {
1113: PyException pye = Py.JavaError(t);
1114: pye.instantiate();
1115:
1116: // attach catching frame
1117: if (frame != null && pye.traceback.tb_frame != frame) {
1118: pye.traceback = new PyTraceback(pye.traceback);
1119: }
1120:
1121: ThreadState ts = getThreadState();
1122:
1123: ts.exception = pye;
1124:
1125: return pye;
1126: }
1127:
1128: public static boolean matchException(PyException pye, PyObject e) {
1129: pye.instantiate();
1130: // FIXME, see bug 737978
1131: //
1132: // A special case for IOError's to allow them to also match
1133: // java.io.IOExceptions. This is a hack for 1.0.x until I can do
1134: // it right in 1.1
1135: if (e == Py.IOError) {
1136: if (__builtin__.isinstance(pye.value, PyJavaClass
1137: .lookup(java.io.IOException.class))) {
1138: return true;
1139: }
1140: }
1141: // FIXME too, same approach for OutOfMemoryError
1142: if (e == Py.MemoryError) {
1143: if (__builtin__.isinstance(pye.value, PyJavaClass
1144: .lookup(java.lang.OutOfMemoryError.class))) {
1145: return true;
1146: }
1147: }
1148: if (e instanceof PyClass) {
1149: return __builtin__.isinstance(pye.value, (PyClass) e);
1150: } else {
1151: if (e == pye.type)
1152: return true;
1153: if (e instanceof PyTuple) {
1154: PyObject[] l = ((PyTuple) e).getArray();
1155: for (int i = 0; i < l.length; i++) {
1156: if (matchException(pye, l[i]))
1157: return true;
1158: }
1159: }
1160: return false;
1161: }
1162: }
1163:
1164: /* Implement the raise statement */
1165: // reraise the current exception
1166: public static PyException makeException() {
1167: ThreadState ts = getThreadState();
1168: if (ts.exception == null) {
1169: throw Py.ValueError("no exception to reraise");
1170: }
1171: return ts.exception;
1172: }
1173:
1174: public static PyException makeException(PyObject type) {
1175: if (type instanceof PyInstance) {
1176: return new PyException(type.fastGetClass(), type);
1177: } else {
1178: return makeException(type, Py.None);
1179: }
1180: }
1181:
1182: public static PyException makeException(PyObject type,
1183: PyObject value) {
1184: if (type instanceof PyInstance) {
1185: if (value != Py.None) {
1186: throw TypeError("instance exceptions may not have "
1187: + "a separate value");
1188: } else {
1189: return new PyException(type.fastGetClass(), type);
1190: }
1191: }
1192: PyException exc = new PyException(type, value);
1193: exc.instantiate();
1194: return exc;
1195: }
1196:
1197: public static PyException makeException(PyObject type,
1198: PyObject value, PyObject traceback) {
1199: if (type instanceof PyInstance) {
1200: if (value != Py.None) {
1201: throw TypeError("instance exceptions may not have "
1202: + "a separate value");
1203: } else {
1204: type = type.fastGetClass();
1205: //return new PyException(type.__class__, type);
1206: }
1207: }
1208:
1209: if (traceback == None)
1210: return new PyException(type, value);
1211: if (!(traceback instanceof PyTraceback))
1212: throw TypeError("raise 3rd arg must be traceback or None");
1213:
1214: return new PyException(type, value, (PyTraceback) traceback);
1215: }
1216:
1217: public static PyObject runCode(PyCode code, PyObject locals,
1218: PyObject globals) {
1219: PyFrame f;
1220: if (locals == null) {
1221: if (globals != null) {
1222: locals = globals;
1223: } else {
1224: locals = Py.getFrame().getf_locals();
1225: }
1226: }
1227:
1228: if (globals == null)
1229: globals = Py.getFrame().f_globals;
1230:
1231: PyTableCode tc = null;
1232: if (code instanceof PyTableCode)
1233: tc = (PyTableCode) code;
1234:
1235: f = new PyFrame(tc, locals, globals,
1236: Py.getThreadState().systemState.builtins);
1237: return code.call(f);
1238: }
1239:
1240: public static void exec(PyObject o, PyObject globals,
1241: PyObject locals) {
1242: PyCode code;
1243: if (o instanceof PyCode) {
1244: code = (PyCode) o;
1245: if (locals == null && o instanceof PyTableCode
1246: && ((PyTableCode) o).hasFreevars()) {
1247: throw Py
1248: .TypeError("code object passed to exec may not contain free variables");
1249: }
1250: } else {
1251: String contents = null;
1252: if (o instanceof PyString)
1253: contents = o.toString();
1254: else if (o instanceof PyFile) {
1255: PyFile fp = (PyFile) o;
1256: if (fp.closed)
1257: return;
1258: contents = fp.read().toString();
1259: } else
1260: throw Py
1261: .TypeError("exec: argument 1 must be string, code or file object");
1262: code = Py.compile_flags(contents, "<string>", "exec", Py
1263: .getCompilerFlags());
1264: }
1265: Py.runCode(code, locals, globals);
1266: }
1267:
1268: private static ThreadStateMapping threadStateMapping = null;
1269:
1270: public static final ThreadState getThreadState() {
1271: return getThreadState(null);
1272: }
1273:
1274: public static final ThreadState getThreadState(
1275: PySystemState newSystemState) {
1276: if (threadStateMapping == null) {
1277: synchronized (Py.class) {
1278: if (threadStateMapping == null)
1279: threadStateMapping = ThreadStateMapping
1280: .makeMapping();
1281: }
1282: }
1283: return threadStateMapping.getThreadState(newSystemState);
1284: }
1285:
1286: public static final PySystemState setSystemState(
1287: PySystemState newSystemState) {
1288: ThreadState ts = getThreadState(newSystemState);
1289: PySystemState oldSystemState = ts.systemState;
1290: if (oldSystemState != newSystemState) {
1291: //System.err.println("Warning: changing systemState "+
1292: // "for same thread!");
1293: ts.systemState = newSystemState;
1294: }
1295: return oldSystemState;
1296: }
1297:
1298: public static final PySystemState getSystemState() {
1299: return getThreadState().systemState;
1300: //defaultSystemState;
1301: }
1302:
1303: /* Get and set the current frame */
1304:
1305: public static PyFrame getFrame() {
1306: //System.out.println("getFrame");
1307: ThreadState ts = getThreadState();
1308: if (ts == null)
1309: return null;
1310: return ts.frame;
1311: }
1312:
1313: public static void setFrame(PyFrame f) {
1314: //System.out.println("setFrame");
1315: getThreadState().frame = f;
1316: }
1317:
1318: /* These are not used anymore. Uncomment them if there is a future
1319: clamor to make this functionality more easily usable
1320: public static void pushFrame(PyFrame f) {
1321: ThreadState ts = getThreadState();
1322: f.f_back = ts.frame;
1323: if (f.f_builtins == null) f.f_builtins = f.f_back.f_builtins;
1324: ts.frame = f;
1325: }
1326:
1327: public static PyFrame popFrame() {
1328: ThreadState ts = getThreadState();
1329: PyFrame f = ts.frame.f_back;
1330: ts.frame = f;
1331: return f;
1332: }
1333: */
1334:
1335: /* A collection of functions for implementing the print statement */
1336:
1337: public static StdoutWrapper stderr;
1338: static StdoutWrapper stdout;
1339:
1340: //public static StdinWrapper stdin;
1341:
1342: public static void print(PyObject file, PyObject o) {
1343: if (file == None)
1344: print(o);
1345: else
1346: new FixedFileWrapper(file).print(o);
1347: }
1348:
1349: public static void printComma(PyObject file, PyObject o) {
1350: if (file == None)
1351: printComma(o);
1352: else
1353: new FixedFileWrapper(file).printComma(o);
1354: }
1355:
1356: public static void println(PyObject file, PyObject o) {
1357: if (file == None)
1358: println(o);
1359: else
1360: new FixedFileWrapper(file).println(o);
1361: }
1362:
1363: public static void printlnv(PyObject file) {
1364: if (file == None)
1365: println();
1366: else
1367: new FixedFileWrapper(file).println();
1368: }
1369:
1370: public static void print(PyObject o) {
1371: stdout.print(o);
1372: }
1373:
1374: public static void printComma(PyObject o) {
1375: stdout.printComma(o);
1376: }
1377:
1378: public static void println(PyObject o) {
1379: stdout.println(o);
1380: }
1381:
1382: public static void println() {
1383: stdout.println();
1384: }
1385:
1386: /* A collection of convenience functions for converting PyObjects
1387: to Java primitives */
1388:
1389: public static boolean py2boolean(PyObject o) {
1390: return o.__nonzero__();
1391: }
1392:
1393: public static byte py2byte(PyObject o) {
1394: if (o instanceof PyInteger)
1395: return (byte) ((PyInteger) o).getValue();
1396:
1397: Object i = o.__tojava__(Byte.TYPE);
1398: if (i == null || i == Py.NoConversion)
1399: throw Py.TypeError("integer required");
1400: return ((Byte) i).byteValue();
1401: }
1402:
1403: public static short py2short(PyObject o) {
1404: if (o instanceof PyInteger)
1405: return (short) ((PyInteger) o).getValue();
1406:
1407: Object i = o.__tojava__(Short.TYPE);
1408: if (i == null || i == Py.NoConversion)
1409: throw Py.TypeError("integer required");
1410: return ((Short) i).shortValue();
1411: }
1412:
1413: public static int py2int(PyObject o) {
1414: return py2int(o, "integer required");
1415: }
1416:
1417: public static int py2int(PyObject o, String msg) {
1418: if (o instanceof PyInteger)
1419: return (int) ((PyInteger) o).getValue();
1420: Object obj = o.__tojava__(Integer.TYPE);
1421: if (obj == Py.NoConversion)
1422: throw Py.TypeError(msg);
1423: return ((Integer) obj).intValue();
1424: }
1425:
1426: public static long py2long(PyObject o) {
1427: if (o instanceof PyInteger)
1428: return (long) ((PyInteger) o).getValue();
1429:
1430: Object i = o.__tojava__(Long.TYPE);
1431: if (i == null || i == Py.NoConversion)
1432: throw Py.TypeError("integer required");
1433: return ((Long) i).longValue();
1434: }
1435:
1436: public static float py2float(PyObject o) {
1437: if (o instanceof PyFloat)
1438: return (float) ((PyFloat) o).getValue();
1439: if (o instanceof PyInteger)
1440: return (float) ((PyInteger) o).getValue();
1441:
1442: Object i = o.__tojava__(Float.TYPE);
1443: if (i == null || i == Py.NoConversion)
1444: throw Py.TypeError("float required");
1445: return ((Float) i).floatValue();
1446: }
1447:
1448: public static double py2double(PyObject o) {
1449: if (o instanceof PyFloat)
1450: return (double) ((PyFloat) o).getValue();
1451: if (o instanceof PyInteger)
1452: return (double) ((PyInteger) o).getValue();
1453:
1454: Object i = o.__tojava__(Double.TYPE);
1455: if (i == null || i == Py.NoConversion)
1456: throw Py.TypeError("float required");
1457: return ((Double) i).doubleValue();
1458: }
1459:
1460: public static char py2char(PyObject o) {
1461: return py2char(o, "char required");
1462: }
1463:
1464: public static char py2char(PyObject o, String msg) {
1465: if (o instanceof PyString) {
1466: PyString s = (PyString) o;
1467: if (s.__len__() != 1)
1468: throw Py.TypeError(msg);
1469: return s.toString().charAt(0);
1470: }
1471: if (o instanceof PyInteger) {
1472: return (char) ((PyInteger) o).getValue();
1473: }
1474:
1475: Object i = o.__tojava__(Character.TYPE);
1476: if (i == null || i == Py.NoConversion)
1477: throw Py.TypeError(msg);
1478: return ((Character) i).charValue();
1479: }
1480:
1481: public static void py2void(PyObject o) {
1482: if (o != Py.None) {
1483: throw Py.TypeError("None required for void return");
1484: }
1485: }
1486:
1487: private static PyString[] letters = null;
1488:
1489: public static final PyString makeCharacter(Character o) {
1490: return makeCharacter(o.charValue());
1491: }
1492:
1493: static final PyString makeCharacter(char c) {
1494: return makeCharacter(c, false);
1495: }
1496:
1497: static final PyString makeCharacter(char c, boolean explicitUnicode) {
1498: if (explicitUnicode || c > 255) {
1499: return new PyUnicode(new Character(c).toString());
1500: }
1501:
1502: if (letters == null) {
1503: letters = new PyString[256];
1504: for (char j = 0; j < 256; j++) {
1505: letters[j] = new PyString(new Character(j).toString());
1506: }
1507: }
1508: return letters[c];
1509: }
1510:
1511: /**
1512: * Uses the PyObjectAdapter passed to {@link PySystemState#initialize} to turn o into a PyObject.
1513: *
1514: * @see ClassicPyObjectAdapter - default PyObjectAdapter type
1515: */
1516: public static PyObject java2py(Object o) {
1517: return getAdapter().adapt(o);
1518: }
1519:
1520: /**
1521: * @return the ExtensiblePyObjectAdapter used by java2py.
1522: */
1523: public static ExtensiblePyObjectAdapter getAdapter() {
1524: if (adapter == null) {
1525: adapter = new ClassicPyObjectAdapter();
1526: }
1527: return adapter;
1528: }
1529:
1530: /**
1531: * Set the ExtensiblePyObjectAdapter used by java2py.
1532: *
1533: * @param adapter The new ExtensiblePyObjectAdapter
1534: */
1535: protected static void setAdapter(ExtensiblePyObjectAdapter adapter) {
1536: Py.adapter = adapter;
1537: }
1538:
1539: /**
1540: * Handles wrapping Java objects in PyObject to expose them to jython.
1541: */
1542: private static ExtensiblePyObjectAdapter adapter;
1543:
1544: public static PyObject makeClass(String name, PyObject[] bases,
1545: PyCode code, PyObject doc) {
1546: return makeClass(name, bases, code, doc, null, null);
1547: }
1548:
1549: public static PyObject makeClass(String name, PyObject[] bases,
1550: PyCode code, PyObject doc, PyObject[] closure_cells) {
1551: return makeClass(name, bases, code, doc, null, closure_cells);
1552: }
1553:
1554: public static PyObject makeClass(String name, PyObject[] bases,
1555: PyCode code, PyObject doc, Class proxyClass) {
1556: return makeClass(name, bases, code, doc, proxyClass, null);
1557: }
1558:
1559: private static Class[] pyClassCtrSignature = { String.class,
1560: PyTuple.class, PyObject.class, Class.class };
1561:
1562: static private final PyType CLASS_TYPE = PyType
1563: .fromClass(PyClass.class);
1564:
1565: public static PyObject makeClass(String name, PyObject[] bases,
1566: PyCode code, PyObject doc, Class proxyClass,
1567: PyObject[] closure_cells) {
1568: PyFrame frame = getFrame();
1569: PyObject globals = frame.f_globals;
1570:
1571: PyObject dict = code.call(Py.EmptyObjects, Py.NoKeywords,
1572: globals, Py.EmptyObjects, new PyTuple(closure_cells));
1573: if (doc != null)
1574: dict.__setitem__("__doc__", doc);
1575:
1576: PyObject metaclass;
1577:
1578: metaclass = dict.__finditem__("__metaclass__");
1579:
1580: if (metaclass == null) {
1581: if (bases.length != 0) {
1582: PyObject base = bases[0];
1583:
1584: if (base instanceof PyMetaClass) {
1585: // jython-only, experimental PyMetaClass hook
1586: // xxx keep?
1587: try {
1588: java.lang.reflect.Constructor ctor = base
1589: .getClass().getConstructor(
1590: pyClassCtrSignature);
1591: return (PyObject) ctor
1592: .newInstance(new Object[] { name,
1593: new PyTuple(bases), dict,
1594: proxyClass });
1595: } catch (Exception e) {
1596: throw Py
1597: .TypeError("meta-class fails to supply proper "
1598: + "ctr: " + base.safeRepr());
1599: }
1600: }
1601: metaclass = base.__findattr__("__class__");
1602: if (metaclass == null) {
1603: metaclass = base.getType();
1604: }
1605: } else {
1606: if (globals != null)
1607: metaclass = globals.__finditem__("__metaclass__");
1608: }
1609: }
1610:
1611: if (metaclass == null
1612: || metaclass == CLASS_TYPE
1613: || (metaclass instanceof PyJavaClass && ((PyJavaClass) metaclass).proxyClass == Class.class)) {
1614: boolean more_general = false;
1615: for (int i = 0; i < bases.length; i++) {
1616: if (!(bases[i] instanceof PyClass)) {
1617: metaclass = bases[i].getType();
1618: more_general = true;
1619: break;
1620: }
1621: }
1622: if (!more_general)
1623: return new PyClass(name, new PyTuple(bases), dict,
1624: proxyClass);
1625: }
1626:
1627: if (proxyClass != null) {
1628: throw Py
1629: .TypeError("the meta-class cannot handle java subclassing");
1630: }
1631:
1632: return metaclass.__call__(new PyString(name),
1633: new PyTuple(bases), dict);
1634: }
1635:
1636: private static int nameindex = 0;
1637:
1638: public static synchronized String getName() {
1639: String name = "org.python.pycode._pyx" + nameindex;
1640: nameindex += 1;
1641: return name;
1642: }
1643:
1644: public static CompilerFlags getCompilerFlags() {
1645: return getCompilerFlags(0, false);
1646: }
1647:
1648: public static CompilerFlags getCompilerFlags(int flags,
1649: boolean dont_inherit) {
1650: CompilerFlags cflags = null;
1651: if (dont_inherit) {
1652: cflags = new CompilerFlags(flags);
1653: } else {
1654: PyFrame frame = Py.getFrame();
1655: if (frame != null && frame.f_code != null) {
1656: cflags = new CompilerFlags(frame.f_code.co_flags
1657: | flags);
1658: }
1659: }
1660: return cflags;
1661: }
1662:
1663: // w/o compiler-flags
1664:
1665: public static PyCode compile(modType node, String filename) {
1666: return compile(node, getName(), filename);
1667: }
1668:
1669: public static PyCode compile(modType node, String name,
1670: String filename) {
1671: return compile(node, name, filename, true, false);
1672: }
1673:
1674: public static PyCode compile(modType node, String name,
1675: String filename, boolean linenumbers, boolean printResults) {
1676: return compile_flags(node, name, filename, linenumbers,
1677: printResults, null);
1678: }
1679:
1680: public static PyCode compile(InputStream istream, String filename,
1681: String type) {
1682: return compile_flags(istream, filename, type, null);
1683: }
1684:
1685: // with compiler-flags
1686:
1687: public static PyCode compile_flags(modType node, String name,
1688: String filename, boolean linenumbers, boolean printResults,
1689: CompilerFlags cflags) {
1690: try {
1691: ByteArrayOutputStream ostream = new ByteArrayOutputStream();
1692: Module.compile(node, ostream, name, filename, linenumbers,
1693: printResults, false, cflags);
1694:
1695: saveClassFile(name, ostream);
1696:
1697: return BytecodeLoader.makeCode(name, ostream.toByteArray(),
1698: filename);
1699: } catch (Throwable t) {
1700: throw parser.fixParseError(null, t, filename);
1701: }
1702: }
1703:
1704: public static PyCode compile_flags(InputStream istream,
1705: String filename, String type, CompilerFlags cflags) {
1706: modType node = parser.parse(istream, type, filename, cflags);
1707: boolean printResults = false;
1708: if (type.equals("single"))
1709: printResults = true;
1710: return Py.compile_flags(node, getName(), filename, true,
1711: printResults, cflags);
1712: }
1713:
1714: public static PyCode compile_flags(String data, String filename,
1715: String type, CompilerFlags cflags) {
1716: return Py.compile_flags(new java.io.ByteArrayInputStream(
1717: (data + "\n\n").getBytes()), filename, type, cflags);
1718: }
1719:
1720: public static PyObject compile_command_flags(String string,
1721: String filename, String kind, CompilerFlags cflags,
1722: boolean stdprompt) {
1723: modType node = parser.partialParse(string + "\n", kind,
1724: filename, cflags, stdprompt);
1725:
1726: if (node == null)
1727: return Py.None;
1728: return Py.compile_flags(node, Py.getName(), filename, true,
1729: true, cflags);
1730: }
1731:
1732: public static PyObject[] unpackSequence(PyObject o, int length) {
1733: if (o instanceof PyTuple) {
1734: PyTuple tup = (PyTuple) o;
1735: //System.err.println("unpack tuple");
1736: if (tup.__len__() == length)
1737: return tup.getArray();
1738: throw Py.ValueError("unpack tuple of wrong size");
1739: }
1740:
1741: PyObject[] ret = new PyObject[length];
1742: PyObject iter = o.__iter__();
1743: try {
1744: for (int i = 0; i < length; i++) {
1745: PyObject tmp = iter.__iternext__();
1746: if (tmp == null) {
1747: throw Py.ValueError("unpack sequence too short");
1748: }
1749: ret[i] = tmp;
1750: }
1751: } catch (PyException exc) {
1752: if (Py.matchException(exc, Py.AttributeError)) {
1753: throw Py.TypeError("unpack non-sequence");
1754: } else {
1755: throw exc;
1756: }
1757: }
1758:
1759: if (iter.__iternext__() != null) {
1760: throw Py.ValueError("unpack sequence too long");
1761: }
1762: return ret;
1763: }
1764:
1765: public static PyObject iter(PyObject seq, String message) {
1766: try {
1767: return seq.__iter__();
1768: } catch (PyException exc) {
1769: if (Py.matchException(exc, Py.TypeError))
1770: throw Py.TypeError(message);
1771: throw exc;
1772: }
1773: }
1774:
1775: private static IdImpl idimpl = IdImpl.getInstance();
1776:
1777: public static long id(PyObject o) {
1778: return idimpl.id(o);
1779: }
1780:
1781: public static String idstr(PyObject o) {
1782: return idimpl.idstr(o);
1783: }
1784:
1785: public static long java_obj_id(Object o) {
1786: return idimpl.java_obj_id(o);
1787: }
1788:
1789: public static String safeRepr(PyObject o) {
1790: return o.safeRepr();
1791: }
1792:
1793: public static void printResult(PyObject ret) {
1794: Py.getThreadState().systemState.invoke("displayhook", ret);
1795: }
1796:
1797: public static final int ERROR = -1;
1798: public static final int WARNING = 0;
1799: public static final int MESSAGE = 1;
1800: public static final int COMMENT = 2;
1801: public static final int DEBUG = 3;
1802:
1803: public static void maybeWrite(String type, String msg, int level) {
1804: if (level <= Options.verbose) {
1805: System.err.println(type + ": " + msg);
1806: }
1807: }
1808:
1809: public static void writeError(String type, String msg) {
1810: maybeWrite(type, msg, ERROR);
1811: }
1812:
1813: public static void writeWarning(String type, String msg) {
1814: maybeWrite(type, msg, WARNING);
1815: }
1816:
1817: public static void writeMessage(String type, String msg) {
1818: maybeWrite(type, msg, MESSAGE);
1819: }
1820:
1821: public static void writeComment(String type, String msg) {
1822: maybeWrite(type, msg, COMMENT);
1823: }
1824:
1825: public static void writeDebug(String type, String msg) {
1826: maybeWrite(type, msg, DEBUG);
1827: }
1828:
1829: public static void saveClassFile(String name,
1830: ByteArrayOutputStream bytestream) {
1831: String dirname = Options.proxyDebugDirectory;
1832: if (dirname == null)
1833: return;
1834:
1835: byte[] bytes = bytestream.toByteArray();
1836: File dir = new File(dirname);
1837: File file = makeFilename(name, dir);
1838: new File(file.getParent()).mkdirs();
1839: try {
1840: FileOutputStream o = new FileOutputStream(file);
1841: o.write(bytes);
1842: o.close();
1843: } catch (Throwable t) {
1844: t.printStackTrace();
1845: }
1846: }
1847:
1848: private static File makeFilename(String name, File dir) {
1849: int index = name.indexOf(".");
1850: if (index == -1)
1851: return new File(dir, name + ".class");
1852:
1853: return makeFilename(name.substring(index + 1, name.length()),
1854: new File(dir, name.substring(0, index)));
1855: }
1856:
1857: private static boolean abstract_issubclass(PyObject derived,
1858: PyObject cls) {
1859: if (derived == cls)
1860: return true;
1861: PyObject bases = derived.__findattr__("__bases__");
1862: if (bases == null)
1863: return false;
1864: for (int i = 0; i < bases.__len__(); i++) {
1865: if (abstract_issubclass(bases.__getitem__(i), cls))
1866: return true;
1867: }
1868: return false;
1869: }
1870:
1871: public static boolean isInstance(PyObject obj, PyObject cls) {
1872: if (cls instanceof PyType) {
1873: PyType objtype = obj.getType();
1874: if (objtype == cls)
1875: return true;
1876: return objtype.isSubType((PyType) cls);
1877: } else if (cls instanceof PyClass) {
1878: if (!(obj instanceof PyInstance))
1879: return false;
1880: return ((PyClass) obj.fastGetClass())
1881: .isSubClass((PyClass) cls);
1882: } else if (cls.getClass() == PyTuple.class) {
1883: for (int i = 0; i < cls.__len__(); i++) {
1884: if (isInstance(obj, cls.__getitem__(i)))
1885: return true;
1886: }
1887: return false;
1888: } else {
1889: if (cls.__findattr__("__bases__") == null)
1890: throw Py
1891: .TypeError("isinstance() arg 2 must be a class, type,"
1892: + " or tuple of classes and types");
1893: PyObject ocls = obj.__findattr__("__class__");
1894: if (ocls == null)
1895: return false;
1896: return abstract_issubclass(ocls, cls);
1897: }
1898: }
1899:
1900: public static boolean isSubClass(PyObject derived, PyObject cls) {
1901: if (derived instanceof PyType && cls instanceof PyType) {
1902: if (derived == cls)
1903: return true;
1904: return ((PyType) derived).isSubType((PyType) cls);
1905: } else if (cls instanceof PyClass && derived instanceof PyClass) {
1906: return ((PyClass) derived).isSubClass((PyClass) cls);
1907: } else if (cls.getClass() == PyTuple.class) {
1908: for (int i = 0; i < cls.__len__(); i++) {
1909: if (isSubClass(derived, cls.__getitem__(i)))
1910: return true;
1911: }
1912: return false;
1913: } else {
1914: if (derived.__findattr__("__bases__") == null)
1915: throw Py
1916: .TypeError("issubclass() arg 1 must be a class");
1917: if (cls.__findattr__("__bases__") == null)
1918: throw Py
1919: .TypeError("issubclass() arg 2 must be a class, type,"
1920: + " or tuple of classes and types");
1921: return abstract_issubclass(derived, cls);
1922: }
1923: }
1924:
1925: static PyObject[] make_array(PyObject o) {
1926: if (o instanceof PyTuple)
1927: return ((PyTuple) o).getArray();
1928:
1929: PyObject iter = o.__iter__();
1930:
1931: // Guess result size and allocate space.
1932: int n = 10;
1933: try {
1934: n = o.__len__();
1935: } catch (PyException exc) {
1936: }
1937:
1938: PyObject[] objs = new PyObject[n];
1939:
1940: int i;
1941: for (i = 0;; i++) {
1942: PyObject item = iter.__iternext__();
1943: if (item == null)
1944: break;
1945: if (i >= n) {
1946: if (n < 500) {
1947: n += 10;
1948: } else {
1949: n += 100;
1950: }
1951: PyObject[] newobjs = new PyObject[n];
1952: System.arraycopy(objs, 0, newobjs, 0, objs.length);
1953: objs = newobjs;
1954: }
1955: objs[i] = item;
1956: }
1957:
1958: // Cut back if guess was too large.
1959: if (i < n) {
1960: PyObject[] newobjs = new PyObject[i];
1961: System.arraycopy(objs, 0, newobjs, 0, i);
1962: objs = newobjs;
1963: }
1964: return objs;
1965: }
1966:
1967: }
1968:
1969: /** @deprecated **/
1970: class FixedFileWrapper extends StdoutWrapper {
1971: private PyObject file;
1972:
1973: public FixedFileWrapper(PyObject file) {
1974: name = "fixed file";
1975: this .file = file;
1976:
1977: if (file instanceof PyJavaInstance) {
1978: Object tmp = file.__tojava__(OutputStream.class);
1979: if ((tmp != Py.NoConversion) && (tmp != null)) {
1980: OutputStream os = (OutputStream) tmp;
1981: this .file = new PyFile(os, "<java OutputStream>");
1982: } else {
1983: tmp = file.__tojava__(Writer.class);
1984: if ((tmp != Py.NoConversion) && (tmp != null)) {
1985: Writer w = (Writer) tmp;
1986: this .file = new PyFile(w, "<java Writer>");
1987: }
1988: }
1989: }
1990: }
1991:
1992: protected PyObject myFile() {
1993: return file;
1994: }
1995: }
1996:
1997: /**
1998: * A code object wrapper for a python function.
1999: */
2000: class JavaCode extends PyCode {
2001: private PyObject func;
2002:
2003: public JavaCode(PyObject func) {
2004: this .func = func;
2005: if (func instanceof PyReflectedFunction)
2006: this .co_name = ((PyReflectedFunction) func).__name__;
2007: }
2008:
2009: public PyObject call(PyFrame frame, PyObject closure) {
2010: System.out.println("call #1");
2011: return Py.None;
2012: }
2013:
2014: public PyObject call(PyObject args[], String keywords[],
2015: PyObject globals, PyObject[] defaults, PyObject closure) {
2016: return func.__call__(args, keywords);
2017: }
2018:
2019: public PyObject call(PyObject self, PyObject args[],
2020: String keywords[], PyObject globals, PyObject[] defaults,
2021: PyObject closure) {
2022: return func.__call__(self, args, keywords);
2023: }
2024:
2025: public PyObject call(PyObject globals, PyObject[] defaults,
2026: PyObject closure) {
2027: return func.__call__();
2028: }
2029:
2030: public PyObject call(PyObject arg1, PyObject globals,
2031: PyObject[] defaults, PyObject closure) {
2032: return func.__call__(arg1);
2033: }
2034:
2035: public PyObject call(PyObject arg1, PyObject arg2,
2036: PyObject globals, PyObject[] defaults, PyObject closure) {
2037: return func.__call__(arg1, arg2);
2038: }
2039:
2040: public PyObject call(PyObject arg1, PyObject arg2, PyObject arg3,
2041: PyObject globals, PyObject[] defaults, PyObject closure) {
2042: return func.__call__(arg1, arg2, arg3);
2043: }
2044: }
2045:
2046: /**
2047: * A function object wrapper for a java method which comply with the
2048: * PyArgsKeywordsCall standard.
2049: */
2050: class JavaFunc extends PyObject {
2051: java.lang.reflect.Method method;
2052:
2053: public JavaFunc(java.lang.reflect.Method method) {
2054: this .method = method;
2055: }
2056:
2057: public PyObject __call__(PyObject[] args, String[] kws) {
2058: Object[] margs = new Object[] { args, kws };
2059: try {
2060: return Py.java2py(method.invoke(null, margs));
2061: } catch (Throwable t) {
2062: throw Py.JavaError(t);
2063: }
2064: }
2065:
2066: public PyObject _doget(PyObject container) {
2067: return _doget(container, null);
2068: }
2069:
2070: public PyObject _doget(PyObject container, PyObject wherefound) {
2071: if (container == null)
2072: return this ;
2073: return new PyMethod(container, this , wherefound);
2074: }
2075:
2076: public boolean _doset(PyObject container) {
2077: throw Py.TypeError("java function not settable: "
2078: + method.getName());
2079: }
2080: }
|