Python Protoletariat
Protoletariat is a Python utility designed to address the long-standing issue of absolute imports in Python code generated by the official Protocol Buffers compiler (`protoc`). It acts as a post-processing step, rewriting these problematic absolute imports into correct relative imports, enabling smoother integration of generated protobuf code within Python packages. The library is actively maintained with frequent dependency updates.
Warnings
- gotcha The official `protoc` compiler generates Python code with absolute imports (e.g., `import other_pb2`) which often leads to `ModuleNotFoundError` when the generated files are part of a Python package or module structure. `protoletariat` is designed specifically to fix this post-generation.
- gotcha `protoletariat` is primarily a command-line tool (`protol`) that modifies generated Python `.py` files in-place. It is not generally intended for direct programmatic import and use within application code to fix imports at runtime.
- gotcha `protoletariat` relies on the `protoc` executable being installed and available in your system's PATH to inspect `FileDescriptorProtos` and correctly identify generated imports.
Install
-
pip install protoletariat
Imports
- protol
This library is primarily used as a command-line tool named `protol`.
Quickstart
mkdir -p out protos
cat <<EOF > protos/thing1.proto
syntax = "proto3";
import "thing2.proto";
package things;
message Thing1 { Thing2 thing2 = 1; }
EOF
cat <<EOF > protos/thing2.proto
syntax = "proto3";
package things;
message Thing2 { string data = 1; }
EOF
# Step 1: Generate Python code with protoc
protoc \
--python_out=out \
--proto_path=protos protos/thing1.proto protos/thing2.proto
echo "\n--- Before protoletariat ---"
cat out/thing1_pb2.py | grep 'import thing2_pb2'
# Step 2: Fix imports with protol
protol \
--create-package \
--in-place \
--python-out out \
--proto-path=protos protos/thing1.proto protos/thing2.proto
echo "\n--- After protoletariat ---"
cat out/thing1_pb2.py | grep 'import thing2_pb2'
# Expected output shows 'from . import thing2_pb2'