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)
我想指定lol为samplein的依赖项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。
对此我们能做些什么呢?我可以在这里使用环境变量或一些占位符吗?我不想使用诗歌之类的工具。
我一直在广泛寻找 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或类似的钩子中完成。