python - Protobuf 生成的 Python 包内部的隐式相对导入使得从外部导入是不可能的
问题描述
我有一个看起来像这样的包:
setup.py
requirements.txt
alphausblue/
api/
ripple/
org_pb2.py
org/
v1/
org_pb2_grpc.py
在 org_pb2_grpc.py 我有以下导入行:
from api.ripple import org_pb2 as api_dot_ripple_dot_org__pb2
我遇到的问题是,当我从alphausblue
目录内部导入时,导入工作正常。但是,当我从包中创建一个轮子时,将其上传到 Test PyPI,再次下载并尝试将其导入到这样的测试环境中:
>>> import alphausblue
>>> import alphausblue.org
>>> import alphausblue.org.v1
>>> import alphausblue.org.v1.org_pb2_grpc
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "\anaconda3\envs\test\lib\site-packages\alphausblue\org\v1\org_pb2_grpc.py", line 5, in <module>
from api.ripple import org_pb2 as api_dot_ripple_dot_org__pb2
ModuleNotFoundError: No module named 'api'
我得到上面的错误。我可以将代码从alphausblue/
to移动/
,然后导入工作,但我必须这样做org.v1.org_pb2_grpc
,这不是我想要的。看来这应该可行,所以我在这里缺少什么?
更新 这似乎是protoc如何生成 Python 代码的问题。我将在这里调查潜在的解决方案,看看我自己是否无法解决问题。
解决方案
所以,我尝试了很多方法来让 Protobuf 做我想做的事,即。工作,但无法弄清楚。因此,我对构建脚本进行了修改以执行此操作:
mkdir -p generated/py/alphausblue
python3 -m grpc_tools.protoc -I . --python_out=./generated/py/alphausblue --grpc_python_out=./generated/py/alphausblue \
./org/v1/*.proto \
./kvstore/v1/*.proto \
./iam/v1/*.proto \
./admin/v1/*.proto \
./cost/v1/*.proto \
./billing/v1/*.proto \
./operations/v1/*.proto \
./preferences/v1/*.proto
python3 -m grpc_tools.protoc -I . --python_out=./generated/py/alphausblue \
$(for v in $(find ./api -type d); do echo -n "$v/*.proto "; done)
for package in $(find generated/py/alphausblue -mindepth 1 -maxdepth 1 -type d -printf "%f "); do
echo "Found package ${package}. Beginning replacement"
find generated/py/alphausblue/. -name '*.py' -exec sed -i -e "s/from ${package}/from alphausblue.${package}/g" {} \;
done
这里的前两个命令从 .proto 文件生成 Python 代码。下一个命令使用 find 和 sed 获取包本身中的所有顶级包名称,并将隐式相对导入替换为绝对导入。
推荐阅读
- mongodb - mongodb - 嵌套文档的子聚合
- php - 我在 Laravel 文件上传时遇到问题。如何获取原始上传文件?
- c - CS50 pset5 卸载功能中的拼写错误
- mysql - MySQL,相同的更新脚本多个数据库
- angular - Angular,不加载登录数据
- git - 我提交,推送到 github 并拉取一个请求然后再次克隆,我尝试了 git pull request,但它给了我一个错误,为什么?
- java - 如何更改 CountryCodePicker (CCP) 的对话框
- python - 我想更新我创建的模型。但是,我想通过模型的 id 来做到这一点
- java - 卡在弹簧数据 jpa 左连接上,提供具有相同数据的多条记录
- javascript - 如何从一年中获取日期以及总共过去了多少天?