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

Simplify __new__ #125

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
4 changes: 3 additions & 1 deletion examples/pure/pure.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ from enum import Enum, auto
MY_CONSTANT: builtins.int
class A:
x: builtins.int
def __new__(cls,x:builtins.int): ...
def __new__(cls, x:builtins.int) -> A:
...

def show_x(self) -> None:
...

Expand Down
2 changes: 0 additions & 2 deletions pyo3-stub-gen-derive/src/gen_stub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ mod arg;
mod attr;
mod member;
mod method;
mod new;
mod pyclass;
mod pyclass_enum;
mod pyfunction;
Expand All @@ -76,7 +75,6 @@ use arg::*;
use attr::*;
use member::*;
use method::*;
use new::*;
use pyclass::*;
use pyclass_enum::*;
use pyfunction::*;
Expand Down
40 changes: 27 additions & 13 deletions pyo3-stub-gen-derive/src/gen_stub/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,22 @@ use syn::{
Error, GenericArgument, ImplItemFn, PathArguments, Result, Type, TypePath, TypeReference,
};

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum MethodType {
Instance,
Static,
Class,
New,
}

#[derive(Debug)]
pub struct MethodInfo {
name: String,
args: Vec<ArgInfo>,
sig: Option<Signature>,
r#return: Option<Type>,
doc: String,
is_static: bool,
is_class: bool,
r#type: MethodType,
}

fn replace_inner(ty: &mut Type, self_: &Type) {
Expand Down Expand Up @@ -62,27 +69,30 @@ impl TryFrom<ImplItemFn> for MethodInfo {
let attrs = parse_pyo3_attrs(&attrs)?;
let mut method_name = None;
let mut text_sig = Signature::overriding_operator(&sig);
let mut is_static = false;
let mut is_class = false;
let mut method_type = MethodType::Instance;
for attr in attrs {
match attr {
Attr::Name(name) => method_name = Some(name),
Attr::Signature(text_sig_) => text_sig = Some(text_sig_),
Attr::StaticMethod => is_static = true,
Attr::ClassMethod => is_class = true,
Attr::StaticMethod => method_type = MethodType::Static,
Attr::ClassMethod => method_type = MethodType::Class,
Attr::New => method_type = MethodType::New,
_ => {}
}
}
let name = method_name.unwrap_or(sig.ident.to_string());
let name = if method_type == MethodType::New {
"__new__".to_string()
} else {
method_name.unwrap_or(sig.ident.to_string())
};
let r#return = escape_return_type(&sig.output);
Ok(MethodInfo {
name,
sig: text_sig,
args: parse_args(sig.inputs)?,
r#return,
doc,
is_static,
is_class,
r#type: method_type,
})
}
}
Expand All @@ -95,23 +105,27 @@ impl ToTokens for MethodInfo {
args,
sig,
doc,
is_class,
is_static,
r#type,
} = self;
let args_with_sig = ArgsWithSignature { args, sig };
let ret_tt = if let Some(ret) = ret {
quote! { <#ret as pyo3_stub_gen::PyStubType>::type_output }
} else {
quote! { ::pyo3_stub_gen::type_info::no_return_type_output }
};
let type_tt = match r#type {
MethodType::Instance => quote! { ::pyo3_stub_gen::type_info::MethodType::Instance },
MethodType::Static => quote! { ::pyo3_stub_gen::type_info::MethodType::Static },
MethodType::Class => quote! { ::pyo3_stub_gen::type_info::MethodType::Class },
MethodType::New => quote! { ::pyo3_stub_gen::type_info::MethodType::New },
};
tokens.append_all(quote! {
::pyo3_stub_gen::type_info::MethodInfo {
name: #name,
args: #args_with_sig,
r#return: #ret_tt,
doc: #doc,
is_static: #is_static,
is_class: #is_class,
r#type: #type_tt
}
})
}
Expand Down
49 changes: 0 additions & 49 deletions pyo3-stub-gen-derive/src/gen_stub/new.rs

This file was deleted.

30 changes: 12 additions & 18 deletions pyo3-stub-gen-derive/src/gen_stub/pymethods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ use proc_macro2::TokenStream as TokenStream2;
use quote::{quote, ToTokens, TokenStreamExt};
use syn::{Error, ImplItem, ItemImpl, Result, Type};

use super::{quote_option, MemberInfo, MethodInfo, NewInfo};
use super::{MemberInfo, MethodInfo};

pub struct PyMethodsInfo {
struct_id: Type,
new: Option<NewInfo>,
getters: Vec<MemberInfo>,
methods: Vec<MethodInfo>,
}
Expand All @@ -15,26 +14,24 @@ impl TryFrom<ItemImpl> for PyMethodsInfo {
type Error = Error;
fn try_from(item: ItemImpl) -> Result<Self> {
let struct_id = *item.self_ty.clone();
let mut new = None;
let mut getters = Vec::new();
let mut methods = Vec::new();

for inner in item.items {
if let ImplItem::Fn(item_fn) = inner {
if NewInfo::is_candidate(&item_fn)? {
new = Some(NewInfo::try_from(item_fn)?);
} else if MemberInfo::is_candidate_item(&item_fn)? {
getters.push(MemberInfo::try_from(item_fn)?);
} else {
let mut method = MethodInfo::try_from(item_fn)?;
method.replace_self(&item.self_ty);
methods.push(method);
}
for inner in item.items.into_iter() {
let ImplItem::Fn(item_fn) = inner else {
continue;
};
if MemberInfo::is_candidate_item(&item_fn)? {
getters.push(MemberInfo::try_from(item_fn)?);
continue;
}

let mut method = MethodInfo::try_from(item_fn)?;
method.replace_self(&item.self_ty);
methods.push(method);
}
Ok(Self {
struct_id,
new,
getters,
methods,
})
Expand All @@ -45,15 +42,12 @@ impl ToTokens for PyMethodsInfo {
fn to_tokens(&self, tokens: &mut TokenStream2) {
let Self {
struct_id,
new,
getters,
methods,
} = self;
let new_tt = quote_option(new);
tokens.append_all(quote! {
::pyo3_stub_gen::type_info::PyMethodsInfo {
struct_id: std::any::TypeId::of::<#struct_id>,
new: #new_tt,
getters: &[ #(#getters),* ],
methods: &[ #(#methods),* ],
}
Expand Down
2 changes: 0 additions & 2 deletions pyo3-stub-gen/src/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ mod function;
mod member;
mod method;
mod module;
mod new;
mod stub_info;
mod variable;

Expand All @@ -20,7 +19,6 @@ pub use function::*;
pub use member::*;
pub use method::*;
pub use module::*;
pub use new::*;
pub use stub_info::*;
pub use variable::*;

Expand Down
8 changes: 0 additions & 8 deletions pyo3-stub-gen/src/generate/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,13 @@ use std::fmt;
pub struct ClassDef {
pub name: &'static str,
pub doc: &'static str,
pub new: Option<NewDef>,
pub members: Vec<MemberDef>,
pub methods: Vec<MethodDef>,
}

impl Import for ClassDef {
fn import(&self) -> HashSet<ModuleRef> {
let mut import = HashSet::new();
if let Some(new) = &self.new {
import.extend(new.import());
}
for member in &self.members {
import.extend(member.import());
}
Expand All @@ -33,7 +29,6 @@ impl From<&PyClassInfo> for ClassDef {
// This is only an initializer. See `StubInfo::gather` for the actual merging.
Self {
name: info.pyclass_name,
new: None,
doc: info.doc,
members: info.members.iter().map(MemberDef::from).collect(),
methods: Vec::new(),
Expand All @@ -56,9 +51,6 @@ impl fmt::Display for ClassDef {
for member in &self.members {
member.fmt(f)?;
}
if let Some(new) = &self.new {
new.fmt(f)?;
}
for method in &self.methods {
method.fmt(f)?;
}
Expand Down
35 changes: 21 additions & 14 deletions pyo3-stub-gen/src/generate/method.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
use crate::{generate::*, type_info::*, TypeInfo};
use std::{collections::HashSet, fmt};

pub use crate::type_info::MethodType;

/// Definition of a class method.
#[derive(Debug, Clone, PartialEq)]
pub struct MethodDef {
pub name: &'static str,
pub args: Vec<Arg>,
pub r#return: TypeInfo,
pub doc: &'static str,
pub is_static: bool,
pub is_class: bool,
pub r#type: MethodType,
}

impl Import for MethodDef {
Expand All @@ -29,8 +30,7 @@ impl From<&MethodInfo> for MethodDef {
args: info.args.iter().map(Arg::from).collect(),
r#return: (info.r#return)(),
doc: info.doc,
is_static: info.is_static,
is_class: info.is_class,
r#type: info.r#type,
}
}
}
Expand All @@ -39,16 +39,23 @@ impl fmt::Display for MethodDef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let indent = indent();
let mut needs_comma = false;
if self.is_static {
writeln!(f, "{indent}@staticmethod")?;
write!(f, "{indent}def {}(", self.name)?;
} else if self.is_class {
writeln!(f, "{indent}@classmethod")?;
write!(f, "{indent}def {}(cls", self.name)?;
needs_comma = true;
} else {
write!(f, "{indent}def {}(self", self.name)?;
needs_comma = true;
match self.r#type {
MethodType::Static => {
writeln!(f, "{indent}@staticmethod")?;
write!(f, "{indent}def {}(", self.name)?;
}
MethodType::Class | MethodType::New => {
if self.r#type == MethodType::Class {
// new is a classmethod without the decorator
writeln!(f, "{indent}@classmethod")?;
}
write!(f, "{indent}def {}(cls", self.name)?;
needs_comma = true;
}
MethodType::Instance => {
write!(f, "{indent}def {}(self", self.name)?;
needs_comma = true;
}
}
for arg in &self.args {
if needs_comma {
Expand Down
41 changes: 0 additions & 41 deletions pyo3-stub-gen/src/generate/new.rs

This file was deleted.

Loading
Loading