Python

정의 슬롯

C API를 사용하여 모듈 객체클래스 를 정의할 때 슬롯 배열을 사용할 수 있습니다. 슬롯은 기본적으로 생성할 객체의 특징을 기술하는 키-값 쌍입니다. 이를 통해 데이터와 실행 시 사용되는 구조를 분리함으로써, CPython 및 기타 Python C API 구현이 하위 호환성을 깨뜨리지 않으면서도 구조를 업데이트할 수 있게 됩니다.

이 섹션은 슬롯에 대해 일반적인 내용을 다룹니다. 객체별 동작 및 슬롯 값에 대해서는 슬롯을 적용하는 함수들의 문서를 참조하십시오.

슬롯이 이를 적용하는 함수로 전달될 때, 해당 함수는 슬롯 배열이나 그가 가리키는 데이터(재귀적)를 수정하지 않습니다. 함수 실행이 끝난 후 호출자는 PySlot_STATIC 으로 명시적으로 표시된 데이터를 제외하고, 배열과 그가 가리키는 모든 데이터(재귀적)를 수정하거나 해제할 수 있습니다.

별도로 명시되지 않는 한, 단일 슬롯 배열 내에 동일한 ID(sl_id)를 가진 여러 개의 슬롯이 존재할 수 없습니다.

Added in version 3.15: 슬롯 배열은 이전의 객체 정의 방식을 일반화한 것입니다. 즉, 타입에는 PyType_SpecPyType_Slot 을 사용하고, 모듈에는 PyModuleDefPyModuleDef_Slot 을 사용하는 방식입니다. 이전 API는 soft deprecated 상태이며, 삭제 계획은 없습니다.

슬롯 배열의 항목은 다음 구조를 사용합니다.

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

다음 중 선택된 슬롯 ID:

0인 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

슬롯에 대한 데이터입니다. 이 멤버들은 익명 유니온(anonymous union)의 일부이며, 슬롯 ID에서 요구하는 데이터 유형에 따라 사용할 멤버가 달라집니다: 각각 데이터 포인터, 함수 포인터, 크기, 부호 있는 정수 또는 부호 없는 정수입니다.

특정 슬롯 ID에 대해 별도로 명시되지 않는 한, 포인터(즉, sl_ptrsl_func)는 NULL일 수 없습니다.

uint16_t sl_flags

다음 플래그 중 0개 이상의 항목을 비트별 OR 연산으로 결합한 값입니다.

PySlot_STATIC
…의 일부 안정 ABI 버전 3.15 이후로.

슬롯이 가리키는 모든 데이터는 정적으로 할당되고 고정된 값입니다. 따라서 인터프리터가 이 정보를 복사할 필요가 없습니다.

이 플래그는 함수 포인터의 경우 암시적으로 적용됩니다.

이 플래그는 슬롯이 ‘간접적으로’ 가리키는 데이터에도 적용됩니다. 단, Py_slot_subslots 를 통해 중첩된 슬롯의 경우 별도의 PySlot_STATIC 플래그를 가질 수 있습니다. 예를 들어, PyMemberDef 구조체 배열을 가리키는 Py_tp_members 슬롯에 이 플래그가 적용되면, 전체 배열과 각 요소의 이름 및 독스트링이 모두 정적이고 고정된 값이어야 합니다.

PySlot_INTPTR
…의 일부 안정 ABI 버전 3.15 이후로.

데이터는 sl_ptr 에 저장되며, CPython이 이를 적절한 타입으로 캐스팅합니다.

이 플래그는 기존의 PyType_SlotPyModuleDef_Slot 구조체에서 이식하는 과정을 간소화할 수 있습니다.

PySlot_OPTIONAL
…의 일부 안정 ABI 버전 3.15 이후로.

슬롯 ID가 알려지지 않은 경우, 인터프리터는 오류를 발생시키는 대신 해당 슬롯을 무시해야 합니다.

예를 들어, Python 3.16에서 새로운 슬롯 ID와 함께 새로운 기능을 추가하는 경우, 해당 슬롯에 PySlot_OPTIONAL 을 표시하여 Python 3.15가 이를 무시하도록 할 수 있습니다.

“선택성(optionality)”은 알려지지 않은 슬롯 ID에만 적용됩니다. 이 플래그가 알려진 슬롯의 잘못된 값을 건너뛰게 만들지는 않습니다.

Added in version 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 이후로.

sl_id 및 특정 유니온 멤버 세트를 포함하는 PySlot 구조를 정의하기 위한 편의용 매크로입니다.

PySlot_STATIC_DATAPySlot_STATIC 플래그를 설정합니다. 다른 매크로는 플래그를 설정하지 않습니다.

이 매크로들은 C++ 표준 2020 버전부터 추가된 C 언어 기능인 지정 초기화(designated initializers) 를 사용합니다. 코드가 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)}

Added in version 3.15.

PySlot_END
…의 일부 안정 ABI 버전 3.15 이후로.

PySlot 배열의 끝을 표시하는 편의용 매크로입니다.

다음과 같이 정의됨:

#define PySlot_END {0}

Added in version 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)}}

Added in version 3.15.

공통 슬롯 ID

다음 슬롯 ID들은 타입 및 모듈 정의 모두에서 사용될 수 있습니다.

Py_slot_end
…의 일부 안정 ABI 버전 3.15 이후로.

슬롯 배열의 끝을 표시합니다. 0으로 정의됩니다.

Added in version 3.15.

Py_slot_subslots
…의 일부 안정 ABI 버전 3.15 이후로.

중첩된 슬롯 배열.

sl_ptr 값은 PySlot 구조체 배열을 가리켜야 합니다. 현재 슬롯 배열의 Py_slot_subslots 이 나타나는 지점에서, 해당 배열 내의 슬롯들(ID가 0인 종료자를 포함하지 않음)은 마치 원래 그 위치에 삽입된 것처럼 처리됩니다.

슬롯 중첩 깊이는 5단계로 제한됩니다. 이 제한은 향후 해제될 수 있습니다.

Added in version 3.15.

Py_slot_invalid
…의 일부 안정 ABI 버전 3.15 이후로.

예약됨; 항상 알 수 없는 슬롯 ID로 취급됩니다. UINT16_MAX``(``0xFFFF)로 정의됩니다.

PySlot_OPTIONAL 플래그와 함께 사용될 때 효과가 없는 슬롯을 정의합니다. 해당 플래그 없이는 이 ID를 가진 슬롯을 처리할 때 오류가 발생합니다.

Added in version 3.15.

분실물 보관소