Skip to content

Commit dcacdfb

Browse files
authored
Bump Rust to 1.90, bump PyO3 to 0.27.1; bump codspeed to 4.1.1 (#75)
1 parent c62b5ea commit dcacdfb

File tree

8 files changed

+42
-42
lines changed

8 files changed

+42
-42
lines changed

.github/workflows/codspeed.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ permissions:
1313
env:
1414
UV_FROZEN: true
1515
UV_PYTHON: 3.14 # use the latest version of Python because it is faster
16-
RUST_VERSION: "1.87.0"
16+
RUST_VERSION: "1.90.0"
1717

1818
jobs:
1919
benchmarks:

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ permissions:
1212
contents: read
1313

1414
env:
15-
RUST_VERSION: "1.87.0"
15+
RUST_VERSION: "1.90.0"
1616

1717
jobs:
1818
build:

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ name = "libipld"
1313
crate-type = ["rlib", "cdylib"]
1414

1515
[dependencies]
16-
pyo3 = { version = "0.25.1", features = ["generate-import-lib", "anyhow"] }
16+
pyo3 = { version = "0.27.1", features = ["generate-import-lib", "anyhow"] }
1717
python3-dll-a = "0.2.14"
18-
anyhow = "1.0.95"
18+
anyhow = "1.0.100"
1919
libipld = { version = "0.16.0", features = ["dag-cbor"] }
20-
multibase = "0.9.1"
20+
multibase = "0.9.2"
2121
byteorder = "1.5.0"
2222
multihash = "0.18.1"
2323

profiling/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ structopt = "0.3.26"
1111
clap = "4.5.29"
1212

1313
[dependencies.pyo3]
14-
version = "0.25.1"
14+
version = "0.27.1"

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ testing = [
5151
]
5252
codspeed = [
5353
# only run on CI with the latest Python version
54-
'pytest-codspeed==3.2.0; python_version == "3.14" and implementation_name == "cpython"',
54+
'pytest-codspeed==4.1.1; python_version == "3.14" and implementation_name == "cpython"',
5555
]
5656

5757
all = [

pytests/test_decode_car.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def test_decode_car_invalid_header_type() -> None:
4141
header_obj = libipld.encode_dag_cbor('strInsteadOfObj')
4242
libipld.decode_car(header_len + header_obj)
4343

44-
assert "cannot be converted to 'PyDict'" in str(exc_info.value)
44+
assert "cannot be cast as 'dict'" in str(exc_info.value)
4545

4646

4747
def test_decode_car_invalid_header_version_key() -> None:
@@ -77,7 +77,7 @@ def test_decode_car_invalid_header_roots_value_type() -> None:
7777
header_obj = libipld.encode_dag_cbor({'version': 1, 'roots': 123})
7878
libipld.decode_car(header_len + header_obj)
7979

80-
assert "cannot be converted to 'PyList'" in str(exc_info.value)
80+
assert "cannot be cast as 'list'" in str(exc_info.value)
8181

8282

8383
def test_decode_car_invalid_header_roots_value_empty_list() -> None:

src/lib.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use ::libipld::cid::{Cid, Error as CidError, Result as CidResult, Version};
77
use anyhow::{anyhow, Result};
88
use byteorder::{BigEndian, ByteOrder};
99
use multihash::Multihash;
10-
use pyo3::{ffi, prelude::*, types::*, BoundObject, PyObject, Python};
10+
use pyo3::{ffi, prelude::*, types::*, BoundObject, Python};
1111
use pyo3::pybacked::PyBackedStr;
1212

1313
fn cid_hash_to_pydict<'py>(py: Python<'py>, cid: &Cid) -> Bound<'py, PyDict> {
@@ -56,7 +56,7 @@ fn sort_map_keys(keys: &Bound<PyList>, len: usize) -> Result<Vec<(PyBackedStr, u
5656
let mut keys_str = Vec::with_capacity(len);
5757
for i in 0..len {
5858
let item = keys.get_item(i)?;
59-
let key = match item.downcast::<PyString>() {
59+
let key = match item.cast::<PyString>() {
6060
Ok(k) => k.to_owned(),
6161
Err(_) => return Err(anyhow!("Map keys must be strings")),
6262
};
@@ -88,11 +88,11 @@ fn sort_map_keys(keys: &Bound<PyList>, len: usize) -> Result<Vec<(PyBackedStr, u
8888
}
8989

9090
fn get_bytes_from_py_any<'py>(obj: &'py Bound<'py, PyAny>) -> PyResult<&'py [u8]> {
91-
if let Ok(b) = obj.downcast::<PyBytes>() {
91+
if let Ok(b) = obj.cast::<PyBytes>() {
9292
Ok(b.as_bytes())
93-
} else if let Ok(ba) = obj.downcast::<PyByteArray>() {
93+
} else if let Ok(ba) = obj.cast::<PyByteArray>() {
9494
Ok(unsafe { ba.as_bytes() })
95-
} else if let Ok(s) = obj.downcast::<PyString>() {
95+
} else if let Ok(s) = obj.cast::<PyString>() {
9696
Ok(s.to_str()?.as_bytes())
9797
} else {
9898
Err(get_err(
@@ -108,15 +108,15 @@ fn string_new_bound<'py>(py: Python<'py>, s: &[u8]) -> Result<Bound<'py, PyStrin
108108
let ptr = s.as_ptr() as *const c_char;
109109
let len = s.len() as ffi::Py_ssize_t;
110110
unsafe {
111-
Ok(Bound::from_owned_ptr(py, ffi::PyUnicode_FromStringAndSize(ptr, len)).downcast_into_unchecked())
111+
Ok(Bound::from_owned_ptr(py, ffi::PyUnicode_FromStringAndSize(ptr, len)).cast_into_unchecked())
112112
}
113113
}
114114

115115
fn decode_dag_cbor_to_pyobject<R: Read + Seek>(
116116
py: Python,
117117
r: &mut R,
118118
depth: usize,
119-
) -> Result<PyObject> {
119+
) -> Result<Py<PyAny>> {
120120
unsafe {
121121
if depth > ffi::Py_GetRecursionLimit() as usize {
122122
PyErr::new::<pyo3::exceptions::PyRecursionError, _>(
@@ -149,7 +149,7 @@ fn decode_dag_cbor_to_pyobject<R: Read + Seek>(
149149
ffi::PyList_SET_ITEM(ptr, i, decode_dag_cbor_to_pyobject(py, r, depth + 1)?.into_ptr());
150150
}
151151

152-
let list: Bound<'_, PyList> = Bound::from_owned_ptr(py, ptr).downcast_into_unchecked();
152+
let list: Bound<'_, PyList> = Bound::from_owned_ptr(py, ptr).cast_into_unchecked();
153153
list.into_pyobject(py)?.into()
154154
}
155155
}
@@ -268,7 +268,7 @@ fn encode_dag_cbor_from_pyobject<'py, W: Write>(
268268
}
269269

270270
Ok(())
271-
} else if let Ok(l) = obj.downcast::<PyList>() {
271+
} else if let Ok(l) = obj.cast::<PyList>() {
272272
let len = l.len();
273273

274274
encode::write_u64(w, MajorKind::Array, len as u64)?;
@@ -278,7 +278,7 @@ fn encode_dag_cbor_from_pyobject<'py, W: Write>(
278278
}
279279

280280
Ok(())
281-
} else if let Ok(map) = obj.downcast::<PyDict>() {
281+
} else if let Ok(map) = obj.cast::<PyDict>() {
282282
let len = map.len();
283283
let keys = sort_map_keys(&map.keys(), len)?;
284284
let values = map.values();
@@ -294,7 +294,7 @@ fn encode_dag_cbor_from_pyobject<'py, W: Write>(
294294
}
295295

296296
Ok(())
297-
} else if let Ok(f) = obj.downcast::<PyFloat>() {
297+
} else if let Ok(f) = obj.cast::<PyFloat>() {
298298
let v = f.value();
299299
if !v.is_finite() {
300300
return Err(NumberOutOfRange::new::<f64>().into());
@@ -305,7 +305,7 @@ fn encode_dag_cbor_from_pyobject<'py, W: Write>(
305305
w.write_all(&buf)?;
306306

307307
Ok(())
308-
} else if let Ok(b) = obj.downcast::<PyBytes>() {
308+
} else if let Ok(b) = obj.cast::<PyBytes>() {
309309
// FIXME (MarshalX): it's not efficient to try to parse it as CID
310310
let cid = Cid::try_from(b.as_bytes());
311311
if let Ok(_) = cid {
@@ -324,7 +324,7 @@ fn encode_dag_cbor_from_pyobject<'py, W: Write>(
324324
}
325325

326326
Ok(())
327-
} else if let Ok(s) = obj.downcast::<PyString>() {
327+
} else if let Ok(s) = obj.cast::<PyString>() {
328328
let buf = s.to_str()?.as_bytes();
329329

330330
encode::write_u64(w, MajorKind::TextString, buf.len() as u64)?;
@@ -402,7 +402,7 @@ fn read_cid_from_bytes<R: Read>(r: &mut R) -> CidResult<Cid> {
402402
}
403403

404404
#[pyfunction]
405-
pub fn decode_car<'py>(py: Python<'py>, data: &[u8]) -> PyResult<(PyObject, Bound<'py, PyDict>)> {
405+
pub fn decode_car<'py>(py: Python<'py>, data: &[u8]) -> PyResult<(Py<PyAny>, Bound<'py, PyDict>)> {
406406
let buf = &mut BufReader::new(Cursor::new(data));
407407

408408
if let Err(_) = read_u64_leb128(buf) {
@@ -418,15 +418,15 @@ pub fn decode_car<'py>(py: Python<'py>, data: &[u8]) -> PyResult<(PyObject, Boun
418418
));
419419
};
420420

421-
let header = header_obj.downcast_bound::<PyDict>(py)?;
421+
let header = header_obj.cast_bound::<PyDict>(py)?;
422422

423423
let Some(version) = header.get_item("version")? else {
424424
return Err(get_err(
425425
"Failed to read CAR header",
426426
"Version is None".to_string(),
427427
));
428428
};
429-
if version.downcast::<PyInt>()?.extract::<u64>()? != 1 {
429+
if version.cast::<PyInt>()?.extract::<u64>()? != 1 {
430430
return Err(get_err(
431431
"Failed to read CAR header",
432432
"Unsupported version. Version must be 1".to_string(),
@@ -439,7 +439,7 @@ pub fn decode_car<'py>(py: Python<'py>, data: &[u8]) -> PyResult<(PyObject, Boun
439439
"Roots is None".to_string(),
440440
));
441441
};
442-
if roots.downcast::<PyList>()?.len() == 0 {
442+
if roots.cast::<PyList>()?.len() == 0 {
443443
return Err(get_err(
444444
"Failed to read CAR header",
445445
"Roots is empty. Must be at least one".to_string(),
@@ -488,7 +488,7 @@ pub fn decode_car<'py>(py: Python<'py>, data: &[u8]) -> PyResult<(PyObject, Boun
488488
}
489489

490490
#[pyfunction]
491-
pub fn decode_dag_cbor(py: Python, data: &[u8]) -> PyResult<PyObject> {
491+
pub fn decode_dag_cbor(py: Python, data: &[u8]) -> PyResult<Py<PyAny>> {
492492
let mut reader = BufReader::new(Cursor::new(data));
493493
let py_object = decode_dag_cbor_to_pyobject(py, &mut reader, 0);
494494
if let Ok(py_object) = py_object {
@@ -537,7 +537,7 @@ pub fn encode_dag_cbor<'py>(
537537

538538
fn get_cid_from_py_any<'py>(data: &Bound<PyAny>) -> PyResult<Cid> {
539539
let cid: CidResult<Cid>;
540-
if let Ok(s) = data.downcast::<PyString>() {
540+
if let Ok(s) = data.cast::<PyString>() {
541541
cid = Cid::try_from(s.to_str()?);
542542
} else {
543543
cid = Cid::try_from(get_bytes_from_py_any(data)?);

uv.lock

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)