Exercise 2: Two Elements Sharing the Same id — Possible Solution
====================================================================
THE TEST
------------------------------
e1 =
(sibling 1)
e2 = (sibling 2, same id, different tag)
sel = parse_selector("#dup")
matches_selector(e1, sel)
matches_selector(e2, sel)
RESULT
------------------------------
e1 -> True
e2 -> True
Both report a match. Nothing here treats this as an error, a warning,
or even a noteworthy event -- each call to matches_selector runs
completely independently and returns the answer for that one element
in isolation.
WHY matches_simple CAN'T DETECT THIS
------------------------------
matches_simple's id check is exactly one line:
if simple.id is not None:
if element.attrs.get('id') != simple.id:
return False
This only ever looks at ONE element's own attrs dict and compares it
against the id string written in the selector. It has no parameter,
no global registry, and no way to ask "has any other element in this
document already claimed this id?" -- the function's entire signature
is (element, simple), a single element and a single simple selector.
Detecting a duplicate would require passing in something entirely
absent from this design: either the whole document (so the function
could search every other node before answering), or a separate,
pre-built id -> element table populated once per document and checked
against during matching.
Real browsers don't do this kind of duplicate detection at match-time
either -- id uniqueness is a validity rule enforced (or not) by HTML
validators and dev-tools warnings, not something baked into how a
document.querySelector('#dup')-style lookup itself works. A real
browser's own getElementById() simply returns the FIRST matching
element it finds and silently ignores the rest, which is a different
but related kind of "not really enforcing uniqueness" behavior.
WHY THIS WORKS AS AN ANSWER
------------------------------
The absence of duplicate-id detection isn't a bug to be fixed inside
matches_simple -- it's a direct, honest consequence of the function's
own scope: it was designed to answer "does this one element satisfy
this one simple selector," and answering "is this id unique across
the whole document" is a genuinely different question that would need
genuinely different inputs. A parser or validator layer built on top
of this matcher could add that check separately, but the matcher
itself, as designed, has no way to even ask the question.