diff --git a/src/mwparserfromhell/wikicode.py b/src/mwparserfromhell/wikicode.py index 482d937..b6c379f 100644 --- a/src/mwparserfromhell/wikicode.py +++ b/src/mwparserfromhell/wikicode.py @@ -160,6 +160,12 @@ def getter(i: int, node: Node) -> Generator[tuple[int, Node]]: else: inodes = enumerate(self.nodes) for i, node in inodes: + if ( + forcetype is Wikilink + and isinstance(node, Wikilink) + and not str(node.title) + ): + continue if (forcetype is None or isinstance(node, forcetype)) and match( cast(N, node) ): diff --git a/tests/test_parser.py b/tests/test_parser.py index 8ec4a40..2c921f4 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -102,3 +102,29 @@ def test_skip_style_tags(pyparser): without_style = parser.Parser().parse(text, skip_style_tags=True) assert_wikicode_equal(a, with_style) assert_wikicode_equal(b, without_style) + + +@pytest.mark.parametrize( + "text", + [ + "[[]]", + "[[|]]", + "[[|foo]]", + "[[|||]]", + ], +) +def test_empty_title_wikilink_filter_wikilinks(text): + """[[]] and [[|...]] have an empty title and should not be links. + + MediaWiki does not render these as hyperlinks; filter_wikilinks() should + not return false positives, while the parsed Wikilink node remains + available to tools that want to detect and fix invalid wikilinks. + Regression test for https://github.com/earwig/mwparserfromhell/issues/292. + """ + parsed = parser.Parser().parse(text) + assert parsed.filter_wikilinks() == [] + assert parsed.filter(forcetype=Wikilink) == [] + assert list(parsed.ifilter(forcetype=Wikilink)) == [] + assert isinstance(parsed.get(0), Wikilink) + assert parsed.get(0) in parsed.filter() + assert str(parsed) == text