Imports (in nested sub-directories) within compiled `*_pb2.py` and `*_pb2.pyi` cannot be resolved on Python 3
Dear Protobuf community
I hope you are all doing well 😉
The Issue
Version: Protoc v3.20.1
Language: Python (Python 3.10.5)
OS: Windows/Linux/macOS
For quite long I have been facing a problem where imports (from and to nested sub-directories) within compiled *_pb2.py and *_pb2.pyi Protobuf files/modules generated from protoc --python_out --mypy_out cannot be resolved in my projects.
E.g. you might have the following file/module structure:
-
./-
a_pb2.py -
b_pb2.py -
./sub/-
c_pb2.py -
./nested/-
d_pb2.py -
__init__.py
-
-
__init__.py
-
-
__init__.py
-
Now assume, c.proto is importing a.proto, b.proto and d.proto.
protoc will generate the following import statements for c_pb2.py:
# c_pb2.py
from google.protobuf import descriptor as _descriptor
import a_pb2 as a__pb2
import b_pb2 as b__pb2
from sub.nested import d_pb2 as sub_dot_nested__d__pb2
# ...
Using these modules will not work under Python 3, as the imports are not relative. Nested imports are working for --dart_out and we extensively use a nested directory structure, to cope with project complexity.
I there any way to generate correct imports with the Protoc Python generator in the future?
A Workaround
As it can get quite cumbersome to fix these issues, I came up with a script that will fix the imports (https://pypi.org/project/fix-protobuf-imports/):
fix-protobuf-imports /path/to/python_out/dir
This will result in the following working imports:
# c_pb2.py
from google.protobuf import descriptor as _descriptor
from .. import a_pb2 as a__pb2
from .. import b_pb2 as b__pb2
from ..sub.nested import d_pb2 as sub_dot_nested__d__pb2
# ...
Regards
Many thanks for checking this issue and best regards to you all 😄 Markus