sys.monitoring --- پایش رویدادهای اجرا¶
اضافه شده در نسخهی 3.12.
توجه
sys.monitoring یک فضای نام درون ماژول sys است، نه یک ماژول مستقل، و import sys.monitoring با یک ModuleNotFoundError شکست خواهد خورد. در عوض، بهسادگی import sys را انجام دهید و سپس از sys.monitoring استفاده کنید.
این فضای نام دسترسی به توابع و ثابتهای لازم برای فعالسازی و کنترل پایش رویدادها را فراهم میکند.
هنگامی که برنامهها اجرا میشوند، رویدادهایی رخ میدهند که ممکن است برای ابزارهایی که اجرا را پایش میکنند جالب توجه باشند. فضای نام sys.monitoring امکاناتی را برای دریافت کالبکها هنگام رخ دادن رویدادهای مورد نظر فراهم میکند.
API پایش از سه کامپوننت تشکیل میشود:
شناسههای ابزار¶
شناسه ابزار یک عدد صحیح و نام مرتبط است. شناسههای ابزار برای جلوگیری از تداخل ابزارها با یکدیگر و امکان فعالیت همزمان چندین ابزار به کار میروند. در حال حاضر ابزارها کاملاً مستقل هستند و نمیتوان از آنها برای پایش یکدیگر استفاده کرد. این محدودیت ممکن است در آینده برداشته شود.
پیش از ثبت یا فعالسازی رویدادها، یک ابزار باید شناسهای انتخاب کند. شناسهها اعداد صحیحی در بازهی ۰ تا ۵ (شامل ۰ و ۵) هستند.
ثبت و استفاده از ابزارها¶
- sys.monitoring.use_tool_id(tool_id: int, name: str, /) None¶
باید پیش از آنکه بتوان از tool_id استفاده کرد، فراخوانی شود. tool_id باید در بازهی ۰ تا ۵ باشد (شامل ۰ و ۵). اگر tool_id در حال استفاده باشد، یک
ValueErrorپرتاب میشود.
- sys.monitoring.clear_tool_id(tool_id: int, /) None¶
ثبت تمام رویدادها و توابع کالبک مرتبط با tool_id را لغو میکند.
اضافه شده در نسخهی 3.14.
- sys.monitoring.free_tool_id(tool_id: int, /) None¶
باید هنگامی فراخوانی شود که یک ابزار دیگر به tool_id نیازی ندارد. پیش از آزادسازی tool_id،
clear_tool_id()را فراخوانی میکند.تغییر یافته در نسخهی 3.14: Now calls
clear_tool_id()before releasing tool_id. Previously, it would not disable global or local events associated with tool_id, nor unregister any callback functions.
- sys.monitoring.get_tool(tool_id: int, /) str | None¶
اگر tool_id در حال استفاده باشد، نام ابزار را برمیگرداند؛ در غیر این صورت
Noneرا برمیگرداند. tool_id باید در بازهی ۰ تا ۵ (شامل هر دو) باشد.
ماشین مجازی (VM) همهی شناسهها را از نظر رویدادها یکسان در نظر میگیرد، اما شناسههای زیر از پیش تعریفشدهاند تا همکاری ابزارها آسانتر شود:
sys.monitoring.DEBUGGER_ID = 0
sys.monitoring.COVERAGE_ID = 1
sys.monitoring.PROFILER_ID = 2
sys.monitoring.OPTIMIZER_ID = 5
رویدادها¶
رویدادهای زیر پشتیبانی میشوند:
- sys.monitoring.events.BRANCH_LEFT¶
یک شاخهی شرطی به چپ میرود.
تعیین نحوهی نمایش شاخههای «چپ» و «راست» بر عهده ابزار است. تضمینی وجود ندارد که کدام شاخه «چپ» و کدام «راست» باشد، بهجز این که در طول عمر برنامه ثابت خواهد بود.
- sys.monitoring.events.BRANCH_RIGHT¶
یک شاخه شرطی به سمت راست میرود.
- sys.monitoring.events.CALL¶
یک فراخوانی در کد پایتون (رویداد پیش از فراخوانی رخ میدهد).
- sys.monitoring.events.C_RAISE¶
استثنایی که از هر فراخوانیپذیر، به جز توابع پایتون، پرتاب میشود (رویداد پس از خروج رخ میدهد).
- sys.monitoring.events.C_RETURN¶
بازگشت از هر فراخوانیپذیر، بهجز توابع پایتون (رویداد پس از بازگشت رخ میدهد).
- sys.monitoring.events.EXCEPTION_HANDLED¶
استثنایی مدیریت میشود.
- sys.monitoring.events.INSTRUCTION¶
یک دستور ماشین مجازی در شرف اجرا شدن است.
- sys.monitoring.events.JUMP¶
یک پرش غیرشرطی در گراف جریان کنترل انجام میشود.
- sys.monitoring.events.LINE¶
دستوری که شمارهی خط متفاوتی از دستور پیشین دارد، در آستانهی اجرا شدن است.
- sys.monitoring.events.PY_RESUME¶
ازسرگیری یک تابع پایتون (برای توابع تولیدگر و همروال)، بهاستثنای فراخوانیهای
throw().
- sys.monitoring.events.PY_RETURN¶
بازگشت از یک تابع پایتون (درست پیش از بازگشت رخ میدهد؛ فریم تابع فراخوانیشده روی پشته خواهد بود).
- sys.monitoring.events.PY_START¶
آغاز یک تابع پایتون (بلافاصله پس از فراخوانی رخ میدهد، فریم تابع فراخوانیشده روی پشته خواهد بود)
- sys.monitoring.events.PY_THROW¶
یک تابع پایتون با فراخوانی
throw()از سر گرفته میشود.
- sys.monitoring.events.PY_UNWIND¶
خروج از یک تابع پایتون در حین باز شدن استثنا (exception unwinding). این شامل استثناهایی میشود که مستقیماً درون تابع پرتاب شدهاند و اجازه داده میشود به انتشار ادامه دهند.
- sys.monitoring.events.PY_YIELD¶
Yield از یک تابع پایتون (درست پیش از yield رخ میدهد، فریم فراخوانیشونده روی پشته خواهد بود).
- sys.monitoring.events.RAISE¶
استثنایی پرتاب میشود، بهجز آنهایی که رویداد
STOP_ITERATIONرا ایجاد میکنند.
- sys.monitoring.events.STOP_ITERATION¶
یک
StopIterationمصنوعی پرتاب میشود؛ the STOP_ITERATION event را ببینید.
ممکن است رویدادهای بیشتری در آینده افزوده شوند.
این رویدادها ویژگیهای فضای نام sys.monitoring.events هستند. هر رویداد بهصورت یک ثابت عدد صحیح با مقدار توانی از ۲ نمایش داده میشود. برای تعریف مجموعهای از رویدادها، کافی است رویدادهای جداگانه را با OR بیتی با هم ترکیب کنید. برای مثال، برای مشخص کردن هر دو رویداد PY_RETURN و PY_START، از عبارت PY_RETURN | PY_START استفاده کنید.
- sys.monitoring.events.NO_EVENTS¶
نام مستعاری برای
0تا کاربران بتوانند مقایسههای صریحی مانند این انجام دهند:if get_events(DEBUGGER_ID) == NO_EVENTS: ...
تنظیم این رویداد، همه رویدادها را غیرفعال میکند.
رویدادهای محلی¶
رویدادهای محلی با اجرای عادی برنامه مرتبط هستند و در مکانهای بهوضوح تعریفشده رخ میدهند. میتوان تمام رویدادهای محلی را غیرفعال کرد. رویدادهای محلی عبارتند از:
رویداد منسوخ¶
BRANCH
رویداد BRANCH در 3.14 منسوخ شده است. استفاده از رویدادهای BRANCH_LEFT و BRANCH_RIGHT عملکرد بسیار بهتری خواهد داشت، زیرا میتوان آنها را بهطور مستقل غیرفعال کرد.
رویدادهای جانبی¶
رویدادهای کمکی را میتوان مانند سایر رویدادها پایش کرد، اما توسط رویداد دیگری کنترل میشوند:
رویدادهای C_RETURN و C_RAISE توسط رویداد CALL کنترل میشوند. رویدادهای C_RETURN و C_RAISE تنها در صورتی مشاهده میشوند که رویداد CALL متناظر پایش شود.
رویدادهای دیگر¶
سایر رویدادها لزوماً به مکان مشخصی در برنامه وابسته نیستند و نمیتوان آنها را بهصورت جداگانه از طریق DISABLE غیرفعال کرد.
رویدادهای دیگری که میتوان آنها را پایش کرد عبارتند از:
رویداد STOP_ITERATION¶
PEP 380 مشخص میکند که هنگام برگرداندن یک مقدار از یک تولیدگر یا همروال، استثنای StopIteration پرتاب میشود. با این حال، این روش بسیار ناکارآمدی برای برگرداندن یک مقدار است، بنابراین برخی از پیادهسازیهای پایتون، بهویژه CPython 3.12+، استثنایی پرتاب نمیکنند مگر اینکه برای کد دیگر قابل مشاهده باشد.
برای اینکه ابزارها بتوانند استثناهای واقعی را بدون کُند کردن تولیدگرها و همروالها پایش کنند، رویداد STOP_ITERATION فراهم شده است. STOP_ITERATION را میتوان بهصورت محلی غیرفعال کرد، برخلاف RAISE.
توجه داشته باشید که رویداد STOP_ITERATION و رویداد RAISE برای استثنای StopIteration معادل هستند و هنگام تولید رویدادها، بهعنوان قابل تعویض در نظر گرفته میشوند. پیادهسازیها به دلایل کارایی، STOP_ITERATION را ترجیح میدهند، اما ممکن است یک رویداد RAISE همراه با یک StopIteration تولید کنند.
فعال و غیرفعال کردن رویدادها¶
برای پایش یک رویداد، باید آن را روشن کرد و یک کالبک متناظر باید ثبت شود. رویدادها را میتوان با تنظیم آنها بهصورت سراسری و/یا برای یک شیء کد (code object) خاص، روشن یا خاموش کرد. یک رویداد تنها یکبار فعال میشود، حتی اگر هم بهصورت سراسری و هم بهصورت محلی روشن شده باشد.
تنظیم رویدادها بهصورت سراسری¶
رویدادها را میتوان با تغییر مجموعه رویدادهای در حال پایش، بهصورت سراسری کنترل کرد.
- sys.monitoring.get_events(tool_id: int, /) int¶
یک
intبازمیگرداند که همه رویدادهای فعال را نشان میدهد.
- sys.monitoring.set_events(tool_id: int, event_set: int, /) None¶
تمام رویدادهایی را که در event_set تنظیم شدهاند، فعال میکند. اگر tool_id در حال استفاده نباشد، یک
ValueErrorپرتاب میکند.
هیچ رویدادی بهطور پیشفرض فعال نیست.
رویدادها بهازای هر شیء کد¶
رویدادها را همچنین میتوان بر اساس هر شیء کد کنترل کرد. توابع تعریفشده در زیر که یک types.CodeType را میپذیرند، باید آماده باشند تا یک شیء مشابه را از توابعی که در پایتون تعریف نشدهاند بپذیرند (به API پایش C مراجعه کنید).
- sys.monitoring.get_local_events(tool_id: int, code: CodeType, /) int¶
تمام رویدادهای محلی برای code را برمیگرداند
- sys.monitoring.set_local_events(tool_id: int, code: CodeType, event_set: int, /) None¶
تمام رویدادهای محلی برای code را که در event_set تنظیم شدهاند، فعال میکند. اگر tool_id در حال استفاده نباشد، یک
ValueErrorپرتاب میکند.
غیرفعالسازی رویدادها¶
- sys.monitoring.DISABLE¶
مقدار خاصی که میتوان آن را از یک تابع کالبک بازگرداند تا رویدادها را برای موقعیت فعلی کد غیرفعال کند.
رویدادهای محلی را میتوان برای یک موقعیت کد مشخص با برگرداندن sys.monitoring.DISABLE از یک تابع کالبک غیرفعال کرد. این کار، رویدادهای تنظیمشده یا سایر موقعیتهای کد برای همان رویداد را تغییر نمیدهد.
غیرفعال کردن رویدادها برای محلهای مشخص، برای پایش با کارایی بالا بسیار مهم است. برای مثال، اگر اشکالزدا همه پایش را به جز چند نقطه شکست غیرفعال کند، میتوان یک برنامه را بدون سربار تحت یک اشکالزدا اجرا کرد.
اگر DISABLE توسط یک کالبک برای یک رویداد سراسری برگردانده شود، ValueError توسط مفسر در مکانی نامشخص پرتاب خواهد شد (یعنی هیچ ردگیری پشتهای ارائه نخواهد شد).
- sys.monitoring.restart_events() None¶
تمام رویدادهایی را که توسط
sys.monitoring.DISABLEغیرفعالشده بودند، برای همه ابزارها فعال کنید.
ثبت توابع کالبک¶
- sys.monitoring.register_callback(tool_id: int, event: int, func: Callable | None, /) Callable | None¶
شیء فراخوانیپذیر func را برای event با tool_id دادهشده ثبت میکند
اگر کالبک دیگری برای tool_id و event دادهشده ثبت شده باشد، آن کالبک از ثبت خارج شده و بازگردانده میشود. در غیر این صورت
register_callback()مقدارNoneرا برمیگرداند.یک رویداد حسابرسی
sys.monitoring.register_callbackرا با آرگومانfuncپرتاب میکند.
میتوان توابع را با فراخوانی sys.monitoring.register_callback(tool_id, event, None) از ثبت خارج کرد.
توابع کالبک را میتوان در هر زمان ثبت و لغو ثبت کرد.
کالبکها تنها یک بار فراخوانی میشوند، صرفنظر از اینکه رویداد هم بهصورت سراسری و هم بهصورت محلی فعال شده باشد. بنابراین، اگر ممکن است رویدادی توسط کد شما برای هر دو رویداد سراسری و محلی فعال شود، کالبک باید بهگونهای نوشته شود که هر یک از محرکها را مدیریت کند.
آرگومانهای تابع کالبک¶
- sys.monitoring.MISSING¶
مقدار ویژهای که به یک تابع کالبک ارسال میشود تا نشان دهد که آرگومانی برای فراخوانی وجود ندارد.
هنگامی که یک رویداد فعال رخ میدهد، تابع کالبک ثبتشده فراخوانی میشود. توابع کالبکی که شیئی غیر از DISABLE برمیگردانند، بیاثر خواهند بود. رویدادهای مختلف، آرگومانهای مختلفی را در اختیار تابع کالبک قرار میدهند، به شرح زیر:
-
func(code: CodeType, instruction_offset: int) -> object
-
func(code: CodeType, instruction_offset: int, retval: object) -> object
CALL،C_RAISEوC_RETURN(arg0 میتواند بهطور خاصMISSINGباشد):func(code: CodeType, instruction_offset: int, callable: object, arg0: object) -> object
code نمایانگر شیء کدی است که فراخوانی در آن انجام میشود، در حالی که callable شیئی است که قرار است فراخوانی شود (و در نتیجه رویداد را فعال کرده است). اگر آرگومانی وجود نداشته باشد، arg0 برابر با
sys.monitoring.MISSINGتنظیم میشود.برای متدهای نمونه، callable شیء تابعی خواهد بود که در کلاس یافت میشود، با arg0 تنظیمشده به نمونه (یعنی آرگومان
selfمتد).RAISE،RERAISE،EXCEPTION_HANDLED،PY_UNWIND،PY_THROWوSTOP_ITERATION:func(code: CodeType, instruction_offset: int, exception: BaseException) -> object
LINE:func(code: CodeType, line_number: int) -> object
BRANCH_LEFT،BRANCH_RIGHTوJUMP:func(code: CodeType, instruction_offset: int, destination_offset: int) -> object
توجه داشته باشید که destination_offset محل اجرای بعدی کد است.
-
func(code: CodeType, instruction_offset: int) -> object