From bae07c9baf3e53164de6f85a18ce747a76b9ffde Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Mon, 8 Oct 2007 02:46:15 +0000 Subject: Breaking ground for PEP 3137 implementation: Get rid of buffer(). Use memoryview() in its place where possible. In a few places, do things a bit different, because memoryview() can't slice (yet). --- Lib/_abcoll.py | 2 +- Lib/ctypes/test/test_array_in_pointer.py | 2 +- Lib/ctypes/test/test_byteswap.py | 2 +- Lib/ctypes/test/test_strings.py | 12 +++---- Lib/sqlite3/dbapi2.py | 2 +- Lib/sqlite3/test/dbapi.py | 2 +- Lib/sqlite3/test/types.py | 6 ++-- Lib/sqlite3/test/userfunctions.py | 17 +++++----- Lib/subprocess.py | 10 ++++-- Lib/test/test_array.py | 2 +- Lib/test/test_buffer.py | 56 -------------------------------- Lib/test/test_bytes.py | 16 ++++----- Lib/test/test_io.py | 2 +- Lib/test/test_marshal.py | 4 +-- Lib/test/test_repr.py | 6 ---- Lib/test/test_struct.py | 14 ++++---- Lib/test/test_types.py | 48 --------------------------- Lib/test/test_unicode.py | 2 +- Lib/types.py | 2 -- Modules/_ctypes/_ctypes.c | 18 +++------- Modules/_sqlite/connection.c | 22 ++++--------- Modules/_sqlite/cursor.c | 7 ++-- Modules/_sqlite/statement.c | 14 ++++---- Python/bltinmodule.c | 3 +- 24 files changed, 72 insertions(+), 199 deletions(-) delete mode 100644 Lib/test/test_buffer.py diff --git a/Lib/_abcoll.py b/Lib/_abcoll.py index 5fbb219..2a9676f 100644 --- a/Lib/_abcoll.py +++ b/Lib/_abcoll.py @@ -491,7 +491,7 @@ class Sequence(metaclass=ABCMeta): Sequence.register(tuple) Sequence.register(basestring) -Sequence.register(buffer) +Sequence.register(memoryview) class MutableSequence(Sequence): diff --git a/Lib/ctypes/test/test_array_in_pointer.py b/Lib/ctypes/test/test_array_in_pointer.py index 0b46fb9..2b939f0 100644 --- a/Lib/ctypes/test/test_array_in_pointer.py +++ b/Lib/ctypes/test/test_array_in_pointer.py @@ -6,7 +6,7 @@ import re def dump(obj): # helper function to dump memory contents in hex, with a hyphen # between the bytes. - h = str(hexlify(buffer(obj))) + h = str(hexlify(memoryview(obj))) return re.sub(r"(..)", r"\1-", h)[:-1] diff --git a/Lib/ctypes/test/test_byteswap.py b/Lib/ctypes/test/test_byteswap.py index 342e18e..dab9722 100644 --- a/Lib/ctypes/test/test_byteswap.py +++ b/Lib/ctypes/test/test_byteswap.py @@ -4,7 +4,7 @@ from binascii import hexlify from ctypes import * def bin(s): - return str(hexlify(buffer(s))).upper() + return str(hexlify(memoryview(s))).upper() # Each *simple* type that supports different byte orders has an # __ctype_be__ attribute that specifies the same type in BIG ENDIAN diff --git a/Lib/ctypes/test/test_strings.py b/Lib/ctypes/test/test_strings.py index ad3c49e..0a06332 100644 --- a/Lib/ctypes/test/test_strings.py +++ b/Lib/ctypes/test/test_strings.py @@ -30,17 +30,17 @@ class StringArrayTestCase(unittest.TestCase): buf.value = "Hello, World" self.failUnlessEqual(buf.value, "Hello, World") - self.failUnlessRaises(TypeError, setattr, buf, "value", buffer("Hello, World")) - self.assertRaises(TypeError, setattr, buf, "value", buffer("abc")) - self.assertRaises(ValueError, setattr, buf, "raw", buffer("x" * 100)) + self.failUnlessRaises(TypeError, setattr, buf, "value", memoryview(b"Hello, World")) + self.assertRaises(TypeError, setattr, buf, "value", memoryview(b"abc")) + self.assertRaises(ValueError, setattr, buf, "raw", memoryview(b"x" * 100)) def test_c_buffer_raw(self): buf = c_buffer(32) - buf.raw = buffer(b"Hello, World") + buf.raw = memoryview(b"Hello, World") self.failUnlessEqual(buf.value, "Hello, World") - self.assertRaises(TypeError, setattr, buf, "value", buffer("abc")) - self.assertRaises(ValueError, setattr, buf, "raw", buffer("x" * 100)) + self.assertRaises(TypeError, setattr, buf, "value", memoryview(b"abc")) + self.assertRaises(ValueError, setattr, buf, "raw", memoryview(b"x" * 100)) def test_param_1(self): BUF = c_char * 4 diff --git a/Lib/sqlite3/dbapi2.py b/Lib/sqlite3/dbapi2.py index 7eb28e8..52fb4ae 100644 --- a/Lib/sqlite3/dbapi2.py +++ b/Lib/sqlite3/dbapi2.py @@ -50,7 +50,7 @@ def TimestampFromTicks(ticks): version_info = tuple([int(x) for x in version.split(".")]) sqlite_version_info = tuple([int(x) for x in sqlite_version.split(".")]) -Binary = buffer +Binary = memoryview def register_adapters_and_converters(): def adapt_date(val): diff --git a/Lib/sqlite3/test/dbapi.py b/Lib/sqlite3/test/dbapi.py index faf31b1..6d4c4fe 100644 --- a/Lib/sqlite3/test/dbapi.py +++ b/Lib/sqlite3/test/dbapi.py @@ -593,7 +593,7 @@ class ConstructorTests(unittest.TestCase): ts = sqlite.TimestampFromTicks(42) def CheckBinary(self): - b = sqlite.Binary(chr(0) + "'") + b = sqlite.Binary(b"\0'") class ExtensionTests(unittest.TestCase): def CheckScriptStringSql(self): diff --git a/Lib/sqlite3/test/types.py b/Lib/sqlite3/test/types.py index 20f0093..1377835 100644 --- a/Lib/sqlite3/test/types.py +++ b/Lib/sqlite3/test/types.py @@ -62,7 +62,7 @@ class SqliteTypeTests(unittest.TestCase): self.failUnlessEqual(row[0], val) def CheckBlob(self): - val = buffer(b"Guglhupf") + val = memoryview(b"Guglhupf") self.cur.execute("insert into test(b) values (?)", (val,)) self.cur.execute("select b from test") row = self.cur.fetchone() @@ -203,7 +203,7 @@ class DeclTypesTests(unittest.TestCase): def CheckBlob(self): # default - val = buffer(b"Guglhupf") + val = memoryview(b"Guglhupf") self.cur.execute("insert into test(bin) values (?)", (val,)) self.cur.execute("select bin from test") row = self.cur.fetchone() @@ -305,7 +305,7 @@ class BinaryConverterTests(unittest.TestCase): def CheckBinaryInputForConverter(self): testdata = b"abcdefg" * 10 - result = self.con.execute('select ? as "x [bin]"', (buffer(bz2.compress(testdata)),)).fetchone()[0] + result = self.con.execute('select ? as "x [bin]"', (memoryview(bz2.compress(testdata)),)).fetchone()[0] self.failUnlessEqual(testdata, result) class DateTimeTests(unittest.TestCase): diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py index ab4f756..994057e 100644 --- a/Lib/sqlite3/test/userfunctions.py +++ b/Lib/sqlite3/test/userfunctions.py @@ -36,7 +36,7 @@ def func_returnfloat(): def func_returnnull(): return None def func_returnblob(): - return buffer(b"blob") + return b"blob" def func_raiseexception(): 5/0 @@ -49,7 +49,7 @@ def func_isfloat(v): def func_isnone(v): return type(v) is type(None) def func_isblob(v): - return type(v) is buffer + return isinstance(v, (bytes, memoryview)) class AggrNoStep: def __init__(self): @@ -100,7 +100,8 @@ class AggrCheckType: self.val = None def step(self, whichType, val): - theType = {"str": str, "int": int, "float": float, "None": type(None), "blob": buffer} + theType = {"str": str, "int": int, "float": float, "None": type(None), + "blob": bytes} self.val = int(theType[whichType] is type(val)) def finalize(self): @@ -196,8 +197,8 @@ class FunctionTests(unittest.TestCase): cur = self.con.cursor() cur.execute("select returnblob()") val = cur.fetchone()[0] - self.failUnlessEqual(type(val), buffer) - self.failUnlessEqual(val, buffer(b"blob")) + self.failUnlessEqual(type(val), bytes) + self.failUnlessEqual(val, memoryview(b"blob")) def CheckFuncException(self): cur = self.con.cursor() @@ -234,7 +235,7 @@ class FunctionTests(unittest.TestCase): def CheckParamBlob(self): cur = self.con.cursor() - cur.execute("select isblob(?)", (buffer(b"blob"),)) + cur.execute("select isblob(?)", (memoryview(b"blob"),)) val = cur.fetchone()[0] self.failUnlessEqual(val, 1) @@ -252,7 +253,7 @@ class AggregateTests(unittest.TestCase): ) """) cur.execute("insert into test(t, i, f, n, b) values (?, ?, ?, ?, ?)", - ("foo", 5, 3.14, None, buffer(b"blob"),)) + ("foo", 5, 3.14, None, memoryview(b"blob"),)) self.con.create_aggregate("nostep", 1, AggrNoStep) self.con.create_aggregate("nofinalize", 1, AggrNoFinalize) @@ -344,7 +345,7 @@ class AggregateTests(unittest.TestCase): def CheckAggrCheckParamBlob(self): cur = self.con.cursor() - cur.execute("select checkType('blob', ?)", (buffer(b"blob"),)) + cur.execute("select checkType('blob', ?)", (memoryview(b"blob"),)) val = cur.fetchone()[0] self.failUnlessEqual(val, 1) diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 362d59a..a34eb29 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -1041,8 +1041,11 @@ class Popen(object): def _communicate(self, input): - if isinstance(input, str): # Unicode - input = input.encode("utf-8") # XXX What else? + if self.stdin: + if isinstance(input, str): # Unicode + input = input.encode("utf-8") # XXX What else? + if not isinstance(input, (bytes, str8)): + input = bytes(input) read_set = [] write_set = [] stdout = None # Return @@ -1071,7 +1074,8 @@ class Popen(object): # When select has indicated that the file is writable, # we can write up to PIPE_BUF bytes without risk # blocking. POSIX defines PIPE_BUF >= 512 - bytes_written = os.write(self.stdin.fileno(), buffer(input, input_offset, 512)) + chunk = input[input_offset : input_offset + 512] + bytes_written = os.write(self.stdin.fileno(), chunk) input_offset += bytes_written if input_offset >= len(input): self.stdin.close() diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py index db029f3..5e4bde6 100755 --- a/Lib/test/test_array.py +++ b/Lib/test/test_array.py @@ -708,7 +708,7 @@ class BaseTest(unittest.TestCase): def test_buffer(self): a = array.array(self.typecode, self.example) - b = bytes(buffer(a)) + b = bytes(memoryview(a)) self.assertEqual(b[0], a.tostring()[0]) def test_weakref(self): diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py deleted file mode 100644 index 834c05b..0000000 --- a/Lib/test/test_buffer.py +++ /dev/null @@ -1,56 +0,0 @@ -"""Unit tests for buffer objects. - -For now, we just test (the brand new) rich comparison. - -""" - -import unittest -from test import test_support - -class BufferTests(unittest.TestCase): - - def test_comparison(self): - a = buffer("a.b.c") - b = buffer("a.b" + ".c") - self.assert_(a == b) - self.assert_(a <= b) - self.assert_(a >= b) - self.assert_(a == "a.b.c") - self.assert_(a <= "a.b.c") - self.assert_(a >= "a.b.c") - b = buffer("a.b.c.d") - self.assert_(a != b) - self.assert_(a <= b) - self.assert_(a < b) - self.assert_(a != "a.b.c.d") - self.assert_(a < "a.b.c.d") - self.assert_(a <= "a.b.c.d") - b = buffer("a.b") - self.assert_(a != b) - self.assert_(a >= b) - self.assert_(a > b) - self.assert_(a != "a.b") - self.assert_(a > "a.b") - self.assert_(a >= "a.b") - b = object() - self.assert_(a != b) - self.failIf(a == b) - self.assertRaises(TypeError, lambda: a < b) - - def test_extended_getslice(self): - # Test extended slicing by comparing with list slicing. - s = bytes(range(255, -1, -1)) - b = buffer(s) - indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300) - for start in indices: - for stop in indices: - # Skip step 0 (invalid) - for step in indices[1:]: - self.assertEqual(b[start:stop:step], - s[start:stop:step]) - -def test_main(): - test_support.run_unittest(BufferTests) - -if __name__ == "__main__": - test_main() diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index cfcd282..61950cc 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -343,7 +343,7 @@ class BytesTest(unittest.TestCase): def test_from_buffer(self): sample = str8("Hello world\n\x80\x81\xfe\xff") - buf = buffer(sample) + buf = memoryview(sample) b = bytes(buf) self.assertEqual(b, bytes(map(ord, sample))) @@ -456,8 +456,8 @@ class BytesTest(unittest.TestCase): b = bytes([0x1a, 0x2b, 0x30]) self.assertEquals(bytes.fromhex('1a2B30'), b) self.assertEquals(bytes.fromhex(' 1A 2B 30 '), b) - self.assertEquals(bytes.fromhex(buffer(b'')), bytes()) - self.assertEquals(bytes.fromhex(buffer(b'0000')), bytes([0, 0])) + self.assertEquals(bytes.fromhex(memoryview(b'')), bytes()) + self.assertEquals(bytes.fromhex(memoryview(b'0000')), bytes([0, 0])) self.assertRaises(ValueError, bytes.fromhex, 'a') self.assertRaises(ValueError, bytes.fromhex, 'rt') self.assertRaises(ValueError, bytes.fromhex, '1a b cd') @@ -630,7 +630,7 @@ class BytesTest(unittest.TestCase): self.assertEqual(b' a bb c '.split(None, 3), [b'a', b'bb', b'c']) def test_split_buffer(self): - self.assertEqual(b'a b'.split(buffer(b' ')), [b'a', b'b']) + self.assertEqual(b'a b'.split(memoryview(b' ')), [b'a', b'b']) def test_split_string_error(self): self.assertRaises(TypeError, b'a b'.split, ' ') @@ -653,7 +653,7 @@ class BytesTest(unittest.TestCase): self.assertEqual(b' a bb c '.rsplit(None, 3), [b'a', b'bb', b'c']) def test_rplit_buffer(self): - self.assertEqual(b'a b'.rsplit(buffer(b' ')), [b'a', b'b']) + self.assertEqual(b'a b'.rsplit(memoryview(b' ')), [b'a', b'b']) def test_rplit_string_error(self): self.assertRaises(TypeError, b'a b'.rsplit, ' ') @@ -707,9 +707,9 @@ class BytesTest(unittest.TestCase): self.assertEqual(b.rstrip(), b' \t\n\r\f\vabc') def test_strip_buffer(self): - self.assertEqual(b'abc'.strip(buffer(b'ac')), b'b') - self.assertEqual(b'abc'.lstrip(buffer(b'ac')), b'bc') - self.assertEqual(b'abc'.rstrip(buffer(b'ac')), b'ab') + self.assertEqual(b'abc'.strip(memoryview(b'ac')), b'b') + self.assertEqual(b'abc'.lstrip(memoryview(b'ac')), b'bc') + self.assertEqual(b'abc'.rstrip(memoryview(b'ac')), b'ab') def test_strip_string_error(self): self.assertRaises(TypeError, b'abc'.strip, 'b') diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 5c30e50..644593d 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -251,7 +251,7 @@ class IOTest(unittest.TestCase): def test_array_writes(self): a = array.array('i', range(10)) - n = len(buffer(a)) + n = len(memoryview(a)) f = io.open(test_support.TESTFN, "wb", 0) self.assertEqual(f.write(a), n) f.close() diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py index 47e610f..3e44886 100644 --- a/Lib/test/test_marshal.py +++ b/Lib/test/test_marshal.py @@ -98,9 +98,9 @@ class StringTestCase(unittest.TestCase, HelperMixin): for s in ["", "Andr\xe8 Previn", "abc", " "*10000]: self.helper(s) - def test_buffer(self): + def test_bytes(self): for s in [b"", b"Andr\xe8 Previn", b"abc", b" "*10000]: - self.helper(buffer(s)) + self.helper(s) class ExceptionTestCase(unittest.TestCase): def test_exceptions(self): diff --git a/Lib/test/test_repr.py b/Lib/test/test_repr.py index 075aca9..8d9e99d 100644 --- a/Lib/test/test_repr.py +++ b/Lib/test/test_repr.py @@ -163,12 +163,6 @@ class ReprTests(unittest.TestCase): eq(r([[[[[[{}]]]]]]), "[[[[[[{}]]]]]]") eq(r([[[[[[[{}]]]]]]]), "[[[[[[[...]]]]]]]") - def test_buffer(self): - # XXX doesn't test buffers with no b_base or read-write buffers (see - # bufferobject.c). The test is fairly incomplete too. Sigh. - x = buffer('foo') - self.failUnless(repr(x).startswith('I', data) vereq(value, 0x12345678) -# Test methods to pack and unpack from buffers rather than strings. +# Test methods to pack and unpack from memoryviews rather than strings. test_unpack_from() test_pack_into() test_pack_into_fn() -test_unpack_with_buffer() +test_unpack_with_memoryview() def test_bool(): for prefix in tuple("<>!=")+('',): diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index a40145b..70c281f 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -203,54 +203,6 @@ class TypesTests(unittest.TestCase): self.assertRaises(TypeError, type, 1, 2) self.assertRaises(TypeError, type, 1, 2, 3, 4) - def test_buffers(self): - self.assertRaises(ValueError, buffer, 'asdf', -1) - self.assertRaises(TypeError, buffer, None) - - a = buffer(b'asdf') - hash(a) - b = a * 5 - if a == b: - self.fail('buffers should not be equal') - if str(b) != ('asdf' * 5): - self.fail('repeated buffer has wrong content') - if str(a * 0) != '': - self.fail('repeated buffer zero times has wrong content') - if str(a + buffer(b'def')) != 'asdfdef': - self.fail('concatenation of buffers yields wrong content') - if str(buffer(a)) != 'asdf': - self.fail('composing buffers failed') - if str(buffer(a, 2)) != 'df': - self.fail('specifying buffer offset failed') - if str(buffer(a, 0, 2)) != 'as': - self.fail('specifying buffer size failed') - if str(buffer(a, 1, 2)) != 'sd': - self.fail('specifying buffer offset and size failed') - self.assertRaises(ValueError, buffer, buffer(b'asdf', 1), -1) - if str(buffer(buffer(b'asdf', 0, 2), 0)) != 'as': - self.fail('composing length-specified buffer failed') - if str(buffer(buffer(b'asdf', 0, 2), 0, 5000)) != 'as': - self.fail('composing length-specified buffer failed') - if str(buffer(buffer(b'asdf', 0, 2), 0, -1)) != 'as': - self.fail('composing length-specified buffer failed') - if str(buffer(buffer(b'asdf', 0, 2), 1, 2)) != 's': - self.fail('composing length-specified buffer failed') - - try: a[1] = 'g' - except TypeError: pass - else: self.fail("buffer assignment should raise TypeError") - - try: a[0:1] = 'g' - except TypeError: pass - else: self.fail("buffer slice assignment should raise TypeError") - - # array.array() returns an object that does not implement a char buffer, - # something which int() uses for conversion. - import array - try: int(buffer(array.array('b'))) - except TypeError: pass - else: self.fail("char buffer (at C level) not working") - def test_main(): run_unittest(TypesTests) diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index 1358419..d33643a 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -713,7 +713,7 @@ class UnicodeTest( if not sys.platform.startswith('java'): self.assertEqual( str( - buffer(b'character buffers are decoded to unicode'), + memoryview(b'character buffers are decoded to unicode'), 'utf-8', 'strict' ), diff --git a/Lib/types.py b/Lib/types.py index 4c49ba3..5c1f249 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -22,8 +22,6 @@ try: except NameError: pass -BufferType = buffer - TupleType = tuple ListType = list DictType = DictionaryType = dict diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index e24a328..22f2cb3 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -739,18 +739,12 @@ CharArray_set_raw(CDataObject *self, PyObject *value) { char *ptr; Py_ssize_t size; - int rel = 0; Py_buffer view; - if (PyBuffer_Check(value)) { - if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0) - return -1; - size = view.len; - ptr = view.buf; - rel = 1; - } else if (-1 == PyString_AsStringAndSize(value, &ptr, &size)) { + if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0) return -1; - } + size = view.len; + ptr = view.buf; if (size > self->b_size) { PyErr_SetString(PyExc_ValueError, "string too long"); @@ -759,12 +753,10 @@ CharArray_set_raw(CDataObject *self, PyObject *value) memcpy(self->b_ptr, ptr, size); - if (rel) - PyObject_ReleaseBuffer(value, &view); + PyObject_ReleaseBuffer(value, &view); return 0; fail: - if (rel) - PyObject_ReleaseBuffer(value, &view); + PyObject_ReleaseBuffer(value, &view); return -1; } diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index e8c28e3..75ccc9a 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -425,16 +425,16 @@ void _pysqlite_set_result(sqlite3_context* context, PyObject* py_val) sqlite3_result_int64(context, (PY_LONG_LONG)longval); } else if (PyFloat_Check(py_val)) { sqlite3_result_double(context, PyFloat_AsDouble(py_val)); - } else if (PyBuffer_Check(py_val)) { + } else if (PyString_Check(py_val)) { + sqlite3_result_text(context, PyString_AsString(py_val), -1, SQLITE_TRANSIENT); + } else if (PyUnicode_Check(py_val)) { + sqlite3_result_text(context, PyUnicode_AsString(py_val), -1, SQLITE_TRANSIENT); + } else if (PyObject_CheckBuffer(py_val)) { if (PyObject_AsCharBuffer(py_val, &buffer, &buflen) != 0) { PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer"); } else { sqlite3_result_blob(context, buffer, buflen, SQLITE_TRANSIENT); } - } else if (PyString_Check(py_val)) { - sqlite3_result_text(context, PyString_AsString(py_val), -1, SQLITE_TRANSIENT); - } else if (PyUnicode_Check(py_val)) { - sqlite3_result_text(context, PyUnicode_AsString(py_val), -1, SQLITE_TRANSIENT); } else { /* TODO: raise error */ } @@ -478,16 +478,8 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_ break; case SQLITE_BLOB: buflen = sqlite3_value_bytes(cur_value); - cur_py_value = PyBuffer_New(buflen); - if (!cur_py_value) { - break; - } - if (PyObject_AsWriteBuffer(cur_py_value, &raw_buffer, &buflen)) { - Py_DECREF(cur_py_value); - cur_py_value = NULL; - break; - } - memcpy(raw_buffer, sqlite3_value_blob(cur_value), buflen); + cur_py_value = PyBytes_FromStringAndSize( + sqlite3_value_blob(cur_value), buflen); break; case SQLITE_NULL: default: diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index c468754..638cbe2 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -380,14 +380,11 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) } else { /* coltype == SQLITE_BLOB */ nbytes = sqlite3_column_bytes(self->statement->st, i); - buffer = PyBuffer_New(nbytes); + buffer = PyBytes_FromStringAndSize( + sqlite3_column_blob(self->statement->st, i), nbytes); if (!buffer) { break; } - if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &nbytes)) { - break; - } - memcpy(raw_buffer, sqlite3_column_blob(self->statement->st, i), nbytes); converted = buffer; } } diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index b1a4e76..9080c9b 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -102,13 +102,6 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec #endif } else if (PyFloat_Check(parameter)) { rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter)); - } else if (PyBuffer_Check(parameter)) { - if (PyObject_AsCharBuffer(parameter, &buffer, &buflen) == 0) { - rc = sqlite3_bind_blob(self->st, pos, buffer, buflen, SQLITE_TRANSIENT); - } else { - PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer"); - rc = -1; - } } else if PyString_Check(parameter) { string = PyString_AsString(parameter); rc = sqlite3_bind_text(self->st, pos, string, -1, SQLITE_TRANSIENT); @@ -118,6 +111,13 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec rc = sqlite3_bind_text(self->st, pos, string, -1, SQLITE_TRANSIENT); Py_DECREF(stringval); + } else if (PyObject_CheckBuffer(parameter)) { + if (PyObject_AsCharBuffer(parameter, &buffer, &buflen) == 0) { + rc = sqlite3_bind_blob(self->st, pos, buffer, buflen, SQLITE_TRANSIENT); + } else { + PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer"); + rc = -1; + } } else { rc = -1; } diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 9179a42..cafffdc 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1787,8 +1787,7 @@ _PyBuiltin_Init(void) SETBUILTIN("True", Py_True); SETBUILTIN("basestring", &PyBaseString_Type); SETBUILTIN("bool", &PyBool_Type); - SETBUILTIN("buffer", &PyBuffer_Type); - SETBUILTIN("memoryview", &PyMemoryView_Type); + SETBUILTIN("memoryview", &PyMemoryView_Type); SETBUILTIN("bytes", &PyBytes_Type); SETBUILTIN("classmethod", &PyClassMethod_Type); #ifndef WITHOUT_COMPLEX -- cgit v0.12