[Final] PEP 757 - C API to import-export Python integers

원문 링크: PEP 757 - C API to import-export Python integers

상태: Final 유형: Standards Track 작성일: 13-Sep-2024

PEP 757 – C API를 이용한 Python 정수 import/export

개요

새로운 C API, 특히 PyLongWriter_Create()PyLong_Export() 함수를 추가하여 Python 정수(int 객체)를 import하고 export하는 기능을 제공합니다.

도입 배경 (Rationale)

gmpy2, SAGE, Python-FLINT와 같은 프로젝트들은 Python의 내부(PyLongObject 구조체)에 직접 접근하거나 비효율적인 임시 형식(예: Python-FLINT의 16진수 문자열)을 사용하여 Python int 객체를 import 및 export합니다.

Python 3.12에서는 int 구현이 tag와 “compact values”를 추가하는 방향으로 변경되었습니다. 3.13 alpha 1 릴리스에서는 비공개, 비문서화된 _PyLong_New() 함수가 제거되었지만, 이 함수는 앞서 언급된 프로젝트들에서 Python 정수를 import하는 데 사용되고 있었습니다. 이 함수는 3.13 alpha 2에서 복원되었습니다.

이러한 프로젝트들이 Python의 내부 구현 세부 사항에 노출되지 않으면서도 효율적으로 연동될 수 있도록, 공개적이고 효율적인 추상화 계층이 필요합니다. 이는 Python 내부 구현이 변경되더라도 해당 프로젝트들이 깨지지 않도록 할 것입니다. 예를 들어, gmpy2의 구현은 최근 CPython 3.9 및 CPython 3.12에 맞춰 변경된 바 있습니다.

명세 (Specification)

레이아웃 API (Layout API)

GMP(GNU Multiple Precision Arithmetic Library)와 유사한 import-export 함수에 필요한 데이터입니다.

struct PyLongLayout

임의 정밀도 정수의 절대값을 나타내는 “digit” 배열(GMP 용어로는 “limb”)의 레이아웃입니다. “충분히 큰” 절대값을 가진 정수에서 내부적으로 사용되는 Python int 객체의 기본 레이아웃을 얻으려면 PyLong_GetNativeLayout() 함수를 사용합니다.

sys.int_info는 Python에 유사한 정보를 노출합니다.

  • uint8_t bits_per_digit: digit당 비트 수. 예를 들어, 15비트 digit은 비트 0-14에 유의미한 정보가 포함됨을 의미합니다.
  • uint8_t digit_size: digit의 바이트 크기. 예를 들어, 15비트 digit은 최소 2바이트를 필요로 합니다.
  • int8_t digits_order: digit 순서:
    • 1: 최상위 digit 우선 (most significant digit first)
    • -1: 최하위 digit 우선 (least significant digit first)
  • int8_t digit_endianness: digit의 엔디안(endianness):
    • 1: 최상위 바이트 우선 (big endian)
    • -1: 최하위 바이트 우선 (little endian)

const PyLongLayout *PyLong_GetNativeLayout(void)

Python int 객체의 기본 레이아웃을 가져옵니다. PyLongLayout 구조체를 참조하세요. 이 함수는 Python 초기화 전이나 종료 후에는 호출되어서는 안 됩니다. 반환된 레이아웃은 Python이 종료될 때까지 유효합니다. 이 레이아웃은 모든 Python 서브 인터프리터에서 동일하므로 캐시할 수 있습니다.

Export API

Python int 객체를 export하는 데 사용됩니다.

struct PyLongExport

Python int 객체의 export 구조입니다. 두 가지 경우가 있습니다:

  • digitsNULL인 경우, value 멤버만 사용합니다.
  • digitsNULL이 아닌 경우, negative, ndigits, digits 멤버를 사용합니다.

  • int64_t value: export된 int 객체의 네이티브 정수 값. digitsNULL인 경우에만 유효합니다.
  • uint8_t negative: 숫자가 음수이면 1, 아니면 0. digitsNULL이 아닌 경우에만 유효합니다.
  • Py_ssize_t ndigits: digits 배열의 digit 수. digitsNULL이 아닌 경우에만 유효합니다.
  • const void *digits: 읽기 전용 부호 없는 digit 배열. NULL일 수 있습니다.

PyLongExport.digitsNULL이 아닌 경우, PyLongExport 구조체의 private 필드에 Python int 객체에 대한 강력한 참조(strong reference)를 저장하여 PyLong_FreeExport()가 호출될 때까지 구조체가 유효하게 유지되도록 합니다.

int PyLong_Export(PyObject *obj, PyLongExport *export_long)

Python int 객체를 export합니다. export_long은 호출자가 할당한 PyLongExport 구조체를 가리켜야 하며, NULL이 아니어야 합니다. 성공 시 *export_long을 채우고 0을 반환합니다. 오류 발생 시 예외를 설정하고 -1을 반환합니다. export가 더 이상 필요하지 않을 때 PyLong_FreeExport()를 호출해야 합니다.

CPython 구현 세부 사항: obj가 Python int 객체 또는 서브클래스인 경우 이 함수는 항상 성공합니다. CPython 3.14에서는 PyLong_Export()에서 메모리 복사가 필요하지 않으며, 이는 Python int의 내부 digit 배열을 노출하기 위한 얇은 래퍼(thin wrapper)에 불과합니다.

void PyLong_FreeExport(PyLongExport *export_long)

PyLong_Export()로 생성된 export_long export를 해제합니다. CPython 구현 세부 사항: export_long->digitsNULL인 경우 PyLong_FreeExport() 호출은 선택 사항입니다.

Import API

PyLongWriter API를 사용하여 정수를 import할 수 있습니다.

struct PyLongWriter

Python int writer 인스턴스입니다. 이 인스턴스는 PyLongWriter_Finish() 또는 PyLongWriter_Discard()에 의해 파괴되어야 합니다.

PyLongWriter *PyLongWriter_Create(int negative, Py_ssize_t ndigits, void **digits)

PyLongWriter를 생성합니다. 성공 시 *digits를 할당하고 writer를 반환합니다. 오류 발생 시 예외를 설정하고 NULL을 반환합니다. negative는 숫자가 음수이면 1, 아니면 0입니다. ndigitsdigits 배열의 숫자(digit) 수입니다. 0보다 커야 합니다. digitsNULL이 아니어야 합니다.

이 함수를 성공적으로 호출한 후, 호출자는 digits 배열을 채우고 PyLongWriter_Finish()를 호출하여 Python int를 얻어야 합니다. digits의 레이아웃은 PyLong_GetNativeLayout()에 의해 설명됩니다. Digits는 [0; (1 << bits_per_digit) - 1] 범위에 있어야 합니다 (bits_per_digit는 digit당 비트 수). 사용되지 않는 최상위 digit은 0으로 설정해야 합니다. 또는 PyLongWriter_Discard()를 호출하여 int 객체를 생성하지 않고 writer 인스턴스를 파괴할 수 있습니다.

CPython 3.14에서는 PyLongWriter_Create() 구현이 private _PyLong_New() 함수에 대한 얇은 래퍼입니다.

PyObject *PyLongWriter_Finish(PyLongWriter *writer)

PyLongWriter_Create()로 생성된 PyLongWriter를 완료합니다. 성공 시 Python int 객체를 반환합니다. 오류 발생 시 예외를 설정하고 NULL을 반환합니다. 이 함수는 digit을 정규화하고 필요한 경우 객체를 compact integer로 변환합니다. 호출 후 writer 인스턴스와 digits 배열은 유효하지 않습니다.

void PyLongWriter_Discard(PyLongWriter *writer)

PyLongWriter_Create()로 생성된 PyLongWriter를 폐기합니다. writerNULL이 아니어야 합니다. 호출 후 writer 인스턴스와 digits 배열은 유효하지 않습니다.

작은 정수 import 최적화 (Optimize import for small integers)

제안된 import API는 큰 정수에 효율적입니다. Python 내부(internals)에 직접 접근하는 것과 비교할 때, 제안된 import API는 작은 정수에서 상당한 성능 오버헤드를 가질 수 있습니다.

몇 개의 digit을 가진 작은 정수(예: 1 또는 2 digit)의 경우, 기존 API를 사용할 수 있습니다:

  • PyLong_FromUInt64()
  • PyLong_FromLong()
  • PyLong_FromNativeBytes()

구현 (Implementation)

벤치마크 (Benchmarks)

Export: PyLong_Export() with gmpy2

벤치마크 결과 (Linux Fedora 40, CPU 격리, 릴리스 모드로 빌드된 Python):

Benchmark ref pep757  
1<<7 91.3 ns 89.9 ns 1.02x faster
1<<38 120 ns 94.9 ns 1.27x faster
1<<300 196 ns 203 ns 1.04x slower
1<<3000 939 ns 945 ns 1.01x slower
Geometric mean (ref)     1.05x faster

1<<7 (128) 및 1<<38과 같은 작은 정수의 export에서 pep757 구현이 더 빠르며, 1<<3001<<3000과 같은 큰 정수에서는 약간 느리거나 비슷한 성능을 보였습니다.

Import: PyLongWriter_Create() with gmpy2

벤치마크 결과 (Linux Fedora 40, CPU 격리, 릴리스 모드로 빌드된 Python):

Benchmark ref pep757  
1<<7 56.7 ns 56.2 ns 1.01x faster
1<<300 191 ns 213 ns 1.12x slower
Geometric mean (ref)     1.03x slower

1<<7 (128)과 같은 작은 정수의 import에서 pep757 구현이 약간 더 빠르며, 1<<300과 같은 큰 정수에서는 약간 느려졌습니다. 1<<38, 1<<3000 벤치마크는 유의미하지 않다고 숨겨졌습니다.

하위 호환성 (Backwards Compatibility)

새로운 API만 추가되므로 하위 호환성에 미치는 영향은 없습니다.

기각된 아이디어 (Rejected Ideas)

임의의 레이아웃 지원 (Support arbitrary layout)

Python 정수를 import-export하기 위해 임의의 레이아웃을 지원하는 것은 편리할 수 있습니다. 예를 들어, PyLongWriter_Create()layout 매개변수를 추가하고 PyLongExport 구조체에 layout 멤버를 추가하는 것이 제안되었습니다. 그러나 구현이 더 복잡하고 실제로 필요하지 않습니다. 엄밀히 필요한 것은 Python의 “네이티브(native)” 레이아웃을 사용하여 import-export하는 API뿐입니다. 나중에 임의의 레이아웃에 대한 사용 사례가 있다면 새로운 API를 추가할 수 있습니다.

PyLong_GetNativeLayout() 함수를 추가하지 않음 (Don’t add PyLong_GetNativeLayout() function)

현재 대부분의 정수 import/export에 필요한 정보는 PyLong_GetInfo() (및 sys.int_info)를 통해 이미 사용 가능합니다. 또한, 더 많은 정보(예: digits 순서)를 추가할 수 있으며, 이 인터페이스는 PyLongObject의 미래 발전에 어떤 제약도 가하지 않습니다. 문제는 PyLong_GetInfo()가 편리한 C 구조체가 아닌 Python 객체(named tuple)를 반환한다는 점이며, 이는 사람들이 현재의 세미-프라이빗 매크로(PyLong_SHIFTPyLong_BASE 등)를 선호하게 만들 수 있습니다.

mpz_import/export와 유사한 API 제공 (Provide mpz_import/export-like API instead)

int 객체에서 데이터를 import/export하는 또 다른 접근 방식은 C 확장이 연속적인 버퍼를 제공하고 CPython이 정수의 절대값을 export(또는 import)하는 것을 기대하는 것입니다. 이 접근 방식의 주요 단점은 CPython 측면에서 훨씬 더 복잡하다는 것입니다(즉, 다른 레이아웃 간의 실제 변환). 예를 들어, CPython에서 PyLong_FromNativeBytes()PyLong_AsNativeBytes() 구현(함께 필요한 API의 제한된 버전을 제공)은 약 500줄의 코드를 차지했습니다(현재 구현은 약 100줄).

export API에서 value 필드를 삭제 (Drop value field from the export API)

이 제안에 따르면, 하나의 export 유형(digit 배열)만 존재하게 됩니다. 주어진 정수에 대해 이러한 뷰를 사용할 수 없는 경우, export 함수에 의해 에뮬레이션되거나 PyLong_Export()가 오류를 반환할 것입니다. 두 경우 모두, 사용자는 PyLong_AsLongAndOverflow()와 같이 “충분히 작은” 정수(즉, 일부 머신 정수 형식에 맞는 정수)를 얻기 위해 다른 C-API 함수를 사용할 것으로 가정합니다. 이 경우 PyLong_Export()는 비효율적이거나 실패할 것입니다. 이는 API 설계자 관점에서는 단순화처럼 보일 수 있지만, 최종 사용자에게는 덜 편리할 것입니다. 사용자는 Python 개발을 따라야 하고, 작은 정수를 export하기 위한 다양한 변형을 벤치마크하며(위의 경우 PyLong_AsInt64() 대신 선택된 이유가 명확한가요?), 다양한 CPython 버전 또는 다른 Python 구현에 대해 다른 코드 경로를 지원해야 할 수도 있습니다.

논의 (Discussions)

이 문서는 퍼블릭 도메인 또는 CC0-1.0-Universal 라이선스 중 더 관대한 조건에 따라 배포됩니다.

The translation is complete, following all the specified guidelines.

PEP 757 – C API를 이용한 Python 정수 import/export

개요

새로운 C API, 특히 PyLongWriter_Create()PyLong_Export() 함수를 추가하여 Python 정수(int 객체)를 import하고 export하는 기능을 제공합니다.

도입 배경 (Rationale)

gmpy2, SAGE, Python-FLINT와 같은 프로젝트들은 Python의 내부(PyLongObject 구조체)에 직접 접근하거나 비효율적인 임시 형식(예: Python-FLINT의 16진수 문자열)을 사용하여 Python int 객체를 import 및 export합니다.

Python 3.12에서는 int 구현이 tag와 “compact values”를 추가하는 방향으로 변경되었습니다. 3.13 alpha 1 릴리스에서는 비공개, 비문서화된 _PyLong_New() 함수가 제거되었지만, 이 함수는 앞서 언급된 프로젝트들에서 Python 정수를 import하는 데 사용되고 있었습니다. 이 함수는 3.13 alpha 2에서 복원되었습니다.

이러한 프로젝트들이 Python의 내부 구현 세부 사항에 노출되지 않으면서도 효율적으로 연동될 수 있도록, 공개적이고 효율적인 추상화 계층이 필요합니다. 이는 Python 내부 구현이 변경되더라도 해당 프로젝트들이 깨지지 않도록 할 것입니다. 예를 들어, gmpy2의 구현은 최근 CPython 3.9 및 CPython 3.12에 맞춰 변경된 바 있습니다.

명세 (Specification)

레이아웃 API (Layout API)

GMP(GNU Multiple Precision Arithmetic Library)와 유사한 import-export 함수에 필요한 데이터입니다.

struct PyLongLayout

임의 정밀도 정수의 절대값을 나타내는 “digit” 배열(GMP 용어로는 “limb”)의 레이아웃입니다. “충분히 큰” 절대값을 가진 정수에서 내부적으로 사용되는 Python int 객체의 기본 레이아웃을 얻으려면 PyLong_GetNativeLayout() 함수를 사용합니다.

sys.int_info는 Python에 유사한 정보를 노출합니다.

  • uint8_t bits_per_digit: digit당 비트 수. 예를 들어, 15비트 digit은 비트 0-14에 유의미한 정보가 포함됨을 의미합니다.
  • uint8_t digit_size: digit의 바이트 크기. 예를 들어, 15비트 digit은 최소 2바이트를 필요로 합니다.
  • int8_t digits_order: digit 순서:
    • 1: 최상위 digit 우선 (most significant digit first)
    • -1: 최하위 digit 우선 (least significant digit first)
  • int8_t digit_endianness: digit의 엔디안(endianness):
    • 1: 최상위 바이트 우선 (big endian)
    • -1: 최하위 바이트 우선 (little endian)

const PyLongLayout *PyLong_GetNativeLayout(void)

Python int 객체의 기본 레이아웃을 가져옵니다. PyLongLayout 구조체를 참조하세요. 이 함수는 Python 초기화 전이나 종료 후에는 호출되어서는 안 됩니다. 반환된 레이아웃은 Python이 종료될 때까지 유효합니다. 이 레이아웃은 모든 Python 서브 인터프리터에서 동일하므로 캐시할 수 있습니다.

Export API

Python int 객체를 export하는 데 사용됩니다.

struct PyLongExport

Python int 객체의 export 구조입니다. 두 가지 경우가 있습니다:

  • digitsNULL인 경우, value 멤버만 사용합니다.
  • digitsNULL이 아닌 경우, negative, ndigits, digits 멤버를 사용합니다.

  • int64_t value: export된 int 객체의 네이티브 정수 값. digitsNULL인 경우에만 유효합니다.
  • uint8_t negative: 숫자가 음수이면 1, 아니면 0. digitsNULL이 아닌 경우에만 유효합니다.
  • Py_ssize_t ndigits: digits 배열의 digit 수. digitsNULL이 아닌 경우에만 유효합니다.
  • const void *digits: 읽기 전용 부호 없는 digit 배열. NULL일 수 있습니다.

PyLongExport.digitsNULL이 아닌 경우, PyLongExport 구조체의 private 필드에 Python int 객체에 대한 강력한 참조(strong reference)를 저장하여 PyLong_FreeExport()가 호출될 때까지 구조체가 유효하게 유지되도록 합니다.

int PyLong_Export(PyObject *obj, PyLongExport *export_long)

Python int 객체를 export합니다. export_long은 호출자가 할당한 PyLongExport 구조체를 가리켜야 하며, NULL이 아니어야 합니다. 성공 시 *export_long을 채우고 0을 반환합니다. 오류 발생 시 예외를 설정하고 -1을 반환합니다. export가 더 이상 필요하지 않을 때 PyLong_FreeExport()를 호출해야 합니다.

CPython 구현 세부 사항: obj가 Python int 객체 또는 서브클래스인 경우 이 함수는 항상 성공합니다. CPython 3.14에서는 PyLong_Export()에서 메모리 복사가 필요하지 않으며, 이는 Python int의 내부 digit 배열을 노출하기 위한 얇은 래퍼(thin wrapper)에 불과합니다.

void PyLong_FreeExport(PyLongExport *export_long)

PyLong_Export()로 생성된 export_long export를 해제합니다. CPython 구현 세부 사항: export_long->digitsNULL인 경우 PyLong_FreeExport() 호출은 선택 사항입니다.

Import API

PyLongWriter API를 사용하여 정수를 import할 수 있습니다.

struct PyLongWriter

Python int writer 인스턴스입니다. 이 인스턴스는 PyLongWriter_Finish() 또는 PyLongWriter_Discard()에 의해 파괴되어야 합니다.

PyLongWriter *PyLongWriter_Create(int negative, Py_ssize_t ndigits, void **digits)

PyLongWriter를 생성합니다. 성공 시 *digits를 할당하고 writer를 반환합니다. 오류 발생 시 예외를 설정하고 NULL을 반환합니다. negative는 숫자가 음수이면 1, 아니면 0입니다. ndigitsdigits 배열의 숫자(digit) 수입니다. 0보다 커야 합니다. digitsNULL이 아니어야 합니다.

이 함수를 성공적으로 호출한 후, 호출자는 digits 배열을 채우고 PyLongWriter_Finish()를 호출하여 Python int를 얻어야 합니다. digits의 레이아웃은 PyLong_GetNativeLayout()에 의해 설명됩니다. Digits는 [0; (1 << bits_per_digit) - 1] 범위에 있어야 합니다 (bits_per_digit는 digit당 비트 수). 사용되지 않는 최상위 digit은 0으로 설정해야 합니다. 또는 PyLongWriter_Discard()를 호출하여 int 객체를 생성하지 않고 writer 인스턴스를 파괴할 수 있습니다.

CPython 3.14에서는 PyLongWriter_Create() 구현이 private _PyLong_New() 함수에 대한 얇은 래퍼입니다.

PyObject *PyLongWriter_Finish(PyLongWriter *writer)

PyLongWriter_Create()로 생성된 PyLongWriter를 완료합니다. 성공 시 Python int 객체를 반환합니다. 오류 발생 시 예외를 설정하고 NULL을 반환합니다. 이 함수는 digit을 정규화하고 필요한 경우 객체를 compact integer로 변환합니다. 호출 후 writer 인스턴스와 digits 배열은 유효하지 않습니다.

void PyLongWriter_Discard(PyLongWriter *writer)

PyLongWriter_Create()로 생성된 PyLongWriter를 폐기합니다. writerNULL이 아니어야 합니다. 호출 후 writer 인스턴스와 digits 배열은 유효하지 않습니다.

작은 정수 import 최적화 (Optimize import for small integers)

제안된 import API는 큰 정수에 효율적입니다. Python 내부(internals)에 직접 접근하는 것과 비교할 때, 제안된 import API는 작은 정수에서 상당한 성능 오버헤드를 가질 수 있습니다.

몇 개의 digit을 가진 작은 정수(예: 1 또는 2 digit)의 경우, 기존 API를 사용할 수 있습니다:

  • PyLong_FromUInt64()
  • PyLong_FromLong()
  • PyLong_FromNativeBytes()

구현 (Implementation)

벤치마크 (Benchmarks)

Export: PyLong_Export() with gmpy2

벤치마크 결과 (Linux Fedora 40, CPU 격리, 릴리스 모드로 빌드된 Python):

Benchmark ref pep757  
1<<7 91.3 ns 89.9 ns 1.02x faster
1<<38 120 ns 94.9 ns 1.27x faster
1<<300 196 ns 203 ns 1.04x slower
1<<3000 939 ns 945 ns 1.01x slower
Geometric mean (ref)     1.05x faster

1<<7 (128) 및 1<<38과 같은 작은 정수의 export에서 pep757 구현이 더 빠르며, 1<<3001<<3000과 같은 큰 정수에서는 약간 느리거나 비슷한 성능을 보였습니다.

Import: PyLongWriter_Create() with gmpy2

벤치마크 결과 (Linux Fedora 40, CPU 격리, 릴리스 모드로 빌드된 Python):

Benchmark ref pep757  
1<<7 56.7 ns 56.2 ns 1.01x faster
1<<300 191 ns 213 ns 1.12x slower
Geometric mean (ref)     1.03x slower

1<<7 (128)과 같은 작은 정수의 import에서 pep757 구현이 약간 더 빠르며, 1<<300과 같은 큰 정수에서는 약간 느려졌습니다. 1<<38, 1<<3000 벤치마크는 유의미하지 않다고 숨겨졌습니다.

하위 호환성 (Backwards Compatibility)

새로운 API만 추가되므로 하위 호환성에 미치는 영향은 없습니다.

기각된 아이디어 (Rejected Ideas)

임의의 레이아웃 지원 (Support arbitrary layout)

Python 정수를 import-export하기 위해 임의의 레이아웃을 지원하는 것은 편리할 수 있습니다. 예를 들어, PyLongWriter_Create()layout 매개변수를 추가하고 PyLongExport 구조체에 layout 멤버를 추가하는 것이 제안되었습니다. 그러나 구현이 더 복잡하고 실제로 필요하지 않습니다. 엄밀히 필요한 것은 Python의 “네이티브(native)” 레이아웃을 사용하여 import-export하는 API뿐입니다. 나중에 임의의 레이아웃에 대한 사용 사례가 있다면 새로운 API를 추가할 수 있습니다.

PyLong_GetNativeLayout() 함수를 추가하지 않음 (Don’t add PyLong_GetNativeLayout() function)

현재 대부분의 정수 import/export에 필요한 정보는 PyLong_GetInfo() (및 sys.int_info)를 통해 이미 사용 가능합니다. 또한, 더 많은 정보(예: digits 순서)를 추가할 수 있으며, 이 인터페이스는 PyLongObject의 미래 발전에 어떤 제약도 가하지 않습니다. 문제는 PyLong_GetInfo()가 편리한 C 구조체가 아닌 Python 객체(named tuple)를 반환한다는 점이며, 이는 사람들이 현재의 세미-프라이빗 매크로(PyLong_SHIFTPyLong_BASE 등)를 선호하게 만들 수 있습니다.

mpz_import/export와 유사한 API 제공 (Provide mpz_import/export-like API instead)

int 객체에서 데이터를 import/export하는 또 다른 접근 방식은 C 확장이 연속적인 버퍼를 제공하고 CPython이 정수의 절대값을 export(또는 import)하는 것을 기대하는 것입니다. 이 접근 방식의 주요 단점은 CPython 측면에서 훨씬 더 복잡하다는 것입니다(즉, 다른 레이아웃 간의 실제 변환). 예를 들어, CPython에서 PyLong_FromNativeBytes()PyLong_AsNativeBytes() 구현(함께 필요한 API의 제한된 버전을 제공)은 약 500줄의 코드를 차지했습니다(현재 구현은 약 100줄).

export API에서 value 필드를 삭제 (Drop value field from the export API)

이 제안에 따르면, 하나의 export 유형(digit 배열)만 존재하게 됩니다. 주어진 정수에 대해 이러한 뷰를 사용할 수 없는 경우, export 함수에 의해 에뮬레이션되거나 PyLong_Export()가 오류를 반환할 것입니다. 두 경우 모두, 사용자는 PyLong_AsLongAndOverflow()와 같이 “충분히 작은” 정수(즉, 일부 머신 정수 형식에 맞는 정수)를 얻기 위해 다른 C-API 함수를 사용할 것으로 가정합니다. 이 경우 PyLong_Export()는 비효율적이거나 실패할 것입니다. 이는 API 설계자 관점에서는 단순화처럼 보일 수 있지만, 최종 사용자에게는 덜 편리할 것입니다. 사용자는 Python 개발을 따라야 하고, 작은 정수를 export하기 위한 다양한 변형을 벤치마크하며(위의 경우 PyLong_AsInt64() 대신 선택된 이유가 명확한가요?), 다양한 CPython 버전 또는 다른 Python 구현에 대해 다른 코드 경로를 지원해야 할 수도 있습니다.

논의 (Discussions)

이 문서는 퍼블릭 도메인 또는 CC0-1.0-Universal 라이선스 중 더 관대한 조건에 따라 배포됩니다.

⚠️ 알림: 이 문서는 AI를 활용하여 번역되었으며, 기술적 정확성을 보장하지 않습니다. 정확한 내용은 반드시 원문을 확인하시기 바랍니다.

Comments