[Python-checkins] r68578 - in sandbox/trunk/io-c: _bufferedio.c _iomodule.h io.c test_io.py
antoine.pitrou
python-checkins at python.org
Tue Jan 13 21:45:42 CET 2009
Author: antoine.pitrou
Date: Tue Jan 13 21:45:41 2009
New Revision: 68578
Log:
Define our own PyNumber_AsOff_t with the expected behaviour
Modified:
sandbox/trunk/io-c/_bufferedio.c
sandbox/trunk/io-c/_iomodule.h
sandbox/trunk/io-c/io.c
sandbox/trunk/io-c/test_io.py
Modified: sandbox/trunk/io-c/_bufferedio.c
==============================================================================
--- sandbox/trunk/io-c/_bufferedio.c (original)
+++ sandbox/trunk/io-c/_bufferedio.c Tue Jan 13 21:45:41 2009
@@ -737,10 +737,10 @@
{
Py_off_t target, n;
int whence = 0;
- PyObject *res = NULL;
+ PyObject *targetobj, *res = NULL;
CHECK_INITIALIZED(self)
- if (!PyArg_ParseTuple(args, OFF_T_ARG "|i:seek", &target, &whence)) {
+ if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
return NULL;
}
@@ -749,6 +749,9 @@
"whence must be between 0 and 2, not %d", whence);
return NULL;
}
+ target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
+ if (target == -1 && PyErr_Occurred())
+ return NULL;
ENTER_BUFFERED(self)
Modified: sandbox/trunk/io-c/_iomodule.h
==============================================================================
--- sandbox/trunk/io-c/_iomodule.h (original)
+++ sandbox/trunk/io-c/_iomodule.h Tue Jan 13 21:45:41 2009
@@ -53,36 +53,46 @@
PyObject *PyExc_BlockingIOError;
+/*
+ * Offset type for positioning.
+ */
+
#if defined(MS_WIN64) || defined(MS_WINDOWS)
/* Windows uses long long for offsets */
typedef PY_LONG_LONG Py_off_t;
-# define PyNumber_AsOff_t(o, exc) PyLong_AsLongLong(o)
-# define PyLong_FromOff_t PyLong_FromLongLong
-# define OFF_T_ARG "L"
+# define PyLong_AsOff_t PyLong_AsLongLong
+# define PyLong_FromOff_t PyLong_FromLongLong
+# define PY_OFF_T_MAX PY_LLONG_MAX
+# define PY_OFF_T_MIN PY_LLONG_MIN
#else
/* Other platforms use off_t */
typedef off_t Py_off_t;
#if (SIZEOF_OFF_T == SIZEOF_SIZE_T)
-# define PyNumber_AsOff_t PyNumber_AsSsize_t
-# define PyLong_FromOff_t PyLong_FromSsize_t
-# define OFF_T_ARG "n"
+# define PyLong_AsOff_t PyLong_AsSsize_t
+# define PyLong_FromOff_t PyLong_FromSsize_t
+# define PY_OFF_T_MAX PY_SSIZE_T_MAX
+# define PY_OFF_T_MIN PY_SSIZE_T_MIN
#elif (SIZEOF_OFF_T == SIZEOF_LONG_LONG)
-# define PyNumber_AsOff_t(o, exc) PyLong_AsLongLong(o)
-# define PyLong_FromOff_t PyLong_FromLongLong
-# define OFF_T_ARG "L"
+# define PyLong_AsOff_t PyLong_AsLongLong
+# define PyLong_FromOff_t PyLong_FromLongLong
+# define PY_OFF_T_MAX PY_LLONG_MAX
+# define PY_OFF_T_MIN PY_LLONG_MIN
#elif (SIZEOF_OFF_T == SIZEOF_LONG)
-# define PyNumber_AsOff_t(o, exc) PyLong_AsLong(o)
-# define PyLong_FromOff_t PyLong_FromLong
-# define OFF_T_ARG "l"
+# define PyLong_AsOff_t PyLong_AsLong
+# define PyLong_FromOff_t PyLong_FromLong
+# define PY_OFF_T_MAX LONG_MAX
+# define PY_OFF_T_MIN LONG_MIN
#else
# error off_t does not match either size_t, long, or long long!
#endif
#endif
+extern Py_off_t PyNumber_AsOff_t(PyObject *item, PyObject *err);
+
/* Implementation details */
extern PyObject *_PyIO_str_close;
Modified: sandbox/trunk/io-c/io.c
==============================================================================
--- sandbox/trunk/io-c/io.c (original)
+++ sandbox/trunk/io-c/io.c Tue Jan 13 21:45:41 2009
@@ -509,6 +509,53 @@
return NULL;
}
+/*
+ * Private helpers for the io module.
+ */
+
+Py_off_t
+PyNumber_AsOff_t(PyObject *item, PyObject *err)
+{
+ Py_off_t result;
+ PyObject *runerr;
+ PyObject *value = PyNumber_Index(item);
+ if (value == NULL)
+ return -1;
+
+ /* We're done if PyLong_AsSsize_t() returns without error. */
+ result = PyLong_AsOff_t(value);
+ if (result != -1 || !(runerr = PyErr_Occurred()))
+ goto finish;
+
+ /* Error handling code -- only manage OverflowError differently */
+ if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError))
+ goto finish;
+
+ PyErr_Clear();
+ /* If no error-handling desired then the default clipping
+ is sufficient.
+ */
+ if (!err) {
+ assert(PyLong_Check(value));
+ /* Whether or not it is less than or equal to
+ zero is determined by the sign of ob_size
+ */
+ if (_PyLong_Sign(value) < 0)
+ result = PY_OFF_T_MIN;
+ else
+ result = PY_OFF_T_MAX;
+ }
+ else {
+ /* Otherwise replace the error with caller's error object. */
+ PyErr_Format(err,
+ "cannot fit '%.200s' into an offset-sized integer",
+ item->ob_type->tp_name);
+ }
+
+ finish:
+ Py_DECREF(value);
+ return result;
+}
/*
* Module definition
Modified: sandbox/trunk/io-c/test_io.py
==============================================================================
--- sandbox/trunk/io-c/test_io.py (original)
+++ sandbox/trunk/io-c/test_io.py Tue Jan 13 21:45:41 2009
@@ -177,8 +177,7 @@
self.assertEqual(f.tell(), 13)
self.assertEqual(f.truncate(12), 12)
self.assertEqual(f.tell(), 12)
- # Disabled until PyNumber_AsOff_t exists
- #self.assertRaises(TypeError, f.seek, 0.0)
+ self.assertRaises(TypeError, f.seek, 0.0)
def read_ops(self, f, buffered=False):
data = f.read(5)
@@ -200,8 +199,7 @@
self.assertEqual(f.seek(-6, 1), 5)
self.assertEqual(f.read(5), b" worl")
self.assertEqual(f.tell(), 10)
- # Disabled until PyNumber_AsOff_t exists
- #self.assertRaises(TypeError, f.seek, 0.0)
+ self.assertRaises(TypeError, f.seek, 0.0)
if buffered:
f.seek(0)
self.assertEqual(f.read(), b"hello world\n")
@@ -915,8 +913,7 @@
rw.seek(2, 1)
self.assertEquals(7, rw.tell())
self.assertEquals(b"fl", rw.read(11))
- # Disabled until PyNumber_AsOff_t exists
- #self.assertRaises(TypeError, rw.seek, 0.0)
+ self.assertRaises(TypeError, rw.seek, 0.0)
def check_flush_and_read(self, read_func):
raw = io.BytesIO(b"abcdefghi")
More information about the Python-checkins
mailing list