[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

AltStyle によって変換されたページ (->オリジナル) /