11import functools
22import logging
3+ import warnings
4+ from collections import Counter
35
4- import ocdsmerge_rs .exceptions
56from django .conf import settings
67from ocdsextensionregistry import ProfileBuilder
78from ocdsextensionregistry .exceptions import ExtensionWarning
89from ocdsmerge_rs import Merger
10+ from ocdsmerge_rs .exceptions import DuplicateIdValueWarning , MergeError , MergeWarning
911
1012from process .models import CollectionFile , CollectionNote , CompiledRelease , Data
11- from process .util import create_note , create_warnings_note , get_or_create
13+ from process .util import create_note , get_or_create
1214
1315logger = logging .getLogger (__name__ )
1416
@@ -32,15 +34,37 @@ def save_compiled_release(merged, collection, ocid):
3234
3335
3436def compile_releases_by_ocdskit (collection , ocid , releases , extensions ):
35- with create_warnings_note ( collection , ExtensionWarning ):
37+ with warnings . catch_warnings ( record = True , action = "always" , category = ExtensionWarning ) as wlist :
3638 merger = _get_merger (frozenset (extensions ))
3739
40+ for w in filter_warnings (wlist , ExtensionWarning ):
41+ create_note (collection , CollectionNote .Level .WARNING , str (w .message ), data = {"type" : w .category .__name__ })
42+
3843 try :
39- with create_warnings_note ( collection , ocdsmerge_rs . exceptions . MergeWarning ):
44+ with warnings . catch_warnings ( record = True , action = "always" , category = MergeWarning ) as wlist :
4045 return merger .create_compiled_release (releases )
41- except ocdsmerge_rs .exceptions .MergeError as e :
46+
47+ notes = []
48+ paths = Counter ()
49+ for w in filter_warnings (wlist , DuplicateIdValueWarning ): # DuplicateIdValueWarning is the only MergeWarning
50+ notes .append (str (w .message ))
51+ paths [w .message .path ] += 1
52+
53+ if notes :
54+ create_note (
55+ collection ,
56+ CollectionNote .Level .WARNING ,
57+ notes ,
58+ data = {"type" : "DuplicateIdValueWarning" , "paths" : dict (paths )},
59+ )
60+ except MergeError as e :
4261 logger .exception ("OCID %s can't be compiled, skipping" , ocid )
43- create_note (collection , CollectionNote .Level .ERROR , f"OCID { ocid } can't be compiled" , data = str (e ))
62+ create_note (
63+ collection ,
64+ CollectionNote .Level .ERROR ,
65+ f"OCID { ocid } can't be compiled" ,
66+ data = {"type" : type (e ).__name__ , "message" : str (e ), ** vars (e )},
67+ )
4468
4569
4670@functools .lru_cache
@@ -51,3 +75,12 @@ def _get_merger(extensions):
5175 builder = ProfileBuilder (tag , extensions , standard_base_url = url )
5276 patched_schema = builder .patched_release_schema ()
5377 return Merger (rules = Merger .get_rules (Merger .dereference (patched_schema )))
78+
79+
80+ def filter_warnings (wlist , category ):
81+ """Yield warnings that match category, re-emitting non-matching warnings."""
82+ for w in wlist :
83+ if issubclass (w .category , category ):
84+ yield w
85+ else :
86+ warnings .warn_explicit (w .message , w .category , w .filename , w .lineno , source = w .source )
0 commit comments