This made me remember that for-else statement exists.
I left this as-is because I find for-else statements hard to read (I never remember what it means!) and find this to be clearer even if there's a bit more boilerplate.
I avoid for-else for the same reason, but how about this:
if not any(subtopic in names for names, header, doc in subtopics[name]):
OK, I agree that's clearer. I used _ to match header and doc to make the line a bit shorter and to make it a bit clearer for me to read since those aren't being used.
This should work but we have _ as a function imported from mercurial.i18n.