풀 리퀘스트의 수명 주기

소개

CPython은 풀 리퀘스트 기반 워크플로를 사용합니다. 즉, Git에서 브랜치를 만들고 변경한 다음, 해당 변경 사항을 GitHub의 포크(origin)에 푸시하고, 공식 CPython 저장소(upstream)를 대상으로 풀 리퀘스트를 생성합니다.

요약 자료는 풀 리퀘스트 생성 빠른 참조를 참조하십시오.

단계별 가이드

이미 시스템을 설정하고, 소스 코드를 가져오고, Python을 빌드했어야 합니다.

  • upstream 저장소의 데이터 업데이트:

    git fetch upstream
    
  • 업스트림 저장소의 main 브랜치에서 로컬 클론에 새 브랜치를 생성하십시오.:

    git checkout -b <branch-name> upstream/main
    

    참고

    버그 수정을 포함하여 Python에 대한 거의 모든 변경 사항은 먼저 main 브랜치를 대상으로 작성해야 합니다. 자세한 내용은 여기를 참조하십시오.

  • 코드를 변경하고 git statusgit diff를 사용하여 변경 사항을 확인하십시오.

    (좋은 PR 만들기에서 자세히 알아보기)

  • 변경 사항에 문제가 없고 테스트 실패를 일으키지 않는지 확인하십시오.:

    make patchcheck
    ./python -m test
    

    (patchcheck테스트 실행 및 작성에 대해 자세히 알아보기)

  • 변경 사항에 만족하면 파일을 추가하고 커밋하십시오.:

    git add <filenames>
    git commit -m '<message>'
    

    (좋은 커밋 만들기에서 자세히 알아보기)

  • 코드가 올바르게 린트되지 않으면 pre-commit이 다음과 같은 오류 메시지와 함께 커밋을 차단합니다.:

    Doc/library/stdtypes.rst:5718: No newline at end of file. (missing-final-newline)
    
  • 모든 린트 오류를 수정한 후에는 작업 내용을 GitHub 포크에 푸시할 수 있습니다.:

    git push origin <branch-name>
    
  • 마지막으로 https://github.com/<your-username>/cpython으로 이동하십시오. 방금 푸시한 브랜치가 표시된 상자와 공식 CPython 저장소를 대상으로 풀 리퀘스트를 생성할 수 있는 녹색 버튼이 보입니다.

  • 사람들이 리뷰 의견을 추가하기 시작하면 해당 브랜치로 전환하여 추가 변경 사항을 만들고 커밋한 후 푸시하면 풀 리퀘스트가 자동으로 업데이트됩니다.:

    git switch <branch-name>
    # make changes and run tests
    git add <filenames>
    git commit -m '<message>'
    git push origin <branch-name>
    
    • 풀 리퀘스트를 리뷰하는 코어 팀 구성원이 풀 리퀘스트 브랜치에 하나 이상의 커밋을 푸시했다면, 브랜치를 체크아웃한 후 편집하기 전에 다음을 실행하십시오.:

      git pull origin <branch-name>  # pull = fetch + merge
      

      포크에 푸시하지 않은 로컬 변경 사항이 있고 병합 충돌이 발생하면 Git이 이를 경고하고 충돌 해결 모드로 진입합니다. 아래의 병합 충돌 해결를 참조하십시오.

  • 시간이 지나 메인 브랜치와 병합 충돌이 발생하면 GitHub에 이를 알리는 경고가 표시되며, 충돌을 해결하라는 요청을 받을 수 있습니다. 로컬에서 충돌을 해결하면서 메인 브랜치의 변경 사항을 병합하십시오.:

    git switch <branch-name>
    git pull upstream main  # pull = fetch + merge
    # resolve conflicts: see "Resolving Merge Conflicts" below
    git push origin <branch-name>
    
  • 풀 리퀘스트가 승인되고 병합되면 브랜치 삭제가 가능합니다.:

    git branch -D <branch-name>  # delete local branch
    git push origin -d <branch-name>  # delete remote branch
    

병합 충돌 해결

서로 다른 브랜치(또는 서로 다른 저장소에 있는 브랜치의 변형)의 변경 사항을 병합할 때 두 브랜치에 하나 이상의 파일에 대한 호환되지 않는 변경 사항이 포함되어 있을 수 있습니다. 이를 “병합 충돌”이라고 하며 다음과 같이 수동으로 해결해야 합니다.

  1. 병합 충돌이 발생한 파일을 확인하십시오.:

    git status
    
  2. 영향받는 파일을 편집하여 의도한 최종 상태로 만드십시오. Git이 삽입한 특수한 “충돌 마커”를 반드시 제거하십시오.

  3. 영향받는 파일 커밋하기:

    git add <filenames>
    git merge --continue
    

마지막 명령을 실행하면 Git이 커밋 메시지를 작성할 편집기를 열 수도 있습니다. 일반적으로는 내용을 그대로 두고 편집기를 닫아도 됩니다.

자세한 기술적 설명은 병합 명령 문서를 참조하십시오.

강제 푸시하지 마십시오

커밋 기록을 온전히 유지하려면 기록을 스쿼시하거나 수정한 다음 PR에 강제 푸시하지 마십시오. 리뷰어는 개별 커밋을 살펴보고 싶어 하는 경우가 많습니다.

CPython은 스쿼시 병합을 사용하므로 PR은 병합될 때 하나의 커밋이 됩니다.

좋은 PR 만들기

제출할 풀 리퀘스트를 만들 때 풀 리퀘스트가 받아들여지도록 하기 위해 해야 할 일이 몇 가지 있습니다.

  1. 올바른 Python 버전을 기준으로 변경하십시오. 일반적으로 모든 변경 사항은 먼저 main 브랜치를 기준으로 만듭니다. 여기에는 버그 수정도 포함됩니다. 변경 사항이 그곳에 병합된 후에는 백포트되어 이전 유지보수 릴리스에도 적용됩니다. 이렇게 하면 영향받는 모든 버전을 처리할 수 있습니다. 따라서 새 변경 사항의 기반을 유지보수 브랜치로 직접 지정하는 방식은 해당 변경 사항이 main에 적용되지 않거나 이전 Python 버전에서는 main과 다른 접근 방식이 필요한 경우와 같은 특정 상황에서만 사용합니다.

  2. Python의 스타일 지침을 반드시 따르십시오. Python 코드는 PEP 8을 따라야 하며, C 코드는 PEP 7을 따라야 합니다. 한두 군데 일치하지 않는 부분은 풀 리퀘스트를 병합하는 코어 팀 구성원이 수정할 수 있습니다. 하지만 스타일 지침에서 체계적으로 벗어난 경우에는 형식 문제를 수정할 때까지 풀 리퀘스트 처리가 보류됩니다.

    참고

    코드 형식만 변경하는 풀 리퀘스트는 일반적으로 거부됩니다. 반면에 문서와 독스트링의 오타 및 문법 오류 수정은 환영합니다.

  3. 하위 호환성을 고려해야 한다는 점에 유의하십시오. 최종적으로 풀 리퀘스트를 처리하는 코어 개발자가 해당 변경 사항을 받아들일 수 있는지 최종 판단하지만, 하위 호환성을 일찍부터 고려하면 이러한 이유로 풀 리퀘스트가 거부되는 일을 방지하는 데 도움이 됩니다. 풀 리퀘스트에서 도입한 변경 사항 때문에 코드가 망가질 사람의 입장에서 생각해 보십시오. 어떤 변경이든 누군가의 코드를 망가뜨릴 가능성이 매우 높으며, 누군가에게 코드를 업데이트하도록 강제하게 되므로 변경할 타당한 이유가 있어야 합니다. (물론 새 클래스나 함수에는 적용되지 않습니다. 새 인자는 선택 사항이어야 하며 기존 동작을 유지하는 기본값이 있어야 합니다.) 확신이 서지 않으면 PEP 387을 살펴보거나 숙련된 개발자와 문제를 논의하십시오.

  4. 적절한 테스트를 마련했는지 확인하십시오. 이를 통해 풀 리퀘스트가 예상대로 작동하는지 검증해야 합니다. 적절한 테스트가 없으면 풀 리퀘스트는 받아들여지지 않습니다!

  5. 모든 테스트가 통과하는지 확인하십시오. 전체 테스트 스위트는 변경 사항으로 인해 실행될 때 실패가 없어야 합니다. 변경 사항과 인터프리터의 다른 부분 사이에 알지 못하는 상호 작용이 있을 수 있으므로, 변경 사항의 영향을 받는 것으로 보이는 테스트만 실행해서는 충분하지 않습니다.

  6. 풀 리퀘스트의 범위를 명확히 한정하고 작게 유지하십시오. 풀 리퀘스트 하나는 문제 하나를 해결하거나 기능 하나를 추가해야 합니다. 관련 없는 여러 변경 사항을 결합하면 풀 리퀘스트를 검토하기가 더 어려워지고 불필요하게 알림을 받는 사람의 수가 늘어납니다.

  7. 적절한 문서화 추가/변경 사항을 포함해야 합니다.

NEWS와 Python의 새로운 기능 업데이트

NEWS 항목이 필요한 변경 사항

코드베이스의 변경 사항은 대부분 Misc/NEWS.d에 항목을 추가할 만하지만, 다음은 예외입니다:

  • 문서 변경 사항

  • 테스트 변경 사항

  • 사용자에게 드러나는 영향이 없는 엄격한 내부 변경 사항

  • 이미 NEWS 항목이 있는 변경 사항

  • 아직 정식 릴리스에 포함되지 않은 되돌리기(알파 및 베타 릴리스 포함)

마지막 두 가지에 관해서는 다음 사항에 유의하십시오:

  1. 릴리스 전에 변경 사항을 되돌리면, 해당 항목을 삭제하기만 하면 됩니다. 그렇지 않으면 변경 사항을 되돌렸음을 알리는 새 항목을 추가해야 합니다(예를 들어 기능이 알파에서 릴리스된 후 첫 번째 베타 전에 제외되는 경우).

  2. 변경 사항이 이전에 릴리스되지 않은 변경 사항에 대한 수정(또는 기타 조정)이고 원래의 NEWS 항목이 여전히 유효한 경우, 추가 항목은 필요하지 않습니다.

“Python의 새로운 기능” 항목이 필요한 변경 사항

변경 사항이 최종 사용자에게 특히 흥미로운 경우(예: 새로운 기능, 상당한 개선 또는 하위 호환성이 없는 변경 사항), NEWS 항목과 함께 “Python의 새로운 기능” 문서(Doc/whatsnew/에 있는 3.X.rst 파일로, X는 현재 Python 버전)에 항목을 추가하십시오.

대부분의 경우 “Python의 새로운 기능” 항목에서 NEWS 항목의 문구를 재사용하는 것으로 충분합니다.

참고

“Python의 새로운 기능”에 항목을 추가해야 하는 변경 사항은 유지보수 릴리스에 포함하기에 적합하지 않을 가능성이 매우 높습니다.

NEWS 항목을 추가하는 방법

NEWS 항목은 개별 파일로 Misc/NEWS.d 디렉터리에 들어갑니다. blurb-it를 사용하거나 blurb 도구와 이 도구의 blurb add 명령을 사용하여 NEWS 항목을 만들 수 있습니다.

blurb에 관한 자세한 내용은 저장소에서 확인할 수 있습니다.

도구를 사용할 수 없다면 NEWS 항목 파일을 수동으로 만들 수 있습니다. Misc/NEWS.d 디렉터리에는 next라는 하위 디렉터리가 있으며, 이 디렉터리에는 영향을 받은 대상의 분류를 나타내는 다양한 하위 디렉터리가 있습니다(예를 들어 표준 라이브러리 관련 변경 사항은 Misc/NEWS.d/next/Library에 둡니다). 파일 이름 자체는 <datetime>.gh-issue-<issue-number>.<nonce>.rst 형식이어야 합니다:

  • <datetime>은 오늘 날짜와 현재 현지 시간을 하이픈(-)으로 연결한 YYYY-MM-DD-hh-mm-ss 형식입니다(예: 2017-05-27-16-46-23).

  • <issue-number>는 변경 사항과 관련된 이슈 번호입니다(예: gh-issue-12345의 경우 12345).

  • <nonce>는 파일 이름이 브랜치 전체에서 고유하도록 보장하는 고유 문자열입니다(예: Yl4gI2). 일반적으로 6자이지만, 문자와 숫자로 이루어진 임의 길이의 문자열일 수 있습니다. 키보드에서 임의의 문자를 입력하여 고유성을 확보할 수 있습니다.

따라서 파일 이름은 Misc/NEWS.d/next/Library/2017-05-27-16-46-23.gh-issue-12345.Yl4gI2.rst 같은 형태일 수 있습니다.

NEWS 항목을 작성하는 방법

모든 NEWS 항목은 최종적으로 변경 로그의 일부가 됩니다. 변경 로그에는 항목이 매우 많으며, 주된 대상 독자는 코어 개발자와 기여자가 아니라 사용자입니다. NEWS 항목을 작성할 때 이 점을 고려하십시오. 변경 사항이 사용자에게 미치는 영향을 간결하고 정확하게 설명하십시오. 장황한 기술적 설명과 여담은 피하고, 독자가 변경 사항의 실제 diff를 읽었다고 기대하거나 읽도록 요구하지 마십시오.

NEWS 파일의 내용은 유효한 reStructuredText여야 합니다. 열 너비는 80자를 사용해야 합니다. 파일에는 들여쓰기나 선행 표식(예: -)이 없습니다. 이슈 번호는 파일 이름의 일부이므로 항목을 이슈 번호로 시작할 필요도 없습니다. 관련 인라인 마크업도 사용할 수 있습니다. 다음은 NEWS 항목의 예입니다:

Fix warning message when :func:`os.chdir` fails inside
:func:`test.support.temp_cwd`. Contributed by Chris Jerdonek.

관련 :func: 같은 인라인 Sphinx 역할을 사용하면 독자가 더 많은 정보를 찾는 데 도움이 됩니다. 관련 make html을 사용하여 HTML을 빌드하고 링크 대상이 적절한지 확인할 수 있습니다.

저작권

국제 조약으로 저작권 보호를 위한 고지 요건이 폐지되었으므로 저작권 고지는 선택 사항이며 정보 제공을 위한 것입니다. 그러나 여전히 정보 제공의 역할을 합니다.

미국 저작권청에 따르면 유효한 저작권 고지에는 저작물의 최초 출판 연도가 포함됩니다. 예를 들면 다음과 같습니다:

Copyright (C) 2001 Python Software Foundation.

이후 연도를 추가하도록 고지를 갱신할 필요는 없으며, 그러한 PR은 종료됩니다.

python/cpython#126133도 참고하십시오.

오타 수정

문서의 오타와 문법 오류를 수정하는 것은 연결된 이슈가 필요하지 않은 기여입니다. 이러한 수정에 가장 적합한 위치는 Doc/(최종 사용자 문서) 및 InternalDocs/ 디렉터리입니다.

오타 수정 PR은 작고 집중된 상태로 유지하십시오. 관련 없는 여러 파일을 변경하는 대규모 PR은 불필요하게 많은 리뷰어에게 알림을 보내며 리뷰하기도 더 어렵습니다. 대규모 오타 수정 PR이나 위에 나열된 디렉터리 외부를 변경하는 PR은 이 절을 참조하도록 안내한 후 종료될 수 있습니다.

patchcheck

patchcheck는 진행 중인 변경 사항에 관한 간단한 자동화 체크리스트로, 개발자가 일반적인 검사를 수행하도록 안내합니다. patchcheck를 실행하려면 다음과 같이 하십시오:

Unix에서(macOS 포함):

make patchcheck

Windows에서(빌드에 한 번이라도 성공한 후):

.\python.bat Tools\patchcheck\patchcheck.py

자동화 체크리스트에서는 다음 항목을 검사합니다:

  • 문서가 업데이트되었습니까?

  • 테스트 스위트가 업데이트되었습니까?

  • Misc/NEWS.d/next 아래에 항목을 추가했습니까? (blurb-it 또는 blurb 도구 사용)

  • 필요한 경우 configure를 다시 생성했습니까?

  • 필요한 경우 pyconfig.h.in을 다시 생성했습니까?

이는 완성된 풀 리퀘스트를 제출하기 전에 확인해야 할 사항을 기억하는 데 도움이 됩니다.

좋은 커밋 만들기

각 기능이나 버그 수정은 하나의 풀 리퀘스트에서 처리해야 하며, 각 풀 리퀘스트에는 여러 커밋이 포함될 수 있습니다. 특히 다음 사항을 준수하십시오:

  • 하나의 커밋에서 두 개 이상의 이슈를 수정하지 마십시오(물론 하나의 코드 변경으로 모든 이슈가 수정되는 경우는 제외합니다).

  • 기능이나 버그 수정과 같은 커밋에서 관련 없는 코드를 외관상 변경하지 마십시오.

커밋 메시지는 다음 구조를 따라야 합니다:

Make the spam module more spammy

The spam module sporadically came up short on spam. This change
raises the amount of spam in the module by making it more spammy.

첫 번째 줄이나 문장은 커밋의 목적을 간결하고 핵심적으로 설명해야 합니다. 명령형(위 예에서 사용한 형식)이 ‘spam 모듈이 이제 더 spam다워졌습니다’와 같은 서술형보다 훨씬 권장됩니다. 기존 제목 줄을 확인하려면 git log --oneline을 사용하십시오. 또한 첫 번째 줄은 마침표로 끝나면 안 됩니다.

이 내용만으로 커밋을 충분히 설명할 수 없다면, 무슨 일이 있었는지 적절히 상세하게 설명하는 새 문단을 하나 이상 추가할 수 있습니다(커밋 메시지를 읽는 코어 팀 구성원이 변경의 근거를 이해할 수 있을 만큼 상세해야 합니다).

풀 리퀘스트를 병합할 때 커밋 메시지를 어떻게 작성해야 하는지에 관한 자세한 지침은 the Git bootcamp를 확인하십시오.

참고

How to Write a Git Commit Message는 좋은 커밋 메시지를 작성하는 방법을 설명하는 훌륭한 글입니다.

라이선스

변경 사항을 수락하려면 PSF license에 따라 작업물을 배포하는 데 대한 공식 승인이 필요합니다. 따라서 Python Software Foundation이 Python에서 사용할 수 있도록 코드를 라이선스할 수 있게 하는 contributor agreement에 서명해야 합니다(저작권은 본인에게 유지됩니다).

참고

이 문서에는 한 번만 서명하면 되며, 이후 Python에 기여하는 모든 내용에 적용됩니다.

CLA에 서명하는 데 필요한 단계는 다음과 같습니다:

  1. 변경 사항을 만들고 풀 리퀘스트로 제출하십시오.

  2. python-cla-bot이 커밋 작성자에게 Contributor License Agreement 서명이 필요하다는 댓글을 풀 리퀘스트에 남기면, 댓글에 있는 버튼을 클릭하여 서명하십시오. GitHub로 로그인하고 “Authorize Python CLA Bot”을 클릭한 다음 “Sign”을 클릭하십시오.

  3. 서명하면 python-cla-bot 댓글이 “모든 커밋 작성자가 Contributor License Agreement에 서명했습니다”라고 표시하도록 업데이트됩니다.

CLA에 다시 서명해야 하는 이유는 무엇입니까?

원본 풀 리퀘스트에 대해 이미 CLA에 서명했더라도 CLA 봇이 백포트 풀 리퀘스트에 대해 CLA에 서명하라고 요청하는 경우가 있습니다. 이는 커밋에 사용하는 모든 이메일 주소에 대해 CLA에 서명해야 하기 때문입니다.

configured your Git client에서 하나의 이메일 주소를 설정하고 이 주소로 CLA에 서명했지만, configured your GitHub account에서는 다른 기본 이메일 주소(흔히 비공개 id+username@users.noreply.github.com 주소)를 설정한 경우에 이런 일이 발생할 수 있습니다.

  1. 원본 PR에서 CLA 봇은 커밋의 모든 이메일이 CLA에 서명했는지 확인합니다.

  2. 그런 다음 PR을 스쿼시 병합하면 작성자의 기본 이메일을 사용하는 하나의 새 커밋이 생성됩니다. 이 이메일은 원래 커밋할 때 사용한 이메일과 다를 수 있습니다.

  3. 백포트에는 이 새로운 단일 커밋만 있는 경우가 많습니다. 그러면 CLA 봇은 기본 이메일이 CLA에 서명했는지 확인합니다.

  4. 해결 방법은 백포트 PR에서 CLA not signed – click to sign 버튼을 클릭하는 것입니다.

Git 클라이언트 설정을 확인하려면 git config user.email 명령을 실행하고, 커밋에 사용된 이메일 주소를 확인하려면 PR URL에 .patch를 추가하십시오:

제출

작업에 만족하면 변경 사항을 브랜치에 커밋하십시오. 일반적으로 git commit -a를 실행하면 모든 변경 사항이 커밋됩니다. 언제든지 git status를 실행하여 아직 남아 있는 변경 사항을 확인할 수 있습니다.

모든 변경 사항을 커밋했으면(즉, git status에 아무것도 표시되지 않으면) 브랜치를 포크에 푸시하십시오.:

git push origin <branch name>

그러면 변경 사항이 GitHub에 올라갑니다.

이제 포크에서 풀 리퀘스트 만들기를 수행하십시오. 이것이 이슈 추적기의 기존 이슈에 대응하는 풀 리퀘스트라면, 풀 리퀘스트 제목에는 gh-NNNNN: 접두사를 사용하고 설명에는 #NNNNN을 사용하여 이슈 번호를 참조하십시오.

보고되지 않은 이슈에 대한 풀 리퀘스트라면(기존 이슈가 있는지 이슈 추적기에서 이미 검색했다고 가정합니다) 새 이슈를 만들고 풀 리퀘스트에서 참조하십시오. 정보가 부족하여 검토자가 풀 리퀘스트 검토를 미루지 않도록 관련 세부 정보를 최대한 많이 작성하십시오.

이슈가 너무 간단하여 풀 리퀘스트에서 해결하려는 사항에 관한 논의를 추적할 이슈가 필요하지 않다면(예: 철자 오류 수정), 커밋 권한이 있는 사람이 풀 리퀘스트에 “skip issue” 레이블을 추가해야 합니다.

코드 검토 의견을 반영하는 과정에서 풀 리퀘스트에 여러 커밋이 포함될 수 있습니다. 스쿼시, 어멘드 또는 GitHub에 강제 푸시가 필요한 작업을 하지 말고 풀 리퀘스트의 커밋 기록을 그대로 유지하십시오. 상세한 커밋 기록이 있으면 검토자가 커밋 간 차이를 살펴보고 자신의 의견이 반영되었는지 쉽게 확인할 수 있습니다. 풀 리퀘스트가 병합될 때 커밋은 스쿼시됩니다.

b.p.o의 기존 패치를 GitHub로 변환하기

GitHub 풀 리퀘스트로 변환해야 하는 패치가 이슈 추적기에 있다면, 먼저 원래 패치 작성자에게 직접 풀 리퀘스트를 준비해 달라고 요청하십시오. 작성자가 일주일이 지나도 응답하지 않으면 다른 기여자가 기존 패치를 바탕으로 풀 리퀘스트를 준비해도 됩니다. 이 경우 양측 모두 CLA에 서명해야 합니다. 다른 사람의 패치를 바탕으로 풀 리퀘스트를 만들 때는 풀 리퀘스트 설명과 커밋 메시지에 “Co-authored-by: Author Name <email_address> .”를 추가하여 원래 패치 작성자를 명시하십시오. 공동 작성자 정보를 올바르게 추가하는 방법은 GitHub 문서를 참조하십시오.

관련 Git에 패치 적용하기도 참조하십시오.

검토

우선, 인내심을 가져 주십시오! 풀 리퀘스트를 제출하는 사람은 여러분의 풀 리퀘스트를 검토할 수 있는 사람보다 훨씬 많습니다. 풀 리퀘스트가 검토되려면 검토자가 풀 리퀘스트를 살펴볼 여유 시간과 의욕이 있어야 합니다(누구에게도 풀 리퀘스트를 검토하도록 강요할 수 없으며, 풀 리퀘스트를 검토하기 위해 고용된 사람도 없습니다). 한 달이 지나도 검토자로부터 아무런 반응도 받지 못했다면(즉, 댓글이 달리지 않았다면), 먼저 issue tracker에서 해당 이슈를 “핑”하여 구독자들에게 풀 리퀘스트에 검토가 필요하다는 사실을 상기시키십시오. 이슈를 핑한 후 일주일 이내에 응답을 받지 못하면 Core Development Discourse category에 글을 게시하여 풀 리퀘스트를 검토해 줄 사람을 요청할 수 있습니다.

누군가 풀 리퀘스트를 살펴볼 시간을 내게 되면 개선 방법에 관한 의견을 남길 가능성이 큽니다(걱정하지 마십시오. Python 코어 팀 구성원도 변경을 요청받아 자신의 풀 리퀘스트를 돌려받습니다). 그러면 이러한 의견을 반영하도록 풀 리퀘스트를 업데이트해야 하며, 만족스러운 해결책이 나올 때까지 검토 과정이 반복됩니다.

풀 리퀘스트를 검토하는 방법

Python 개발 과정의 병목 현상 중 하나는 코드 리뷰가 부족하다는 점입니다. 버그 추적기를 살펴보면 수정 사항이 마련된 이슈가 많지만, 제안된 해결책을 아무도 검토하지 않아 메인 소스 코드 저장소에 병합되지 못하고 있음을 알 수 있습니다. 풀 리퀘스트를 검토하는 일은 풀 리퀘스트를 제공하는 것만큼 유익할 수 있으며, 다른 개발자의 작업에 건설적인 의견을 제시할 수 있게 해 줍니다. 이 가이드에서는 코드 리뷰를 제출하기 위한 체크리스트를 제공합니다. 코드 리뷰가 유용하려면 완벽해야 한다는 것은 흔한 오해입니다. 전혀 그렇지 않습니다! 풀 리퀘스트를 테스트하거나 코드를 직접 다뤄 보고 풀 리퀘스트나 이슈 추적기에 의견을 남기는 것만으로도 도움이 됩니다.

  1. 아직 하지 않았다면 설정 가이드를 따라 CPython 저장소의 사본을 가져오고 빌드한 다음 테스트를 실행하십시오.

  2. 버그 추적기에서 이슈를 재현하는 데 필요한 단계를 확인하고, 저장소 안에서 ./python을 실행하여 시작할 수 있는 사용 중인 버전의 Python REPL(대화형 셸 프롬프트)에서 이슈를 재현할 수 있는지 확인하십시오.

  3. 풀 리퀘스트를 체크아웃하고 적용하십시오(지침 다른 사람의 풀 리퀘스트 체크아웃하기을 참조하십시오).

  4. 변경 사항이 C 파일에 영향을 준다면 다시 빌드하십시오.

  5. Python REPL(대화형 셸 프롬프트)을 시작하고 이슈를 재현할 수 있는지 확인하십시오. 이제 풀 리퀘스트가 적용되었으므로 이슈가 수정되어야 합니다(이론상으로는 그렇지만 실수는 발생하기 마련입니다! 좋은 검토는 코드가 Python 저장소에 병합되기 전에 이러한 실수를 찾아내는 것을 목표로 합니다). 또한 수정 사항의 작성자가 놓쳤을 수 있는 극단적인 사례가 이 이슈나 관련 이슈에 있는지 확인해 보아야 합니다.

  6. 시간이 있다면 전체 테스트 스위트를 실행하십시오. 시간이 부족하다면 변경 사항이 적용된 모듈의 테스트를 실행하십시오. 하지만 풀 리퀘스트가 ‘병합 준비 완료’ 상태라고 추천하려면 항상 전체 테스트 스위트가 통과하는지 확인해야 합니다.

GitHub에서 풀 리퀘스트 리뷰 남기기

풀 리퀘스트를 검토할 때는 검토 과정에 관한 추가 세부 정보와 맥락을 제공해야 합니다.

풀 리퀘스트를 단순히 “승인”하는 대신 의견을 남기십시오. 예를 들면 다음과 같습니다:

  1. PR을 테스트했다면 결과와 함께 ‘Windows 10’, ‘Ubuntu 16.4’, ‘Mac High Sierra’처럼 테스트한 시스템과 버전을 보고하십시오.

  2. 변경을 요청한다면 변경 방법도 제안해 보십시오.

  3. 풀 리퀘스트의 “나쁜” 점뿐만 아니라 “좋은” 점에도 의견을 남기십시오. 그러면 PR 작성자가 의견에서 좋은 점을 더 쉽게 찾을 수 있습니다.

  4. 현재 PR의 CI 실패를 살펴보십시오. PR 진행에 도움이 되는 간단한 방법은 아래의 “CI를 정상 상태로 유지하기”를 참조하십시오.

다른 코어 팀 구성원의 검토 무효화하기

요청된 변경 사항이 적용되었음을 확인한 코어 팀 구성원은 다른 팀 구성원의 검토를 무효화할 수 있습니다. 코어 팀 구성원이 자신을 PR 담당자로 지정했다면 해당 PR을 적극적으로 관리하고 있다는 뜻이므로, 그 구성원의 검토를 무효화해서는 안 됩니다.

지속적 통합을 정상 상태로 유지하기

일반적으로 변경 관리 워크플로에서는 실패 항목이 있는 PR의 병합을 허용하지 않습니다. 따라서 PR에서 CI 실패를 발견하면 원인을 살펴보십시오.

일반적으로 실패는 현재 PR의 변경 사항과 직접 관련되어 있습니다. 실패에 관해 아는 내용이 있다면 검토 의견으로 작성자에게 알려 주십시오. CI 실행에서는 때때로 수천 줄의 출력이 생성됩니다. 트레이스백을 찾아 의견에 넣는 간단한 작업만으로도 PR 작성자에게 도움이 됩니다.

실패가 살펴보고 있는 변경 사항과 관련이 없어 보인다면 Release Status 빌드봇 대시보드에도 동일한 실패가 있는지 확인하십시오. 그렇다면 해당 실패가 이전 변경 사항에서 발생했다는 뜻입니다. 빌드봇 UI를 사용하면 문제를 발생시킨 PR을 찾아 다른 PR에도 영향을 미친다는 의견을 남길 수 있습니다.

그래도 실패의 원인을 찾을 수 없다면 실행된 검사 목록 옆에 “This branch is out-of-date with the base branch” 표시가 있는지 확인하십시오. 이 메시지 옆의 Update branch를 클릭하면 베이스 브랜치의 최신 변경 사항이 PR에 병합됩니다.

그래도 PR의 실패가 해결되지 않는다면 실패한 해당 검사를 다시 실행해 볼 수 있습니다. 관련 Re-run jobs 버튼은 코어 팀과 트리아지 팀의 구성원에게만 표시된다는 점에 유의하십시오. 해당 권한이 있다면 실패한 GitHub Actions 작업으로 이동하여 오른쪽 위의 Re-run jobs를 클릭한 다음 Re-run failed jobs를 선택하십시오. 이 버튼은 다른 모든 작업이 완료된 후에만 표시됩니다.

버튼에 접근할 수 없다면 해당 팀의 구성원에게 작업을 다시 실행해 달라고 요청하십시오. 또는 빈 커밋을 푸시하거나 Update branch 버튼으로 브랜치를 업데이트하여 직접 CI를 다시 실행할 수 있습니다.

실패한 작업을 다시 실행하는 것을 가장 먼저 시도해서는 안 되지만, 분산 시스템에서는 간헐적인 실패가 발생할 수 있고 일부 단위 테스트는 과부하된 가상 머신에 민감하므로 때로는 도움이 됩니다. 이러한 불안정한 동작을 식별하면, 이 특정 불안정성을 설명하는 이슈가 이슈 추적기에 있는지 찾아보십시오. 찾을 수 없다면 새 이슈를 만드십시오.

Update branch 버튼

관련 Update branch 버튼을 클릭하면 베이스 브랜치(일반적으로 main)의 최신 변경 사항을 PR에 병합할 수 있습니다. 이는 오래된 PR에서 CI를 정상 상태로 유지하거나 베이스 브랜치에서 CI 실패가 수정되었는지 확인하는 데 유용합니다.

PR이 매우 오래되었다면 마지막 CI 실행 이후 추가되거나 변경된 CI 검사에서 PR이 실패하지 않는지 확인하기 위해 병합 전에 브랜치를 업데이트하는 것이 유용할 수 있습니다.

정당한 이유 없이 Update branch를 클릭하지 마십시오. 실제로는 새로운 변경 사항이 없는데도 PR을 지켜보는 모든 사람에게 새로운 변경 사항이 있다고 알리고, 한정된 CI 리소스를 소모하기 때문입니다.

커밋/거부

풀 리퀘스트가 수용 가능한 상태에 도달하면(따라서 “수락된” 것으로 간주되면) 병합되거나 거부됩니다. 거부되더라도 개인적인 일로 받아들이지 마십시오! 풀 리퀘스트의 병합 여부와 관계없이 여러분의 작업은 여전히 소중하게 평가됩니다. Python에 무엇을 포함하고 무엇을 포함하지 않을지 균형을 잡는 일은 까다로우며, 모든 사람의 기여를 받아들일 수는 없습니다.

하지만 풀 리퀘스트가 병합되면 Python의 VCS(버전 관리 시스템)에 반영되어 Python의 다음 기능 릴리스에 포함됩니다. 병합을 수행하는 코어 팀 구성원이 필요하다고 판단하면 버그 수정으로 이전 버전의 Python에 백포트될 수도 있습니다.

공로 표기

사소하지 않은 기여는 Python의 새로운 기능 문서와 해당 기여의 뉴스 항목에도 공로가 표기되는 경우가 많습니다.