The object has died (overwritten or deleted) and cannot be mutated
MrIbrahem opened this issue · 3 comments
I'm encountering a DeadIndexError when attempting to access the name property of a template after parsing and editting Wikitext containing nested templates. Here's a minimal example to reproduce the issue:
import wikitextparser as wtp
text = "{{Ficha de medicamento| Drugs.com = {{drugs.com|monograph|alitretinoin}}}}"
parsed = wtp.parse(text)
n = 0
for template in parsed.templates:
n += 1
print(f'template {n}:')
print(template)
na = template.name
normal = template.normal_name()
print(f'normal: {normal}')
for arg in template.arguments:
arg.value = arg.value.rstrip() + '\n'
error:
Traceback (most recent call last):
File "I:\mdwiki\pybot\md_core\tests7.py", line 10, in <module>
na = template.name
^^^^^^^^^^^^^
File "C:\Program Files\Python311\Lib\site-packages\wikitextparser\_parser_function.py", line 95, in name
return self(2, -2)
^^^^^^^^^^^
File "C:\Program Files\Python311\Lib\site-packages\wikitextparser\_wikitext.py", line 317, in __call__
else (s + start if start >= 0 else e + start) : e
~~^~~~~~~
File "C:\Program Files\Python311\Lib\site-packages\wikitextparser\_wikitext.py", line 173, in __add__
raise DeadIndexError(
wikitextparser._wikitext.DeadIndexError: this usually means that the object has died (overwritten or deleted) and cannot be mutated
@coderabbitai found a solution to this problem
When the code runs in the first template no error occurs, but I changed the value of the argument which is the second template in parsed.templates, and when the code starts running in the second template the error occurs.
When the value of the last argument in the first template is modified, all objects that are entirely contained within that specific portion of the wikitext—meaning those that both start and end within that area, as opposed to parent objects whose start and end tokens extend beyond it—are invalidated or overwritten. This includes the second template, as it falls within the affected segment.
This behavior is expected. While tracking all changes within a text segment might be possible (and some early wikitextparser versions attempted this), the process is computationally too expensive and can be unintuitive. Therefore, it's not currently implemented.
Fortunately, a simple workaround exists: iterate over templates in reverse order:
-for template in parsed.templates:
+for template in reversed(parsed.templates):
This works because WikiText.templates
are returned in the order they appear in the text. Modifying a later template never invalidates its preceding parent.