Trước hết thì như nhiều bác đã nói trong này, không có khái niệm "ngôn ngữ thông dịch" hay "ngôn ngữ biên dịch", cái quyết định là cài đặt của ngôn ngữ chứ không phải bản thân ngôn ngữ đó.
Như C++ thường được coi là ngôn ngữ biên dịch nhưng thực ra vẫn có C++ interpreter (
https://root.cern/cling/).
Python cũng vậy. Bản chính thức của Python là CPython là một interpreter, nó đọc từng chỉ thị bytecode đọc đến đâu thì thực thi đến đó. Nhưng cũng có một số cài đặt khác không phải interpreter. Bác có nhắc đến PyPy, nó là JIT (Just-in-time) compiler, không phải interpreter. Có nghĩa khi thực thi bytecode thì nó dịch một phần hoặc toàn bộ ra mã máy rồi thực thi phần đó, cho nên hiệu năng hơn vài lần so với CPython.
JIT compiler thậm chí nhiều lúc còn có thể nhanh hơn cả compiler, vì nó có thông tin về kiến trúc máy tính được chạy hay tập dữ liệu đầu vào. Chẳng hạn một chương trình C++ nếu khi build chỉ tune cho kiến trúc x86 generic thì có thể sẽ chậm hơn chương trình Java chạy các đoạn mã sử dụng tập lệnh AVX512 do JIT compiler sinh ra.
Nói thêm thì còn một loại nữa là AOT (Ahead-of-time) compiler, tức khi cài chương trình thì nó dịch bycode / code toàn bộ ra mã máy thành file nhị phân. Nhưng lần sau khi chạy chương trình thì dùng file nhị phân đó. Đại diện là bộ ART của Android hay mới đây có cái Rosetta 2 của Mac M1.