protobuf icon indicating copy to clipboard operation
protobuf copied to clipboard

Imports (in nested sub-directories) within compiled `*_pb2.py` and `*_pb2.pyi` cannot be resolved on Python 3

Open Atokulus opened this issue 3 years ago • 0 comments

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

Atokulus avatar Jul 28 '22 17:07 Atokulus