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

Add null-check for function's documents #1169

Merged
merged 8 commits into from
Oct 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]
## Added
### Added
- Add support for keyword-only arguments without default values in `#[pyfunction]`. [#1209](https://github.com/PyO3/pyo3/pull/1209)

### Changed
- Fields of `PyMethodDef`, `PyGetterDef`, `PySetterDef`, and `PyClassAttributeDef` are now private. [#1169](https://github.com/PyO3/pyo3/pull/1169)

### Fixed
- Fix invalid document for protocol methods. [#1169](https://github.com/PyO3/pyo3/pull/1169)

## [0.12.1] - 2020-09-16
### Fixed
- Fix building for a 32-bit Python on 64-bit Windows with a 64-bit Rust toolchain. [#1179](https://github.com/PyO3/pyo3/pull/1179)
Expand Down
8 changes: 4 additions & 4 deletions guide/src/class.md
Original file line number Diff line number Diff line change
Expand Up @@ -754,14 +754,14 @@ impl pyo3::IntoPy<PyObject> for MyClass {
}

pub struct Pyo3MethodsInventoryForMyClass {
methods: &'static [pyo3::class::PyMethodDefType],
methods: Vec<pyo3::class::PyMethodDefType>,
}
impl pyo3::class::methods::PyMethodsInventory for Pyo3MethodsInventoryForMyClass {
fn new(methods: &'static [pyo3::class::PyMethodDefType]) -> Self {
fn new(methods: Vec<pyo3::class::PyMethodDefType>) -> Self {
Self { methods }
}
fn get(&self) -> &'static [pyo3::class::PyMethodDefType] {
self.methods
fn get(&'static self) -> &'static [pyo3::class::PyMethodDefType] {
&self.methods
}
}
impl pyo3::class::methods::HasMethodsInventory for MyClass {
Expand Down
17 changes: 5 additions & 12 deletions pyo3-derive-backend/src/from_pyobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,9 @@ impl<'a> Container<'a> {
"Cannot derive FromPyObject for empty structs and variants.",
));
}
let transparent = attrs.iter().any(ContainerAttribute::transparent);
let transparent = attrs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes here are unrelated?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did for address clippy warnings.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although clippy only asked to replace the implementation with matches!(), no?

Copy link
Member Author

@kngwyu kngwyu Oct 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but since we support MSRV(1.39), we cannot use macthes.

.iter()
.any(|attr| *attr == ContainerAttribute::Transparent);
if transparent {
Self::check_transparent_len(fields)?;
}
Expand Down Expand Up @@ -182,7 +184,6 @@ impl<'a> Container<'a> {
let err_name = attrs
.iter()
.find_map(|a| a.annotation())
.cloned()
.unwrap_or_else(|| path.segments.last().unwrap().ident.to_string());

let v = Container {
Expand Down Expand Up @@ -306,18 +307,10 @@ enum ContainerAttribute {
}

impl ContainerAttribute {
/// Return whether this attribute is `Transparent`
fn transparent(&self) -> bool {
match self {
ContainerAttribute::Transparent => true,
_ => false,
}
}

/// Convenience method to access `ErrorAnnotation`.
fn annotation(&self) -> Option<&String> {
fn annotation(&self) -> Option<String> {
match self {
ContainerAttribute::ErrorAnnotation(s) => Some(s),
ContainerAttribute::ErrorAnnotation(s) => Some(s.to_string()),
_ => None,
}
}
Expand Down
13 changes: 11 additions & 2 deletions pyo3-derive-backend/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ pub fn add_fn_to_module(
doc,
};

let doc = &spec.doc;
let doc = syn::LitByteStr::new(spec.doc.value().as_bytes(), spec.doc.span());

let python_name = &spec.python_name;

Expand All @@ -212,7 +212,16 @@ pub fn add_fn_to_module(
fn #function_wrapper_ident<'a>(
args: impl Into<pyo3::derive_utils::PyFunctionArguments<'a>>
) -> pyo3::PyResult<&'a pyo3::types::PyCFunction> {
pyo3::types::PyCFunction::new_with_keywords(#wrapper_ident, stringify!(#python_name), #doc, args.into())
let name = concat!(stringify!(#python_name), "\0");
let name = std::ffi::CStr::from_bytes_with_nul(name.as_bytes()).unwrap();
let doc = std::ffi::CStr::from_bytes_with_nul(#doc).unwrap();
pyo3::types::PyCFunction::internal_new(
name,
doc,
pyo3::class::PyMethodType::PyCFunctionWithKeywords(#wrapper_ident),
pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS,
args.into(),
)
}
})
}
Expand Down
10 changes: 5 additions & 5 deletions pyo3-derive-backend/src/pyclass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,14 +215,14 @@ fn impl_methods_inventory(cls: &syn::Ident) -> TokenStream {
quote! {
#[doc(hidden)]
pub struct #inventory_cls {
methods: &'static [pyo3::class::PyMethodDefType],
methods: Vec<pyo3::class::PyMethodDefType>,
}
impl pyo3::class::methods::PyMethodsInventory for #inventory_cls {
fn new(methods: &'static [pyo3::class::PyMethodDefType]) -> Self {
fn new(methods: Vec<pyo3::class::PyMethodDefType>) -> Self {
Self { methods }
}
fn get(&self) -> &'static [pyo3::class::PyMethodDefType] {
self.methods
fn get(&'static self) -> &'static [pyo3::class::PyMethodDefType] {
&self.methods
}
}

Expand Down Expand Up @@ -483,7 +483,7 @@ fn impl_descriptors(
pyo3::inventory::submit! {
#![crate = pyo3] {
type Inventory = <#cls as pyo3::class::methods::HasMethodsInventory>::Methods;
<Inventory as pyo3::class::methods::PyMethodsInventory>::new(&[#(#py_methods),*])
<Inventory as pyo3::class::methods::PyMethodsInventory>::new(vec![#(#py_methods),*])
}
}
})
Expand Down
2 changes: 1 addition & 1 deletion pyo3-derive-backend/src/pyimpl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub fn impl_methods(ty: &syn::Type, impls: &mut Vec<syn::ImplItem>) -> syn::Resu
pyo3::inventory::submit! {
#![crate = pyo3] {
type Inventory = <#ty as pyo3::class::methods::HasMethodsInventory>::Methods;
<Inventory as pyo3::class::methods::PyMethodsInventory>::new(&[#(
<Inventory as pyo3::class::methods::PyMethodsInventory>::new(vec![#(
#(#cfg_attributes)*
#methods
),*])
Expand Down
87 changes: 33 additions & 54 deletions pyo3-derive-backend/src/pymethod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,25 +570,24 @@ pub fn impl_py_method_def(spec: &FnSpec, wrapper: &TokenStream) -> TokenStream {
pyo3::class::PyMethodDefType::Method({
#wrapper

pyo3::class::PyMethodDef {
ml_name: stringify!(#python_name),
ml_meth: pyo3::class::PyMethodType::PyCFunction(__wrap),
ml_flags: pyo3::ffi::METH_NOARGS,
ml_doc: #doc,
}
pyo3::class::PyMethodDef::cfunction(
concat!(stringify!(#python_name), "\0"),
__wrap,
#doc
)
})
}
} else {
quote! {
pyo3::class::PyMethodDefType::Method({
#wrapper

pyo3::class::PyMethodDef {
ml_name: stringify!(#python_name),
ml_meth: pyo3::class::PyMethodType::PyCFunctionWithKeywords(__wrap),
ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS,
ml_doc: #doc,
}
pyo3::class::PyMethodDef::cfunction_with_keywords(
concat!(stringify!(#python_name), "\0"),
__wrap,
0,
#doc
)
})
}
}
Expand All @@ -601,12 +600,7 @@ pub fn impl_py_method_def_new(spec: &FnSpec, wrapper: &TokenStream) -> TokenStre
pyo3::class::PyMethodDefType::New({
#wrapper

pyo3::class::PyMethodDef {
ml_name: stringify!(#python_name),
ml_meth: pyo3::class::PyMethodType::PyNewFunc(__wrap),
ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS,
ml_doc: #doc,
}
pyo3::class::PyMethodDef::new_func(concat!(stringify!(#python_name), "\0"), __wrap, #doc)
})
}
}
Expand All @@ -618,13 +612,12 @@ pub fn impl_py_method_def_class(spec: &FnSpec, wrapper: &TokenStream) -> TokenSt
pyo3::class::PyMethodDefType::Class({
#wrapper

pyo3::class::PyMethodDef {
ml_name: stringify!(#python_name),
ml_meth: pyo3::class::PyMethodType::PyCFunctionWithKeywords(__wrap),
ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS |
pyo3::class::PyMethodDef::cfunction_with_keywords(
concat!(stringify!(#python_name), "\0"),
__wrap,
pyo3::ffi::METH_CLASS,
ml_doc: #doc,
}
#doc
)
})
}
}
Expand All @@ -636,12 +629,12 @@ pub fn impl_py_method_def_static(spec: &FnSpec, wrapper: &TokenStream) -> TokenS
pyo3::class::PyMethodDefType::Static({
#wrapper

pyo3::class::PyMethodDef {
ml_name: stringify!(#python_name),
ml_meth: pyo3::class::PyMethodType::PyCFunctionWithKeywords(__wrap),
ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS | pyo3::ffi::METH_STATIC,
ml_doc: #doc,
}
pyo3::class::PyMethodDef::cfunction_with_keywords(
concat!(stringify!(#python_name), "\0"),
__wrap,
pyo3::ffi::METH_STATIC,
#doc
)
})
}
}
Expand All @@ -652,10 +645,7 @@ pub fn impl_py_method_class_attribute(spec: &FnSpec<'_>, wrapper: &TokenStream)
pyo3::class::PyMethodDefType::ClassAttribute({
#wrapper

pyo3::class::PyClassAttributeDef {
name: stringify!(#python_name),
meth: __wrap,
}
pyo3::class::PyClassAttributeDef::new(concat!(stringify!(#python_name), "\0"), __wrap)
})
}
}
Expand All @@ -666,10 +656,7 @@ pub fn impl_py_const_class_attribute(spec: &ConstSpec, wrapper: &TokenStream) ->
pyo3::class::PyMethodDefType::ClassAttribute({
#wrapper

pyo3::class::PyClassAttributeDef {
name: stringify!(#python_name),
meth: __wrap,
}
pyo3::class::PyClassAttributeDef::new(concat!(stringify!(#python_name), "\0"), __wrap)
})
}
}
Expand All @@ -681,12 +668,12 @@ pub fn impl_py_method_def_call(spec: &FnSpec, wrapper: &TokenStream) -> TokenStr
pyo3::class::PyMethodDefType::Call({
#wrapper

pyo3::class::PyMethodDef {
ml_name: stringify!(#python_name),
ml_meth: pyo3::class::PyMethodType::PyCFunctionWithKeywords(__wrap),
ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS,
ml_doc: #doc,
}
pyo3::class::PyMethodDef::cfunction_with_keywords(
concat!(stringify!(#python_name), "\0"),
__wrap,
pyo3::ffi::METH_STATIC,
#doc
)
})
}
}
Expand All @@ -700,11 +687,7 @@ pub(crate) fn impl_py_setter_def(
pyo3::class::PyMethodDefType::Setter({
#wrapper

pyo3::class::PySetterDef {
name: stringify!(#python_name),
meth: __wrap,
doc: #doc,
}
pyo3::class::PySetterDef::new(concat!(stringify!(#python_name), "\0"), __wrap, #doc)
})
}
}
Expand All @@ -718,11 +701,7 @@ pub(crate) fn impl_py_getter_def(
pyo3::class::PyMethodDefType::Getter({
#wrapper

pyo3::class::PyGetterDef {
name: stringify!(#python_name),
meth: __wrap,
doc: #doc,
}
pyo3::class::PyGetterDef::new(concat!(stringify!(#python_name), "\0"), __wrap, #doc)
})
}
}
Expand Down
14 changes: 7 additions & 7 deletions pyo3-derive-backend/src/pyproto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,12 @@ fn impl_proto_impl(
py_methods.push(quote! {
pyo3::class::PyMethodDefType::Method({
#method
pyo3::class::PyMethodDef {
ml_name: stringify!(#name),
ml_meth: pyo3::class::PyMethodType::PyCFunctionWithKeywords(__wrap),
ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS | #coexist,
ml_doc: ""
}
pyo3::class::PyMethodDef::cfunction_with_keywords(
concat!(stringify!(#name), "\0"),
__wrap,
#coexist,
"\0"
)
})
});
}
Expand All @@ -123,7 +123,7 @@ fn inventory_submission(py_methods: Vec<TokenStream>, ty: &syn::Type) -> TokenSt
pyo3::inventory::submit! {
#![crate = pyo3] {
type Inventory = <#ty as pyo3::class::methods::HasMethodsInventory>::Methods;
<Inventory as pyo3::class::methods::PyMethodsInventory>::new(&[#(#py_methods),*])
<Inventory as pyo3::class::methods::PyMethodsInventory>::new(vec![#(#py_methods),*])
}
}
}
Expand Down
10 changes: 2 additions & 8 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,18 +132,12 @@ fn standard_element_type_from_type_char(type_char: u8) -> ElementType {

#[cfg(target_endian = "little")]
fn is_matching_endian(c: u8) -> bool {
match c {
b'@' | b'=' | b'<' => true,
_ => false,
}
c == b'@' || c == b'=' || c == b'>'
}

#[cfg(target_endian = "big")]
fn is_matching_endian(c: u8) -> bool {
match c {
b'@' | b'=' | b'>' | b'!' => true,
_ => false,
}
c == b'@' || c == b'=' || c == b'>' || c == b'!'
}

/// Trait implemented for possible element types of `PyBuffer`.
Expand Down
Loading