Skip to content

Generating multiple files [questions, bug? errors] #357

Open
@1oglop1

Description

@1oglop1

Hello, I'm new to GRPC (learning 5 days now).
My goal is to generate python SDK for Gitlab Gitaly from published protos.
I started with default protoc but quickly found out the problem with sys.path and everything else mentioned in motivation.

Then I found this project which gave me hope.
At first, I tried the latest release version 1.2.5 which lead NoImplementedError -> Client Streaming.

Then I installed the latest master 5f7e4d58efa8aeb7af28c9ed89e4870548a1ce62 .
This let me process some files but not others.

Gitaly proto structure looks like this:

├── blob.proto
├── cleanup.proto
├── commit.proto
├── conflicts.proto
├── diff.proto
├── errors.proto
├── hook.proto
├── internal.proto
├── lint.proto
├── namespace.proto
├── objectpool.proto
├── operations.proto
├── praefect.proto
├── ref.proto
├── remote.proto
├── repository-service.proto
├── server.proto
├── shared.proto
├── smarthttp.proto
├── ssh.proto
├── transaction.proto
└── wiki.proto

Most of the files depend on shared.proto and lint.proto.
Here is what I tried:

Default protoc:

	python -m grpc_tools.protoc \
	--proto_path=${PROTO_PATH} \
	--python_out=${PROTO_OUTPUT}/normal \
	--grpc_python_out=${PROTO_OUTPUT}/normal \
	${PROTO_PATH}/ssh.proto

Result are 2 files that import lint_pb2 and shared_pb2 which are nowhere to be found... great

ssh_pb2.py
ssh_pb2_grpc.py

Then I tried the wildcard:

	python -m grpc_tools.protoc \
	--proto_path=${PROTO_PATH} \
	--python_out=${PROTO_OUTPUT}/normal \
	--grpc_python_out=${PROTO_OUTPUT}/normal \
	${PROTO_PATH}/*.proto

This created all relevant files but was not really usable due to the broken sys.path.

betterprotoc.

	python -m grpc_tools.protoc \
	--proto_path=${PROTO_PATH} \
	--python_betterproto_out=${PROTO_OUTPUT}/better \
	${PROTO_PATH}/ssh.proto

Bug #1

The result is the generated package that does not respect the input filenames so everything ended up in __init__.py that was thousands of lines long.

Actual result:

better
├── gitaly
│   └── __init__.py
└── __init__.py

Expected result:

better
├── gitaly
│   ├── __init__.py
│   ├── shared.py
│   ├── lint.py
│   └── ssh.py
└── __init__.py

Bug #2 failure with some files

I also tried to use the wildcard *.proto

	python -m grpc_tools.protoc \
	--proto_path=${PROTO_PATH} \
	--python_betterproto_out=${PROTO_OUTPUT}/better \
	${PROTO_PATH}/*.proto

But this resulted in a StopIteration I was not able to debug. What I realised was that this may be a problem only with some files.

I was able to pin down which files have caused this error:

transaction.proto
wiki.proto
repository-service.proto
ref.proto
diff.proto
commit.proto

Traceback shows something about enum type but that's unlikely because the other files that work also contain that type.

Traceback (most recent call last):
  File "/home/user/cache/pypoetry/virtualenvs/gitaly-client-rXVxS8FM-py3.9/bin/protoc-gen-python_betterproto", line 8, in <module>
    sys.exit(main())
  File "/home/user/cache/pypoetry/virtualenvs/gitaly-client-rXVxS8FM-py3.9/lib/python3.9/site-packages/betterproto/plugin/main.py", line 32, in main
    response = generate_code(request)
  File "/home/user/cache/pypoetry/virtualenvs/gitaly-client-rXVxS8FM-py3.9/lib/python3.9/site-packages/betterproto/plugin/parser.py", line 107, in generate_code
    read_protobuf_service(service, index, output_package)
  File "/home/user/cache/pypoetry/virtualenvs/gitaly-client-rXVxS8FM-py3.9/lib/python3.9/site-packages/betterproto/plugin/parser.py", line 191, in read_protobuf_service
    ServiceMethodCompiler(
  File "<string>", line 7, in __init__
  File "/home/user/cache/pypoetry/virtualenvs/gitaly-client-rXVxS8FM-py3.9/lib/python3.9/site-packages/betterproto/plugin/models.py", line 683, in __post_init__
    self.mutable_default_args  # ensure this is called before rendering
  File "/home/user/cache/pypoetry/virtualenvs/gitaly-client-rXVxS8FM-py3.9/lib/python3.9/site-packages/betterproto/plugin/models.py", line 720, in mutable_default_args
    and f.default_value_string != "None"
  File "/home/user/cache/pypoetry/virtualenvs/gitaly-client-rXVxS8FM-py3.9/lib/python3.9/site-packages/betterproto/plugin/models.py", line 486, in default_value_string
    enum = next(
StopIteration
--python_betterproto_out: protoc-gen-python_betterproto: Plugin failed with status code 1.

It would be very nice if betterproto can respect the initial *.proto structure because right now it seems to only read package IIUC.
Please let me know if I can help you with further debugging or this example is good enough.

my environment:

[tool.poetry.dependencies]
python = "~3.9"
grpcio = "^1.44.0"
grpcio-tools = "^1.44.0"
betterproto = {git = "https://github.com/danielgtaylor/python-betterproto.git", rev = "5f7e4d58efa8aeb7af28c9ed89e4870548a1ce62"}

[tool.poetry.dev-dependencies]
pytest = "^5.2"
ptpython = "^3.0.20"
types-protobuf = ">=0.1.14"
betterproto = {extras = ["compiler"], git = "https://github.com/danielgtaylor/python-betterproto.git", rev = "5f7e4d58efa8aeb7af28c9ed89e4870548a1ce62"}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions