Skip to content

Commit 00e8a42

Browse files
committed
adds '+tuple-of' mime string and changes ',' -> '|' to signify union types
1 parent eb4aff1 commit 00e8a42

File tree

2 files changed

+26
-14
lines changed

2 files changed

+26
-14
lines changed

fileformats/core/identification.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from .utils import add_exc_note, fspaths_converter, is_union
1212

1313
LIST_MIME = "+list-of"
14+
TUPLE_MIME = "+tuple-of"
1415
IANA_MIME_TYPE_REGISTRIES = [
1516
"application",
1617
"audio",
@@ -101,13 +102,18 @@ def from_mime(
101102
FormatRecognitionError
102103
if the MIME string does not correspond to a valid file format class
103104
"""
104-
if mime_str.endswith(LIST_MIME):
105-
item_mime = mime_str[: -len(LIST_MIME)]
105+
if match := re.match(
106+
r".*(" + re.escape(LIST_MIME) + "|" + re.escape(TUPLE_MIME) + r")$", mime_str
107+
):
108+
item_mime = mime_str[: -len(match.group(1))]
106109
if item_mime.startswith("[") and item_mime.endswith("]"):
107110
item_mime = item_mime[1:-1]
108-
return ty.List[from_mime(item_mime)] # type: ignore
109-
if "," in mime_str:
110-
return functools.reduce(operator.or_, (from_mime(t) for t in mime_str.split(","))) # type: ignore
111+
if match.group(1) == LIST_MIME:
112+
return list[from_mime(item_mime)] # type: ignore
113+
else:
114+
return tuple[from_mime(item_mime)] # type: ignore
115+
if "|" in mime_str:
116+
return functools.reduce(operator.or_, (from_mime(t) for t in mime_str.split("|"))) # type: ignore
111117
return fileformats.core.DataType.from_mime(mime_str)
112118

113119

@@ -149,14 +155,14 @@ def to_mime(
149155
f"Cannot convert {datatype} to official mime-type as it is not a proper "
150156
'file-type, please use official=False to convert to "mime-like" string instead'
151157
)
152-
if origin is list:
158+
if origin in (list, tuple):
153159
item_mime = to_mime(ty.get_args(datatype)[0], official=official)
154160
if "," in item_mime:
155161
item_mime = "[" + item_mime + "]"
156-
item_mime += LIST_MIME
162+
item_mime += LIST_MIME if origin is list else TUPLE_MIME
157163
return item_mime
158164
if is_union(datatype):
159-
return ",".join(to_mime(t, official=official) for t in ty.get_args(datatype))
165+
return "|".join(to_mime(t, official=official) for t in ty.get_args(datatype))
160166
if (
161167
isinstance(datatype, str)
162168
and datatype.startswith("fileformats.")

fileformats/core/tests/test_identification.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,27 @@ def test_to_from_mime_roundtrip() -> None:
3535

3636

3737
def test_to_from_list_mime_roundtrip() -> None:
38-
mime_str = to_mime(ty.List[Foo], official=False)
38+
mime_str = to_mime(list[Foo], official=False)
3939
assert isinstance(mime_str, str)
40-
assert from_mime(mime_str) == ty.List[Foo]
40+
assert from_mime(mime_str) == list[Foo]
41+
42+
43+
def test_to_from_tuple_mime_roundtrip() -> None:
44+
mime_str = to_mime(tuple[Foo], official=False)
45+
assert isinstance(mime_str, str)
46+
assert from_mime(mime_str) == tuple[Foo]
4147

4248

4349
def test_to_from_union_mime_roundtrip() -> None:
44-
mime_str = to_mime(ty.Union[Foo, Bar], official=False)
50+
mime_str = to_mime(Foo | Bar, official=False)
4551
assert isinstance(mime_str, str)
46-
assert from_mime(mime_str) == ty.Union[Foo, Bar]
52+
assert from_mime(mime_str) == Foo | Bar
4753

4854

4955
def test_to_from_list_union_mime_roundtrip() -> None:
50-
mime_str = to_mime(ty.List[ty.Union[Foo, Bar]], official=False)
56+
mime_str = to_mime(list[Foo | Bar], official=False)
5157
assert isinstance(mime_str, str)
52-
assert from_mime(mime_str) == ty.List[ty.Union[Foo, Bar]]
58+
assert from_mime(mime_str) == list[Foo | Bar]
5359

5460

5561
def test_official_mime_fail() -> None:

0 commit comments

Comments
 (0)