PEP 852, do Peter Bierma trình bày ngày 10/11/2026, đề xuất thêm một bộ hàm mới vào C API để extension viết bằng C có thể định nghĩa hàm async và dùng await như code Python thuần. Đề xuất đang ở trạng thái Draft, nhắm tới Python 3.16, xây dựng trên thư viện PyAwaitable mà tác giả đã thử nghiệm từ đầu năm 2024.

Nếu bạn chỉ viết Python thuần, tin này có vẻ xa lạ. Nhưng mọi thư viện nhanh bạn dùng — pydantic-core, driver database, HTTP client — đều có lõi viết bằng C hoặc Rust, và khi lõi đó không viết được code async, cả hệ sinh thái phải đi đường vòng.

Vấn đề hiện tại: C API không biết async là gì

Python thuần đã có async/await từ 3.5 (PEP 492), nhưng C API vẫn không có interface chính thức để định nghĩa coroutine function. Muốn viết hàm async trong C chỉ có ba cách, đều dở: viết phần async bằng Python thuần rồi gọi API event loop từ C (mất hiệu năng); tự cài giao thức coroutine bằng tay (phức tạp, khó bảo trì); hoặc dựa vào binding generator như PyO3, pybind11 (không wrap được API ngoài CPython).

Hệ quả đã rõ: mypyc vẫn chưa hỗ trợ đầy đủ tính năng async vì phải tự xây kiểu coroutine từ đầu; PyO3 theo dõi hỗ trợ async fn từ năm 2021 mà vẫn thiếu async context manager.

PEP 852 đề xuất những gì

Trung tâm của đề xuất là kiểu đối tượng mới PyAsync: một object mờ triển khai giao thức Coroutine, được asyncio.iscoroutine() nhận diện, dùng được với asyncio.create_task() và cả các event loop khác.

Các hàm chính:

  • PyAsync_New() — tạo một đối tượng async rỗng.
  • PyAsync_AddAwait() — xếp một awaitable vào hàng đợi kèm callback.
  • PyAsync_SetResult() — đặt giá trị await trả về (mặc định None).
  • PyAsync_SetArbValue() / PyAsync_GetArbValue() — giữ một con trỏ dữ liệu chung cho callback (C không có closure).

Kèm theo PyAsync_AddExpr() (gọi hàm rồi await kết quả trong một bước) và PyAsync_Cancel() (hủy đối tượng).

Ví dụ trong PEP: chỉ vài chục dòng C là đủ để viết hàm tương đương async def await_from_c(func): return await func():

static int
return_result(PyObject *asyncobj, PyObject *result)
{
PyAsync_SetResult(asyncobj, result);
return 1;
}
/* Equivalent to: async def await_from_c(func): return await func() */
static PyObject *
await_from_c(PyObject *self, PyObject *func) /* METH_O */
{
PyObject *asyncobj = PyAsync_New();
if (asyncobj == NULL) {
return NULL;
}
if (PyAsync_AddExpr(asyncobj, PyObject_CallNoArgs(func), return_result, NULL) < 0) {
PyAsync_Cancel(asyncobj);
Py_DECREF(asyncobj);
return NULL;
}
return asyncobj;
}

Lưu ý: mỗi PyAsync chỉ await được một lần; hủy object chưa từng await sẽ phát RuntimeWarning như coroutine Python thuần.

Vì sao không để ở thư viện bên ngoài?

PyAwaitable ra đời đầu năm 2024 để thử nghiệm thiết kế ngoài core trước khi đưa vào CPython. Nó cần vào core vì: thêm dependency native vào C extension có rào cản rất cao; phân phối dependency native cực kỳ khó; và các binding library như PyO3 không thể wrap API không thuộc CPython. Victor Stinner khen API “được thiết kế tốt và tiện dùng”.

Điều này có ý nghĩa gì với bạn

Với đa số lập trình viên Django và FastAPI, PEP 852 không đổi một dòng code nào của bạn. Giá trị nằm ở tầng dưới: các thư viện lõi — driver database, HTTP client, bộ validate — sẽ viết được logic async ngay trong code native, thay vì vòng qua Python thuần. Về lâu dài, đó là những thư viện nhanh hơn, ít bug hơn. Nếu bạn viết C extension hoặc Cython, hãy theo dõi PEP này; còn hiện tại, thử trước qua thư viện PyAwaitable trên PyPI.

Bài viết liên quan

Câu hỏi thường gặp

PEP 852 đã được chấp thuận chưa?

Chưa. PEP đang ở trạng thái Draft, mới trình bày ngày 10/11/2026, mục tiêu là Python 3.16.

Code Python thuần của tôi có bị ảnh hưởng không?

Không. PEP 852 chỉ thêm hàm mới cho C API — code Python của bạn không đổi gì.

Khi nào tôi dùng được API này?

Nếu được chấp thuận, API sẽ có mặt trong Python 3.16 (beta 4/5/2027, chính thức 5/10/2027). Trong lúc chờ, thử thư viện PyAwaitable.

💬 Tin này ảnh hưởng tới dự án của bạn thế nào? Chia sẻ góc nhìn của bạn trong phần bình luận — mình đọc hết và sẽ tổng hợp những ý hay nhất.

Nguồn tham khảo