@@ -197,46 +197,54 @@ def _resolve_external_content(self) -> list[nodes.Node]:
197197# Extra context register and management.
198198# ======================================
199199
200- class ContextGenerator (ABC ):
201- name : str
200+ class ContextGenerator (ABC ): ...
202201
203202class FullPhaseContextGenerator (ContextGenerator ):
204203 @abstractmethod
205- def generate (self , caller : Caller , node : pending_node ) -> dict [ str , Any ] : ...
204+ def generate (self , caller : Caller , n : pending_node ) -> Context : ...
206205
207206class ParsePhaseContextGenerator (ContextGenerator ):
208207 @abstractmethod
209- def generate (self , caller : ParseCaller , node : pending_node ) -> dict [ str , Any ] : ...
208+ def generate (self , caller : ParseCaller , n : pending_node ) -> Context : ...
210209
211210class TransformPhaseContextGenerator (ContextGenerator ):
212211 @abstractmethod
213- def generate (self , caller : TransformCaller , node : pending_node ) -> dict [ str , Any ] : ...
212+ def generate (self , caller : TransformCaller , n : pending_node ) -> Context : ...
214213
215214class ExtraContextRegistry :
215+ names : set [str ]
216216 full : dict [str , FullPhaseContextGenerator ]
217217 parsing : dict [str , ParsePhaseContextGenerator ]
218218 parsed : dict [str , ParsePhaseContextGenerator ]
219219 post_transform : dict [str , TransformPhaseContextGenerator ]
220220
221221 def __init__ (self ) -> None :
222+ self .names = set ()
222223 self .full = {}
223- self .parsing_ctx = {}
224+ self .parsing = {}
224225 self .parsed = {}
225226 self .post_transform = {}
226227
227- def add_full_phase_context (self , ctxgen : FullPhaseContextGenerator ):
228- self .full ['_' + ctxgen .name ] = ctxgen
228+ def _name_dedup (self , name : str ) -> None :
229+ if name in self .names :
230+ raise ValueError (f'Context generator { name } already exists' )
231+ self .names .add (name )
232+
233+ def add_full_phase_context (self , name : str , ctxgen : FullPhaseContextGenerator ):
234+ self ._name_dedup (name )
235+ self .full ['_' + name ] = ctxgen
229236
230- def add_parse_phase_context (
231- self , phase : Literal [ Phase . Parsing , Phase . Parsed ], ctxgen : ParsePhaseContextGenerator ,
232- ) -> None :
233- if phase == Phase . Parsing :
234- self . parsing [ '_' + ctxgen . name ] = ctxgen
235- else :
236- self .parsed ['_' + ctxgen . name ] = ctxgen
237+ def add_parsing_phase_context ( self , name : str , ctxgen : ParsePhaseContextGenerator ) -> None :
238+ self . _name_dedup ( name )
239+ self . parsing [ '_' + name ] = ctxgen
240+
241+ def add_parsed ( self , name : str , ctxgen : ParsePhaseContextGenerator ) -> None :
242+ self . _name_dedup ( name )
243+ self .parsed ['_' + name ] = ctxgen
237244
238- def add_transform_generator (self , ctxgen : TransformPhaseContextGenerator ) -> None :
239- self .post_transform ['_' + ctxgen .name ] = ctxgen
245+ def add_transform_generator (self , name : str , ctxgen : TransformPhaseContextGenerator ) -> None :
246+ self ._name_dedup (name )
247+ self .post_transform ['_' + name ] = ctxgen
240248
241249
242250EXTRACTX_REGISTRY = ExtraContextRegistry ()
@@ -246,49 +254,40 @@ class _ExtraContextGenerator:
246254 @classmethod
247255 def safe_generate (cls , name : str , gen : Callable [[], None ], node : pending_node ):
248256 try :
249- # ctxgen.generate can be user-defined code,
250- # exception of any kind are possible.
257+ # ctxgen.generate can be user-defined code, exception of any kind are possible.
251258 gen ()
252259 except Exception :
253- reporter = utils .Reporter (f'Failed to generate extra context { name } :' )
260+ reporter = utils .Reporter (f'Failed to generate extra context { name } :' , '' )
254261 reporter .code (traceback .format_exc ())
255262 node += reporter
256263
257264 @classmethod
258265 def full (cls , caller : Caller , n : pending_node ) -> None :
259- ctx = {}
260266 for name , ctxgen in EXTRACTX_REGISTRY .full .items ():
261267 def gen ():
262- ctx [name ] = ctxgen .generate (caller , n ),
268+ n . extra [name ] = ctxgen .generate (caller , n )
263269 cls .safe_generate (name , gen , n )
264- n .extra .append (ctx )
265270
266271 @classmethod
267272 def on_parsing (cls , caller : ParseCaller , n : pending_node ) -> None :
268- ctx = {}
269273 for name , ctxgen in EXTRACTX_REGISTRY .parsing .items ():
270274 def gen ():
271- ctx [name ] = ctxgen .generate (caller , n ),
275+ n . extra [name ] = ctxgen .generate (caller , n )
272276 cls .safe_generate (name , gen , n )
273- n .extra .append (ctx )
274277
275278 @classmethod
276279 def on_parsed (cls , caller : ParseCaller , n : pending_node ) -> None :
277- ctx = {}
278280 for name , ctxgen in EXTRACTX_REGISTRY .parsed .items ():
279281 def gen ():
280- ctx [name ] = ctxgen .generate (caller , n ),
282+ n . extra [name ] = ctxgen .generate (caller , n )
281283 cls .safe_generate (name , gen , n )
282- n .extra .append (ctx )
283284
284285 @classmethod
285286 def on_post_transform (cls , caller : TransformCaller , n : pending_node ) -> None :
286- ctx = {}
287287 for name , ctxgen in EXTRACTX_REGISTRY .post_transform .items ():
288288 def gen ():
289- ctx [name ] = ctxgen .generate (caller , n ),
289+ n . extra [name ] = ctxgen .generate (caller , n )
290290 cls .safe_generate (name , gen , n )
291- n .extra .append (ctx )
292291
293292# ===============
294293# Render workflow
0 commit comments