# 2. 설정 스크립트 작성하기

참고

이 문서는 https://setuptools.readthedocs.io/en/latest/setuptools.html 의 `setuptools` 설명서가 현재 여기에 포함된 모든 관련 정보를 독립적으로 다루기 전까지만 보존됩니다.

설정 스크립트는 Distutils를 사용하여 모듈을 빌드, 배포 및 설치하는 모든 활동의 중심입니다. 설정 스크립트의 주요 목적은 여러분의 모듈 배포를 Distutils에 설명하여, 여러분의 모듈에 대해 작동하는 다양한 명령이 올바르게 수행되도록 하는 것입니다. 위의 간단한 예 섹션에서 보았듯이, 설정 스크립트는 주로 `setup()`에 대한 호출로 구성되며, 모듈 개발자가 Distutils에 제공하는 대부분의 정보는 `setup()`에 키워드 인자로 제공됩니다.

다음 몇 개의 섹션에서 다룰, 약간 더 개선된 예가 여기 있습니다: Distutils의 자체 설정 스크립트. (Distutils가 파이썬 1.6 이상에 포함되어 있지만, 파이썬 1.5.2 사용자가 다른 모듈 배포판을 설치하는 데 사용할 수 있도록 독립적으로 존재함에 유의하십시오. 여기에 표시된 Distutils의 자체 설정 스크립트는 파이썬 1.5.2에 패키지를 설치하는 데 사용됩니다.)

    #!/usr/bin/env python

    from distutils.core import setup

    setup(name='Distutils',
          version='1.0',
          description='Python Distribution Utilities',
          author='Greg Ward',
          author_email='gward@python.net',
          url='https://www.python.org/sigs/distutils-sig/',
          packages=['distutils', 'distutils.command'],
         )

이 섹션과 간단한 예 섹션에 제시된 간단한 단일 파일 배포판에는 두 가지 차이점이 있습니다: 더 많은 메타 데이터와 모듈이 아니라 패키지를 사용한 순수 파이썬 모듈 명세. 이것은 Distutils가 (지금까지) 두 개의 패키지로 분할된 수십 개의 모듈로 구성되어 있어서 중요합니다; 모든 모듈의 명시적인 목록은 생성하기가 지루하고 유지하기가 어려울 것입니다. 추가 메타 데이터에 대한 자세한 내용은, 섹션 추가 메타 데이터를 참조하십시오.

설정 스크립트에 제공된 모든 경로명(파일이나 디렉터리)은 슬래시로 구분된 유닉스 규칙을 사용하여 작성해야 함에 유의하십시오. Distutils는 이 플랫폼 중립적 표현을 실제로 경로명을 사용하기 전에 현재 플랫폼에 적절한 것으로 변환합니다. 이는 운영 체제에 걸쳐 설정 스크립트를 이식성 있게 만드는데, 이것은 물론 Distutils의 주요 목표 중 하나입니다. 이러한 취지로, 이 문서의 모든 경로명은 슬래시로 구분됩니다.

물론, 이것은 Distutils 함수에 주어진 경로명에만 적용됩니다. 예를 들어, `glob.glob()`이나 `os.listdir()`과 같은 표준 파이썬 함수를 사용하여 파일을 지정하면, 경로 구분자를 하드 코딩 하는 대신 이식성 있는 코드를 작성하도록 주의해야 합니다:

    glob.glob(os.path.join('mydir', 'subdir', '*.html'))
    os.listdir(os.path.join('mydir', 'subdir'))

## 2.1. 전체 패키지 나열하기

`packages` 옵션은 Distutils가 `packages` 리스트에 언급된 각 패키지에 있는 모든 순수 파이썬 모듈을 처리(빌드, 배포, 설치 등)하도록 지시합니다. 물론 이를 위해서는 패키지 이름과 파일 시스템의 디렉터리 간의 대응 관계가 있어야 합니다. 기본 대응 관계는 가장 분명한 것입니다, 즉, 패키지 `distutils`는 배포 루트에 상대적인 디렉터리 `distutils`에서 발견됩니다. 따라서 설정 스크립트에서 `packages = ['foo']`라고 할 때, Distutils가 설정 스크립트가 있는 디렉터리에 상대적으로 `foo/__init__.py` 파일(여러분의 시스템에서는 철자가 다를 수 있지만, 무슨 뜻인지는 알 겁니다)을 찾을 것이라고 약속하는 것입니다. 이 약속을 어기면, Distutils는 경고를 표시하지만, 여전히 손상된 패키지를 처리합니다.

다른 규칙을 사용하여 소스 디렉터리를 배치하는 것도 문제가 되지 않습니다: Distutils에 규칙에 대해 알리기 위해 `package_dir` 옵션을 제공하기만 하면 됩니다. 예를 들어, 모든 파이썬 소스를 `lib` 밑에 유지하여, “루트 패키지”의 모듈(즉, 어떤 패키지에도 속하지 않은 것)은 `lib`에 있고, `foo` 패키지의 모듈은 `lib/foo`에 있고 등등. 그러면 다음을 여러분의 설정 스크립트에 넣습니다:

    package_dir = {'': 'lib'}

이 딕셔너리의 키는 패키지 이름이며, 빈 패키지 이름은 루트 패키지를 나타냅니다. 값은 배포 루트에 상대적인 디렉터리 이름입니다. 이 경우, `packages = ['foo']`라고 할 때, 파일 `lib/foo/__init__.py`가 존재한다고 약속하는 것입니다.

또 다른 가능한 규칙은 `foo` 패키지를 `lib`에, `foo.bar` 패키지를 `lib/bar`에 두는 것입니다. 이것은 설치 스크립트에서 다음과 같이 작성됩니다

    package_dir = {'foo': 'lib'}

`package_dir` 딕셔너리의 `package: dir` 항목은 package 아래의 모든 패키지에 묵시적으로 적용되므로, `foo.bar` 사례는 여기에서 자동으로 처리됩니다. 이 예에서, `packages = ['foo', 'foo.bar']`가 있으면 Distutils에 `lib/__init__.py`와 `lib/bar/__init__.py`를 찾도록 지시합니다. (`package_dir`이 재귀적으로 적용되지만, `packages`의 모든 패키지를 명시적으로 나열해야 함에 유의하십시오: Distutils는 `__init__.py` 파일이 있는 디렉터리를 찾기 위해 소스 트리를 재귀적으로 스캔하지 않습니다.)

## 2.2. 개별 모듈 나열하기

소규모 모듈 배포의 경우, 패키지를 나열하는 대신 모든 모듈을 나열하는 것이 좋습니다—특히 “루트 패키지”에 있는 단일 모듈의 경우 (즉, 패키지가 아예 없습니다). 이 가장 간단한 경우는 섹션 간단한 예에 표시되었습니다; 다음은 약간 더 개선된 예입니다:

    py_modules = ['mod1', 'pkg.mod2']

이것은 두 모듈을 기술합니다, 하나는 “루트” 패키지에 있고, 다른 하나는 `pkg` 패키지에 있습니다. 다시, 기본 패키지/디렉터리 레이아웃은 이 두 모듈이 `mod1.py`와 `pkg/mod2.py`에서 발견될 수 있고 `pkg/__init__.py`도 존재함을 암시합니다. 그리고 다시, `package_dir` 옵션을 사용하여 패키지/디렉터리 대응 관계를 재정의할 수 있습니다.

## 2.3. 확장 모듈 기술하기

순수 파이썬 모듈을 작성하는 것보다 파이썬 확장 모듈을 작성하는 것이 조금 더 복잡한 것처럼, 확장 모듈을 Distutils에 설명하는 것은 조금 더 복잡합니다. 순수한 모듈과 달리, 단지 모듈이나 패키지를 나열하고 Distutils가 가서 올바른 파일을 찾을 것으로 기대할 수는 없습니다; 확장 이름, 소스 파일 및 컴파일/링크 요구 사항(인클루드 디렉터리, 링크할 라이브러리 등)을 지정해야 합니다.

이 모든 것은 `setup()`에 대한 또 다른 키워드 인자를 통해 수행됩니다, `ext_modules` 옵션. `ext_modules`는 단지 `Extension` 인스턴스의 리스트일 뿐이며, 각각 단일 확장 모듈을 설명합니다. 여러분의 배포판에 `foo`라는 단일 확장이 포함되어 있고 `foo.c`로 구현되었다고 가정합시다. 컴파일러/링커에 대한 추가 지침이 필요하지 않으면, 이 확장을 설명하는 것은 매우 간단합니다:

    Extension('foo', ['foo.c'])

`Extension` 클래스는 `setup()`과 함께 `distutils.core`에서 임포트 할 수 있습니다. 따라서, 이 하나의 확장만 포함하고 다른 것은 포함하지 않는 모듈 배포판의 설정 스크립트는 다음과 같습니다:

    from distutils.core import setup, Extension
    setup(name='foo',
          version='1.0',
          ext_modules=[Extension('foo', ['foo.c'])],
          )

`Extension` 클래스(실제로는, build_ext 명령으로 구현된 하부 확장 빌드 시스템)는 파이썬 확장을 설명하는 데 많은 유연성을 지원하고, 다음 섹션에서 설명합니다.

### 2.3.1. 확장 이름과 패키지

`Extension` 생성자에 대한 첫 번째 인자는 항상 패키지 이름을 포함한 확장의 이름입니다. 예를 들면,

    Extension('foo', ['src/foo1.c', 'src/foo2.c'])

는 루트 패키지에 있는 확장을 설명하지만,

    Extension('pkg.foo', ['src/foo1.c', 'src/foo2.c'])

는 `pkg` 패키지에 있는 같은 확장을 설명합니다. 소스 파일과 결과 객체 코드는 두 경우 모두 동일합니다; 유일한 차이점은 결과 확장이 존재할 파일 시스템에서의 위치(그리고 파이썬의 이름 공간 계층에서의 위치)입니다.

모두 같은 패키지에 있는 여러 개의 확장이 있으면 (또는 모두 같은 베이스 패키지 아래), `setup()`에 `ext_package` 키워드 인자를 사용하십시오. 예를 들면,

    setup(...,
          ext_package='pkg',
          ext_modules=[Extension('foo', ['foo.c']),
                       Extension('subpkg.bar', ['bar.c'])],
         )

는 `foo.c`를 확장 `pkg.foo`로, `bar.c`를 `pkg.subpkg.bar`로 컴파일합니다.

### 2.3.2. 확장 소스 파일

`Extension` 생성자에 대한 두 번째 인자는 소스 파일 리스트입니다. Distutils는 현재 C, C++ 및 Objective-C 확장만 지원하므로, 일반적으로 C/C++/Objective-C 소스 파일입니다. (C++ 소스 파일을 구별하기 위해 적절한 확장자를 사용해야 합니다: `.cc`와 `.cpp`는 유닉스와 윈도우 컴파일러 모두에서 인식되는 것 같습니다.)

그러나, 리스트에 SWIG 인터페이스 (`.i`) 파일을 포함할 수도 있습니다; build_ext 명령은 SWIG 확장을 처리하는 방법을 알고 있습니다: 인터페이스 파일에 대해 SWIG을 실행하고 결과 C/C++ 파일을 확장으로 컴파일합니다.

이 경고에도 불구하고, SWIG에 대한 옵션은 현재 다음과 같이 전달될 수 있습니다:

    setup(...,
          ext_modules=[Extension('_foo', ['foo.i'],
                                 swig_opts=['-modern', '-I../include'])],
          py_modules=['foo'],
         )

또는 다음과 같이 명령 줄에서:

    > python setup.py build_ext --swig-opts="-modern -I../include"

일부 플랫폼에서는, 컴파일러에서 처리되고 확장에 포함되는 비 소스 파일을 포함할 수 있습니다. 현재, 이것은 Visual C++ 용 윈도우 메시지 텍스트 (`.mc`) 파일과 리소스 정의 (`.rc`) 파일을 의미합니다. 이들은 바이너리 리소스 (`.res`) 파일로 컴파일되고 실행 파일에 링크됩니다.

### 2.3.3. 전 처리기 옵션

`Extension`에 대한 세 가지 선택적 인자는 검색할 인클루드 디렉터리나 정의/정의 해제할 전 처리기 매크로를 지정해야 하는 경우 도움이 됩니다: `include_dirs`, `define_macros` 및 `undef_macros`.

예를 들어, 확장에 배포 루트 아래의 `include` 디렉터리에 있는 헤더 파일이 필요한 경우, `include_dirs` 옵션을 사용하십시오:

    Extension('foo', ['foo.c'], include_dirs=['include'])

거기에 절대 디렉터리를 지정할 수 있습니다; X11R6이 `/usr`에 설치된 유닉스 시스템에서만 확장이 빌드된다는 것을 알고 있다면, 다음과 같이 할 수 있습니다

    Extension('foo', ['foo.c'], include_dirs=['/usr/include/X11'])

코드를 배포하려는 경우 이런 종류의 이식성 없는 사용을 피해야 합니다: 다음과 같은 C 코드를 작성하는 것이 좋습니다

    #include <X11/Xlib.h>

다른 파이썬 확장의 헤더 파일을 포함해야 하는 경우, Distutils install_headers 명령으로 헤더 파일이 일관된 방식으로 설치된다는 사실을 이용할 수 있습니다. 예를 들어, Numerical Python 헤더 파일은 (표준 유닉스 설치 시) `/usr/local/include/python1.5/Numerical`에 설치됩니다. (정확한 위치는 플랫폼과 파이썬 설치에 따라 다릅니다.) 파이썬 인클루드 디렉터리—이 경우 `/usr/local/include/python1.5`—는 파이썬 확장을 빌드할 때 항상 검색 경로에 포함되므로, 다음과 같이 C 코드를 작성하는 것이 가장 좋습니다

    #include <Numerical/arrayobject.h>

`Numerical` 인클루드 디렉터리를 헤더 검색 경로에 바로 넣어야 하면, Distutils `distutils.sysconfig` 모듈을 사용하여 해당 디렉터리를 찾을 수 있습니다:

    from distutils.sysconfig import get_python_inc
    incdir = os.path.join(get_python_inc(plat_specific=1), 'Numerical')
    setup(...,
          Extension(..., include_dirs=[incdir]),
          )

이것은 꽤 이식성 있지만—플랫폼과 관계없이, 모든 파이썬 설치에서 작동합니다—C 코드를 현명하게 작성하기가 더 쉽습니다.

`define_macros`와 `undef_macros` 옵션을 사용하여 전 처리기 매크로를 정의하고 정의를 해제할 수 있습니다. `define_macros`는 `(name, value)` 튜플의 리스트를 취합니다, 여기서 `name`은 정의할 매크로의 이름(문자열)이고 `value`는 값입니다: 문자열이거나 `None`. (매크로 `FOO`를 `None`으로 정의하는 것은 C 소스에서 값이 없는 `#define FOO`와 같습니다: 대부분의 컴파일러에서는 `FOO`를 문자열 `1`로 설정합니다.) `undef_macros`는 정의 해제할 매크로의 리스트입니다.

예를 들면:

    Extension(...,
              define_macros=[('NDEBUG', '1'),
                             ('HAVE_STRFTIME', None)],
              undef_macros=['HAVE_FOO', 'HAVE_BAR'])

는 모든 C 소스 파일의 맨 위에 다음과 같은 것을 넣는 것과 동등합니다:

    #define NDEBUG 1
    #define HAVE_STRFTIME
    #undef HAVE_FOO
    #undef HAVE_BAR

### 2.3.4. 라이브러리 옵션

확장을 빌드할 때 링크할 라이브러리와 해당 라이브러리를 검색할 디렉터리를 지정할 수도 있습니다. `libraries` 옵션은 링크할 라이브러리의 리스트이고, `library_dirs`는 링크 시점에 라이브러리를 검색할 디렉터리 리스트이고, `runtime_library_dirs`는 실행 시간에 공유 (동적으로 로드된) 라이브러리를 검색할 디렉터리 리스트입니다.

예를 들어, 대상 시스템의 표준 라이브러리 검색 경로에 있는 것으로 알려진 라이브러리와 링크해야 하면

    Extension(...,
              libraries=['gdbm', 'readline'])

비표준 위치의 라이브러리와 링크해야 하면, `library_dirs`에 위치를 포함해야 합니다:

    Extension(...,
              library_dirs=['/usr/X11R6/lib'],
              libraries=['X11', 'Xt'])

(다시, 코드를 배포하려는 경우 이러한 이식성 없는 구성은 피해야 합니다.)

### 2.3.5. 다른 옵션

특수한 경우를 처리하는 데 사용할 수 있는 다른 옵션이 아직 남아있습니다.

`optional` 옵션은 불리언입니다. 참이면, 그 확장에서의 빌드 실패는 빌드 프로세스를 중단시키지 않고 대신 실패한 확장을 설치하지 않습니다.

`extra_objects` 옵션은 링커에 전달할 객체 파일의 리스트입니다. 컴파일러의 기본 확장자가 사용되므로 이러한 파일에는 확장자가 없어야 합니다.

`extra_compile_args`와 `extra_link_args`를 사용하여 해당 컴파일러와 링커 명령 줄에 대한 추가 명령 줄 옵션을 지정할 수 있습니다.

`export_symbols`는 윈도우에서만 유용합니다. 내보낼 심볼 (함수나 변수) 목록을 포함할 수 있습니다. 컴파일된 확장을 빌드할 때는 이 옵션이 필요하지 않습니다: Distutils는 내 보내는 심볼 목록에 `initmodule`을 자동으로 추가합니다.

`depends` 옵션은 확장이 의존하는 파일의 리스트입니다 (예를 들어 헤더 파일). build 명령은 이전 빌드 이후 이 파일들에 수정된 파일이 있으면 소스에 대해 컴파일러를 호출하여 확장을 다시 빌드합니다.

## 2.4. 배포판과 패키지의 관계

배포판은 세 가지 방법으로 패키지와 관련될 수 있습니다:

1. 패키지나 모듈이 필요할 수 있습니다.

2. 패키지나 모듈을 제공할 수 있습니다.

3. 패키지나 모듈을 폐기(obsolete)할 수 있습니다.

이러한 관계는 `distutils.core.setup()` 함수에 키워드 인자를 사용하여 지정할 수 있습니다.

requires 키워드 인자를 `setup()`에 제공하여 다른 파이썬 모듈과 패키지에 대한 의존성을 지정할 수 있습니다. 값은 문자열 리스트여야 합니다. 각 문자열은 필요한 패키지와 선택적으로 충분한 버전을 지정합니다.

모듈이나 패키지의 임의의 버전이 필요하도록 지정하려면, 문자열은 모듈이나 패키지 이름으로만 구성되어야 합니다. 예로는 `'mymodule'`과 `'xml.parsers.expat'`이 있습니다.

특정 버전이 필요하면, 일련의 한정자를 괄호 안에 제공할 수 있습니다. 각 한정자는 비교 연산자와 버전 번호로 구성될 수 있습니다. 허용되는 비교 연산자는 다음과 같습니다:

    <    >    ==
    <=   >=   !=

쉼표(와 선택적인 공백)로 구분된 여러 한정자를 사용하여 결합 할 수 있습니다. 이 경우, 모든 한정자가 일치해야 합니다; 논리적 AND가 평가를 결합하는 데 사용됩니다.

여러 가지 예를 살펴보겠습니다:

Requires 표현식 | 설명
--- | ---
`==1.0` | 버전 `1.0`만 호환됩니다
`>1.0, !=1.5.1, <2.0` | `1.0` 이후와 `2.0` 이전의 모든 버전이 호환됩니다, `1.5.1`은 제외

이제 의존성을 지정할 수 있으니, 다른 배포에 필요한 것을 제공할 수도 있어야 합니다. 이는 `setup()`에 provides 키워드 인자를 사용하여 수행됩니다. 이 키워드의 값은 문자열의 리스트이며, 각 문자열은 파이썬 모듈이나 패키지의 이름이며, 선택적으로 버전을 식별합니다. 버전을 지정하지 않으면, 배포판의 버전과 일치하는 것으로 간주합니다.

몇 가지 예:

Provides 표현식 | 설명
--- | ---
`mypkg` | 배포판 버전을 사용하여, `mypkg`를 제공합니다
`mypkg (1.1)` | 배포판 버전과 관계없이, `mypkg` 버전 1.1을 제공합니다

패키지는 obsoletes 키워드 인자를 사용하여 다른 패키지를 폐기한다고 선언할 수 있습니다. 이것의 값은 requires 키워드의 값과 유사합니다: 모듈이나 패키지 지정자를 제공하는 문자열의 리스트. 각 지정자는 모듈이나 패키지 이름으로 구성되고 선택적으로 하나 이상의 버전 한정자가 뒤따릅니다. 버전 한정자는 모듈이나 패키지 이름 다음에 괄호 안에 주어집니다.

한정자에 의해 식별된 버전은 기술 중인 배포판에 의해 폐기되는 버전입니다. 한정자가 제공되지 않으면, 명명된 모듈이나 패키지의 모든 버전이 폐기되는 것으로 이해됩니다.

## 2.5. 스크립트 설치하기

지금까지 우리는 순수하거나 순수하지 않은 파이썬 모듈을 다루어 왔는데, 보통은 그 스스로 실행하지 않고 스크립트가 임포트 합니다.

스크립트는 명령 줄에서 시작하려는 의도로 만들어진, 파이썬 소스 코드를 포함하는 파일입니다. 스크립트는 Distutils가 매우 복잡한 작업을 수행하도록 요구하지는 않습니다. 유일한 영리한 기능은 스크립트의 첫 번째 줄이 `#!`로 시작하고 단어 “python”을 포함하면, Distutils가 첫 번째 줄을 조정하여 현재 인터프리터 위치를 참조하도록 만든다는 것입니다. 기본적으로, 현재 인터프리터 위치로 바뀝니다. `--executable` (또는 `-e`) 옵션을 사용하면 인터프리터 경로를 명시적으로 재정의할 수 있습니다.

`scripts` 옵션은 단순히 이런 방식으로 처리할 파일의 리스트입니다. PyXML 설정 스크립트에서:

    setup(...,
          scripts=['scripts/xmlproc_parse', 'scripts/xmlproc_val']
          )

버전 3.1에서 변경: 템플릿이 제공되지 않으면 모든 스크립트가 `MANIFEST` 파일에 추가됩니다. 배포할 파일 지정하기를 참조하십시오.

## 2.6. 패키지 데이터 설치하기

종종, 추가 파일을 패키지에 설치해야 합니다. 이러한 파일은 종종 패키지 구현과 밀접한 관련이 있는 데이터, 또는 패키지를 사용하는 프로그래머가 관심을 가질 설명서가 포함된 텍스트 파일입니다. 이러한 파일을 패키지 데이터(package data)라고 합니다.

`setup()` 함수에 `package_data` 키워드 인자를 사용하여 패키지 데이터를 패키지에 추가할 수 있습니다. 값은 패키지 이름에서 패키지로 복사해야 하는 상대 경로 이름의 리스트로의 매핑이어야 합니다. 경로는 패키지를 포함하는 디렉터리에 상대적으로 해석됩니다 (적절하면 `package_dir` 매핑의 정보가 사용됩니다); 즉, 파일은 소스 디렉터리에서 패키지 일부가 될 것으로 예상됩니다. glob 패턴도 포함할 수 있습니다.

경로 이름에는 디렉터리 부분이 포함될 수 있습니다; 모든 필요한 디렉터리가 설치 시에 만들어집니다.

예를 들어, 패키지에 여러 데이터 파일이 있는 서브 디렉터리가 있어야 하면, 소스 트리에서 다음과 같이 파일을 배열할 수 있습니다:

    setup.py
    src/
        mypkg/
            __init__.py
            module.py
            data/
                tables.dat
                spoons.dat
                forks.dat

`setup()`에 대한 해당 호출은 다음과 같습니다:

    setup(...,
          packages=['mypkg'],
          package_dir={'mypkg': 'src/mypkg'},
          package_data={'mypkg': ['data/*.dat']},
          )

버전 3.1에서 변경: 템플릿이 제공되지 않으면 `package_data`와 일치하는 모든 파일이 `MANIFEST` 파일에 추가됩니다. 배포할 파일 지정하기를 참조하십시오.

## 2.7. 추가 파일 설치하기

`data_files` 옵션은 모듈 배포에 필요한 추가 파일을 지정하는 데 사용할 수 있습니다: 구성 파일, 메시지 카탈로그, 데이터 파일, 이전 범주에 맞지 않는 모든 것.

`data_files`는 다음과 같은 방식으로 (directory, files) 쌍의 시퀀스를 지정합니다:

    setup(...,
          data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
                      ('config', ['cfg/data.cfg'])],
         )

시퀀스의 각 (directory, files) 쌍은 설치 디렉터리와 그곳에 설치할 파일을 지정합니다.

files의 각 파일 이름은 패키지 소스 배포의 맨 위에 있는 `setup.py` 스크립트에 상대적으로 해석됩니다. 데이터 파일이 설치될 디렉터리를 지정할 수 있지만 데이터 파일 자체의 이름을 바꿀 수는 없음에 유의하십시오.

directory는 상대 경로여야 합니다. 설치 접두사(시스템 설치의 경우 파이썬의 `sys.prefix`; 사용자 설치의 경우 `site.USER_BASE`)에 상대적으로 해석됩니다. Distutils는 directory에 절대 설치 경로를 허용하지만, 휠(wheel) 패키징 형식과 호환되지 않아서 권장하지 않습니다. 설치되는 파일의 최종 위치를 판별하기 위해 files의 디렉터리 정보가 사용되지 않습니다; 파일 이름 만 사용됩니다.

대상 디렉터리를 지정하지 않고 `data_files` 옵션을 간단한 files의 시퀀스로 지정할 수 있지만, 이 방법은 권장되지 않으며, 이 경우 install 명령은 경고를 인쇄합니다. 대상 디렉터리에 데이터 파일을 직접 설치하려면, directory에 빈 문자열을 지정해야 합니다.

버전 3.1에서 변경: 템플릿이 제공되지 않으면 `data_files`와 일치하는 모든 파일이 `MANIFEST` 파일에 추가됩니다. 배포할 파일 지정하기를 참조하십시오.

## 2.8. 추가 메타 데이터

설정 스크립트에는 이름과 버전 이외의 추가 메타 데이터가 포함될 수 있습니다. 이 정보에는 다음이 포함됩니다:

메타 데이터 | 설명 | 값 | 노트
--- | --- | --- | ---
`name` | 패키지 이름 | 짧은 문자열 | (1)
`version` | 이 릴리스의 버전 | 짧은 문자열 | (1)(2)
`author` | 패키지 저자의 이름 | 짧은 문자열 | (3)
`author_email` | 패키지 저자의 이메일 주소 | 이메일 주소 | (3)
`maintainer` | 패키지 관리자의 이름 | 짧은 문자열 | (3)
`maintainer_email` | 패키지 관리자의 이메일 주소 | 이메일 주소 | (3)
`url` | 패키지 홈페이지 | URL | (1)
`description` | 패키지에 대한 짧은 요약 설명 | 짧은 문자열 |
`long_description` | 패키지에 대한 자세한 설명 | 긴 문자열 | (4)
`download_url` | 패키지를 다운로드할 수 있는 위치 | URL |
`classifiers` | 범주 목록 | 문자열의 리스트 | (6)(7)
`platforms` | 플랫폼 목록 | 문자열의 리스트 | (6)(8)
`keywords` | 키워드의 리스트 | 문자열의 리스트 | (6)(8)
`license` | 패키지 라이선스 | 짧은 문자열 | (5)

노트:

1. 이 필드는 필수입니다.

2. 버전은 major.minor[.patch[.sub]] 형식을 사용하는 것이 좋습니다.

3. author나 maintainer를 식별해야 합니다. maintainer가 제공되면, distutils는 이를 `PKG-INFO`에 저자로 나열합니다.

4. `long_description` 필드는 패키지를 게시할 때 PyPI에서 프로젝트 페이지를 빌드하는 데 사용됩니다.

5. `license` 필드는 라이선스가 “License” Trove 분류에서 선택되지 않았을 때 패키지에 대한 라이선스를 나타내는 텍스트입니다. `Classifier` 필드를 참조하십시오. 폐지되었지만 여전히 `license`의 별칭으로 작동하는 `licence` 배포 옵션이 있음에 유의하십시오.

6. 이 필드는 리스트여야 합니다.

7. 유효한 분류자는 PyPI에 나열되어 있습니다.

8. 이전 버전과의 호환성을 유지하기 위해, 이 필드는 문자열도 허용합니다. 쉼표로 구분된 문자열 `'foo, bar'`를 전달하면, `['foo', 'bar']`로 변환되고, 그렇지 않으면, 하나의 문자열 리스트로 변환됩니다.

‘짧은 문자열’

  한 줄의 텍스트, 200자 이하.

‘긴 문자열’

  reStructuredText 형식의 여러 줄 단순 텍스트 (http://docutils.sourceforge.net/ 을 참조하십시오).

‘문자열의 리스트’

  아래를 참조하십시오.

버전 정보를 인코딩하는 것은 그 자체로 기술입니다. 파이썬 패키지는 일반적으로 major.minor[.patch][sub] 버전 형식을 따릅니다. 소프트웨어의 초기 실험 릴리스의 major 번호는 0입니다. 패키지의 주요 이정표를 나타내는 릴리스마다 증가합니다. 중요한 새로운 기능이 패키지에 추가되면 minor 번호가 증가합니다. 버그 수정이 릴리스 되면 patch 번호가 증가합니다. 서브 릴리스를 나타내는 데 추가 후행 버전 정보가 사용되기도 합니다. 이것들은 “a1,a2,…,aN” (기능과 API가 변경될 수 있는 알파 릴리스의 경우), “b1,b2,…,bN” (버그만 수정하는 베타 릴리스의 경우) 및 “pr1,pr2,…,prN” (최종 사전 릴리스 테스트 용) 입니다. 몇 가지 예:

0.1.0

  패키지의 첫 번째 실험 릴리스

1.0.1a2

  1.0의 첫 번째 패치 버전의 두 번째 알파 릴리스

`classifiers`는 리스트로 지정해야 합니다:

    setup(...,
          classifiers=[
              'Development Status :: 4 - Beta',
              'Environment :: Console',
              'Environment :: Web Environment',
              'Intended Audience :: End Users/Desktop',
              'Intended Audience :: Developers',
              'Intended Audience :: System Administrators',
              'License :: OSI Approved :: Python Software Foundation License',
              'Operating System :: MacOS :: MacOS X',
              'Operating System :: Microsoft :: Windows',
              'Operating System :: POSIX',
              'Programming Language :: Python',
              'Topic :: Communications :: Email',
              'Topic :: Office/Business',
              'Topic :: Software Development :: Bug Tracking',
              ],
          )

버전 3.7에서 변경: `setup`은 이제 `classifiers`, `keywords` 또는 `platforms` 필드가 리스트나 문자열로 지정되지 않으면 경고합니다.

## 2.9. 설정 스크립트 디버깅하기

때때로 문제가 발생하고, 설치 스크립트가 개발자가 원하는 것을 수행하지 않습니다.

Distutils는 설정 스크립트를 실행할 때 모든 예외를 포착하고, 스크립트가 종료되기 전에 간단한 에러 메시지를 인쇄합니다. 이 동작의 동기는 파이썬에 대해 잘 모르고 패키지를 설치하려는 관리자를 혼동하지 않도록 하는 것입니다. Distutils의 내부로부터의 크고 긴 트레이스백을 얻으면, 끝까지 읽어서 권한 문제라는 것을 알아차리지 못하고 패키지나 파이썬 설치가 손상되었다고 생각할 수 있습니다.

반면에, 이것은 개발자가 실패의 원인을 찾는 데 도움이 되지 않습니다. 이를 위해, `DISTUTILS_DEBUG` 환경 변수를 빈 문자열 이외의 것으로 설정할 수 있으며, distutils는 현재 수행 중인 작업에 대한 자세한 정보를 인쇄하고, 예외가 발생하면 전체 트레이스백을 덤프하며, 외부 프로그램(C 컴파일러와 같은)이 실패할 때 전체 명령 줄을 인쇄합니다.