venv — Skapande av virtuella miljöer

Tillagd i version 3.3.

Källkod: Lib/venv/


Modulen venv stöder skapandet av lättviktiga ”virtuella miljöer”, var och en med sin egen oberoende uppsättning Python-paket installerade i sina site-kataloger. En virtuell miljö skapas ovanpå en befintlig Python-installation, känd som den virtuella miljöns ”bas”-Python, och är som standard isolerad från paketen i basmiljön, så att endast de som uttryckligen har installerats i den virtuella miljön är tillgängliga. Se Virtuella miljöer och site:s virtual environments documentation för mer information.

När de används i en virtuell miljö kommer vanliga installationsverktyg som pip att installera Python-paket i en virtuell miljö utan att du uttryckligen behöver be dem att göra det.

En virtuell miljö är (bland annat):

  • Används för att innehålla en specifik Python-tolk och programvarubibliotek och binärfiler som behövs för att stödja ett projekt (bibliotek eller applikation). Dessa är som standard isolerade från programvara i andra virtuella miljöer och Python-tolkar och -bibliotek som är installerade i operativsystemet.

  • Innehålls i en katalog som vanligtvis heter .venv eller venv i projektkatalogen eller under en behållarkatalog för många virtuella miljöer, t.ex. ~/.virtualenvs.

  • Inte checkat in i källkontrollsystem som Git.

  • Betraktas som engångsbruk - det ska vara enkelt att ta bort och återskapa den från grunden. Du placerar inte någon projektkod i miljön.

  • Betraktas inte som flyttbar eller kopierbar - man återskapar bara samma miljö på målplatsen.

Se PEP 405 för mer bakgrund om virtuella Python-miljöer.

Tillgänglighet: not Android, not iOS, not WASI.

Denna modul stöds inte på mobile platforms eller WebAssembly platforms.

Skapa virtuella miljöer

Virtuella miljöer skapas genom att köra modulen venv:

python -m venv /stig/till/ny/virtuell/miljö

Detta skapar målkatalogen (inklusive överordnade kataloger efter behov) och placerar en pyvenv.cfg-fil i den med en home-nyckel som pekar på den Python-installation från vilken kommandot kördes. Det skapar också en bin (eller Scripts i Windows) underkatalog som innehåller en kopia eller symlänk av den körbara Python-filen (beroende på vilken plattform eller vilka argument som användes när miljön skapades). Den skapar också en lib/pythonX.Y/site-packages-underkatalog (i Windows är detta Libsite-packages). Om en befintlig katalog anges kommer den att återanvändas.

Ändrad i version 3.5: Användningen av venv rekommenderas nu för att skapa virtuella miljöer.

Deprecated since version 3.6, removed in version 3.8: pyvenv var det rekommenderade verktyget för att skapa virtuella miljöer för Python 3.3 och 3.4, och ersattes i 3.5 av att venv körs direkt.

I Windows anropar du kommandot venv på följande sätt:

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

Kommandot, om det körs med -h, kommer att visa de tillgängliga alternativen:

användning: venv [-h] [--system-site-packages] [--symlänkar | --kopior] [--clear]
            [--upgrade] [--without-pip] [--prompt PROMPT] [--upgrade-deps]
            [--without-scm-ignore-files]
            ENV_DIR [ENV_DIR ...]

Skapar virtuella Python-miljöer i en eller flera målkataloger.

När en miljö har skapats kanske du vill aktivera den, t.ex. genom att hämta ett
ett activate-skript i dess bin-katalog.
ENV_DIR

Ett obligatoriskt argument som anger den katalog där miljön ska skapas.

--system-site-packages

Ge den virtuella miljön tillgång till systemkatalogen site-packages.

Försök att använda symlänkar i stället för kopior, när symlänkar inte är standard för plattformen.

--copies

Försök att använda kopior i stället för symlänkar, även om symlänkar är standard för plattformen.

--clear

Ta bort innehållet i miljökatalogen om den redan finns, innan miljön skapas.

--upgrade

Uppgradera miljökatalogen så att den använder den här versionen av Python, förutsatt att Python har uppgraderats på plats.

--without-pip

Skippar installation eller uppgradering av pip i den virtuella miljön (pip startas som standard).

--prompt <PROMPT>

Ger ett alternativt promptprefix för denna miljö.

--upgrade-deps

Uppgradera kärnberoenden (pip) till den senaste versionen i PyPI.

--without-scm-ignore-files

Skippar att lägga till SCM ignore-filer i miljökatalogen (Git stöds som standard).

Ändrad i version 3.4: Installerar pip som standard, lade till alternativen --without-pip och --copies.

Ändrad i version 3.4: I tidigare versioner gavs ett felmeddelande ut om målkatalogen redan fanns, såvida inte alternativet --clear eller --upgrade hade angetts.

Ändrad i version 3.9: Lägg till --upgrade-deps alternativ för att uppgradera pip + setuptools till det senaste på PyPI.

Ändrad i version 3.12: setuptools är inte längre ett centralt venv-beroende.

Ändrad i version 3.13: Lagt till alternativet --without-scm-ignore-files.

Ändrad i version 3.13: venv skapar nu en .gitignore-fil för Git som standard.

Anteckning

Även om symlinks stöds i Windows rekommenderas de inte. Särskilt värt att notera är att om du dubbelklickar på python.exe i File Explorer kommer symbollänken att lösas ivrigt och ignorera den virtuella miljön.

Anteckning

I Microsoft Windows kan det vara nödvändigt att aktivera skriptet Activate.ps1 genom att ange exekveringsprincipen för användaren. Du kan göra detta genom att utfärda följande PowerShell-kommando:

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

Se Om exekveringsprinciper” för mer information.

Den skapade filen pyvenv.cfg innehåller även nyckeln include-system-site-packages, som sätts till true om venv körs med alternativet --system-site-packages, annars false.

Om inte alternativet --without-pip anges, kommer ensurepip` att anropas för att starta upp pip i den virtuella miljön.

Flera sökvägar kan anges för venv, i vilket fall en identisk virtuell miljö kommer att skapas, i enlighet med de angivna alternativen, på varje angiven sökväg.

Hur venv fungerar

När en Python-tolk körs från en virtuell miljö pekar sys.prefix och sys.exec_prefix på katalogerna i den virtuella miljön, medan sys.base_prefix och sys.base_exec_prefix pekar på katalogerna i den bas-Python som användes för att skapa miljön. Det räcker att kontrollera sys.prefix != sys.base_prefix för att avgöra om den aktuella tolken körs från en virtuell miljö.

En virtuell miljö kan ”aktiveras” med hjälp av ett skript i dess binärkatalog (bin på POSIX; Scripts på Windows). Då läggs katalogen till i PATH, så att om du kör python kommer miljöns Python-tolk att anropas och du kan köra installerade skript utan att behöva använda hela sökvägen. Aktiveringsskriptets anrop är plattformsspecifikt (<venv> måste ersättas med sökvägen till den katalog som innehåller den virtuella miljön):

Plattform

Skal

Kommando för att aktivera virtuell miljö

POSIX

bash/zsh

$ källa <venv>/bin/activate

fisk

$ källa <venv>/bin/activate.fish

csh/tcsh

$ källa <venv>/bin/activate.csh

pwsh

$ <venv>/bin/Activate.ps1

Fönster

cmd.exe

C:\> <venv>\Scripts\activate.bat

PowerShell

PS C:\> <venv>\Scripts\Activate.ps1

Tillagd i version 3.4: fish och csh aktiveringsskript.

Tillagd i version 3.8: PowerShell-aktiveringsskript installerade under POSIX för PowerShell Core-stöd.

Du behöver inte specifikt aktivera en virtuell miljö, eftersom du bara kan ange den fullständiga sökvägen till den miljöns Python-tolk när du anropar Python. Dessutom bör alla skript som är installerade i miljön kunna köras utan att den aktiveras.

För att uppnå detta har skript som installeras i virtuella miljöer en ”shebang”-rad som pekar på miljöns Python-tolk, #!/<path-to-venv>/bin/python. Det innebär att skriptet kommer att köras med den tolken oavsett värdet på PATH. På Windows stöds ”shebang” radbehandling om du har Pythons installationshanterare installerat. Om du dubbelklickar på ett installerat skript i ett Windows Explorer-fönster kommer det att köras med rätt tolk utan att miljön behöver vara aktiverad eller på PATH.

När en virtuell miljö har aktiverats sätts miljövariabeln VIRTUAL_ENV till sökvägen för miljön. Eftersom det inte krävs någon explicit aktivering av en virtuell miljö för att använda den, kan man inte förlita sig på VIRTUAL_ENV för att avgöra om en virtuell miljö används.

Varning

Eftersom skript som installeras i miljöer inte bör förvänta sig att miljön ska aktiveras innehåller deras shebang-rader de absoluta sökvägarna till miljöns tolkar. På grund av detta är miljöer i sig inte portabla, i det allmänna fallet. Du bör alltid ha ett enkelt sätt att återskapa en miljö (om du till exempel har en kravfil requirements.txt kan du anropa pip install -r requirements.txt med hjälp av miljöns pip för att installera alla paket som behövs i miljön). Om du av någon anledning behöver flytta miljön till en ny plats, bör du återskapa den på den önskade platsen och ta bort den på den gamla platsen. Om du flyttar en miljö för att du har flyttat en överordnad katalog till den, bör du återskapa miljön på dess nya plats. Annars kan det hända att programvara som installerats i miljön inte fungerar som förväntat.

Du kan inaktivera en virtuell miljö genom att skriva deactivate i ditt skal. Den exakta mekanismen är plattformsspecifik och är en intern implementeringsdetalj (vanligtvis används ett skript eller en skalfunktion).

API

Den högnivåmetod som beskrivs ovan använder sig av ett enkelt API som tillhandahåller mekanismer för tredjepartsskapare av virtuella miljöer för att anpassa skapandet av miljöer efter deras behov, EnvBuilder-klassen.

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())

Klassen EnvBuilder accepterar följande nyckelordsargument vid instansiering:

  • system_site_packages – ett booleskt värde som anger att systemets Python-site-paket ska vara tillgängliga för miljön (standard är False).

  • clear – ett booleskt värde som, om det är sant, raderar innehållet i en eventuell befintlig målkatalog innan miljön skapas.

  • symlinks – ett booleanskt värde som anger om Python-binärfilen ska försöka symlänkas i stället för att kopieras.

  • upgrade – ett booleskt värde som, om det är sant, kommer att uppgradera en befintlig miljö med den Python som körs - för användning när Python har uppgraderats på plats (standard är False).

  • with_pip – ett booleskt värde som, om det är sant, säkerställer att pip är installerat i den virtuella miljön. Detta använder ensurepip med alternativet --default-pip.

  • prompt – en sträng som ska användas när den virtuella miljön aktiveras (standardvärdet är None, vilket innebär att katalognamnet för miljön används). Om den speciella strängen "." anges, används basnamnet för den aktuella katalogen som prompt.

  • upgrade_deps – Uppdatera basmodulerna för venv till de senaste på PyPI

  • scm_ignore_files – Skapar ignoreringsfiler baserade på de angivna källkontrollhanterarna (SCM) i iterabeln. Stöd definieras genom att ha en metod med namnet create_{scm}_ignore_file. Det enda värdet som stöds som standard är "git" via create_git_ignore_file().

Ändrad i version 3.4: Lagt till parametern with_pip

Ändrad i version 3.6: Lagt till parametern prompt

Ändrad i version 3.9: Lagt till parametern upgrade_deps

Ändrad i version 3.13: Lagt till parametern scm_ignore_files

EnvBuilder kan användas som basklass.

create(env_dir)

Skapa en virtuell miljö genom att ange den målkatalog (absolut eller relativt den aktuella katalogen) som ska innehålla den virtuella miljön. Metoden create kommer antingen att skapa miljön i den angivna katalogen eller ge upphov till ett lämpligt undantag.

Metoden create i klassen EnvBuilder illustrerar de hooks som finns tillgängliga för anpassning av underklasser:

def create(self, env_dir):
    """
    Skapa en virtualiserad Python-miljö i en katalog.
    env_dir är målkatalogen för att skapa en miljö i.
    """
    env_dir = os.path.abspath(env_dir)
    context = self.ensure_directories(env_dir)
    self.create_configuration(sammanhang)
    self.setup_python(kontext)
    self.setup_scripts(kontext)
    self.post_setup(kontext)

Var och en av metoderna ensure_directories(), create_configuration(), setup_python(), setup_scripts() och post_setup() kan åsidosättas.

ensure_directories(env_dir)

Skapar miljökatalogen och alla nödvändiga underkataloger som inte redan finns, och returnerar ett kontextobjekt. Detta kontextobjekt är bara en hållare för attribut (t.ex. sökvägar) som kan användas av de andra metoderna. Om EnvBuilder skapas med argumentet clear=True, kommer innehållet i miljökatalogen att rensas och sedan kommer alla nödvändiga underkataloger att återskapas.

Det returnerade kontextobjektet är en types.SimpleNamespace med följande attribut:

  • env_dir - Platsen för den virtuella miljön. Används för __VENV_DIR__ i aktiveringsskript (se install_scripts()).

  • env_name - Namnet på den virtuella miljön. Används för __VENV_NAME__ i aktiveringsskript (se install_scripts()).

  • prompt - Prompten som ska användas av aktiveringsskripten. Används för __VENV_PROMPT__ i aktiveringsskript (se install_scripts()).

  • executable - Den underliggande Python-körbara filen som används av den virtuella miljön. Detta tar hänsyn till det fall då en virtuell miljö skapas från en annan virtuell miljö.

  • inc_path - Inkluderingssökvägen för den virtuella miljön.

  • lib_path - Sökvägen till purelib för den virtuella miljön.

  • bin_path - Skriptsökvägen för den virtuella miljön.

  • bin_name - Namnet på skriptsökvägen i förhållande till den virtuella miljöns plats. Används för __VENV_BIN_NAME__ i aktiveringsskript (se install_scripts()).

  • env_exe - Namnet på Python-tolken i den virtuella miljön. Används för __VENV_PYTHON__ i aktiveringsskript (se install_scripts()).

  • env_exec_cmd - Namnet på Python-tolken, med hänsyn tagen till omdirigeringar i filsystemet. Detta kan användas för att köra Python i den virtuella miljön.

Ändrad i version 3.11: venv sysconfig-installationsschemat används för att konstruera sökvägarna till de skapade katalogerna.

Ändrad i version 3.12: Attributet lib_path lades till i kontexten och kontextobjektet dokumenterades.

create_configuration(context)

Skapar konfigurationsfilen pyvenv.cfg i miljön.

setup_python(context)

Skapar en kopia eller en symbolisk länk till den körbara Python-filen i miljön. På POSIX-system, om en specifik körbar python3.x användes, kommer symlänkar till python och python3 att skapas som pekar på den körbara filen, såvida inte filer med dessa namn redan finns.

setup_scripts(context)

Installerar aktiveringsskript som är lämpliga för plattformen i den virtuella miljön.

upgrade_dependencies(context)

Uppgraderar de centrala venv-beroendepaketen (för närvarande pip) i miljön. Detta görs genom att skriva ut till den körbara filen pip i miljön.

Tillagd i version 3.9.

Ändrad i version 3.12: setuptools är inte längre ett centralt venv-beroende.

post_setup(context)

En platshållande metod som kan åsidosättas i tredjepartsimplementeringar för att förinstallera paket i den virtuella miljön eller utföra andra steg efter skapandet.

install_scripts(context, path)

Den här metoden kan anropas från setup_scripts() eller post_setup() i underklasser för att hjälpa till att installera anpassade skript i den virtuella miljön.

path är sökvägen till en katalog som bör innehålla underkatalogerna common, posix, nt; var och en innehållande skript avsedda för bin-katalogen i miljön. Innehållet i common och den katalog som motsvarar os.name kopieras efter att platshållare har ersatts med text:

  • __VENV_DIR__ ersätts med den absoluta sökvägen till miljökatalogen.

  • __VENV_NAME__ ersätts med miljönamnet (sista sökvägssegmentet i miljökatalogen).

  • __VENV_PROMPT__ ersätts med prompt (miljöns namn omgivet av parenteser och med ett efterföljande mellanslag)

  • __VENV_BIN_NAME__ ersätts med namnet på bin-katalogen (antingen bin eller Scripts).

  • __VENV_PYTHON__ ersätts med den absoluta sökvägen till miljöns körbara fil.

Katalogerna får existera (för när en befintlig miljö uppgraderas).

create_git_ignore_file(context)

Skapar en fil med namnet .gitignore i den virtuella miljön som gör att hela katalogen ignoreras av källkontrollhanteraren Git.

Tillagd i version 3.13.

Ändrad i version 3.7.2: Windows använder nu omdirigeringsskript för python[w].exe istället för att kopiera de faktiska binärerna. I 3.7.2 gör endast setup_python() ingenting om den inte körs från en build i källträdet.

Ändrad i version 3.7.3: Windows kopierar redirector-skript som en del av setup_python() istället för setup_scripts(). Detta var inte fallet i 3.7.2. Vid användning av symlänkar länkas de ursprungliga körbara filerna.

Det finns också en bekvämlighetsfunktion på modulnivå:

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

Skapa en EnvBuilder med de angivna nyckelordsargumenten, och anropa dess create()-metod med argumentet env_dir.

Tillagd i version 3.3.

Ändrad i version 3.4: Parametern with_pip har lagts till

Ändrad i version 3.6: Parametern prompt har lagts till

Ändrad i version 3.9: Parametern upgrade_deps har lagts till

Ändrad i version 3.13: Parametern scm_ignore_files har lagts till

Ett exempel på utökning av EnvBuilder

Följande skript visar hur man utökar EnvBuilder genom att implementera en underklass som installerar setuptools och pip i en skapad virtuell miljö:

import os
import os.path
from subprocess import Popen, PIPE
import sys
from threading import Thread
from urllib.parse import urlparse
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, _, _, _ = urlparse(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)

Detta skript finns också tillgängligt för nedladdning online.