Source code for jsonschema_diff.core.tools.context
from__future__importannotationsfromtypingimport(TYPE_CHECKING,Dict,Iterable,List,Mapping,Sequence,Type,TypeAlias,Union,)ifTYPE_CHECKING:fromjsonschema_diff.core.parameter_baseimportCompare# Key type accepted in rules: parameter name or Compare subclass
[docs]classRenderContextHandler:"""Expand context comparators based on pair- and directed-dependency rules."""@staticmethod
[docs]defresolve(*,pair_context_rules:PAIR_CONTEXT_RULES_TYPE,context_rules:CONTEXT_RULES_TYPE,for_render:Mapping[str,"Compare"],not_for_render:Mapping[str,"Compare"],)->Dict[str,"Compare"]:""" Build the final ordered context for rendering. Parameters ---------- pair_context_rules : Sequence[Sequence[RULE_KEY]] Undirected groups: if one member is rendered, pull the rest (order preserved). context_rules : Mapping[RULE_KEY, Sequence[RULE_KEY]] Directed dependencies: ``source → [targets...]``. for_render : Mapping[str, Compare] Initial items, order defines primary screen order. not_for_render : Mapping[str, Compare] Optional items that may be added by the rules. Returns ------- dict Ordered ``{name -> Compare}`` ready for UI. Algorithm (high-level) ---------------------- * Walk through *for_render* keys. * While iterating, append new candidates to the tail of the scan list. * A candidate is added once when first matched by any rule. """out:Dict[str,"Compare"]=dict(for_render)# preserves orderpool_not:Dict[str,"Compare"]=dict(not_for_render)# preserves insertion orderseq:List[str]=list(out.keys())# scan listin_out=set(seq)# O(1) membership checksdef_matches(rule:RULE_KEY,name:str,cmp_obj:"Compare")->bool:"""Return True if *rule* matches given *(name, object)* pair."""ifisinstance(rule,str):returnrule==name# rule is a comparator classtry:returnisinstance(cmp_obj,rule)exceptTypeError:returnFalsedef_expand(rule:RULE_KEY,pool:Mapping[str,"Compare"])->Iterable[str]:""" Yield keys from *pool* matching *rule* (order-stable). * String rule → single key. * Class rule → all keys whose comparator ``isinstance`` the class. """ifisinstance(rule,str):ifruleinpool:yieldrulereturnforn,objinlist(pool.items()):# snapshot to stay safe on ``del``try:ifisinstance(obj,rule):yieldnexceptTypeError:continuei=0whilei<len(seq):name=seq[i]cmp_obj=out[name]# 1) Undirected groupsforgroupinpair_context_rules:ifany(_matches(entry,name,cmp_obj)forentryingroup):forentryingroup:forcandin_expand(entry,pool_not):ifcandinin_out:continueout[cand]=pool_not[cand]seq.append(cand)in_out.add(cand)delpool_not[cand]# 2) Directed dependenciesforsource,targetsincontext_rules.items():if_matches(source,name,cmp_obj):forentryintargets:forcandin_expand(entry,pool_not):ifcandinin_out:continueout[cand]=pool_not[cand]seq.append(cand)in_out.add(cand)delpool_not[cand]i+=1returnout