Merge pull request #542 from PyO3/index_bytes

Implement Index for PyBytes
This commit is contained in:
Yuji Kanagawa 2019-07-17 21:22:07 +09:00 committed by GitHub
commit cf8f63cacf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 2 deletions

View File

@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
* `module` argument to `pyclass` macro. [#499](https://github.com/PyO3/pyo3/pull/499) * `module` argument to `pyclass` macro. [#499](https://github.com/PyO3/pyo3/pull/499)
* `py_run!` macro [#512](https://github.com/PyO3/pyo3/pull/512) * `py_run!` macro [#512](https://github.com/PyO3/pyo3/pull/512)
* Use existing fields and methods before calling custom __getattr__. [#505](https://github.com/PyO3/pyo3/pull/512) * Use existing fields and methods before calling custom __getattr__. [#505](https://github.com/PyO3/pyo3/pull/512)
* `PyBytes` can now be indexed just like `Vec<u8>`
### Fixed ### Fixed

View File

@ -11,16 +11,22 @@ use crate::types::PyAny;
use crate::AsPyPointer; use crate::AsPyPointer;
use crate::Python; use crate::Python;
use std::borrow::Cow; use std::borrow::Cow;
use std::ops::Index;
use std::os::raw::c_char; use std::os::raw::c_char;
use std::slice::SliceIndex;
use std::str; use std::str;
/// Represents a Python `string`. /// Represents a Python `string`.
///
/// This type is immutable
#[repr(transparent)] #[repr(transparent)]
pub struct PyString(PyObject); pub struct PyString(PyObject);
pyobject_native_type!(PyString, ffi::PyUnicode_Type, ffi::PyUnicode_Check); pyobject_native_type!(PyString, ffi::PyUnicode_Type, ffi::PyUnicode_Check);
/// Represents a Python `byte` string. /// Represents a Python `bytes`.
///
/// This type is immutable
#[repr(transparent)] #[repr(transparent)]
pub struct PyBytes(PyObject); pub struct PyBytes(PyObject);
@ -120,6 +126,15 @@ impl PyBytes {
} }
} }
/// This is the same way [Vec] is indexed
impl<I: SliceIndex<[u8]>> Index<I> for PyBytes {
type Output = I::Output;
fn index(&self, index: I) -> &Self::Output {
&self.as_bytes()[index]
}
}
/// Converts Rust `str` to Python object. /// Converts Rust `str` to Python object.
/// See `PyString::new` for details on the conversion. /// See `PyString::new` for details on the conversion.
impl ToPyObject for str { impl ToPyObject for str {
@ -203,7 +218,7 @@ impl<'source> FromPyObject<'source> for String {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::PyString; use super::{PyBytes, PyString};
use crate::instance::AsPyRef; use crate::instance::AsPyRef;
use crate::object::PyObject; use crate::object::PyObject;
use crate::Python; use crate::Python;
@ -261,4 +276,12 @@ mod test {
assert!(py_string.to_string().is_ok()); assert!(py_string.to_string().is_ok());
assert_eq!(Cow::Borrowed(s), py_string.to_string().unwrap()); assert_eq!(Cow::Borrowed(s), py_string.to_string().unwrap());
} }
#[test]
fn test_bytes_index() {
let gil = Python::acquire_gil();
let py = gil.python();
let bytes = PyBytes::new(py, b"Hello World");
assert_eq!(bytes[1], b'e');
}
} }