From db674c5505c83f41e93e08dca4a00e407260a7ca Mon Sep 17 00:00:00 2001 From: Tom Close Date: Fri, 20 Sep 2024 17:10:43 +1000 Subject: [PATCH] relaxes typed set to allow unused fspaths (will be dropped on copy if trimmed is provided) --- fileformats/generic/set.py | 15 +++------------ .../{test_directory.py => test_collection.py} | 19 +++++++++++++++---- 2 files changed, 18 insertions(+), 16 deletions(-) rename fileformats/generic/tests/{test_directory.py => test_collection.py} (80%) diff --git a/fileformats/generic/set.py b/fileformats/generic/set.py index 2f5ccec..f04d4b5 100644 --- a/fileformats/generic/set.py +++ b/fileformats/generic/set.py @@ -1,10 +1,9 @@ import typing as ty import itertools from pathlib import Path -from fileformats.core import FileSet, validated_property +from fileformats.core import FileSet from fileformats.core.mixin import WithClassifiers from fileformats.core.collection import TypedCollection -from fileformats.core.exceptions import FormatMismatchError class TypedSet(TypedCollection): @@ -27,16 +26,8 @@ def __repr__(self) -> str: paths_repr += ", ..." return f"{self.type_name}({paths_repr})" - @validated_property - def _all_paths_used(self) -> None: - all_contents_paths = set(itertools.chain(*(c.fspaths for c in self.contents))) - missing = self.fspaths - all_contents_paths - if missing: - contents_str = "\n".join(repr(c) for c in self.contents) - raise FormatMismatchError( - f"Paths {[str(p) for p in missing]} are not used by any of the " - f"contents of {self.type_name}:\n{contents_str}" - ) + def required_paths(self) -> ty.FrozenSet[Path]: + return frozenset(itertools.chain(*(c.required_paths() for c in self.contents))) class SetOf(WithClassifiers, TypedSet): # type: ignore[misc] diff --git a/fileformats/generic/tests/test_directory.py b/fileformats/generic/tests/test_collection.py similarity index 80% rename from fileformats/generic/tests/test_directory.py rename to fileformats/generic/tests/test_collection.py index 4cf2916..2ba751d 100644 --- a/fileformats/generic/tests/test_directory.py +++ b/fileformats/generic/tests/test_collection.py @@ -34,9 +34,11 @@ def test_directory_optional_contents(tmp_path): optional_dir = DirectoryOf[MyFormatGz, ty.Optional[YourFormat]](sample_dir) assert optional_dir.contents == [my_format] + your_format = YourFormat.sample(dest_dir=tmp_path) optional_dir = DirectoryOf[MyFormatGz, ty.Optional[YourFormat]](sample_dir) assert optional_dir.contents == [my_format, your_format] + required_dir = DirectoryOf[MyFormatGz, YourFormat](sample_dir) assert required_dir.contents == [my_format, your_format] @@ -47,15 +49,24 @@ def test_set_optional_contents(): sample_set = SetOf[MyFormatGz, YourFormat](my_format, your_format) assert sample_set.contents == [my_format, your_format] - with pytest.raises( - FormatMismatchError, match="are not used by any of the contents of " - ): - SetOf[MyFormatGz](my_format, your_format) + assert set(sample_set.required_paths()) == {my_format.fspath, your_format.fspath} + + sample_set = SetOf[MyFormatGz](my_format, your_format) + assert list(sample_set.required_paths()) == [my_format.fspath] + with pytest.raises( FormatMismatchError, match="Did not find the required content types" ): SetOf[MyFormatGz, YourFormat](my_format) + sample_set = SetOf[MyFormatGz, ty.Optional[YourFormat]](my_format) assert sample_set.contents == [my_format] + assert list(sample_set.required_paths()) == [my_format.fspath] + sample_set = SetOf[MyFormatGz, ty.Optional[YourFormat]](my_format, your_format) assert sample_set.contents == [my_format, your_format] + assert set(sample_set.required_paths()) == {my_format.fspath, your_format.fspath} + + sample_set = SetOf[ty.Optional[MyFormatGz]](my_format) + assert sample_set.contents == [my_format] + assert list(sample_set.required_paths()) == [my_format.fspath]