add support for slices in Editops.__delitem__
This commit is contained in:
parent
f9e04fc2a9
commit
9c25719946
|
@ -5,7 +5,7 @@
|
|||
- fix hashing for custom classes
|
||||
|
||||
#### Added
|
||||
- add support for slicing in `Editops.__getitem__`
|
||||
- add support for slicing in `Editops.__getitem__`/`Editops.__delitem__`
|
||||
|
||||
### [2.5.0] - 2022-08-14
|
||||
#### Added
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit d937555ad76a6f1ed853ab4b7102a7b22b6f0fcf
|
||||
Subproject commit ac6ae2e61ecd3b6fc19ac7568c2db7ad8b100a47
|
|
@ -109,6 +109,7 @@ cdef extern from "rapidfuzz/details/types.hpp" namespace "rapidfuzz" nogil:
|
|||
RfEditops inverse() except +
|
||||
RfEditops remove_subsequence(const RfEditops& subsequence) except +
|
||||
RfEditops slice(int, int, int) except +
|
||||
void remove_slice(int, int, int) except +
|
||||
int64_t get_src_len()
|
||||
void set_src_len(int64_t)
|
||||
int64_t get_dest_len()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Tuple, List, Union, Any
|
||||
from typing import Tuple, List, Union
|
||||
|
||||
from . import (
|
||||
Hamming as Hamming,
|
||||
|
@ -50,7 +50,7 @@ class Editops:
|
|||
def copy(self) -> Editops: ...
|
||||
def inverse(self) -> Editops: ...
|
||||
def remove_subsequence(self, subsequence: Editops) -> Editops: ...
|
||||
def apply(self, source_string: str | bytes, destination_string: str | bytes) -> str: ...
|
||||
def apply(self, source_string: Union[str, bytes], destination_string: Union[str, bytes]) -> str: ...
|
||||
@property
|
||||
def src_len(self) -> int: ...
|
||||
@src_len.setter
|
||||
|
@ -59,8 +59,8 @@ class Editops:
|
|||
def dest_len(self) -> int: ...
|
||||
@dest_len.setter
|
||||
def dest_len(self, value: int) -> None: ...
|
||||
def __delitem__(self, item: int) -> None: ...
|
||||
def __getitem__(self, key: int) -> Editop: ...
|
||||
def __delitem__(self, item: Union[int, slice]) -> None: ...
|
||||
def __getitem__(self, key: Union[int, slice]) -> Editop: ...
|
||||
def __repr__(self) -> str: ...
|
||||
|
||||
class Opcode:
|
||||
|
@ -91,7 +91,7 @@ class Opcodes:
|
|||
def __len__(self) -> int: ...
|
||||
def copy(self) -> Opcodes: ...
|
||||
def inverse(self) -> Opcodes: ...
|
||||
def apply(self, source_string: str | bytes, destination_string: str | bytes) -> str: ...
|
||||
def apply(self, source_string: Union[str, bytes], destination_string: Union[str, bytes]) -> str: ...
|
||||
@property
|
||||
def src_len(self) -> int: ...
|
||||
@src_len.setter
|
||||
|
|
|
@ -500,15 +500,27 @@ cdef class Editops:
|
|||
def __len__(self):
|
||||
return self.editops.size()
|
||||
|
||||
def __delitem__(self, item):
|
||||
cdef Py_ssize_t index = item
|
||||
if index < 0:
|
||||
index += <Py_ssize_t>self.editops.size()
|
||||
def __delitem__(self, key):
|
||||
cdef Py_ssize_t index
|
||||
cdef Py_ssize_t start, stop, step
|
||||
|
||||
if index < 0 or index >= <Py_ssize_t>self.editops.size():
|
||||
raise IndexError("Editops index out of range")
|
||||
if isinstance(key, int):
|
||||
index = key
|
||||
if index < 0:
|
||||
index += <Py_ssize_t>self.editops.size()
|
||||
|
||||
self.editops.erase(self.editops.begin() + index)
|
||||
if index < 0 or index >= <Py_ssize_t>self.editops.size():
|
||||
raise IndexError("Editops index out of range")
|
||||
|
||||
self.editops.erase(self.editops.begin() + index)
|
||||
elif isinstance(key, slice):
|
||||
start, stop, step = key.indices(<Py_ssize_t>self.editops.size())
|
||||
if step < 0:
|
||||
raise ValueError("step sizes below 0 lead to an invalid order of editops")
|
||||
|
||||
self.editops.remove_slice(start, stop, step)
|
||||
else:
|
||||
raise TypeError("Expected index or slice")
|
||||
|
||||
def __getitem__(self, key):
|
||||
cdef Py_ssize_t index
|
||||
|
@ -535,7 +547,7 @@ cdef class Editops:
|
|||
(<Editops>x).editops = self.editops.slice(start, stop, step)
|
||||
return x
|
||||
else:
|
||||
raise TypeError("Expected index")
|
||||
raise TypeError("Expected index or slice")
|
||||
|
||||
def __repr__(self):
|
||||
return "Editops([" + ", ".join(repr(op) for op in self) + f"], src_len={self.editops.get_src_len()}, dest_len={self.editops.get_dest_len()})"
|
||||
|
|
|
@ -71,6 +71,7 @@ def test_editops_get_index():
|
|||
with pytest.raises(IndexError):
|
||||
ops[-6]
|
||||
|
||||
|
||||
def test_editops_get_slice():
|
||||
"""
|
||||
test __getitem__ with slice of Editops
|
||||
|
@ -110,6 +111,53 @@ def test_editops_get_slice():
|
|||
with pytest.raises(ValueError):
|
||||
ops[::-1]
|
||||
|
||||
|
||||
def test_editops_del_slice():
|
||||
"""
|
||||
test __delitem__ with slice of Editops
|
||||
"""
|
||||
ops = Editops(
|
||||
[
|
||||
("delete", 1, 1),
|
||||
("replace", 2, 1),
|
||||
("insert", 6, 5),
|
||||
("insert", 6, 6),
|
||||
("insert", 6, 7),
|
||||
],
|
||||
7,
|
||||
9,
|
||||
)
|
||||
|
||||
ops_list = [
|
||||
("delete", 1, 1),
|
||||
("replace", 2, 1),
|
||||
("insert", 6, 5),
|
||||
("insert", 6, 6),
|
||||
("insert", 6, 7),
|
||||
]
|
||||
|
||||
def del_test(key):
|
||||
_ops = ops[::]
|
||||
_ops_list = ops_list[::]
|
||||
del _ops[key]
|
||||
del _ops_list[key]
|
||||
assert _ops.as_list() == _ops_list
|
||||
|
||||
del_test(slice(None, 4, None))
|
||||
del_test(slice(1, None, None))
|
||||
del_test(slice(1, 4, None))
|
||||
del_test(slice(None, 4, 2))
|
||||
del_test(slice(1, None, 2))
|
||||
del_test(slice(1, 4, 2))
|
||||
|
||||
del_test(slice(None, -1, None))
|
||||
del_test(slice(-4, None, None))
|
||||
del_test(slice(-4, -1, None))
|
||||
del_test(slice(None, -1, 2))
|
||||
del_test(slice(-4, None, 2))
|
||||
del_test(slice(-4, -1, 2))
|
||||
|
||||
|
||||
def test_editops_inversion():
|
||||
"""
|
||||
test correct inversion of Editops
|
||||
|
|
Loading…
Reference in New Issue