Skip to content

Commit a937bfc

Browse files
authored
Fix protobuf 6.x compatibility: regenerate v6 with gencode floor 6.30.0 (#840)
The v6 stubs were generated with grpcio-tools 1.76.0, which embeds a gencode floor of 6.31.1. The ValidateProtobufRuntimeVersion check is patch-strict, so any user on protobuf 6.0-6.31.0 (all allowed by requirements.txt protobuf<7.0.0) failed at `import ydb` with a VersionError. Regenerate v6 with grpcio-tools 1.72.1 (bundled protoc 30.0), lowering the floor to 6.30.0 -- the lowest existing 6.x release -- so the entire protobuf 6 major is covered. This also lowers the grpc-side floor (GRPC_GENERATED_VERSION) from 1.76.0 to 1.72.1, the minimum achievable for protoc 30.0. Clean up the generation script: protoc is taken solely from the protoc bundled inside grpcio-tools, so drop the unused standalone protoc download, PROTOC_VER, PY_PROTOBUF_VER and grpclib from the Dockerfile; make GRPCIO_VER explicit per target in the Makefile, document the grpcio-tools -> protoc -> gencode mapping, and add the missing protobuf-6 to the aggregate `protobuf` target.
1 parent d5e3b8b commit a937bfc

107 files changed

Lines changed: 308 additions & 312 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
* Fix incompatibility with protobuf 6.30–6.31.0: regenerate v6 stubs with the lowest 6.x gencode floor (6.30.0) instead of 6.31.1
2+
13
## 3.29.4 ##
24
* Fix leaked topic reader stream when close interrupts stream creation during reconnect
35
* Include reconnector and read session ids in topic reader logs

Makefile

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
1-
protobuf: protobuf-3 protobuf-4 protobuf-5
1+
# protoc version (hence the generated gencode and, for protobuf >= 6, its embedded
2+
# runtime-version floor) is determined SOLELY by the grpcio-tools version pinned via
3+
# GRPCIO_VER below (see generate-protobuf.Dockerfile). Keep this table in sync:
4+
#
5+
# v3: grpcio-tools 1.39.0 -> protoc 3.17 -> protobuf 3.x old-style (runs on protobuf >= 3.13)
6+
# v4: grpcio-tools 1.50.0 -> protoc 21.x -> protobuf 4.21 builder (no runtime floor)
7+
# v5: grpcio-tools 1.50.0 -> protoc 21.x -> protobuf 4.21 builder (no runtime floor; serves 5.x)
8+
# v6: grpcio-tools 1.72.1 -> protoc 30.0 -> protobuf 6.30.0 gencode (floor 6.30.0, the lowest 6.x)
9+
#
10+
# v5 deliberately uses the same no-floor 4.21 gencode as v4: it maximizes the range of
11+
# installed protobuf 5.x runtimes it tolerates. Raising it to a "true" 5.x gencode would
12+
# only add a runtime-version floor and strand users below it.
13+
protobuf: protobuf-3 protobuf-4 protobuf-5 protobuf-6
214

315
protobuf-3:
4-
docker build -f generate-protobuf.Dockerfile . -t ydb-python-sdk-proto-generator-env-3 --build-arg GRPCIO_VER=1.39.0 --build-arg PY_PROTOBUF_VER=3.20.3
16+
docker build -f generate-protobuf.Dockerfile . -t ydb-python-sdk-proto-generator-env-3 --build-arg GRPCIO_VER=1.39.0
517
docker run --rm -it -v $${PWD}:$${PWD} -w $${PWD} ydb-python-sdk-proto-generator-env-3 python generate_protoc.py --target-version=v3
618

719
protobuf-4:
8-
docker build -f generate-protobuf.Dockerfile . -t ydb-python-sdk-proto-generator-env-4
20+
docker build -f generate-protobuf.Dockerfile . -t ydb-python-sdk-proto-generator-env-4 --build-arg GRPCIO_VER=1.50.0
921
docker run --rm -it -v $${PWD}:$${PWD} -w $${PWD} ydb-python-sdk-proto-generator-env-4 python generate_protoc.py --target-version=v4
1022

1123
protobuf-5:
12-
docker build -f generate-protobuf.Dockerfile . -t ydb-python-sdk-proto-generator-env-5 --build-arg PY_PROTOBUF_VER=5.26.1 --build-arg PROTOC_VER=26.1
24+
docker build -f generate-protobuf.Dockerfile . -t ydb-python-sdk-proto-generator-env-5 --build-arg GRPCIO_VER=1.50.0
1325
docker run --rm -it -v $${PWD}:$${PWD} -w $${PWD} ydb-python-sdk-proto-generator-env-5 python generate_protoc.py --target-version=v5
1426

1527
protobuf-6:
16-
docker build -f generate-protobuf.Dockerfile . -t ydb-python-sdk-proto-generator-env-6 --build-arg GRPCIO_VER=1.76.0 --build-arg PY_PROTOBUF_VER=6.30.2 --build-arg PROTOC_VER=30.2
17-
docker run --rm -it -v $${PWD}:$${PWD} -w $${PWD} ydb-python-sdk-proto-generator-env-6 python generate_protoc.py --target-version=v6
28+
docker build -f generate-protobuf.Dockerfile . -t ydb-python-sdk-proto-generator-env-6 --build-arg GRPCIO_VER=1.72.1
29+
docker run --rm -it -v $${PWD}:$${PWD} -w $${PWD} ydb-python-sdk-proto-generator-env-6 python generate_protoc.py --target-version=v6

generate-protobuf.Dockerfile

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1+
# The *_pb2.py / *_pb2_grpc.py stubs are produced by the protoc that ships INSIDE
2+
# grpcio-tools (generate_protoc.py -> grpc_tools.command.build_package_protos uses the
3+
# bundled protoc, NOT a standalone one). Therefore GRPCIO_VER is the ONLY knob that
4+
# controls the generated gencode version and, for protobuf >= 6, its embedded
5+
# runtime-version floor. grpcio-tools pulls a compatible protobuf runtime transitively.
6+
#
7+
# grpcio-tools 1.39.0 -> protoc 3.17 -> protobuf 3.x old-style gencode (v3)
8+
# grpcio-tools 1.50.0 -> protoc 21.x -> protobuf 4.21 builder gencode (v4, v5)
9+
# grpcio-tools 1.72.1 -> protoc 30.0 -> protobuf 6.30.0 gencode (floor 6.30.0) (v6)
110
FROM python:3.9.15
2-
ENV GRPCLIB_VER=0.4.3
311
ARG GRPCIO_VER=1.50.0
4-
ARG PY_PROTOBUF_VER=4.21.9
5-
RUN \
6-
python -m pip install --upgrade pip && \
7-
python -m pip install grpcio==${GRPCIO_VER} && \
8-
python -m pip install grpclib==${GRPCLIB_VER} && \
9-
python -m pip install grpcio-tools==${GRPCIO_VER} && \
10-
python -m pip install protobuf==${PY_PROTOBUF_VER}
11-
12-
ARG PROTOC_VER=21.8
13-
RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VER}/protoc-${PROTOC_VER}-linux-x86_64.zip && \
14-
unzip protoc-*.zip && \
15-
rm -f protoc-*.zip && \
16-
mv bin/protoc /usr/local/bin/protoc && \
17-
mv include well-known-protos
12+
RUN python -m pip install --upgrade pip && \
13+
python -m pip install "grpcio-tools==${GRPCIO_VER}"
14+
# Surface the real protoc version that will generate the stubs (catches silent drift).
15+
RUN python -m grpc_tools.protoc --version

ydb/_grpc/v6/draft/protos/ydb_dynamic_config_pb2.py

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ydb/_grpc/v6/draft/protos/ydb_dynamic_config_pb2_grpc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import warnings
55

66

7-
GRPC_GENERATED_VERSION = '1.76.0'
7+
GRPC_GENERATED_VERSION = '1.72.1'
88
GRPC_VERSION = grpc.__version__
99
_version_not_supported = False
1010

@@ -17,7 +17,7 @@
1717
if _version_not_supported:
1818
raise RuntimeError(
1919
f'The grpc package installed is at version {GRPC_VERSION},'
20-
+ ' but the generated code in draft/protos/ydb_dynamic_config_pb2_grpc.py depends on'
20+
+ f' but the generated code in draft/protos/ydb_dynamic_config_pb2_grpc.py depends on'
2121
+ f' grpcio>={GRPC_GENERATED_VERSION}.'
2222
+ f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
2323
+ f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'

ydb/_grpc/v6/draft/protos/ydb_federated_query_pb2.py

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ydb/_grpc/v6/draft/protos/ydb_federated_query_pb2.pyi

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import datetime
2-
31
from protos.annotations import sensitive_pb2 as _sensitive_pb2
42
from protos.annotations import validation_pb2 as _validation_pb2
53
from protos import ydb_operation_pb2 as _ydb_operation_pb2
@@ -101,20 +99,20 @@ class Limits(_message.Message):
10199
result_ttl: _duration_pb2.Duration
102100
execution_timeout: _duration_pb2.Duration
103101
execution_deadline: _timestamp_pb2.Timestamp
104-
def __init__(self, vcpu_rate_limit: _Optional[int] = ..., flow_rate_limit: _Optional[int] = ..., vcpu_time_limit: _Optional[int] = ..., max_result_size: _Optional[int] = ..., max_result_rows: _Optional[int] = ..., memory_limit: _Optional[int] = ..., result_ttl: _Optional[_Union[datetime.timedelta, _duration_pb2.Duration, _Mapping]] = ..., execution_timeout: _Optional[_Union[datetime.timedelta, _duration_pb2.Duration, _Mapping]] = ..., execution_deadline: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ...
102+
def __init__(self, vcpu_rate_limit: _Optional[int] = ..., flow_rate_limit: _Optional[int] = ..., vcpu_time_limit: _Optional[int] = ..., max_result_size: _Optional[int] = ..., max_result_rows: _Optional[int] = ..., memory_limit: _Optional[int] = ..., result_ttl: _Optional[_Union[_duration_pb2.Duration, _Mapping]] = ..., execution_timeout: _Optional[_Union[_duration_pb2.Duration, _Mapping]] = ..., execution_deadline: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ...
105103

106104
class StreamingDisposition(_message.Message):
107105
__slots__ = ("oldest", "fresh", "from_time", "time_ago", "from_last_checkpoint")
108106
class FromTime(_message.Message):
109107
__slots__ = ("timestamp",)
110108
TIMESTAMP_FIELD_NUMBER: _ClassVar[int]
111109
timestamp: _timestamp_pb2.Timestamp
112-
def __init__(self, timestamp: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ...
110+
def __init__(self, timestamp: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ...
113111
class TimeAgo(_message.Message):
114112
__slots__ = ("duration",)
115113
DURATION_FIELD_NUMBER: _ClassVar[int]
116114
duration: _duration_pb2.Duration
117-
def __init__(self, duration: _Optional[_Union[datetime.timedelta, _duration_pb2.Duration, _Mapping]] = ...) -> None: ...
115+
def __init__(self, duration: _Optional[_Union[_duration_pb2.Duration, _Mapping]] = ...) -> None: ...
118116
class FromLastCheckpoint(_message.Message):
119117
__slots__ = ("force",)
120118
FORCE_FIELD_NUMBER: _ClassVar[int]
@@ -200,7 +198,7 @@ class CommonMeta(_message.Message):
200198
created_at: _timestamp_pb2.Timestamp
201199
modified_at: _timestamp_pb2.Timestamp
202200
revision: int
203-
def __init__(self, id: _Optional[str] = ..., created_by: _Optional[str] = ..., modified_by: _Optional[str] = ..., created_at: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ..., modified_at: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ..., revision: _Optional[int] = ...) -> None: ...
201+
def __init__(self, id: _Optional[str] = ..., created_by: _Optional[str] = ..., modified_by: _Optional[str] = ..., created_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ..., modified_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ..., revision: _Optional[int] = ...) -> None: ...
204202

205203
class QueryMeta(_message.Message):
206204
__slots__ = ("common", "submitted_at", "started_at", "finished_at", "execute_mode", "status", "last_job_query_revision", "last_job_id", "expire_at", "result_expire_at", "started_by", "aborted_by", "paused_by", "has_saved_checkpoints")
@@ -262,7 +260,7 @@ class QueryMeta(_message.Message):
262260
aborted_by: str
263261
paused_by: str
264262
has_saved_checkpoints: bool
265-
def __init__(self, common: _Optional[_Union[CommonMeta, _Mapping]] = ..., submitted_at: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ..., started_at: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ..., finished_at: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ..., execute_mode: _Optional[_Union[ExecuteMode, str]] = ..., status: _Optional[_Union[QueryMeta.ComputeStatus, str]] = ..., last_job_query_revision: _Optional[int] = ..., last_job_id: _Optional[str] = ..., expire_at: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ..., result_expire_at: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ..., started_by: _Optional[str] = ..., aborted_by: _Optional[str] = ..., paused_by: _Optional[str] = ..., has_saved_checkpoints: bool = ...) -> None: ...
263+
def __init__(self, common: _Optional[_Union[CommonMeta, _Mapping]] = ..., submitted_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ..., started_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ..., finished_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ..., execute_mode: _Optional[_Union[ExecuteMode, str]] = ..., status: _Optional[_Union[QueryMeta.ComputeStatus, str]] = ..., last_job_query_revision: _Optional[int] = ..., last_job_id: _Optional[str] = ..., expire_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ..., result_expire_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ..., started_by: _Optional[str] = ..., aborted_by: _Optional[str] = ..., paused_by: _Optional[str] = ..., has_saved_checkpoints: bool = ...) -> None: ...
266264

267265
class BriefQuery(_message.Message):
268266
__slots__ = ("type", "name", "meta", "visibility", "automatic")
@@ -535,7 +533,7 @@ class BriefJob(_message.Message):
535533
visibility: Acl.Visibility
536534
automatic: bool
537535
expire_at: _timestamp_pb2.Timestamp
538-
def __init__(self, meta: _Optional[_Union[CommonMeta, _Mapping]] = ..., query_meta: _Optional[_Union[QueryMeta, _Mapping]] = ..., query_name: _Optional[str] = ..., visibility: _Optional[_Union[Acl.Visibility, str]] = ..., automatic: bool = ..., expire_at: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ...
536+
def __init__(self, meta: _Optional[_Union[CommonMeta, _Mapping]] = ..., query_meta: _Optional[_Union[QueryMeta, _Mapping]] = ..., query_name: _Optional[str] = ..., visibility: _Optional[_Union[Acl.Visibility, str]] = ..., automatic: bool = ..., expire_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ...
539537

540538
class Job(_message.Message):
541539
__slots__ = ("meta", "text", "query_meta", "plan", "issue", "statistics", "result_set_meta", "ast", "query_name", "acl", "automatic", "expire_at", "syntax", "parameters")
@@ -574,7 +572,7 @@ class Job(_message.Message):
574572
expire_at: _timestamp_pb2.Timestamp
575573
syntax: QueryContent.QuerySyntax
576574
parameters: _containers.MessageMap[str, _ydb_value_pb2.TypedValue]
577-
def __init__(self, meta: _Optional[_Union[CommonMeta, _Mapping]] = ..., text: _Optional[str] = ..., query_meta: _Optional[_Union[QueryMeta, _Mapping]] = ..., plan: _Optional[_Union[QueryPlan, _Mapping]] = ..., issue: _Optional[_Iterable[_Union[_ydb_issue_message_pb2.IssueMessage, _Mapping]]] = ..., statistics: _Optional[_Union[QueryStatistics, _Mapping]] = ..., result_set_meta: _Optional[_Iterable[_Union[ResultSetMeta, _Mapping]]] = ..., ast: _Optional[_Union[QueryAst, _Mapping]] = ..., query_name: _Optional[str] = ..., acl: _Optional[_Union[Acl, _Mapping]] = ..., automatic: bool = ..., expire_at: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ..., syntax: _Optional[_Union[QueryContent.QuerySyntax, str]] = ..., parameters: _Optional[_Mapping[str, _ydb_value_pb2.TypedValue]] = ...) -> None: ...
575+
def __init__(self, meta: _Optional[_Union[CommonMeta, _Mapping]] = ..., text: _Optional[str] = ..., query_meta: _Optional[_Union[QueryMeta, _Mapping]] = ..., plan: _Optional[_Union[QueryPlan, _Mapping]] = ..., issue: _Optional[_Iterable[_Union[_ydb_issue_message_pb2.IssueMessage, _Mapping]]] = ..., statistics: _Optional[_Union[QueryStatistics, _Mapping]] = ..., result_set_meta: _Optional[_Iterable[_Union[ResultSetMeta, _Mapping]]] = ..., ast: _Optional[_Union[QueryAst, _Mapping]] = ..., query_name: _Optional[str] = ..., acl: _Optional[_Union[Acl, _Mapping]] = ..., automatic: bool = ..., expire_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ..., syntax: _Optional[_Union[QueryContent.QuerySyntax, str]] = ..., parameters: _Optional[_Mapping[str, _ydb_value_pb2.TypedValue]] = ...) -> None: ...
578576

579577
class ListJobsRequest(_message.Message):
580578
__slots__ = ("operation_params", "page_token", "limit", "query_id", "filter")

ydb/_grpc/v6/draft/protos/ydb_federated_query_pb2_grpc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import warnings
55

66

7-
GRPC_GENERATED_VERSION = '1.76.0'
7+
GRPC_GENERATED_VERSION = '1.72.1'
88
GRPC_VERSION = grpc.__version__
99
_version_not_supported = False
1010

@@ -17,7 +17,7 @@
1717
if _version_not_supported:
1818
raise RuntimeError(
1919
f'The grpc package installed is at version {GRPC_VERSION},'
20-
+ ' but the generated code in draft/protos/ydb_federated_query_pb2_grpc.py depends on'
20+
+ f' but the generated code in draft/protos/ydb_federated_query_pb2_grpc.py depends on'
2121
+ f' grpcio>={GRPC_GENERATED_VERSION}.'
2222
+ f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
2323
+ f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'

ydb/_grpc/v6/draft/protos/ydb_keyvalue_pb2.py

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ydb/_grpc/v6/draft/protos/ydb_keyvalue_pb2_grpc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import warnings
55

66

7-
GRPC_GENERATED_VERSION = '1.76.0'
7+
GRPC_GENERATED_VERSION = '1.72.1'
88
GRPC_VERSION = grpc.__version__
99
_version_not_supported = False
1010

@@ -17,7 +17,7 @@
1717
if _version_not_supported:
1818
raise RuntimeError(
1919
f'The grpc package installed is at version {GRPC_VERSION},'
20-
+ ' but the generated code in draft/protos/ydb_keyvalue_pb2_grpc.py depends on'
20+
+ f' but the generated code in draft/protos/ydb_keyvalue_pb2_grpc.py depends on'
2121
+ f' grpcio>={GRPC_GENERATED_VERSION}.'
2222
+ f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
2323
+ f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'

0 commit comments

Comments
 (0)