RustPython 기여일지 - 1
서론
이번에 처음으로 RustPython에 기여를 하게 되었다.
간단하게 RustPython을 소개하자면, c-api 의존성을 최대한 줄인 rust 기반 python 인터프리터이고, 목표는 현재로써는 CPython 3.14 호환을 목표로 하고있다.
근본적인 차이는, 지금으로써는 GIL 차이가 크다. CPython은 GIL 해제를 실험적 기능으로 제공하고 있다. 하지만 RustPython은 기본적으로 GIL 해제이다. 따라서 꽤 많은 경우에서 RustPython이 멀티 스레딩 환경에서 CPython을 조금은 앞서는 경향이 있다.
Python의 변형이 꽤나 많은데, 그중에서도 RustPython은 두가지 목적에 특화되어있다. WASM과 다른 Rust 앱 포팅이다. 또한 C 기반이 아니므로 메모리나 여러 안정성과 보안 면에서 CPython보다 낫다.
하지만 단점으로써 가장 큰게, CPython 단일 스레드 기준으로 많이 느리다. 예전엔 10배 이상 차이났지만, 지속적인 기여로 2배정도까지 따라잡았다.
또한 지금 RustPython의 버전은 0.~이다. 이 말은 실제 이용가능하게 배포 준비까지 오지 않았다는 뜻이므로, 이러한 부분에서 걸리는 부분이 많다.
특히나 치명적인 약점은 C 기반 python 확장이 불가능하다는 것이다. 가능은 하겠는데 맞지 않는다.
기여
최근 기여한 영역으로, 간단하게 설명하자면 Python은 총 3가지의 객체 내부 저장소를 가지는데,
클래스 dict : 모든 인스턴스가 공유. 메서드, 클래스 변수, 디스크립터가 여기 산다.
인스턴스
__dict__: 인스턴스마다 따로. 우리가self.x = 1하면 보통 여기 들어간다.슬롯 :
__dict__없이, C 구조체의 고정된 자리에 값을 박아두는 방식.
총 이렇게 3가지를 가진다. 이 중에서도 이제 인스턴스 __dict__ 로 잘못 구현되어있는 부분이 있어서, 이걸 슬롯으로 바꿔주는 작업을 했다.
이 작업을 한번 하니, 이런 문제점을 가진 시스템 정의 타입이 많았고, 그것들을 모두 이슈로 올려두었다.
그리고 추가로, 이 부분에 대해서 개선하는 방식을 취했는데,
rust와 c의 공통점으로, 타입, 크기와 같은 부분에 민감하다. 모든 컴파일 타임 언어의 특징으로써, 사전에 일어날 버그를 잡는다고 보면 되는데, 이때 시스템 정의 타입과 사용자 정의 타입 오류를 처리하는 로직인 invoke_exception 부분에 대해서, 실제로 이게 제일 빠른 방법인가 논의가 나왔다. 이걸 해결한 pr이 있는데 바로
Add new_payload_exception helper for constructing built-in payload exceptions by kangdora · Pull Request #8403 · RustPython/RustPython
이 pr이다.
아까 언급한 크기에 민감함때문에, python에서
class A(SystemExit):
def __init__(self):
self.name = "A"이와 같은 식으로 접근하면 이 객체의 크기가 커지므로, rust에서 사용자 타입 오류를 처리할 수 없다.
그러나 이미 정의되어있는 SystemExit 같은 경우는 추가적인 payload 가 있더라도 시스템이 이미 아는 크기라서 이 경우는 처리가 가능한것이다.
따라서 KeyError과 같은 BaseException 상속 타입과 다르게, 적용이 되어야 하는 추가적인 payload를 처리하는 exception을 제네릭을 이용해서 처리했다.
오픈 소스의 장점은, 이러한 소소한 변경으로 학생 신분인 내가 사회에 기여할 수 있는 일이자, 좋은 설계를 엿보고 체험할 수 있는 부분이라는 점이 장점으로 다가온다.
댓글
아직 댓글이 없습니다.