Skip to content

Commit a58d582

Browse files
authored
Implement unsupported ops for sqlite3.Blob (RustPython#6066)
1 parent c4a8051 commit a58d582

File tree

2 files changed

+52
-6
lines changed

2 files changed

+52
-6
lines changed

Lib/test/test_sqlite3/test_dbapi.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,8 +1421,6 @@ def test_blob_set_slice_error(self):
14211421
with self.assertRaises(BufferError):
14221422
self.blob[5:10] = memoryview(b"abcde")[::2]
14231423

1424-
# TODO: RUSTPYTHON
1425-
@unittest.expectedFailure
14261424
def test_blob_sequence_not_supported(self):
14271425
with self.assertRaisesRegex(TypeError, "unsupported operand"):
14281426
self.blob + self.blob

stdlib/src/sqlite.rs

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> {
2020

2121
#[pymodule]
2222
mod _sqlite {
23+
use crossbeam_utils::atomic::AtomicCell;
2324
use libsqlite3_sys::{
2425
SQLITE_BLOB, SQLITE_DETERMINISTIC, SQLITE_FLOAT, SQLITE_INTEGER, SQLITE_NULL,
2526
SQLITE_OPEN_CREATE, SQLITE_OPEN_READWRITE, SQLITE_OPEN_URI, SQLITE_TEXT, SQLITE_TRACE_STMT,
@@ -67,11 +68,14 @@ mod _sqlite {
6768
PySetterValue,
6869
},
6970
object::{Traverse, TraverseFn},
70-
protocol::{PyBuffer, PyIterReturn, PyMappingMethods, PySequence, PySequenceMethods},
71+
protocol::{
72+
PyBuffer, PyIterReturn, PyMappingMethods, PyNumberMethods, PySequence,
73+
PySequenceMethods,
74+
},
7175
sliceable::{SaturatedSliceIter, SliceableSequenceOp},
7276
types::{
73-
AsMapping, AsSequence, Callable, Comparable, Constructor, Hashable, IterNext, Iterable,
74-
PyComparisonOp, SelfIter, Unconstructible,
77+
AsMapping, AsNumber, AsSequence, Callable, Comparable, Constructor, Hashable, IterNext,
78+
Iterable, PyComparisonOp, SelfIter, Unconstructible,
7579
},
7680
utils::ToCString,
7781
};
@@ -2058,7 +2062,7 @@ mod _sqlite {
20582062
}
20592063
}
20602064

2061-
#[pyclass(with(AsMapping, Unconstructible))]
2065+
#[pyclass(with(AsMapping, Unconstructible, AsNumber, AsSequence))]
20622066
impl Blob {
20632067
#[pymethod]
20642068
fn close(&self) {
@@ -2349,6 +2353,50 @@ mod _sqlite {
23492353
}
23502354
}
23512355

2356+
impl AsNumber for Blob {
2357+
fn as_number() -> &'static PyNumberMethods {
2358+
static AS_NUMBER: PyNumberMethods = PyNumberMethods {
2359+
add: Some(|a, b, vm| {
2360+
Err(vm.new_type_error(format!(
2361+
"unsupported operand type(s) for +: '{}' and '{}'",
2362+
a.class().name(),
2363+
b.class().name()
2364+
)))
2365+
}),
2366+
multiply: Some(|a, b, vm| {
2367+
Err(vm.new_type_error(format!(
2368+
"unsupported operand type(s) for *: '{}' and '{}'",
2369+
a.class().name(),
2370+
b.class().name()
2371+
)))
2372+
}),
2373+
..PyNumberMethods::NOT_IMPLEMENTED
2374+
};
2375+
&AS_NUMBER
2376+
}
2377+
}
2378+
2379+
impl AsSequence for Blob {
2380+
fn as_sequence() -> &'static PySequenceMethods {
2381+
static AS_SEQUENCE: PySequenceMethods = PySequenceMethods {
2382+
length: AtomicCell::new(None),
2383+
concat: AtomicCell::new(None),
2384+
repeat: AtomicCell::new(None),
2385+
item: AtomicCell::new(None),
2386+
ass_item: AtomicCell::new(None),
2387+
contains: atomic_func!(|seq, _needle, vm| {
2388+
Err(vm.new_type_error(format!(
2389+
"argument of type '{}' is not iterable",
2390+
seq.obj.class().name(),
2391+
)))
2392+
}),
2393+
inplace_concat: AtomicCell::new(None),
2394+
inplace_repeat: AtomicCell::new(None),
2395+
};
2396+
&AS_SEQUENCE
2397+
}
2398+
}
2399+
23522400
#[pyattr]
23532401
#[pyclass(name)]
23542402
#[derive(Debug, PyPayload)]

0 commit comments

Comments
 (0)