[Jython-checkins] jython: Use _io to name backing module for io, vs _jyio. Fixes #2368.

jim.baker jython-checkins at python.org
Sun Nov 1 15:37:30 EST 2015


https://hg.python.org/jython/rev/8e135fff613a
changeset:   7789:8e135fff613a
user:        Jim Baker <jim.baker at rackspace.com>
date:        Sun Nov 01 13:37:19 2015 -0700
summary:
  Use _io to name backing module for io, vs _jyio. Fixes #2368.

Existing Python code out there expects that names that were defined in
_jyio to be available in _io. The easiest way to fix this issue is to
rename org.python.modules._io._io to org.python.modules._io._jyio; and
to rename Lib/_jyio.py to Lib/_io.py; and fix up various imports as
necessary.

files:
  Lib/_io.py                                     |  38 +++++----
  Lib/io.py                                      |  14 +-
  Lib/test/test_io_jy.py                         |  23 ++++++
  src/org/python/modules/Setup.java              |   2 +-
  src/org/python/modules/_io/PyIOBase.java       |   4 +-
  src/org/python/modules/_io/PyRawIOBase.java    |   6 +-
  src/org/python/modules/_io/_jyio.java          |   4 +-
  tests/java/org/python/modules/_io/_ioTest.java |  12 +--
  8 files changed, 63 insertions(+), 40 deletions(-)


diff --git a/Lib/_jyio.py b/Lib/_io.py
rename from Lib/_jyio.py
rename to Lib/_io.py
--- a/Lib/_jyio.py
+++ b/Lib/_io.py
@@ -1,14 +1,21 @@
-"""
-This is based on  _pyio.py from CPython 2.7 which is Python implementation of
+"""This is based on  _pyio.py from CPython 2.7 which is Python implementation of
 the io module. The upgrade from a 2.6-ish version accounts for the large
 number of changes made all at once.
 
-It is here to stand in for classes that should be provided by the _io module.
-In CPython 2.7, when client code imports io, that module imports a set of
-classes from _io and re-exports them as its own. In Jython, io.py imports
-those things from _jyio, which in turn imports from _io those so far
-implemented in Java. _jyio implements the rest here using nearly the same
-code as _pyio.
+It is here to stand in for classes that should be provided by the Java
+implementation of the _io module.  In CPython 2.7, when client code
+imports io, that module imports a set of classes from _io and
+re-exports them as its own. In Jython, io.py imports those things from
+_io, which in turn imports from _jyio those so far implemented in
+Java. Consequently _io implements the rest here using nearly the same
+code as _pyio. (Previous to Jython 2.7.1, the import was reversed:
+this specific Python-based module was named _jyio, and it imported
+from org.python.modules.io._io; although reasonable enough for Jython
+itself, we found that extant Python code expected that the _io module
+was the one defining various classes and constants. See
+http://bugs.jython.org/issue2368 for more background. If we ever get
+around to rewriting this module completely to Java, which is doubtful,
+this problem will go away.)
 
 Some classes have gained an underscore to match their _io module names:
 _IOBase, _RawIOBase, _BufferedIOBase, _TextIOBase.
@@ -16,12 +23,11 @@
 As Jython implements more and more of _io in Java, the Python implementations here
 will progressively be replaced with imports from _io. Eventually we should implement
 all this in Java, remove this module and revert io.py to its CPython original.
+
 """
 
 from __future__ import (print_function, unicode_literals)
 
-import _io  # Java implementations to replace this module
-
 import os
 import abc
 import codecs
@@ -41,7 +47,7 @@
 __metaclass__ = type
 
 # open() uses st_blksize whenever we can
-from _io import DEFAULT_BUFFER_SIZE
+from _jyio import DEFAULT_BUFFER_SIZE
 
 # NOTE: Base classes defined here are registered with the "official" ABCs
 # defined in io.py.
@@ -58,7 +64,7 @@
         self.characters_written = characters_written
 
 
-from _io import (open, UnsupportedOperation, _IOBase, _RawIOBase, FileIO)
+from _jyio import (open, UnsupportedOperation, _IOBase, _RawIOBase, FileIO)
 
 
 class _BufferedIOBase(_IOBase):
@@ -253,9 +259,9 @@
         try:
             name = self.name
         except AttributeError:
-            return "<_jyio.{0}>".format(clsname)
+            return "<_io.{0}>".format(clsname)
         else:
-            return "<_jyio.{0} name={1!r}>".format(clsname, name)
+            return "<_io.{0} name={1!r}>".format(clsname, name)
 
     ### Lower-level APIs ###
 
@@ -1076,9 +1082,9 @@
         try:
             name = self.name
         except AttributeError:
-            return "<_jyio.TextIOWrapper encoding='{0}'>".format(self.encoding)
+            return "<_io.TextIOWrapper encoding='{0}'>".format(self.encoding)
         else:
-            return "<_jyio.TextIOWrapper name={0!r} encoding='{1}'>".format(
+            return "<_io.TextIOWrapper name={0!r} encoding='{1}'>".format(
                 name, self.encoding)
 
     @property
diff --git a/Lib/io.py b/Lib/io.py
--- a/Lib/io.py
+++ b/Lib/io.py
@@ -66,15 +66,15 @@
 import abc
 
 # For the time being, import everything via _jyio instead of from _io directly
-import _jyio
-from _jyio import (DEFAULT_BUFFER_SIZE, BlockingIOError, UnsupportedOperation,
+import _io
+from _io import (DEFAULT_BUFFER_SIZE, BlockingIOError, UnsupportedOperation,
                  open,
                  FileIO,
                  BytesIO, StringIO, BufferedReader,
                  BufferedWriter, BufferedRWPair, BufferedRandom,
                  IncrementalNewlineDecoder, TextIOWrapper)
 
-OpenWrapper = _jyio.open # for compatibility with _pyio
+OpenWrapper = _io.open # for compatibility with _pyio
 
 # for seek()
 SEEK_SET = 0
@@ -84,16 +84,16 @@
 # Declaring ABCs in C is tricky so we do it here.
 # Method descriptions and default implementations are inherited from the C
 # version however.
-class IOBase(_jyio._IOBase):
+class IOBase(_io._IOBase):
     __metaclass__ = abc.ABCMeta
 
-class RawIOBase(_jyio._RawIOBase, IOBase):
+class RawIOBase(_io._RawIOBase, IOBase):
     pass
 
-class BufferedIOBase(_jyio._BufferedIOBase, IOBase):
+class BufferedIOBase(_io._BufferedIOBase, IOBase):
     pass
 
-class TextIOBase(_jyio._TextIOBase, IOBase):
+class TextIOBase(_io._TextIOBase, IOBase):
     pass
 
 RawIOBase.register(FileIO)
diff --git a/Lib/test/test_io_jy.py b/Lib/test/test_io_jy.py
new file mode 100644
--- /dev/null
+++ b/Lib/test/test_io_jy.py
@@ -0,0 +1,23 @@
+import unittest
+from test import test_support
+
+import _io
+
+class NameTest(unittest.TestCase):
+
+    def test_names_available_in__io_module(self):
+        # verifies fix for http://bugs.jython.org/issue2368
+        self.assertGreaterEqual(
+            set(dir(_io)),
+            { 'BlockingIOError', 'BufferedRWPair', 'BufferedRandom',
+              'BufferedReader', 'BufferedWriter', 'BytesIO',
+              'DEFAULT_BUFFER_SIZE', 'FileIO', 'IncrementalNewlineDecoder',
+              'TextIOWrapper', 'UnsupportedOperation',
+              '_BufferedIOBase', '_IOBase', '_RawIOBase', '_TextIOBase'
+            })
+
+def test_main():
+    test_support.run_unittest(NameTest)
+
+if __name__ == "__main__":
+    test_main()
diff --git a/src/org/python/modules/Setup.java b/src/org/python/modules/Setup.java
--- a/src/org/python/modules/Setup.java
+++ b/src/org/python/modules/Setup.java
@@ -34,7 +34,7 @@
         "_csv:org.python.modules._csv._csv",
         "_functools:org.python.modules._functools._functools",
         "_hashlib",
-        "_io:org.python.modules._io._io",
+        "_jyio:org.python.modules._io._jyio",
         "_json:org.python.modules._json._json",
         "_jythonlib:org.python.modules._jythonlib._jythonlib",
         "_marshal",
diff --git a/src/org/python/modules/_io/PyIOBase.java b/src/org/python/modules/_io/PyIOBase.java
--- a/src/org/python/modules/_io/PyIOBase.java
+++ b/src/org/python/modules/_io/PyIOBase.java
@@ -95,7 +95,7 @@
     protected PyException unsupported(String op) {
         String fmt = "%s.%s() not supported";
         String msg = String.format(fmt, getType().fastGetName(), op);
-        return _io.UnsupportedOperation(msg);
+        return _jyio.UnsupportedOperation(msg);
     }
 
     @ExposedMethod(doc = "Internal: raise an exception for unsupported operations.")
@@ -437,7 +437,7 @@
      * Return a file descriptor for the stream. A CPython file descriptor is an int, but this is not
      * the natural choice in Jython, since Java has no such convention of using integers. File
      * descriptors should be passed around opaquely, so their actual type is irrelevant, as long as
-     * (say) {@link _io#open(PyObject[], String[])} accepts the type that {@link FileIO#fileno()}
+     * (say) {@link _jyio#open(PyObject[], String[])} accepts the type that {@link FileIO#fileno()}
      * returns.
      *
      * @return a file descriptor (as opaque object)
diff --git a/src/org/python/modules/_io/PyRawIOBase.java b/src/org/python/modules/_io/PyRawIOBase.java
--- a/src/org/python/modules/_io/PyRawIOBase.java
+++ b/src/org/python/modules/_io/PyRawIOBase.java
@@ -134,7 +134,7 @@
         PyObject readMethod = __getattr__("read");
 
         // Quite often, a single read operation will do the trick
-        PyObject prev = readMethod.__call__(_io.DEFAULT_BUFFER_SIZE);
+        PyObject prev = readMethod.__call__(_jyio.DEFAULT_BUFFER_SIZE);
 
         if (!prev.__nonzero__()) {
             // Nothing on the first read: that means we're done
@@ -142,7 +142,7 @@
 
         } else {
             // Try a second read
-            PyObject curr = readMethod.__call__(_io.DEFAULT_BUFFER_SIZE);
+            PyObject curr = readMethod.__call__(_jyio.DEFAULT_BUFFER_SIZE);
             if (!curr.__nonzero__()) {
                 // Nothing on the second read: the result is just the first one
                 return prev;
@@ -155,7 +155,7 @@
                 // Accumulate the current read result and get another, until we run out of bytes.
                 do {
                     list.add(curr);
-                    curr = readMethod.__call__(_io.DEFAULT_BUFFER_SIZE);
+                    curr = readMethod.__call__(_jyio.DEFAULT_BUFFER_SIZE);
                 } while (curr.__nonzero__());
 
                 // Stitch it all together
diff --git a/src/org/python/modules/_io/_io.java b/src/org/python/modules/_io/_jyio.java
rename from src/org/python/modules/_io/_io.java
rename to src/org/python/modules/_io/_jyio.java
--- a/src/org/python/modules/_io/_io.java
+++ b/src/org/python/modules/_io/_jyio.java
@@ -16,7 +16,7 @@
 /**
  * The Python _io module implemented in Java.
  */
-public class _io implements ClassDictInit {
+public class _jyio implements ClassDictInit {
 
     /**
      * This method is called when the module is loaded, to populate the namespace (dictionary) of
@@ -26,7 +26,7 @@
      * @param dict namespace of the module
      */
     public static void classDictInit(PyObject dict) {
-        dict.__setitem__("__name__", new PyString("_io"));
+        dict.__setitem__("__name__", new PyString("_jyio"));
         dict.__setitem__("__doc__", new PyString(__doc__));
         dict.__setitem__("DEFAULT_BUFFER_SIZE", DEFAULT_BUFFER_SIZE);
 
diff --git a/tests/java/org/python/modules/_io/_ioTest.java b/tests/java/org/python/modules/_io/_ioTest.java
--- a/tests/java/org/python/modules/_io/_ioTest.java
+++ b/tests/java/org/python/modules/_io/_ioTest.java
@@ -5,15 +5,10 @@
 import static org.junit.matchers.JUnitMatchers.*;
 
 import java.io.File;
-import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.nio.channels.Channels;
-import java.nio.channels.FileChannel;
-import java.nio.channels.WritableByteChannel;
 import java.util.Arrays;
 
 import org.junit.Before;
@@ -24,7 +19,6 @@
 import org.python.core.PyObject;
 import org.python.core.PyStringMap;
 import org.python.core.PySystemState;
-import org.python.core.imp;
 import org.python.core.io.RawIOBase;
 import org.python.util.PythonInterpreter;
 
@@ -78,7 +72,7 @@
         interp.exec("import io");
 
         // There should be a helper function
-        PyException pye = _io.UnsupportedOperation("Message from _ioTest");
+        PyException pye = _jyio.UnsupportedOperation("Message from _ioTest");
         PyObject type = pye.type;
         String repr = type.toString();
         assertEquals("Class name", "<class '_io.UnsupportedOperation'>", repr);
@@ -102,7 +96,7 @@
             interp.exec("raise _io.UnsupportedOperation()");
             fail("_io.UnsupportedOperation not raised when expected");
         } catch (PyException e) {
-            assertEquals(_io.UnsupportedOperation, e.type);
+            assertEquals(_jyio.UnsupportedOperation, e.type);
         }
     }
 
@@ -157,7 +151,7 @@
         RawIOBase fd = (RawIOBase)pyfd.__tojava__(RawIOBase.class);
         PyObject[] args = new PyObject[] {pyfd, Py.newString(mode), Py.False};
         String[] kwds = {"closefd"};
-        PyObject file2 = _io.open(args, kwds);
+        PyObject file2 = _jyio.open(args, kwds);
         file2.invoke("close");
     }
 

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


More information about the Jython-checkins mailing list