venv — 가상 환경 만들기

venv — 가상 환경 만들기

venv 모듈은 각각 자체 site 디렉터리에 독립적인 Python 패키지 집합을 가진 "가상 환경(virtual environment)"을 가볍게 만들 수 있게 해 줘요. 가상 환경은 기존 Python 설치(가상 환경의 "베이스" Python) 위에 만들어지며, 기본적으로 베이스 환경의 패키지로부터 격리됩니다.

출처: Python 표준 라이브러리

버전 3.3에서 추가. / 사용 가능 환경: Android 아님, iOS 아님, WASI 아님.

본문

venv 모듈은 각자 자신의 site 디렉터리에 독립적인 Python 패키지 집합이 설치되는 가벼운 "가상 환경"을 만들 수 있게 해 줍니다. 가상 환경은 기존 Python 설치(가상 환경의 "베이스" Python) 위에 만들어지며, 기본적으로 베이스 환경의 패키지로부터 격리되어 가상 환경에 명시적으로 설치된 패키지만 사용할 수 있어요. 자세한 내용은 Virtual Environments와 site의 가상 환경 문서를 참고하세요.

가상 환경 안에서 쓰면 pip 같은 일반적인 설치 도구는 명시적으로 알려주지 않아도 Python 패키지를 가상 환경에 설치합니다.

가상 환경은 (다른 것들 중에서도) 다음과 같은 특성을 가져요.

  • 프로젝트(라이브러리나 애플리케이션)를 지원하는 데 필요한 특정 Python 인터프리터와 소프트웨어 라이브러리·바이너리를 담는 용도로 씁니다. 기본적으로 이들은 다른 가상 환경의 소프트웨어와 운영체제에 설치된 Python 인터프리터·라이브러리로부터 격리돼요.
  • 디렉터리에 담기며, 관례상 프로젝트 디렉터리의 .venvvenv, 또는 많은 가상 환경을 위한 컨테이너 디렉터리(예: ~/.virtualenvs) 아래에 위치합니다.
  • Git 같은 소스 제어 시스템에 커밋하지 않습니다.
  • 일회용(disposable)으로 간주합니다 — 처음부터 삭제하고 다시 만드는 것이 간단해야 해요. 환경에 프로젝트 코드를 두지 않습니다.
  • 이동·복사 가능한 것으로 간주하지 않습니다 — 대상 위치에 같은 환경을 그냥 다시 만들면 됩니다.

Python 가상 환경에 대한 배경 지식은 PEP 405를 참고하세요.

가상 환경 만들기 (Creating virtual environments)

가상 환경은 venv 모듈을 실행해 만듭니다.

python -m venv /path/to/new/virtual/environment

이 명령은 대상 디렉터리(필요한 상위 디렉터리 포함)를 만들고, 그 안에 명령이 실행된 Python 설치를 가리키는 home 키가 있는 pyvenv.cfg 파일을 배치합니다. 또한 Python 실행 파일의 복사본이나 심볼릭 링크를 담은 bin(Windows에선 Scripts) 하위 디렉터리도 만들고(플랫폼 또는 환경 생성 시 사용된 인자에 따라 적절히), lib/pythonX.Y/site-packages 하위 디렉터리도 만들어요 (Windows에선 Lib\site-packages). 기존 디렉터리를 지정하면 재사용됩니다.

버전 3.5에서 변경: 가상 환경을 만들 때 venv 사용이 권장됩니다. 버전 3.6부터 비추천, 3.8에서 제거: pyvenv는 Python 3.3·3.4의 가상 환경 생성 권장 도구였고, 3.5에서 venv를 직접 실행하는 방식으로 대체되었습니다.

Windows에서는 venv 명령을 다음과 같이 호출해요.

PS> python -m venv C:\path\to\new\virtual\environment

이 명령을 -h와 함께 실행하면 사용 가능한 옵션을 보여 줍니다.

usage: venv [-h] [--system-site-packages] [--symlinks | --copies] [--clear]
            [--upgrade] [--without-pip] [--prompt PROMPT] [--upgrade-deps]
            [--without-scm-ignore-files]
            ENV_DIR [ENV_DIR ...]

Creates virtual Python environments in one or more target directories.

Once an environment has been created, you may wish to activate it, e.g. by
sourcing an activate script in its bin directory.
  • ENV_DIR — 필수 인자. 환경을 만들 디렉터리를 지정합니다.
  • --system-site-packages — 가상 환경에 시스템 site-packages 디렉터리 접근을 허용합니다.
  • --symlinks — 심볼릭 링크가 플랫폼 기본값이 아닐 때, 복사 대신 심볼릭 링크를 사용하려 시도합니다.
  • --copies — 심볼릭 링크가 플랫폼 기본값일 때도, 심볼릭 링크 대신 복사를 사용하려 시도합니다.
  • --clear — 환경 디렉터리가 이미 존재하면, 환경 생성 전에 그 내용을 삭제합니다.
  • --upgrade — Python이 제자리에서 업그레이드되었다고 가정하고, 환경 디렉터리를 이 Python 버전을 쓰도록 업그레이드합니다.
  • --without-pip — 가상 환경에서 pip 설치·업그레이드를 건너뜁니다 (pip는 기본적으로 부트스트랩됩니다).
  • --prompt <PROMPT> — 이 환경의 대체 프롬프트 접두어를 제공합니다.
  • --upgrade-deps — 핵심 의존성(pip)을 PyPI의 최신 버전으로 업그레이드합니다.
  • --without-scm-ignore-files — 환경 디렉터리에 SCM ignore 파일 추가를 건너뜁니다 (Git이 기본 지원됩니다).

버전 3.4에서 변경: 기본적으로 pip를 설치하고, --without-pip--copies 옵션을 추가했습니다. 버전 3.4에서 변경: 이전 버전에서는 --clear 또는 --upgrade 옵션을 제공하지 않으면 대상 디렉터리가 이미 존재할 때 오류가 발생했습니다. 버전 3.9에서 변경: pip + setuptools를 PyPI의 최신으로 업그레이드하는 --upgrade-deps 옵션 추가. 버전 3.12에서 변경: setuptools는 더 이상 핵심 venv 의존성이 아닙니다. 버전 3.13에서 변경: --without-scm-ignore-files 옵션 추가. 버전 3.13에서 변경: venv가 기본적으로 Git용 .gitignore 파일을 만듭니다.

참고 — Windows에서도 심볼릭 링크는 지원되지만 권장하지 않아요. 특히 파일 탐색기에서 python.exe를 더블클릭하면 심볼릭 링크가 즉시 해석(resolve)되어 가상 환경을 무시합니다.

참고 — Microsoft Windows에서는 사용자에 대한 실행 정책을 설정해 Activate.ps1 스크립트를 활성화해야 할 수 있어요. 다음 PowerShell 명령으로 할 수 있습니다.

PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

자세한 내용은 About Execution Policies를 참고하세요.

생성된 pyvenv.cfg 파일은 --system-site-packages 옵션으로 venv를 실행하면 true로, 아니면 false로 설정되는 include-system-site-packages 키도 포함해요.

--without-pip 옵션을 주지 않으면 ensurepip가 호출되어 가상 환경에 pip를 부트스트랩합니다.

venv에는 여러 경로를 줄 수 있는데, 그 경우 주어진 옵션에 따라 각 경로에 동일한 가상 환경이 만들어집니다.

venv의 동작 방식 (How venvs work)

Python 인터프리터가 가상 환경에서 실행되고 있으면 sys.prefixsys.exec_prefix는 가상 환경의 디렉터리를, sys.base_prefixsys.base_exec_prefix는 환경을 만드는 데 사용된 베이스 Python의 디렉터리를 가리켜요. 현재 인터프리터가 가상 환경에서 실행 중인지 확인하려면 sys.prefix != sys.base_prefix를 검사하는 것으로 충분합니다.

가상 환경은 바이너리 디렉터리(POSIX의 bin, Windows의 Scripts)의 스크립트로 "활성화(activate)"할 수 있어요. 그러면 그 디렉터리가 PATH 앞에 붙어, python을 실행하면 환경의 Python 인터프리터가 호출되고 전체 경로를 쓰지 않고도 설치된 스크립트를 실행할 수 있습니다. 활성화 스크립트 호출은 플랫폼별입니다 (<venv>는 가상 환경이 담긴 디렉터리 경로로 바꿔야 해요).

플랫폼 가상 환경 활성화 명령
POSIX bash/zsh $ source <venv>/bin/activate
fish $ source <venv>/bin/activate.fish
csh/tcsh $ source <venv>/bin/activate.csh
pwsh $ <venv>/bin/Activate.ps1
Windows cmd.exe C:\> <venv>\Scripts\activate.bat
PowerShell PS C:\> <venv>\Scripts\Activate.ps1

버전 3.4에서 추가: fish와 csh 활성화 스크립트. 버전 3.8에서 추가: PowerShell Core 지원을 위해 POSIX에 설치되는 PowerShell 활성화 스크립트.

가상 환경을 반드시 활성화할 필요는 없어요. Python을 호출할 때 그 환경의 Python 인터프리터 전체 경로를 지정하면 되니까요. 또한 환경에 설치된 모든 스크립트는 활성화 없이도 실행 가능해야 합니다.

이를 위해 가상 환경에 설치된 스크립트에는 환경의 Python 인터프리터를 가리키는 "shebang" 줄, 즉 #!/<path-to-venv>/bin/python이 있어요. 그래서 PATH 값과 무관하게 그 인터프리터로 스크립트가 실행됩니다. Windows에서는 Python install manager가 설치되어 있으면 "shebang" 줄 처리가 지원됩니다. 따라서 Windows 탐색기 창에서 설치된 스크립트를 더블클릭하면 환경을 활성화하거나 PATH에 넣지 않아도 올바른 인터프리터로 실행돼요.

가상 환경이 활성화되면 VIRTUAL_ENV 환경 변수가 환경의 경로로 설정됩니다. 가상 환경을 사용하는 데 명시적 활성화가 필요하지 않으므로, VIRTUAL_ENV를 가상 환경 사용 여부 판단에 의존할 수 없습니다.

경고 — 환경에 설치된 스크립트는 환경이 활성화되어 있을 것을 기대하면 안 되므로, 그 shebang 줄은 환경 인터프리터의 절대 경로를 담습니다. 이 때문에 환경은 일반적인 경우 본질적으로 이식 불가능해요. 항상 환경을 다시 만드는 간단한 수단을 마련해 두어야 합니다 (예: requirements.txt가 있으면 환경의 pip로 pip install -r requirements.txt를 호출해 환경이 필요한 모든 패키지를 설치할 수 있어요). 어떤 이유로든 환경을 새 위치로 옮겨야 한다면, 원하는 위치에 다시 만들고 옛 위치의 것은 삭제하세요. 부모 디렉터리를 옮겨 환경을 옮겼다면, 새 위치에서 환경을 다시 만들어야 해요. 그렇지 않으면 환경에 설치된 소프트웨어가 예상대로 동작하지 않을 수 있습니다.

가상 환경은 셸에 deactivate를 입력해 비활성화할 수 있어요. 정확한 메커니즘은 플랫폼별이며 내부 구현 세부 사항입니다 (보통 스크립트나 셸 함수가 사용됩니다).

API

위에서 설명한 고수준 메서드는, 제3자 가상 환경 생성자가 자신의 필요에 따라 환경 생성을 커스터마이즈할 수 있는 메커니즘을 제공하는 간단한 API, 즉 EnvBuilder 클래스를 사용합니다.

class venv.EnvBuilder(system_site_packages=False, clear=False, symlinks=False, upgrade=False, with_pip=False, prompt=None, upgrade_deps=False, *, scm_ignore_files=frozenset())

EnvBuilder 클래스는 인스턴스화 시 다음 키워드 인자를 받습니다.

  • system_site_packages — 시스템 Python site-packages가 환경에서 사용 가능해야 하는지를 나타내는 불리언 (기본 False).
  • clear — 참이면 환경을 만들기 전에 기존 대상 디렉터리의 내용을 삭제하는 불리언.
  • symlinks — 복사 대신 Python 바이너리를 심볼릭 링크하려 시도할지 나타내는 불리언.
  • upgrade — 참이면 실행 중인 Python으로 기존 환경을 업그레이드하는 불리언 — 그 Python이 제자리에서 업그레이드된 경우에 씁니다 (기본 False).
  • with_pip — 참이면 가상 환경에 pip가 설치되도록 보장하는 불리언. --default-pip 옵션으로 ensurepip를 사용해요.
  • prompt — 가상 환경이 활성화된 후 사용할 문자열 (기본 None — 환경의 디렉터리 이름이 사용됨). 특수 문자열 "."를 주면 현재 디렉터리의 basename이 프롬프트로 사용됩니다.
  • upgrade_deps — 기본 venv 모듈을 PyPI의 최신으로 갱신.
  • scm_ignore_files — 반복 가능한 객체 안의 지정된 소스 제어 관리자(SCM)에 대한 ignore 파일을 만듭니다. 지원은 create_{scm}_ignore_file이라는 메서드가 있는지로 정의됩니다. 기본적으로 지원하는 유일한 값은 create_git_ignore_file()을 통한 "git"입니다.

버전 3.4에서 변경: with_pip 매개변수 추가. 버전 3.6에서 변경: prompt 매개변수 추가. 버전 3.9에서 변경: upgrade_deps 매개변수 추가. 버전 3.13에서 변경: scm_ignore_files 매개변수 추가.

EnvBuilder는 기본 클래스로 사용될 수 있습니다.

create(env_dir)

가상 환경을 담을 대상 디렉터리(현재 디렉터리에 대한 절대 또는 상대)를 지정해 가상 환경을 만듭니다. create 메서드는 지정한 디렉터리에 환경을 만들거나 적절한 예외를 일으킵니다.

EnvBuilder 클래스의 create 메서드는 하위 클래스 커스터마이즈에 사용할 수 있는 훅을 보여 줍니다.

def create(self, env_dir):
    """
    Create a virtualized Python environment in a directory.
    env_dir is the target directory to create an environment in.
    """
    env_dir = os.path.abspath(env_dir)
    context = self.ensure_directories(env_dir)
    self.create_configuration(context)
    self.setup_python(context)
    self.setup_scripts(context)
    self.post_setup(context)

ensure_directories(), create_configuration(), setup_python(), setup_scripts(), post_setup() 각각은 오버라이드할 수 있어요.

ensure_directories(env_dir)

아직 존재하지 않는 환경 디렉터리와 필요한 모든 하위 디렉터리를 만들고 컨텍스트 객체를 반환합니다. 이 컨텍스트 객체는 다른 메서드들이 쓰는 속성(경로 등)을 담는 홀더일 뿐이에요. EnvBuilderclear=True로 만들면 환경 디렉터리 내용이 비워진 뒤 필요한 하위 디렉터리가 다시 만들어집니다.

반환된 컨텍스트 객체는 다음 속성을 가진 types.SimpleNamespace입니다.

  • env_dir — 가상 환경의 위치. 활성화 스크립트의 __VENV_DIR__에 사용 (install_scripts() 참고).
  • env_name — 가상 환경의 이름. 활성화 스크립트의 __VENV_NAME__에 사용.
  • prompt — 활성화 스크립트가 사용할 프롬프트. __VENV_PROMPT__에 사용.
  • executable — 가상 환경이 사용하는 기본 Python 실행 파일. 다른 가상 환경에서 가상 환경을 만들 때를 고려합니다.
  • inc_path — 가상 환경의 include 경로.
  • lib_path — 가상 환경의 purelib 경로.
  • bin_path — 가상 환경의 스크립트 경로.
  • bin_name — 가상 환경 위치 기준 스크립트 경로의 이름. 활성화 스크립트의 __VENV_BIN_NAME__에 사용.
  • env_exe — 가상 환경의 Python 인터프리터 이름. __VENV_PYTHON__에 사용.
  • env_exec_cmd — 파일시스템 리다이렉션을 고려한 Python 인터프리터 이름. 가상 환경에서 Python을 실행하는 데 쓸 수 있어요.

버전 3.11에서 변경: 생성된 디렉터리 경로를 구성할 때 venv sysconfig 설치 스킴을 사용합니다. 버전 3.12에서 변경: 컨텍스트에 lib_path 속성이 추가되고 컨텍스트 객체가 문서화되었습니다.

create_configuration(context)

환경에 pyvenv.cfg 구성 파일을 만듭니다.

setup_python(context)

환경에 Python 실행 파일의 복사본이나 심볼릭 링크를 만듭니다. POSIX 시스템에서 특정 실행 파일 python3.x를 사용했다면, 같은 이름의 파일이 이미 없을 때 그 실행 파일을 가리키는 pythonpython3 심볼릭 링크가 만들어져요.

setup_scripts(context)

플랫폼에 적합한 활성화 스크립트를 가상 환경에 설치합니다.

upgrade_dependencies(context)

환경의 핵심 venv 의존성 패키지(현재는 pip)를 업그레이드합니다. 환경 안의 pip 실행 파일을 호출하는 방식으로 수행됩니다. (버전 3.9에서 추가 / 버전 3.12에서 변경: setuptools는 더 이상 핵심 venv 의존성이 아닙니다)

post_setup(context)

제3자 구현에서 가상 환경에 패키지를 미리 설치하거나 생성 후 단계를 수행하기 위해 오버라이드할 수 있는 자리 표시자 메서드입니다.

install_scripts(context, path)

이 메서드는 하위 클래스의 setup_scripts()post_setup()에서 호출해 가상 환경에 커스텀 스크립트를 설치하는 데 도움을 줄 수 있습니다. pathcommon, posix, nt 하위 디렉터리를 담아야 하는 디렉터리의 경로이며, 각각 환경의 bin 디렉터리로 향하는 스크립트를 담습니다. commonos.name에 해당하는 디렉터리의 내용은 플레이스홀더의 텍스트 치환 후 복사됩니다.

  • __VENV_DIR__ — 환경 디렉터리의 절대 경로로 대체됨.
  • __VENV_NAME__ — 환경 이름(환경 디렉터리의 마지막 경로 세그먼트)으로 대체됨.
  • __VENV_PROMPT__ — 프롬프트(환경 이름을 괄호로 감싸고 뒤에 공백)로 대체됨.
  • __VENV_BIN_NAME__bin 디렉터리의 이름(bin 또는 Scripts)으로 대체됨.
  • __VENV_PYTHON__ — 환경 실행 파일의 절대 경로로 대체됨.

디렉터리는 (기존 환경을 업그레이드하는 경우) 이미 존재할 수 있습니다.

create_git_ignore_file(context)

가상 환경 안에, 전체 디렉터리가 Git 소스 제어 관리자에 무시되게 하는 .gitignore 파일을 만듭니다. (버전 3.13에서 추가)

버전 3.7.2에서 변경: Windows가 실제 바이너리를 복사하는 대신 python[w].exe용 리다이렉터 스크립트를 사용합니다. 3.7.2에서 setup_python()은 소스 트리의 빌드에서 실행하지 않는 한 아무것도 하지 않습니다. 버전 3.7.3에서 변경: Windows가 setup_scripts() 대신 setup_python()의 일부로 리다이렉터 스크립트를 복사합니다. 3.7.2에서는 그렇지 않았어요. 심볼릭 링크를 쓸 때는 원본 실행 파일이 연결됩니다.

모듈 수준의 편의 함수도 있어요.

venv.create(env_dir, system_site_packages=False, clear=False, symlinks=False, with_pip=False, prompt=None, upgrade_deps=False, *, scm_ignore_files=frozenset())

주어진 키워드 인자로 EnvBuilder를 만들고 env_dir 인자로 그 create() 메서드를 호출합니다.

버전 3.3에서 추가. / 버전 3.4에서 변경: with_pip 매개변수 추가. / 버전 3.6에서 변경: prompt 매개변수 추가. / 버전 3.9에서 변경: upgrade_deps 매개변수 추가. / 버전 3.13에서 변경: scm_ignore_files 매개변수 추가.

EnvBuilder 확장 예제 (An example of extending EnvBuilder)

다음 스크립트는 만들어진 가상 환경에 setuptools와 pip를 설치하는 하위 클래스를 구현해 EnvBuilder를 확장하는 방법을 보여 줍니다.

import os
import os.path
from subprocess import Popen, PIPE
import sys
from threading import Thread
from urllib.parse import urlsplit
from urllib.request import urlretrieve
import venv

class ExtendedEnvBuilder(venv.EnvBuilder):
    """
    This builder installs setuptools and pip so that you can pip or
    easy_install other packages into the created virtual environment.

    :param nodist: If true, setuptools and pip are not installed into the
                   created virtual environment.
    :param nopip: If true, pip is not installed into the created
                  virtual environment.
    :param progress: If setuptools or pip are installed, the progress of the
                     installation can be monitored by passing a progress
                     callable. If specified, it is called with two
                     arguments: a string indicating some progress, and a
                     context indicating where the string is coming from.
                     The context argument can have one of three values:
                     'main', indicating that it is called from virtualize()
                     itself, and 'stdout' and 'stderr', which are obtained
                     by reading lines from the output streams of a subprocess
                     which is used to install the app.

                     If a callable is not specified, default progress
                     information is output to sys.stderr.
    """

    def __init__(self, *args, **kwargs):
        self.nodist = kwargs.pop('nodist', False)
        self.nopip = kwargs.pop('nopip', False)
        self.progress = kwargs.pop('progress', None)
        self.verbose = kwargs.pop('verbose', False)
        super().__init__(*args, **kwargs)

    def post_setup(self, context):
        """
        Set up any packages which need to be pre-installed into the
        virtual environment being created.

        :param context: The information for the virtual environment
                        creation request being processed.
        """
        os.environ['VIRTUAL_ENV'] = context.env_dir
        if not self.nodist:
            self.install_setuptools(context)
        # Can't install pip without setuptools
        if not self.nopip and not self.nodist:
            self.install_pip(context)

    def reader(self, stream, context):
        """
        Read lines from a subprocess' output stream and either pass to a progress
        callable (if specified) or write progress information to sys.stderr.
        """
        progress = self.progress
        while True:
            s = stream.readline()
            if not s:
                break
            if progress is not None:
                progress(s, context)
            else:
                if not self.verbose:
                    sys.stderr.write('.')
                else:
                    sys.stderr.write(s.decode('utf-8'))
                sys.stderr.flush()
        stream.close()

    def install_script(self, context, name, url):
        _, _, path, _, _ = urlsplit(url)
        fn = os.path.split(path)[-1]
        binpath = context.bin_path
        distpath = os.path.join(binpath, fn)
        # Download script into the virtual environment's binaries folder
        urlretrieve(url, distpath)
        progress = self.progress
        if self.verbose:
            term = '\n'
        else:
            term = ''
        if progress is not None:
            progress('Installing %s ...%s' % (name, term), 'main')
        else:
            sys.stderr.write('Installing %s ...%s' % (name, term))
            sys.stderr.flush()
        # Install in the virtual environment
        args = [context.env_exe, fn]
        p = Popen(args, stdout=PIPE, stderr=PIPE, cwd=binpath)
        t1 = Thread(target=self.reader, args=(p.stdout, 'stdout'))
        t1.start()
        t2 = Thread(target=self.reader, args=(p.stderr, 'stderr'))
        t2.start()
        p.wait()
        t1.join()
        t2.join()
        if progress is not None:
            progress('done.', 'main')
        else:
            sys.stderr.write('done.\n')
        # Clean up - no longer needed
        os.unlink(distpath)

    def install_setuptools(self, context):
        """
        Install setuptools in the virtual environment.

        :param context: The information for the virtual environment
                        creation request being processed.
        """
        url = "https://bootstrap.pypa.io/ez_setup.py"
        self.install_script(context, 'setuptools', url)
        # clear up the setuptools archive which gets downloaded
        pred = lambda o: o.startswith('setuptools-') and o.endswith('.tar.gz')
        files = filter(pred, os.listdir(context.bin_path))
        for f in files:
            f = os.path.join(context.bin_path, f)
            os.unlink(f)

    def install_pip(self, context):
        """
        Install pip in the virtual environment.

        :param context: The information for the virtual environment
                        creation request being processed.
        """
        url = 'https://bootstrap.pypa.io/get-pip.py'
        self.install_script(context, 'pip', url)


def main(args=None):
    import argparse

    parser = argparse.ArgumentParser(prog=__name__,
                                     description='Creates virtual Python '
                                                 'environments in one or '
                                                 'more target '
                                                 'directories.')
    parser.add_argument('dirs', metavar='ENV_DIR', nargs='+',
                        help='A directory in which to create the '
                             'virtual environment.')
    parser.add_argument('--no-setuptools', default=False,
                        action='store_true', dest='nodist',
                        help="Don't install setuptools or pip in the "
                             "virtual environment.")
    parser.add_argument('--no-pip', default=False,
                        action='store_true', dest='nopip',
                        help="Don't install pip in the virtual "
                             "environment.")
    parser.add_argument('--system-site-packages', default=False,
                        action='store_true', dest='system_site',
                        help='Give the virtual environment access to the '
                             'system site-packages dir.')
    if os.name == 'nt':
        use_symlinks = False
    else:
        use_symlinks = True
    parser.add_argument('--symlinks', default=use_symlinks,
                        action='store_true', dest='symlinks',
                        help='Try to use symlinks rather than copies, '
                             'when symlinks are not the default for '
                             'the platform.')
    parser.add_argument('--clear', default=False, action='store_true',
                        dest='clear', help='Delete the contents of the '
                                           'virtual environment '
                                           'directory if it already '
                                           'exists, before virtual '
                                           'environment creation.')
    parser.add_argument('--upgrade', default=False, action='store_true',
                        dest='upgrade', help='Upgrade the virtual '
                                             'environment directory to '
                                             'use this version of '
                                             'Python, assuming Python '
                                             'has been upgraded '
                                             'in-place.')
    parser.add_argument('--verbose', default=False, action='store_true',
                        dest='verbose', help='Display the output '
                                             'from the scripts which '
                                             'install setuptools and pip.')
    options = parser.parse_args(args)
    if options.upgrade and options.clear:
        raise ValueError('you cannot supply --upgrade and --clear together.')
    builder = ExtendedEnvBuilder(system_site_packages=options.system_site,
                                   clear=options.clear,
                                   symlinks=options.symlinks,
                                   upgrade=options.upgrade,
                                   nodist=options.nodist,
                                   nopip=options.nopip,
                                   verbose=options.verbose)
    for d in options.dirs:
        builder.create(d)

if __name__ == '__main__':
    rc = 1
    try:
        main()
        rc = 0
    except Exception as e:
        print('Error: %s' % e, file=sys.stderr)
    sys.exit(rc)

이 스크립트는 온라인에서도 다운로드할 수 있습니다.