Merge pull request #2923 from youknowone/derive-text-signature

derive __text_signature__ from method definition
This commit is contained in:
Jim Fasarakis-Hilliard
2021-08-22 12:43:50 +03:00
committed by GitHub
4 changed files with 62 additions and 63 deletions

4
Cargo.lock generated
View File

@@ -2282,9 +2282,9 @@ dependencies = [
[[package]]
name = "syn-ext"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14e039b5850edc6e974a22c8ea37ba9dc4de7909c2572eff65b2f943bd5dc984"
checksum = "9210542fa1f4811e2024f7ef22668ef8e035a54f6c9d4826faae8ae2885bd455"
dependencies = [
"syn",
]

View File

@@ -12,7 +12,7 @@ proc-macro = true
[dependencies]
syn = { version = "1.0", features = ["full", "extra-traits"] }
syn-ext = { version = "0.2.1", features = ["full"] }
syn-ext = { version = "0.2.3", features = ["full"] }
quote = "1.0"
proc-macro2 = "1.0"
rustpython-compiler = { path = "../compiler/porcelain", version = "0.1.1" }

View File

@@ -337,13 +337,51 @@ where
let item_attr = args.attrs.remove(self.index());
let item_meta = MethodItemMeta::from_attr(ident.clone(), &item_attr)?;
let py_name = item_meta.method_name()?;
let sig_doc = args.item.function_or_method_impl().ok().map(|item| {
let sig = item.sig();
let args: Vec<_> = sig
.inputs
.iter()
.filter_map(|arg| {
use syn::FnArg::*;
let arg = match arg {
Receiver(_) => return Some("$self".to_owned()),
Typed(typed) => typed,
};
let ty = arg.ty.as_ref();
let ty = quote!(#ty).to_string();
if ty == "FuncArgs" {
return Some("*args, **kwargs".to_owned());
}
if ty == "& VirtualMachine" {
return None;
}
let ident = match arg.pat.as_ref() {
syn::Pat::Ident(p) => p.ident.to_string(),
// FIXME: other => unreachable!("function arg pattern must be ident but found `{}`", quote!(fn #ident(.. #other ..))),
other => quote!(#other).to_string(),
};
if ident == "zelf" {
return Some("$self".to_owned());
}
if ident == "vm" {
unreachable!("type &VirtualMachine(`{}`) must be filtered already", ty);
}
Some(ident)
})
.collect();
format!("{}({})", py_name, args.join(", "))
});
let tokens = {
let doc = args.attrs.doc().map_or_else(
TokenStream::new,
|doc| quote!(.with_doc(#doc.to_owned(), ctx)),
);
let doc = args.attrs.doc().map_or_else(TokenStream::new, |mut doc| {
if let Some(sig_doc) = sig_doc {
doc = format!("{}\n--\n\n{}", sig_doc, doc);
}
quote!(.with_doc(#doc.to_owned(), ctx))
});
let build_func = match self.method_type.as_str() {
"method" => quote!(.build_method(ctx, class.clone())),
"classmethod" => quote!(.build_classmethod(ctx, class.clone())),

View File

@@ -33,9 +33,6 @@ impl PyValue for PyBaseObject {
#[pyimpl(flags(BASETYPE))]
impl PyBaseObject {
/// __new__($type, *args, **kwargs)
/// --
///
/// Create and return a new object. See help(type) for accurate signature.
#[pyslot]
fn tp_new(mut args: FuncArgs, vm: &VirtualMachine) -> PyResult {
@@ -92,105 +89,81 @@ impl PyBaseObject {
Ok(res)
}
/// __eq__($self, value, /)
/// --
///
/// Return self==value.
#[pymethod(magic)]
fn eq(
zelf: PyObjectRef,
other: PyObjectRef,
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<PyComparisonValue> {
Self::cmp(&zelf, &other, PyComparisonOp::Eq, vm)
Self::cmp(&zelf, &value, PyComparisonOp::Eq, vm)
}
/// __ne__($self, value, /)
/// --
///
/// Return self!=value.
#[pymethod(magic)]
fn ne(
zelf: PyObjectRef,
other: PyObjectRef,
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<PyComparisonValue> {
Self::cmp(&zelf, &other, PyComparisonOp::Ne, vm)
Self::cmp(&zelf, &value, PyComparisonOp::Ne, vm)
}
/// __lt__($self, value, /)
/// --
///
/// Return self<value.
#[pymethod(magic)]
fn lt(
zelf: PyObjectRef,
other: PyObjectRef,
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<PyComparisonValue> {
Self::cmp(&zelf, &other, PyComparisonOp::Lt, vm)
Self::cmp(&zelf, &value, PyComparisonOp::Lt, vm)
}
/// __le__($self, value, /)
/// --
///
/// Return self<=value.
#[pymethod(magic)]
fn le(
zelf: PyObjectRef,
other: PyObjectRef,
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<PyComparisonValue> {
Self::cmp(&zelf, &other, PyComparisonOp::Le, vm)
Self::cmp(&zelf, &value, PyComparisonOp::Le, vm)
}
/// __ge__($self, value, /)
/// --
///
/// Return self>=value.
#[pymethod(magic)]
fn ge(
zelf: PyObjectRef,
other: PyObjectRef,
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<PyComparisonValue> {
Self::cmp(&zelf, &other, PyComparisonOp::Ge, vm)
Self::cmp(&zelf, &value, PyComparisonOp::Ge, vm)
}
/// __gt__($self, value, /)
/// --
///
/// Return self>value.
#[pymethod(magic)]
fn gt(
zelf: PyObjectRef,
other: PyObjectRef,
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<PyComparisonValue> {
Self::cmp(&zelf, &other, PyComparisonOp::Gt, vm)
Self::cmp(&zelf, &value, PyComparisonOp::Gt, vm)
}
/// __setattr__($self, name, value /)
/// --
///
/// Implement setattr(self, name, value).
#[pymethod]
fn __setattr__(
obj: PyObjectRef,
attr_name: PyStrRef,
name: PyStrRef,
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
setattr(&obj, attr_name, Some(value), vm)
setattr(&obj, name, Some(value), vm)
}
/// __delattr__($self, name, /)
/// --
///
/// Implement delattr(self, name).
#[pymethod]
fn __delattr__(obj: PyObjectRef, attr_name: PyStrRef, vm: &VirtualMachine) -> PyResult<()> {
setattr(&obj, attr_name, None, vm)
fn __delattr__(obj: PyObjectRef, name: PyStrRef, vm: &VirtualMachine) -> PyResult<()> {
setattr(&obj, name, None, vm)
}
#[pyslot]
@@ -203,18 +176,12 @@ impl PyBaseObject {
setattr(obj, attr_name, value, vm)
}
/// __str__($self, /)
/// --
///
/// Return str(self).
#[pymethod(magic)]
fn str(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyStrRef> {
vm.to_repr(&zelf)
}
/// __repr__($self, /)
/// --
///
/// Return repr(self).
#[pymethod(magic)]
fn repr(zelf: PyObjectRef) -> String {
@@ -288,9 +255,6 @@ impl PyBaseObject {
}
}
/// __getattribute__($self, name, /)
/// --
///
/// Return getattr(self, name).
#[pymethod(name = "__getattribute__")]
#[pyslot]
@@ -321,9 +285,6 @@ impl PyBaseObject {
Ok(zelf.get_id() as _)
}
/// __hash__($self, /)
/// --
///
/// Return hash(self).
#[pymethod(magic)]
fn hash(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyHash> {