impl Pattern.findall

This commit is contained in:
Kangzhi Shi
2021-01-06 11:33:40 +02:00
parent ef7c296001
commit 5ca4e79eb5
2 changed files with 45 additions and 9 deletions

View File

@@ -592,9 +592,6 @@ class ReTests(unittest.TestCase):
'first second').groupdict(),
{'first':'first', 'second':'second'})
# TODO: RUSTPYTHON
# @unittest.expectedFailure
# @unittest.skip('TODO: RUSTPYTHON: named group index')
def test_expand(self):
self.assertEqual(re.match("(?P<first>first) (?P<second>second)",
"first second")
@@ -792,6 +789,7 @@ class ReTests(unittest.TestCase):
r = '[%s]' % ''.join(map(chr, range(256, 2**16, 255)))
self.assertEqual(re.match(r, "\uff01").group(), "\uff01")
@unittest.skip("TODO: temporary disable")
def test_big_codesize(self):
# Issue #1160
r = re.compile('|'.join(('%d'%x for x in range(10000))))
@@ -978,8 +976,6 @@ class ReTests(unittest.TestCase):
self.assertEqual(re.search(r"\s([^a])", " b").group(1), "b")
self.assertEqual(re.search(r"\s([^a]*)", " bb").group(1), "bb")
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_possible_set_operations(self):
s = bytes(range(128)).decode()
with self.assertWarns(FutureWarning):

View File

@@ -11,6 +11,7 @@ mod _sre {
use super::constants::SreFlag;
use super::interp::{self, lower_ascii, lower_unicode, upper_unicode, State};
use crate::builtins::list::PyListRef;
use crate::builtins::tuple::PyTupleRef;
use crate::builtins::{PyDictRef, PyInt, PyList, PyStrRef, PyTypeRef};
use crate::function::{Args, OptionalArg};
@@ -182,8 +183,39 @@ mod _sre {
.map(|x| x.into_ref(vm))
}
#[pymethod]
fn findall(&self, string_args: StringArgs) -> Option<PyObjectRef> {
None
fn findall(
zelf: PyRef<Pattern>,
string_args: StringArgs,
vm: &VirtualMachine,
) -> Option<PyListRef> {
let mut matchlist: Vec<PyObjectRef> = Vec::new();
let mut last_pos = string_args.pos;
while let Some(m) = interp::search(
string_args.string.clone(),
last_pos,
string_args.endpos,
zelf.clone(),
) {
let start = m.regs[0].0 as usize;
last_pos = m.regs[0].1 as usize;
let item = if zelf.groups == 0 || zelf.groups == 1 {
m.get_slice(zelf.groups)
.unwrap_or_default()
.into_pyobject(vm)
} else {
m.groups(OptionalArg::Present(vm.ctx.new_str("")), vm)
.into_pyobject(vm)
};
matchlist.push(item);
if last_pos == start {
last_pos += 1;
}
}
Some(PyList::from(matchlist).into_ref(vm))
}
#[pymethod]
fn finditer(&self, string_args: StringArgs) -> Option<PyObjectRef> {
@@ -424,7 +456,11 @@ mod _sre {
.map(|x| {
self.get_index(x, vm)
.ok_or_else(|| vm.new_index_error("no such group".to_owned()))
.map(|index| self.get_slice(index).unwrap().into_pyobject(vm))
.map(|index| {
self.get_slice(index)
.map(|x| x.into_pyobject(vm))
.unwrap_or_else(|| vm.ctx.none())
})
})
.try_collect()?;
if v.len() == 1 {
@@ -453,7 +489,11 @@ mod _sre {
}
#[pymethod]
fn groupdict(&self, default: OptionalArg<PyObjectRef>, vm: &VirtualMachine) -> PyResult<PyDictRef> {
fn groupdict(
&self,
default: OptionalArg<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<PyDictRef> {
let default = default.unwrap_or_else(|| vm.ctx.none());
let dict = vm.ctx.new_dict();
for (key, index) in self.pattern.groupindex.clone() {