잘 만든 업무 공간을 복사해 새 일을 시작하고 싶었다. 그렇다고 원래 Python 프로세스와 실행 중인 변수까지 따라오면 두 프로젝트가 같은 상태를 공유하게 된다. 나는 복사를 파일이 몇 개 늘어나는 기능으로 보지 않고 무엇을 이어받고 무엇을 새로 만들어야 하는지 나누는 기능으로 설계했다.
복사가 진행되는 동안 새 프로젝트는 실행하지 않는다
copyWorkspace는 원본 runtime을 준비하고 노트북 저장과 초안 캡처를 요청한 뒤 새 프로젝트 ID를 만든다. 새 사본에는 copyPending을 표시한다. 문서와 설정이 절반만 준비된 상태를 완성된 프로젝트처럼 실행할 수 없게 하려는 경계다. 기존 원본과 다른 프로젝트는 각자의 runtime에 남긴다.
이 과정의 캡처 요청이 모든 사이트의 저장 전 초안을 완벽히 보존한다는 의미는 아니다. 복사의 출발점에서 저장 가능한 자료를 준비하는 경로다. 나는 문서 캡처의 지원 범위와 복사 완료 표시를 나눠 설명한다. 일부 상태가 저장되지 않았다면 폴더 복사 성공만으로 그 상태가 복구됐다고 할 수 없다.
같은 문서를 새 식별자로 연결한다
원본 프로젝트의 탭마다 새 ID를 만들고 메모리 안의 탭 참조도 그 대응으로 바꾼다. 미지정 계정은 새 빈 프로필로 만들고, 의도적으로 선택한 저장 계정의 연결은 같은 세션을 가리킬 수 있다. 계정 연결을 유지하는 것과 쿠키 파일을 새 폴더로 복제하는 일을 같은 것으로 처리하지 않는다.
새 탭에는 주소와 제목, 고정 여부 등 작업 배치를 이어 준다. 그러나 탭 ID가 달라지므로 이후 작업은 새 프로젝트 context로 확인해야 한다. 표시가 비슷하다는 이유로 원본 탭을 계속 실행 대상으로 쓰면 복사의 의미가 사라진다. 사본의 관계를 새로 잇는 단계가 자료 복사만큼 중요했다.
노트북 파일과 커널 메모리를 나눠 복사한다
노트북은 원본 문서를 encode한 뒤 대상 서비스의 import로 가져온다. import는 실행 중인 대상에는 허용하지 않고 커널을 종료한 뒤 새 문서를 저장한다. 원본 커널의 전역 변수나 프로세스 핸들을 대상에게 넘기는 경로는 없다. 저장된 문서가 있다고 이전 메모리까지 살아 있는 것은 아니다.
첨부 자료 복사는 work.ipynb 자체와 runtime·jupyter-runtime·ipython·pip-cache, previous 이력 항목을 제외한다. 노트북 문서는 앞의 전용 가져오기로 처리하고 실행용 중간 폴더를 일반 자료처럼 가져오지 않는다. 무엇을 뺐는지 정해야 사본에서 지난 실행의 잔여물을 새 결과로 오해하지 않는다.
패키지 복사는 완전한 환경 이식과 다르다
대상에는 새 Python 가상환경을 준비한다. 현재 Windows 경로에서는 원본의 프로젝트 로컬 site-packages를 대상 환경으로 복사한다. 이 기능은 원래 커널을 공유하는 것이 아니며 기본 공통 의존성을 읽는 구조도 유지한다. 파일을 가져왔다고 다른 운영체제까지 같은 환경으로 재현됐다고 말하지 않는다.
네이티브 확장과 버전 충돌, 원래 외부 파일을 가리키는 설정은 별도의 확인이 필요하다. 작업 폴더 복사에는 일부 저장소·대형 의존성과 인증 저장 파일의 제외 필터도 있다. 그러나 이 필터를 모든 비밀자료를 찾아 지우는 정화기로 소개하지 않는다. 사본의 공개와 다른 PC 이전은 추가 검토가 필요한 다른 작업이다.
시험에서는 자료가 남고 변수는 없는지 본다
기존 프로젝트 격리 시험은 원본에서 만든 로컬 패키지와 입력 파일을 사본에서 읽게 한다. 새 sys.prefix에 사본 프로젝트가 나타나는지 확인하고, 원본 커널에 있던 project_value는 globals에 없다고 검사한다. 자료 재사용과 메모리 초기화를 함께 확인하는 시나리오다.
이 글은 해당 시험 코드와 과거 QA 기록을 읽어 구현 범위를 설명한다. 현재 사용자 프로젝트를 실제로 복사하거나 원래 프로그램 시험을 다시 돌리지 않았다. 시험 자료는 소유한 fixture이며 모든 패키지와 사이트 문서가 같은 방식으로 복사된다는 전수 검증도 아니다. 확인한 세 가지 조건을 전체 이식 성공으로 확대하지 않는다.
실패한 사본은 실행 가능한 완성본으로 남기지 않는다
복사 중 오류가 나면 새 사본의 컨트롤러와 커널, 예약을 정리하고 새 프로젝트를 제거하는 복구 경로로 간다. 원본과 다른 프로젝트의 실행은 그 대상이 아니다. 정리에 실패하면 원래 오류와 정리 오류를 함께 보고한다. 일부 파일은 복구 자료로 남을 수 있지만 실행 가능한 프로젝트로 열어 두지 않는다는 의도가 코드에 있다.
따라서 복사 완료는 폴더 수가 늘었다는 것보다 강한 조건이다. 새 식별자 연결과 자료 준비, 상태 저장이 끝나야 사용 가능한 사본이 된다. 나는 업무 공간의 복사를 과거 실행을 통째로 이어받는 기능보다 검증 가능한 새 출발점을 만드는 기능으로 보고 있다. 예약을 일시정지하는 이유는 별도 글에서 더 깊게 다룬다.