2

我们希望为我们软件的不同版本提供准备部署venv

因此,我想编写一个简单的 Python 脚本,它调用几个 bash 命令来安装我们需要的每个包。

所以步骤是:

  1. 创建一个venv名称以版本号为后缀的名称
  2. 激活这个venv
  3. 从安装包PyPy
  4. cd进入几个本地包文件夹
  5. 通过安装它们git install .
  6. cpvenv文件夹中的几个文件

我现在的问题是,我找不到venv从脚本中激活的方法。我已经读过它是如何在 Python 2 中完成的(带有execfile)和exec(open(path_to_env_activate).read())Python 3 中的。

但是,Python3 的第二个版本给了我一个语法错误:

Traceback (most recent call last):
  File "build.py", line 32, in <module>
    exec(open(venv_activate).read())
  File "<string>", line 1
    @echo off
            ^
SyntaxError: invalid syntax

我在这里做错了什么?或者是否有一种最佳实践如何venv使用带有脚本的软件包进行安装?

4

1 回答 1

0

我发现这个问题的解决方案是使用 Venv 模块来创建环境,并结合来自 Virtualenv 中的 activate_this.py 模块的代码。模块源代码:https ://github.com/pypa/virtualenv/blob/main/src/virtualenv/activation/python/activate_this.py

这个解决方案对我来说效果很好。我使用它来生成环境并安装 json 模板文件中描述的包。

这是我的 venv_controller:

import venv
import os
import sys
import site
from pathlib import Path

class VenvController:
    
    def __init__(self): 
        self.venv_name = 'venv'
        self.base = str(Path().absolute() / self.venv_name)
        self.bin_dir = str(Path().absolute() / self.venv_name / 'bin')
    
    def create(self, project_name):
        # Create venv
        venv.create(
                self.base,
                prompt=f'arkistak-{project_name}',
                with_pip=True
        )

        
    def activate(self):
        
        # Only activating if venv created
        if not os.path.exists(self.base):
            return False
        
        # Activate new environment. refer to 
        # https://github.com/pypa/virtualenv/blob/main
        # /src/virtualenv/activation/python/activate_this.py
        os.environ['PATH'] = os.pathsep.join([self.bin_dir] + 
                os.environ.get("PATH", "").split(os.pathsep))
        os.environ['VIRTUAL_ENV'] = self.base
        prev_length = len(sys.path)
        for lib in "__LIB_FOLDERS__".split(os.pathsep):
            path = os.path.realpath(os.path.join(self.bin_dir, lib))
            site.addsitedir(path)

        sys.path[:] = sys.path[prev_length:] + sys.path[0:prev_length]
        sys.real_prefix = sys.prefix
        sys.prefix = self.base
        return True
于 2020-11-21T23:33:18.390 回答