在 pyproject.toml 中指定本地相对依赖关系

Opa*_*pal 24 python pip pyproject.toml

我有以下项目结构:

root
  - sample/
    - src/
    - tests/
    - pyproject.toml
  - libs/
    - lol/
      - src/
      - tests/
      - pyproject.toml
Run Code Online (Sandbox Code Playgroud)

我想指定lolsamplein的依赖项sample/pyproject.toml。怎样才能做到呢?我试过了:

dependencies = [ 
   "lol @ file://libs/lol"
]
Run Code Online (Sandbox Code Playgroud)

但它给了我:

ValueError: non-local file URIs are not supported on this platform: 'file://libs/lol'
Run Code Online (Sandbox Code Playgroud)

没关系,但是我不能在这里放置绝对路径,因为这将是共享代码。对于 也一样file://./lib/lol

对此我们能做些什么呢?我可以在这里使用环境变量或一些占位符吗?我不想使用诗歌之类的工具。

jac*_*cob 5

我一直在广泛寻找 toml 依赖项中相对路径包的解决方案。这个解决方案确实很糟糕,但它是迄今为止我拥有的最好的解决方案。基本上,我使用 git hooks 来修改每台机器上的 toml 文件及其各自的绝对路径。见下文:

我的pyproject.toml文件:
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

[tool.setuptools]
packages = ["rotor", "stator"]

[project]
version = "1.0.0"
name = "RTTS"
readme = "README.md"
requires-python = ">=3.10"
# ADD DEPENDENCIES HERE

# more stuff as needed...
Run Code Online (Sandbox Code Playgroud)

请注意,重要的部分是评论标识符# ADD DEPENDENCIES HERE

我的toml_mod.py文件(位于 旁边pyproject.toml):
from pathlib import Path

PATH = Path(__file__).parents[0].resolve()
DEPENDENCIES = f"['celery', 'daqhats@{PATH.as_uri()}/daqhats', 'eventlet', 'Flask', 'Flask-SocketIO', 'redis', 'RPi.GPIO']"
CONFIG = []

with open(f"{PATH}/pyproject.toml", 'rb') as f:
    line_bytes = f.readline()
    while line_bytes:
        if line_bytes.decode().strip() == "# ADD DEPENDENCIES HERE":
            CONFIG.append(f"dependencies = {DEPENDENCIES}\n".encode())
        else:
            CONFIG.append(line_bytes)
        line_bytes = f.readline()

with open("pyproject.toml", 'wb') as f:
    for line_bytes in CONFIG:
        f.write(line_bytes)
Run Code Online (Sandbox Code Playgroud)

您可以将daqhats第 4 行的包替换为本地包文件结构。然后,循环在 toml 文件中查找注释标识符,并将其替换为相应主机上的特定绝对路径。

我的基本post-receivegit 钩子:
#!/bin/bash

unset $(git rev-parse --local-env-vars)

cd /home/pi/Projects/Alpha
git fetch
git reset --hard origin/master

python toml_mod.py
Run Code Online (Sandbox Code Playgroud)

请注意,我获取并重置到另一个目录,用主版本覆盖该目录中所做的任何更改。

对我来说,我在 Windows 上进行开发并推送到一堆嵌入式系统。在我的 Windows 开发机器上提交后,我使用 git hooks 自动推送到我的开发网络上的每个嵌入式系统。对我来说,post-receive钩子是用于部署的,我永远不会在这个部署目录中工作(在我的例子中/home/pi/Projects/Alpha是在嵌入式设备上)。这意味着在执行硬重置时覆盖的唯一合并冲突origin/master是上次部署中的先前 toml 修改。每个嵌入式系统都有一个裸露的主存储库和它自己的post-receive钩子。这使得对每个设备的部署变得容易,并且使用该设备的相应路径而不是某些硬编码的路径。这是一个解决方法。

您的情况可能会有所不同,并且您可能必须使用不同的钩子文件(即post-<your git event here>根据您的开发流程和使用情况)。如果要在工作开发人员的目录中修改 toml,您可能需要采取一些技巧,不要覆盖它们的所有冲突,或者只是对初始克隆进行 toml 修改,然后不再进行(也许有一个post-clone钩子)。此外,该钩子必须是主机操作系统可以使用的脚本(在我的例子中是 linux bash)。

笔记:

Python 3.11 中有这个tomllib库,但它不写入 toml 文件(它只读取它们)。有些包会写入 toml 文件,但我在这个答案中特别坚持使用标准库,因为尚未安装依赖项。这个答案唯一假设的是主机有 Python 和 git 存储库。修改 toml 文件后会安装依赖项。对于部署,这可以在同一个post-receive钩子pip install /path/to/pyproject.toml/directory或类似的钩子中完成。

  • 谢谢你,非常令人印象深刻。但这确实很糟糕,不是我想要的。我觉得我正在引入一种技术债务。这样,我最好将依赖项存储在“requirements.txt”文件中。 (2认同)