Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ffi: add PyConfig::warn_default_encoding to 3.10+ #2370

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added the internal `IntoPyResult` trait to give better error messages when function return types do not implement `IntoPy`. [#2326](https://github.com/PyO3/pyo3/pull/2326)
- Add `PyDictKeys`, `PyDictValues` and `PyDictItems` Rust types to represent `dict_keys`, `dict_values` and `dict_items` types. [#2358](https://github.com/PyO3/pyo3/pull/2358)
- Add an experimental `generate-import-lib` feature to support auto-generating non-abi3 python import libraries for Windows targets. [#2364](https://github.com/PyO3/pyo3/pull/2364)
- Add FFI definition `Py_ExitStatusException`. [#2370](https://github.com/PyO3/pyo3/pull/2370)

### Changed

Expand All @@ -28,7 +29,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Fixed incorrectly disabled FFI definition `PyThreadState_DeleteCurrent`. [#2357](https://github.com/PyO3/pyo3/pull/2357)
- Correct FFI definition `PyEval_EvalCodeEx` to take `*const *mut PyObject` array arguments instead of `*mut *mut PyObject` (this was changed in CPython 3.6). [#2368](https://github.com/PyO3/pyo3/pull/2368)

- Added missing `warn_default_encoding` field to `PyConfig` on 3.10+. The previously missing field could result in incorrect behavior or crashes. [#2370](https://github.com/PyO3/pyo3/pull/2370)
- Fixed order of `pathconfig_warnings` and `program_name` fields of `PyConfig` on 3.10+. Previously, the order of the fields was swapped and this could lead to incorrect behavior or crashes. [#2370](https://github.com/PyO3/pyo3/pull/2370)

## [0.16.4] - 2022-04-14

Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -49,6 +49,7 @@ send_wrapper = "0.5"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.61"
rayon = "1.0.2"
widestring = "0.5.1"

[build-dependencies]
pyo3-build-config = { path = "pyo3-build-config", version = "0.16.4", features = ["resolve-config"] }
Expand Down
4 changes: 3 additions & 1 deletion pyo3-ffi/src/cpython/initconfig.rs
Expand Up @@ -110,6 +110,8 @@ pub struct PyConfig {
pub warnoptions: PyWideStringList,
pub site_import: c_int,
pub bytes_warning: c_int,
#[cfg(Py_3_10)]
pub warn_default_encoding: c_int,
pub inspect: c_int,
pub interactive: c_int,
pub optimization_level: c_int,
Expand All @@ -127,9 +129,9 @@ pub struct PyConfig {
pub legacy_windows_stdio: c_int,

pub check_hash_pycs_mode: *mut wchar_t,
pub pathconfig_warnings: c_int,
#[cfg(Py_3_10)]
pub program_name: *mut wchar_t,
pub pathconfig_warnings: c_int,
pub pythonpath_env: *mut wchar_t,
pub home: *mut wchar_t,
#[cfg(Py_3_10)]
Expand Down
2 changes: 1 addition & 1 deletion pyo3-ffi/src/cpython/pylifecycle.rs
Expand Up @@ -23,7 +23,7 @@ extern "C" {

pub fn Py_RunMain() -> c_int;

// skipped Py_ExitStatusException
pub fn Py_ExitStatusException(status: PyStatus) -> !;

// skipped _Py_RestoreSignals

Expand Down
76 changes: 76 additions & 0 deletions tests/test_pep_587.rs
@@ -0,0 +1,76 @@
#![cfg(all(Py_3_8, not(any(PyPy, Py_LIMITED_API))))]

use pyo3::ffi;

#[cfg(Py_3_10)]
use widestring::WideCString;

#[test]
fn test_default_interpreter() {
macro_rules! ensure {
($py_call:expr) => {{
let status = $py_call;
unsafe {
if ffi::PyStatus_Exception(status) != 0 {
ffi::Py_ExitStatusException(status);
}
}
}};
}

let mut preconfig = unsafe { std::mem::zeroed() };

unsafe { ffi::PyPreConfig_InitPythonConfig(&mut preconfig) };
preconfig.utf8_mode = 1;

ensure!(unsafe { ffi::Py_PreInitialize(&preconfig) });

let mut config = unsafe { std::mem::zeroed() };
unsafe { ffi::PyConfig_InitPythonConfig(&mut config) };

// Require manually calling _Py_InitializeMain to exercise more ffi code
config._init_main = 0;

// Set program_name as regression test for #2370
#[cfg(all(Py_3_10, windows))]
{
use libc::wchar_t;
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
let mut value: Vec<wchar_t> = OsStr::new("some_test\0").encode_wide().collect();

unsafe {
ffi::PyConfig_SetString(&mut config, &mut config.program_name, value.as_ptr());
}
}
#[cfg(all(Py_3_10, unix))]
{
unsafe {
ffi::PyConfig_SetBytesString(
&mut config,
&mut config.program_name,
"some_test\0".as_ptr().cast(),
);
}
}

ensure!(unsafe { ffi::Py_InitializeFromConfig(&config) });

// The GIL is held.
assert_eq!(unsafe { ffi::PyGILState_Check() }, 1);

// Now proceed with the Python main initialization. This will initialize
// importlib. And if the custom importlib bytecode was registered above,
// our extension module will get imported and initialized.
ensure!(unsafe { ffi::_Py_InitializeMain() });

// The GIL is held after finishing initialization.
assert_eq!(unsafe { ffi::PyGILState_Check() }, 1);

// Confirm program name set above was picked up correctly
#[cfg(Py_3_10)]
{
let program_name = unsafe { WideCString::from_ptr_str(ffi::Py_GetProgramName().cast()) };
assert_eq!(program_name.to_string().unwrap(), "some_test");
}
}