C API Tính ổn định¶
Trừ khi có tài liệu khác, C API của Python chịu sự điều chỉnh của Chính sách tương thích ngược, PEP 387. Hầu hết các thay đổi đối với nó đều tương thích với nguồn (thường chỉ bằng cách thêm API mới). Việc thay đổi API hiện có hoặc xóa API chỉ được thực hiện sau một thời gian không dùng nữa hoặc để khắc phục các sự cố nghiêm trọng.
Giao diện nhị phân ứng dụng của CPython (ABI) tương thích tiến và lùi trên một bản phát hành nhỏ (nếu chúng được biên dịch theo cùng một cách; xem Cân nhắc về nền tảng bên dưới). Vì vậy, mã được biên dịch cho Python 3.10.0 sẽ hoạt động trên 3.10.8 và ngược lại, nhưng sẽ cần được biên dịch riêng cho 3.9.x và 3.11.x.
Có hai cấp độ C API với các kỳ vọng về độ ổn định khác nhau:
Unstable API, có thể thay đổi ở các phiên bản nhỏ mà không có thời gian ngừng sử dụng. Nó được đánh dấu bằng tiền tố
PyUnstabletrong tên.Limited API, tương thích với một số phiên bản nhỏ. Khi
Py_LIMITED_APIđược xác định, chỉ tập hợp con này được hiển thị từPython.h.
Những điều này sẽ được thảo luận chi tiết hơn dưới đây.
Các tên có tiền tố là dấu gạch dưới, chẳng hạn như _Py_InternalState, là API riêng tư có thể thay đổi mà không cần thông báo ngay cả trong các bản phát hành bản vá. Nếu bạn cần sử dụng API này, hãy cân nhắc liên hệ với CPython developers để thảo luận về việc thêm API công khai cho trường hợp sử dụng của bạn.
C không ổn định API¶
Bất kỳ API nào được đặt tên bằng tiền tố PyUnstable đều hiển thị chi tiết triển khai CPython và có thể thay đổi trong mọi bản phát hành nhỏ (ví dụ: từ 3.9 đến 3.10) mà không có bất kỳ cảnh báo ngừng sử dụng nào. Tuy nhiên, nó sẽ không thay đổi trong bản phát hành sửa lỗi (ví dụ: từ 3.10.0 đến 3.10.1).
Nó thường dành cho các công cụ chuyên dụng, cấp thấp như trình gỡ lỗi.
Các dự án sử dụng API này dự kiến sẽ tuân theo sự phát triển của CPython và dành nhiều nỗ lực hơn để điều chỉnh các thay đổi.
Giao diện nhị phân ứng dụng ổn định¶
Để đơn giản, tài liệu này nói về extensions, nhưng API giới hạn và ABI ổn định hoạt động theo cách tương tự cho tất cả các mục đích sử dụng API – ví dụ: nhúng Python.
Giới hạn C API¶
Python 3.2 đã giới thiệu Limited API, một tập hợp con của C API của Python. Các tiện ích mở rộng chỉ sử dụng Limited API có thể được biên dịch một lần và tải trên nhiều phiên bản Python. Nội dung của API giới hạn là listed below.
-
Py_LIMITED_API¶
Xác định macro này trước khi bao gồm
Python.hđể chọn tham gia chỉ sử dụng API giới hạn và chọn phiên bản API giới hạn.Xác định
Py_LIMITED_APIvới giá trịPY_VERSION_HEXtương ứng với phiên bản Python thấp nhất mà tiện ích mở rộng của bạn hỗ trợ. Tiện ích mở rộng sẽ tương thích với ABI với tất cả các bản phát hành Python 3 từ phiên bản được chỉ định trở đi và có thể sử dụng API giới hạn được giới thiệu cho phiên bản đó.Thay vì sử dụng trực tiếp macro
PY_VERSION_HEX, hãy mã hóa cứng một phiên bản nhỏ tối thiểu (ví dụ:0x030A0000cho Python 3.10) để ổn định khi biên dịch với các phiên bản Python trong tương lai.Bạn cũng có thể định nghĩa
Py_LIMITED_APIthành3. Điều này hoạt động tương tự như0x03020000(Python 3.2, phiên bản giới thiệu Limited API).
ABI ổn định¶
Để kích hoạt tính năng này, Python cung cấp Stable ABI: một tập hợp các ký hiệu sẽ vẫn tương thích với ABI trên các phiên bản Python 3.x.
Ghi chú
ABI ổn định ngăn ngừa các sự cố ABI, như lỗi liên kết do thiếu ký hiệu hoặc hỏng dữ liệu do thay đổi bố cục cấu trúc hoặc chữ ký hàm. Tuy nhiên, những thay đổi khác trong Python có thể thay đổi behavior của tiện ích mở rộng. Xem Chính sách tương thích ngược của Python (PEP 387) để biết chi tiết.
ABI ổn định chứa các ký hiệu hiển thị trong Limited API, nhưng cũng có các ký hiệu khác – ví dụ: các chức năng cần thiết để hỗ trợ các phiên bản cũ hơn của Limited API.
Trên Windows, các tiện ích mở rộng sử dụng ABI ổn định phải được liên kết với python3.dll thay vì thư viện dành riêng cho phiên bản như python39.dll.
Trên một số nền tảng, Python sẽ tìm và tải các tệp thư viện dùng chung có tên bằng thẻ abi3 (ví dụ: mymodule.abi3.so). Nó không kiểm tra xem các tiện ích mở rộng như vậy có phù hợp với ABI ổn định hay không. Người dùng (hoặc công cụ đóng gói của họ) cần đảm bảo rằng, chẳng hạn như các tiện ích mở rộng được xây dựng bằng API 3.10+ Limited không được cài đặt cho các phiên bản Python thấp hơn.
Tất cả các hàm trong ABI ổn định đều hiện diện dưới dạng các hàm trong thư viện dùng chung của Python, không chỉ dưới dạng macro. Điều này làm cho chúng có thể sử dụng được từ các ngôn ngữ không sử dụng bộ tiền xử lý C.
Phạm vi và hiệu suất API hạn chế¶
Mục tiêu của Limited API là cho phép mọi thứ có thể với C API đầy đủ, nhưng có thể kèm theo một hình phạt về hiệu suất.
Ví dụ: mặc dù PyList_GetItem() có sẵn nhưng biến thể macro “không an toàn” PyList_GET_ITEM() thì không. Macro có thể nhanh hơn vì nó có thể dựa vào chi tiết triển khai theo phiên bản cụ thể của đối tượng danh sách.
Nếu không xác định Py_LIMITED_API, một số hàm C API sẽ được nội tuyến hoặc thay thế bằng macro. Việc xác định Py_LIMITED_API sẽ vô hiệu hóa nội tuyến này, cho phép tính ổn định khi cấu trúc dữ liệu của Python được cải thiện nhưng có thể làm giảm hiệu suất.
Bằng cách loại bỏ định nghĩa Py_LIMITED_API, có thể biên dịch tiện ích mở rộng API giới hạn với ABI dành riêng cho phiên bản. Điều này có thể cải thiện hiệu suất cho phiên bản Python đó nhưng sẽ hạn chế khả năng tương thích. Việc biên dịch bằng Py_LIMITED_API sau đó sẽ mang lại một tiện ích mở rộng có thể được phân phối khi không có tiện ích mở rộng dành riêng cho phiên bản - ví dụ: đối với các bản phát hành trước của phiên bản Python sắp tới.
Giới hạn API Hãy cẩn thận¶
Lưu ý rằng việc biên dịch bằng Py_LIMITED_API là not đảm bảo hoàn toàn rằng mã tuân theo Limited API hoặc Stable ABI. Py_LIMITED_API chỉ đề cập đến các định nghĩa, nhưng API cũng bao gồm các vấn đề khác, chẳng hạn như ngữ nghĩa dự kiến.
Một vấn đề mà Py_LIMITED_API không đề phòng là gọi hàm với các đối số không hợp lệ ở phiên bản Python thấp hơn. Ví dụ: hãy xem xét một hàm bắt đầu chấp nhận NULL cho một đối số. Trong Python 3.9, NULL hiện chọn một hành vi mặc định, nhưng trong Python 3.8, đối số sẽ được sử dụng trực tiếp, gây ra sự cố và vô hiệu hóa NULL. Một đối số tương tự hoạt động cho các trường cấu trúc.
Một vấn đề khác là một số trường cấu trúc hiện không bị ẩn khi Py_LIMITED_API được xác định, mặc dù chúng là một phần của API Limited.
Vì những lý do này, chúng tôi khuyên bạn nên thử nghiệm tiện ích mở rộng với các phiên bản Python nhỏ all mà nó hỗ trợ và tốt nhất là xây dựng bằng phiên bản lowest đó.
Chúng tôi cũng khuyên bạn nên xem lại tài liệu về tất cả API đã sử dụng để kiểm tra xem liệu nó có phải là một phần rõ ràng của API giới hạn hay không. Ngay cả khi xác định Py_LIMITED_API, một số khai báo riêng tư vẫn bị lộ vì lý do kỹ thuật (hoặc thậm chí vô tình là lỗi).
Cũng lưu ý rằng API giới hạn không nhất thiết phải ổn định: biên dịch bằng Py_LIMITED_API bằng Python 3.8 có nghĩa là tiện ích mở rộng sẽ chạy với Python 3.12, nhưng không nhất thiết phải là compile với Python 3.12. Đặc biệt, các bộ phận của API Limited có thể không được dùng nữa và bị xóa, miễn là ABI ổn định vẫn ổn định.
Cân nhắc về nền tảng¶
Độ ổn định của ABI không chỉ phụ thuộc vào Python mà còn phụ thuộc vào trình biên dịch được sử dụng, các thư viện cấp thấp hơn và các tùy chọn trình biên dịch. Vì mục đích của Stable ABI, những chi tiết này xác định một “nền tảng”. Chúng thường phụ thuộc vào loại hệ điều hành và kiến trúc bộ xử lý
Mỗi nhà phân phối Python cụ thể có trách nhiệm đảm bảo rằng tất cả các phiên bản Python trên một nền tảng cụ thể đều được xây dựng theo cách không phá vỡ ABI ổn định. Đây là trường hợp xảy ra với các bản phát hành Windows và macOS từ python.org và nhiều nhà phân phối bên thứ ba.
Nội dung của Limited API¶
Hiện tại, Limited API bao gồm các mục sau:
PyErr_Display()PyModuleDef_BasePyUnicode_AsDecodedObject()PyUnicode_AsDecodedUnicode()PyUnicode_AsEncodedObject()PyUnicode_AsEncodedUnicode()PyVarObject.ob_basePyWeakReferencePy_FileSystemDefaultEncodeErrorsPy_FileSystemDefaultEncodingPy_HasFileSystemDefaultEncodingPy_UTF8ModePy_intptr_tPy_uintptr_tssizessizeargfuncssizessizeobjargprocsymtable