From c2ca015d431294d1552dd4cbeb12b52ac8fbca37 Mon Sep 17 00:00:00 2001 From: Adrien Vannson Date: Thu, 20 Nov 2025 16:40:11 +0100 Subject: [PATCH 01/12] Conformance action --- .github/workflows/ci.yml | 243 +++++++++++++++++++++------------------ 1 file changed, 130 insertions(+), 113 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 49686a6..56b10aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,151 +12,168 @@ permissions: contents: read jobs: - test-dependencies: - name: Check running without dependencies - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 + # test-dependencies: + # name: Check running without dependencies + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 - - name: Install uv with Python 3.12 - uses: astral-sh/setup-uv@v5 - with: - version: "0.7.5" - python-version: "3.12" + # - name: Install uv with Python 3.12 + # uses: astral-sh/setup-uv@v5 + # with: + # version: "0.7.5" + # python-version: "3.12" + + # - name: Install betterproto2 + # working-directory: ./betterproto2 + # run: uv sync --locked + + # - name: Install betterproto2_compiler + # working-directory: ./betterproto2_compiler + # run: uv sync --locked + + # - name: Compile test files + # working-directory: ./betterproto2_compiler + # shell: bash + # run: uv run poe generate + + # - name: Move compiled files to betterproto2 + # shell: bash + # run: cp -r betterproto2_compiler/tests/outputs betterproto2/tests - - name: Install betterproto2 - working-directory: ./betterproto2 - run: uv sync --locked + # - name: Execute test suite + # working-directory: ./betterproto2 + # run: uv run poe test - - name: Install betterproto2_compiler - working-directory: ./betterproto2_compiler - run: uv sync --locked - - name: Compile test files - working-directory: ./betterproto2_compiler - shell: bash - run: uv run poe generate + # - name: Add Pydantic + # working-directory: ./betterproto2 + # run: uv sync --locked --extra=pydantic - - name: Move compiled files to betterproto2 - shell: bash - run: cp -r betterproto2_compiler/tests/outputs betterproto2/tests + # - name: Execute test suite + # working-directory: ./betterproto2 + # run: uv run poe test - - name: Execute test suite - working-directory: ./betterproto2 - run: uv run poe test + # - name: Add all but Pydantic + # working-directory: ./betterproto2 + # run: uv sync --locked --extra=grpclib --extra=grpcio --extra=protobuf - - name: Add Pydantic - working-directory: ./betterproto2 - run: uv sync --locked --extra=pydantic + # - name: Execute test suite + # working-directory: ./betterproto2 + # run: uv run poe test - - name: Execute test suite - working-directory: ./betterproto2 - run: uv run poe test + # - name: Add grpclib + # working-directory: ./betterproto2 + # run: uv sync --locked --extra=grpclib - - name: Add all but Pydantic - working-directory: ./betterproto2 - run: uv sync --locked --extra=grpclib --extra=grpcio --extra=protobuf + # - name: Execute test suite + # working-directory: ./betterproto2 + # run: uv run poe test - - name: Execute test suite - working-directory: ./betterproto2 - run: uv run poe test + # - name: Add all but grpclib + # working-directory: ./betterproto2 + # run: uv sync --locked --extra=pydantic --extra=grpcio --extra=protobuf - - name: Add grpclib - working-directory: ./betterproto2 - run: uv sync --locked --extra=grpclib + # - name: Execute test suite + # working-directory: ./betterproto2 + # run: uv run poe test - - name: Execute test suite - working-directory: ./betterproto2 - run: uv run poe test + # - name: Add grpcio + # working-directory: ./betterproto2 + # run: uv sync --locked --extra=grpcio - - name: Add all but grpclib - working-directory: ./betterproto2 - run: uv sync --locked --extra=pydantic --extra=grpcio --extra=protobuf + # - name: Execute test suite + # working-directory: ./betterproto2 + # run: uv run poe test - - name: Execute test suite - working-directory: ./betterproto2 - run: uv run poe test + # - name: Add all but grpcio + # working-directory: ./betterproto2 + # run: uv sync --locked --extra=pydantic --extra=grpclib --extra=protobuf - - name: Add grpcio - working-directory: ./betterproto2 - run: uv sync --locked --extra=grpcio + # - name: Execute test suite + # working-directory: ./betterproto2 + # run: uv run poe test - - name: Execute test suite - working-directory: ./betterproto2 - run: uv run poe test + # - name: Add protobuf + # working-directory: ./betterproto2 + # run: uv sync --locked --extra=protobuf - - name: Add all but grpcio - working-directory: ./betterproto2 - run: uv sync --locked --extra=pydantic --extra=grpclib --extra=protobuf + # - name: Execute test suite + # working-directory: ./betterproto2 + # run: uv run poe test - - name: Execute test suite - working-directory: ./betterproto2 - run: uv run poe test + # - name: Add all but protobuf + # working-directory: ./betterproto2 + # run: uv sync --locked --extra=pydantic --extra=grpclib --extra=grpcio - - name: Add protobuf - working-directory: ./betterproto2 - run: uv sync --locked --extra=protobuf + # - name: Execute test suite + # working-directory: ./betterproto2 + # run: uv run poe test - - name: Execute test suite - working-directory: ./betterproto2 - run: uv run poe test + # tests: + # name: ${{ matrix.os }} / ${{ matrix.python-version }} + # runs-on: ${{ matrix.os }}-latest + # strategy: + # fail-fast: false + # matrix: + # os: [Ubuntu, MacOS, Windows] + # python-version: ['3.10', '3.11', '3.12', '3.13'] + # steps: + # - uses: actions/checkout@v4 + # - name: Install uv with Python ${{ matrix.python-version }} + # uses: astral-sh/setup-uv@v5 + # with: + # version: "0.7.5" + # python-version: ${{ matrix.python-version }} - - name: Add all but protobuf - working-directory: ./betterproto2 - run: uv sync --locked --extra=pydantic --extra=grpclib --extra=grpcio + # - name: Install betterproto2 + # working-directory: ./betterproto2 + # run: uv sync --locked --all-extras --all-groups - - name: Execute test suite - working-directory: ./betterproto2 - run: uv run poe test + # - name: Install betterproto2_compiler + # working-directory: ./betterproto2_compiler + # run: uv sync --locked --all-extras --all-groups + + # - name: Test betterproto2_compiler + # working-directory: ./betterproto2_compiler + # shell: bash + # run: uv run poe test + + # - name: Compile test files + # working-directory: ./betterproto2_compiler + # shell: bash + # run: uv run poe generate + + # - name: Move compiled files to betterproto2 + # shell: bash + # run: cp -r betterproto2_compiler/tests/outputs betterproto2/tests + + # - name: Execute test suite + # working-directory: ./betterproto2 + # shell: bash + # run: uv run poe test + + conformance: + runs-on: ubuntu-latest - tests: - name: ${{ matrix.os }} / ${{ matrix.python-version }} - runs-on: ${{ matrix.os }}-latest - strategy: - fail-fast: false - matrix: - os: [Ubuntu, MacOS, Windows] - python-version: ['3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v4 - - name: Install uv with Python ${{ matrix.python-version }} - uses: astral-sh/setup-uv@v5 + - name: Install Node.js + uses: actions/setup-node@v6 with: - version: "0.7.5" - python-version: ${{ matrix.python-version }} - - - name: Install betterproto2 - working-directory: ./betterproto2 - run: uv sync --locked --all-extras --all-groups - - - name: Install betterproto2_compiler - working-directory: ./betterproto2_compiler - run: uv sync --locked --all-extras --all-groups - - - name: Test betterproto2_compiler - working-directory: ./betterproto2_compiler - shell: bash - run: uv run poe test - - - name: Compile test files - working-directory: ./betterproto2_compiler - shell: bash - run: uv run poe generate - - - name: Move compiled files to betterproto2 - shell: bash - run: cp -r betterproto2_compiler/tests/outputs betterproto2/tests - - - name: Execute test suite - working-directory: ./betterproto2 - shell: bash - run: uv run poe test + node-version: 24 + + - name: Install conformance runner + run: npm install -g protobuf-conformance + + - name: Verify runner + run: conformance_test_runner --help From 0ecef9d363e8680dc6a87801fa6469536543a7cd Mon Sep 17 00:00:00 2001 From: Adrien Vannson Date: Thu, 20 Nov 2025 17:29:05 +0100 Subject: [PATCH 02/12] Compile files for conformance test --- .github/workflows/ci.yml | 27 +- betterproto2/tests/conformance/main.py | 127 +++++++++ betterproto2_compiler/tests/generate.py | 1 + .../inputs/conformance/conformance.proto | 172 +++++++++++ .../conformance/test_messages_proto3.proto | 269 ++++++++++++++++++ 5 files changed, 594 insertions(+), 2 deletions(-) create mode 100644 betterproto2/tests/conformance/main.py create mode 100644 betterproto2_compiler/tests/inputs/conformance/conformance.proto create mode 100644 betterproto2_compiler/tests/inputs/conformance/test_messages_proto3.proto diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 56b10aa..c3fdb39 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -175,5 +175,28 @@ jobs: - name: Install conformance runner run: npm install -g protobuf-conformance - - name: Verify runner - run: conformance_test_runner --help + # - name: Verify runner + # run: conformance_test_runner --help + + - name: Install uv with Python 3.10 + uses: astral-sh/setup-uv@v5 + with: + version: "0.7.5" + python-version: 3.10 + + - name: Install betterproto2 + working-directory: ./betterproto2 + run: uv sync --locked --all-extras --all-groups + + - name: Install betterproto2_compiler + working-directory: ./betterproto2_compiler + run: uv sync --locked --all-extras --all-groups + + - name: Compile test files + working-directory: ./betterproto2_compiler + shell: bash + run: uv run poe generate + + - name: Move compiled files to betterproto2 + shell: bash + run: cp -r betterproto2_compiler/tests/outputs betterproto2/tests diff --git a/betterproto2/tests/conformance/main.py b/betterproto2/tests/conformance/main.py new file mode 100644 index 0000000..7359dea --- /dev/null +++ b/betterproto2/tests/conformance/main.py @@ -0,0 +1,127 @@ +import betterproto2 + +import struct +import sys + +from tests.outputs.conformance.conformance import ( + ConformanceResponse, + ConformanceRequest, + TestCategory, + WireFormat, +) +from tests.outputs.conformance.protobuf_test_messages.proto3 import TestAllTypesProto3 + + +test_count = 0 +verbose = False + + +class ProtocolError(Exception): + pass + + +def do_test(request: ConformanceRequest) -> ConformanceResponse: + response = ConformanceResponse() + + is_json = betterproto2.which_one_of(request, "payload")[0] == "json_payload" + + if request.message_type != "protobuf_test_messages.proto3.TestAllTypesProto3": + return ConformanceResponse(skipped="non proto3 tests not supported") + + try: + if betterproto2.which_one_of(request, "payload")[0] == "protobuf_payload": + try: + test_message = TestAllTypesProto3.parse(request.protobuf_payload) + except Exception as e: + response.parse_error = str(e) + return response + + elif betterproto2.which_one_of(request, "payload")[0] == "json_payload": + try: + ignore_unknown_fields = request.test_category == TestCategory.JSON_IGNORE_UNKNOWN_PARSING_TEST + test_message = TestAllTypesProto3.from_json(request.json_payload, ignore_unknown_fields=ignore_unknown_fields) + except Exception as e: + response.parse_error = str(e) + return response + + elif betterproto2.which_one_of(request, "payload")[0] == "text_payload": + return ConformanceResponse(skipped="text input not supported") + try: + text_format.Parse(request.text_payload, test_message) + except Exception as e: + response.parse_error = str(e) + return response + + else: + raise ProtocolError("Request didn't have payload.") + + if request.requested_output_format == WireFormat.UNSPECIFIED: + raise ProtocolError("Unspecified output format") + + elif request.requested_output_format == WireFormat.PROTOBUF: + response.protobuf_payload = bytes(test_message) + + elif request.requested_output_format == WireFormat.JSON: + try: + response.json_payload = test_message.to_json() + except Exception as e: + response.serialize_error = str(e) + return response + + elif request.requested_output_format == WireFormat.TEXT_FORMAT: + return ConformanceResponse(skipped="text output not supported") + # response.text_payload = text_format.MessageToString( + # test_message, print_unknown_fields=request.print_unknown_fields + # ) + + except Exception as e: + response.runtime_error = str(e) + + return response + + +def do_test_io(): + length_bytes = sys.stdin.buffer.read(4) + if len(length_bytes) == 0: + return False # EOF + elif len(length_bytes) != 4: + raise IOError("I/O error") + + length = struct.unpack(" map_int32_int32 = 56; + map map_int64_int64 = 57; + map map_uint32_uint32 = 58; + map map_uint64_uint64 = 59; + map map_sint32_sint32 = 60; + map map_sint64_sint64 = 61; + map map_fixed32_fixed32 = 62; + map map_fixed64_fixed64 = 63; + map map_sfixed32_sfixed32 = 64; + map map_sfixed64_sfixed64 = 65; + map map_int32_float = 66; + map map_int32_double = 67; + map map_bool_bool = 68; + map map_string_string = 69; + map map_string_bytes = 70; + map map_string_nested_message = 71; + map map_string_foreign_message = 72; + map map_string_nested_enum = 73; + map map_string_foreign_enum = 74; + + oneof oneof_field { + uint32 oneof_uint32 = 111; + NestedMessage oneof_nested_message = 112; + string oneof_string = 113; + bytes oneof_bytes = 114; + bool oneof_bool = 115; + uint64 oneof_uint64 = 116; + float oneof_float = 117; + double oneof_double = 118; + NestedEnum oneof_enum = 119; + google.protobuf.NullValue oneof_null_value = 120; + } + + // Well-known types + google.protobuf.BoolValue optional_bool_wrapper = 201; + google.protobuf.Int32Value optional_int32_wrapper = 202; + google.protobuf.Int64Value optional_int64_wrapper = 203; + google.protobuf.UInt32Value optional_uint32_wrapper = 204; + google.protobuf.UInt64Value optional_uint64_wrapper = 205; + google.protobuf.FloatValue optional_float_wrapper = 206; + google.protobuf.DoubleValue optional_double_wrapper = 207; + google.protobuf.StringValue optional_string_wrapper = 208; + google.protobuf.BytesValue optional_bytes_wrapper = 209; + + repeated google.protobuf.BoolValue repeated_bool_wrapper = 211; + repeated google.protobuf.Int32Value repeated_int32_wrapper = 212; + repeated google.protobuf.Int64Value repeated_int64_wrapper = 213; + repeated google.protobuf.UInt32Value repeated_uint32_wrapper = 214; + repeated google.protobuf.UInt64Value repeated_uint64_wrapper = 215; + repeated google.protobuf.FloatValue repeated_float_wrapper = 216; + repeated google.protobuf.DoubleValue repeated_double_wrapper = 217; + repeated google.protobuf.StringValue repeated_string_wrapper = 218; + repeated google.protobuf.BytesValue repeated_bytes_wrapper = 219; + + google.protobuf.Duration optional_duration = 301; + google.protobuf.Timestamp optional_timestamp = 302; + google.protobuf.FieldMask optional_field_mask = 303; + google.protobuf.Struct optional_struct = 304; + google.protobuf.Any optional_any = 305; + google.protobuf.Value optional_value = 306; + google.protobuf.NullValue optional_null_value = 307; + + repeated google.protobuf.Duration repeated_duration = 311; + repeated google.protobuf.Timestamp repeated_timestamp = 312; + repeated google.protobuf.FieldMask repeated_fieldmask = 313; + repeated google.protobuf.Struct repeated_struct = 324; + repeated google.protobuf.Any repeated_any = 315; + repeated google.protobuf.Value repeated_value = 316; + repeated google.protobuf.ListValue repeated_list_value = 317; + + // Test field-name-to-JSON-name convention. + // (protobuf says names can be any valid C/C++ identifier.) + int32 fieldname1 = 401; + int32 field_name2 = 402; + int32 _field_name3 = 403; + int32 field__name4_ = 404; + int32 field0name5 = 405; + int32 field_0_name6 = 406; + int32 fieldName7 = 407; + int32 FieldName8 = 408; + int32 field_Name9 = 409; + int32 Field_Name10 = 410; + int32 FIELD_NAME11 = 411; + int32 FIELD_name12 = 412; + int32 __field_name13 = 413; + int32 __Field_name14 = 414; + int32 field__name15 = 415; + int32 field__Name16 = 416; + int32 field_name17__ = 417; + int32 Field_name18__ = 418; + + // Reserved for testing unknown fields + reserved 501 to 510; + + reserved "reserved_field"; + reserved 999999; +} + +message ForeignMessage { + int32 c = 1; +} + +enum ForeignEnum { + FOREIGN_FOO = 0; + FOREIGN_BAR = 1; + FOREIGN_BAZ = 2; +} + +message NullHypothesisProto3 {} + +message EnumOnlyProto3 { + enum Bool { + kFalse = 0; + kTrue = 1; + } +} \ No newline at end of file From 4e8e10ea230a7febe09c2616f78f646277a50911 Mon Sep 17 00:00:00 2001 From: Adrien Vannson Date: Thu, 20 Nov 2025 17:31:49 +0100 Subject: [PATCH 03/12] Fix Python version --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c3fdb39..16c02fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -182,7 +182,7 @@ jobs: uses: astral-sh/setup-uv@v5 with: version: "0.7.5" - python-version: 3.10 + python-version: "3.10" - name: Install betterproto2 working-directory: ./betterproto2 From 2a07b359b6d2e2e11c65639f186545b26f7f628a Mon Sep 17 00:00:00 2001 From: Adrien Vannson Date: Thu, 20 Nov 2025 17:38:36 +0100 Subject: [PATCH 04/12] Run the tests --- .github/workflows/ci.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 16c02fa..1c23ed4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -200,3 +200,16 @@ jobs: - name: Move compiled files to betterproto2 shell: bash run: cp -r betterproto2_compiler/tests/outputs betterproto2/tests + + - name: Create test script + shell: bash + working-directory: ./betterproto2 + run: | + echo '#!/bin/bash' > script.sh + echo 'python -m tests.conformance.main' >> script.sh + chmod +x script.sh + + - name: Run conformance tests + working-directory: ./betterproto2 + run: | + uv run conformance_test_runner ./script.sh From e9ba226fca896486f4e12e508461e11262f1c353 Mon Sep 17 00:00:00 2001 From: Adrien Vannson Date: Thu, 20 Nov 2025 17:43:00 +0100 Subject: [PATCH 05/12] Format code --- betterproto2/tests/conformance/main.py | 27 +++++++++++++------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/betterproto2/tests/conformance/main.py b/betterproto2/tests/conformance/main.py index 7359dea..0727b6b 100644 --- a/betterproto2/tests/conformance/main.py +++ b/betterproto2/tests/conformance/main.py @@ -1,17 +1,15 @@ -import betterproto2 - import struct import sys +import betterproto2 from tests.outputs.conformance.conformance import ( - ConformanceResponse, ConformanceRequest, + ConformanceResponse, TestCategory, WireFormat, ) from tests.outputs.conformance.protobuf_test_messages.proto3 import TestAllTypesProto3 - test_count = 0 verbose = False @@ -39,18 +37,20 @@ def do_test(request: ConformanceRequest) -> ConformanceResponse: elif betterproto2.which_one_of(request, "payload")[0] == "json_payload": try: ignore_unknown_fields = request.test_category == TestCategory.JSON_IGNORE_UNKNOWN_PARSING_TEST - test_message = TestAllTypesProto3.from_json(request.json_payload, ignore_unknown_fields=ignore_unknown_fields) + test_message = TestAllTypesProto3.from_json( + request.json_payload, ignore_unknown_fields=ignore_unknown_fields + ) except Exception as e: response.parse_error = str(e) return response elif betterproto2.which_one_of(request, "payload")[0] == "text_payload": - return ConformanceResponse(skipped="text input not supported") - try: - text_format.Parse(request.text_payload, test_message) - except Exception as e: - response.parse_error = str(e) - return response + return ConformanceResponse(skipped="text input not supported") + try: + text_format.Parse(request.text_payload, test_message) + except Exception as e: + response.parse_error = str(e) + return response else: raise ProtocolError("Request didn't have payload.") @@ -121,7 +121,6 @@ def do_test_io(): # f.write("Hello!") if not do_test_io(): sys.stderr.write( - "conformance_python: received EOF from test runner " - + "after %s tests, exiting\n" % (test_count,) + "conformance_python: received EOF from test runner " + "after %s tests, exiting\n" % (test_count,) ) - sys.exit(0) \ No newline at end of file + sys.exit(0) From 3ca909888fd3cd92e197552764a8c9b704be2f08 Mon Sep 17 00:00:00 2001 From: Adrien Vannson Date: Thu, 20 Nov 2025 17:47:20 +0100 Subject: [PATCH 06/12] Add failing tests list --- .github/workflows/ci.yml | 2 +- .../tests/conformance/failing_tests.txt | 174 ++++++++++++++++++ 2 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 betterproto2/tests/conformance/failing_tests.txt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1c23ed4..e6f83d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -212,4 +212,4 @@ jobs: - name: Run conformance tests working-directory: ./betterproto2 run: | - uv run conformance_test_runner ./script.sh + uv run conformance_test_runner --failure_list tests/conformance/failing_tests.txt ./script.sh diff --git a/betterproto2/tests/conformance/failing_tests.txt b/betterproto2/tests/conformance/failing_tests.txt new file mode 100644 index 0000000..0142ca0 --- /dev/null +++ b/betterproto2/tests/conformance/failing_tests.txt @@ -0,0 +1,174 @@ +Required.Proto3.DurationProtoInputTooLarge.JsonOutput # Should have failed to serialize, but didn't. +Required.Proto3.DurationProtoInputTooSmall.JsonOutput # Should have failed to serialize, but didn't. +Required.Proto3.DurationProtoNanosTooLarge.JsonOutput # Should have failed to serialize, but didn't. +Required.Proto3.DurationProtoNanosTooSmall.JsonOutput # Should have failed to serialize, but didn't. +Required.Proto3.DurationProtoNanosWrongSign.JsonOutput # Should have failed to serialize, but didn't. +Required.Proto3.DurationProtoNanosWrongSignNegativeSecs.JsonOutput # Should have failed to serialize, but didn't. +Required.Proto3.JsonInput.AnyWithFieldMask.JsonOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.AnyWithFieldMask.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.AnyWithNoType.JsonOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.AnyWithNoType.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.BoolMapEscapedKey.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.BoolMapField.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.DoubleFieldTooLarge # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.DoubleFieldTooSmall # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.DurationJsonInputTooLarge # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.DurationMaxValue.JsonOutput # JSON output we received from test was unparseable. +Required.Proto3.JsonInput.DurationMaxValue.ProtobufOutput # Output was not equivalent to reference message: modified: optional_duration.seconds: 315576000000 -> 315576000001deleted: option +Required.Proto3.JsonInput.DurationMinValue.JsonOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.DurationMinValue.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.DurationNegativeNanos.JsonOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.DurationNegativeNanos.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.DurationNegativeSeconds.JsonOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.DurationNegativeSeconds.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.DurationRepeatedValue.JsonOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.DurationRepeatedValue.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.EmptyFieldMask.JsonOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.EmptyFieldMask.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.FieldMask.JsonOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.FieldMask.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.FieldNameInLowerCamelCase.Validator # Expected JSON payload but got type 1 +Required.Proto3.JsonInput.FieldNameInSnakeCase.JsonOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.FieldNameInSnakeCase.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.FieldNameWithMixedCases.JsonOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.FieldNameWithMixedCases.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.FieldNameWithMixedCases.Validator # Expected JSON payload but got type 1 +Required.Proto3.JsonInput.FieldNameWithNumbers.JsonOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.FieldNameWithNumbers.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.FieldNameWithNumbers.Validator # Expected JSON payload but got type 1 +Required.Proto3.JsonInput.FloatFieldTooLarge # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.FloatFieldTooSmall # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.Int32FieldLeadingSpace # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.Int32FieldNotInteger # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.Int32FieldQuotedExponentialValue.JsonOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.Int32FieldQuotedExponentialValue.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.Int32FieldTooLarge # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.Int32FieldTooSmall # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.Int32FieldTrailingSpace # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.Int64FieldTooLarge # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.Int64FieldTooSmall # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.OneofFieldDuplicate # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.OptionalBytesWrapper.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.OriginalProtoFieldName.JsonOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.OriginalProtoFieldName.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.RepeatedBytesWrapper.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotMessage # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.SkipsDefaultPrimitive.Validator # Expected JSON payload but got type 1 +Required.Proto3.JsonInput.StringFieldNotAString # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.TimestampJsonInputLowercaseT # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.TimestampJsonInputLowercaseZ # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.TimestampJsonInputMissingT # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.TimestampLittleAfterEpochlValue.JsonOutput # Output was not equivalent to reference message: deleted: optional_timestamp.nanos: 1 +Required.Proto3.JsonInput.TimestampLittleAfterEpochlValue.ProtobufOutput # Output was not equivalent to reference message: deleted: optional_timestamp.nanos: 1 +Required.Proto3.JsonInput.TimestampLittleBeforeEpochValue.JsonOutput # Output was not equivalent to reference message: modified: optional_timestamp.nanos: 999999999 -> 999999000 +Required.Proto3.JsonInput.TimestampLittleBeforeEpochValue.ProtobufOutput # Output was not equivalent to reference message: modified: optional_timestamp.nanos: 999999999 -> 999999000 +Required.Proto3.JsonInput.TimestampMaxValue.JsonOutput # Output was not equivalent to reference message: modified: optional_timestamp.nanos: 999999999 -> 999999000 +Required.Proto3.JsonInput.TimestampMaxValue.ProtobufOutput # Output was not equivalent to reference message: modified: optional_timestamp.nanos: 999999999 -> 999999000 +Required.Proto3.JsonInput.TimestampNanoAfterEpochlValue.JsonOutput # Output was not equivalent to reference message: deleted: optional_timestamp.nanos: 1 +Required.Proto3.JsonInput.TimestampNanoAfterEpochlValue.ProtobufOutput # Output was not equivalent to reference message: deleted: optional_timestamp.nanos: 1 +Required.Proto3.JsonInput.TimestampNanoBeforeEpochValue.JsonOutput # Output was not equivalent to reference message: modified: optional_timestamp.nanos: 999999999 -> 999999000 +Required.Proto3.JsonInput.TimestampNanoBeforeEpochValue.ProtobufOutput # Output was not equivalent to reference message: modified: optional_timestamp.nanos: 999999999 -> 999999000 +Required.Proto3.JsonInput.TimestampRepeatedValue.JsonOutput # Output was not equivalent to reference message: modified: repeated_timestamp[1].nanos: 999999999 -> 999999000 +Required.Proto3.JsonInput.TimestampRepeatedValue.ProtobufOutput # Output was not equivalent to reference message: modified: repeated_timestamp[1].nanos: 999999999 -> 999999000 +Required.Proto3.JsonInput.TimestampWithMissingColonInOffset # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.Uint32FieldNotInteger # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.Uint32FieldTooLarge # Should have failed to parse, but didn't. +Required.Proto3.JsonInput.Uint64FieldTooLarge # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.IllegalZeroFieldNum_Case_0 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.IllegalZeroFieldNum_Case_1 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.IllegalZeroFieldNum_Case_2 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.IllegalZeroFieldNum_Case_3 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.MismatchedGroupTags # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.MismatchedNestedGroupTags # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofBeforeUnknownValue.DOUBLE # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED32 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED64 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofBeforeUnknownValue.FLOAT # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED32 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED64 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.BYTES # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.STRING # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.BYTES # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.STRING # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.BYTES # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.MESSAGE # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.STRING # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInPackedField.BOOL # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInPackedField.DOUBLE # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInPackedField.ENUM # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInPackedField.FIXED32 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInPackedField.FIXED64 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInPackedField.FLOAT # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT32 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT64 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInPackedField.SFIXED32 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInPackedField.SFIXED64 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT32 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT64 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT32 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT64 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInsideUnknownValue.DOUBLE # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInsideUnknownValue.FIXED32 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInsideUnknownValue.FIXED64 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInsideUnknownValue.FLOAT # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED32 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED64 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.RepeatedScalarMessageMerge.JsonOutput # Output was not equivalent to reference message: deleted: optional_nested_message.corecursive.optional_int64: 1234modified: optio +Required.Proto3.ProtobufInput.RepeatedScalarMessageMerge.ProtobufOutput # Output was not equivalent to reference message: deleted: optional_nested_message.corecursive.optional_int64: 1234modified: optio +Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.ENUM.JsonOutput # JSON output we received from test was unparseable. +Required.Proto3.ProtobufInput.UnknownWireType6_Field0_Version1 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnknownWireType6_Field0_Version3 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnknownWireType6_Field1_Version1 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnknownWireType6_Field1_Version3 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnknownWireType6_Field2_Version1 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnknownWireType6_Field2_Version3 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnknownWireType6_Field3_Version1 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnknownWireType6_Field3_Version3 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnknownWireType7_Field0_Version1 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnknownWireType7_Field0_Version3 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnknownWireType7_Field1_Version1 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnknownWireType7_Field1_Version3 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnknownWireType7_Field2_Version1 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnknownWireType7_Field2_Version3 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnknownWireType7_Field3_Version1 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnknownWireType7_Field3_Version3 # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnmatchedEndGroup # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnmatchedEndGroupNested # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnmatchedEndGroupNestedLen # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnmatchedEndGroupUnknown # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnmatchedEndGroupWithData # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnmatchedEndGroupWrongType # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnmatchedStartGroup # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnmatchedStartGroupNested # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnmatchedStartGroupNestedLen # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnmatchedStartGroupUnknown # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnmatchedStartGroupWithData # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.UnmatchedStartGroupWrongType # Should have failed to parse, but didn't. +Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.MissingDefault.JsonOutput # Failed to parse input or produce output. +Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.MissingDefault.ProtobufOutput # Failed to parse input or produce output. +Required.Proto3.ProtobufInput.ValidDataOneof.BOOL.MultipleValuesForDifferentField.JsonOutput # JSON output we received from test was unparseable. +Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.MultipleValuesForDifferentField.JsonOutput # JSON output we received from test was unparseable. +Required.Proto3.ProtobufInput.ValidDataOneof.DOUBLE.MultipleValuesForDifferentField.JsonOutput # JSON output we received from test was unparseable. +Required.Proto3.ProtobufInput.ValidDataOneof.ENUM.MultipleValuesForDifferentField.JsonOutput # JSON output we received from test was unparseable. +Required.Proto3.ProtobufInput.ValidDataOneof.FLOAT.MultipleValuesForDifferentField.JsonOutput # JSON output we received from test was unparseable. +Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.Merge.JsonOutput # Output was not equivalent to reference message: deleted: oneof_nested_message.corecursive.optional_int32: 1deleted: oneof_nested +Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.Merge.ProtobufOutput # Output was not equivalent to reference message: deleted: oneof_nested_message.corecursive.optional_int32: 1deleted: oneof_nested +Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.MultipleValuesForDifferentField.JsonOutput # JSON output we received from test was unparseable. +Required.Proto3.ProtobufInput.ValidDataOneof.STRING.MultipleValuesForDifferentField.JsonOutput # JSON output we received from test was unparseable. +Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.MultipleValuesForDifferentField.JsonOutput # JSON output we received from test was unparseable. +Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.MultipleValuesForDifferentField.ProtobufOutput # Output was not equivalent to reference message: deleted: oneof_uint32: 1added: oneof_nested_message: { } +Required.Proto3.ProtobufInput.ValidDataOneof.UINT64.MultipleValuesForDifferentField.JsonOutput # JSON output we received from test was unparseable. +Required.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.JsonOutput # JSON output we received from test was unparseable. +Required.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.JsonOutput # JSON output we received from test was unparseable. +Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[4].JsonOutput # JSON output we received from test was unparseable. +Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[5].JsonOutput # JSON output we received from test was unparseable. +Required.Proto3.TimestampProtoInputTooLarge.JsonOutput # Should have failed to serialize, but didn't. +Required.Proto3.TimestampProtoInputTooSmall.JsonOutput # Should have failed to serialize, but didn't. +Required.Proto3.TimestampProtoNanoTooLarge.JsonOutput # Should have failed to serialize, but didn't. +Required.Proto3.TimestampProtoNegativeNanos.JsonOutput # Should have failed to serialize, but didn't. From 91771a828bcf677bd7d86a1af94876f7cd78d57b Mon Sep 17 00:00:00 2001 From: Adrien Vannson Date: Thu, 20 Nov 2025 17:51:01 +0100 Subject: [PATCH 07/12] Format proto files --- .../tests/inputs/conformance/conformance.proto | 8 ++++---- .../inputs/conformance/test_messages_proto3.proto | 14 ++++++-------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/betterproto2_compiler/tests/inputs/conformance/conformance.proto b/betterproto2_compiler/tests/inputs/conformance/conformance.proto index 3620dad..bbb7554 100644 --- a/betterproto2_compiler/tests/inputs/conformance/conformance.proto +++ b/betterproto2_compiler/tests/inputs/conformance/conformance.proto @@ -35,14 +35,14 @@ enum WireFormat { UNSPECIFIED = 0; PROTOBUF = 1; JSON = 2; - JSPB = 3; // Only used inside Google. Opensource testees just skip it. + JSPB = 3; // Only used inside Google. Opensource testees just skip it. TEXT_FORMAT = 4; } enum TestCategory { UNSPECIFIED_TEST = 0; - BINARY_TEST = 1; // Test binary wire format. - JSON_TEST = 2; // Test json wire format. + BINARY_TEST = 1; // Test binary wire format. + JSON_TEST = 2; // Test json wire format. // Similar to JSON_TEST. However, during parsing json, testee should ignore // unknown fields. This feature is optional. Each implementation can decide // whether to support it. See @@ -169,4 +169,4 @@ message ConformanceResponse { message JspbEncodingConfig { // Encode the value field of Any as jspb array if true, otherwise binary. bool use_jspb_array_any_format = 1; -} \ No newline at end of file +} diff --git a/betterproto2_compiler/tests/inputs/conformance/test_messages_proto3.proto b/betterproto2_compiler/tests/inputs/conformance/test_messages_proto3.proto index eb6b7bc..088e1ea 100644 --- a/betterproto2_compiler/tests/inputs/conformance/test_messages_proto3.proto +++ b/betterproto2_compiler/tests/inputs/conformance/test_messages_proto3.proto @@ -16,12 +16,6 @@ syntax = "proto3"; package protobuf_test_messages.proto3; -option java_package = "com.google.protobuf_test_messages.proto3"; -option objc_class_prefix = "Proto3"; - -// This is the default, but we specify it here explicitly. -option optimize_for = SPEED; - import "google/protobuf/any.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/field_mask.proto"; @@ -30,6 +24,10 @@ import "google/protobuf/timestamp.proto"; import "google/protobuf/wrappers.proto"; option cc_enable_arenas = true; +option java_package = "com.google.protobuf_test_messages.proto3"; +option objc_class_prefix = "Proto3"; +// This is the default, but we specify it here explicitly. +option optimize_for = SPEED; // This proto includes every type of field in both singular and repeated // forms. @@ -48,7 +46,7 @@ message TestAllTypesProto3 { FOO = 0; BAR = 1; BAZ = 2; - NEG = -1; // Intentionally negative. + NEG = -1; // Intentionally negative. } enum AliasedEnum { @@ -266,4 +264,4 @@ message EnumOnlyProto3 { kFalse = 0; kTrue = 1; } -} \ No newline at end of file +} From 0b1a00e733af642383c64a38824459941c072962 Mon Sep 17 00:00:00 2001 From: Adrien Vannson Date: Thu, 20 Nov 2025 18:01:04 +0100 Subject: [PATCH 08/12] Fix lint --- betterproto2/tests/conformance/main.py | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/betterproto2/tests/conformance/main.py b/betterproto2/tests/conformance/main.py index 0727b6b..0f3532c 100644 --- a/betterproto2/tests/conformance/main.py +++ b/betterproto2/tests/conformance/main.py @@ -21,7 +21,7 @@ class ProtocolError(Exception): def do_test(request: ConformanceRequest) -> ConformanceResponse: response = ConformanceResponse() - is_json = betterproto2.which_one_of(request, "payload")[0] == "json_payload" + # is_json = betterproto2.which_one_of(request, "payload")[0] == "json_payload" if request.message_type != "protobuf_test_messages.proto3.TestAllTypesProto3": return ConformanceResponse(skipped="non proto3 tests not supported") @@ -46,11 +46,6 @@ def do_test(request: ConformanceRequest) -> ConformanceResponse: elif betterproto2.which_one_of(request, "payload")[0] == "text_payload": return ConformanceResponse(skipped="text input not supported") - try: - text_format.Parse(request.text_payload, test_message) - except Exception as e: - response.parse_error = str(e) - return response else: raise ProtocolError("Request didn't have payload.") @@ -85,12 +80,12 @@ def do_test_io(): if len(length_bytes) == 0: return False # EOF elif len(length_bytes) != 4: - raise IOError("I/O error") + raise OSError("I/O error") length = struct.unpack(" Date: Thu, 20 Nov 2025 18:02:49 +0100 Subject: [PATCH 09/12] Format code --- betterproto2/tests/conformance/main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/betterproto2/tests/conformance/main.py b/betterproto2/tests/conformance/main.py index 0f3532c..57d09ac 100644 --- a/betterproto2/tests/conformance/main.py +++ b/betterproto2/tests/conformance/main.py @@ -113,5 +113,7 @@ def do_test_io(): while True: if not do_test_io(): - print("conformance_python: received EOF from test runner after", test_count, "tests, exiting\n", file=sys.stderr) + print( + "conformance_python: received EOF from test runner after", test_count, "tests, exiting\n", file=sys.stderr + ) sys.exit(0) From 25c32c17ca1119d400bb0cf4676b8748117137f0 Mon Sep 17 00:00:00 2001 From: Adrien Vannson Date: Thu, 20 Nov 2025 18:03:26 +0100 Subject: [PATCH 10/12] Add back full CI --- .github/workflows/ci.yml | 225 +++++++++++++++++++-------------------- 1 file changed, 111 insertions(+), 114 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e6f83d6..dba9f85 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,154 +12,154 @@ permissions: contents: read jobs: - # test-dependencies: - # name: Check running without dependencies - # runs-on: ubuntu-latest - # steps: - # - uses: actions/checkout@v4 - - # - name: Install uv with Python 3.12 - # uses: astral-sh/setup-uv@v5 - # with: - # version: "0.7.5" - # python-version: "3.12" + test-dependencies: + name: Check running without dependencies + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 - # - name: Install betterproto2 - # working-directory: ./betterproto2 - # run: uv sync --locked + - name: Install uv with Python 3.12 + uses: astral-sh/setup-uv@v5 + with: + version: "0.7.5" + python-version: "3.12" - # - name: Install betterproto2_compiler - # working-directory: ./betterproto2_compiler - # run: uv sync --locked + - name: Install betterproto2 + working-directory: ./betterproto2 + run: uv sync --locked - # - name: Compile test files - # working-directory: ./betterproto2_compiler - # shell: bash - # run: uv run poe generate + - name: Install betterproto2_compiler + working-directory: ./betterproto2_compiler + run: uv sync --locked - # - name: Move compiled files to betterproto2 - # shell: bash - # run: cp -r betterproto2_compiler/tests/outputs betterproto2/tests + - name: Compile test files + working-directory: ./betterproto2_compiler + shell: bash + run: uv run poe generate - # - name: Execute test suite - # working-directory: ./betterproto2 - # run: uv run poe test + - name: Move compiled files to betterproto2 + shell: bash + run: cp -r betterproto2_compiler/tests/outputs betterproto2/tests + - name: Execute test suite + working-directory: ./betterproto2 + run: uv run poe test - # - name: Add Pydantic - # working-directory: ./betterproto2 - # run: uv sync --locked --extra=pydantic - # - name: Execute test suite - # working-directory: ./betterproto2 - # run: uv run poe test + - name: Add Pydantic + working-directory: ./betterproto2 + run: uv sync --locked --extra=pydantic + - name: Execute test suite + working-directory: ./betterproto2 + run: uv run poe test - # - name: Add all but Pydantic - # working-directory: ./betterproto2 - # run: uv sync --locked --extra=grpclib --extra=grpcio --extra=protobuf - # - name: Execute test suite - # working-directory: ./betterproto2 - # run: uv run poe test + - name: Add all but Pydantic + working-directory: ./betterproto2 + run: uv sync --locked --extra=grpclib --extra=grpcio --extra=protobuf + - name: Execute test suite + working-directory: ./betterproto2 + run: uv run poe test - # - name: Add grpclib - # working-directory: ./betterproto2 - # run: uv sync --locked --extra=grpclib - # - name: Execute test suite - # working-directory: ./betterproto2 - # run: uv run poe test + - name: Add grpclib + working-directory: ./betterproto2 + run: uv sync --locked --extra=grpclib + - name: Execute test suite + working-directory: ./betterproto2 + run: uv run poe test - # - name: Add all but grpclib - # working-directory: ./betterproto2 - # run: uv sync --locked --extra=pydantic --extra=grpcio --extra=protobuf - # - name: Execute test suite - # working-directory: ./betterproto2 - # run: uv run poe test + - name: Add all but grpclib + working-directory: ./betterproto2 + run: uv sync --locked --extra=pydantic --extra=grpcio --extra=protobuf + - name: Execute test suite + working-directory: ./betterproto2 + run: uv run poe test - # - name: Add grpcio - # working-directory: ./betterproto2 - # run: uv sync --locked --extra=grpcio - # - name: Execute test suite - # working-directory: ./betterproto2 - # run: uv run poe test + - name: Add grpcio + working-directory: ./betterproto2 + run: uv sync --locked --extra=grpcio + - name: Execute test suite + working-directory: ./betterproto2 + run: uv run poe test - # - name: Add all but grpcio - # working-directory: ./betterproto2 - # run: uv sync --locked --extra=pydantic --extra=grpclib --extra=protobuf - # - name: Execute test suite - # working-directory: ./betterproto2 - # run: uv run poe test + - name: Add all but grpcio + working-directory: ./betterproto2 + run: uv sync --locked --extra=pydantic --extra=grpclib --extra=protobuf + - name: Execute test suite + working-directory: ./betterproto2 + run: uv run poe test - # - name: Add protobuf - # working-directory: ./betterproto2 - # run: uv sync --locked --extra=protobuf - # - name: Execute test suite - # working-directory: ./betterproto2 - # run: uv run poe test + - name: Add protobuf + working-directory: ./betterproto2 + run: uv sync --locked --extra=protobuf + - name: Execute test suite + working-directory: ./betterproto2 + run: uv run poe test - # - name: Add all but protobuf - # working-directory: ./betterproto2 - # run: uv sync --locked --extra=pydantic --extra=grpclib --extra=grpcio - # - name: Execute test suite - # working-directory: ./betterproto2 - # run: uv run poe test + - name: Add all but protobuf + working-directory: ./betterproto2 + run: uv sync --locked --extra=pydantic --extra=grpclib --extra=grpcio - # tests: - # name: ${{ matrix.os }} / ${{ matrix.python-version }} - # runs-on: ${{ matrix.os }}-latest - # strategy: - # fail-fast: false - # matrix: - # os: [Ubuntu, MacOS, Windows] - # python-version: ['3.10', '3.11', '3.12', '3.13'] - # steps: - # - uses: actions/checkout@v4 + - name: Execute test suite + working-directory: ./betterproto2 + run: uv run poe test + + tests: + name: ${{ matrix.os }} / ${{ matrix.python-version }} + runs-on: ${{ matrix.os }}-latest + strategy: + fail-fast: false + matrix: + os: [Ubuntu, MacOS, Windows] + python-version: ['3.10', '3.11', '3.12', '3.13'] + steps: + - uses: actions/checkout@v4 - # - name: Install uv with Python ${{ matrix.python-version }} - # uses: astral-sh/setup-uv@v5 - # with: - # version: "0.7.5" - # python-version: ${{ matrix.python-version }} + - name: Install uv with Python ${{ matrix.python-version }} + uses: astral-sh/setup-uv@v5 + with: + version: "0.7.5" + python-version: ${{ matrix.python-version }} - # - name: Install betterproto2 - # working-directory: ./betterproto2 - # run: uv sync --locked --all-extras --all-groups + - name: Install betterproto2 + working-directory: ./betterproto2 + run: uv sync --locked --all-extras --all-groups - # - name: Install betterproto2_compiler - # working-directory: ./betterproto2_compiler - # run: uv sync --locked --all-extras --all-groups + - name: Install betterproto2_compiler + working-directory: ./betterproto2_compiler + run: uv sync --locked --all-extras --all-groups - # - name: Test betterproto2_compiler - # working-directory: ./betterproto2_compiler - # shell: bash - # run: uv run poe test + - name: Test betterproto2_compiler + working-directory: ./betterproto2_compiler + shell: bash + run: uv run poe test - # - name: Compile test files - # working-directory: ./betterproto2_compiler - # shell: bash - # run: uv run poe generate + - name: Compile test files + working-directory: ./betterproto2_compiler + shell: bash + run: uv run poe generate - # - name: Move compiled files to betterproto2 - # shell: bash - # run: cp -r betterproto2_compiler/tests/outputs betterproto2/tests + - name: Move compiled files to betterproto2 + shell: bash + run: cp -r betterproto2_compiler/tests/outputs betterproto2/tests - # - name: Execute test suite - # working-directory: ./betterproto2 - # shell: bash - # run: uv run poe test + - name: Execute test suite + working-directory: ./betterproto2 + shell: bash + run: uv run poe test conformance: runs-on: ubuntu-latest @@ -175,9 +175,6 @@ jobs: - name: Install conformance runner run: npm install -g protobuf-conformance - # - name: Verify runner - # run: conformance_test_runner --help - - name: Install uv with Python 3.10 uses: astral-sh/setup-uv@v5 with: From 5310d7459fbf945175c622c155546ad731c464f1 Mon Sep 17 00:00:00 2001 From: Adrien Vannson Date: Thu, 20 Nov 2025 18:20:19 +0100 Subject: [PATCH 11/12] Run conformance tests with all Python versions on MacOS and Ubuntu --- .github/workflows/ci.yml | 34 +++++----------------------------- 1 file changed, 5 insertions(+), 29 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dba9f85..22ed7b5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -161,44 +161,19 @@ jobs: shell: bash run: uv run poe test - conformance: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - + # Run conformance test on all Ubuntu and MacOS versions - name: Install Node.js + if: matrix.os == 'Ubuntu' || matrix.os == 'MacOS' uses: actions/setup-node@v6 with: node-version: 24 - name: Install conformance runner + if: matrix.os == 'Ubuntu' || matrix.os == 'MacOS' run: npm install -g protobuf-conformance - - name: Install uv with Python 3.10 - uses: astral-sh/setup-uv@v5 - with: - version: "0.7.5" - python-version: "3.10" - - - name: Install betterproto2 - working-directory: ./betterproto2 - run: uv sync --locked --all-extras --all-groups - - - name: Install betterproto2_compiler - working-directory: ./betterproto2_compiler - run: uv sync --locked --all-extras --all-groups - - - name: Compile test files - working-directory: ./betterproto2_compiler - shell: bash - run: uv run poe generate - - - name: Move compiled files to betterproto2 - shell: bash - run: cp -r betterproto2_compiler/tests/outputs betterproto2/tests - - name: Create test script + if: matrix.os == 'Ubuntu' || matrix.os == 'MacOS' shell: bash working-directory: ./betterproto2 run: | @@ -207,6 +182,7 @@ jobs: chmod +x script.sh - name: Run conformance tests + if: matrix.os == 'Ubuntu' || matrix.os == 'MacOS' working-directory: ./betterproto2 run: | uv run conformance_test_runner --failure_list tests/conformance/failing_tests.txt ./script.sh From 80e4ac8837131f886663af5c375b5b1eaa3eaf30 Mon Sep 17 00:00:00 2001 From: Adrien Vannson Date: Thu, 20 Nov 2025 18:24:47 +0100 Subject: [PATCH 12/12] Pin conformance test version --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 22ed7b5..47a2356 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -170,7 +170,7 @@ jobs: - name: Install conformance runner if: matrix.os == 'Ubuntu' || matrix.os == 'MacOS' - run: npm install -g protobuf-conformance + run: npm install -g protobuf-conformance@33.1.0 - name: Create test script if: matrix.os == 'Ubuntu' || matrix.os == 'MacOS'