기본 콘텐츠로 건너뛰기

4월, 2026의 게시물 표시

bytes.hex bytes_per_sep range

CPython: bytes.hex(bytes_per_sep) 허용 범위가 커졌다 — sys.maxsize도 이제 OK(gh-147944) meta_description: Python 3.15에서 bytes.hex/bytearray.hex/memoryview.hex 및 binascii.b2a_hex의 bytes_per_sep 인자 허용 범위가 확대되어 sys.maxsize와 -sys.maxsize가 유효해졌다(gh-147944). 겉보기엔 테스트 한 줄 바뀐 수준이지만, 실제로는 Argument Clinic 변환(int→Py_ssize_t)과 정수 변환 경로가 정리되면서 “경계값에서의 Overflow/TypeError”가 더 일관되게 동작한다. 이 글은 무엇이 바뀌었는지, 실무에서 어디에 도움이 되는지(로그/헥스 덤프/프로토콜 디버깅), 그리고 안전한 사용 패턴을 정리한다. meta_keywords: python,bytes,bytearray,memoryview,hex,bytes_per_sep,binascii,b2a_hex,Py_ssize_t,sys.maxsize,OverflowError,Argument Clinic,debugging,hexdump,logging,protocol,binary,호환성,경계값,테스트 meta_robots: index,follow 바이너리 로그를 남기거나(패킷/토큰/압축 데이터), 디버깅용으로 bytes.hex() 를 쓰다 보면 이런 걸 해본 적이 있을 거다. “너무 길어서 보기 힘드니, 구분자(sep)를 넣어서 그룹으로 끊자” 예: payload.hex(':', 2) # b9:01ef 처럼 2바이트마다 구분 payload.hex(' ', -2) # 반대 방향(왼쪽부터)으로 2바이트마다 이때 bytes_per_sep 에 “엄청 큰 값”을 넣으면, 사실상 구분자를 넣지 않는 효과가 난다. bytes_per_sep 가 길이보다 크면 → 구분자 없음 그런데 C...

bytes.replace count as keyword

CPython: 이제 bytes.replace()의 count를 키워드로 쓸 수 있다 — 그런데 이 변화가 실무에 주는 이득은? meta_description: CPython에서 bytes.replace()/bytearray.replace()의 count 인자가 키워드 인자로도 지원된다(gh-147856). 겉보기엔 사소한 문법 변화지만, 래퍼 함수/타입 힌트/리팩터링 안정성, 그리고 바이너리 프로토콜 처리 코드의 가독성에 꽤 도움이 된다. 이 글은 무엇이 바뀌었는지, 기존 코드와 호환성은 어떤지, 실무에서 어떻게 써야 이득이 되는지(예시 포함) 정리한다. meta_keywords: python,bytes,bytearray,replace,count,keyword argument,stdlib,cpython,argument clinic,METH_KEYWORDS,refactor,typing,protocol,binary,text processing,호환성,가독성,리팩터링,테스트 meta_robots: index,follow 파이썬 표준 라이브러리/빌트인에 들어가는 변화는 가끔 ‘한 줄짜리 편의’처럼 보이는데, 실제로는 코드베이스 전체의 유지보수 비용을 조금씩 깎는 역할을 한다. 이번 CPython PR(gh-147856)이 딱 그 케이스다. 이제 bytes.replace() 와 bytearray.replace() 에서 count 를 키워드 인자 로 줄 수 있다. 예전에는 이렇게만 됐다. b"aa".replace(b"a", b"b", 1) 이제는 이렇게도 된다. b"aa".replace(b"a", b"b", count=1) “그래서 뭐?” 싶을 수 있는데, 실무에서 특히 바이너리 처리 코드 를 많이 만지는 팀에겐 의외로 이득이 있다. 1) 정확히 무엇이 바뀌었나: 시그니처가 ‘positional-only...

Avoiding a Leak on Allocation Failure

CPython: 서브인터프리터 데이터 공유에서 ‘할당 실패’ 한 번이 누적 메모리 누수로 이어질 수 있던 경로(gh-147960) meta_description: CPython의 cross-interpreter data 공유 코드에서 튜플을 공유 데이터로 바꾸는 과정(_tuple_shared) 중 메모리 할당이 실패하면, 에러는 MemoryError로 떨어지지만 일부 구조체가 해제되지 않아 누수가 생길 수 있었다. gh-147960은 실패 경로에서 shared 구조체를 RawFree 해 누수를 막는다. 이 글은 “왜 이런 한 줄이 중요해지는지”, 서브인터프리터/임베딩/확장모듈 개발자가 놓치기 쉬운 실패 경로 설계, 테스트/관측 포인트를 실무 관점으로 정리한다. meta_keywords: python,cpython,subinterpreters,cross-interpreter data,_tuple_shared,MemoryError,allocation failure,memory leak,PyMem_RawFree,PyMem_Calloc,error path,임베딩,확장모듈,안정성,회귀,테스트,관측,메모리 meta_robots: index,follow CPython PR 하나가 병합됐다. 제목은 소박하다: “할당 실패 시 _tuple_shared()에서 메모리 누수 방지” diff는 더 소박하다: 한 줄 하지만 이런 종류의 패치는, 특정 환경에서는 체감 임팩트가 크다. 서버가 오래 떠 있고 서브인터프리터(subinterpreters)를 많이 돌리거나 임베딩/확장 모듈이 많고 메모리 압박 상황(컨테이너 제한/스파이크)이 가끔 생기는 곳 여기서는 “드물게 한 번 터지는 할당 실패”가 누적으로 번지는 문제가 되기 쉽다. 1) 무엇이 바뀌었나: 실패 경로에서 구조체를 하나 더 해제한다 PR에서 바뀐 코드는 이거다. 튜플 공유 데이터를 만들면서 shared->items 배열을 PyMem_Calloc()...

sqlite3 Collation Busy Crash Fix

CPython sqlite3: create_collation 중 SQLITE_BUSY가 터질 때 크래시하던 경로가 막혔다(gh-146090) meta_description: CPython sqlite3 모듈에서 Connection.create_collation()이 실행 중인 statement 때문에 SQLITE_BUSY로 실패하는 경우, 특정 참조/해제 경로에서 크래시가 날 수 있던 버그가 수정됐다(gh-146090). 이 글은 왜 BUSY가 나오는지, 애플리케이션/라이브러리에서 재현을 줄이는 패턴, 회귀 테스트 아이디어, 그리고 업그레이드 우선순위를 정리한다. meta_keywords: python,sqlite3,cpython,create_collation,SQLITE_BUSY,OperationalError,collation,statement,커서,트랜잭션,MemoryError,SystemError,callback context,레퍼런스카운트,회귀테스트,업그레이드,안정성,크래시 meta_robots: index,follow SQLite는 “가볍고 빠른 내장 DB”라는 이미지가 강하지만, 파이썬에서 sqlite3를 조금만 깊게 쓰기 시작하면 ‘DB가 바쁜 상태(BUSY)’ 를 마주칠 때가 있다. 대표적으로 이런 케이스다. 같은 연결에서 커서를 열어 SELECT ... ORDER BY ... COLLATE mycoll 을 실행 중인데 그 와중에 create_collation("mycoll", ...) 로 같은 이름의 collation을 교체하려고 한다 이때 SQLite는 자연스럽게 SQLITE_BUSY 를 반환한다. (실행 중인 statement가 collation을 쓰고 있으니 “지금은 바꾸지 마”라는 뜻) 문제는 예전의 CPython sqlite3 구현에서 이 실패 경로가 파이썬 예외(OperationalError)로 끝나지 않고, 특정 조건에서 크래시까지 이어질 수 있는 모서리 가 있었다는 점이다...