forked from p15670423/monkey
Island: Add transform functions to make immutable copies of sequences
This commit is contained in:
parent
3fd7051869
commit
b3bfc598a3
|
@ -0,0 +1,36 @@
|
||||||
|
from typing import Any, MutableSequence, Sequence, Union
|
||||||
|
|
||||||
|
|
||||||
|
def make_immutable_nested_sequence(sequence_or_element: Union[Sequence, Any]) -> Sequence:
|
||||||
|
"""
|
||||||
|
Take a Sequence of Sequences (or other types) and return an immutable copy
|
||||||
|
|
||||||
|
Takes a Sequence of Sequences, for example `List[List[int, float]]]` and returns an immutable
|
||||||
|
copy. Note that if the Sequence does not contain other sequences, `make_sequence_immutable()`
|
||||||
|
will be more performant.
|
||||||
|
|
||||||
|
:param sequence_or_element: A nested sequence or an element from within a nested sequence
|
||||||
|
:return: An immutable copy of the sequence if `sequence_or_element` is a Sequence, otherwise
|
||||||
|
just return `sequence_or_element`
|
||||||
|
"""
|
||||||
|
if isinstance(sequence_or_element, str):
|
||||||
|
return sequence_or_element
|
||||||
|
|
||||||
|
if isinstance(sequence_or_element, Sequence):
|
||||||
|
return tuple(map(make_immutable_nested_sequence, sequence_or_element))
|
||||||
|
|
||||||
|
return sequence_or_element
|
||||||
|
|
||||||
|
|
||||||
|
def make_immutable_sequence(sequence: Sequence):
|
||||||
|
"""
|
||||||
|
Take a Sequence and return an immutable copy
|
||||||
|
|
||||||
|
:param sequence: A Sequence to create an immutable copy from
|
||||||
|
:return: An immutable copy of `sequence`
|
||||||
|
"""
|
||||||
|
|
||||||
|
if isinstance(sequence, MutableSequence):
|
||||||
|
return tuple(sequence)
|
||||||
|
|
||||||
|
return sequence
|
|
@ -0,0 +1,53 @@
|
||||||
|
from itertools import zip_longest
|
||||||
|
import pytest
|
||||||
|
from typing import MutableSequence, Sequence
|
||||||
|
|
||||||
|
from monkey_island.cc.models.transforms import (
|
||||||
|
make_immutable_nested_sequence,
|
||||||
|
make_immutable_sequence,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_make_immutable_sequence__list():
|
||||||
|
mutable_sequence = [1, 2, 3]
|
||||||
|
immutable_sequence = make_immutable_sequence(mutable_sequence)
|
||||||
|
|
||||||
|
assert isinstance(immutable_sequence, Sequence)
|
||||||
|
assert not isinstance(immutable_sequence, MutableSequence)
|
||||||
|
assert_sequences_equal(mutable_sequence, immutable_sequence)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"mutable_sequence", [
|
||||||
|
[1, 2, 3],
|
||||||
|
[[1, 2, 3], [4, 5, 6]],
|
||||||
|
[[1, 2, 3, [4, 5, 6]], [4, 5, 6]],
|
||||||
|
[8, [5.3, "invalid_comm_type"]]]
|
||||||
|
)
|
||||||
|
def test_make_immutable_nested_sequence(mutable_sequence):
|
||||||
|
immutable_sequence = make_immutable_nested_sequence(mutable_sequence)
|
||||||
|
|
||||||
|
assert isinstance(immutable_sequence, Sequence)
|
||||||
|
assert not isinstance(immutable_sequence, MutableSequence)
|
||||||
|
assert_sequences_equal(mutable_sequence, immutable_sequence)
|
||||||
|
|
||||||
|
|
||||||
|
def assert_sequence_immutable_recursive(sequence: Sequence):
|
||||||
|
assert not isinstance(sequence, MutableSequence)
|
||||||
|
|
||||||
|
for s in sequence:
|
||||||
|
if isinstance(s, str):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if isinstance(s, Sequence):
|
||||||
|
assert_sequence_immutable_recursive(s)
|
||||||
|
assert not isinstance(s, MutableSequence)
|
||||||
|
|
||||||
|
|
||||||
|
def assert_sequences_equal(a: Sequence, b: Sequence):
|
||||||
|
assert len(a) == len(b)
|
||||||
|
for i, j in zip_longest(a, b):
|
||||||
|
if isinstance(i, str) or not isinstance(i, Sequence):
|
||||||
|
assert i == j
|
||||||
|
else:
|
||||||
|
assert_sequences_equal(i, j)
|
Loading…
Reference in New Issue