Skip to content

Commit 4082b13

Browse files
authored
Merge pull request RustPython#1873 from youknowone/fromargs-generic
merge SplitArgs + Generic support for FromArgs
2 parents 98b5876 + 14f1a42 commit 4082b13

File tree

6 files changed

+135
-138
lines changed

6 files changed

+135
-138
lines changed

derive/src/from_args.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,11 @@ enum ParameterKind {
1616

1717
impl ParameterKind {
1818
fn from_ident(ident: &Ident) -> Option<ParameterKind> {
19-
if ident == "positional_only" {
20-
Some(ParameterKind::PositionalOnly)
21-
} else if ident == "positional_or_keyword" {
22-
Some(ParameterKind::PositionalOrKeyword)
23-
} else if ident == "keyword_only" {
24-
Some(ParameterKind::KeywordOnly)
25-
} else {
26-
None
19+
match ident.to_string().as_str() {
20+
"positional_only" => Some(ParameterKind::PositionalOnly),
21+
"positional_or_keyword" => Some(ParameterKind::PositionalOrKeyword),
22+
"keyword_only" => Some(ParameterKind::KeywordOnly),
23+
_ => None,
2724
}
2825
}
2926
}
@@ -150,6 +147,13 @@ fn generate_field(field: &Field) -> Result<TokenStream2, Diagnostic> {
150147
};
151148

152149
let name = &field.ident;
150+
if let Some(name) = name {
151+
if name.to_string().starts_with("_phantom") {
152+
return Ok(quote! {
153+
#name: std::marker::PhantomData,
154+
});
155+
}
156+
}
153157
let middle = quote! {
154158
.map(|x| ::rustpython_vm::pyobject::TryFromObject::try_from_object(vm, x)).transpose()?
155159
};
@@ -210,8 +214,9 @@ pub fn impl_from_args(input: DeriveInput) -> Result<TokenStream2, Diagnostic> {
210214
};
211215

212216
let name = input.ident;
217+
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
213218
let output = quote! {
214-
impl ::rustpython_vm::function::FromArgs for #name {
219+
impl #impl_generics ::rustpython_vm::function::FromArgs for #name #ty_generics #where_clause {
215220
fn from_args(
216221
vm: &::rustpython_vm::VirtualMachine,
217222
args: &mut ::rustpython_vm::function::PyFuncArgs

vm/src/obj/objbytearray.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,15 @@ use std::convert::TryFrom;
44
use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
55

66
use super::objbyteinner::{
7-
ByteInnerExpandtabsOptions, ByteInnerFindOptions, ByteInnerNewOptions, ByteInnerPaddingOptions,
8-
ByteInnerSplitOptions, ByteInnerSplitlinesOptions, ByteInnerTranslateOptions, ByteOr,
9-
PyByteInner,
7+
ByteInnerFindOptions, ByteInnerNewOptions, ByteInnerPaddingOptions, ByteInnerSplitOptions,
8+
ByteInnerTranslateOptions, ByteOr, PyByteInner,
109
};
1110
use super::objint::PyIntRef;
1211
use super::objiter;
1312
use super::objslice::PySliceRef;
1413
use super::objstr::{PyString, PyStringRef};
1514
use super::objtype::PyClassRef;
16-
use super::pystr::PyCommonString;
15+
use super::pystr::{self, PyCommonString};
1716
use crate::cformat::CFormatString;
1817
use crate::function::{OptionalArg, OptionalOption};
1918
use crate::obj::objstr::do_cformat_string;
@@ -440,12 +439,12 @@ impl PyByteArray {
440439
}
441440

442441
#[pymethod(name = "expandtabs")]
443-
fn expandtabs(&self, options: ByteInnerExpandtabsOptions) -> PyByteArray {
442+
fn expandtabs(&self, options: pystr::ExpandTabsArgs) -> PyByteArray {
444443
self.borrow_value().expandtabs(options).into()
445444
}
446445

447446
#[pymethod(name = "splitlines")]
448-
fn splitlines(&self, options: ByteInnerSplitlinesOptions, vm: &VirtualMachine) -> PyResult {
447+
fn splitlines(&self, options: pystr::SplitLinesArgs, vm: &VirtualMachine) -> PyResult {
449448
let as_bytes = self
450449
.borrow_value()
451450
.splitlines(options)

vm/src/obj/objbyteinner.rs

Lines changed: 21 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use super::objnone::PyNoneRef;
1414
use super::objsequence::PySliceableSequence;
1515
use super::objslice::PySliceRef;
1616
use super::objstr::{self, PyString, PyStringRef};
17-
use super::pystr::{self, PyCommonString, StringRange};
17+
use super::pystr::{self, PyCommonString, PyCommonStringWrapper, StringRange};
1818
use crate::function::{OptionalArg, OptionalOption};
1919
use crate::pyhash;
2020
use crate::pyobject::{
@@ -255,43 +255,7 @@ impl ByteInnerTranslateOptions {
255255
}
256256
}
257257

258-
#[derive(FromArgs)]
259-
pub struct ByteInnerSplitOptions {
260-
#[pyarg(positional_or_keyword, default = "None")]
261-
sep: Option<PyByteInner>,
262-
#[pyarg(positional_or_keyword, default = "-1")]
263-
maxsplit: isize,
264-
}
265-
266-
impl ByteInnerSplitOptions {
267-
pub fn get_value(self, vm: &VirtualMachine) -> PyResult<(Option<Vec<u8>>, isize)> {
268-
let sep = if let Some(s) = self.sep {
269-
let sep = s.elements;
270-
if sep.is_empty() {
271-
return Err(vm.new_value_error("empty separator".to_owned()));
272-
}
273-
Some(sep)
274-
} else {
275-
None
276-
};
277-
Ok((sep, self.maxsplit))
278-
}
279-
}
280-
281-
#[derive(FromArgs)]
282-
pub struct ByteInnerExpandtabsOptions {
283-
#[pyarg(positional_or_keyword, optional = true)]
284-
tabsize: OptionalArg<PyIntRef>,
285-
}
286-
287-
impl ByteInnerExpandtabsOptions {
288-
pub fn get_value(self) -> usize {
289-
match self.tabsize.into_option() {
290-
Some(int) => int.as_bigint().to_usize().unwrap_or(0),
291-
None => 8,
292-
}
293-
}
294-
}
258+
pub type ByteInnerSplitOptions = pystr::SplitArgs<PyByteInner, [u8], u8>;
295259

296260
#[derive(FromArgs)]
297261
pub struct ByteInnerSplitlinesOptions {
@@ -970,19 +934,13 @@ impl PyByteInner {
970934
where
971935
F: Fn(&[u8], &VirtualMachine) -> PyObjectRef,
972936
{
973-
let (sep, maxsplit) = options.get_value(vm)?;
974-
let sep_ref = match sep {
975-
Some(ref v) => Some(&v[..]),
976-
None => None,
977-
};
978937
let elements = self.elements.py_split(
979-
sep_ref,
980-
maxsplit,
938+
options,
981939
vm,
982940
|v, s, vm| v.split_str(s).map(|v| convert(v, vm)).collect(),
983941
|v, s, n, vm| v.splitn_str(n, s).map(|v| convert(v, vm)).collect(),
984942
|v, n, vm| v.py_split_whitespace(n, |v| convert(v, vm)),
985-
);
943+
)?;
986944
Ok(vm.ctx.new_list(elements))
987945
}
988946

@@ -995,19 +953,13 @@ impl PyByteInner {
995953
where
996954
F: Fn(&[u8], &VirtualMachine) -> PyObjectRef,
997955
{
998-
let (sep, maxsplit) = options.get_value(vm)?;
999-
let sep_ref = match sep {
1000-
Some(ref v) => Some(&v[..]),
1001-
None => None,
1002-
};
1003956
let mut elements = self.elements.py_split(
1004-
sep_ref,
1005-
maxsplit,
957+
options,
1006958
vm,
1007959
|v, s, vm| v.rsplit_str(s).map(|v| convert(v, vm)).collect(),
1008960
|v, s, n, vm| v.rsplitn_str(n, s).map(|v| convert(v, vm)).collect(),
1009961
|v, n, vm| v.py_rsplit_whitespace(n, |v| convert(v, vm)),
1010-
);
962+
)?;
1011963
elements.reverse();
1012964
Ok(vm.ctx.new_list(elements))
1013965
}
@@ -1050,8 +1002,8 @@ impl PyByteInner {
10501002
Ok((front, has_mid, back))
10511003
}
10521004

1053-
pub fn expandtabs(&self, options: ByteInnerExpandtabsOptions) -> Vec<u8> {
1054-
let tabsize = options.get_value();
1005+
pub fn expandtabs(&self, options: pystr::ExpandTabsArgs) -> Vec<u8> {
1006+
let tabsize = options.tabsize();
10551007
let mut counter: usize = 0;
10561008
let mut res = vec![];
10571009

@@ -1082,9 +1034,7 @@ impl PyByteInner {
10821034
res
10831035
}
10841036

1085-
pub fn splitlines(&self, options: ByteInnerSplitlinesOptions) -> Vec<&[u8]> {
1086-
let keepends = options.get_value();
1087-
1037+
pub fn splitlines(&self, options: pystr::SplitLinesArgs) -> Vec<&[u8]> {
10881038
let mut res = vec![];
10891039

10901040
if self.elements.is_empty() {
@@ -1093,7 +1043,7 @@ impl PyByteInner {
10931043

10941044
let mut prev_index = 0;
10951045
let mut index = 0;
1096-
let keep = if keepends { 1 } else { 0 };
1046+
let keep = if options.keepends { 1 } else { 0 };
10971047
let slice = &self.elements;
10981048

10991049
while index < slice.len() {
@@ -1435,13 +1385,23 @@ pub fn bytes_zfill(bytes: &[u8], width: usize) -> Vec<u8> {
14351385
}
14361386
}
14371387

1388+
impl PyCommonStringWrapper<[u8]> for PyByteInner {
1389+
fn as_ref(&self) -> &[u8] {
1390+
&self.elements
1391+
}
1392+
}
1393+
14381394
const ASCII_WHITESPACES: [u8; 6] = [0x20, 0x09, 0x0a, 0x0c, 0x0d, 0x0b];
14391395

1440-
impl PyCommonString<'_, u8> for [u8] {
1396+
impl PyCommonString<u8> for [u8] {
14411397
fn get_slice(&self, range: std::ops::Range<usize>) -> &Self {
14421398
&self[range]
14431399
}
14441400

1401+
fn is_empty(&self) -> bool {
1402+
Self::is_empty(self)
1403+
}
1404+
14451405
fn len(&self) -> usize {
14461406
Self::len(self)
14471407
}

vm/src/obj/objbytes.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ use std::ops::Deref;
44
use std::str::FromStr;
55

66
use super::objbyteinner::{
7-
ByteInnerExpandtabsOptions, ByteInnerFindOptions, ByteInnerNewOptions, ByteInnerPaddingOptions,
8-
ByteInnerSplitOptions, ByteInnerSplitlinesOptions, ByteInnerTranslateOptions, PyByteInner,
7+
ByteInnerFindOptions, ByteInnerNewOptions, ByteInnerPaddingOptions, ByteInnerSplitOptions,
8+
ByteInnerTranslateOptions, PyByteInner,
99
};
1010
use super::objint::PyIntRef;
1111
use super::objiter;
1212
use super::objslice::PySliceRef;
1313
use super::objstr::{PyString, PyStringRef};
1414
use super::objtype::PyClassRef;
15-
use super::pystr::PyCommonString;
15+
use super::pystr::{self, PyCommonString};
1616
use crate::cformat::CFormatString;
1717
use crate::function::{OptionalArg, OptionalOption};
1818
use crate::obj::objstr::do_cformat_string;
@@ -401,12 +401,12 @@ impl PyBytes {
401401
}
402402

403403
#[pymethod(name = "expandtabs")]
404-
fn expandtabs(&self, options: ByteInnerExpandtabsOptions) -> PyBytes {
404+
fn expandtabs(&self, options: pystr::ExpandTabsArgs) -> PyBytes {
405405
self.inner.expandtabs(options).into()
406406
}
407407

408408
#[pymethod(name = "splitlines")]
409-
fn splitlines(&self, options: ByteInnerSplitlinesOptions, vm: &VirtualMachine) -> PyResult {
409+
fn splitlines(&self, options: pystr::SplitLinesArgs, vm: &VirtualMachine) -> PyResult {
410410
let as_bytes = self
411411
.inner
412412
.splitlines(options)

0 commit comments

Comments
 (0)