اشیاء کد

اشیای کد از جزئیات سطح پایین پیاده‌سازی سی‌پایتون هستند. هر یک نمایانگر تکه‌ای از کد اجرایی است که هنوز به تابعی مقید نشده است.

type PyCodeObject

ساختار C اشیایی که برای توصیف اشیاء کد استفاده می‌شوند. فیلد‌های این نوع ممکن است در هر زمان تغییر کنند.

PyTypeObject PyCode_Type

این یک نمونه از PyTypeObject است که شیء کد پایتون را نمایندگی می‌کند و شیء کد

int PyCode_Check(PyObject *co)

اگر co یک شیء کد باشد، مقدار true را برمی‌گرداند. این تابع همیشه موفق می‌شود.

Py_ssize_t PyCode_GetNumFree(PyCodeObject *co)

تعداد متغیرهای آزاد (بستار) در یک شیء کد را برمی‌گرداند.

int PyUnstable_Code_GetFirstFree(PyCodeObject *co)
این است API ناپایداراین ممکن است بدون هشدار در نسخه‌های جزئی تغییر کند.

موقعیت نخستین متغیر آزاد (بستار) در یک شیء کد را برمی‌گرداند.

تغییر یافته در نسخه‌ی 3.13: به عنوان بخشی از API ناپایدار C از PyCode_GetFirstFree تغییر نام داده شده است. نام قدیمی منسوخ شده است، اما تا زمانی که امضای تابع دوباره تغییر کند، در دسترس باقی خواهد ماند.

PyCodeObject *PyUnstable_Code_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
این است API ناپایداراین ممکن است بدون هشدار در نسخه‌های جزئی تغییر کند.

یک شیء کد جدید برمی‌گرداند. اگر برای ایجاد یک فریم به یک شیء کد ساختگی نیاز دارید، به‌جای آن از PyCode_NewEmpty() استفاده کنید.

از آنجا که تعریف بایت‌کد اغلب تغییر می‌کند، فراخوانی مستقیم PyUnstable_Code_New() می‌تواند شما را به یک نسخه‌ی دقیق پایتون مقید کند.

آرگومان‌های متعدد این تابع به شیوه‌های پیچیده‌ای به یکدیگر وابسته‌اند، به این معنا که تغییرات ظریف در مقادیر به احتمال زیاد به اجرای نادرست یا فروپاشی ماشین مجازی منجر می‌شود. از این تابع تنها با نهایت احتیاط استفاده کنید.

تغییر یافته در نسخه‌ی 3.11: پارامترهای qualname و exceptiontable افزوده شدند.

تغییر یافته در نسخه‌ی 3.12: از PyCode_New به‌عنوان بخشی از API ناپایدار C تغییر نام داده شده است. نام قدیمی منسوخ شده است، اما تا زمانی که امضای آن دوباره تغییر کند، در دسترس باقی خواهد ماند.

PyCodeObject *PyUnstable_Code_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
این است API ناپایداراین ممکن است بدون هشدار در نسخه‌های جزئی تغییر کند.

مشابه PyUnstable_Code_New() است، اما یک «posonlyargcount» اضافی برای آرگومان‌های صرفاً جایگاهی دارد. همان هشدارهایی که درباره‌ی PyUnstable_Code_New صدق می‌کنند، درباره‌ی این تابع نیز صدق می‌کنند.

اضافه شده در نسخه‌ی 3.8: به‌صورت PyCode_NewWithPosOnlyArgs

تغییر یافته در نسخه‌ی 3.11: پارامترهای qualname و exceptiontable افزوده شدند.

تغییر یافته در نسخه‌ی 3.12: به PyUnstable_Code_NewWithPosOnlyArgs تغییر نام یافت. نام قدیمی منسوخ شده است، اما تا زمانی که امضا دوباره تغییر کند، در دسترس باقی خواهد ماند.

PyCodeObject *PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
مقدار بازگشتی: مرجع جدید.

یک شیء کد خالی جدید با نام پرونده، نام تابع و شماره سطر اول مشخص‌شده برمی‌گرداند. شیء کد حاصل در صورت اجرا یک Exception پرتاب می‌کند.

int PyCode_Addr2Line(PyCodeObject *co, int byte_offset)

شماره سطر دستوری را برمی‌گرداند که در byte_offset یا پیش از آن قرار دارد و پس از آن پایان می‌یابد. اگر فقط به شماره سطر یک فریم نیاز دارید، به‌جای آن از PyFrame_GetLineNumber() استفاده کنید.

برای پیمایش کارآمد شماره سطرهای یک شیء کد، از API توصیف‌شده در PEP 626 استفاده کنید.

int PyCode_Addr2Location(PyObject *co, int byte_offset, int *start_line, int *start_column, int *end_line, int *end_column)

اشاره‌گرهای int ارسال‌شده را برابر شماره سطر و ستون کد منبع برای دستورالعمل در byte_offset قرار می‌دهد. وقتی اطلاعات برای هیچ عنصر خاصی در دسترس نباشد، مقدار را 0 قرار می‌دهد.

اگر تابع با موفقیت اجرا شود، 1 و در غیر این صورت 0 برمی‌گرداند.

اضافه شده در نسخه‌ی 3.11.

PyObject *PyCode_GetCode(PyCodeObject *co)

معادل کد پایتون getattr(co, 'co_code') است. یک ارجاع قوی به PyBytesObject برمی‌گرداند که بایت‌کد موجود در یک شیء کد را نمایش می‌دهد. در صورت خطا، NULL برگردانده می‌شود و یک استثنا مطرح می‌شود.

این PyBytesObject ممکن است به‌صورت درخواستی توسط مفسر ایجاد شود و لزوماً بایت‌کدی را که در واقع توسط سی‌پایتون اجرا می‌شود نشان نمی‌دهد. کاربرد اصلی این تابع در اشکال‌زداها و پروفایل‌گیرها است.

اضافه شده در نسخه‌ی 3.11.

PyObject *PyCode_GetVarnames(PyCodeObject *co)

معادل کد پایتون getattr(co, 'co_varnames') است. یک ارجاع جدید به PyTupleObject شامل نام‌های متغیرهای محلی برمی‌گرداند. در صورت خطا، NULL برگردانده می‌شود و یک استثنا مطرح می‌شود.

اضافه شده در نسخه‌ی 3.11.

PyObject *PyCode_GetCellvars(PyCodeObject *co)

معادل کد پایتونِ getattr(co, 'co_cellvars') است. یک ارجاع جدید به PyTupleObject حاوی نام متغیرهای محلی‌ای که توابع تودرتو به آن‌ها ارجاع می‌دهند، برمی‌گرداند. در صورت خطا، NULL برگردانده می‌شود و یک استثنا مطرح می‌شود.

اضافه شده در نسخه‌ی 3.11.

PyObject *PyCode_GetFreevars(PyCodeObject *co)

معادل کد پایتونِ getattr(co, 'co_freevars') است. یک ارجاع جدید به PyTupleObject برمی‌گرداند که نام‌های متغیرهای آزاد (بستار) را در بر می‌گیرد. در صورت خطا، NULL برگردانده می‌شود و یک استثنا پرتاب می‌شود.

اضافه شده در نسخه‌ی 3.11.

int PyCode_AddWatcher(PyCode_WatchCallback callback)

callback را به‌عنوان دیده‌بان (watcher) شیء کد برای مفسر فعلی ثبت می‌کند. شناسه‌ای برمی‌گرداند که می‌توان آن را به PyCode_ClearWatcher() ارسال کرد. در صورت بروز خطا (مثلاً وقتی دیگر هیچ شناسه‌ی دیده‌بانی در دسترس نیست)، مقدار -1 را برمی‌گرداند و یک استثنا تنظیم می‌کند.

اضافه شده در نسخه‌ی 3.12.

int PyCode_ClearWatcher(int watcher_id)

پاک کردن پایشگر (watcher) شناسایی‌شده با watcher_id که پیش‌تر از PyCode_AddWatcher() برای مفسر فعلی برگردانده شده است. در صورت موفقیت 0 را برمی‌گرداند، یا در صورت خطا -1 را برمی‌گرداند و یک استثنا تنظیم می‌کند (مثلاً اگر watcher_id داده‌شده هرگز ثبت نشده باشد.)

اضافه شده در نسخه‌ی 3.12.

type PyCodeEvent

شمارش رویدادهای ممکن دیده‌بان شیء کد: - PY_CODE_EVENT_CREATE - PY_CODE_EVENT_DESTROY

اضافه شده در نسخه‌ی 3.12.

typedef int (*PyCode_WatchCallback)(PyCodeEvent event, PyCodeObject *co)

نوع تابع کال‌بک دیده‌بان شیء کد.

اگر event برابر PY_CODE_EVENT_CREATE باشد، کال‌بک پس از آنکه co به‌طور کامل مقداردهی اولیه شده باشد فراخوانی می‌شود. در غیر این صورت، کال‌بک پیش از آنکه تخریب co رخ دهد فراخوانی می‌شود، تا بتوان وضعیت پیشین co را بررسی کرد.

اگر event برابر PY_CODE_EVENT_DESTROY باشد، گرفتن ارجاعی در کال‌بک به شیء کدی که در شرف نابودی است، آن را احیا می‌کند و مانع آزاد شدن آن در این زمان می‌شود. هنگامی که شیء احیاشده بعداً نابود شود، هر کال‌بک ناظری که در آن زمان فعال باشد، دوباره فراخوانی خواهد شد.

کاربران این API نباید به جزئیات پیاده‌سازی داخلی ران‌تایم تکیه کنند. چنین جزئیاتی ممکن است شامل ترتیب و زمان‌بندی دقیق ایجاد و تخریب اشیاء کد باشد، اما به همین موارد محدود نمی‌شود. هرچند تغییر در این جزئیات ممکن است تفاوت‌هایی قابل‌مشاهده برای ناظرها ایجاد کند (از جمله اینکه آیا یک کال‌بک فراخوانی می‌شود یا خیر)، اما معناشناسی کد پایتونِ در حال اجرا را تغییر نمی‌دهد.

اگر کال‌بک یک استثنا تنظیم کند، باید -1 را برگرداند؛ این استثنا با استفاده از PyErr_WriteUnraisable() به‌عنوان یک استثنای غیرقابل‌پرتاب (unraisable) چاپ خواهد شد. در غیر این صورت باید 0 را برگرداند.

ممکن است هنگام ورود به کال‌بک، از قبل استثنایی در انتظار تنظیم‌شده باشد. در این حالت، کال‌بک باید 0 را برگرداند در حالی که همان استثنا همچنان تنظیم‌شده است. این بدان معناست که کال‌بک مجاز نیست هیچ API دیگری را که می‌تواند استثنایی تنظیم کند فراخوانی کند، مگر آنکه ابتدا وضعیت استثنا را ذخیره و پاک کند و پیش از بازگشت، آن را بازیابی کند.

اضافه شده در نسخه‌ی 3.12.

PyObject *PyCode_Optimize(PyObject *code, PyObject *consts, PyObject *names, PyObject *lnotab_obj)

این تابعی است که هیچ کاری انجام نمی‌دهد.

پیش از پایتون 3.10، این تابع بهینه‌سازی‌های پایه را روی یک شیء کد انجام می‌داد.

تغییر یافته در نسخه‌ی 3.10: این تابع اکنون هیچ کاری انجام نمی‌دهد.

پرچم‌های شیء کد

اشیاء کد شامل یک میدان بیتی (bit-field) از پرچم‌ها هستند که می‌توان آن را به‌عنوان ویژگی پایتونی co_flags بازیابی کرد (برای مثال با استفاده از PyObject_GetAttrString())، و با استفاده از آرگومان flags در PyUnstable_Code_New() و توابع مشابه تنظیم کرد.

پرچم‌هایی که نام‌شان با CO_FUTURE_ آغاز می‌شود، به قابلیت‌هایی مربوط‌اند که معمولاً از طریق دستورهای آینده‌نما قابل انتخاب هستند. این پرچم‌ها را می‌توان در PyCompilerFlags.cf_flags به کار برد. توجه داشته باشید که بسیاری از پرچم‌های CO_FUTURE_ در نسخه‌های فعلی پایتون الزامی هستند و تنظیم کردن آن‌ها هیچ اثری ندارد.

پرچم‌های زیر در دسترس هستند. برای معنای آن‌ها، به مستندات پیوند‌شده‌ی معادل‌های پایتونی آن‌ها مراجعه کنید.

پرچم

معنی

CO_OPTIMIZED

inspect.CO_OPTIMIZED

CO_NEWLOCALS

inspect.CO_NEWLOCALS

CO_VARARGS

inspect.CO_VARARGS

CO_VARKEYWORDS

inspect.CO_VARKEYWORDS

CO_NESTED

inspect.CO_NESTED

CO_GENERATOR

inspect.CO_GENERATOR

CO_COROUTINE

inspect.CO_COROUTINE

CO_ITERABLE_COROUTINE

inspect.CO_ITERABLE_COROUTINE

CO_ASYNC_GENERATOR

inspect.CO_ASYNC_GENERATOR

CO_HAS_DOCSTRING

inspect.CO_HAS_DOCSTRING

CO_METHOD

inspect.CO_METHOD

CO_FUTURE_DIVISION

بدون اثر (__future__.division)

CO_FUTURE_ABSOLUTE_IMPORT

بدون اثر (__future__.absolute_import)

CO_FUTURE_WITH_STATEMENT

بدون اثر (__future__.with_statement)

CO_FUTURE_PRINT_FUNCTION

بدون اثر (__future__.print_function)

CO_FUTURE_UNICODE_LITERALS

بدون اثر (__future__.unicode_literals)

CO_FUTURE_GENERATOR_STOP

بدون اثر (__future__.generator_stop)

CO_FUTURE_ANNOTATIONS

__future__.annotations

اطلاعات اضافی

برای پشتیبانی از توسعه‌های سطح پایین در ارزیابی فریم، مانند کامپایلرهای خارجیِ در لحظه (just-in-time)، می‌توان داده‌های اضافیِ دلخواه را به اشیاء کد الصاق کرد.

این توابع بخشی از سطح نا‌پایدار C API هستند: این کارکرد جزئی از پیاده‌سازی سی‌پایتون است و ممکن است API بدون هشدار منسوخ‌شدن تغییر کند.

Py_ssize_t PyUnstable_Eval_RequestCodeExtraIndex(freefunc free)
این است API ناپایداراین ممکن است بدون هشدار در نسخه‌های جزئی تغییر کند.

یک مقدار اندیس مات جدید برمی‌گرداند که برای افزودن داده به اشیاء کد استفاده می‌شود.

معمولاً این تابع را یک‌بار (به ازای هر مفسر) فراخوانی می‌کنید و از نتیجه‌ی آن به همراه PyCode_GetExtra و PyCode_SetExtra برای دستکاری داده‌ها روی هر یک از اشیاء کد استفاده می‌کنید.

اگر free برابر NULL نباشد: هنگامی که یک شیء کد تخصیص‌زدایی شود، free روی داده‌های غیر NULL ذخیره‌شده تحت اندیس جدید فراخوانی خواهد شد. هنگام ذخیره‌سازی PyObject از Py_DecRef() استفاده کنید.

اضافه شده در نسخه‌ی 3.6: به‌عنوان _PyEval_RequestCodeExtraIndex

تغییر یافته در نسخه‌ی 3.12: به PyUnstable_Eval_RequestCodeExtraIndex تغییر نام یافت. نام خصوصی قدیمی منسوخ شده است، اما تا زمانی که API تغییر کند، دسترس‌پذیر خواهد بود.

int PyUnstable_Code_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
این است API ناپایداراین ممکن است بدون هشدار در نسخه‌های جزئی تغییر کند.

extra را برابر داده‌ی اضافی ذخیره‌شده در اندیس داده‌شده قرار می‌دهد. در صورت موفقیت، 0 برمی‌گرداند. در صورت شکست، یک استثنا تنظیم کرده و -1 برمی‌گرداند.

اگر داده‌ای در آن اندیس قرار داده نشده باشد، extra را برابر NULL قرار دهید و بدون تنظیم استثنا، ۰ را برگردانید.

اضافه شده در نسخه‌ی 3.6: به‌صورت _PyCode_GetExtra

تغییر یافته در نسخه‌ی 3.12: به PyUnstable_Code_GetExtra تغییر نام یافت. نام خصوصی قدیمی منسوخ شده است، اما تا زمانی که API تغییر کند، در دسترس خواهد بود.

int PyUnstable_Code_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
این است API ناپایداراین ممکن است بدون هشدار در نسخه‌های جزئی تغییر کند.

داده‌های اضافی ذخیره‌شده در اندیس داده‌شده را برابر extra قرار می‌دهد. در صورت موفقیت، 0 را برمی‌گرداند. در صورت شکست، استثنا را تنظیم می‌کند و -1 را برمی‌گرداند.

اضافه شده در نسخه‌ی 3.6: به‌صورت _PyCode_SetExtra

تغییر یافته در نسخه‌ی 3.12: به PyUnstable_Code_SetExtra تغییر نام داده شد. نام خصوصی قدیمی منسوخ شده است، اما تا زمان تغییر API در دسترس خواهد بود.