Prevent `str` from converting to `Vec<&str>` and `Vec<String>` (#2500)

This commit is contained in:
Jérome Eertmans 2022-07-13 22:44:44 +02:00 committed by GitHub
parent adfc83681d
commit 308ffa25b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 2 deletions

View File

@ -40,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Prevent multiple `#[pymethods]` with the same name for a single `#[pyclass]`. [#2399](https://github.com/PyO3/pyo3/pull/2399)
- Fixup `lib_name` when using `PYO3_CONFIG_FILE`. [#2404](https://github.com/PyO3/pyo3/pull/2404)
- Iterators over `PySet` and `PyDict` will now panic if the underlying collection is mutated during the iteration. [#2380](https://github.com/PyO3/pyo3/pull/2380)
- `FromPyObject::extract` now raises an error if source type is `PyString` and target type is `Vec<T>`. [#2500](https://github.com/PyO3/pyo3/pull/2500)
### Fixed

View File

@ -1,8 +1,8 @@
// Copyright (c) 2017-present PyO3 Project and Contributors
use crate::err::{self, PyDowncastError, PyErr, PyResult};
use crate::exceptions::PyValueError;
use crate::internal_tricks::get_ssize_index;
use crate::types::{PyAny, PyList, PyTuple};
use crate::types::{PyAny, PyList, PyString, PyTuple};
use crate::{ffi, PyNativeType, ToPyObject};
use crate::{AsPyPointer, IntoPyPointer, Py, Python};
use crate::{FromPyObject, PyTryFrom};
@ -270,6 +270,9 @@ where
T: FromPyObject<'a>,
{
fn extract(obj: &'a PyAny) -> PyResult<Self> {
if let Ok(true) = obj.is_instance_of::<PyString>() {
return Err(PyValueError::new_err("Can't extract `str` to `Vec`"));
}
extract_sequence(obj)
}
}
@ -364,6 +367,19 @@ mod tests {
assert!(<PySequence as PyTryFrom>::try_from(v.to_object(py).as_ref(py)).is_ok());
});
}
#[test]
fn test_strings_cannot_be_extracted_to_vec() {
Python::with_gil(|py| {
let v = "London Calling";
let ob = v.to_object(py);
assert!(ob.extract::<Vec<&str>>(py).is_err());
assert!(ob.extract::<Vec<String>>(py).is_err());
assert!(ob.extract::<Vec<char>>(py).is_err());
});
}
#[test]
fn test_seq_empty() {
Python::with_gil(|py| {