Afaik, you could have multiple CPython interpreters per process before, but the GIL was global to the address space, not a per interpreter instance. I believe the GIL work also put interpreter state behind a single struct instead of a handful of global variables.
This could be totes wrong, all from memory, too tired to fact check.
Putting interpreter state behind a struct allows for multiple CPython instances per address space and each can no run on their own thread independently, they all get their own GI(L) lock. These interpreter instances would still have their own Global to This interpreter Lock, but not a Global lock for all CPython interpreters running in a process (like it was before with interpreter state in globals).
Unrelated but complementary. We could remove the GIL, making Python multithreaded, but if interpreter state was still in a handful globals, you could have only one interpreter per process.
This could be totes wrong, all from memory, too tired to fact check.