msrv: bump to 1.48
This commit is contained in:
parent
f29a8e1b91
commit
6a65f98bd2
|
@ -123,7 +123,7 @@ jobs:
|
||||||
rust-target: "x86_64-apple-darwin",
|
rust-target: "x86_64-apple-darwin",
|
||||||
}
|
}
|
||||||
# Test minimal supported Rust version
|
# Test minimal supported Rust version
|
||||||
- rust: 1.41.1
|
- rust: 1.48.0
|
||||||
python-version: "3.10"
|
python-version: "3.10"
|
||||||
platform:
|
platform:
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,14 @@ PyO3 versions, please see the [migration guide](https://pyo3.rs/latest/migration
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Packaging
|
||||||
|
|
||||||
|
- Update MSRV to Rust 1.48. [#2004](https://github.com/PyO3/pyo3/pull/2004)
|
||||||
|
- Update `indoc` optional dependency to 1.0. [#2004](https://github.com/PyO3/pyo3/pull/2004)
|
||||||
|
- Update `paste` optional dependency to 1.0. [#2004](https://github.com/PyO3/pyo3/pull/2004)
|
||||||
|
|
||||||
## [0.15.1] - 2021-11-19
|
## [0.15.1] - 2021-11-19
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
13
Cargo.toml
13
Cargo.toml
|
@ -21,9 +21,8 @@ parking_lot = "0.11.0"
|
||||||
|
|
||||||
# support crates for macros feature
|
# support crates for macros feature
|
||||||
pyo3-macros = { path = "pyo3-macros", version = "=0.15.1", optional = true }
|
pyo3-macros = { path = "pyo3-macros", version = "=0.15.1", optional = true }
|
||||||
# indoc must stay at 0.3.x for Rust 1.41 compatibility
|
indoc = { version = "1.0.3", optional = true }
|
||||||
indoc = { version = "0.3.6", optional = true }
|
paste = { version = "1.0.6", optional = true }
|
||||||
paste = { version = "0.1.18", optional = true }
|
|
||||||
unindent = { version = "0.1.4", optional = true }
|
unindent = { version = "0.1.4", optional = true }
|
||||||
|
|
||||||
# support crate for multiple-pymethods feature
|
# support crate for multiple-pymethods feature
|
||||||
|
@ -32,7 +31,7 @@ inventory = { version = "0.1.4", optional = true }
|
||||||
|
|
||||||
# crate integrations that can be added using the eponymous features
|
# crate integrations that can be added using the eponymous features
|
||||||
anyhow = { version = "1.0", optional = true }
|
anyhow = { version = "1.0", optional = true }
|
||||||
eyre = { version = ">= 0.4, < 0.7" , optional = true }
|
eyre = { version = ">= 0.4, < 0.7", optional = true }
|
||||||
hashbrown = { version = ">= 0.9, < 0.12", optional = true }
|
hashbrown = { version = ">= 0.9, < 0.12", optional = true }
|
||||||
indexmap = { version = ">= 1.6, < 1.8", optional = true }
|
indexmap = { version = ">= 1.6, < 1.8", optional = true }
|
||||||
num-bigint = { version = "0.4", optional = true }
|
num-bigint = { version = "0.4", optional = true }
|
||||||
|
@ -41,11 +40,7 @@ serde = { version = "1.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
assert_approx_eq = "1.1.0"
|
assert_approx_eq = "1.1.0"
|
||||||
# O.3.5 uses the matches! macro, which isn't compatible with Rust 1.41
|
criterion = "0.3.5"
|
||||||
criterion = "=0.3.4"
|
|
||||||
# half and bitflags use if/match in const fn, which isn't compatible with Rust 1.41
|
|
||||||
half = "=1.7.1"
|
|
||||||
bitflags = "=1.2.1"
|
|
||||||
trybuild = "1.0.49"
|
trybuild = "1.0.49"
|
||||||
rustversion = "1.0"
|
rustversion = "1.0"
|
||||||
# 1.0.0 requires Rust 1.50
|
# 1.0.0 requires Rust 1.50
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
[![benchmark](https://github.com/PyO3/pyo3/actions/workflows/bench.yml/badge.svg)](https://pyo3.rs/dev/bench/)
|
[![benchmark](https://github.com/PyO3/pyo3/actions/workflows/bench.yml/badge.svg)](https://pyo3.rs/dev/bench/)
|
||||||
[![codecov](https://codecov.io/gh/PyO3/pyo3/branch/main/graph/badge.svg)](https://codecov.io/gh/PyO3/pyo3)
|
[![codecov](https://codecov.io/gh/PyO3/pyo3/branch/main/graph/badge.svg)](https://codecov.io/gh/PyO3/pyo3)
|
||||||
[![crates.io](https://img.shields.io/crates/v/pyo3)](https://crates.io/crates/pyo3)
|
[![crates.io](https://img.shields.io/crates/v/pyo3)](https://crates.io/crates/pyo3)
|
||||||
[![minimum rustc 1.41](https://img.shields.io/badge/rustc-1.41+-blue.svg)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html)
|
[![minimum rustc 1.48](https://img.shields.io/badge/rustc-1.48+-blue.svg)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html)
|
||||||
[![dev chat](https://img.shields.io/gitter/room/nwjs/nw.js.svg)](https://gitter.im/PyO3/Lobby)
|
[![dev chat](https://img.shields.io/gitter/room/nwjs/nw.js.svg)](https://gitter.im/PyO3/Lobby)
|
||||||
[![contributing notes](https://img.shields.io/badge/contribute-on%20github-Green)](https://github.com/PyO3/pyo3/blob/main/Contributing.md)
|
[![contributing notes](https://img.shields.io/badge/contribute-on%20github-Green)](https://github.com/PyO3/pyo3/blob/main/Contributing.md)
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
PyO3 supports the following software versions:
|
PyO3 supports the following software versions:
|
||||||
- Python 3.6 and up (CPython and PyPy)
|
- Python 3.6 and up (CPython and PyPy)
|
||||||
- Rust 1.41 and up
|
- Rust 1.48 and up
|
||||||
|
|
||||||
You can use PyO3 to write a native Python module in Rust, or to embed Python in a Rust binary. The following sections explain each of these in turn.
|
You can use PyO3 to write a native Python module in Rust, or to embed Python in a Rust binary. The following sections explain each of these in turn.
|
||||||
|
|
||||||
|
|
|
@ -352,15 +352,12 @@ impl<'a> FnSpec<'a> {
|
||||||
parse_method_receiver(first_arg)
|
parse_method_receiver(first_arg)
|
||||||
};
|
};
|
||||||
|
|
||||||
#[allow(clippy::manual_strip)] // for strip_prefix replacement supporting rust < 1.45
|
|
||||||
// strip get_ or set_
|
// strip get_ or set_
|
||||||
let strip_fn_name = |prefix: &'static str| {
|
let strip_fn_name = |prefix: &'static str| {
|
||||||
let ident = name.unraw().to_string();
|
name.unraw()
|
||||||
if ident.starts_with(prefix) {
|
.to_string()
|
||||||
Some(syn::Ident::new(&ident[prefix.len()..], ident.span()))
|
.strip_prefix(prefix)
|
||||||
} else {
|
.map(|stripped| syn::Ident::new(stripped, name.span()))
|
||||||
None
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let (fn_type, skip_first_arg, fixed_convention) = match fn_type_attr {
|
let (fn_type, skip_first_arg, fixed_convention) = match fn_type_attr {
|
||||||
|
|
|
@ -15,13 +15,11 @@ pub struct MethodProto {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MethodProto {
|
impl MethodProto {
|
||||||
// TODO: workaround for no unsized casts in const fn on Rust 1.45 (stable in 1.46)
|
|
||||||
const EMPTY_ARGS: &'static [&'static str] = &[];
|
|
||||||
pub const fn new(name: &'static str, proto: &'static str) -> Self {
|
pub const fn new(name: &'static str, proto: &'static str) -> Self {
|
||||||
MethodProto {
|
MethodProto {
|
||||||
name,
|
name,
|
||||||
proto,
|
proto,
|
||||||
args: MethodProto::EMPTY_ARGS,
|
args: &[],
|
||||||
with_self: false,
|
with_self: false,
|
||||||
with_result: true,
|
with_result: true,
|
||||||
}
|
}
|
||||||
|
|
|
@ -399,14 +399,9 @@ pub fn impl_py_getter_def(cls: &syn::Type, property_type: PropertyType) -> Resul
|
||||||
|
|
||||||
/// Split an argument of pyo3::Python from the front of the arg list, if present
|
/// Split an argument of pyo3::Python from the front of the arg list, if present
|
||||||
fn split_off_python_arg<'a>(args: &'a [FnArg<'a>]) -> (Option<&FnArg>, &[FnArg]) {
|
fn split_off_python_arg<'a>(args: &'a [FnArg<'a>]) -> (Option<&FnArg>, &[FnArg]) {
|
||||||
if args
|
match args {
|
||||||
.get(0)
|
[py, args @ ..] if utils::is_python(py.ty) => (Some(py), args),
|
||||||
.map(|py| utils::is_python(py.ty))
|
args => (None, args),
|
||||||
.unwrap_or(false)
|
|
||||||
{
|
|
||||||
(Some(&args[0]), &args[1..])
|
|
||||||
} else {
|
|
||||||
(None, args)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,8 +62,6 @@ pub fn option_type_argument(ty: &syn::Type) -> Option<&syn::Type> {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct PythonDoc(TokenStream);
|
pub struct PythonDoc(TokenStream);
|
||||||
|
|
||||||
// TODO(#1782) use strip_prefix on Rust 1.45 or greater
|
|
||||||
#[allow(clippy::manual_strip)]
|
|
||||||
/// Collects all #[doc = "..."] attributes into a TokenStream evaluating to a null-terminated string
|
/// Collects all #[doc = "..."] attributes into a TokenStream evaluating to a null-terminated string
|
||||||
/// e.g. concat!("...", "\n", "\0")
|
/// e.g. concat!("...", "\n", "\0")
|
||||||
pub fn get_doc(
|
pub fn get_doc(
|
||||||
|
@ -107,11 +105,11 @@ pub fn get_doc(
|
||||||
// Strip single left space from literal strings, if needed.
|
// Strip single left space from literal strings, if needed.
|
||||||
// e.g. `/// Hello world` expands to #[doc = " Hello world"]
|
// e.g. `/// Hello world` expands to #[doc = " Hello world"]
|
||||||
let doc_line = lit_str.value();
|
let doc_line = lit_str.value();
|
||||||
if doc_line.starts_with(' ') {
|
doc_line
|
||||||
syn::LitStr::new(&doc_line[1..], lit_str.span()).to_tokens(tokens)
|
.strip_prefix(' ')
|
||||||
} else {
|
.map(|stripped| syn::LitStr::new(stripped, lit_str.span()))
|
||||||
lit_str.to_tokens(tokens)
|
.unwrap_or(lit_str)
|
||||||
}
|
.to_tokens(tokens);
|
||||||
} else {
|
} else {
|
||||||
// This is probably a macro doc from Rust 1.54, e.g. #[doc = include_str!(...)]
|
// This is probably a macro doc from Rust 1.54, e.g. #[doc = include_str!(...)]
|
||||||
token_stream.to_tokens(tokens)
|
token_stream.to_tokens(tokens)
|
||||||
|
|
|
@ -75,12 +75,7 @@ impl ElementType {
|
||||||
pub fn from_format(format: &CStr) -> ElementType {
|
pub fn from_format(format: &CStr) -> ElementType {
|
||||||
match format.to_bytes() {
|
match format.to_bytes() {
|
||||||
[char] | [b'@', char] => native_element_type_from_type_char(*char),
|
[char] | [b'@', char] => native_element_type_from_type_char(*char),
|
||||||
[modifier, char]
|
[modifier, char] if matches!(modifier, b'=' | b'<' | b'>' | b'!') => {
|
||||||
if (*modifier == b'='
|
|
||||||
|| *modifier == b'<'
|
|
||||||
|| *modifier == b'>'
|
|
||||||
|| *modifier == b'!') =>
|
|
||||||
{
|
|
||||||
standard_element_type_from_type_char(*char)
|
standard_element_type_from_type_char(*char)
|
||||||
}
|
}
|
||||||
_ => ElementType::Unknown,
|
_ => ElementType::Unknown,
|
||||||
|
|
|
@ -542,7 +542,6 @@ pub unsafe extern "C" fn alloc_with_freelist<T: PyClassWithFreeList>(
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// - `obj` must be a valid pointer to an instance of T (not a subclass).
|
/// - `obj` must be a valid pointer to an instance of T (not a subclass).
|
||||||
/// - The GIL must be held.
|
/// - The GIL must be held.
|
||||||
#[allow(clippy::collapsible_if)] // for if cfg!
|
|
||||||
pub unsafe extern "C" fn free_with_freelist<T: PyClassWithFreeList>(obj: *mut c_void) {
|
pub unsafe extern "C" fn free_with_freelist<T: PyClassWithFreeList>(obj: *mut c_void) {
|
||||||
let obj = obj as *mut ffi::PyObject;
|
let obj = obj as *mut ffi::PyObject;
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
|
@ -560,10 +559,9 @@ pub unsafe extern "C" fn free_with_freelist<T: PyClassWithFreeList>(obj: *mut c_
|
||||||
};
|
};
|
||||||
free(obj as *mut c_void);
|
free(obj as *mut c_void);
|
||||||
|
|
||||||
if cfg!(Py_3_8) {
|
#[cfg(Py_3_8)]
|
||||||
if ffi::PyType_HasFeature(ty, ffi::Py_TPFLAGS_HEAPTYPE) != 0 {
|
if ffi::PyType_HasFeature(ty, ffi::Py_TPFLAGS_HEAPTYPE) != 0 {
|
||||||
ffi::Py_DECREF(ty as *mut ffi::PyObject);
|
ffi::Py_DECREF(ty as *mut ffi::PyObject);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,6 @@ extern "C" {
|
||||||
fn _Py_CheckRecursiveCall(_where: *mut c_char) -> c_int;
|
fn _Py_CheckRecursiveCall(_where: *mut c_char) -> c_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
|
||||||
// skipped Py_EnterRecursiveCall
|
// skipped Py_EnterRecursiveCall
|
||||||
// skipped Py_LeaveRecursiveCall
|
// skipped Py_LeaveRecursiveCall
|
||||||
|
|
||||||
|
|
51
src/gil.rs
51
src/gil.rs
|
@ -69,33 +69,36 @@ pub(crate) fn gil_is_acquired() -> bool {
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(not(PyPy))]
|
#[cfg(not(PyPy))]
|
||||||
#[allow(clippy::collapsible_if)] // for if cfg!
|
|
||||||
pub fn prepare_freethreaded_python() {
|
pub fn prepare_freethreaded_python() {
|
||||||
// Protect against race conditions when Python is not yet initialized and multiple threads
|
// Protect against race conditions when Python is not yet initialized and multiple threads
|
||||||
// concurrently call 'prepare_freethreaded_python()'. Note that we do not protect against
|
// concurrently call 'prepare_freethreaded_python()'. Note that we do not protect against
|
||||||
// concurrent initialization of the Python runtime by other users of the Python C API.
|
// concurrent initialization of the Python runtime by other users of the Python C API.
|
||||||
START.call_once_force(|_| unsafe {
|
START.call_once_force(|_| unsafe {
|
||||||
if cfg!(not(Py_3_7)) {
|
// Use call_once_force because if initialization panics, it's okay to try again.
|
||||||
// Use call_once_force because if initialization panics, it's okay to try again.
|
|
||||||
if ffi::Py_IsInitialized() != 0 {
|
|
||||||
if ffi::PyEval_ThreadsInitialized() == 0 {
|
|
||||||
// We can only safely initialize threads if this thread holds the GIL.
|
|
||||||
assert!(
|
|
||||||
!ffi::PyGILState_GetThisThreadState().is_null(),
|
|
||||||
"Python threading is not initialized and cannot be initialized by this \
|
|
||||||
thread, because it is not the thread which initialized Python."
|
|
||||||
);
|
|
||||||
ffi::PyEval_InitThreads();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ffi::Py_InitializeEx(0);
|
|
||||||
ffi::PyEval_InitThreads();
|
|
||||||
|
|
||||||
// Release the GIL.
|
// TODO(#1782) - Python 3.6 legacy code
|
||||||
ffi::PyEval_SaveThread();
|
#[cfg(not(Py_3_7))]
|
||||||
|
if ffi::Py_IsInitialized() != 0 {
|
||||||
|
if ffi::PyEval_ThreadsInitialized() == 0 {
|
||||||
|
// We can only safely initialize threads if this thread holds the GIL.
|
||||||
|
assert!(
|
||||||
|
!ffi::PyGILState_GetThisThreadState().is_null(),
|
||||||
|
"Python threading is not initialized and cannot be initialized by this \
|
||||||
|
thread, because it is not the thread which initialized Python."
|
||||||
|
);
|
||||||
|
ffi::PyEval_InitThreads();
|
||||||
}
|
}
|
||||||
} else if ffi::Py_IsInitialized() == 0 {
|
} else {
|
||||||
// In Python 3.7 and up PyEval_InitThreads is irrelevant.
|
ffi::Py_InitializeEx(0);
|
||||||
|
ffi::PyEval_InitThreads();
|
||||||
|
|
||||||
|
// Release the GIL.
|
||||||
|
ffi::PyEval_SaveThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
// In Python 3.7 and up PyEval_InitThreads is irrelevant.
|
||||||
|
#[cfg(Py_3_7)]
|
||||||
|
if ffi::Py_IsInitialized() == 0 {
|
||||||
ffi::Py_InitializeEx(0);
|
ffi::Py_InitializeEx(0);
|
||||||
|
|
||||||
// Release the GIL.
|
// Release the GIL.
|
||||||
|
@ -134,7 +137,6 @@ pub fn prepare_freethreaded_python() {
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(not(PyPy))]
|
#[cfg(not(PyPy))]
|
||||||
#[allow(clippy::collapsible_if)] // for if cfg!
|
|
||||||
pub unsafe fn with_embedded_python_interpreter<F, R>(f: F) -> R
|
pub unsafe fn with_embedded_python_interpreter<F, R>(f: F) -> R
|
||||||
where
|
where
|
||||||
F: for<'p> FnOnce(Python<'p>) -> R,
|
F: for<'p> FnOnce(Python<'p>) -> R,
|
||||||
|
@ -149,10 +151,9 @@ where
|
||||||
|
|
||||||
// Changed in version 3.7: This function is now called by Py_Initialize(), so you don’t have to
|
// Changed in version 3.7: This function is now called by Py_Initialize(), so you don’t have to
|
||||||
// call it yourself anymore.
|
// call it yourself anymore.
|
||||||
if cfg!(not(Py_3_7)) {
|
#[cfg(not(Py_3_7))]
|
||||||
if ffi::PyEval_ThreadsInitialized() == 0 {
|
if ffi::PyEval_ThreadsInitialized() == 0 {
|
||||||
ffi::PyEval_InitThreads();
|
ffi::PyEval_InitThreads();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safe: the GIL is already held because of the Py_IntializeEx call.
|
// Safe: the GIL is already held because of the Py_IntializeEx call.
|
||||||
|
|
|
@ -111,7 +111,7 @@
|
||||||
//!
|
//!
|
||||||
//! PyO3 supports the following software versions:
|
//! PyO3 supports the following software versions:
|
||||||
//! - Python 3.6 and up (CPython and PyPy)
|
//! - Python 3.6 and up (CPython and PyPy)
|
||||||
//! - Rust 1.41 and up
|
//! - Rust 1.48 and up
|
||||||
//!
|
//!
|
||||||
//! # Example: Building a native Python module
|
//! # Example: Building a native Python module
|
||||||
//!
|
//!
|
||||||
|
|
|
@ -83,7 +83,8 @@ where
|
||||||
slots.push(ffi::Py_tp_free, free as _);
|
slots.push(ffi::Py_tp_free, free as _);
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg!(Py_3_9) {
|
#[cfg(Py_3_9)]
|
||||||
|
{
|
||||||
let members = py_class_members::<T>();
|
let members = py_class_members::<T>();
|
||||||
if !members.is_empty() {
|
if !members.is_empty() {
|
||||||
slots.push(ffi::Py_tp_members, into_raw(members))
|
slots.push(ffi::Py_tp_members, into_raw(members))
|
||||||
|
@ -155,7 +156,8 @@ fn tp_init_additional<T: PyClass>(type_object: *mut ffi::PyTypeObject) {
|
||||||
|
|
||||||
// Setting buffer protocols via slots doesn't work until Python 3.9, so on older versions we
|
// Setting buffer protocols via slots doesn't work until Python 3.9, so on older versions we
|
||||||
// must manually fixup the type object.
|
// must manually fixup the type object.
|
||||||
if cfg!(not(Py_3_9)) {
|
#[cfg(not(Py_3_9))]
|
||||||
|
{
|
||||||
if let Some(buffer) = T::get_buffer() {
|
if let Some(buffer) = T::get_buffer() {
|
||||||
unsafe {
|
unsafe {
|
||||||
(*(*type_object).tp_as_buffer).bf_getbuffer = buffer.bf_getbuffer;
|
(*(*type_object).tp_as_buffer).bf_getbuffer = buffer.bf_getbuffer;
|
||||||
|
@ -166,7 +168,8 @@ fn tp_init_additional<T: PyClass>(type_object: *mut ffi::PyTypeObject) {
|
||||||
|
|
||||||
// Setting tp_dictoffset and tp_weaklistoffset via slots doesn't work until Python 3.9, so on
|
// Setting tp_dictoffset and tp_weaklistoffset via slots doesn't work until Python 3.9, so on
|
||||||
// older versions again we must fixup the type object.
|
// older versions again we must fixup the type object.
|
||||||
if cfg!(not(Py_3_9)) {
|
#[cfg(not(Py_3_9))]
|
||||||
|
{
|
||||||
// __dict__ support
|
// __dict__ support
|
||||||
if let Some(dict_offset) = PyCell::<T>::dict_offset() {
|
if let Some(dict_offset) = PyCell::<T>::dict_offset() {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -258,12 +261,6 @@ fn py_class_members<T: PyClass>() -> Vec<ffi::structmember::PyMemberDef> {
|
||||||
members
|
members
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stub needed since the `if cfg!()` above still compiles contained code.
|
|
||||||
#[cfg(not(Py_3_9))]
|
|
||||||
fn py_class_members<T: PyClass>() -> Vec<ffi::structmember::PyMemberDef> {
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
|
|
||||||
const PY_GET_SET_DEF_INIT: ffi::PyGetSetDef = ffi::PyGetSetDef {
|
const PY_GET_SET_DEF_INIT: ffi::PyGetSetDef = ffi::PyGetSetDef {
|
||||||
name: ptr::null_mut(),
|
name: ptr::null_mut(),
|
||||||
get: None,
|
get: None,
|
||||||
|
@ -272,7 +269,6 @@ const PY_GET_SET_DEF_INIT: ffi::PyGetSetDef = ffi::PyGetSetDef {
|
||||||
closure: ptr::null_mut(),
|
closure: ptr::null_mut(),
|
||||||
};
|
};
|
||||||
|
|
||||||
#[allow(clippy::collapsible_if)] // for if cfg!
|
|
||||||
fn py_class_properties(
|
fn py_class_properties(
|
||||||
is_dummy: bool,
|
is_dummy: bool,
|
||||||
for_each_method_def: &dyn Fn(&mut dyn FnMut(&[PyMethodDefType])),
|
for_each_method_def: &dyn Fn(&mut dyn FnMut(&[PyMethodDefType])),
|
||||||
|
|
|
@ -227,8 +227,9 @@ impl PyString {
|
||||||
pub unsafe fn data(&self) -> PyResult<PyStringData<'_>> {
|
pub unsafe fn data(&self) -> PyResult<PyStringData<'_>> {
|
||||||
let ptr = self.as_ptr();
|
let ptr = self.as_ptr();
|
||||||
|
|
||||||
if cfg!(not(Py_3_12)) {
|
#[cfg(not(Py_3_12))]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
|
{
|
||||||
let ready = ffi::PyUnicode_READY(ptr);
|
let ready = ffi::PyUnicode_READY(ptr);
|
||||||
if ready != 0 {
|
if ready != 0 {
|
||||||
// Exception was created on failure.
|
// Exception was created on failure.
|
||||||
|
|
|
@ -23,22 +23,15 @@ fn _test_compile_errors() {
|
||||||
t.compile_fail("tests/ui/invalid_pymethods.rs");
|
t.compile_fail("tests/ui/invalid_pymethods.rs");
|
||||||
t.compile_fail("tests/ui/invalid_pymethod_names.rs");
|
t.compile_fail("tests/ui/invalid_pymethod_names.rs");
|
||||||
t.compile_fail("tests/ui/invalid_argument_attributes.rs");
|
t.compile_fail("tests/ui/invalid_argument_attributes.rs");
|
||||||
|
t.compile_fail("tests/ui/missing_clone.rs");
|
||||||
t.compile_fail("tests/ui/reject_generics.rs");
|
t.compile_fail("tests/ui/reject_generics.rs");
|
||||||
|
t.compile_fail("tests/ui/wrong_aspyref_lifetimes.rs");
|
||||||
|
|
||||||
tests_rust_1_48(&t);
|
|
||||||
tests_rust_1_49(&t);
|
tests_rust_1_49(&t);
|
||||||
tests_rust_1_54(&t);
|
tests_rust_1_54(&t);
|
||||||
tests_rust_1_55(&t);
|
tests_rust_1_55(&t);
|
||||||
tests_rust_1_56(&t);
|
tests_rust_1_56(&t);
|
||||||
|
|
||||||
#[rustversion::since(1.48)]
|
|
||||||
fn tests_rust_1_48(t: &trybuild::TestCases) {
|
|
||||||
t.compile_fail("tests/ui/missing_clone.rs");
|
|
||||||
t.compile_fail("tests/ui/wrong_aspyref_lifetimes.rs");
|
|
||||||
}
|
|
||||||
#[rustversion::before(1.48)]
|
|
||||||
fn tests_rust_1_48(_t: &trybuild::TestCases) {}
|
|
||||||
|
|
||||||
#[rustversion::since(1.49)]
|
#[rustversion::since(1.49)]
|
||||||
fn tests_rust_1_49(t: &trybuild::TestCases) {
|
fn tests_rust_1_49(t: &trybuild::TestCases) {
|
||||||
t.compile_fail("tests/ui/deprecations.rs");
|
t.compile_fail("tests/ui/deprecations.rs");
|
||||||
|
|
|
@ -2,9 +2,7 @@
|
||||||
//! but can't even be cfg-ed out on MSRV because the compiler doesn't support
|
//! but can't even be cfg-ed out on MSRV because the compiler doesn't support
|
||||||
//! the syntax.
|
//! the syntax.
|
||||||
|
|
||||||
// TODO(#1782) rustversion attribute can't go on modules until Rust 1.42, so this
|
#[rustversion::since(1.54)]
|
||||||
// funky dance has to happen...
|
|
||||||
mod requires_1_54 {
|
mod requires_1_54 {
|
||||||
#[rustversion::since(1.54)]
|
|
||||||
include!("not_msrv/requires_1_54.rs");
|
include!("not_msrv/requires_1_54.rs");
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,15 @@ error[E0277]: the trait bound `PyDict: PyClass` is not satisfied
|
||||||
|
|
|
|
||||||
= note: required because of the requirements on the impl of `PyClassBaseType` for `PyDict`
|
= note: required because of the requirements on the impl of `PyClassBaseType` for `PyDict`
|
||||||
note: required by a bound in `PyClassBaseType`
|
note: required by a bound in `PyClassBaseType`
|
||||||
--> src/class/impl_.rs:766:1
|
--> src/class/impl_.rs
|
||||||
|
|
|
|
||||||
766 | / pub trait PyClassBaseType: Sized {
|
| / pub trait PyClassBaseType: Sized {
|
||||||
767 | | type Dict;
|
| | type Dict;
|
||||||
768 | | type WeakRef;
|
| | type WeakRef;
|
||||||
769 | | type LayoutAsBase: PyCellLayout<Self>;
|
| | type LayoutAsBase: PyCellLayout<Self>;
|
||||||
... |
|
... |
|
||||||
772 | | type Initializer: PyObjectInit<Self>;
|
| | type Initializer: PyObjectInit<Self>;
|
||||||
773 | | }
|
| | }
|
||||||
| |_^ required by this bound in `PyClassBaseType`
|
| |_^ required by this bound in `PyClassBaseType`
|
||||||
= note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@ error[E0277]: the trait bound `PyDict: PyClass` is not satisfied
|
||||||
|
|
|
|
||||||
= note: required because of the requirements on the impl of `PyClassBaseType` for `PyDict`
|
= note: required because of the requirements on the impl of `PyClassBaseType` for `PyDict`
|
||||||
note: required by a bound in `ThreadCheckerInherited`
|
note: required by a bound in `ThreadCheckerInherited`
|
||||||
--> src/class/impl_.rs:753:47
|
--> src/class/impl_.rs
|
||||||
|
|
|
|
||||||
753 | pub struct ThreadCheckerInherited<T: Send, U: PyClassBaseType>(PhantomData<T>, U::ThreadChecker);
|
| pub struct ThreadCheckerInherited<T: Send, U: PyClassBaseType>(PhantomData<T>, U::ThreadChecker);
|
||||||
| ^^^^^^^^^^^^^^^ required by this bound in `ThreadCheckerInherited`
|
| ^^^^^^^^^^^^^^^ required by this bound in `ThreadCheckerInherited`
|
||||||
= note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
|
@ -50,6 +50,3 @@ fn my_module(_py: Python, m: &PyModule) -> PyResult<()> {
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: ensure name deprecated on #[pyfunction] and #[pymodule]
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ note: required because it appears within the type `NotThreadSafe`
|
||||||
5 | struct NotThreadSafe {
|
5 | struct NotThreadSafe {
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
note: required by a bound in `ThreadCheckerStub`
|
note: required by a bound in `ThreadCheckerStub`
|
||||||
--> src/class/impl_.rs:710:33
|
--> src/class/impl_.rs
|
||||||
|
|
|
|
||||||
710 | pub struct ThreadCheckerStub<T: Send>(PhantomData<T>);
|
| pub struct ThreadCheckerStub<T: Send>(PhantomData<T>);
|
||||||
| ^^^^ required by this bound in `ThreadCheckerStub`
|
| ^^^^ required by this bound in `ThreadCheckerStub`
|
||||||
= note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
Loading…
Reference in New Issue