[Jython-checkins] jython: Unify approach to isInteractive().

jeff.allen jython-checkins at python.org
Sun Sep 23 09:57:17 EDT 2018


https://hg.python.org/jython/rev/fbe8e11c24c8
changeset:   8184:fbe8e11c24c8
user:        Jeff Allen <ja.py at farowl.co.uk>
date:        Sun Sep 23 09:02:44 2018 +0100
summary:
  Unify approach to isInteractive().

This change combines the emulation of CPython Py_FdIsInteractive, evolved in the
rework of jython.main, with the launcher-based detection from #2325. The simple
test there "echo 'print 1' | dist\bin\jython" still produces output identical
with CPython's.

files:
  src/org/python/core/PrePy.java         |  51 ++++++++++++-
  src/org/python/core/Py.java            |  36 ---------
  src/org/python/core/PySystemState.java |  11 +-
  src/org/python/util/PyServlet.java     |   3 +-
  4 files changed, 50 insertions(+), 51 deletions(-)


diff --git a/src/org/python/core/PrePy.java b/src/org/python/core/PrePy.java
--- a/src/org/python/core/PrePy.java
+++ b/src/org/python/core/PrePy.java
@@ -45,6 +45,44 @@
         }
     }
 
+    /**
+     * Get a System property if it is defined, not null, and we are allowed to access it, otherwise
+     * return the given default.
+     *
+     * @param key of the entry to return
+     * @param defaultValue to return if null or disallowed
+     * @return property value or given default
+     */
+    public static String getSystemProperty(String key, String defaultValue) {
+        try {
+            String value = System.getProperty(key, null);
+            return value != null ? value : defaultValue;
+        } catch (AccessControlException ace) {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Determine whether <b>standard input</b> is an interactive stream. If the Java system property
+     * {@code python.launcher.tty} is defined and equal to {@code true} or {@code false}, then that
+     * provides the result. This property is normally supplied by the launcher. In the absence of
+     * this certainty, we use {@link #haveConsole()}.
+     *
+     * @return true if (we think) standard input is an interactive stream
+     */
+    public static boolean isInteractive() {
+        // python.launcher.tty is authoritative; see http://bugs.jython.org/issue2325
+        String tty = getSystemProperty("python.launcher.tty", "");
+        if (tty.equalsIgnoreCase("true")) {
+            return true;
+        } else if (tty.equalsIgnoreCase("false")) {
+            return false;
+        } else {
+            // See if we have access to System.console()
+            return haveConsole();
+        }
+    }
+
     /** Return {@code true} iff the console is accessible through System.console(). */
     public static boolean haveConsole() {
         try {
@@ -56,11 +94,10 @@
 
     /**
      * Check whether an input stream is interactive. This emulates CPython
-     * {@code Py_FdIsInteractive} within the constraints of pure Java.
-     *
-     * The input stream is considered ``interactive'' if either
+     * {@code Py_FdIsInteractive} within the constraints of pure Java. The input stream is
+     * considered ``interactive'' if either
      * <ol type="a">
-     * <li>it is {@code System.in} and {@code System.console()} is not {@code null}, or</li>
+     * <li>it is {@code System.in} and {@link #isInteractive()} is {@code true}, or</li>
      * <li>the {@code -i} flag was given ({@link Options#interactive}={@code true}), and the
      * filename associated with it is {@code null} or {@code"<stdin>"} or {@code "???"}.</li>
      * </ol>
@@ -70,7 +107,7 @@
      * @return true iff thought to be interactive
      */
     public static boolean isInteractive(InputStream fp, String filename) {
-        if (fp == System.in && haveConsole()) {
+        if (fp == System.in && isInteractive()) {
             return true;
         } else if (!Options.interactive) {
             return false;
@@ -133,8 +170,8 @@
      * @return the full name of the jar file containing this class, <code>null</code> if not
      *         available.
      */
-    public static String _getJarFileName() {
-        Class<Py> thisClass = Py.class;
+    private static String _getJarFileName() {
+        Class<PrePy> thisClass = PrePy.class;
         String fullClassName = thisClass.getName();
         String className = fullClassName.substring(fullClassName.lastIndexOf(".") + 1);
         URL url = thisClass.getResource(className + ".class");
diff --git a/src/org/python/core/Py.java b/src/org/python/core/Py.java
--- a/src/org/python/core/Py.java
+++ b/src/org/python/core/Py.java
@@ -1831,40 +1831,6 @@
         }
     }
 
-    /**
-     * Determine whether <b>standard input</b> is an interactive stream. This is not the same as
-     * deciding whether the interpreter is or should be in interactive mode. Amongst other things,
-     * this affects the type of console that may be legitimately installed during system
-     * initialisation.
-     * <p>
-     * If the Java system property {@code python.launcher.tty} is defined and equal to {@code true}
-     * or {@code false}, then that provides the result. This property is normally supplied by the
-     * launcher. In the absence of this certainty, we try to find outusing {@code isatty()} in the
-     * Posix emulation library. Note that the result may vary according to whether a
-     * <code>jnr-posix</code> native library is found along <code>java.library.path</code>, or the
-     * pure Java fall-back is used.
-     *
-     * @return true if (we think) standard input is an interactive stream
-     */
-    public static boolean isInteractive() {
-        String tty = System.getProperty("python.launcher.tty");
-        if (tty != null) {
-            // python.launcher.tty is authoritative; see http://bugs.jython.org/issue2325
-            tty = tty.toLowerCase();
-            if (tty.equals("true")) {
-                return true;
-            } else if (tty.equals("false")) {
-                return false;
-            }
-        }
-        // Base decision on whether System.in is interactive according to OS
-        try {
-            POSIX posix = POSIXFactory.getPOSIX();
-            return posix.isatty(FileDescriptor.in);
-        } catch (SecurityException ex) {}
-        return false;
-    }
-
     private static final String IMPORT_SITE_ERROR = ""
             + "Cannot import site module and its dependencies: %s\n"
             + "Determine if the following attributes are correct:\n" //
@@ -2809,7 +2775,6 @@
      * @param args constructor-arguments
      * @return a new instance of the desired class
      */
-    @SuppressWarnings("unchecked")
     public static <T> T newJ(PyModule module, Class<T> jcls, Object... args) {
         PyObject cls = module.__getattr__(jcls.getSimpleName().intern());
         return newJ(cls, jcls, args);
@@ -2834,7 +2799,6 @@
      * @param args constructor-arguments
      * @return a new instance of the desired class
      */
-    @SuppressWarnings("unchecked")
     public static <T> T newJ(PyModule module, Class<T> jcls, String[] keywords, Object... args) {
         PyObject cls = module.__getattr__(jcls.getSimpleName().intern());
         return newJ(cls, jcls, keywords, args);
diff --git a/src/org/python/core/PySystemState.java b/src/org/python/core/PySystemState.java
--- a/src/org/python/core/PySystemState.java
+++ b/src/org/python/core/PySystemState.java
@@ -1064,11 +1064,8 @@
     }
 
     public static Properties getBaseProperties() {
-        try {
-            return System.getProperties();
-        } catch (AccessControlException ace) {
-            return new Properties();
-        }
+        // Moved to PrePy since does not depend on PyObject). Retain in 2.7.x for compatibility.
+        return PrePy.getSystemProperties();
     }
 
     public static synchronized void initialize() {
@@ -1096,7 +1093,7 @@
             return;
         }
         if (preProperties == null) {
-            preProperties = getBaseProperties();
+            preProperties = PrePy.getSystemProperties();
         }
         if (postProperties == null) {
             postProperties = new Properties();
@@ -1197,7 +1194,7 @@
         initialized = true;
         Py.setAdapter(adapter);
         boolean standalone = false;
-        String jarFileName = Py._getJarFileName();
+        String jarFileName = Py.getJarFileName();
         if (jarFileName != null) {
             standalone = isStandalone(jarFileName);
         }
diff --git a/src/org/python/util/PyServlet.java b/src/org/python/util/PyServlet.java
--- a/src/org/python/util/PyServlet.java
+++ b/src/org/python/util/PyServlet.java
@@ -15,6 +15,7 @@
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 
+import org.python.core.PrePy;
 import org.python.core.Py;
 import org.python.core.PyException;
 import org.python.core.PyObject;
@@ -98,7 +99,7 @@
     protected static void init(Properties props, ServletContext context) {
         String rootPath = getRootPath(context);
         context.setAttribute(INIT_ATTR, true);
-        Properties baseProps = PySystemState.getBaseProperties();
+        Properties baseProps = PrePy.getSystemProperties();
         // Context parameters
         Enumeration<?> e = context.getInitParameterNames();
         while (e.hasMoreElements()) {

-- 
Repository URL: https://hg.python.org/jython


More information about the Jython-checkins mailing list