001: // Copyright (c) Corporation for National Research Initiatives
002:
003: // This class implements the standard Python sys module.
004:
005: package org.python.core;
006:
007: import java.io.File;
008: import java.io.FileInputStream;
009: import java.io.FilterInputStream;
010: import java.io.IOException;
011: import java.io.InputStream;
012: import java.net.URL;
013: import java.net.URLDecoder;
014: import java.security.AccessControlException;
015: import java.util.Enumeration;
016: import java.util.Hashtable;
017: import java.util.Properties;
018: import java.util.StringTokenizer;
019: import java.util.jar.JarEntry;
020: import java.util.jar.JarFile;
021:
022: import org.python.core.adapter.ClassicPyObjectAdapter;
023: import org.python.core.adapter.ExtensiblePyObjectAdapter;
024: import org.python.modules.Setup;
025:
026: /**
027: * The "sys" module.
028: */
029:
030: // xxx this should really be a module!
031: public class PySystemState extends PyObject {
032: public static final String JYTHON_JAR = "jython.jar";
033:
034: private static final String JAR_URL_PREFIX = "jar:file:";
035: private static final String JAR_SEPARATOR = "!";
036:
037: private static final String PYTHON_CACHEDIR = "python.cachedir";
038: protected static final String PYTHON_CACHEDIR_SKIP = "python.cachedir.skip";
039: protected static final String CACHEDIR_DEFAULT_NAME = "cachedir";
040:
041: /**
042: * The current version of Jython.
043: * <p>
044: * Usually updated by hand.<br>
045: * Replaced by ant when doing a snapshot build.
046: * <p>
047: * This also applies for the <code>PY_*</code> integer values below
048: */
049: public static String version = "2.2";
050:
051: private static int PY_MAJOR_VERSION = 2;
052: private static int PY_MINOR_VERSION = 2;
053: private static int PY_MICRO_VERSION = 0;
054: private static int PY_RELEASE_LEVEL = 0x0F;
055: private static int PY_RELEASE_SERIAL = 0;
056:
057: public static int hexversion = ((PY_MAJOR_VERSION << 24)
058: | (PY_MINOR_VERSION << 16) | (PY_MICRO_VERSION << 8)
059: | (PY_RELEASE_LEVEL << 4) | (PY_RELEASE_SERIAL << 0));
060:
061: public static PyTuple version_info;
062:
063: public static int maxunicode = 65535;
064:
065: /**
066: * The copyright notice for this release.
067: */
068: // TBD: should we use \u00a9 Unicode c-inside-circle?
069: public static String copyright = "Copyright (c) 2000-2007, Jython Developers\n"
070: + "All rights reserved.\n\n"
071: +
072:
073: "Copyright (c) 2000 BeOpen.com.\n"
074: + "All Rights Reserved.\n\n"
075: +
076:
077: "Copyright (c) 2000 The Apache Software Foundation. All rights\n"
078: + "reserved.\n\n"
079: +
080:
081: "Copyright (c) 1995-2000 Corporation for National Research "
082: + "Initiatives.\n"
083: + "All Rights Reserved.\n\n"
084: +
085:
086: "Copyright (c) 1991-1995 Stichting Mathematisch Centrum, "
087: + "Amsterdam.\n" + "All Rights Reserved.\n\n";
088:
089: /**
090: * The arguments passed to this program on the command line.
091: */
092: public PyList argv = new PyList();
093:
094: /**
095: * Exit a Python program with the given status.
096: *
097: * @param status the value to exit with
098: * @exception Py.SystemExit always throws this exception.
099: * When caught at top level the program will exit.
100: */
101: public static void exit(PyObject status) {
102: throw new PyException(Py.SystemExit, status);
103: }
104:
105: /**
106: * Exit a Python program with the status 0.
107: */
108: public static void exit() {
109: exit(Py.None);
110: }
111:
112: public PyObject modules;
113: public PyList path;
114: public static PyObject builtins;
115:
116: public PyList meta_path;
117: public PyList path_hooks;
118: public PyObject path_importer_cache;
119:
120: public static String platform = "java";
121: public static String byteorder = "big";
122:
123: public PyObject ps1 = new PyString(">>> ");
124: public PyObject ps2 = new PyString("... ");
125:
126: public static int maxint = Integer.MAX_VALUE;
127: public static int minint = Integer.MIN_VALUE;
128:
129: public PyObject executable = Py.None;
130:
131: public static PyList warnoptions;
132:
133: private ClassLoader classLoader = null;
134:
135: public ClassLoader getClassLoader() {
136: return classLoader;
137: }
138:
139: public void setClassLoader(ClassLoader classLoader) {
140: this .classLoader = classLoader;
141: }
142:
143: public static PyTuple exc_info() {
144: PyException exc = Py.getThreadState().exception;
145: if (exc == null)
146: return new PyTuple(new PyObject[] { Py.None, Py.None,
147: Py.None });
148: return new PyTuple(new PyObject[] { exc.type, exc.value,
149: exc.traceback });
150: }
151:
152: public static PyFrame _getframe() {
153: return _getframe(-1);
154: }
155:
156: public static PyFrame _getframe(int depth) {
157: PyFrame f = Py.getFrame();
158:
159: while (depth > 0 && f != null) {
160: f = f.f_back;
161: --depth;
162: }
163: if (f == null)
164: throw Py.ValueError("call stack is not deep enough");
165: return f;
166: }
167:
168: public PyObject stdout, stderr, stdin;
169: public PyObject __stdout__, __stderr__, __stdin__;
170:
171: public PyObject __displayhook__, __excepthook__;
172:
173: public PyObject last_value = Py.None;
174: public PyObject last_type = Py.None;
175: public PyObject last_traceback = Py.None;
176:
177: // xxx fix this accessors
178: public PyObject __findattr__(String name) {
179: if (name == "exc_value") {
180: PyException exc = Py.getThreadState().exception;
181: if (exc == null)
182: return null;
183: return exc.value;
184: }
185: if (name == "exc_type") {
186: PyException exc = Py.getThreadState().exception;
187: if (exc == null)
188: return null;
189: return exc.type;
190: }
191: if (name == "exc_traceback") {
192: PyException exc = Py.getThreadState().exception;
193: if (exc == null)
194: return null;
195: return exc.traceback;
196: }
197: if (name == "warnoptions") {
198: if (warnoptions == null)
199: warnoptions = new PyList();
200: return warnoptions;
201: }
202:
203: PyObject ret = super .__findattr__(name);
204: if (ret != null)
205: return ret;
206:
207: return __dict__.__finditem__(name);
208: }
209:
210: public PyObject __dict__;
211:
212: public void __setattr__(String name, PyObject value) {
213: PyType selftype = getType();
214: if (selftype == null)
215: return;
216: PyObject ret = selftype.lookup(name); // xxx fix fix fix
217: if (ret != null) {
218: ret.jtryset(this , value);
219: return;
220: }
221: if (__dict__ == null) {
222: __dict__ = new PyStringMap();
223: }
224: __dict__.__setitem__(name, value);
225: //throw Py.AttributeError(name);
226: }
227:
228: public void __delattr__(String name) {
229: if (__dict__ != null) {
230: __dict__.__delitem__(name);
231: return;
232: }
233: throw Py.AttributeError("del '" + name + "'");
234: }
235:
236: // xxx
237: public void __rawdir__(PyDictionary accum) {
238: accum.update(__dict__);
239: }
240:
241: public String safeRepr() throws PyIgnoreMethodTag {
242: return "module 'sys'";
243: }
244:
245: public String toString() {
246: return "sys module";
247: }
248:
249: private int recursionlimit = 1000;
250:
251: public int getrecursionlimit() {
252: return recursionlimit;
253: }
254:
255: public void setrecursionlimit(int recursionlimit) {
256: if (recursionlimit <= 0) {
257: throw Py.ValueError("Recursion limit must be positive");
258: }
259: this .recursionlimit = recursionlimit;
260: }
261:
262: // xxx fix and polish this
263: public PySystemState() {
264: initialize();
265: modules = new PyStringMap();
266:
267: argv = (PyList) defaultArgv.repeat(1);
268: path = (PyList) defaultPath.repeat(1);
269: path.append(Py.newString("__classpath__"));
270:
271: meta_path = new PyList();
272: meta_path.append(new PrecompiledImporter());
273: path_hooks = new PyList();
274: path_hooks.append(new JavaImporter());
275: path_hooks.append(PyJavaClass.lookup(ZipFileImporter.class));
276: path_importer_cache = new PyDictionary();
277:
278: // Set up the initial standard ins and outs
279: __stdout__ = stdout = new PyFile(System.out, "<stdout>");
280: __stderr__ = stderr = new PyFile(System.err, "<stderr>");
281: __stdin__ = stdin = new PyFile(getSystemIn(), "<stdin>");
282: __displayhook__ = new PySystemStateFunctions("displayhook", 10,
283: 1, 1);
284: __excepthook__ = new PySystemStateFunctions("excepthook", 30,
285: 3, 3);
286:
287: // This isn't quite right...
288: if (builtins == null) {
289: builtins = new PyStringMap();
290: __builtin__.fillWithBuiltins(builtins);
291: }
292: PyModule __builtin__ = new PyModule("__builtin__", builtins);
293: modules.__setitem__("__builtin__", __builtin__);
294:
295: if (getType() != null) {
296: __dict__ = new PyStringMap();
297: __dict__.invoke("update", getType().getDict());
298: __dict__.__setitem__("displayhook", __displayhook__);
299: __dict__.__setitem__("excepthook", __excepthook__);
300: }
301: }
302:
303: private static PyList defaultPath;
304: private static PyList defaultArgv;
305:
306: public static Properties registry; // = init_registry();
307: public static String prefix;
308: public static String exec_prefix = "";
309:
310: private static String findRoot(Properties preProperties,
311: Properties postProperties, String jarFileName) {
312: String root = null;
313: try {
314: if (postProperties != null)
315: root = postProperties.getProperty("python.home");
316: if (root == null)
317: root = preProperties.getProperty("python.home");
318: if (root == null)
319: root = preProperties.getProperty("install.root");
320:
321: String version = preProperties.getProperty("java.version");
322: if (version == null)
323: version = "???";
324: String lversion = version.toLowerCase();
325: if (lversion.startsWith("java"))
326: version = version.substring(4, version.length());
327:
328: if (lversion.startsWith("jdk")
329: || lversion.startsWith("jre")) {
330: version = version.substring(3, version.length());
331: }
332: if (version.equals("12"))
333: version = "1.2";
334: if (version != null)
335: platform = "java" + version;
336: } catch (Exception exc) {
337: return null;
338: }
339: // If install.root is undefined find JYTHON_JAR in class.path
340: if (root == null) {
341: String classpath = preProperties
342: .getProperty("java.class.path");
343: if (classpath != null) {
344: int jpy = classpath.toLowerCase().indexOf(JYTHON_JAR);
345: if (jpy >= 0) {
346: int start = classpath.lastIndexOf(
347: java.io.File.pathSeparator, jpy) + 1;
348: root = classpath.substring(start, jpy);
349: } else {
350: // in case JYTHON_JAR is referenced from a MANIFEST inside another jar on the classpath
351: root = jarFileName;
352: }
353: }
354: }
355: return root;
356: }
357:
358: private static void initRegistry(Properties preProperties,
359: Properties postProperties, boolean standalone,
360: String jarFileName) {
361: if (registry != null) {
362: Py.writeError("systemState",
363: "trying to reinitialize registry");
364: return;
365: }
366:
367: registry = preProperties;
368: prefix = exec_prefix = findRoot(preProperties, postProperties,
369: jarFileName);
370:
371: // Load the default registry
372: if (prefix != null) {
373: if (prefix.length() == 0) {
374: prefix = exec_prefix = ".";
375: }
376: try {
377: addRegistryFile(new File(prefix, "registry"));
378: File homeFile = new File(registry
379: .getProperty("user.home"), ".jython");
380: addRegistryFile(homeFile);
381: } catch (Exception exc) {
382: }
383: }
384: if (postProperties != null) {
385: for (Enumeration e = postProperties.keys(); e
386: .hasMoreElements();) {
387: String key = (String) e.nextElement();
388: String value = (String) postProperties.get(key);
389: registry.put(key, value);
390: }
391: }
392: if (standalone) {
393: // set default standalone property (if not yet set)
394: if (!registry.containsKey(PYTHON_CACHEDIR_SKIP)) {
395: registry.put(PYTHON_CACHEDIR_SKIP, "true");
396: }
397: }
398: // Set up options from registry
399: Options.setFromRegistry();
400: }
401:
402: private static void addRegistryFile(File file) {
403: if (file.exists()) {
404: if (!file.isDirectory()) {
405: registry = new Properties(registry);
406: try {
407: FileInputStream fp = new FileInputStream(file);
408: try {
409: registry.load(fp);
410: } finally {
411: fp.close();
412: }
413: } catch (IOException e) {
414: System.err.println("couldn't open registry file: "
415: + file.toString());
416: }
417: } else {
418: System.err.println("warning: " + file.toString()
419: + " is a directory, not a file");
420: }
421: }
422: }
423:
424: private static boolean initialized = false;
425:
426: public static Properties getBaseProperties() {
427: try {
428: return System.getProperties();
429: } catch (AccessControlException ace) {
430: return new Properties();
431: }
432: }
433:
434: public static synchronized void initialize() {
435: if (initialized)
436: return;
437: initialize(getBaseProperties(), null, new String[] { "" });
438: }
439:
440: public static synchronized void initialize(
441: Properties preProperties, Properties postProperties,
442: String[] argv) {
443: initialize(preProperties, postProperties, argv, null);
444: }
445:
446: public static synchronized void initialize(
447: Properties preProperties, Properties postProperties,
448: String[] argv, ClassLoader classLoader) {
449: initialize(preProperties, postProperties, argv, classLoader,
450: new ClassicPyObjectAdapter());
451: }
452:
453: public static synchronized void initialize(
454: Properties preProperties, Properties postProperties,
455: String[] argv, ClassLoader classLoader,
456: ExtensiblePyObjectAdapter adapter) {
457:
458: //System.err.println("initializing system state");
459: //Thread.currentThread().dumpStack();
460:
461: if (initialized) {
462: //if (postProperties != null) {
463: // Py.writeError("systemState",
464: // "trying to reinitialize with new " +
465: // "properties");
466: //}
467: return;
468: }
469: initialized = true;
470:
471: Py.setAdapter(adapter);
472: boolean standalone = false;
473: String jarFileName = getJarFileName();
474: if (jarFileName != null) {
475: standalone = isStandalone(jarFileName);
476: }
477:
478: // initialize the JPython registry
479: initRegistry(preProperties, postProperties, standalone,
480: jarFileName);
481:
482: // other initializations
483: initBuiltins(registry);
484: initStaticFields();
485:
486: // Initialize the path (and add system defaults)
487: defaultPath = initPath(registry, standalone, jarFileName);
488: defaultArgv = initArgv(argv);
489:
490: // Set up the known Java packages
491: initPackages(registry);
492:
493: // Finish up standard Python initialization...
494: Py.defaultSystemState = new PySystemState();
495: Py.setSystemState(Py.defaultSystemState);
496:
497: if (classLoader != null)
498: Py.defaultSystemState.setClassLoader(classLoader);
499: Py.initClassExceptions(PySystemState.builtins);
500: // Make sure that Exception classes have been loaded
501: new PySyntaxError("", 1, 1, "", "");
502: }
503:
504: private static void initStaticFields() {
505: Py.None = new PyNone();
506: Py.NotImplemented = new PyNotImplemented();
507: Py.NoKeywords = new String[0];
508: Py.EmptyObjects = new PyObject[0];
509:
510: Py.EmptyTuple = new PyTuple(Py.EmptyObjects);
511: Py.NoConversion = new PySingleton("Error");
512: Py.Ellipsis = new PyEllipsis();
513:
514: Py.Zero = new PyInteger(0);
515: Py.One = new PyInteger(1);
516:
517: Py.EmptyString = new PyString("");
518: Py.Newline = new PyString("\n");
519: Py.Space = new PyString(" ");
520:
521: // Setup standard wrappers for stdout and stderr...
522: Py.stderr = new StderrWrapper();
523: Py.stdout = new StdoutWrapper();
524:
525: String s = null;
526: if (PY_RELEASE_LEVEL == 0x0A)
527: s = "alpha";
528: else if (PY_RELEASE_LEVEL == 0x0B)
529: s = "beta";
530: else if (PY_RELEASE_LEVEL == 0x0C)
531: s = "candidate";
532: else if (PY_RELEASE_LEVEL == 0x0F)
533: s = "final";
534: else if (PY_RELEASE_LEVEL == 0xAA)
535: s = "snapshot";
536: version_info = new PyTuple(new PyObject[] {
537: Py.newInteger(PY_MAJOR_VERSION),
538: Py.newInteger(PY_MINOR_VERSION),
539: Py.newInteger(PY_MICRO_VERSION), Py.newString(s),
540: Py.newInteger(PY_RELEASE_SERIAL) });
541: }
542:
543: public static PackageManager packageManager;
544: public static File cachedir;
545:
546: private static void initCacheDirectory(Properties props) {
547: if (Py.frozen) {
548: cachedir = null;
549: return;
550: }
551: String skip = props.getProperty(PYTHON_CACHEDIR_SKIP, "false");
552: if (skip.equalsIgnoreCase("true")) {
553: cachedir = null;
554: return;
555: }
556: cachedir = new File(props.getProperty(PYTHON_CACHEDIR,
557: CACHEDIR_DEFAULT_NAME));
558: if (!cachedir.isAbsolute()) {
559: cachedir = new File(PySystemState.prefix, cachedir
560: .getPath());
561: }
562: }
563:
564: private static void initPackages(Properties props) {
565: initCacheDirectory(props);
566: File pkgdir;
567: if (cachedir != null) {
568: pkgdir = new File(cachedir, "packages");
569: } else {
570: pkgdir = null;
571: }
572: packageManager = new SysPackageManager(pkgdir, props);
573: }
574:
575: private static PyList initArgv(String[] args) {
576: PyList argv = new PyList();
577: if (args != null) {
578: for (int i = 0; i < args.length; i++) {
579: argv.append(new PyString(args[i]));
580: }
581: }
582: return argv;
583: }
584:
585: private static Hashtable builtinNames;
586: public static String[] builtin_module_names = null;
587:
588: private static void addBuiltin(String name) {
589: String classname;
590: String modname;
591:
592: int colon = name.indexOf(':');
593: if (colon != -1) {
594: // name:fqclassname
595: modname = name.substring(0, colon).trim();
596: classname = name.substring(colon + 1, name.length()).trim();
597: if (classname.equals("null"))
598: // name:null, i.e. remove it
599: classname = null;
600: } else {
601: modname = name.trim();
602: classname = "org.python.modules." + modname;
603: }
604: if (classname != null)
605: builtinNames.put(modname, classname);
606: else
607: builtinNames.remove(modname);
608: }
609:
610: private static void initBuiltins(Properties props) {
611: builtinNames = new Hashtable();
612:
613: // add builtins specified in the Setup.java file
614: for (int i = 0; i < Setup.builtinModules.length; i++)
615: addBuiltin(Setup.builtinModules[i]);
616:
617: // add builtins specified in the registry file
618: String builtinprop = props.getProperty(
619: "python.modules.builtin", "");
620: StringTokenizer tok = new StringTokenizer(builtinprop, ",");
621: while (tok.hasMoreTokens())
622: addBuiltin(tok.nextToken());
623:
624: int n = builtinNames.size();
625: builtin_module_names = new String[n];
626: Enumeration keys = builtinNames.keys();
627: for (int i = 0; i < n; i++)
628: builtin_module_names[i] = (String) keys.nextElement();
629: }
630:
631: static String getBuiltin(String name) {
632: return (String) builtinNames.get(name);
633: }
634:
635: private static PyList initPath(Properties props,
636: boolean standalone, String jarFileName) {
637: PyList path = new PyList();
638: if (!Py.frozen) {
639: addPaths(path, props.getProperty("python.prepath", ""));
640:
641: if (prefix != null) {
642: String libpath = new File(prefix, "Lib").toString();
643: path.append(new PyString(libpath));
644: }
645:
646: addPaths(path, props.getProperty("python.path", ""));
647: }
648: if (standalone) {
649: // standalone jython: add the /Lib directory inside JYTHON_JAR to the path
650: addPaths(path, jarFileName + "/Lib");
651: }
652:
653: return path;
654: }
655:
656: /**
657: * Check if we are in standalone mode.
658: *
659: * @param jarFileName The name of the jar file
660: *
661: * @return <code>true</code> if we have a standalone .jar file, <code>false</code> otherwise.
662: */
663: private static boolean isStandalone(String jarFileName) {
664: boolean standalone = false;
665: if (jarFileName != null) {
666: JarFile jarFile = null;
667: try {
668: jarFile = new JarFile(jarFileName);
669: JarEntry jarEntry = jarFile
670: .getJarEntry("Lib/javaos.py");
671: standalone = jarEntry != null;
672: } catch (IOException ioe) {
673: } finally {
674: if (jarFile != null) {
675: try {
676: jarFile.close();
677: } catch (IOException e) {
678: }
679: }
680: }
681: }
682: return standalone;
683: }
684:
685: /**
686: * @return the full name of the jar file containing this class, <code>null</code> if not available.
687: */
688: private static String getJarFileName() {
689: String jarFileName = null;
690: Class this Class = PySystemState.class;
691: String fullClassName = this Class.getName();
692: String className = fullClassName.substring(fullClassName
693: .lastIndexOf(".") + 1);
694: URL url = this Class.getResource(className + ".class");
695: // we expect an URL like jar:file:/install_dir/jython.jar!/org/python/core/PySystemState.class
696: if (url != null) {
697: try {
698: String urlString = URLDecoder.decode(url.toString());
699: int jarSeparatorIndex = urlString
700: .indexOf(JAR_SEPARATOR);
701: if (urlString.startsWith(JAR_URL_PREFIX)
702: && jarSeparatorIndex > 0) {
703: jarFileName = urlString.substring(JAR_URL_PREFIX
704: .length(), jarSeparatorIndex);
705: }
706: } catch (Exception e) {
707: }
708: }
709: return jarFileName;
710: }
711:
712: private static void addPaths(PyList path, String pypath) {
713: StringTokenizer tok = new StringTokenizer(pypath,
714: java.io.File.pathSeparator);
715: while (tok.hasMoreTokens())
716: path.append(new PyString(tok.nextToken().trim()));
717: }
718:
719: public static PyJavaPackage add_package(String n) {
720: return add_package(n, null);
721: }
722:
723: public static PyJavaPackage add_package(String n, String contents) {
724: return packageManager.makeJavaPackage(n, contents, null);
725: }
726:
727: /**
728: * Add a classpath directory to the list of places that are searched
729: * for java packages.
730: * <p>
731: * <b>Note</b>. Classes found in directory and subdirectory are not
732: * made available to jython by this call. It only makes the java
733: * package found in the directory available. This call is mostly
734: * usefull if jython is embedded in an application that deals with
735: * its own classloaders. A servlet container is a very good example.
736: * Calling add_classdir("<context>/WEB-INF/classes") makes the java
737: * packages in WEB-INF classes available to jython import. However the
738: * actual classloading is completely handled by the servlet container's
739: * context classloader.
740: */
741: public static void add_classdir(String directoryPath) {
742: packageManager.addDirectory(new File(directoryPath));
743: }
744:
745: /**
746: * Add a .jar & .zip directory to the list of places that are searched
747: * for java .jar and .zip files. The .jar and .zip files found will not
748: * be cached.
749: * <p>
750: * <b>Note</b>. Classes in .jar and .zip files found in the directory
751: * are not made available to jython by this call. See the note for
752: * add_classdir(dir) for more details.
753: *
754: * @param directoryPath The name of a directory.
755: *
756: * @see #add_classdir
757: */
758: public static void add_extdir(String directoryPath) {
759: packageManager.addJarDir(directoryPath, false);
760: }
761:
762: /**
763: * Add a .jar & .zip directory to the list of places that are searched
764: * for java .jar and .zip files.
765: * <p>
766: * <b>Note</b>. Classes in .jar and .zip files found in the directory
767: * are not made available to jython by this call. See the note for
768: * add_classdir(dir) for more details.
769: *
770: * @param directoryPath The name of a directory.
771: * @param cache Controls if the packages in the zip and jar
772: * file should be cached.
773: *
774: * @see #add_classdir
775: */
776: public static void add_extdir(String directoryPath, boolean cache) {
777: packageManager.addJarDir(directoryPath, cache);
778: }
779:
780: public TraceFunction tracefunc = null;
781: public TraceFunction profilefunc = null;
782:
783: public void settrace(PyObject tracefunc) {
784: //InterpreterState interp = Py.getThreadState().interp;
785: if (tracefunc == Py.None) {
786: this .tracefunc = null;
787: } else {
788: this .tracefunc = new PythonTraceFunction(tracefunc);
789: }
790: }
791:
792: public void setprofile(PyObject profilefunc) {
793: //InterpreterState interp = Py.getThreadState().interp;
794:
795: if (profilefunc == Py.None) {
796: this .profilefunc = null;
797: } else {
798: this .profilefunc = new PythonTraceFunction(profilefunc);
799: }
800: }
801:
802: private InputStream getSystemIn() {
803: if (Options.pollStandardIn) {
804: return new PollingInputStream(System.in);
805: } else {
806: return System.in;
807: }
808: }
809:
810: public String getdefaultencoding() {
811: return codecs.getDefaultEncoding();
812: }
813:
814: public void setdefaultencoding(String encoding) {
815: codecs.setDefaultEncoding(encoding);
816: }
817:
818: // Not public by design. We can't rebind the displayhook if
819: // a reflected function is inserted in the class dict.
820:
821: static void displayhook(PyObject o) {
822: /* Print value except if null or None */
823: /* After printing, also assign to '_' */
824: /* Before, set '_' to None to avoid recursion */
825: if (o == Py.None)
826: return;
827:
828: PySystemState sys = Py.getThreadState().systemState;
829: sys.builtins.__setitem__("_", Py.None);
830: Py.stdout.println(o.__repr__());
831: sys.builtins.__setitem__("_", o);
832: }
833:
834: static void excepthook(PyObject type, PyObject val, PyObject tb) {
835: Py.displayException(type, val, tb, null);
836: }
837:
838: public void callExitFunc() throws PyIgnoreMethodTag {
839: PyObject exitfunc = __findattr__("exitfunc");
840: if (exitfunc != null) {
841: try {
842: exitfunc.__call__();
843: } catch (PyException exc) {
844: if (!Py.matchException(exc, Py.SystemExit)) {
845: Py.println(stderr, Py
846: .newString("Error in sys.exitfunc:"));
847: }
848: Py.printException(exc);
849: }
850: }
851: }
852: }
853:
854: // This class is based on a suggestion from Yunho Jeon
855: class PollingInputStream extends FilterInputStream {
856: public PollingInputStream(InputStream s) {
857: super (s);
858: }
859:
860: private void waitForBytes() throws IOException {
861: try {
862: while (available() == 0) {
863: //System.err.println("waiting...");
864: Thread.sleep(100);
865: }
866: } catch (InterruptedException e) {
867: throw new PyException(Py.KeyboardInterrupt,
868: "interrupt waiting on <stdin>");
869: }
870: }
871:
872: public int read() throws IOException {
873: waitForBytes();
874: return super .read();
875: }
876:
877: public int read(byte b[], int off, int len) throws IOException {
878: waitForBytes();
879: return super .read(b, off, len);
880: }
881: }
882:
883: class PySystemStateFunctions extends PyBuiltinFunctionSet {
884: PySystemStateFunctions(String name, int index, int minargs,
885: int maxargs) {
886: super (name, index, minargs, maxargs);
887: }
888:
889: public PyObject __call__(PyObject arg) {
890: switch (index) {
891: case 10:
892: PySystemState.displayhook(arg);
893: return Py.None;
894: default:
895: throw info.unexpectedCall(1, false);
896: }
897: }
898:
899: public PyObject __call__(PyObject arg1, PyObject arg2, PyObject arg3) {
900: switch (index) {
901: case 30:
902: PySystemState.excepthook(arg1, arg2, arg3);
903: return Py.None;
904: default:
905: throw info.unexpectedCall(3, false);
906: }
907: }
908: }
|