Merge pull request #2289 from davidhewitt/fix-get-tzinfo

ffi: fix segfault in _GET_TZINFO methods
This commit is contained in:
David Hewitt 2022-04-10 13:18:40 +01:00 committed by GitHub
commit e6901e344e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 1 deletions

View File

@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Default to "m" ABI tag when choosing `libpython` link name for CPython 3.7 on Unix. [#2288](https://github.com/PyO3/pyo3/pull/2288)
### Fixed
- Fix segfault when calling FFI methods `PyDateTime_DATE_GET_TZINFO` or `PyDateTime_TIME_GET_TZINFO` on `datetime` or `time` without a tzinfo. [#2289](https://github.com/PyO3/pyo3/pull/2289)
## [0.16.3] - 2022-04-05
### Packaging

View File

@ -155,7 +155,11 @@ macro_rules! _PyDateTime_GET_FOLD {
#[cfg(not(PyPy))]
macro_rules! _PyDateTime_GET_TZINFO {
($o: expr) => {
(*$o).tzinfo
if (*$o).hastzinfo != 0 {
(*$o).tzinfo
} else {
$crate::Py_None()
}
};
}

View File

@ -180,3 +180,44 @@ fn ucs4() {
}
})
}
#[test]
#[cfg(not(PyPy))]
fn test_get_tzinfo() {
crate::Python::with_gil(|py| {
use crate::types::{PyDateTime, PyTime};
use crate::{AsPyPointer, PyAny, ToPyObject};
let datetime = py.import("datetime").map_err(|e| e.print(py)).unwrap();
let timezone = datetime.getattr("timezone").unwrap();
let utc = timezone.getattr("utc").unwrap().to_object(py);
let dt = PyDateTime::new(py, 2018, 1, 1, 0, 0, 0, 0, Some(&utc)).unwrap();
assert!(
unsafe { py.from_borrowed_ptr::<PyAny>(PyDateTime_DATE_GET_TZINFO(dt.as_ptr())) }
.is(&utc)
);
let dt = PyDateTime::new(py, 2018, 1, 1, 0, 0, 0, 0, None).unwrap();
assert!(
unsafe { py.from_borrowed_ptr::<PyAny>(PyDateTime_DATE_GET_TZINFO(dt.as_ptr())) }
.is_none()
);
let t = PyTime::new(py, 0, 0, 0, 0, Some(&utc)).unwrap();
assert!(
unsafe { py.from_borrowed_ptr::<PyAny>(PyDateTime_TIME_GET_TZINFO(t.as_ptr())) }
.is(&utc)
);
let t = PyTime::new(py, 0, 0, 0, 0, None).unwrap();
assert!(
unsafe { py.from_borrowed_ptr::<PyAny>(PyDateTime_TIME_GET_TZINFO(t.as_ptr())) }
.is_none()
);
})
}