[Jython-checkins] jython: Implement _io._IOBase in Java
jeff.allen
jython-checkins at python.org
Sun Dec 9 21:29:40 CET 2012
http://hg.python.org/jython/rev/4c44912ee03f
changeset: 6893:4c44912ee03f
user: Jeff Allen <ja...py at farowl.co.uk>
date: Sat Dec 08 16:31:29 2012 +0000
summary:
Implement _io._IOBase in Java
There is now an implementation in org.python.modules._io.PyIOBase.java. Score in test_io.py is slightly up again at fail/error/skip = 12/58/99, but this will come down in later rounds when PyFileIO finally joins the new class hierarchy.
files:
CoreExposed.includes | 1 +
Lib/_jyio.py | 285 +-
Lib/test/test_io.py | 5 +-
src/org/python/modules/_io/Closer.java | 67 +
src/org/python/modules/_io/PyIOBase.java | 812 +++++
src/org/python/modules/_io/PyIOBaseDerived.java | 1538 ++++++++++
src/org/python/modules/_io/_io.java | 2 +
src/templates/_io._IOBase.derived | 210 +
src/templates/mappings | 1 +
9 files changed, 2643 insertions(+), 278 deletions(-)
diff --git a/CoreExposed.includes b/CoreExposed.includes
--- a/CoreExposed.includes
+++ b/CoreExposed.includes
@@ -59,6 +59,7 @@
org/python/modules/_csv/PyDialect.class
org/python/modules/_csv/PyReader.class
org/python/modules/_csv/PyWriter.class
+org/python/modules/_io/PyIOBase.class
org/python/modules/_io/PyFileIO.class
org/python/modules/_functools/PyPartial.class
org/python/modules/_hashlib$Hash.class
diff --git a/Lib/_jyio.py b/Lib/_jyio.py
--- a/Lib/_jyio.py
+++ b/Lib/_jyio.py
@@ -57,274 +57,7 @@
self.characters_written = characters_written
-from _io import (open, UnsupportedOperation)
-
-
-class _IOBase:
- __metaclass__ = abc.ABCMeta
-
- """The abstract base class for all I/O classes, acting on streams of
- bytes. There is no public constructor.
-
- This class provides dummy implementations for many methods that
- derived classes can override selectively; the default implementations
- represent a file that cannot be read, written or seeked.
-
- Even though _IOBase does not declare read, readinto, or write because
- their signatures will vary, implementations and clients should
- consider those methods part of the interface. Also, implementations
- may raise a IOError when operations they do not support are called.
-
- The basic type used for binary data read from or written to a file is
- bytes. bytearrays are accepted too, and in some cases (such as
- readinto) needed. Text I/O classes work with str data.
-
- Note that calling any method (even inquiries) on a closed stream is
- undefined. Implementations may raise IOError in this case.
-
- _IOBase (and its subclasses) support the iterator protocol, meaning
- that an _IOBase object can be iterated over yielding the lines in a
- stream.
-
- _IOBase also supports the :keyword:`with` statement. In this example,
- fp is closed after the suite of the with statement is complete:
-
- with open('spam.txt', 'r') as fp:
- fp.write('Spam and eggs!')
- """
-
- ### Internal ###
-
- def _unsupported(self, name):
- """Internal: raise an exception for unsupported operations."""
- raise UnsupportedOperation("%s.%s() not supported" %
- (self.__class__.__name__, name))
-
- ### Positioning ###
-
- def seek(self, pos, whence=0):
- """Change stream position.
-
- Change the stream position to byte offset offset. offset is
- interpreted relative to the position indicated by whence. Values
- for whence are:
-
- * 0 -- start of stream (the default); offset should be zero or positive
- * 1 -- current stream position; offset may be negative
- * 2 -- end of stream; offset is usually negative
-
- Return the new absolute position.
- """
- self._unsupported("seek")
-
- def tell(self):
- """Return current stream position."""
- return self.seek(0, 1)
-
- def truncate(self, pos=None):
- """Truncate file to size bytes.
-
- Size defaults to the current IO position as reported by tell(). Return
- the new size.
- """
- self._unsupported("truncate")
-
- ### Flush and close ###
-
- def flush(self):
- """Flush write buffers, if applicable.
-
- This is not implemented for read-only and non-blocking streams.
- """
- self._checkClosed()
- # XXX Should this return the number of bytes written???
-
- __closed = False
-
- def close(self):
- """Flush and close the IO object.
-
- This method has no effect if the file is already closed.
- """
- if not self.__closed:
- self.flush()
- self.__closed = True
-
- def __del__(self):
- """Destructor. Calls close()."""
- # The try/except block is in case this is called at program
- # exit time, when it's possible that globals have already been
- # deleted, and then the close() call might fail. Since
- # there's nothing we can do about such failures and they annoy
- # the end users, we suppress the traceback.
- try:
- self.close()
- except:
- pass
-
- ### Inquiries ###
-
- def seekable(self):
- """Return whether object supports random access.
-
- If False, seek(), tell() and truncate() will raise IOError.
- This method may need to do a test seek().
- """
- return False
-
- def _checkSeekable(self, msg=None):
- """Internal: raise an IOError if file is not seekable
- """
- if not self.seekable():
- raise IOError("File or stream is not seekable."
- if msg is None else msg)
-
-
- def readable(self):
- """Return whether object was opened for reading.
-
- If False, read() will raise IOError.
- """
- return False
-
- def _checkReadable(self, msg=None):
- """Internal: raise an IOError if file is not readable
- """
- if not self.readable():
- raise IOError("File or stream is not readable."
- if msg is None else msg)
-
- def writable(self):
- """Return whether object was opened for writing.
-
- If False, write() and truncate() will raise IOError.
- """
- return False
-
- def _checkWritable(self, msg=None):
- """Internal: raise an IOError if file is not writable
- """
- if not self.writable():
- raise IOError("File or stream is not writable."
- if msg is None else msg)
-
- @property
- def closed(self):
- """closed: bool. True iff the file has been closed.
-
- For backwards compatibility, this is a property, not a predicate.
- """
- return self.__closed
-
- def _checkClosed(self, msg=None):
- """Internal: raise an ValueError if file is closed
- """
- if self.closed:
- raise ValueError("I/O operation on closed file."
- if msg is None else msg)
-
- ### Context manager ###
-
- def __enter__(self):
- """Context management protocol. Returns self."""
- self._checkClosed()
- return self
-
- def __exit__(self, *args):
- """Context management protocol. Calls close()"""
- self.close()
-
- ### Lower-level APIs ###
-
- # XXX Should these be present even if unimplemented?
-
- def fileno(self):
- """Returns underlying file descriptor if one exists.
-
- An IOError is raised if the IO object does not use a file descriptor.
- """
- self._unsupported("fileno")
-
- def isatty(self):
- """Return whether this is an 'interactive' stream.
-
- Return False if it can't be determined.
- """
- self._checkClosed()
- return False
-
- ### Readline[s] and writelines ###
-
- def readline(self, limit=-1):
- r"""Read and return a line from the stream.
-
- If limit is specified, at most limit bytes will be read.
-
- The line terminator is always b'\n' for binary files; for text
- files, the newlines argument to open can be used to select the line
- terminator(s) recognized.
- """
- # For backwards compatibility, a (slowish) readline().
- if hasattr(self, "peek"):
- def nreadahead():
- readahead = self.peek(1)
- if not readahead:
- return 1
- n = (readahead.find(b"\n") + 1) or len(readahead)
- if limit >= 0:
- n = min(n, limit)
- return n
- else:
- def nreadahead():
- return 1
- if limit is None:
- limit = -1
- elif not isinstance(limit, (int, long)):
- raise TypeError("limit must be an integer")
- res = bytearray()
- while limit < 0 or len(res) < limit:
- b = self.read(nreadahead())
- if not b:
- break
- res += b
- if res.endswith(b"\n"):
- break
- return bytes(res)
-
- def __iter__(self):
- self._checkClosed()
- return self
-
- def next(self):
- line = self.readline()
- if not line:
- raise StopIteration
- return line
-
- def readlines(self, hint=None):
- """Return a list of lines from the stream.
-
- hint can be specified to control the number of lines read: no more
- lines will be read if the total size (in bytes/characters) of all
- lines so far exceeds hint.
- """
- if hint is not None and not isinstance(hint, (int, long)):
- raise TypeError("integer or None expected")
- if hint is None or hint <= 0:
- return list(self)
- n = 0
- lines = []
- for line in self:
- lines.append(line)
- n += len(line)
- if n >= hint:
- break
- return lines
-
- def writelines(self, lines):
- self._checkClosed()
- for line in lines:
- self.write(line)
+from _io import (open, UnsupportedOperation, _IOBase)
class _RawIOBase(_IOBase):
@@ -569,9 +302,9 @@
try:
name = self.name
except AttributeError:
- return "<_pyio.{0}>".format(clsname)
+ return "<_jyio.{0}>".format(clsname)
else:
- return "<_pyio.{0} name={1!r}>".format(clsname, name)
+ return "<_jyio.{0} name={1!r}>".format(clsname, name)
### Lower-level APIs ###
@@ -1325,9 +1058,9 @@
try:
name = self.name
except AttributeError:
- return "<_pyio.TextIOWrapper encoding='{0}'>".format(self.encoding)
+ return "<_jyio.TextIOWrapper encoding='{0}'>".format(self.encoding)
else:
- return "<_pyio.TextIOWrapper name={0!r} encoding='{1}'>".format(
+ return "<_jyio.TextIOWrapper name={0!r} encoding='{1}'>".format(
name, self.encoding)
@property
@@ -1361,12 +1094,12 @@
def close(self):
if self.buffer is not None and not self.closed:
- self.flush()
+ # Jython difference: flush and close via super.
+ # Sets __closed for quick _checkClosed().
+ super(TextIOWrapper, self).close()
self.buffer.close()
- @property
- def closed(self):
- return self.buffer.closed
+ # Jython difference: @property closed(self) inherited from _IOBase.__closed
@property
def name(self):
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -37,8 +37,9 @@
from test import test_support as support
import codecs
-import io # C implementation of io
-import _pyio as pyio # Python implementation of io
+import io # subject of test
+import _io # compiled implementation of io
+import _pyio as pyio # Python implementation of io
try:
import threading
except ImportError:
diff --git a/src/org/python/modules/_io/Closer.java b/src/org/python/modules/_io/Closer.java
new file mode 100644
--- /dev/null
+++ b/src/org/python/modules/_io/Closer.java
@@ -0,0 +1,67 @@
+/* Copyright (c)2012 Jython Developers */
+package org.python.modules._io;
+
+import java.lang.ref.WeakReference;
+import java.util.concurrent.Callable;
+
+import org.python.core.PyObject;
+import org.python.core.PySystemState;
+
+/**
+ * A class to take responsibility for closing a stream on JVM shutdown. On creation a Closer adds
+ * itself to a list that will be run by PySystemState on shutdown and it maintains a reference to
+ * its client PyIOBase. The client (assuming it kept a reference to the Closer) may dismiss the
+ * closer at any time: normally this will be when the client stream is closed directly, or
+ * implicitly through {@link PyIOBase#__exit__(PyObject, PyObject, PyObject)}. A possibility is that
+ * the JVM exits before an <code>close()</code> is called. In that case, {@link Closer#call()} will
+ * be called, and the <code>Closer</code> will call the client's close operation.
+ * <p>
+ * In case the close operation is overridden so that it does not dismiss the closer, it is useful to
+ * have the client's finalize dismiss the closer. If not, the Closer will remain registered and this
+ * will keep the <code>PyIOBase</code> object alive in the JVM, which is mostly harmless.
+ */
+/*
+ * Adapted from PyFile, but significantly different to call the overridden close operation of the
+ * client itself, rather than just the underlying file.
+ */
+class Closer<C extends PyIOBase> implements Callable<Void> {
+
+ /** The client in need of closing. */
+ private final WeakReference<C> client;
+
+ /** Interpreter state that will call {@link #call()} on shutdown. */
+ private PySystemState sys;
+
+ public Closer(C toClose, PySystemState sys) {
+ this.client = new WeakReference<C>(toClose);
+ this.sys = sys;
+ sys.registerCloser(this);
+ }
+
+ /**
+ * Tell the Closer that its services are no longer required. This unhooks it from the shutdown
+ * list. Repeated calls are allowed but only the first has any effect.
+ */
+ public synchronized void dismiss() {
+ if (sys != null) {
+ sys.unregisterCloser(this);
+ sys = null;
+ }
+ }
+
+ /**
+ * Called as part of a shutdown process. If the client is still (weakly) reachable, invoke its
+ * "close" method.
+ */
+ @Override
+ public synchronized Void call() {
+ // This will prevent a call to dismiss() manipulating the caller's list of closers
+ sys = null;
+ // Call close on the client (if it still exists)
+ C toClose = client.get();
+ if (toClose != null) {
+ toClose.invoke("close");
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/org/python/modules/_io/PyIOBase.java b/src/org/python/modules/_io/PyIOBase.java
new file mode 100644
--- /dev/null
+++ b/src/org/python/modules/_io/PyIOBase.java
@@ -0,0 +1,812 @@
+/* Copyright (c)2012 Jython Developers */
+package org.python.modules._io;
+
+import org.python.core.BufferProtocol;
+import org.python.core.Py;
+import org.python.core.PyArray;
+import org.python.core.PyBUF;
+import org.python.core.PyBuffer;
+import org.python.core.PyByteArray;
+import org.python.core.PyException;
+import org.python.core.PyList;
+import org.python.core.PyNewWrapper;
+import org.python.core.PyObject;
+import org.python.core.PyString;
+import org.python.core.PyStringMap;
+import org.python.core.PyType;
+import org.python.core.PyUnicode;
+import org.python.core.buffer.SimpleStringBuffer;
+import org.python.core.io.FileIO;
+import org.python.expose.ExposedGet;
+import org.python.expose.ExposedMethod;
+import org.python.expose.ExposedNew;
+import org.python.expose.ExposedType;
+
+/**
+ * The Python module <code>_io._IOBase</code>, on which the <code>io</code> module depends directly.
+ * <p>
+ * <b>Implementation note:</b> The code is based heavily on the Jython 2.6-ish
+ * <code>_fileio.PyFileIO</code>, the purely Java-accessible {@link org.python.core.io.IOBase} (both
+ * Philip Jenvey's work), and the Python implementation in <code>Lib/_pyio</code>. We do not simply
+ * delegate to the implementation in {@link org.python.core.io} because of the need to override
+ * parts of the implementation in Python subclasses. A call to {@link #close()}, for example, is
+ * required to call {@link #flush()}, but if delegated to the pure Java implementation would not
+ * call the version of <code>flush()</code> overridden in a Python sub-class of
+ * <code>_io._IOBase</code>. Equally, the use made by <code>PyRawIOBase.read(int)</code> of
+ * <code>readinto(bytearray)</code> would not pick up the version of <code>readinto</code> defined
+ * in Python.
+ */
+ at ExposedType(name = "_io._IOBase", doc = PyIOBase.doc)
+public class PyIOBase extends PyObject {
+
+ public static final PyType TYPE = PyType.fromClass(PyIOBase.class);
+
+ /** The ioDelegate's closer object; ensures the stream is closed at shutdown */
+ private Closer<PyIOBase> closer;
+
+ protected PyIOBase() {
+ this(TYPE);
+ }
+
+ protected PyIOBase(PyType subtype) {
+ super(subtype);
+ closer = new Closer<PyIOBase>(this, Py.getSystemState());
+ }
+
+ /**
+ * Provide a dictionary in the object, mainly so that methods can be overridden at instance
+ * level, mainly, in fact, so that the test <code>test_flush_error_on_close</code> passes.
+ */
+ @ExposedGet
+ protected PyObject __dict__ = new PyStringMap();
+
+ @Override
+ public PyObject fastGetDict() {
+ return __dict__;
+ }
+
+ @ExposedNew
+ static PyObject _IOBase___new__(PyNewWrapper new_, boolean init, PyType subtype,
+ PyObject[] args, String[] keywords) {
+ if (new_.for_type == subtype) {
+ // We only want an _io._IOBase, so the constructor does it all
+ return new PyIOBase();
+ } else {
+ // We want some sub-class of it (in which __init__ will be called by the caller)
+ return new PyIOBaseDerived(subtype);
+ }
+ }
+
+ /**
+ * Convenience method returning a PyException(_io.UnsupportedOperation), ripe for throwing, and
+ * naming the unsupported operation. Like many similar methods, this does not actually throw
+ * (raise) the exception: it should be thrown from the place where the problem is.
+ *
+ * @param op name of operation
+ * @return the exception for throwing
+ */
+ protected PyException unsupported(String op) {
+ String fmt = "%s.%s() not supported";
+ String msg = String.format(fmt, getType().fastGetName(), op);
+ return _io.UnsupportedOperation(msg);
+ }
+
+ @ExposedMethod(doc = "Internal: raise an exception for unsupported operations.")
+ final void _IOBase__unsupported(String name) {
+ throw unsupported(name);
+ }
+
+ /**
+ * Position the read or write pointer at a given byte offset <code>pos</code> relative to a
+ * position indicated by <code>whence</code>.
+ * <ul>
+ * <li>If <code>whence</code>=0, the position will be set to <code>pos</code> bytes.</li>
+ * <li>If <code>whence</code>=1 the position will be set to the current position plus
+ * <code>pos</code>.</li>
+ * <li>If <code>whence</code>=2 the position will be set to the stream size plus
+ * <code>pos</code> (and usually <code>pos</code><=0).</li>
+ * </ul>
+ *
+ * @param pos relative to the specified point
+ * @param whence 0=from start, 1=from here, 2=from end
+ * @return the new current position
+ */
+ public long seek(long pos, int whence) {
+ return _IOBase_seek(pos, whence);
+ }
+
+ public final long seek(long pos) {
+ return seek(pos, 0);
+ }
+
+ @ExposedMethod(defaults = "0", doc = seek_doc)
+ final long _IOBase_seek(long pos, int whence) {
+ throw unsupported("seek");
+ }
+
+ /**
+ * Get the current stream position.
+ *
+ * @return stream position
+ */
+ public long tell() {
+ return _IOBase_tell();
+ }
+
+ @ExposedMethod(doc = tell_doc)
+ final long _IOBase_tell() {
+ return seek(0, 1);
+ }
+
+ /**
+ * Truncate file to <code>size</code> bytes.
+ *
+ * @param size requested for stream
+ * @return the new size
+ */
+ public long truncate(long size) {
+ return _IOBase_truncate(null); // Just raises an exception anyway
+ }
+
+ /**
+ * Truncate file to <code>size</code> bytes to the current position (as reported by
+ * <code>tell()</code>).
+ *
+ * @param size requested for stream (or null for default)
+ * @return the new size
+ */
+ public long truncate() {
+ return _IOBase_truncate(null);
+ }
+
+ @ExposedMethod(defaults = "null", doc = truncate_doc)
+ final long _IOBase_truncate(PyObject size) {
+ throw unsupported("truncate");
+ }
+
+ /**
+ * Flush write buffers, or no-op for read-only and non-blocking streams. Irrespective of the
+ * concrete type of the i/o object, locally-buffered write data is written downstream. Whether
+ * the downstream in object is also flushed depends upon the specific type of this object.
+ */
+ public void flush() {
+ _IOBase_flush();
+ }
+
+ @ExposedMethod(doc = flush_doc)
+ final void _IOBase_flush() {}
+
+ /**
+ * True if the object is closed to further <b>client</b> operations. It is the state accessed by
+ * <code>closed</code> and checked by {@link #_checkClosed()}. It may be set without making it
+ * an error (for this object and its subclasses) to access some downstream object, notably in
+ * the implementation of <code>close()</code>.
+ */
+ /*
+ * This is the analogue of the IS_CLOSED(self) macro and iobase_closed_get() in CPython
+ * modules/_io/iobase.c. That function checks for the *existence* of an attribute
+ * __IOBase_closed. You can find this exposed in CPython. _pyio.IOBase exposes _IOBase__closed
+ * (aka "__closed") for a similar purpose (note different name).
+ */
+ @ExposedGet(name = "closed", doc = closed_doc)
+ protected boolean __closed;
+
+ /**
+ * Close the stream. If closed already, this is a no-op.
+ */
+ public void close() {
+ _IOBase_close();
+ }
+
+ @ExposedMethod(doc = close_doc)
+ final void _IOBase_close() {
+ if (!__closed) {
+ // Cancel the wake-up call
+ closer.dismiss();
+ // Close should invoke (possibly overridden) flush here.
+ invoke("flush");
+ // Prevent further access from upstream
+ __closed = true;
+ }
+ }
+
+ /**
+ * Is the stream capable of positioning the read/write pointer?
+ *
+ * @return <code>True</code> if may be positioned
+ */
+ public boolean seekable() {
+ return _IOBase_seekable();
+ }
+
+ @ExposedMethod(doc = seekable_doc)
+ final boolean _IOBase_seekable() {
+ return false;
+ }
+
+ /**
+ * Raise an error if the pointer of underlying IO stream <b>is not</b> capable of being
+ * positioned.
+ *
+ * @param msg optional custom message
+ */
+ public void _checkSeekable(String msg) {
+ _IOBase__checkSeekable(msg);
+ }
+
+ /**
+ * Raise an error if the pointer of underlying IO stream <b>is not</b> capable of being
+ * positioned.
+ */
+ public final void _checkSeekable() {
+ _checkSeekable(null);
+ }
+
+ @ExposedMethod(defaults = "null")
+ final void _IOBase__checkSeekable(String msg) {
+ if (!invoke("seekable").__nonzero__()) {
+ throw tailoredIOError(msg, "seek");
+ }
+ }
+
+ /**
+ * Is the stream readable?
+ *
+ * @return <code>true</code> if readable
+ */
+ public boolean readable() {
+ return _IOBase_readable();
+ }
+
+ @ExposedMethod(doc = readable_doc)
+ final boolean _IOBase_readable() {
+ return false;
+ }
+
+ /**
+ * Raise an error if the underlying IO stream <b>is not</b> readable.
+ *
+ * @param msg optional custom message
+ */
+ public void _checkReadable(String msg) {
+ _IOBase__checkReadable(msg);
+ }
+
+ /**
+ * Raise an error if the underlying IO stream <b>is not</b> readable.
+ */
+ public final void _checkReadable() {
+ _checkReadable(null);
+ }
+
+ @ExposedMethod(defaults = "null")
+ final void _IOBase__checkReadable(String msg) {
+ if (!invoke("readable").__nonzero__()) {
+ throw tailoredIOError(msg, "read");
+ }
+ }
+
+ /**
+ * Is the stream writable?
+ *
+ * @return <code>true</code> if writable
+ */
+ public boolean writable() {
+ return _IOBase_writable();
+ }
+
+ @ExposedMethod(doc = writable_doc)
+ final boolean _IOBase_writable() {
+ return false;
+ }
+
+ /**
+ * Raise an error if the underlying IO stream <b>is not</b> writable.
+ *
+ * @param msg optional custom message
+ */
+ public void _checkWritable(String msg) {
+ _IOBase__checkWritable(msg);
+ }
+
+ /**
+ * Raise an error if the underlying IO stream <b>is not</b> writable.
+ */
+ public final void _checkWritable() {
+ _checkWritable(null);
+ }
+
+ @ExposedMethod(defaults = "null")
+ final void _IOBase__checkWritable(String msg) {
+ if (!invoke("writable").__nonzero__()) {
+ throw tailoredIOError(msg, "writ");
+ }
+ }
+
+ /**
+ * Is the stream closed against further client operations?
+ *
+ * @return <code>true</code> if closed
+ */
+ public final boolean closed() {
+ return __closed;
+ }
+
+ /**
+ * Raise an error if the underlying IO stream <b>is</b> closed. (Note opposite sense from
+ * {@link #_checkSeekable}, etc..
+ *
+ * @param msg optional custom message
+ */
+ public void _checkClosed(String msg) {
+ _IOBase__checkClosed(msg);
+ }
+
+ public final void _checkClosed() {
+ _checkClosed(null);
+ }
+
+ @ExposedMethod(defaults = "null")
+ final void _IOBase__checkClosed(String msg) {
+ if (closed()) {
+ throw Py.ValueError(msg != null ? msg : "I/O operation on closed file");
+ }
+ }
+
+ /**
+ * Called at the start of a context-managed suite (supporting the <code>with</code> clause).
+ *
+ * @return this object
+ */
+ public PyObject __enter__() {
+ return _IOBase___enter__();
+ }
+
+ @ExposedMethod(names = {"__enter__", "__iter__"})
+ final PyObject _IOBase___enter__() {
+ _checkClosed();
+ return this;
+ }
+
+ /**
+ * Called at the end of a context-managed suite (supporting the <code>with</code> clause), and
+ * will normally close the stream.
+ *
+ * @return false
+ */
+ public boolean __exit__(PyObject type, PyObject value, PyObject traceback) {
+ return _IOBase___exit__(type, value, traceback);
+ }
+
+ @ExposedMethod
+ final boolean _IOBase___exit__(PyObject type, PyObject value, PyObject traceback) {
+ invoke("close");
+ return false;
+ }
+
+ /**
+ * 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()}
+ * returns.
+ *
+ * @return a file descriptor (as opaque object)
+ */
+ public PyObject fileno() {
+ return _IOBase_fileno();
+ }
+
+ @ExposedMethod(doc = fileno_doc)
+ final PyObject _IOBase_fileno() {
+ throw unsupported("fileno");
+ }
+
+ /**
+ * Is the stream known to be an interactive console? This relies on the ability of the
+ * underlying stream to know, which is not always possible.
+ *
+ * @return <code>true</code> if a console: <code>false</code> if not or we can't tell
+ */
+ public boolean isatty() {
+ return _IOBase_isatty();
+ }
+
+ @ExposedMethod(doc = isatty_doc)
+ final boolean _IOBase_isatty() {
+ _checkClosed();
+ return false;
+ }
+
+ /**
+ * Return one line of text (bytes terminates by <code>'\n'</code>), or the specified number of
+ * bytes, or the whole stream, whichever is shortest.
+ *
+ * @param limit maximum number of bytes (<0 means no limit)
+ * @return the line (or fragment)
+ */
+ public PyObject readline(int limit) {
+ return _readline(limit);
+ }
+
+ /**
+ * Return one line of text (bytes terminates by <code>'\n'</code>), or the whole stream,
+ * whichever is shorter.
+ *
+ * @return the line (or fragment)
+ */
+ public PyObject readline() {
+ return _readline(-1);
+ }
+
+ @ExposedMethod(defaults = "null", doc = readline_doc)
+ final PyObject _IOBase_readline(PyObject limit) {
+ if (limit == null || limit==Py.None) {
+ return _readline(-1);
+ } else if (limit.isIndex()) {
+ return _readline(limit.asInt());
+ } else {
+ throw Py.TypeError("limit must be an integer");
+ }
+ }
+
+ private PyObject _readline(int limit) {
+
+ // Either null, or a thing we can __call__()
+ PyObject peekMethod = __findattr__("peek");
+ // Either an error, or a thing we can __call__()
+ PyObject readMethod = __getattr__("read");
+
+ // We'll count down from the provided limit here
+ int remainingLimit = (limit) >= 0 ? limit : Integer.MAX_VALUE;
+
+ /*
+ * We have two almost independent versions of the implementation, depending on whether we
+ * have a peek() method available.
+ */
+ if (peekMethod != null) {
+ /*
+ * This type/object has some kind of read-ahead buffer that we can scan for end of line,
+ * and refill as required. We are prepared to make a list of the fragments and join them
+ * at the end, but often there is only one.
+ */
+ PyList list = null;
+ PyObject curr = Py.EmptyString;
+
+ while (remainingLimit > 0) {
+
+ // We hope to get away with just one pass of the loop, but if not ...
+ if (curr.__nonzero__()) {
+ // We have some previous bytes that must be added to the list
+ if (list == null) {
+ // ... be first we need a list to add them to.
+ list = new PyList();
+ }
+ list.add(curr);
+ }
+
+ /*
+ * peek() returns a str of bytes from the buffer (if any), doing at most one read to
+ * refill, all without advancing the pointer, or it returns None (in vacuous
+ * non-blocking read).
+ */
+ PyObject peekResult = peekMethod.__call__(Py.One);
+ if (peekResult.__nonzero__()) {
+
+ // Get a look at the bytes themselves
+ PyBuffer peekBuffer = readablePyBuffer(peekResult);
+
+ try {
+ /*
+ * Scan forwards in the peek buffer to see if there is an end-of-line. Most
+ * frequently this succeeds. The number of bytes to scan is limited to the
+ * (remaining) limit value and the peek-buffer length.
+ */
+ int p = 0, nr = peekBuffer.getLen();
+ if (nr > remainingLimit) {
+ nr = remainingLimit;
+ }
+
+ while (p < nr) {
+ if (peekBuffer.byteAt(p++) == '\n') {
+ remainingLimit = p; // Engineer an exit from the outer loop
+ break;
+ }
+ }
+
+ /*
+ * The the next p bytes should be added to the line we are building, and the
+ * pointer advanced: that's a read().
+ */
+ curr = readMethod.__call__(Py.newInteger(p));
+ remainingLimit -= p;
+
+ } finally {
+ // We must let go of the buffer we were given
+ peekBuffer.release();
+ }
+
+ } else {
+ // peekResult was vacuous: we must be finished
+ curr = Py.EmptyString;
+ remainingLimit = 0;
+ }
+ }
+
+ if (list == null) {
+ // We went through the loop at most once and the entire answer is in curr
+ return curr;
+
+ } else {
+ // Previous reads are in the list: return them all stitched together
+ if (curr.__nonzero__()) {
+ list.add(curr);
+ }
+ return Py.EmptyString.join(list);
+ }
+
+ } else {
+ /*
+ * We don't have a peek method, so we'll be reading one byte at a time.
+ */
+ PyByteArray res = new PyByteArray();
+
+ while (remainingLimit > 0) {
+
+ /*
+ * peek() returns a str of bytes from the buffer (if any), doing at most one read to
+ * refill, all without advancing the pointer, or it returns None (in vacuous
+ * non-blocking read).
+ */
+ PyObject curr = readMethod.__call__(Py.One);
+
+ if (curr.__nonzero__()) {
+ if (curr instanceof PyString) {
+ // Should be one-character string holding a byte
+ char c = ((PyString)curr).getString().charAt(0);
+ if (c == '\n') {
+ remainingLimit = 0; // Engineer an exit from the outer loop
+ }
+ res.append((byte)c);
+ } else {
+ String fmt = "read() should have returned a bytes object, not '%.200s'";
+ throw Py.IOError(String.format(fmt, curr.getType().fastGetName()));
+ }
+ } else {
+ remainingLimit = 0; // Exit the outer loop
+ }
+
+ }
+
+ return res.__str__();
+ }
+
+ }
+
+ @Override
+ public PyObject __iter__() {
+ _checkClosed();
+ // Not like this, in spite of what base comment says, because file *is* an iterator
+ // return new PySequenceIter(this);
+ return this;
+ }
+
+ // _IOBase___iter__ = _IOBase___enter__
+
+ @Override
+ public PyObject __iternext__() {
+ PyObject line = invoke("readline");
+ return (!line.__nonzero__()) ? null : line;
+ }
+
+ /**
+ * Read a stream as a sequence of lines.
+ *
+ * @param hint stop reading lines after this many bytes (if not EOF first)
+ * @return list containing the lines read
+ */
+ public PyObject readlines(PyObject hint) {
+ return _IOBase_readlines(hint);
+ }
+
+ @ExposedMethod(defaults = "null", doc = readlines_doc)
+ final PyObject _IOBase_readlines(PyObject hint) {
+
+ int h = 0;
+
+ if (hint==null || hint == Py.None) {
+ return new PyList(this);
+
+ } else if (!hint.isIndex()) {
+ throw Py.TypeError("integer or None expected");
+
+ } else if ((h = hint.asIndex()) <= 0) {
+ return new PyList(this);
+
+ } else {
+ int n = 0;
+ PyList lines = new PyList();
+
+ for (PyObject line : this.asIterable()) {
+ lines.append(line);
+ n += line.__len__();
+ if (n >= h) {
+ break;
+ }
+ }
+ return lines;
+ }
+ }
+
+ /**
+ * Write an iterable sequence of strings to the stream.
+ *
+ * @param lines
+ */
+ public void writelines(PyObject lines) {
+ _IOBase_writelines(lines);
+ }
+
+ @ExposedMethod(doc = writelines_doc)
+ final void _IOBase_writelines(PyObject lines) {
+ _checkClosed();
+ // Either an error, or a thing we can __call__()
+ PyObject writeMethod = __getattr__("write");
+
+ for (PyObject line : lines.asIterable()) {
+ writeMethod.__call__(line);
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ closer.dismiss();
+ invoke("close");
+ super.finalize();
+ }
+
+ /** Convenience method providing the exception in the _checkWhatever() methods. */
+ private static PyException tailoredIOError(String msg, String oper) {
+ if (msg == null) {
+ return Py.IOError("File or stream is not " + oper + "able.");
+ } else {
+ return Py.IOError(msg);
+ }
+ }
+
+ /**
+ * Construct a PyBuffer on a given object suitable for writing to the underlying stream. The
+ * buffer returned will be navigable as a 1D contiguous sequence of bytes.
+ *
+ * @param obj to be wrapped and presented as a buffer
+ * @return a 1D contiguous PyBuffer of bytes
+ * @throws PyException (BufferError) if object has buffer API, but is not 1D contiguous bytes
+ * @throws PyException (TypeError) if object not convertible to a byte array
+ */
+ protected static PyBuffer readablePyBuffer(PyObject obj) throws PyException {
+ if (obj instanceof BufferProtocol) {
+ return ((BufferProtocol)obj).getBuffer(PyBUF.SIMPLE);
+ } else {
+ // Something else we can view as a String?
+ String s;
+ if (obj instanceof PyUnicode) {
+ s = ((PyUnicode)obj).encode();
+ } else if (obj instanceof PyArray) {
+ s = ((PyArray)obj).tostring();
+ } else {
+ // None of the above: complain
+ String fmt = "object must be string or buffer, not %.100s";
+ throw Py.TypeError(String.format(fmt, obj.getType().fastGetName()));
+ }
+ return new SimpleStringBuffer(PyBUF.SIMPLE, s);
+ }
+ }
+
+ /**
+ * Construct a PyBuffer on a given object suitable for reading into from the underlying stream.
+ * The buffer returned will be navigable as a 1D contiguous writable sequence of bytes.
+ *
+ * @param obj to be wrapped and presented as a buffer
+ * @return a 1D contiguous PyBuffer of bytes
+ * @throws PyException (BufferError) if object has buffer API, but is not 1D contiguous bytes
+ * @throws PyException (TypeError) if object not convertible to a byte array
+ */
+ protected static PyBuffer writablePyBuffer(PyObject obj) throws PyException {
+ if (obj instanceof BufferProtocol) {
+ return ((BufferProtocol)obj).getBuffer(PyBUF.WRITABLE);
+ } else {
+ // Can't be a buffer: complain
+ String fmt = "object must be read-write buffer, not %.100s";
+ throw Py.TypeError(String.format(fmt, obj.getType().fastGetName()));
+ }
+ }
+
+ /*
+ * Documentation strings: public where they might be useful to a subclass.
+ */
+ public static final String seek_doc = "Change stream position.\n" + "\n"
+ + "Change the stream position to byte offset offset. offset is\n"
+ + "interpreted relative to the position indicated by whence. Values\n"
+ + "for whence are:\n" + "\n"
+ + "* 0 -- start of stream (the default); offset should be zero or positive\n"
+ + "* 1 -- current stream position; offset may be negative\n"
+ + "* 2 -- end of stream; offset is usually negative\n" + "\n"
+ + "Return the new absolute position.";
+
+ public static final String tell_doc = "Return current stream position.";
+
+ public static final String truncate_doc = "Truncate file to size bytes.\n" + "\n"
+ + "File pointer is left unchanged. Size defaults to the current IO\n"
+ + "position as reported by tell(). Returns the new size.";
+
+ public static final String flush_doc = "Flush write buffers, if applicable.\n" + "\n"
+ + "This is not implemented for read-only and non-blocking streams.";
+
+ // public static final String _flush_self_doc =
+ // "Flush write buffers (if any) into the downstream object\n"
+ // + "without flushing that object. The base implementations of\n"
+ // + "flush() and close() will call this method to move any\n"
+ // + "buffered write-data down to the next i/o object in the\n"
+ // + "stack before flushing or closing that downstream object.\n"
+ // + "A sub-class may override this method if it defines buffered\n"
+ // + "state. Generally sub-classes and clients should not call\n"
+ // + "this method directly.";
+
+ public static final String close_doc = "Flush and close the IO object.\n" + "\n"
+ + "This method has no effect if the file is already closed.";
+
+ public static final String closed_doc = "True if the stream is closed.\n";
+
+ public static final String seekable_doc = "Return whether object supports random access.\n"
+ + "\n" + "If False, seek(), tell() and truncate() will raise IOError.\n"
+ + "This method may need to do a test seek().";
+
+ public static final String readable_doc = "Return whether object was opened for reading.\n"
+ + "\n" + "If False, read() will raise IOError.";
+
+ public static final String writable_doc = "Return whether object was opened for writing.\n"
+ + "\n" + "If False, read() will raise IOError.";
+
+ public static final String fileno_doc = "Returns underlying file descriptor if one exists.\n"
+ + "\n" + "An IOError is raised if the IO object does not use a file descriptor.\n";
+
+ public static final String isatty_doc = "Return whether this is an 'interactive' stream.\n"
+ + "\n" + "Return False if it can't be determined.\n";
+
+ public static final String readline_doc = "Read and return a line from the stream.\n" + "\n"
+ + "If limit is specified, at most limit bytes will be read.\n" + "\n"
+ + "The line terminator is always b'\n' for binary files; for text\n"
+ + "files, the newlines argument to open can be used to select the line\n"
+ + "terminator(s) recognized.\n";
+
+ public static final String readlines_doc = "Return a list of lines from the stream.\n" + "\n"
+ + "hint can be specified to control the number of lines read: no more\n"
+ + "lines will be read if the total size (in bytes/characters) of all\n"
+ + "lines so far exceeds hint.";
+
+ public static final String writelines_doc =
+ "Write a list of lines to the stream. Line separators are not added,\n"
+ + "so it is usual for each of the lines provided to have a line separator\n"
+ + "at the end.";
+
+ static final String doc = "The abstract base class for all I/O classes, acting on streams of\n"
+ + "bytes. There is no public constructor.\n" + "\n"
+ + "This class provides dummy implementations for many methods that\n"
+ + "derived classes can override selectively; the default implementations\n"
+ + "represent a file that cannot be read, written or seeked.\n" + "\n"
+ + "Even though IOBase does not declare read, readinto, or write because\n"
+ + "their signatures will vary, implementations and clients should\n"
+ + "consider those methods part of the interface. Also, implementations\n"
+ + "may raise a IOError when operations they do not support are called.\n" + "\n"
+ + "The basic type used for binary data read from or written to a file is\n"
+ + "bytes. bytearrays are accepted too, and in some cases (such as\n"
+ + "readinto) needed. Text I/O classes work with str data.\n" + "\n"
+ + "Note that calling any method (even inquiries) on a closed stream is\n"
+ + "undefined. Implementations may raise IOError in this case.\n" + "\n"
+ + "IOBase (and its subclasses) support the iterator protocol, meaning\n"
+ + "that an IOBase object can be iterated over yielding the lines in a\n" + "stream.\n"
+ + "\n" + "IOBase also supports the :keyword:`with` statement. In this example,\n"
+ + "fp is closed after the suite of the with statement is complete:\n" + "\n"
+ + "with open('spam.txt', 'r') as fp:\n" + " fp.write('Spam and eggs!')\n";
+
+}
diff --git a/src/org/python/modules/_io/PyIOBaseDerived.java b/src/org/python/modules/_io/PyIOBaseDerived.java
new file mode 100644
--- /dev/null
+++ b/src/org/python/modules/_io/PyIOBaseDerived.java
@@ -0,0 +1,1538 @@
+/* Generated file, do not modify. See jython/src/templates/gderived.py. */
+package org.python.modules._io;
+
+import java.io.Serializable;
+
+import org.python.core.Deriveds;
+import org.python.core.Py;
+import org.python.core.PyBoolean;
+import org.python.core.PyComplex;
+import org.python.core.PyException;
+import org.python.core.PyFloat;
+import org.python.core.PyInteger;
+import org.python.core.PyLong;
+import org.python.core.PyObject;
+import org.python.core.PySequenceIter;
+import org.python.core.PySlice;
+import org.python.core.PyString;
+import org.python.core.PyTuple;
+import org.python.core.PyType;
+import org.python.core.PyUnicode;
+import org.python.core.Slotted;
+import org.python.core.ThreadState;
+
+public class PyIOBaseDerived extends PyIOBase implements Slotted {
+
+ @Override
+ public PyObject getSlot(int index) {
+ return slots[index];
+ }
+
+ @Override
+ public void setSlot(int index, PyObject value) {
+ slots[index] = value;
+ }
+
+ private PyObject[] slots;
+
+ public PyIOBaseDerived(PyType subtype) {
+ super(subtype);
+ slots = new PyObject[subtype.getNumSlots()];
+ }
+
+ @Override
+ public PyString __str__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__str__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__();
+ if (res instanceof PyString) {
+ return (PyString)res;
+ }
+ throw Py.TypeError("__str__" + " returned non-" + "string" + " (type "
+ + res.getType().fastGetName() + ")");
+ }
+ return super.__str__();
+ }
+
+ @Override
+ public PyString __repr__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__repr__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__();
+ if (res instanceof PyString) {
+ return (PyString)res;
+ }
+ throw Py.TypeError("__repr__" + " returned non-" + "string" + " (type "
+ + res.getType().fastGetName() + ")");
+ }
+ return super.__repr__();
+ }
+
+ @Override
+ public PyString __hex__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__hex__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__();
+ if (res instanceof PyString) {
+ return (PyString)res;
+ }
+ throw Py.TypeError("__hex__" + " returned non-" + "string" + " (type "
+ + res.getType().fastGetName() + ")");
+ }
+ return super.__hex__();
+ }
+
+ @Override
+ public PyString __oct__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__oct__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__();
+ if (res instanceof PyString) {
+ return (PyString)res;
+ }
+ throw Py.TypeError("__oct__" + " returned non-" + "string" + " (type "
+ + res.getType().fastGetName() + ")");
+ }
+ return super.__oct__();
+ }
+
+ @Override
+ public PyFloat __float__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__float__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__();
+ if (res instanceof PyFloat) {
+ return (PyFloat)res;
+ }
+ throw Py.TypeError("__float__" + " returned non-" + "float" + " (type "
+ + res.getType().fastGetName() + ")");
+ }
+ return super.__float__();
+ }
+
+ @Override
+ public PyComplex __complex__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__complex__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__();
+ if (res instanceof PyComplex) {
+ return (PyComplex)res;
+ }
+ throw Py.TypeError("__complex__" + " returned non-" + "complex" + " (type "
+ + res.getType().fastGetName() + ")");
+ }
+ return super.__complex__();
+ }
+
+ @Override
+ public PyObject __pos__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__pos__");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__();
+ }
+ return super.__pos__();
+ }
+
+ @Override
+ public PyObject __neg__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__neg__");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__();
+ }
+ return super.__neg__();
+ }
+
+ @Override
+ public PyObject __abs__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__abs__");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__();
+ }
+ return super.__abs__();
+ }
+
+ @Override
+ public PyObject __invert__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__invert__");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__();
+ }
+ return super.__invert__();
+ }
+
+ @Override
+ public PyObject __reduce__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__reduce__");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__();
+ }
+ return super.__reduce__();
+ }
+
+ @Override
+ public PyObject __dir__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__dir__");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__();
+ }
+ return super.__dir__();
+ }
+
+ @Override
+ public PyObject __add__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__add__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__add__(other);
+ }
+
+ @Override
+ public PyObject __radd__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__radd__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__radd__(other);
+ }
+
+ @Override
+ public PyObject __sub__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__sub__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__sub__(other);
+ }
+
+ @Override
+ public PyObject __rsub__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__rsub__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__rsub__(other);
+ }
+
+ @Override
+ public PyObject __mul__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__mul__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__mul__(other);
+ }
+
+ @Override
+ public PyObject __rmul__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__rmul__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__rmul__(other);
+ }
+
+ @Override
+ public PyObject __div__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__div__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__div__(other);
+ }
+
+ @Override
+ public PyObject __rdiv__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__rdiv__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__rdiv__(other);
+ }
+
+ @Override
+ public PyObject __floordiv__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__floordiv__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__floordiv__(other);
+ }
+
+ @Override
+ public PyObject __rfloordiv__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__rfloordiv__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__rfloordiv__(other);
+ }
+
+ @Override
+ public PyObject __truediv__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__truediv__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__truediv__(other);
+ }
+
+ @Override
+ public PyObject __rtruediv__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__rtruediv__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__rtruediv__(other);
+ }
+
+ @Override
+ public PyObject __mod__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__mod__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__mod__(other);
+ }
+
+ @Override
+ public PyObject __rmod__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__rmod__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__rmod__(other);
+ }
+
+ @Override
+ public PyObject __divmod__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__divmod__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__divmod__(other);
+ }
+
+ @Override
+ public PyObject __rdivmod__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__rdivmod__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__rdivmod__(other);
+ }
+
+ @Override
+ public PyObject __rpow__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__rpow__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__rpow__(other);
+ }
+
+ @Override
+ public PyObject __lshift__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__lshift__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__lshift__(other);
+ }
+
+ @Override
+ public PyObject __rlshift__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__rlshift__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__rlshift__(other);
+ }
+
+ @Override
+ public PyObject __rshift__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__rshift__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__rshift__(other);
+ }
+
+ @Override
+ public PyObject __rrshift__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__rrshift__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__rrshift__(other);
+ }
+
+ @Override
+ public PyObject __and__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__and__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__and__(other);
+ }
+
+ @Override
+ public PyObject __rand__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__rand__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__rand__(other);
+ }
+
+ @Override
+ public PyObject __or__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__or__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__or__(other);
+ }
+
+ @Override
+ public PyObject __ror__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__ror__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__ror__(other);
+ }
+
+ @Override
+ public PyObject __xor__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__xor__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__xor__(other);
+ }
+
+ @Override
+ public PyObject __rxor__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__rxor__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__rxor__(other);
+ }
+
+ @Override
+ public PyObject __lt__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__lt__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__lt__(other);
+ }
+
+ @Override
+ public PyObject __le__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__le__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__le__(other);
+ }
+
+ @Override
+ public PyObject __gt__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__gt__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__gt__(other);
+ }
+
+ @Override
+ public PyObject __ge__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__ge__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__ge__(other);
+ }
+
+ @Override
+ public PyObject __eq__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__eq__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__eq__(other);
+ }
+
+ @Override
+ public PyObject __ne__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__ne__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__ne__(other);
+ }
+
+ @Override
+ public PyObject __format__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__format__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__format__(other);
+ }
+
+ @Override
+ public PyObject __iadd__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__iadd__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__iadd__(other);
+ }
+
+ @Override
+ public PyObject __isub__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__isub__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__isub__(other);
+ }
+
+ @Override
+ public PyObject __imul__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__imul__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__imul__(other);
+ }
+
+ @Override
+ public PyObject __idiv__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__idiv__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__idiv__(other);
+ }
+
+ @Override
+ public PyObject __ifloordiv__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__ifloordiv__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__ifloordiv__(other);
+ }
+
+ @Override
+ public PyObject __itruediv__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__itruediv__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__itruediv__(other);
+ }
+
+ @Override
+ public PyObject __imod__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__imod__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__imod__(other);
+ }
+
+ @Override
+ public PyObject __ipow__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__ipow__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__ipow__(other);
+ }
+
+ @Override
+ public PyObject __ilshift__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__ilshift__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__ilshift__(other);
+ }
+
+ @Override
+ public PyObject __irshift__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__irshift__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__irshift__(other);
+ }
+
+ @Override
+ public PyObject __iand__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__iand__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__iand__(other);
+ }
+
+ @Override
+ public PyObject __ior__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__ior__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__ior__(other);
+ }
+
+ @Override
+ public PyObject __ixor__(PyObject other) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__ixor__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__ixor__(other);
+ }
+
+ @Override
+ public PyObject __int__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__int__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__();
+ if (res instanceof PyInteger || res instanceof PyLong) {
+ return res;
+ }
+ throw Py.TypeError("__int__" + " should return an integer");
+ }
+ return super.__int__();
+ }
+
+ @Override
+ public PyObject __long__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__long__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__();
+ if (res instanceof PyLong || res instanceof PyInteger) {
+ return res;
+ }
+ throw Py.TypeError("__long__" + " returned non-" + "long" + " (type "
+ + res.getType().fastGetName() + ")");
+ }
+ return super.__long__();
+ }
+
+ @Override
+ public int hashCode() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__hash__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__();
+ if (res instanceof PyInteger) {
+ return ((PyInteger)res).getValue();
+ } else if (res instanceof PyLong) {
+ return ((PyLong)res).getValue().intValue();
+ }
+ throw Py.TypeError("__hash__ should return a int");
+ }
+ if (self_type.lookup("__eq__") != null || self_type.lookup("__cmp__") != null) {
+ throw Py.TypeError(String.format("unhashable type: '%.200s'", getType().fastGetName()));
+ }
+ return super.hashCode();
+ }
+
+ @Override
+ public PyUnicode __unicode__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__unicode__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__();
+ if (res instanceof PyUnicode) {
+ return (PyUnicode)res;
+ }
+ if (res instanceof PyString) {
+ return new PyUnicode((PyString)res);
+ }
+ throw Py.TypeError("__unicode__" + " should return a " + "unicode");
+ }
+ return super.__unicode__();
+ }
+
+ @Override
+ public int __cmp__(PyObject other) {
+ PyType self_type = getType();
+ PyObject[] where_type = new PyObject[1];
+ PyObject impl = self_type.lookup_where("__cmp__", where_type);
+ // Full Compatibility with CPython __cmp__:
+ // If the derived type don't override __cmp__, the
+ // *internal* super().__cmp__ should be called, not the
+ // exposed one. The difference is that the exposed __cmp__
+ // throws a TypeError if the argument is an instance of the same type.
+ if (impl == null || where_type[0] == TYPE || Py.isSubClass(TYPE, where_type[0])) {
+ return super.__cmp__(other);
+ }
+ PyObject res = impl.__get__(this, self_type).__call__(other);
+ if (res == Py.NotImplemented) {
+ return -2;
+ }
+ int c = res.asInt();
+ return c < 0 ? -1 : c > 0 ? 1 : 0;
+ }
+
+ @Override
+ public boolean __nonzero__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__nonzero__");
+ if (impl == null) {
+ impl = self_type.lookup("__len__");
+ if (impl == null) {
+ return super.__nonzero__();
+ }
+ }
+ PyObject o = impl.__get__(this, self_type).__call__();
+ Class c = o.getClass();
+ if (c != PyInteger.class && c != PyBoolean.class) {
+ throw Py.TypeError(String.format("__nonzero__ should return bool or int, returned %s",
+ self_type.getName()));
+ }
+ return o.__nonzero__();
+ }
+
+ @Override
+ public boolean __contains__(PyObject o) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__contains__");
+ if (impl == null) {
+ return super.__contains__(o);
+ }
+ return impl.__get__(this, self_type).__call__(o).__nonzero__();
+ }
+
+ @Override
+ public int __len__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__len__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__();
+ if (res instanceof PyInteger) {
+ return ((PyInteger)res).getValue();
+ }
+ throw Py.TypeError("__len__ should return a int");
+ }
+ return super.__len__();
+ }
+
+ @Override
+ public PyObject __iter__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__iter__");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__();
+ }
+ impl = self_type.lookup("__getitem__");
+ if (impl == null) {
+ return super.__iter__();
+ }
+ return new PySequenceIter(this);
+ }
+
+ @Override
+ public PyObject __iternext__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("next");
+ if (impl != null) {
+ try {
+ return impl.__get__(this, self_type).__call__();
+ } catch (PyException exc) {
+ if (exc.match(Py.StopIteration)) {
+ return null;
+ }
+ throw exc;
+ }
+ }
+ return super.__iternext__(); // ???
+ }
+
+ @Override
+ public PyObject __finditem__(PyObject key) { // ???
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__getitem__");
+ if (impl != null) {
+ try {
+ return impl.__get__(this, self_type).__call__(key);
+ } catch (PyException exc) {
+ if (exc.match(Py.LookupError)) {
+ return null;
+ }
+ throw exc;
+ }
+ }
+ return super.__finditem__(key);
+ }
+
+ @Override
+ public PyObject __finditem__(int key) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__getitem__");
+ if (impl != null) {
+ try {
+ return impl.__get__(this, self_type).__call__(new PyInteger(key));
+ } catch (PyException exc) {
+ if (exc.match(Py.LookupError)) {
+ return null;
+ }
+ throw exc;
+ }
+ }
+ return super.__finditem__(key);
+ }
+
+ @Override
+ public PyObject __getitem__(PyObject key) {
+ // Same as __finditem__, without swallowing LookupErrors. This allows
+ // __getitem__ implementations written in Python to raise custom
+ // exceptions (such as subclasses of KeyError).
+ //
+ // We are forced to duplicate the code, instead of defining __finditem__
+ // in terms of __getitem__. That's because PyObject defines __getitem__
+ // in terms of __finditem__. Therefore, we would end with an infinite
+ // loop when self_type.lookup("__getitem__") returns null:
+ //
+ // __getitem__ -> super.__getitem__ -> __finditem__ -> __getitem__
+ //
+ // By duplicating the (short) lookup and call code, we are safe, because
+ // the call chains will be:
+ //
+ // __finditem__ -> super.__finditem__
+ //
+ // __getitem__ -> super.__getitem__ -> __finditem__ -> super.__finditem__
+
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__getitem__");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__(key);
+ }
+ return super.__getitem__(key);
+ }
+
+ @Override
+ public void __setitem__(PyObject key, PyObject value) { // ???
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__setitem__");
+ if (impl != null) {
+ impl.__get__(this, self_type).__call__(key, value);
+ return;
+ }
+ super.__setitem__(key, value);
+ }
+
+ @Override
+ public PyObject __getslice__(PyObject start, PyObject stop, PyObject step) { // ???
+ if (step != null) {
+ return __getitem__(new PySlice(start, stop, step));
+ }
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__getslice__");
+ if (impl != null) {
+ PyObject[] indices = PySlice.indices2(this, start, stop);
+ return impl.__get__(this, self_type).__call__(indices[0], indices[1]);
+ }
+ return super.__getslice__(start, stop, step);
+ }
+
+ @Override
+ public void __setslice__(PyObject start, PyObject stop, PyObject step, PyObject value) {
+ if (step != null) {
+ __setitem__(new PySlice(start, stop, step), value);
+ return;
+ }
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__setslice__");
+ if (impl != null) {
+ PyObject[] indices = PySlice.indices2(this, start, stop);
+ impl.__get__(this, self_type).__call__(indices[0], indices[1], value);
+ return;
+ }
+ super.__setslice__(start, stop, step, value);
+ }
+
+ @Override
+ public void __delslice__(PyObject start, PyObject stop, PyObject step) {
+ if (step != null) {
+ __delitem__(new PySlice(start, stop, step));
+ return;
+ }
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__delslice__");
+ if (impl != null) {
+ PyObject[] indices = PySlice.indices2(this, start, stop);
+ impl.__get__(this, self_type).__call__(indices[0], indices[1]);
+ return;
+ }
+ super.__delslice__(start, stop, step);
+ }
+
+ @Override
+ public void __delitem__(PyObject key) { // ???
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__delitem__");
+ if (impl != null) {
+ impl.__get__(this, self_type).__call__(key);
+ return;
+ }
+ super.__delitem__(key);
+ }
+
+ @Override
+ public PyObject __call__(PyObject args[], String keywords[]) {
+ ThreadState ts = Py.getThreadState();
+ if (ts.recursion_depth++ > ts.systemState.getrecursionlimit()) {
+ throw Py.RuntimeError("maximum __call__ recursion depth exceeded");
+ }
+ try {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__call__");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__(args, keywords);
+ }
+ return super.__call__(args, keywords);
+ } finally {
+ --ts.recursion_depth;
+ }
+ }
+
+ @Override
+ public PyObject __findattr_ex__(String name) {
+ return Deriveds.__findattr_ex__(this, name);
+ }
+
+ @Override
+ public void __setattr__(String name, PyObject value) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__setattr__");
+ if (impl != null) {
+ impl.__get__(this, self_type).__call__(PyString.fromInterned(name), value);
+ return;
+ }
+ super.__setattr__(name, value);
+ }
+
+ @Override
+ public void __delattr__(String name) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__delattr__");
+ if (impl != null) {
+ impl.__get__(this, self_type).__call__(PyString.fromInterned(name));
+ return;
+ }
+ super.__delattr__(name);
+ }
+
+ @Override
+ public PyObject __get__(PyObject obj, PyObject type) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__get__");
+ if (impl != null) {
+ if (obj == null) {
+ obj = Py.None;
+ }
+ if (type == null) {
+ type = Py.None;
+ }
+ return impl.__get__(this, self_type).__call__(obj, type);
+ }
+ return super.__get__(obj, type);
+ }
+
+ @Override
+ public void __set__(PyObject obj, PyObject value) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__set__");
+ if (impl != null) {
+ impl.__get__(this, self_type).__call__(obj, value);
+ return;
+ }
+ super.__set__(obj, value);
+ }
+
+ @Override
+ public void __delete__(PyObject obj) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__delete__");
+ if (impl != null) {
+ impl.__get__(this, self_type).__call__(obj);
+ return;
+ }
+ super.__delete__(obj);
+ }
+
+ @Override
+ public PyObject __pow__(PyObject other, PyObject modulo) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__pow__");
+ if (impl != null) {
+ PyObject res;
+ if (modulo == null) {
+ res = impl.__get__(this, self_type).__call__(other);
+ } else {
+ res = impl.__get__(this, self_type).__call__(other, modulo);
+ }
+ if (res == Py.NotImplemented) {
+ return null;
+ }
+ return res;
+ }
+ return super.__pow__(other, modulo);
+ }
+
+ @Override
+ public void dispatch__init__(PyObject[] args, String[] keywords) {
+ Deriveds.dispatch__init__(this, args, keywords);
+ }
+
+ @Override
+ public PyObject __index__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__index__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__();
+ if (res instanceof PyInteger || res instanceof PyLong) {
+ return res;
+ }
+ throw Py.TypeError(String.format("__index__ returned non-(int,long) (type %s)", res
+ .getType().fastGetName()));
+ }
+ return super.__index__();
+ }
+
+ @Override
+ public Object __tojava__(Class c) {
+ // If we are not being asked by the "default" conversion to java, then
+ // we can provide this as the result, as long as it is a instance of the
+ // specified class. Without this, derived.__tojava__(PyObject.class)
+ // would broke. (And that's not pure speculation: PyReflectedFunction's
+ // ReflectedArgs asks for things like that).
+ if ((c != Object.class) && (c != Serializable.class) && (c.isInstance(this))) {
+ return this;
+ }
+ // Otherwise, we call the derived __tojava__, if it exists:
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__tojava__");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__(Py.java2py(c)).__tojava__(Object.class);
+ }
+ return super.__tojava__(c);
+ }
+
+ @Override
+ public Object __coerce_ex__(PyObject o) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__coerce__");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(o);
+ if (res == Py.NotImplemented) {
+ return Py.None;
+ }
+ if (!(res instanceof PyTuple)) {
+ throw Py.TypeError("__coerce__ didn't return a 2-tuple");
+ }
+ return ((PyTuple)res).getArray();
+ }
+ return super.__coerce_ex__(o);
+ }
+
+ @Override
+ public PyObject __enter__() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__enter__");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__();
+ }
+ return super.__enter__();
+ }
+
+ @Override
+ public PyObject fileno() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("fileno");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__();
+ }
+ return super.fileno();
+ }
+
+ // Hand-crafted in _io._IOBase.derived
+
+ @Override
+ public long seek(long pos, int whence) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("seek");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__(Py.newLong(pos), Py.newInteger(whence))
+ .asLong();
+ } else {
+ return super.seek(pos, whence);
+ }
+ }
+
+ @Override
+ public long tell() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("tell");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__().asLong();
+ } else {
+ return super.tell();
+ }
+ }
+
+ @Override
+ public long truncate(long size) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("truncate");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__(Py.newLong(size)).asLong();
+ } else {
+ return super.truncate(size);
+ }
+ }
+
+ @Override
+ public long truncate() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("truncate");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__().asLong();
+ } else {
+ return super.truncate();
+ }
+ }
+
+ @Override
+ public void flush() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("flush");
+ if (impl != null) {
+ impl.__get__(this, self_type).__call__();
+ } else {
+ super.flush();
+ }
+ }
+
+ @Override
+ public void close() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("close");
+ if (impl != null) {
+ impl.__get__(this, self_type).__call__();
+ } else {
+ super.close();
+ }
+ }
+
+ @Override
+ public boolean seekable() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("seekable");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__().__nonzero__();
+ } else {
+ return super.seekable();
+ }
+ }
+
+ @Override
+ public void _checkSeekable(String msg) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("_checkSeekable");
+ if (impl != null) {
+ PyObject pymsg = msg == null ? Py.None : new PyString(msg);
+ impl.__get__(this, self_type).__call__(pymsg);
+ } else {
+ super._checkSeekable(msg);
+ }
+ }
+
+ @Override
+ public boolean readable() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("readable");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__().__nonzero__();
+ } else {
+ return super.readable();
+ }
+ }
+
+ @Override
+ public void _checkReadable(String msg) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("_checkReadable");
+ if (impl != null) {
+ PyObject pymsg = msg == null ? Py.None : new PyString(msg);
+ impl.__get__(this, self_type).__call__(pymsg);
+ } else {
+ super._checkReadable(msg);
+ }
+ }
+
+ @Override
+ public boolean writable() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("writable");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__().__nonzero__();
+ } else {
+ return super.writable();
+ }
+ }
+
+ @Override
+ public void _checkWritable(String msg) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("_checkWritable");
+ if (impl != null) {
+ PyObject pymsg = msg == null ? Py.None : new PyString(msg);
+ impl.__get__(this, self_type).__call__(pymsg);
+ } else {
+ super._checkWritable(msg);
+ }
+ }
+
+ // Note that closed is a property not a predicate, so no derived method.
+
+ @Override
+ public void _checkClosed(String msg) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("_checkClosed");
+ if (impl != null) {
+ PyObject pymsg = msg == null ? Py.None : new PyString(msg);
+ impl.__get__(this, self_type).__call__(pymsg);
+ } else {
+ super._checkClosed(msg);
+ }
+ }
+
+ @Override
+ public boolean __exit__(PyObject type, PyObject value, PyObject traceback) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__exit__");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__(type, value, traceback).__nonzero__();
+ } else {
+ return super.__exit__(type, value, traceback);
+ }
+ }
+
+ @Override
+ public boolean isatty() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("isatty");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__().__nonzero__();
+ } else {
+ return super.isatty();
+ }
+ }
+
+ @Override
+ public PyObject readline() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("readline");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__(Py.None);
+ } else {
+ return super.readline();
+ }
+ }
+
+ @Override
+ public PyObject readline(int limit) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("readline");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__(Py.newInteger(limit));
+ } else {
+ return super.readline(limit);
+ }
+ }
+
+ @Override
+ public PyObject readlines(PyObject hint) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("readlines");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(hint);
+ return res;
+ } else {
+ return super.readlines(hint);
+ }
+ }
+
+ @Override
+ public void writelines(PyObject lines) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("writelines");
+ if (impl != null) {
+ impl.__get__(this, self_type).__call__(lines);
+ } else {
+ super.writelines(lines);
+ }
+ }
+
+}
diff --git a/src/org/python/modules/_io/_io.java b/src/org/python/modules/_io/_io.java
--- a/src/org/python/modules/_io/_io.java
+++ b/src/org/python/modules/_io/_io.java
@@ -29,6 +29,8 @@
dict.__setitem__("__name__", new PyString("_io"));
dict.__setitem__("__doc__", new PyString(__doc__));
dict.__setitem__("DEFAULT_BUFFER_SIZE", DEFAULT_BUFFER_SIZE);
+
+ dict.__setitem__("_IOBase", PyIOBase.TYPE);
dict.__setitem__("FileIO", PyFileIO.TYPE);
// Define UnsupportedOperation exception by constructing the type
diff --git a/src/templates/_io._IOBase.derived b/src/templates/_io._IOBase.derived
new file mode 100644
--- /dev/null
+++ b/src/templates/_io._IOBase.derived
@@ -0,0 +1,210 @@
+base_class: PyIOBase
+want_dict: false
+ctr:
+no_toString: true
+incl: object
+unary1: __enter__
+unary1: fileno
+
+rest:
+ // Hand-crafted in _io._IOBase.derived
+
+ public long seek(long pos, int whence) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("seek");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__(Py.newLong(pos), Py.newInteger(whence))
+ .asLong();
+ } else {
+ return super.seek(pos, whence);
+ }
+ }
+
+ public long tell() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("tell");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__().asLong();
+ } else {
+ return super.tell();
+ }
+ }
+
+ public long truncate(long size) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("truncate");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__(Py.newLong(size)).asLong();
+ } else {
+ return super.truncate(size);
+ }
+ }
+
+ public long truncate() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("truncate");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__().asLong();
+ } else {
+ return super.truncate();
+ }
+ }
+
+ public void flush() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("flush");
+ if (impl != null) {
+ impl.__get__(this, self_type).__call__();
+ } else {
+ super.flush();
+ }
+ }
+
+ public void close() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("close");
+ if (impl != null) {
+ impl.__get__(this, self_type).__call__();
+ } else {
+ super.close();
+ }
+ }
+
+ public boolean seekable() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("seekable");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__().__nonzero__();
+ } else {
+ return super.seekable();
+ }
+ }
+
+ public void _checkSeekable(String msg) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("_checkSeekable");
+ if (impl != null) {
+ PyObject pymsg = msg == null ? Py.None : new PyString(msg);
+ impl.__get__(this, self_type).__call__(pymsg);
+ } else {
+ super._checkSeekable(msg);
+ }
+ }
+
+ public boolean readable() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("readable");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__().__nonzero__();
+ } else {
+ return super.readable();
+ }
+ }
+
+ public void _checkReadable(String msg) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("_checkReadable");
+ if (impl != null) {
+ PyObject pymsg = msg == null ? Py.None : new PyString(msg);
+ impl.__get__(this, self_type).__call__(pymsg);
+ } else {
+ super._checkReadable(msg);
+ }
+ }
+
+ public boolean writable() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("writable");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__().__nonzero__();
+ } else {
+ return super.writable();
+ }
+ }
+
+ public void _checkWritable(String msg) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("_checkWritable");
+ if (impl != null) {
+ PyObject pymsg = msg == null ? Py.None : new PyString(msg);
+ impl.__get__(this, self_type).__call__(pymsg);
+ } else {
+ super._checkWritable(msg);
+ }
+ }
+
+ // Note that closed is a property not a predicate, so no derived method.
+
+ public void _checkClosed(String msg) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("_checkClosed");
+ if (impl != null) {
+ PyObject pymsg = msg == null ? Py.None : new PyString(msg);
+ impl.__get__(this, self_type).__call__(pymsg);
+ } else {
+ super._checkClosed(msg);
+ }
+ }
+
+ public boolean __exit__(PyObject type, PyObject value, PyObject traceback) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("__exit__");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__(type, value, traceback).__nonzero__();
+ } else {
+ return super.__exit__(type, value, traceback);
+ }
+ }
+
+ public boolean isatty() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("isatty");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__().__nonzero__();
+ } else {
+ return super.isatty();
+ }
+ }
+
+ public PyObject readline() {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("readline");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__(Py.None);
+ } else {
+ return super.readline();
+ }
+ }
+
+ public PyObject readline(int limit) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("readline");
+ if (impl != null) {
+ return impl.__get__(this, self_type).__call__(Py.newInteger(limit));
+ } else {
+ return super.readline(limit);
+ }
+ }
+
+ public PyObject readlines(PyObject hint) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("readlines");
+ if (impl != null) {
+ PyObject res = impl.__get__(this, self_type).__call__(hint);
+ return res;
+ } else {
+ return super.readlines(hint);
+ }
+ }
+
+ public void writelines(PyObject lines) {
+ PyType self_type = getType();
+ PyObject impl = self_type.lookup("writelines");
+ if (impl != null) {
+ impl.__get__(this, self_type).__call__(lines);
+ } else {
+ super.writelines(lines);
+ }
+ }
+
+
diff --git a/src/templates/mappings b/src/templates/mappings
--- a/src/templates/mappings
+++ b/src/templates/mappings
@@ -6,6 +6,7 @@
# will map str.expose to org.python.core.PyString. Many classes will have 2
# lines; one for their expose, and one for their derived class.
+_io._IOBase.derived:org.python.modules._io.PyIOBaseDerived
BaseException.derived:org.python.core.PyBaseExceptionDerived
ClasspathPyImporter.derived:org.python.core.ClasspathPyImporterDerived
PyFileIO.derived:org.python.modules._io.PyFileIODerived
--
Repository URL: http://hg.python.org/jython
More information about the Jython-checkins
mailing list