|
5 | 5 | import itertools |
6 | 6 | from .converter import SubtypeVar |
7 | 7 | from .exceptions import ( |
8 | | - FileFormatsError, |
9 | 8 | FormatMismatchError, |
10 | 9 | FormatConversionError, |
11 | 10 | FormatRecognitionError, |
12 | 11 | ) |
13 | 12 | from .utils import ( |
14 | 13 | classproperty, |
15 | 14 | subpackages, |
| 15 | + add_exc_note, |
16 | 16 | to_mime_format_name, |
17 | 17 | from_mime_format_name, |
18 | 18 | IANA_MIME_TYPE_REGISTRIES, |
@@ -51,18 +51,6 @@ def matches(cls, values) -> bool: |
51 | 51 | else: |
52 | 52 | return True |
53 | 53 |
|
54 | | - @classproperty |
55 | | - def namespace(cls): |
56 | | - """The "namespace" the format belongs to under the "fileformats" umbrella |
57 | | - namespace""" |
58 | | - module_parts = cls.__module__.split(".") |
59 | | - if module_parts[0] != "fileformats": |
60 | | - raise FileFormatsError( |
61 | | - f"Cannot create reversible MIME type for {cls} as it is not in the " |
62 | | - "fileformats namespace" |
63 | | - ) |
64 | | - return module_parts[1].replace("_", "-") |
65 | | - |
66 | 54 | @classproperty |
67 | 55 | def all_types(self): |
68 | 56 | return itertools.chain(FileSet.all_formats, Field.all_fields) |
@@ -195,34 +183,52 @@ def from_mime(cls, mime_string): |
195 | 183 | klass = getattr(module, class_name) |
196 | 184 | except AttributeError: |
197 | 185 | if "+" in format_name: |
198 | | - qualifier_names, classified_name = format_name.split("+") |
199 | | - try: |
200 | | - classifiers = [ |
201 | | - getattr(module, from_mime_format_name(q)) |
202 | | - for q in qualifier_names.split(".") |
203 | | - ] |
204 | | - except AttributeError: |
205 | | - raise FormatRecognitionError( |
206 | | - f"Could not load classifiers [{qualifier_names}] from " |
207 | | - f"fileformats.{namespace}, corresponding to MIME, " |
208 | | - f"or MIME-like, type {mime_string}" |
209 | | - ) from None |
210 | | - try: |
211 | | - classified = getattr( |
212 | | - module, from_mime_format_name(classified_name) |
| 186 | + if "_" in namespace: |
| 187 | + parent_namespace = namespace.split("_")[0] |
| 188 | + parent_module = importlib.import_module( |
| 189 | + "fileformats." + parent_namespace |
213 | 190 | ) |
214 | | - except AttributeError: |
| 191 | + else: |
| 192 | + parent_namespace = parent_module = None |
| 193 | + |
| 194 | + def get_format(mime_name): |
| 195 | + name = from_mime_format_name(mime_name) |
| 196 | + try: |
| 197 | + return getattr(module, name) |
| 198 | + except AttributeError: |
| 199 | + if parent_module: |
| 200 | + try: |
| 201 | + return getattr(parent_module, name) |
| 202 | + except AttributeError: |
| 203 | + pass |
| 204 | + err_msg_part = f" or fileformats.{parent_namespace}" |
| 205 | + else: |
| 206 | + err_msg_part = "" |
| 207 | + raise FormatRecognitionError( |
| 208 | + f"Could not load format class {name} (from " |
| 209 | + f"'{mime_name}') fileformats.{namespace}" |
| 210 | + f"{err_msg_part} corresponding " |
| 211 | + f"to MIME, or MIME-like, type {mime_string}" |
| 212 | + ) from None |
| 213 | + |
| 214 | + classifiers_str, classified_name = format_name.split("+") |
| 215 | + classifiers = [get_format(c) for c in classifiers_str.split(".")] |
| 216 | + try: |
| 217 | + classified = get_format(classified_name) |
| 218 | + except FormatRecognitionError as e: |
215 | 219 | try: |
216 | 220 | classified = cls.generically_classifies_by_name[ |
217 | 221 | classified_name |
218 | 222 | ] |
219 | 223 | except KeyError: |
220 | | - raise FormatRecognitionError( |
221 | | - f"Could not load classified class '{classified_name}' from " |
222 | | - f"fileformats.{namespace} or list of generic types " |
223 | | - f"({list(cls.generically_classifies_by_name)}), " |
224 | | - f"corresponding to MIME, or MIME-like, type {mime_string}" |
225 | | - ) from None |
| 224 | + add_exc_note( |
| 225 | + e, |
| 226 | + ( |
| 227 | + "neither list of generic types " |
| 228 | + f"({list(cls.generically_classifies_by_name)})" |
| 229 | + ), |
| 230 | + ) |
| 231 | + raise e |
226 | 232 | klass = classified[classifiers] |
227 | 233 | else: |
228 | 234 | raise FormatRecognitionError( |
|
0 commit comments