Skip to content

Commit 8d2a298

Browse files
committed
Remove stale data when generating documentation
Modify documentation generation (specifically, the custom domain) to keep track of what document name provided objects or attributes. Use this to actually implement the domain's `clear_doc` method. This fixes incremental builds "seeing" stale state, which results in warning spam and incorrect output. This is mainly an issue for local builds, since the builds that actually get published are always clean, but it fixes a development pain point.
1 parent 7255e42 commit 8d2a298

1 file changed

Lines changed: 47 additions & 22 deletions

File tree

_extensions/cps/__init__.py

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def run(self):
116116
# Record object on domain
117117
env = self.state.document.settings.env
118118
domain = cast(CpsDomain, env.get_domain('cps'))
119-
domain.note_object(name, simplify_text(content))
119+
domain.note_object(name, env.docname, simplify_text(content))
120120

121121
# Return generated nodes
122122
return [section]
@@ -285,7 +285,7 @@ def run(self):
285285
# Record object on domain
286286
env = self.state.document.settings.env
287287
domain = cast(CpsDomain, env.get_domain('cps'))
288-
domain.note_attribute(name, context, typedesc, typeformat,
288+
domain.note_attribute(name, env.docname, context, typedesc, typeformat,
289289
required=required, default=default,
290290
description=simplify_text(content),
291291
node=section)
@@ -309,28 +309,43 @@ class Attribute:
309309
required: bool
310310
default: Any
311311

312+
# =============================================================================
313+
@dataclass
314+
class AttributeRef:
315+
docname: str
316+
attribute: Attribute
317+
312318
# =============================================================================
313319
class AttributeSet:
314320

315321
# -------------------------------------------------------------------------
316-
def __init__(self, name, context, attribute, node):
322+
def __init__(self, name, docname, context, attribute, node):
317323
self.name = name
318-
self.instances = [attribute]
319-
self.context = {c: (0, node) for c in context}
324+
self.instances = [AttributeRef(docname, attribute)]
325+
self.context = {c: (0, docname, node) for c in context}
320326

321327
# -------------------------------------------------------------------------
322-
def overload(self, context, attribute, node):
328+
def clear_doc(self, docname):
329+
ni = [ref for ref in self.instances if ref.docname != docname]
330+
self.instances = ni
331+
332+
for key, (_, fn, _) in list(self.context.items()):
333+
if fn == docname:
334+
del self.context[key]
335+
336+
# -------------------------------------------------------------------------
337+
def overload(self, docname, context, attribute, node):
323338
i = len(self.instances)
324-
self.instances.append(attribute)
339+
self.instances.append(AttributeRef(docname, attribute))
325340
for c in context:
326341
if c in self.context:
327342
logger.warning('duplicate declaration of attribute '
328343
f'{self.name!r} on object {c!r}',
329344
location=node)
330345
logger.warning(f'{self.name!r} was previously declared here',
331-
location=self.context[c][1])
346+
location=self.context[c][2])
332347
else:
333-
self.context[c] = (i, node)
348+
self.context[c] = (i, docname, node)
334349

335350
# =============================================================================
336351
class CpsDomain(domains.Domain):
@@ -375,18 +390,28 @@ def attributes(self):
375390
return self.data.setdefault('attributes', {})
376391

377392
# -------------------------------------------------------------------------
378-
def note_object(self, name, description):
393+
def clear_doc(self, docname):
394+
for key, (fn, _) in list(self.objects.items()):
395+
if fn == docname:
396+
del self.objects[key]
397+
398+
for attr in self.attributes.values():
399+
attr.clear_doc(docname)
400+
401+
# -------------------------------------------------------------------------
402+
def note_object(self, name, docname, description):
379403
if name not in self.objects:
380-
self.objects[name] = description
404+
self.objects[name] = (docname, description)
381405

382406
# -------------------------------------------------------------------------
383-
def note_attribute(self, name, context, typedesc, typeformat,
407+
def note_attribute(self, name, docname, context, typedesc, typeformat,
384408
required, default, description, node):
385409
a = Attribute(typedesc, typeformat, description, required, default)
386410
if name not in self.attributes:
387-
self.attributes[name] = AttributeSet(name, context, a, node)
411+
s = AttributeSet(name, docname, context, a, node)
412+
self.attributes[name] = s
388413
else:
389-
self.attributes[name].overload(context, a, node)
414+
self.attributes[name].overload(docname, context, a, node)
390415

391416
# -------------------------------------------------------------------------
392417
def add_role(self, name, styles=None, parent=roles.generic_custom_role):
@@ -417,28 +442,28 @@ def write_schema(app, exception):
417442

418443
object_attributes = {}
419444
for attribute_set in domain.attributes.values():
420-
for i, attribute in enumerate(attribute_set.instances):
445+
for i, ref in enumerate(attribute_set.instances):
421446
schema.add_attribute(
422447
attribute_set.name, i,
423-
attribute.typedesc,
424-
attribute.typeformat,
425-
attribute.description,
426-
attribute.required,
427-
attribute.default,
448+
ref.attribute.typedesc,
449+
ref.attribute.typeformat,
450+
ref.attribute.description,
451+
ref.attribute.required,
452+
ref.attribute.default,
428453
)
429454

430455
for context, attribute_ref in attribute_set.context.items():
431456
attribute = (
432457
attribute_set.name,
433458
attribute_ref[0],
434-
attribute_set.instances[attribute_ref[0]].required
459+
attribute_set.instances[attribute_ref[0]].attribute.required
435460
)
436461
if context in object_attributes:
437462
object_attributes[context].append(attribute)
438463
else:
439464
object_attributes[context] = [attribute]
440465

441-
for name, description in domain.objects.items():
466+
for name, (_, description) in domain.objects.items():
442467
schema.add_object_type(name, description, object_attributes[name])
443468

444469
output_path = os.path.join(app.outdir, config.schema_filename)

0 commit comments

Comments
 (0)