sys.monitoring --- Giám sát sự kiện thực thi¶
Added in version 3.12.
Ghi chú
sys.monitoring là một không gian tên trong mô-đun sys, không phải là mô-đun độc lập và import sys.monitoring sẽ không thành công với ModuleNotFoundError. Thay vào đó, chỉ cần import sys và sau đó sử dụng sys.monitoring.
Không gian tên này cung cấp quyền truy cập vào các chức năng và hằng số cần thiết để kích hoạt và kiểm soát việc giám sát sự kiện.
Khi chương trình thực thi, các sự kiện xảy ra có thể được các công cụ giám sát việc thực thi quan tâm. Không gian tên sys.monitoring cung cấp phương tiện để nhận lệnh gọi lại khi xảy ra sự kiện quan tâm.
Việc giám sát API bao gồm ba thành phần:
Mã định danh công cụ¶
Mã định danh công cụ là một số nguyên và tên liên quan. Mã nhận dạng công cụ được sử dụng để ngăn cản các công cụ can thiệp lẫn nhau và cho phép nhiều công cụ hoạt động cùng một lúc. Hiện tại các công cụ hoàn toàn độc lập và không thể sử dụng để giám sát lẫn nhau. Hạn chế này có thể được dỡ bỏ trong tương lai.
Trước khi đăng ký hoặc kích hoạt sự kiện, công cụ nên chọn một mã định danh. Mã định danh là các số nguyên trong phạm vi từ 0 đến 5.
Đăng ký và sử dụng công cụ¶
- sys.monitoring.use_tool_id(tool_id: int, name: str, /) None¶
Phải được gọi trước khi tool_id có thể được sử dụng. tool_id phải nằm trong phạm vi từ 0 đến 5. Tăng
ValueErrornếu tool_id được sử dụng.
- sys.monitoring.clear_tool_id(tool_id: int, /) None¶
Hủy đăng ký tất cả các sự kiện và chức năng gọi lại liên quan đến tool_id.
- sys.monitoring.free_tool_id(tool_id: int, /) None¶
Nên gọi khi công cụ không còn yêu cầu tool_id nữa. Sẽ gọi
clear_tool_id()trước khi phát hành tool_id.
- sys.monitoring.get_tool(tool_id: int, /) str | None¶
Trả về tên của công cụ nếu tool_id được sử dụng, nếu không nó sẽ trả về
None. tool_id phải nằm trong phạm vi từ 0 đến 5.
Tất cả các ID đều được VM xử lý giống nhau đối với các sự kiện, nhưng các ID sau được xác định trước để giúp các công cụ hợp tác dễ dàng hơn:
sys.monitoring.DEBUGGER_ID = 0
sys.monitoring.COVERAGE_ID = 1
sys.monitoring.PROFILER_ID = 2
sys.monitoring.OPTIMIZER_ID = 5
Sự kiện¶
Các sự kiện sau được hỗ trợ:
- sys.monitoring.events.BRANCH_LEFT¶
Một nhánh có điều kiện đi sang trái.
Công cụ này có quyền xác định cách trình bày các nhánh "trái" và "phải". Không có gì đảm bảo nhánh nào là "trái" và nhánh nào là "phải", ngoại trừ việc nó sẽ nhất quán trong suốt thời gian của chương trình.
- sys.monitoring.events.BRANCH_RIGHT¶
Một nhánh có điều kiện đi sang phải.
- sys.monitoring.events.CALL¶
Cuộc gọi bằng mã Python (sự kiện xảy ra trước cuộc gọi).
- sys.monitoring.events.C_RAISE¶
Một ngoại lệ được tạo ra từ bất kỳ lệnh gọi nào, ngoại trừ các hàm Python (sự kiện xảy ra sau khi thoát).
- sys.monitoring.events.C_RETURN¶
Trả về từ bất kỳ lệnh gọi nào, ngoại trừ các hàm Python (sự kiện xảy ra sau khi trả về).
- sys.monitoring.events.EXCEPTION_HANDLED¶
Một ngoại lệ được xử lý.
- sys.monitoring.events.INSTRUCTION¶
Một lệnh VM sắp được thực thi.
- sys.monitoring.events.JUMP¶
Một bước nhảy vô điều kiện trong biểu đồ luồng điều khiển được thực hiện.
- sys.monitoring.events.LINE¶
Một lệnh sắp được thực thi có số dòng khác với lệnh trước đó.
- sys.monitoring.events.PY_RESUME¶
Tiếp tục hàm Python (dành cho hàm tạo và hàm coroutine), ngoại trừ lệnh gọi
throw().
- sys.monitoring.events.PY_RETURN¶
Trả về từ hàm Python (xảy ra ngay trước khi trả về, khung của callee sẽ nằm trên ngăn xếp).
- sys.monitoring.events.PY_START¶
Bắt đầu một hàm Python (xảy ra ngay sau lệnh gọi, khung của callee sẽ nằm trên ngăn xếp)
- sys.monitoring.events.PY_THROW¶
Hàm Python được tiếp tục bằng lệnh gọi
throw().
- sys.monitoring.events.PY_UNWIND¶
Thoát khỏi hàm Python trong quá trình gỡ bỏ ngoại lệ. Điều này bao gồm các ngoại lệ được đưa ra trực tiếp trong hàm và được phép tiếp tục phổ biến.
- sys.monitoring.events.PY_YIELD¶
Năng suất từ một hàm Python (xảy ra ngay trước năng suất, khung của callee sẽ nằm trên ngăn xếp).
- sys.monitoring.events.RAISE¶
Một ngoại lệ được nêu ra, ngoại trừ những trường hợp gây ra sự kiện
STOP_ITERATION.
- sys.monitoring.events.STOP_ITERATION¶
Một
StopIterationnhân tạo được nâng lên; xem the STOP_ITERATION event.
Nhiều sự kiện có thể được thêm vào trong tương lai.
Những sự kiện này là thuộc tính của không gian tên sys.monitoring.events. Mỗi sự kiện được biểu diễn dưới dạng hằng số nguyên lũy thừa 2. Để xác định một tập hợp các sự kiện, chỉ cần thực hiện theo từng bit HOẶC các sự kiện riêng lẻ cùng nhau. Ví dụ: để chỉ định cả hai sự kiện PY_RETURN và PY_START, hãy sử dụng biểu thức PY_RETURN | PY_START.
- sys.monitoring.events.NO_EVENTS¶
Bí danh cho
0để người dùng có thể so sánh rõ ràng như:nếu get_events(DEBUGGER_ID) == NO_EVENTS: ...
Việc đặt sự kiện này sẽ hủy kích hoạt tất cả các sự kiện.
Sự kiện địa phương¶
Các sự kiện cục bộ gắn liền với việc thực thi bình thường của chương trình và xảy ra tại các vị trí được xác định rõ ràng. Tất cả các sự kiện địa phương có thể bị vô hiệu hóa. Các sự kiện địa phương là:
Sự kiện không được dùng nữa¶
BRANCH
Sự kiện BRANCH không được dùng nữa trong phiên bản 3.14. Sử dụng các sự kiện BRANCH_LEFT và BRANCH_RIGHT sẽ cho hiệu suất tốt hơn nhiều vì chúng có thể bị vô hiệu hóa một cách độc lập.
Sự kiện phụ trợ¶
Các sự kiện phụ trợ có thể được theo dõi như các sự kiện khác, nhưng được kiểm soát bởi một sự kiện khác:
Các sự kiện C_RETURN và C_RAISE được kiểm soát bởi sự kiện CALL. C_RETURN và C_RAISE sự kiện sẽ chỉ được nhìn thấy nếu sự kiện CALL tương ứng đang được theo dõi.
Sự kiện khác¶
Các sự kiện khác không nhất thiết phải gắn với một vị trí cụ thể trong chương trình và không thể tắt riêng lẻ thông qua DISABLE.
Các sự kiện khác có thể được theo dõi là:
Sự kiện STOP_ITERATION¶
PEP 380 chỉ định rằng ngoại lệ StopIteration được đưa ra khi trả về giá trị từ trình tạo hoặc coroutine. Tuy nhiên, đây là một cách rất kém hiệu quả để trả về một giá trị, vì vậy một số triển khai Python, đặc biệt là CPython 3.12+, không đưa ra một ngoại lệ trừ khi nó hiển thị với mã khác.
Để cho phép các công cụ giám sát các trường hợp ngoại lệ thực sự mà không làm chậm trình tạo và coroutine, sự kiện STOP_ITERATION được cung cấp. STOP_ITERATION có thể bị vô hiệu hóa cục bộ, không giống như RAISE.
Lưu ý rằng sự kiện STOP_ITERATION và sự kiện RAISE cho ngoại lệ StopIteration là tương đương và được coi là có thể hoán đổi cho nhau khi tạo sự kiện. Việc triển khai sẽ ưu tiên STOP_ITERATION vì lý do hiệu suất, nhưng có thể tạo ra sự kiện RAISE với StopIteration.
Bật và tắt sự kiện¶
Để theo dõi một sự kiện, nó phải được bật và phải đăng ký cuộc gọi lại tương ứng. Bạn có thể bật hoặc tắt các sự kiện bằng cách đặt các sự kiện trên toàn cầu và/hoặc cho một đối tượng mã cụ thể. Một sự kiện sẽ chỉ kích hoạt một lần, ngay cả khi nó được bật cả trên toàn cầu và cục bộ.
Đặt sự kiện trên toàn cầu¶
Các sự kiện có thể được kiểm soát trên toàn cầu bằng cách sửa đổi tập hợp các sự kiện đang được theo dõi.
- sys.monitoring.get_events(tool_id: int, /) int¶
Trả về
intđại diện cho tất cả các sự kiện đang hoạt động.
- sys.monitoring.set_events(tool_id: int, event_set: int, /) None¶
Kích hoạt tất cả các sự kiện được đặt trong event_set. Tăng
ValueErrornếu tool_id không được sử dụng.
Không có sự kiện nào được kích hoạt theo mặc định.
Mỗi sự kiện đối tượng mã¶
Các sự kiện cũng có thể được kiểm soát trên cơ sở từng đối tượng mã. Các hàm được xác định bên dưới chấp nhận types.CodeType phải được chuẩn bị để chấp nhận một đối tượng trông giống nhau từ các hàm không được xác định trong Python (xem Giám sát C API).
- sys.monitoring.get_local_events(tool_id: int, code: CodeType, /) int¶
Trả về tất cả local events cho code
- sys.monitoring.set_local_events(tool_id: int, code: CodeType, event_set: int, /) None¶
Kích hoạt tất cả local events cho code được đặt trong event_set. Tăng
ValueErrornếu tool_id không được sử dụng.
Vô hiệu hóa sự kiện¶
- sys.monitoring.DISABLE¶
Một giá trị đặc biệt có thể được trả về từ hàm gọi lại để tắt các sự kiện cho vị trí mã hiện tại.
Local events có thể bị vô hiệu hóa đối với một vị trí mã cụ thể bằng cách trả về sys.monitoring.DISABLE từ hàm gọi lại. Điều này không thay đổi sự kiện nào được đặt hoặc bất kỳ vị trí mã nào khác cho cùng một sự kiện.
Việc vô hiệu hóa các sự kiện cho các vị trí cụ thể là rất quan trọng để giám sát hiệu suất cao. Ví dụ: một chương trình có thể được chạy trong trình gỡ lỗi mà không cần chi phí hoạt động nếu trình gỡ lỗi vô hiệu hóa tất cả hoạt động giám sát ngoại trừ một số điểm dừng.
Nếu DISABLE được trả về bằng lệnh gọi lại cho global event, thì ValueError sẽ được trình thông dịch đưa ra ở một vị trí không cụ thể (nghĩa là sẽ không cung cấp dấu vết).
- sys.monitoring.restart_events() None¶
Kích hoạt tất cả các sự kiện đã bị
sys.monitoring.DISABLEtắt cho tất cả các công cụ.
Đăng ký chức năng gọi lại¶
- sys.monitoring.register_callback(tool_id: int, event: int, func: Callable | None, /) Callable | None¶
Đăng ký func có thể gọi cho event với tool_id đã cho
Nếu một lệnh gọi lại khác đã được đăng ký cho tool_id và event nhất định thì lệnh gọi lại đó sẽ không được đăng ký và được trả về. Nếu không thì
register_callback()trả vềNone.Tăng một auditing event
sys.monitoring.register_callbackvới đối sốfunc.
Các chức năng có thể được hủy đăng ký bằng cách gọi sys.monitoring.register_callback(tool_id, event, None).
Chức năng gọi lại có thể được đăng ký và hủy đăng ký bất cứ lúc nào.
Lệnh gọi lại chỉ được gọi một lần bất kể sự kiện có được bật cả trên toàn cầu và cục bộ hay không. Do đó, nếu mã của bạn có thể bật một sự kiện cho cả sự kiện toàn cầu và cục bộ thì lệnh gọi lại cần phải được viết để xử lý một trong hai trình kích hoạt.
Đối số hàm gọi lại¶
- sys.monitoring.MISSING¶
Một giá trị đặc biệt được truyền cho hàm gọi lại để cho biết rằng không có đối số nào cho cuộc gọi.
Khi một sự kiện hoạt động xảy ra, hàm gọi lại đã đăng ký sẽ được gọi. Các hàm gọi lại trả về một đối tượng không phải là DISABLE sẽ không có hiệu lực. Các sự kiện khác nhau sẽ cung cấp cho hàm gọi lại các đối số khác nhau, như sau:
-
func(code: CodeType,guide_offset: int) -> đối tượng
-
func(code: CodeType,guide_offset: int, retval: object) -> đối tượng
CALL,C_RAISEvàC_RETURN(arg0 có thể làMISSINGcụ thể):func(code: CodeType, manual_offset: int, callable: object, arg0: object) -> object
code đại diện cho đối tượng mã nơi cuộc gọi đang được thực hiện, trong khi callable là đối tượng sắp được gọi (và do đó đã kích hoạt sự kiện). Nếu không có đối số, arg0 được đặt thành
sys.monitoring.MISSING.Đối với các phương thức phiên bản, callable sẽ là đối tượng hàm như được tìm thấy trên lớp với arg0 được đặt thành phiên bản (tức là đối số
selfcho phương thức).RAISE,RERAISE,EXCEPTION_HANDLED,PY_UNWIND,PY_THROWvàSTOP_ITERATION:func(code: CodeType,guide_offset: int, ngoại lệ: BaseException) -> đối tượng
LINE:func(code: CodeType, line_number: int) -> đối tượng
BRANCH_LEFT,BRANCH_RIGHTvàJUMP:func(code: CodeType,guide_offset: int, Destination_offset: int) -> đối tượng
Lưu ý rằng destination_offset là nơi mã sẽ thực thi tiếp theo.
-
func(code: CodeType,guide_offset: int) -> đối tượng