[Jython-checkins] jython: Make attributes closed, mode readonly in _io.FileIO.
jeff.allen
jython-checkins at python.org
Sun Dec 16 01:20:11 CET 2012
http://hg.python.org/jython/rev/9968367fa217
changeset: 6904:9968367fa217
user: Jeff Allen <ja...py at farowl.co.uk>
date: Sat Dec 15 23:59:45 2012 +0000
summary:
Make attributes closed, mode readonly in _io.FileIO.
Removed some skps and other suppression of Jython test failures in test_fileio.
test_io scores unchanged at fail/error/skip = 12/15/99, test_fileio down at
0/1/1, but with concessions to Jython ValueError issue still in place.
files:
Lib/test/test_fileio.py | 22 ++++---
src/org/python/modules/_io/OpenMode.java | 17 +++++-
src/org/python/modules/_io/PyFileIO.java | 5 +
src/org/python/modules/_io/PyIOBase.java | 28 +++++++--
src/org/python/modules/_io/PyRawIOBase.java | 22 ++++++-
5 files changed, 74 insertions(+), 20 deletions(-)
diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py
--- a/Lib/test/test_fileio.py
+++ b/Lib/test/test_fileio.py
@@ -66,10 +66,9 @@
self.assertEqual(f.closed, False)
# verify the attributes are readonly
- #XXX: not read only in Jython?
- ###for attr in 'mode', 'closed':
- ### self.assertRaises((AttributeError, TypeError),
- ### setattr, f, attr, 'oops')
+ for attr in 'mode', 'closed':
+ self.assertRaises((AttributeError, TypeError),
+ setattr, f, attr, 'oops')
def testReadinto(self):
# verify readinto
@@ -112,9 +111,9 @@
f.close()
self.assertTrue(f.closed)
- def testMethods(self):
- methods = ['fileno', 'isatty', 'read', 'readinto',
- 'seek', 'tell', 'truncate', 'write', 'seekable',
+ # These methods all accept a call with 0 arguments
+ methods = ['fileno', 'isatty', 'read',
+ 'tell', 'truncate', 'seekable',
'readable', 'writable']
if sys.platform.startswith('atheos'):
methods.remove('truncate')
@@ -127,6 +126,13 @@
# should raise on closed file
self.assertRaises(ValueError, method)
+ # These other methods should be tested using a specific call
+ # in case the test for number of arguments comes first.
+ b = bytearray()
+ self.assertRaises(ValueError, self.f.readinto, b )
+ self.assertRaises(ValueError, self.f.seek, 0)
+ self.assertRaises(ValueError, self.f.write, b )
+
def testOpendir(self):
# Issue 3703: opening a directory should fill the errno
# Windows always returns "[Errno 13]: Permission denied
@@ -188,7 +194,6 @@
return wrapper
- @unittest.skipIf(is_jython, "FIXME: not working in Jython")
@ClosedFDRaises
def testErrnoOnClose(self, f):
f.close()
@@ -307,7 +312,6 @@
self.assertEqual(f.seekable(), False)
self.assertEqual(f.isatty(), True)
- @unittest.skipIf(is_jython, "FIXME: not working in Jython")
def testModeStrings(self):
# check invalid mode strings
for mode in ("", "aU", "wU+", "rw", "rt"):
diff --git a/src/org/python/modules/_io/OpenMode.java b/src/org/python/modules/_io/OpenMode.java
--- a/src/org/python/modules/_io/OpenMode.java
+++ b/src/org/python/modules/_io/OpenMode.java
@@ -140,8 +140,21 @@
message = "can't use U and writing mode at once";
} else if (text && binary) {
message = "can't have text and binary mode at once";
- } else if (reading && writing || appending && (reading || writing)) {
- message = "must have exactly one of read/write/append mode";
+ } else {
+ // How many of r/U, w and a were given?
+ int rwa = 0;
+ if (reading) {
+ rwa += 1;
+ }
+ if (writing) {
+ rwa += 1;
+ }
+ if (appending) {
+ rwa += 1;
+ }
+ if (rwa != 1) {
+ message = "must have exactly one of read/write/append mode";
+ }
}
invalid |= (message != null);
}
diff --git a/src/org/python/modules/_io/PyFileIO.java b/src/org/python/modules/_io/PyFileIO.java
--- a/src/org/python/modules/_io/PyFileIO.java
+++ b/src/org/python/modules/_io/PyFileIO.java
@@ -22,6 +22,7 @@
import org.python.expose.ExposedGet;
import org.python.expose.ExposedMethod;
import org.python.expose.ExposedNew;
+import org.python.expose.ExposedSet;
import org.python.expose.ExposedType;
import com.kenai.constantine.platform.Errno;
@@ -60,6 +61,10 @@
/** The mode as a PyString based on readable and writable */
@ExposedGet(doc = "String giving the file mode: 'rb', 'rb+', or 'wb'")
public final PyString mode;
+ @ExposedSet(name="mode")
+ public final void mode_readonly(PyString value) {
+ readonlyAttributeError("mode");
+ }
private static final PyString defaultMode = new PyString("r");
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
@@ -20,6 +20,7 @@
import org.python.expose.ExposedGet;
import org.python.expose.ExposedMethod;
import org.python.expose.ExposedNew;
+import org.python.expose.ExposedSet;
import org.python.expose.ExposedType;
/**
@@ -197,6 +198,10 @@
*/
@ExposedGet(name = "closed", doc = closed_doc)
protected boolean __closed;
+ @ExposedSet(name="closed")
+ public final void closed_readonly(boolean value) {
+ readonlyAttributeError("closed");
+ }
/**
* Close the stream. If closed already, this is a no-op.
@@ -481,7 +486,7 @@
} else if (limit.isIndex()) {
return _readline(limit.asInt());
} else {
- throw Py.TypeError("limit must be an integer");
+ throw tailoredTypeError("integer limit", limit);
}
}
@@ -653,7 +658,7 @@
return new PyList(this);
} else if (!hint.isIndex()) {
- throw Py.TypeError("integer or None expected");
+ throw tailoredTypeError("integer or None", hint);
} else if ((h = hint.asIndex()) <= 0) {
return new PyList(this);
@@ -739,8 +744,7 @@
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()));
+ throw tailoredTypeError("read-write buffer", obj);
}
return new SimpleStringBuffer(PyBUF.SIMPLE, s);
}
@@ -769,11 +773,23 @@
}
} 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()));
+ throw tailoredTypeError("read-write buffer", obj);
}
}
+ /**
+ * Convenience method providing the exception when an argument is not the expected type.
+ * The format is "<b>type</b> argument expected, got <code>type(arg)</code>."
+ *
+ * @param type of thing expected (or could any text)
+ * @param arg argument provided from which actual type will be reported
+ * @return TypeError to throw
+ */
+ protected static PyException tailoredTypeError(String type, PyObject arg){
+ return Py.TypeError(String.format("%s argument expected, got %.100s.",
+ type, arg.getType().fastGetName()));
+ }
+
/*
* Documentation strings: public where they might be useful to a subclass.
*/
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
@@ -54,7 +54,7 @@
* is not ready with further data)
*/
public PyObject read(int n) {
- return _RawIOBase_read(n);
+ return _read(n);
}
/*
@@ -62,8 +62,24 @@
* terms of read(), in case the latter is a more suitable primitive operation, but that would
* lead to nasty recursion in case a subclass doesn't implement either.)
*/
- @ExposedMethod(defaults = "-1", doc = read_doc)
- final PyObject _RawIOBase_read(int n) {
+ @ExposedMethod(defaults = "null", doc = read_doc)
+ final PyObject _RawIOBase_read(PyObject n) {
+ if (n == null || n == Py.None) {
+ return _read(-1);
+ } else if (n.isIndex()) {
+ return _read(n.asInt());
+ } else {
+ throw tailoredTypeError("integer", n);
+ }
+ }
+
+ /**
+ * Implementation of the read() method once the argument has been reduced to an int.
+ * @param n number of bytes to read (if possible)
+ * @return a PyString holding the bytes read or <code>Py.None</code> (when a non-blocking source
+ * is not ready with further data)
+ */
+ private PyObject _read(int n) {
if (n < 0) {
// This is really a request to read the whole stream
--
Repository URL: http://hg.python.org/jython
More information about the Jython-checkins
mailing list