PEP 632 – distutils 모듈 폐기
- Author:
- Steve Dower <steve.dower at python.org>
- Discussions-To:
- Discourse thread
- Status:
- Final
- Type:
- Standards Track
- Created:
- 03-Sep-2020
- Python-Version:
- 3.10
- Post-History:
- 03-Sep-2020, 22-Jan-2021
- Resolution:
- Python-Dev thread
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain or CC0-1.0, whichever is more permissive 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
distutils 모듈 [1]은 오래전부터 이 모듈 대신 setuptools 패키지 [2]를 사용하도록 권장해 왔습니다. Setuptools는 최근 distutils의 완전한 사본을 통합했으며 더 이상 표준 라이브러리 [3]에 의존하지 않습니다. Pip은 이미 오래전부터 패키지를 설치할 때 distutils를 setuptools로 조용히 대체해 왔으며, distutils 문서에는 2014년(또는 그 이전)부터 이 모듈이 단계적으로 폐지되고 있다고 명시되어 있습니다. 이제 표준 라이브러리에서 이를 제거할 때가 되었습니다.
동기
distutils [1]는 네이티브 확장 모듈의 컴파일을 포함하여 Python 패키지를 패키징하고 배포하기 위한 유틸리티 모음으로, 대부분 문서화되어 있지 않고 유지 보수되지 않고 있습니다. 이는 Python 배포를 기술하는 설정 형식을 정의하며, 소스 코드 디렉터리를 소스 배포판 및 몇 가지 형태의 바이너리 배포로 변환하는 도구를 제공합니다. 표준 라이브러리에 속해 있기 때문에 많은 업데이트는 메이저 릴리스를 통해서만 출시될 수 있으며, 사용자는 특정 수정 사항이 제공될 것이라고 기대할 수 없습니다.
setuptools [2]는 distutils를 기반으로 한 개선판으로, 문서화가 더 잘 되어 있고 유지 보수도 잘 되고 있습니다. setuptools는 매우 유사한 기능을 제공하면서도 이전 Python 릴리스의 사용자를 훨씬 더 잘 지원할 수 있으며, 버그 보고에 더 빠르게 대응할 수 있습니다. setuptools에는 distutils에 추가되지 않은 여러 플랫폼별 개선 사항이 이미 존재하며, distutils 문서에는 오래전부터 setuptools를 우선 사용하라는 권고가 있었습니다.
역사적으로 setuptools는 서브클래싱과 몽키패칭을 사용하여 distutils를 확장해 왔으나, 이제는 기반 코드의 사본을 가져왔습니다. [3] 그 결과 distutils에 대한 마지막에서 두 번째 주요 의존성이 사라졌으며, 더 이상 이를 표준 라이브러리에 유지할 필요가 없습니다.
distutils에 대한 마지막 의존성은 CPython 자체로, CPython은 표준 라이브러리의 네이티브 확장 모듈을 빌드하는 데 distutils를 사용합니다(Windows 제외). 이는 CPython 빌드 시점의 의존성이므로, distutils가 표준 라이브러리에 포함되지 않더라도 이 특정한 경우에는 계속 distutils를 사용할 수 있습니다.
폐지와 제거를 통해 문제는 setuptools 프로젝트에서 수정해야 한다는 점이 분명해지며, 버그 보고의 원인과 불필요한 테스트 유지보수가 줄어들 것입니다. 또한 대체 빌드 백엔드의 개발을 촉진하는 데에도 도움이 될 것이며, 이러한 백엔드는 이제 PEP 517 덕분에 더 쉽게 지원될 수 있습니다.
명세
Python 3.10과 3.11에서 distutils는 공식적으로 폐기 예정으로 표시됩니다. 이 시점에 알려진 모든 이슈는 종료됩니다. import distutils는 폐지 경고를 발생시킵니다. 릴리스를 막는 것으로 간주될 새로운 이슈는 여전히 수정될 수 있지만, 새로운 도구나 플랫폼에 대한 지원은 추가되지 않습니다.
Python 3.10과 3.11 기간 동안, 표준 라이브러리 내에서 distutils를 사용하는 부분은 대체 API를 사용하도록 변경될 수 있습니다.
Python 3.12에서는 distutils가 더 이상 make install이나 어떠한 공식 배포판에 의해서도 설치되지 않습니다. 서드파티 재배포자는 더 이상 자신의 번들이나 저장소에 distutils를 포함해서는 안 됩니다.
이 PEP는 현재 distutils를 사용하는 CPython 빌드 과정의 각 부분을 이전하는 것에 대해서는 아무런 명세도 하지 않습니다. 기여 상황에 따라 이 마이그레이션은 언제든지 이루어질 수 있습니다.
Python 3.12 개발이 시작되고 CPython 빌드 프로세스가 더 이상 표준 라이브러리에 있는 distutils에 의존하지 않게 되면, Lib/distutils 디렉터리 전체와 Lib/test/test_distutils.py 파일이 저장소에서 제거됩니다.
distutils에 대한 다른 참조도 정리됩니다. Python 3.9의 최초 릴리스 기준으로, 다음 모듈의 코드나 주석에 참조가 있습니다:
- Lib/ctypes/util.py
- Lib/site.py
- Lib/sysconfig.py
- Lib/_aix_support.py
- Lib/_bootsubprocess.py
- Lib/_osx_support.py
- Modules/_decimal/tests/formathelper.py
CPython의 다음 Tools도 distutils를 참조합니다. 이들 중 어느 것도 CPython과 함께 설치되지 않는다는 점에 유의하십시오:
- PC/layout (참조가 제거될 예정입니다)
- Tools/msi (참조가 제거될 예정입니다)
- Tools/peg_generator (다른 빌드 도구에 맞게 수정될 예정입니다)
- Tools/test2to3 (예제 프로젝트가 제거될 예정입니다)
distutils 코드는 이미 setuptools에 포함되어 있으므로 다른 형태로 다시 배포할 필요가 없습니다. 해당 기능이 필요한 사람은 setuptools나 다른 빌드 백엔드를 사용해야 합니다.
하위 호환성
distutils를 임포트하는 코드는 Python 3.12부터 더 이상 동작하지 않습니다.
권장하는 마이그레이션 방법은 setuptools에서 동등한(동일하지는 않지만) 임포트를 사용하거나([5] 참조), 다른 빌드 백엔드로 마이그레이션하는 것입니다(PEP 517 참조).
setuptools에는 distutils를 사용하는 setup.py 파일을 동등한 기능으로 투명하게 전환하는 코드가 이미 있으므로, 현재 동작하는 빌드 스크립트 대부분은 setuptools에서도 동작하는 것으로 이미 알려져 있습니다. 이러한 스크립트는 임포트 문을 수정해야 할 수도 있습니다. 구체적인 마이그레이션 조언은 setuptools 문서를 참고하십시오. [5]
일부 프로젝트, 특히 numpy.distutils는 distutils 위에 별도의 패치 모음을 사용합니다. [6] 이렇게 하고 있는 것으로 파악된 프로젝트에는 이미 통보했습니다.
많은 빌드 스크립트가 사용자 정의 명령이나 좁은 범위의 패치를 사용합니다. 이러한 패키지는 이미 setuptools가 distutils를 덮어쓰는 영향을 받고 있으므로, distutils 제거로 인한 혼란은 최소한일 것으로 예상합니다. 그래도 distutils를 임포트하지 않도록 스크립트를 수정해야 할 수는 있습니다.
참조 구현
setuptools 버전 48은 distutils의 완전한 사본을 포함하므로 더 이상 표준 라이브러리의 사본에 의존하지 않습니다. setuptools가 겪어 온 구현 문제 대부분은 표준 라이브러리에 distutils가 계속 존재하기 때문에 생긴 것이므로, distutils를 제거하면 setuptools 구현의 안정성이 향상될 것입니다.
표준 라이브러리에서 distutils를 제거하는 참조 구현은 아직 없으며, 표준 라이브러리의 distutils 사본에 의존하지 않고 CPython의 네이티브 모듈을 빌드하는 구현도 아직 없습니다.
마이그레이션 조언
Note
이 절에서는 이 PEP로 공식적으로 폐지되는, 널리 쓰이는 기능의 대체 수단을 몇 가지 제안합니다. 이 내용은 작성 시점 기준이며, 이후로 갱신되지 않습니다.
다음 모듈이나 타입은 setuptools가 가장 좋은 대체 수단입니다:
distutils.ccompilerdistutils.cmd.Commanddistutils.commanddistutils.configdistutils.core.Distributiondistutils.errors
이러한 모듈이나 타입에 대해서는 표준으로 정의된 Python 패키징 Authority 패키지 중 명시된 것을 사용하십시오:
distutils.version—packaging패키지를 사용하십시오
이러한 모듈이나 함수는 아래에 제시된 표준 라이브러리 모듈을 사용하십시오:
distutils.fancy_getopt—argparse모듈을 사용하십시오distutils.spawn.find_executable—shutil.which함수를 사용하십시오distutils.spawn.spawn—subprocess.run함수를 사용하십시오distutils.sysconfig—sysconfig모듈을 사용하십시오distutils.util.get_platform—platform모듈을 사용하십시오
이러한 함수와 여기에 언급되지 않은 그 밖의 함수는 해당 기능을 직접 다시 구현해야 합니다. 레거시 문서는 https://docs.python.org/3.9/distutils/apiref.html 에서 찾을 수 있습니다.
distutils.dir_util.create_treedistutils.util.change_rootdistutils.util.strtobool
기각된 아이디어
폐지 예정으로 두되 삭제하지 않기
이 접근 방식의 가장 큰 문제는 distutils가 플랫폼 차이 때문에 가장 자주 망가진다는 점입니다. 이는 유지 보수가 없으면 어떤 Python 릴리스와도 맞지 않는 시점에 distutils가 작동을 멈추게 된다는 뜻입니다. 이 때문에 라이브러리는 자신이 언제 작동을 멈출지 신뢰성 있게 감지할 수 없습니다.
반면, 이 PEP는 distutils가 동작을 멈추는 구체적인 날짜를 충분히 앞서 알려 두고, 그때까지 API를 망가뜨리지 않겠다고 약속(커밋)합니다. 이를 통해 유지 관리자는 예측 가능한 일정을 얻을 수 있습니다. 또한 모든 호환성 파괴는 사용자가 이미 동작 변경을 예상하고 있는 시점에 일어나게 되며, 신뢰할 수 있는 감지 메커니즘(구체적으로는 import distutils가 예외를 발생시키는 것)도 제공됩니다.
마지막으로, distutils가 어떤 형태로든 표준 라이브러리에 남아 있는 한, setuptools를 비롯하여 심(shim)이나 대체물을 제공하는 서드파티 패키지와 충돌하게 됩니다. 미리 알려진 버전에서 패키지를 완전히 제거하면 서드파티가 대체물을 안전하게 사용할 수 있습니다.
setuptools와 유사한 기능만 폐지 예정으로 두기
이 제안은 남은 부분을 유지 보수할 자원봉사자가 있다고 가정하지만, 실제로는 그렇지 않습니다. 또한 어떤 기능을 남겨야 하는지 누군가 알고 있다는 것을 전제로 합니다. 하지만 논의에서 보았듯이 이는 전혀 분명하지 않습니다.
distutils의 헬퍼 함수 대부분에는 이미 지원되는 (그리고 개선된) 대안이 있으며, 이러한 대안은 대개 표준 라이브러리에 있습니다. 그리고 호환성을 깨뜨리지 않고서는 레거시 버전에 할 수 있는 일이 거의 없습니다. (또한 유지 관리자가 코드를 수정해야 하는 호환성 파괴는 사실상 다른 함수를 임포트하도록 요구하는 것과 다르지 않습니다.)
이전 절의 마지막 요점이 여기에도 적용됩니다.
참고 문헌
Copyright
This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.