# 소개

파이썬의 애플리케이션 프로그래머용 인터페이스는 다양한 수준에서 C/C++ 프로그래머에게 파이썬 인터프리터에 대한 접근 방법을 제공합니다. 이 API는 C++에서도 동일하게 사용 가능하지만 간결함을 위해 보통 파이썬/C API 로 불립니다. 파이썬/C API를 사용하는 데에는 근본적으로 다른 두 가지 이유가 있습니다. 첫번째 이유는 특정한 목적을 위해 확장 모듈을 작성하기 위해서입니다; 이 확장 모듈들은 파이썬 인터프리터를 확장하는 C 모듈들입니다. 이것이 아마도 가장 흔한 용도일 것입니다. 두번째 이유는 파이썬을 더 큰 애플리케이션의 컴포넌트로 사용하기 위함입니다. 이 기술은 일반적으로 파이썬을 애플리케이션에 임베딩(embedding) 하는 것을 말합니다.

확장 모듈을 작성하는 것은 비교적 잘 다듬어진 과정으로, “쿡북” 접근법이 잘 통하며 프로세스를 다소 자동화하는 툴들도 존재합니다. 사람들은 파이썬이 존재한 초기부터 다른 애플리케이션에 파이썬을 임베드 해왔으나 파이썬을 임베딩 하는 과정은 확장 모듈을 작성하는 것보다 복잡합니다.

많은 API 함수들은 파이썬을 임베딩하거나 확장하는 것에 무관하게 유용합니다. 더욱이 파이썬을 임베드하는 대부분의 애플리케이션은 커스텀 확장을 제공할 필요성이 있기 때문에 파이썬을 임베드하려고 시도하기 전에 확장을 작성하는 것에 친숙해지는 것이 좋습니다.

## Language version compatibility

Python’s C API is compatible with C11 and C++11 versions of C and C++.

This is a lower limit: the C API does not require features from later C/C++ versions. You do not need to enable your compiler’s “c11 mode”.

## 코딩 표준

CPython 에 포함하기 위해 C 코드를 작성하는 경우에는 PEP 7 에 정의된 지침과 표준을 따라야 합니다. 이 지침은 기여하고 있는 파이썬 버전과 상관없이 적용됩니다. 최종적으로 파이썬에 기여하는 것을 기대하지 않는 이상 이 규칙을 따르는 것은 제삼자 확장 모듈에는 필수가 아닙니다.

## 인클루드 파일

파이썬/C API를 사용하기 위한 모든 함수, 타입 그리고 매크로 정의는 다음 행에 의해 인클루드됩니다.

    #define PY_SSIZE_T_CLEAN
    #include <Python.h>

이는 다음과 같은 표준 헤더를 인클루드하는것을 의미합니다: `<stdio.h>`, `<string.h>`, `<errno.h>`, `<limits.h>`, `<assert.h>` 그리고 `<stdlib.h>` (사용 가능한 경우).

참고

파이썬은 일부 시스템의 표준 헤더에 영향을 미치는 전처리기 정의를 정의할 수 있으므로 표준 헤더를 인클루드하기 전에 `Python.h` 를 인클루드해야 합니다.

`Python.h` 를 인클루드하기 전에 항상 `PY_SSIZE_T_CLEAN` 를 정의하는 것을 권장합니다. 이 매크로에 대한 자세한 사항은 인자 구문 분석과 값 구축 을 참조하십시오.

Python.h로 정의된 사용자에게 공개되는 모든 이름들은 (포함된 표준 헤더로 정의된 것은 제외) `Py` 또는 `_Py` 로 시작하는 이름을 가지고 있습니다. `_Py` 로 시작하는 이름들은 파이썬 구현에 의해 내부적으로 사용되며 확장 개발자들에 의해 사용돠어서는 안됩니다. 구조체 멤버들은 이름에 접두사가 붙지 않습니다.

참고

사용자 코드는 `Py` 또는 `_Py` 로 시작하는 이름들을 정의해서는 안됩니다. 이것은 읽는 사람을 혼란스럽게 하며이러한 접두사가 붙는 추가적인 이름을 정의할수도 있는 향후의 파이썬 버전에 대한 사용자 코드의 이식성을 위태롭게 합니다.

헤더 파일들은 일반적으로 파이썬과 함께 설치됩니다. 유닉스에서는 헤더 파일들은 `prefix/include/pythonversion/` 와 `exec_prefix/include/pythonversion/` 안에 들어있습니다. `prefix` 와 `exec_prefix` 는 파이썬의 configure 스크립트에 해당하는 파라미터로 정의되며 버전 은 `'%d.%d' % sys.version_info[:2]` 입니다. 윈도우에서는 헤더 파일들은 `prefix/include` 안에 설치되어 있습니다. `prefix` 는 인스톨러에 의해 지정된 설치 디렉터리 입니다.

헤더를 인클루드 하기 위해선 두 디렉터리 모두 (두 디렉터리가 다를 경우) 컴파일러의 검색 패스에 추가하십시오. 부모 디렉터리를 검색 패스에 추가해서 `#include <pythonX.Y/Python.h>` 처럼 사용해서는 안됩니다. `prefix` 아래의 플랫폼 독립적인 헤더들이 `exec_prefix` 에서 플랫폼 종속적인 헤더를 인클루드 하기 때문에 멀티플랫폼 빌드가 고장날 것입니다.

C++ 사용자들은 파이썬/C API 가 C 만을 사용하여 정의되었어도 헤더 파일들이 `extern "C"` 로 진입점을 제대로 선언한다는 점에 유의해야 합니다. C++ 에서 파이썬/C API 를 사용하기 위해 특별한 조치를 취할 필요는 없습니다.

## 유용한 매크로들

Several useful macros are defined in the Python header files. Many are defined closer to where they are useful (for example, `Py_RETURN_NONE`, `PyMODINIT_FUNC`). Others of a more general utility are defined here. This is not necessarily a complete listing.

Py_CAN_START_THREADS

  If this macro is defined, then the current system is able to start threads.

  Currently, all systems supported by CPython (per PEP 11), with the exception of some WebAssembly platforms, support starting threads.

  Added in version 3.13.

Py_GETENV(s)

  Like `getenv(s)`, but returns `NULL` if `-E` was passed on the command line (see `PyConfig.use_environment`).

### Docstring macros

PyDoc_STRVAR(name, str)

  Creates a variable with name name that can be used in docstrings. If Python is built without docstrings (`--without-doc-strings`), the value will be an empty string.

  예제:

      PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");

      static PyMethodDef deque_methods[] = {
          // ...
          {"pop", (PyCFunction)deque_pop, METH_NOARGS, pop_doc},
          // ...
      }

  Expands to `PyDoc_VAR(name) = PyDoc_STR(str)`.

PyDoc_STR(str)

  Expands to the given input string, or an empty string if docstrings are disabled (`--without-doc-strings`).

  예제:

      static PyMethodDef pysqlite_row_methods[] = {
          {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS,
              PyDoc_STR("Returns the keys of the row.")},
          {NULL, NULL}
      };

PyDoc_VAR(name)

  Declares a static character array variable with the given name. Expands to `static const char name[]`

  For example:

      PyDoc_VAR(python_doc) = PyDoc_STR(
         "A genus of constricting snakes in the Pythonidae family native "
         "to the tropics and subtropics of the Eastern Hemisphere.");

### General utility macros

The following macros are for common tasks not specific to Python.

Py_UNUSED(arg)

  함수의 미사용 인자에 사용하여 컴파일러 경고를 무시합니다. 예시: `int func(int a, int Py_UNUSED(b)) { return a; }`.

  Added in version 3.4.

Py_GCC_ATTRIBUTE(name)

  Use a GCC attribute name, hiding it from compilers that don’t support GCC attributes (such as MSVC).

  This expands to `__attribute__((name))` on a GCC compiler, and expands to nothing on compilers that don’t support GCC attributes.

#### Numeric utilities

Py_ABS(x)

  `x` 의 절댓값을 반환합니다.

  The argument may be evaluated more than once. Consequently, do not pass an expression with side-effects directly to this macro.

  If the result cannot be represented (for example, if `x` has `INT_MIN` value for int type), the behavior is undefined.

  Corresponds roughly to `((x) < 0 ? -(x) : (x))`

  Added in version 3.3.

Py_MAX(x, y)
Py_MIN(x, y)

  Return the larger or smaller of the arguments, respectively.

  Any arguments may be evaluated more than once. Consequently, do not pass an expression with side-effects directly to this macro.

  `Py_MAX` corresponds roughly to `(((x) > (y)) ? (x) : (y))`.

  Added in version 3.3.

Py_ARITHMETIC_RIGHT_SHIFT(type, integer, positions)

  Similar to `integer >> positions`, but forces sign extension, as the C standard does not define whether a right-shift of a signed integer will perform sign extension or a zero-fill.

  integer should be any signed integer type. positions is the number of positions to shift to the right.

  Both integer and positions can be evaluated more than once; consequently, avoid directly passing a function call or some other operation with side-effects to this macro. Instead, store the result as a variable and then pass it.

  type is unused and only kept for backwards compatibility. Historically, type was used to cast integer.

  버전 3.1에서 변경: This macro is now valid for all signed integer types, not just those for which `unsigned type` is legal. As a result, type is no longer used.

Py_CHARMASK(c)

  인자는 문자 또는 [-128, 127] 나 [0, 255] 사이의 정수여야 합니다. 이 매크로는 `unsigned char` 로 캐스팅된 `c` 를 반환합니다

#### Assertion utilities

Py_UNREACHABLE()

  의도적으로 도달할 수 없는 코드 경로가 있을 경우에 이 매크로를 사용하십시오. 예를 들어, `switch` 문에서 가능한 모든 값이 `case` 절에서 다뤄지는 경우에 `default:` 절에서 사용할 수 있습니다. `assert(0)` 또는 `abort()` 대신 사용하십시오.

  릴리즈 모드에서 이 매크로는 컴파일러가 코드를 최적화하는데 도움이 되며 도달할 수 없는 코드에 대한 경고를 방지합니다. 예를 들어, 이 매크로는 릴리즈 모드에서 GCC의 `__builtin_unreachable()` 로 구현됩니다.

  In debug mode, and on unsupported compilers, the macro expands to a call to `Py_FatalError()`.

  A use for `Py_UNREACHABLE()` is following a call to a function that never returns but that is not declared `_Noreturn`.

  코드 경로가 매우 가능성이 낮지만 예외적인 경우에 도달할 수 있는 경우, 이 매크로를 사용해서는 안됩니다. 예를 들어, 메모리가 부족하거나 시스템 콜이 예상 범위를 벗어나는 값을 반환했을 경우에는 호출자에게 에러를 보고하는 것이 좋습니다. 호출자에게 에러를 보고할 수 없는 경우 `Py_FatalError()` 를 사용할 수 있습니다.

  Added in version 3.7.

Py_SAFE_DOWNCAST(value, larger, smaller)

  Cast value to type smaller from type larger, validating that no information was lost.

  On release builds of Python, this is roughly equivalent to `((smaller) value)` (in C++, `static_cast<smaller>(value)` will be used instead).

  On debug builds (implying that `Py_DEBUG` is defined), this asserts that no information was lost with the cast from larger to smaller.

  value, larger, and smaller may all be evaluated more than once in the expression; consequently, do not pass an expression with side-effects directly to this macro.

Py_BUILD_ASSERT(cond)

  Asserts a compile-time condition cond, as a statement. The build will fail if the condition is false or cannot be evaluated at compile time.

  Corresponds roughly to `static_assert(cond)` on C23 and above.

  For example:

      Py_BUILD_ASSERT(sizeof(PyTime_t) == sizeof(int64_t));

  Added in version 3.3.

Py_BUILD_ASSERT_EXPR(cond)

  Asserts a compile-time condition cond, as an expression that evaluates to `0`. The build will fail if the condition is false or cannot be evaluated at compile time.

  For example:

      #define foo_to_char(foo) \
          ((char *)(foo) + Py_BUILD_ASSERT_EXPR(offsetof(struct foo, string) == 0))

  Added in version 3.3.

#### Type size utilities

Py_ARRAY_LENGTH(array)

  Compute the length of a statically allocated C array at compile time.

  The array argument must be a C array with a size known at compile time. Passing an array with an unknown size, such as a heap-allocated array, will result in a compilation error on some compilers, or otherwise produce incorrect results.

  This is roughly equivalent to:

      sizeof(array) / sizeof((array)[0])

Py_MEMBER_SIZE(type, member)

  Return the size of a structure (type) member in bytes.

  Corresponds roughly to `sizeof(((type *)NULL)->member)`.

  Added in version 3.6.

#### Macro definition utilities

Py_FORCE_EXPANSION(X)

  This is equivalent to `X`, which is useful for token-pasting in macros, as macro expansions in X are forcefully evaluated by the preprocessor.

Py_STRINGIFY(x)

  Convert `x` to a C string. For example, `Py_STRINGIFY(123)` returns `"123"`.

  Added in version 3.4.

### Declaration utilities

The following macros can be used in declarations. They are most useful for defining the C API itself, and have limited use for extension authors. Most of them expand to compiler-specific spellings of common extensions to the C language.

Py_ALWAYS_INLINE

  Ask the compiler to always inline a static inline function. The compiler can ignore it and decide to not inline the function.

  Corresponds to `always_inline` attribute in GCC and `__forceinline` in MSVC.

  It can be used to inline performance critical static inline functions when building Python in debug mode with function inlining disabled. For example, MSC disables function inlining when building in debug mode.

  Marking blindly a static inline function with Py_ALWAYS_INLINE can result in worse performances (due to increased code size for example). The compiler is usually smarter than the developer for the cost/benefit analysis.

  If Python is built in debug mode (if the `Py_DEBUG` macro is defined), the `Py_ALWAYS_INLINE` macro does nothing.

  It must be specified before the function return type. Usage:

      static inline Py_ALWAYS_INLINE int random(void) { return 4; }

  Added in version 3.11.

Py_NO_INLINE

  Disable inlining on a function. For example, it reduces the C stack consumption: useful on LTO+PGO builds which heavily inline code (see bpo-33720).

  Corresponds to the `noinline` attribute/specification on GCC and MSVC.

  사용법:

      Py_NO_INLINE static int random(void) { return 4; }

  Added in version 3.11.

Py_DEPRECATED(version)

  Use this to declare APIs that were deprecated in a specific CPython version. The macro must be placed before the symbol name.

  예제:

      Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void);

  버전 3.8에서 변경: MSVC 지원을 추가했습니다.

Py_LOCAL(type)

  Declare a function returning the specified type using a fast-calling qualifier for functions that are local to the current file. Semantically, this is equivalent to `static type`.

Py_LOCAL_INLINE(type)

  Equivalent to `Py_LOCAL` but additionally requests the function be inlined.

Py_LOCAL_SYMBOL

  Macro used to declare a symbol as local to the shared library (hidden). On supported platforms, it ensures the symbol is not exported.

  On compatible versions of GCC/Clang, it expands to `__attribute__((visibility("hidden")))`.

Py_EXPORTED_SYMBOL

  Macro used to declare a symbol (function or data) as exported. On Windows, this expands to `__declspec(dllexport)`. On compatible versions of GCC/Clang, it expands to `__attribute__((visibility("default")))`. This macro is for defining the C API itself; extension modules should not use it.

Py_IMPORTED_SYMBOL

  Macro used to declare a symbol as imported. On Windows, this expands to `__declspec(dllimport)`. This macro is for defining the C API itself; extension modules should not use it.

PyAPI_FUNC(type)

  Macro used by CPython to declare a function as part of the C API. Its expansion depends on the platform and build configuration. This macro is intended for defining CPython’s C API itself; extension modules should not use it for their own symbols.

PyAPI_DATA(type)

  Macro used by CPython to declare a public global variable as part of the C API. Its expansion depends on the platform and build configuration. This macro is intended for defining CPython’s C API itself; extension modules should not use it for their own symbols.

### Outdated macros

The following macros have been used to features that have been standardized in C11.

Py_ALIGNED(num)

  Specify alignment to num bytes on compilers that support it.

  Consider using the C11 standard `_Alignas` specifier over this macro.

Py_LL(number)
Py_ULL(number)

  Use number as a `long long` or `unsigned long long` integer literal, respectively.

  Expands to number followed by `LL` or `LLU`, respectively, but will expand to some compiler-specific suffixes on some older compilers.

  Consider using the C99 standard suffixes `LL` and `LLU` directly.

Py_MEMCPY(dest, src, n)

  This is a soft deprecated alias to `memcpy()`. Use `memcpy()` directly instead.

  버전 3.14부터 폐지됨: The macro is soft deprecated.

Py_VA_COPY

  This is a soft deprecated alias to the C99-standard `va_copy` function.

  Historically, this would use a compiler-specific method to copy a `va_list`.

  버전 3.6에서 변경: This is now an alias to `va_copy`.

## 객체, 형 그리고 참조 횟수

대부분의 파이썬/C API 함수는 하나 이상의 인자와 PyObject* 형의 반환 값을 가집니다. 해당 형은 임의의 파이썬 객체를 나타내는 오파크(Opaque) 데이터 형에 대한 포인터입니다. 할당, 스코프 규칙, 인자 전달 등 대부분의 상황에서 파이썬 언어가 모든 파이썬 객체 형을 동일한 방식으로 취급하기 때문에 단일한 C 형으로 표현하는 것이 적절합니다. 대부분의 객체는 힙에 존재합니다. `PyObject` 형의 자동 변수나 정적 변수를 선언해서는 안되며 PyObject* 형의 포인터 변수만을 선언할 수 있습니다. 유일한 예외는 형 객체입니다. 형 객체들은 절대 할당이 해제돼서는 안되기 때문에 형 객체들은 보통 정적 `PyTypeObject` 객체들입니다.

모든 파이썬 객체는 (파이썬 정수조차도) 형(type) 과 참조 횟수(reference count) 를 가지고 있습니다. 객체의 형은 객체의 종류를 결정합니다. (예를 들어 정수, 리스트, 또는 사용자 정의 함수 등. 표준형 계층 에 추가적인 형들에 대해 설명되어 있습니다.) 잘 알려진 형에는 객체가 해당 형인지를 확인하는 매크로가 있습니다. 예를 들어 `PyList_Check(a)` 는 a 가 가리키는 객체가 파이썬 리스트일 경우에만 참입니다.

### 참조 횟수

오늘날의 컴퓨터는 유한한(그리고 자주 제한되는) 양의 메모리를 가지고 있기 때문에 참조 횟수는 매우 중요합니다; 참조 횟수는 객체에 대해 강한 참조를 갖는 위치의 갯수를 셉니다. 객체를 참조하는 위치는 다른 객체일 수도 있고, C 전역 변수이거나 C 함수 안의 지역 변수일 수도 있습니다. 객체에 대한 마지막 강한 참조가 해제될 때 (즉, 객체의 참조 횟수가 0이 되면), 객체는 할당이 해제됩니다. 객체가 다른 객체에 대한 참조를 가지고 있을 경우, 그 참조들도 해제됩니다. 이들에 대한 참조가 더는 없으면, 다른 객체들이 차례로 할당이 해제될 수 있습니다. (서로를 참조하는 객체에 대해 분명한 문제점이 있으나 현재 해결책은 “그러지 마세요” 입니다.)

참조 횟수는 항상 명시적으로 조작됩니다. 일반적인 방법은 매크로 `Py_INCREF()` 를 사용하여 객체에 대한 새로운 참조를 취하고(즉, 객체의 참조 횟수를 하나 증가시키고), `Py_DECREF()` 를 사용하여 참조를 해제하는 (즉, 참조 횟수를 하나 감소시키는) 것입니다. `Py_DECREF()` 매크로는 참조 횟수가 0이 되는지를 확인하고 객체의 할당해제자(deallocator) 를 호출해야 하므로 참조 횟수를 증가시키는 매크로보다 상당히 복잡합니다. 할당 해제자는 객체의 형 구조체에 포함된 함수 포인터입니다. 형별 할당 해제자는 리스트와 같은 복합 객체 형에 대해서 객체에 포함된 객체에 포함 된 다른 객체에 대한 참조를 해제하고 필요한 추가 마무리 작업을 수행합니다. 참조 횟수가 오버플로우 될 가능성은 없습니다. 참조 횟수를 저장하기 위해서 가상 메모리 안에서 구별되는 메모리 위치 만큼 (`sizeof(Py_ssize_t) >= sizeof(void*)` 라고 가정할 경우) 많은 비트가 사용됩니다. 따라서 참조 횟수 증가는 간단한 연산입니다

객체에 대한 포인터를 포함하는 모든 지역 변수에 대해 객체에 대한 강한 참조를 잡을 (즉, 참조 횟수를 증가시킬) 필요는 없습니다. 이론적으로는 객체의 참조 횟수는 변수가 객체를 가리킬 때 증가하고 변수가 스코프를 벗어날 때 감소합니다. 하지만 이 두 동작은 서로를 상쇄시키기 때문에 결과적으로 참조 횟수는 변하지 않습니다. 참조 횟수를 사용해야만 하는 이유는 우리의 변수가 객체를 참조하는 한 객체가 할당 해제되지 않도록 하기 위함입니다. 만약 객체에 대한 적어도 하나 이상의 다른 참조가 우리의 변수만큼 오래 살아있을 것을 안다면 일시적으로 새로운 strong reference를 취할 (즉, 참조 횟수를 증가시킬) 필요가 없습니다. 이런 현상이 발생하는 중요한 상황은 파이썬이 호출하는 확장 모듈의 C 함수에 인자로 넘겨지는 객체에서 발생합니다. 호출 메커니즘은 호출하는동안 모든 인자에 대한 참조를 보유하도록 보장합니다.

그러나 흔히 하기 쉬운 실수는 리스트에서 객체를 가져와 새 참조를 취하지 않고 유지하는 것입니다. 다른 연산이 리스트에서 객체를 제거해 그 참조를 해제하면 객체가 할당 해제될수도 있습니다. 진짜 위험은 무해해 보이는 연산이 이를 실행할 수도 있는 임의의 파이썬 코드를 실행할수도 있다는 것입니다. `Py_DECREF()` 에서 사용자로 컨트롤을 돌아가게 하는 코드 경로가 있기 때문에 사실 거의 모든 연산이 잠재적으로 위험합니다.

안전한 접근방식은 제네릭 연산들 (`PyObject_`, `PyNumber_`, `PySequence_` 또는 `PyMapping_` 로 시작하는 이름을 가진 함수들) 을 사용하는 것입니다. 이러한 연산들은 항상 반환하는 모든 객체에 대해 새로운 강한 참조를 만듭니다 (즉, 참조 횟수를 증가시킵니다). 이는 함수 호출자에게 연산이 반환된 객체와의 작업이 끝났을 경우 `Py_DECREF()` 를 호출할 책임을 지웁니다. 이건 곧 습관화 될 것입니다.

#### 참조 횟수 상세

파이썬/C API 에서 함수의 참조 횟수 동작은 참조의 소유권 으로 가장 잘 설명됩니다. 소유권은 객체가 아닌 참조에 관련되어 있습니다. (객체는 소유되지 않습니다: 객체는 항상 공유됩니다.) “참조를 소유하는 것” 은 더 이상 참조가 필요하지 않을 때 Py_DECREF 를 호출할 책임이 있다는 것을 의미합니다. 소유권은 양도될 수도 있습니다. 즉, 참조의 소유권을 받은 코드가 소유권이 더 이상 필요하지 않을 때 `Py_DECREF()` 또는 `Py_XDECREF()` 를 호출하거나 책임을 (대게 자신의 호출자에게) 넘김으로써 결국 참조를 해제할 책임이 생긴다는 것을 의미합니다. 함수가 참조의 소유권을 호출자에게 넘길때 호출자는 새로운 참조를 받는다고 합니다. 소유권이 옮겨지지 않을 때 호출자는 참조를 빌린다 라고 합니다. 빌린 참조를 위해서는 아무것도 할 필요가 없습니다.

반대로 호출 함수에게 객체에 대한 참조를 넘길 때는 두가지 가능성이 있습니다: 함수는 객체에 대한 참조를 훔칠 수도, 그러지 않을 수도 있습니다. 참조를 훔치는 것은 함수에 참조를 전달할 때 해당 함수가 전달된 참조를 소유한다고 가정하고 더 이상 책임을 지지 않는다는 것을 의미합니다.

참조를 훔치는 함수는 거의 없습니다. 주목할만한 두가지 예외는 `PyList_SetItem()` 과 `PyTuple_SetItem()` 입니다. 이 두가지 함수는 요소에 대한 참조를 훔칩니다(단, 요소를 넣을 튜플이나 리스트에 대한 참조는 훔치지 않습니다.). 이 함수들은 새로 만들어진 객체들로 튜플이나 리스트를 채우는 일반적인 관행 때문에 참조를 훔치도록 설계되었습니다. 예를 들어, 튜플을 만드는 코드 `(1, 2, "three")` 는 다음과 같을 수 있습니다. (잠시 에러 처리는 잊어버리십시오. 더 좋은 방법으로 코딩하는 방법은 아래에 나와 있습니다.):

    PyObject *t;

    t = PyTuple_New(3);
    PyTuple_SetItem(t, 0, PyLong_FromLong(1L));
    PyTuple_SetItem(t, 1, PyLong_FromLong(2L));
    PyTuple_SetItem(t, 2, PyUnicode_FromString("three"));

여기서 `PyTuple_SetItem()` 는 `PyLong_FromLong()` 가 반환한 참조를 곧바로 훔칩니다. 객체에 대한 참조가 훔쳐져도 계속 객체를 사용하려면 참조를 훔치는 함수를 호출하기 전에 `Py_INCREF()` 를 다른 참조를 가져오는데 사용하십시오.

덧붙이자면, `PyTuple_SetItem()` 은 튜플에 요소를 넣는 유일한 방법입니다. 튜플은 불변 자료형이기 때문에 `PySequence_SetItem()` 과 `PyObject_SetItem()` 는 튜플에 요소를 넣는 것을 거부합니다. `PyTuple_SetItem()` 은 직접 만들고 있는 튜플에만 사용되어야 합니다.

리스트를 채우는 동일한 의미의 코드는 `PyList_New()` 와 `PyList_SetItem()` 을 사용해 만들 수 있습니다.

하지만 실제로는 이렇게 튜플 또는 리스트를 만들고 채우는 경우는 드뭅니다. 일반적인 객체들을 형식 문자열(format string)로 지시되는 C 값으로부터 만들어낼 수 있는 제네릭 함수 `Py_BuildValue()` 가 있습니다. 예룰 들어, 위의 두 블록의 코드를 다음 코드로 대체할 수 있습니다. (에러 검사도 처리합니다.):

    PyObject *tuple, *list;

    tuple = Py_BuildValue("(iis)", 1, 2, "three");
    list = Py_BuildValue("[iis]", 1, 2, "three");

`PyObject_SetItem()` 과 그 친구들은 함수에 전달되는 인자처럼 참조만 빌리고 있는 요소와 함께 사용하는 것이 일반적입니다. 이 경우 새로운 참조를 취하지 않고 참조를 제공할 수 있으므로 참조에 대한 함수들의 동작이 훨씬 멀쩡합니다:

    int
    set_all(PyObject *target, PyObject *item)
    {
        Py_ssize_t i, n;

        n = PyObject_Length(target);
        if (n < 0)
            return -1;
        for (i = 0; i < n; i++) {
            PyObject *index = PyLong_FromSsize_t(i);
            if (!index)
                return -1;
            if (PyObject_SetItem(target, index, item) < 0) {
                Py_DECREF(index);
                return -1;
            }
            Py_DECREF(index);
        }
        return 0;
    }

함수 반환 값에 대해서는 상황이 약간 다릅니다. 대부분의 함수에 참조를 전달해도 해당 참조에 대한 소유권 책임이 바뀌진 않지만 객체에 대한 참조를 제공하는 많은 함수는 참조의 소유권을 제공합니다. 이유는 간단합니다. 대부분의 경우에서 반환된 객체는 즉석에서 생성되고 반환된 참조는 객체에 대한 유일한 참조입니다. 따라서 `PyObject_GetItem()` 과 `PySequence_GetItem()` 처럼 객체에 대한 참조를 반환하는 제네릭 함수들은 언제나 새로운 참조를 반환합니다 (호출자가 객체의 소유자가 됩니다).

함수의 의해 반환된 함수를 소유하고 있는지는 어떤 함수를 호출하느냐에 따라 달라진다는 것을 아는 것이 중요합니다. — 깃털 (함수에 인자로 전달된 객체의 형) 은 해당되지 않습니다! 따라서 `PyList_GetItem()` 를 사용하여 리스트에서 항목을 가져오면 참조를 소유하지 않습니다. — 하지만 동일한 인자를 받는 `PySequence_GetItem()` 를 사용하여 리스트에서 항목을 가져온다면 반환된 객체에 대한 참조를 소유하게 됩니다.

다음은 정수 리스트에 있는 항목의 합계를 구하는 함수를 작성하는 방법의 예시입니다. 한 번은 `PyList_GetItem()` 를 사용하고, 한 번은 `PySequence_GetItem()` 을 사용합니다.

    long
    sum_list(PyObject *list)
    {
        Py_ssize_t i, n;
        long total = 0, value;
        PyObject *item;

        n = PyList_Size(list);
        if (n < 0)
            return -1; /* Not a list */
        for (i = 0; i < n; i++) {
            item = PyList_GetItem(list, i); /* Can't fail */
            if (!PyLong_Check(item)) continue; /* Skip non-integers */
            value = PyLong_AsLong(item);
            if (value == -1 && PyErr_Occurred())
                /* Integer too big to fit in a C long, bail out */
                return -1;
            total += value;
        }
        return total;
    }

    long
    sum_sequence(PyObject *sequence)
    {
        Py_ssize_t i, n;
        long total = 0, value;
        PyObject *item;
        n = PySequence_Length(sequence);
        if (n < 0)
            return -1; /* Has no length */
        for (i = 0; i < n; i++) {
            item = PySequence_GetItem(sequence, i);
            if (item == NULL)
                return -1; /* Not a sequence, or other failure */
            if (PyLong_Check(item)) {
                value = PyLong_AsLong(item);
                Py_DECREF(item);
                if (value == -1 && PyErr_Occurred())
                    /* Integer too big to fit in a C long, bail out */
                    return -1;
                total += value;
            }
            else {
                Py_DECREF(item); /* Discard reference ownership */
            }
        }
        return total;
    }

### 형

파이썬/C API에서 중요한 역할을 하는 다른 데이터 형은 거의 없습니다. 대부분은 int, long, double 그리고 char* 같은 평범한 C 형입니다. 모듈에서 내보내는 함수나 새 객체 형의 데이터 속성들을 나열하는데 사용되는 정적 테이블을 표현하는데 사용되는 구조체 형이 몇가지 있으며, 복소수를 표현하기 위해 사용되는 구조체 형도 있습니다. 이러한 형들은 해당 형들을 사용하는 함수와 함께 다뤄질 것입니다.

type Py_ssize_t
  Part of the 안정 ABI.

  A signed integral type such that `sizeof(Py_ssize_t) == sizeof(size_t)`. C99 doesn’t define such a thing directly (size_t is an unsigned integral type). See PEP 353 for details. `PY_SSIZE_T_MAX` is the largest positive value of type `Py_ssize_t`.

## 예외

파이썬 프로그래머는 특정한 에러 처리가 필요할 경우에만 에러를 처리하면 됩니다. 처리되지 않은 예외는 사용자에게 전달되는 최상위 인터프리터까지 스택 트레이스백과 함께 자동으로 호출자, 호출자의 호출자 등으로 전파됩니다.

그러나 C 프로그래머들에게 에러 검사는 항상 명시적이어야만 합니다. 파이썬/C API의 모든 함수는 해당 함수의 문서에서 명시하지 않는 한 예외를 발생시킬 수 있습니다. 일반적으로 함수에 에러가 발생하면 함수는 예외를 설정하고 소유하고 있는 모든 객체에 대한 참조를 취소하고 에러 표시기를 반환합니다. 달리 문서화되지 않은 경우 표시기는 함수의 반환 형에 따라 `NULL` 또는 `-1` 입니다. 일부 함수는 에러를 의미하는 거짓과 함께 참/거짓의 불리언 결과를 반환합니다. 아주 일부의 함수는 명시적인 에러 표시기가 없거나 모호한 반환값을 가지며 `PyErr_Occurred()` 를 사용하여 명시적인 점검을 요구합니다. 이런 예외는 항상 명시적으로 문서화됩니다.

예외 상태는 스레드 별 공간에서 관리됩니다. (스레드를 사용하지 않는 프로그램에서는 전역 공간을 사용한다는 말과 같습니다.) 스레드는 예외가 발생했거나, 발생하지 않았거나의 두가지 상태 중 하나일 수 있습니다. 함수 `PyErr_Occurred()` 는 이 상태를 확인하기 위해 사용할 수 있습니다. 해당 함수는 예외가 발생했을 경우 예외 형 객체에 대한 빌린 참조를 반환합니다. 예외가 발생하지 않았을 경우엔 `NULL` 을 반환합니다. 예외 상태를 설정하기 위한 여러가지 함수들이 있습니다: `PyErr_SetString()` 는 예외 상태를 설정하기 위해 가장 보편적인 (가장 일반적인 것은 아니지만) 함수입니다. `PyErr_Clear()` 는 예외 상태를 지웁니다.

전체 예외 상태는 예외 형, 해당 예외 값, 트레이스백이라는 세가지 객체로 구성됩니다. (셋 모두 `NULL` 일 수 있습니다.) 이 세가지 객체는 파이썬의 `sys.exc_info()` 의 결과와 같은 의미를 가지고 있지만 동일하지는 않습니다. 파이썬 객체는 `try` … `except` 문으로 처리되는 마지막 예외를 표현하는 반면 C 수준 예외는 `sys.exc_info()` 와 그 친구들로 예외를 전송하는 파이썬 바이트코드 인터프리터의 메인 루프에 도달할 때까지 C 함수들 간에 전달되는 동안에만 존재합니다.

파이썬 1.5부터 선호되어 온 파이썬 코드에서의 스레드 안전한 예외 상태 접근 방법은 파이썬 코드를 위해 스레드 별 예외 상태를 반환하는 `sys.exc_info()` 함수를 호출하는 것입니다. 또한 예외 상태에 접근하는 양쪽 방법의 의미도 바뀌어 에러를 포착하는 함수가 호출자의 예외 상태를 보존하기 위해 스레드의 예외를 저장하고 복원합니다. 이는 평범해 보이는 함수가 처리중인 예외를 덮어씌우는 것으로 인한 예외 처리 코드의 흔한 버그를 방지합니다. 또한 트레이스백의 스택 프레임에 의하여 참조되는 객체들에 대해 종종 원하지 않은 수명 증가가 일어나는 것을 방지합니다

일반적으로 어떤 작업을 수행하기 위해 다른 함수를 호출하는 함수는 호출된 함수가 예외를 일으켰는지 확인해야만 하며 만약 예외가 일어났다면 호출자에게 예외 상태를 전달해야 합니다. 소유하고 있는 모든 객체에 대한 참조를 버리고 에러 표시기를 반환해야 하지만 다른 예외를 설정해서는 안됩니다. — 방금 일어난 예외를 덮어씌우고 정확한 에러 원인에 대한 중요한 정보를 잃어버리게 됩니다.

예외를 감지하고 전달하는 간단한 예가 아래 `sum_sequence()` 예시에 나와 있습니다. 우연히 이 예시에선 에러를 감지했을 때 소유하고 있는 참조를 정리할 필요가 없습니다. 그 다음 예시 함수에서는 몇가지 에러 정리작업을 보여줍니다. 먼저 파이썬을 좋아하는 이유를 상기시키기 위해 같은 의미의 파이썬 코드를 제공합니다:

    def incr_item(dict, key):
        try:
            item = dict[key]
        except KeyError:
            item = 0
        dict[key] = item + 1

다음은 같은 의미의 웅장한 C 코드입니다:

    int
    incr_item(PyObject *dict, PyObject *key)
    {
        /* Objects all initialized to NULL for Py_XDECREF */
        PyObject *item = NULL, *const_one = NULL, *incremented_item = NULL;
        int rv = -1; /* Return value initialized to -1 (failure) */

        item = PyObject_GetItem(dict, key);
        if (item == NULL) {
            /* Handle KeyError only: */
            if (!PyErr_ExceptionMatches(PyExc_KeyError))
                goto error;

            /* Clear the error and use zero: */
            PyErr_Clear();
            item = PyLong_FromLong(0L);
            if (item == NULL)
                goto error;
        }
        const_one = PyLong_FromLong(1L);
        if (const_one == NULL)
            goto error;

        incremented_item = PyNumber_Add(item, const_one);
        if (incremented_item == NULL)
            goto error;

        if (PyObject_SetItem(dict, key, incremented_item) < 0)
            goto error;
        rv = 0; /* Success */
        /* Continue with cleanup code */

     error:
        /* Cleanup code, shared by success and failure path */

        /* Use Py_XDECREF() to ignore NULL references */
        Py_XDECREF(item);
        Py_XDECREF(const_one);
        Py_XDECREF(incremented_item);

        return rv; /* -1 for error, 0 for success */
    }

이 예시는 C `goto` 문의 허용된 사용방법을 보여줍니다! 이 예시는 특정한 예외를 처리하기 위한 `PyErr_ExceptionMatches()` 와 `PyErr_Clear()` 의 사용 방법과 `Py_XDECREF()` 를 사용하여 소유하고 있는 `NULL` 일 수도 있는 참조를 삭제하는 방법을 표현합니다. (이름에 있는 `'X'` 를 주목하십시오. `Py_DECREF()` 는 `NULL` 참조와 마주치면 충돌을 일으킵니다.) 이 예시를 수행하려면 소유하고 있는 참조를 보유하는데 사용하는 변수를 `NULL` 로 초기화하는 것이 중요합니다. 마찬가지로 반환 값은 `-1` (실패) 로 설정되고 마지만 호출이 성공한 뒤에야 성공으로 설정됩니다.

## 파이썬 임베딩하기

확장 작성자들과는 달리 파이썬 인터프리터를 임베딩 하는 사람들만이 걱정해야 하는 한가지 중요한 문제는 파이썬 인터프리터의 초기화, 그리고 아마도 마무리일 것입니다. 인터프리터의 대부분의 기능은 인터프리터가 초기화 된 이후에 사용할 수 있습니다.

기본적인 초기화 함수는 `Py_Initialize()` 입니다. 이 함수는 로드된 모듈 테이블을 초기화 하고 기본 모듈인 `builtins`, `__main__`, 그리고 `sys` 를 생성합니다. 또한 모듈 검색 경로 (`sys.path`) 를 초기화합니다

`Py_Initialize()` 는 “스크립트 인자 리스트” (`sys.argv`) 를 설정하지 않습니다. 만약 후에 실행될 파이썬 코드가 이 변수를 필요로 한다면, 설정 `PyConfig.argv`와 `PyConfig.parse_argv`는 반드시 설정되어야 합니다: 파이썬 초기화 구성을 참조하세요.

대부분의 시스템에서 (특별히 유닉스와 윈도우는 세부적인 부분이 조금 다르긴 하지만) `Py_Initialize()` 는 파이썬 인터프리터를 기준으로 고정된 위치에 파이썬 라이브러리가 있다고 가정하여 표준 파이썬 인터프리터 실행 파일에 대한 최선의 추측을 바탕으로 바탕으로 모듈 검색 경로를 계산합니다. 특히 셸 명령어 검색 경로 (환경 변수 `PATH`) 에서 `python` 이라는 이름의 실행 파일이 발견되는 부모 디렉터리를 기준으로 `lib/pythonX.Y` 같은 이름을 가진 디렉터리를 찾습니다.

예를 들어 파이썬 실행 파일이 `/usr/local/bin/python` 에서 발견된다면 라이브러리는 `/usr/local/lib/pythonX.Y` 에 있는 것으로 가정합니다. (실제로 이 특정 경로는 `PATH` 를 따라 `python` 이라는 이름의 실행 파일이 발견되지 않을 때 사용되는 “fallback” 경로이기도 합니다.) 유저는 환경 변수 `PYTHONHOME` 를 설정하여 이 동작을 재정의하거나 `PYTHONPATH` 를 설정하여 표준 경로 앞에 추가적인 디렉터리를 추가할 수 있습니다.

파이썬을 임베딩하는 애플리케이션은 `Py_InitializeFromConfig()` 를 호출하기 전에 `PyConfig.program_name` 을 설정하여 검색을 제어할 수 있습니다. `PYTHONHOME` 는 여전히 이 값을 재정의하며 `PYTHONPATH` 는 여전히 표준 경로 앞에 추가된다는 점에 유의하십시오. 완전한 제어가 필요한 애플리케이션은 `Py_GetPath()`, `Py_GetPrefix()`, `Py_GetExecPrefix()`, 그리고 `Py_GetProgramFullPath()` 의 자체적인 구현을 제공할 필요가 있습니다. (모두 `Modules/getpath.c` 에 정의되어 있습니다.)

가끔은 파이썬을 “uninitialize” 하는 것이 바람직합니다. 예를 들어 애플리케이션이 다시 시작하거나 (`Py_Initialize()` 다시 호출하기) 애플리케이션에서 파이썬의 사용이 끝나 파이썬이 할당한 메모리를 해제하려고 할 수 있습니다. `Py_FinalizeEx()` 를 호출하여 이를 달성할 수 있습니다. 함수 `Py_IsInitialized()` 는 파이썬이 현재 초기화된 상태에 있을 경우 참을 반환합니다. 이 함수들에 대한 자세한 내용은 다른 장에서 제공됩니다. `Py_FinalizeEx()` 가 파이썬 인터프리터가 할당한 모든 메모리를 해제하지는 않는다는 점에 유의해야 합니다. 예를 들어, 현재 확장 모듈에서 할당한 메모리는 해제할 수 없습니다.

## 디버깅 빌드

파이썬은 인터프리터와 확장 모듈들에 대한 추가적인 검사를 가능하게 하는 여러 매크로를 사용하여 빌드될 수 있습니다. 이러한 검사는 런타임에 많은 오버헤드를 추가하는 경향이 있으므로 기본적으로 실행되지 않습니다.

다양한 유형의 디버깅 빌드의 전체 목록은 파이썬 소스 배포판 안의 `Misc/SpecialBuilds.txt` 파일에 있습니다. 참조 횟수 추적, 메모리 할당자 디버깅, 메인 인터프리터 루프의 저수준 프로파일링을 지원하는 빌드들을 사용할 수 있습니다. 이 섹션에서는 가장 자주 사용되는 빌드만 설명합니다.

Py_DEBUG

`Py_DEBUG` 매크로가 정의된 인터프리터를 컴파일하면 일반적으로 파이썬의 디버그 빌드가 일반적으로 의미하는 빌드가 생성됩니다. `Py_DEBUG` 는 `./configure` 명령에 `--with-pydebug` 를 추가하여 유닉스 빌드에서 활성화됩니다. 또한 파이썬 전용이 아닌 `_DEBUG` 매크로의 존재를 암시합니다. 유닉스 빌드에서 `Py_DEBUG` 가 활성화 되어있으면 컴파일러 최적화가 비활성화됩니다.

아래에 설명된 참조 횟수 디버깅 외에도 추가적인 검사가 수행됩니다, 파이썬 디버그 빌드를 찹조하세요.

`Py_TRACE_REFS` 를 정의하면 참조 추적이 활성화됩니다 (`configure --with-trace-refs option`를 참조하세요). 정의된 경우 모든 `PyObject` 에 두 개의 추가 필드를 추가함으로써 활성 객체에 대한 이중 원형 연결 리스트가 유지됩니다. 또한 모든 할당이 추적됩니다. 인터프리터 종료시에는 현재 사용되고 있는 모든 참조가 출력됩니다. (대화식 모드에서는 인터프리터가 명령문을 실행할 때마다 이후에 출력됩니다.)

자세한 내용은 파이썬 소스 배포판 안의 `Misc/SpecialBuilds.txt` 를 참조하십시오.

## Recommended third party tools

The following third party tools offer both simpler and more sophisticated approaches to creating C, C++ and Rust extensions for Python:

- Cython

- cffi

- HPy

- nanobind (C++)

- Numba

- pybind11 (C++)

- PyO3 (Rust)

- SWIG

Using tools such as these can help avoid writing code that is tightly bound to a particular version of CPython, avoid reference counting errors, and focus more on your own code than on using the CPython API. In general, new versions of Python can be supported by updating the tool, and your code will often use newer and more efficient APIs automatically. Some tools also support compiling for other implementations of Python from a single set of sources.

These projects are not supported by the same people who maintain Python, and issues need to be raised with the projects directly. Remember to check that the project is still maintained and supported, as the list above may become outdated.

더 보기

Python Packaging User Guide: Binary Extensions

  The Python Packaging User Guide not only covers several available tools that simplify the creation of binary extensions, but also discusses the various reasons why creating an extension module may be desirable in the first place.