Quick answer: set_allowed and set_blocked mutate one shared event filter. A later set_allowed can re-permit what you blocked. Configure the filter once, in one place.
A game calls pygame.event.set_blocked(pygame.MOUSEMOTION) to skip mouse-move spam, but the events keep coming — another part of the code called set_allowed later.
One Shared Filter
There’s a single event-allowed filter. set_blocked(x) removes x from it; set_allowed(x) adds it back. They’re not separate lists — whichever runs last for a given type wins.
Configure It Once
# at startup, in one place
pygame.event.set_allowed(None) # block everything
pygame.event.set_allowed([
pygame.QUIT,
pygame.KEYDOWN, pygame.KEYUP,
pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP,
]) # then allow exactly what you handle
An allow-list is clearer than scattered block calls: it states exactly which events your loop cares about, and nothing else gets through.
set_allowed(None) Resets
set_allowed(None) blocks everything; set_blocked(None) allows everything. Start from a known state, then build your list — don’t append to whatever the filter happened to be.
Pump Still Processes Blocked Events
Blocked events are still generated — they just don’t reach event.get(). pygame.event.pump() and internal state still update. Blocking is a get-filter, not a global mute.
Verifying
MOUSEMOTION no longer appears in your event loop. The events you allow-listed all arrive. No other code re-permits what you excluded.
“One filter, last-write-wins. Set the allow-list once at startup instead of scattering block calls.”
An explicit allow-list also documents your input surface — anyone reading it knows exactly which events the game handles.