جایگاه‌های تعریف

برای تعریف اشیای ماژول و کلاس‌ها با استفاده از C API، می‌توانید از آرایه‌ای از جایگاه‌ها استفاده کنید — اساساً جفت‌مقادیر کلید-مقداری که ویژگی‌های شیء مورد نظر برای ایجاد را توصیف می‌کنند. این کار داده‌ها را از ساختارهای استفاده‌شده در زمان اجرا جدا می‌کند و به CPython — و سایر پیاده‌سازی‌های C API پایتون — اجازه می‌دهد تا ساختارها را بدون شکستن سازگاری با نسخه‌های قبلی به‌روزرسانی کنند.

این بخش جایگاه‌ها را به طور کلی مستند می‌کند. برای رفتارها و مقادیر جایگاه‌های خاصِ هر شیء، به مستندات توابعی که جایگاه‌ها را اعمال می‌کنند مراجعه کنید:

هنگامی که جایگاه‌ها به تابعی که آن‌ها را اعمال می‌کند ارسال می‌شوند، آن تابع آرایه‌ی جایگاه‌ها و هیچ‌یک از داده‌هایی را که به آن‌ها اشاره می‌کند (به صورت بازگشتی) تغییر نخواهد داد. پس از اتمام کار تابع، فراخواننده مجاز است آرایه و هر داده‌ای را که به آن اشاره می‌کند (به صورت بازگشتی) تغییر دهد یا حافظه‌ی آن‌ها را آزاد کند، به جز داده‌هایی که صراحتاً با PySlot_STATIC علامت‌گذاری شده‌اند.

به جز در مواردی که خلاف آن مستند شده باشد، چندین جایگاه با یک شناسه (sl_id) نمی‌توانند در یک آرایه‌ی جایگاه واحد وجود داشته باشند.

اضافه شده در نسخه‌ی 3.15: آرایه‌های جایگاه، روش قدیمی‌تر تعریف اشیا را عمومی‌سازی می‌کنند: استفاده از PyType_Spec همراه با PyType_Slot برای انواع، و PyModuleDef همراه با PyModuleDef_Slot برای ماژول‌ها. API قدیمی‌تر منسوخ، از رده خارج شده نرم است؛ هیچ برنامه‌ای برای حذف آن وجود ندارد.

درایه‌های آرایه‌ی جایگاه از ساختار زیر استفاده می‌کنند:

type PySlot
قسمتی از ABI پایدار شامل تمام اعضا از نسخه‌ی 3.15.

یک درایه در آرایه‌ی جایگاه. تعریف‌شده به صورت:

typedef struct {
    uint16_t sl_id;
    uint16_t sl_flags;
    uint32_t _reserved;  // must be 0
    union {
        void *sl_ptr;
        void (*sl_func)(void);
        Py_ssize_t sl_size;
        int64_t sl_int64;
        uint64_t sl_uint64;
    };
} PySlot;
uint16_t sl_id

شناسه‌ی جایگاه، انتخاب‌شده از:

یک sl_id برابر با صفر (Py_slot_end) پایان یک آرایه جایگاه را نشان می‌دهد.

void *sl_ptr
void (*sl_func)(void)
Py_ssize_t sl_size
int64_t sl_int64
uint64_t sl_uint64

داده‌های مربوط به جایگاه. این اعضا بخشی از یک union ناشناس هستند؛ عضوی که باید استفاده شود بستگی به این دارد که شناسه جایگاه چه نوع داده‌ای را نیاز دارد: به ترتیب اشاره‌گر داده، اشاره‌گر تابع، اندازه، عدد صحیح علامت‌دار یا بدون علامت.

به‌جز مواردی که برای یک شناسه جایگاه خاص به شکل دیگری مستند شده باشد، اشاره‌گرها (یعنی sl_ptr و sl_func) نباید NULL باشند.

uint16_t sl_flags

صفر یا چند مورد از پرچم‌های زیر که با عملگر OR ترکیب شده‌اند:

PySlot_STATIC
قسمتی از ABI پایدار از نسخه‌ی 3.15.

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

این پرچم برای اشاره‌گرهای تابع ضمنی است.

این پرچم حتی برای داده‌هایی که جایگاه به‌طور «غیرمستقیم» به آن‌ها اشاره می‌کند نیز اعمال می‌شود، به استثنای جایگاه‌هایی که از طریق Py_slot_subslots تو در تو قرار گرفته‌اند و ممکن است پرچم‌های PySlot_STATIC خود را داشته باشند. برای مثال، اگر روی جایگاه Py_tp_members اعمال شود که به آرایه‌ای از ساختارهای PyMemberDef اشاره می‌کند، آنگاه کل آرایه و همچنین رشته‌های نام و مستندات در عناصر آن باید ایستا و ثابت باشند.

PySlot_INTPTR
قسمتی از ABI پایدار از نسخه‌ی 3.15.

داده‌ها در sl_ptr ذخیره می‌شوند؛ سی‌پایتون آن را به نوع مناسب تبدیل نوع خواهد داد.

این پرچم می‌تواند انتقال از ساختارهای قدیمی‌تر PyType_Slot و PyModuleDef_Slot را ساده‌تر کند.

PySlot_OPTIONAL
قسمتی از ABI پایدار از نسخه‌ی 3.15.

اگر شناسه جایگاه ناشناخته باشد، مفسر باید به‌جای خطا دادن، جایگاه را نادیده بگیرد.

برای مثال، اگر پایتون 3.16 ویژگی جدیدی با یک شناسه جایگاه جدید اضافه کند،attr جایگاه متناظر ممکن است به صورت PySlot_OPTIONAL علامت‌گذاری شود تا پایتون 3.15 آن را نادیده بگیرد.

توجه داشته باشید که «اختیاری بودن» فقط برای شناسه‌های جایگاه ناشناخته اعمال می‌شود. این پرچم باعث نمی‌شود پایتون مقادیر نامعتبر جایگاه‌های شناخته‌شده را نادیده بگیرد.

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

ماکروهای کمکی

PySlot_DATA(name, value)
PySlot_FUNC(name, value)
PySlot_SIZE(name, value)
PySlot_INT64(name, value)
PySlot_UINT64(name, value)
PySlot_STATIC_DATA(name, value)
قسمتی از ABI پایدار از نسخه‌ی 3.15.

ماکروهای کمکی برای تعریف ساختارهای PySlot با sl_id و یک مجموعه عضو union مشخص.

ماکروی PySlot_STATIC_DATA پرچم PySlot_STATIC را تنظیم می‌کند؛ بقیه هیچ پرچمی را تنظیم نمی‌کنند.

توجه داشته باشید که این ماکروها از تعیین‌کننده‌های مقداردهی اولیه (designated initializers) استفاده می‌کنند، که ویژگی زبان C است که C++ آن را در نسخه 2020 استاندارد اضافه کرده است. اگر کد شما باید با C++11 یا قدیمی‌تر سازگار باشد، در عوض از PySlot_PTR استفاده کنید.

به صورت زیر تعریف شده است:

#define PySlot_DATA(NAME, VALUE) \
   {.sl_id=NAME, .sl_ptr=(void*)(VALUE)}

#define PySlot_FUNC(NAME, VALUE) \
   {.sl_id=NAME, .sl_func=(VALUE)}

#define PySlot_SIZE(NAME, VALUE) \
   {.sl_id=NAME, .sl_size=(VALUE)}

#define PySlot_INT64(NAME, VALUE) \
   {.sl_id=NAME, .sl_int64=(VALUE)}

#define PySlot_UINT64(NAME, VALUE) \
   {.sl_id=NAME, .sl_uint64=(VALUE)}

#define PySlot_STATIC_DATA(NAME, VALUE) \
   {.sl_id=NAME, .sl_flags=PySlot_STATIC, .sl_ptr=(VALUE)}

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

PySlot_END
قسمتی از ABI پایدار از نسخه‌ی 3.15.

ماکروی کمکی برای نشانه‌گذاری پایان یک آرایه‌ی PySlot.

به صورت زیر تعریف شده است:

#define PySlot_END {0}

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

PySlot_PTR(name, value)
PySlot_PTR_STATIC(name, value)
قسمتی از ABI پایدار از نسخه‌ی 3.15.

ماکروهای کمکی برای استفاده در کدهای سازگار با C++11. این نسخه‌ی C++ اجازه نمی‌دهد اعضای اتحادی دلخواه را در مقادیر لفظی تنظیم کنید؛ در عوض، این ماکروها پرچم PySlot_INTPTR را تنظیم کرده و مقدار را به (void*) تبدیل نوع می‌دهند.

به صورت زیر تعریف شده است:

#define PySlot_PTR(NAME, VALUE) \
   {NAME, PySlot_INTPTR, {0}, {(void*)(VALUE)}}

#define PySlot_PTR_STATIC(NAME, VALUE) \
   {NAME, PySlot_INTPTR|Py_SLOT_STATIC, {0}, {(void*)(VALUE)}}

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

شناسه‌های رایج جایگاه

شناسه‌های جایگاه زیر ممکن است در تعاریف نوع و ماژول استفاده شوند.

Py_slot_end
قسمتی از ABI پایدار از نسخه‌ی 3.15.

پایان یک آرایه‌ی جایگاه را نشانه‌گذاری می‌کند. به عنوان صفر تعریف شده است.

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

Py_slot_subslots
قسمتی از ABI پایدار از نسخه‌ی 3.15.

آرایه‌ی جایگاه تو در تو.

مقدار (sl_ptr) باید به آرایه‌ای از ساختارهای PySlot اشاره کند. جایگاه‌های موجود در آرایه (تا پیش از پایان‌دهنده‌ی شناسه-صفر که شامل آن نمی‌شود) طوری پردازش خواهند شد که انگار در جایگاه فعلی، در نقطه‌ای که Py_slot_subslots ظاهر می‌شود، درج شده‌اند.

عمق تو در تو بودن جایگاه به ۵ سطح محدود شده است. ممکن است این محدودیت در آینده برداشته شود.

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

Py_slot_invalid
قسمتی از ABI پایدار از نسخه‌ی 3.15.

رزروشده؛ همیشه به عنوان یک شناسه‌ی جایگاه ناشناخته در نظر گرفته خواهد شد. به عنوان UINT16_MAX (0xFFFF) تعریف شده است.

هنگامی که با پرچم PySlot_OPTIONAL استفاده شود، جایگاهی بدون اثر را تعریف می‌کند. بدون این پرچم، پردازش جایگاهی با این شناسه با خطا مواجه خواهد شد.

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