I thought the GIL was not held during execution of foreign code in python (at least that was one point given for why the GIL wasn't a big deal in practice).
No, it must be explicitly released. The GIL must be held to invoke almost all Python runtimes (main exceptions: acquiring the GIL, low-level allocator).