Python2 에서 Python3로 변경시 유의해야 할 점
아래의 참고자료 중 Python2 to Python3 Porting Guide 를 보면 자세한 설명과 그 이유를 알 수 있으니 해당 문서를 참고하길 바랍니다.
C를 Python3로 포팅
: C에서 Python3로 포팅하는 절차는 크게 3가지로 구성된다.
- Modernization, 개발한 코드들이 Python2의 기능으로 마이그레이션 된다. 이 단계 이후에는 Python2.6 이상을 지원하게 된다.
- Porting, Python3도입 후 Python3 뿐만 아니라 Python2에 대한 호환성을 유지하도록 만든다.
- Cleanup, Python2에 대한 지원을 제거한다. 이 단계 후에는 Python3.3 이상의 버전만을 지원한다.
PyObject
: 모든 object 타입들은 이 PyObject 타입의 확장이라 할 수 있다. 이는 Python이 object를 다루기 위해 해당 object를 가리키는 포인터를 저장하는 구조라고 보면 된다. 이 PyObject는 원본 object의 reference count, 해당하는 object에 대한 type object에 대한 포인터를 가지고 있다.
Modernization
: PyObject의 멤버에 대한 사용에서 다음의 항목들의 사용에 주의하라.
From | To | 설명 |
---|---|---|
obj->ob_type |
Py_YPE(obj) |
|
obj->ob_refcnt |
Py_REFCNT(obj) |
|
obj->ob_size |
Py_SIZE(obj) |
|
PyObject_HEAD_INIT(NULL) |
PyVarObject_HEAD_INIT(NULL, 0) |
type object의 초기화 |
PyClass_* , Py_Instance_* |
PyType_* |
앞의 두 클래스는 Python3에서 삭제된 클래스, v2.2에서는 유효 |
PyCObject_* |
PyCapsule_* |
Python3.3에서 삭제된 타입 |
Porting
: modernize의 결과로 당신은 Python2의 가장 최신 feature를 사용하고 있을 것이다. 이제부터는 Python3를 동시에 지원할 수 있도록 할 것이다.
#include <py3c.h>
을 통해 헤더파일을 include하고 헤더 파일의 위치를 컴파일러에 알려줘라- Python3에서의 특별한 점은 Python3에서는 human-readable한 string과 binary data를 나누어 놓았다는 점이다. 따라서
py3c
헤더파일을 이용할 때,native string
은PyStr_* (PyStr_FromString, PyStr_Type, PyStr_Check 등)
을 사용하고binary data
는PyBytes_* (PyBytes_FromString, PyBytes_Type, PyBytes_Check 등)
을 사용해라.
String 종류 | Py2 | Py3 | 사용처 |
---|---|---|---|
PyStr_* |
PyString_* |
PyUnicode_* |
Human-readable 텍스트 |
PyBytes_* |
PyString_* |
PyBytes_* |
Binary data |
PyUnicode_* |
PyUnicode_* |
PyUnicode_* |
Unicode strings |
PyString_* |
PyString_* |
사용불가 | unported code |
- String의 길이를 return하기 위해서는
PyStr_AsUTF8AndSize()
를 사용해라. Python3에서는PyUnicode_AsUTF8AndSize()
가 사용됨에 유의하라. - Python3에서 string이 2 종류(human-readable, binary data)로 분리되었다면, int와 long은 하나의 타입으로 합쳐졌다. 다시말해,
PyInt_*
은 제거되고PyLong_*
만이 남았다. 이를 py3c 헤더파일에서는에일리어싱
으로 정의해 놓았다. - Python3에서
PyFloat_FromString
함수는 2번째 인자를 없앴다. 이를 py3c 헤더파일에서는재정의
함으로써 Python2와 동시에 지원하고 있다. - 모듈 초기화시 Python2에서는
void init<module_name>
함수를 사용하였으나, Python3에서는PyObject *PyInit_<module_name>
함수를 사용한다. 이를 동시에 지원하기 위해서는MODULE_INIT_FUNC
매크로를 사용하라.
Cleanup
: Porting의 결과로 Python2와 Python3를 동시에 지원하고 있는 코드를 얻을 수 있다. 여기서는 C에서 Python2와 관련된 문법을 더이상 사용하지 않도록 하는 것이다. py3c.h
헤더파일이 포함되어있다면 이를 제거하라.
From | To | 설명 |
---|---|---|
PyStr_* |
PyUnicode_* |
PyStr_ 으로 시작하는 함수는 더이상 사용되지 않음 |
PyInt_* |
PyLong_* |
더 이상 사용되지 않음 |
MODULE_INIT_FUNC(module_name) |
PyMODINIT_FUNC Py_Init_<module_name>(void) |
|
Py_TPFLAGS_HAVE_WEAKREFS Py_TPFLAGS_HAVE_ITER |
단순 제거 | |
return PY3C_RICHCMP |
Py_RETURN_RICHCOMPARE() |
링크 참조 |
capsulethunk.h |
사용중이라면 제거하라 | |
#if !IS_PY3 BLOCK |
해당 블럭에 있는 코드 제거 |
참고자료
[Ofiicial] Embedding Python Application
Python/C API Reference Manual
Python/C API Unicode Objects and Codecs
Python/C API List Objects
Python2 to Python3 Porting Guide
NLTK install guide
stackoverflow - No module name
stackoverflow - Python.h: No such file or directory
'잡동사니 > 개발관련' 카테고리의 다른 글
VirtualBox의 seamless기능 사용하기 (0) | 2020.11.08 |
---|---|
직접 LOG 출력 함수를 만들어 보자! (0) | 2020.11.05 |
Python embedding C - C/C++에서 Python 모듈 사용하기(1) (2) | 2020.10.24 |
License 별 주의사항 정리 - GPL, BSD, MIT, Apache ... (0) | 2020.10.15 |
Linux shell 내 branch name 표시 (0) | 2020.10.12 |