From 7e3ece2d2cf340b08f0cf0e54332db010b182537 Mon Sep 17 00:00:00 2001 From: Matthew McNeely Date: Tue, 29 Jul 2025 14:01:15 -0400 Subject: [PATCH 01/14] Bump min grpcio version, pin grpcio-tools to 1.65.x --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 3052276..00d45ce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,14 +22,14 @@ classifiers = [ 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', ] -dependencies = ["grpcio>=1.56.0,<2.0.0", "protobuf>=4.23.0,<7.0.0"] +dependencies = ["grpcio>=1.65.0,<2.0.0", "protobuf>=4.23.0,<7.0.0"] dynamic = ["version"] [tool.setuptools.dynamic] version = { attr = "pydgraph.meta.VERSION" } [project.optional-dependencies] -dev = ["build>=1.2.2.post1", "grpcio-tools>=1.68.0", "pytest>=8.3.3"] +dev = ["build>=1.2.2.post1", "grpcio-tools>=1.65.0,<1.66.0", "pytest>=8.3.3"] [project.urls] "Homepage" = "https://github.com/hypermodeinc/pydgraph" From d8f54296ee22c0eb7b0c9639288e120d0e032b28 Mon Sep 17 00:00:00 2001 From: Matthew McNeely Date: Tue, 29 Jul 2025 14:01:37 -0400 Subject: [PATCH 02/14] Update README --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index d9b3d93..5f5beb2 100644 --- a/README.md +++ b/README.md @@ -606,6 +606,24 @@ source files generated by Protocol Buffer tools. To do that, install the python scripts/protogen.py ``` +**Important**: This project uses grpcio-tools 1.65.x to ensure compatibility with the minimum +supported grpcio version (1.65.0). This version generates code that issues warnings (not errors) for +users with older grpcio versions, providing a graceful upgrade path. It also uses protobuf 5.x which +eliminates Python 3.12+ deprecation warnings. The dev dependencies in `pyproject.toml` are pinned to +the correct version ("grpcio-tools>=1.65.0,<1.66.0") + +#### grpcio 1.65.0 is the minimum version + +While we would prefer to support older grpcio versions, practical limitations prevent this: + +- **Compilation failures**: grpcio versions older than ~1.60.0 fail to compile from source on modern + systems (macOS with recent Xcode, newer Linux distributions) due to C++ compiler compatibility + issues and outdated build configurations. +- **No pre-built wheels**: PyPI doesn't provide pre-built wheels for very old grpcio versions on + modern Python versions (3.11+), forcing compilation from source. +- **Build tool incompatibility**: The build process for older grpcio versions uses deprecated + compiler flags and build patterns that modern toolchains reject. + ### Running tests To run the tests in your local machine, run: From 9b7ed42afb9158cb8dfb9ca0e431fc4d11ed17b0 Mon Sep 17 00:00:00 2001 From: Matthew McNeely Date: Tue, 29 Jul 2025 14:01:52 -0400 Subject: [PATCH 03/14] Update changelog --- CHANGELOG.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee7f7be..a28b5e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [v24.3.0] - 2025-07-29 + +**Chore** + +- Bumped in minimum grpcio version to 1.65.0 +- Pinned the grpcio-tools version to 1.65.x + +**Chore** + +- Updated generated modules following a grpc deps update + ## [v24.2.1] 2025-04-02 -**_Chore_** +**Chore** - Updated generated modules following a grpc deps update From 76b474a5f8cb180f8cd821a60f537e15dd785f9c Mon Sep 17 00:00:00 2001 From: Matthew McNeely Date: Tue, 29 Jul 2025 14:02:05 -0400 Subject: [PATCH 04/14] Update version --- pydgraph/meta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydgraph/meta.py b/pydgraph/meta.py index 812302c..5336ef2 100644 --- a/pydgraph/meta.py +++ b/pydgraph/meta.py @@ -3,4 +3,4 @@ """Metadata about this package.""" -VERSION = "24.2.1" +VERSION = "24.3.0" From 83d92445bf5cdf1448baf4515b1d42ca3f20c230 Mon Sep 17 00:00:00 2001 From: Matthew McNeely Date: Tue, 29 Jul 2025 14:02:27 -0400 Subject: [PATCH 05/14] Update generated protobufs --- pydgraph/proto/api_pb2.py | 24 +++---- pydgraph/proto/api_pb2_grpc.py | 111 ++++++--------------------------- 2 files changed, 27 insertions(+), 108 deletions(-) diff --git a/pydgraph/proto/api_pb2.py b/pydgraph/proto/api_pb2.py index d891f39..e77d663 100644 --- a/pydgraph/proto/api_pb2.py +++ b/pydgraph/proto/api_pb2.py @@ -1,22 +1,12 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE # source: api.proto -# Protobuf Python Version: 5.29.0 +# Protobuf Python Version: 4.25.0 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 5, - 29, - 0, - '', - 'api.proto' -) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -29,16 +19,16 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'api_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None _globals['DESCRIPTOR']._serialized_options = b'\n\tio.dgraphB\013DgraphProtoZ(github.com/dgraph-io/dgo/v240/protos/api' - _globals['_REQUEST_VARSENTRY']._loaded_options = None + _globals['_REQUEST_VARSENTRY']._options = None _globals['_REQUEST_VARSENTRY']._serialized_options = b'8\001' - _globals['_RESPONSE_UIDSENTRY']._loaded_options = None + _globals['_RESPONSE_UIDSENTRY']._options = None _globals['_RESPONSE_UIDSENTRY']._serialized_options = b'8\001' - _globals['_RESPONSE_HDRSENTRY']._loaded_options = None + _globals['_RESPONSE_HDRSENTRY']._options = None _globals['_RESPONSE_HDRSENTRY']._serialized_options = b'8\001' - _globals['_METRICS_NUMUIDSENTRY']._loaded_options = None + _globals['_METRICS_NUMUIDSENTRY']._options = None _globals['_METRICS_NUMUIDSENTRY']._serialized_options = b'8\001' _globals['_REQUEST']._serialized_start=19 _globals['_REQUEST']._serialized_end=331 diff --git a/pydgraph/proto/api_pb2_grpc.py b/pydgraph/proto/api_pb2_grpc.py index 24dec7b..ed4c71d 100644 --- a/pydgraph/proto/api_pb2_grpc.py +++ b/pydgraph/proto/api_pb2_grpc.py @@ -1,29 +1,9 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! """Client and server classes corresponding to protobuf-defined services.""" import grpc -import warnings import api_pb2 as api__pb2 -GRPC_GENERATED_VERSION = '1.71.0' -GRPC_VERSION = grpc.__version__ -_version_not_supported = False - -try: - from grpc._utilities import first_version_is_lower - _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION) -except ImportError: - _version_not_supported = True - -if _version_not_supported: - raise RuntimeError( - f'The grpc package installed is at version {GRPC_VERSION},' - + f' but the generated code in api_pb2_grpc.py depends on' - + f' grpcio>={GRPC_GENERATED_VERSION}.' - + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' - + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' - ) - class DgraphStub(object): """Graph response. @@ -39,27 +19,27 @@ def __init__(self, channel): '/api.Dgraph/Login', request_serializer=api__pb2.LoginRequest.SerializeToString, response_deserializer=api__pb2.Response.FromString, - _registered_method=True) + ) self.Query = channel.unary_unary( '/api.Dgraph/Query', request_serializer=api__pb2.Request.SerializeToString, response_deserializer=api__pb2.Response.FromString, - _registered_method=True) + ) self.Alter = channel.unary_unary( '/api.Dgraph/Alter', request_serializer=api__pb2.Operation.SerializeToString, response_deserializer=api__pb2.Payload.FromString, - _registered_method=True) + ) self.CommitOrAbort = channel.unary_unary( '/api.Dgraph/CommitOrAbort', request_serializer=api__pb2.TxnContext.SerializeToString, response_deserializer=api__pb2.TxnContext.FromString, - _registered_method=True) + ) self.CheckVersion = channel.unary_unary( '/api.Dgraph/CheckVersion', request_serializer=api__pb2.Check.SerializeToString, response_deserializer=api__pb2.Version.FromString, - _registered_method=True) + ) class DgraphServicer(object): @@ -128,7 +108,6 @@ def add_DgraphServicer_to_server(servicer, server): generic_handler = grpc.method_handlers_generic_handler( 'api.Dgraph', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) - server.add_registered_method_handlers('api.Dgraph', rpc_method_handlers) # This class is part of an EXPERIMENTAL API. @@ -147,21 +126,11 @@ def Login(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/api.Dgraph/Login', + return grpc.experimental.unary_unary(request, target, '/api.Dgraph/Login', api__pb2.LoginRequest.SerializeToString, api__pb2.Response.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def Query(request, @@ -174,21 +143,11 @@ def Query(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/api.Dgraph/Query', + return grpc.experimental.unary_unary(request, target, '/api.Dgraph/Query', api__pb2.Request.SerializeToString, api__pb2.Response.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def Alter(request, @@ -201,21 +160,11 @@ def Alter(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/api.Dgraph/Alter', + return grpc.experimental.unary_unary(request, target, '/api.Dgraph/Alter', api__pb2.Operation.SerializeToString, api__pb2.Payload.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def CommitOrAbort(request, @@ -228,21 +177,11 @@ def CommitOrAbort(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/api.Dgraph/CommitOrAbort', + return grpc.experimental.unary_unary(request, target, '/api.Dgraph/CommitOrAbort', api__pb2.TxnContext.SerializeToString, api__pb2.TxnContext.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def CheckVersion(request, @@ -255,18 +194,8 @@ def CheckVersion(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/api.Dgraph/CheckVersion', + return grpc.experimental.unary_unary(request, target, '/api.Dgraph/CheckVersion', api__pb2.Check.SerializeToString, api__pb2.Version.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) From 446b752f4e0b9244bbbe43e69a4f9a73656270c0 Mon Sep 17 00:00:00 2001 From: Matthew McNeely Date: Tue, 29 Jul 2025 14:23:18 -0400 Subject: [PATCH 06/14] Update changelog --- CHANGELOG.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a28b5e1..ecf8ed1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,9 +11,6 @@ adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - Bumped in minimum grpcio version to 1.65.0 - Pinned the grpcio-tools version to 1.65.x - -**Chore** - - Updated generated modules following a grpc deps update ## [v24.2.1] 2025-04-02 From ff70aef9b52e2780e4e48c997140be3e09db67f4 Mon Sep 17 00:00:00 2001 From: Matthew McNeely Date: Tue, 29 Jul 2025 14:23:33 -0400 Subject: [PATCH 07/14] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f5beb2..8124376 100644 --- a/README.md +++ b/README.md @@ -610,7 +610,7 @@ python scripts/protogen.py supported grpcio version (1.65.0). This version generates code that issues warnings (not errors) for users with older grpcio versions, providing a graceful upgrade path. It also uses protobuf 5.x which eliminates Python 3.12+ deprecation warnings. The dev dependencies in `pyproject.toml` are pinned to -the correct version ("grpcio-tools>=1.65.0,<1.66.0") +the correct version (grpcio-tools 1.65.x) #### grpcio 1.65.0 is the minimum version From e1fe6fbf5b190055e0e78b19c47102855dc24e9e Mon Sep 17 00:00:00 2001 From: Matthew McNeely Date: Tue, 29 Jul 2025 14:24:00 -0400 Subject: [PATCH 08/14] Update correctly generated code --- pydgraph/proto/api_pb2.py | 14 ++-- pydgraph/proto/api_pb2_grpc.py | 116 +++++++++++++++++++++++++++------ 2 files changed, 103 insertions(+), 27 deletions(-) diff --git a/pydgraph/proto/api_pb2.py b/pydgraph/proto/api_pb2.py index e77d663..413f23b 100644 --- a/pydgraph/proto/api_pb2.py +++ b/pydgraph/proto/api_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: api.proto -# Protobuf Python Version: 4.25.0 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -19,16 +19,16 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'api_pb2', _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - _globals['DESCRIPTOR']._options = None +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None _globals['DESCRIPTOR']._serialized_options = b'\n\tio.dgraphB\013DgraphProtoZ(github.com/dgraph-io/dgo/v240/protos/api' - _globals['_REQUEST_VARSENTRY']._options = None + _globals['_REQUEST_VARSENTRY']._loaded_options = None _globals['_REQUEST_VARSENTRY']._serialized_options = b'8\001' - _globals['_RESPONSE_UIDSENTRY']._options = None + _globals['_RESPONSE_UIDSENTRY']._loaded_options = None _globals['_RESPONSE_UIDSENTRY']._serialized_options = b'8\001' - _globals['_RESPONSE_HDRSENTRY']._options = None + _globals['_RESPONSE_HDRSENTRY']._loaded_options = None _globals['_RESPONSE_HDRSENTRY']._serialized_options = b'8\001' - _globals['_METRICS_NUMUIDSENTRY']._options = None + _globals['_METRICS_NUMUIDSENTRY']._loaded_options = None _globals['_METRICS_NUMUIDSENTRY']._serialized_options = b'8\001' _globals['_REQUEST']._serialized_start=19 _globals['_REQUEST']._serialized_end=331 diff --git a/pydgraph/proto/api_pb2_grpc.py b/pydgraph/proto/api_pb2_grpc.py index ed4c71d..4b689dd 100644 --- a/pydgraph/proto/api_pb2_grpc.py +++ b/pydgraph/proto/api_pb2_grpc.py @@ -1,9 +1,34 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! """Client and server classes corresponding to protobuf-defined services.""" import grpc +import warnings import api_pb2 as api__pb2 +GRPC_GENERATED_VERSION = '1.65.5' +GRPC_VERSION = grpc.__version__ +EXPECTED_ERROR_RELEASE = '1.66.0' +SCHEDULED_RELEASE_DATE = 'August 6, 2024' +_version_not_supported = False + +try: + from grpc._utilities import first_version_is_lower + _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION) +except ImportError: + _version_not_supported = True + +if _version_not_supported: + warnings.warn( + f'The grpc package installed is at version {GRPC_VERSION},' + + f' but the generated code in api_pb2_grpc.py depends on' + + f' grpcio>={GRPC_GENERATED_VERSION}.' + + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' + + f' This warning will become an error in {EXPECTED_ERROR_RELEASE},' + + f' scheduled for release on {SCHEDULED_RELEASE_DATE}.', + RuntimeWarning + ) + class DgraphStub(object): """Graph response. @@ -19,27 +44,27 @@ def __init__(self, channel): '/api.Dgraph/Login', request_serializer=api__pb2.LoginRequest.SerializeToString, response_deserializer=api__pb2.Response.FromString, - ) + _registered_method=True) self.Query = channel.unary_unary( '/api.Dgraph/Query', request_serializer=api__pb2.Request.SerializeToString, response_deserializer=api__pb2.Response.FromString, - ) + _registered_method=True) self.Alter = channel.unary_unary( '/api.Dgraph/Alter', request_serializer=api__pb2.Operation.SerializeToString, response_deserializer=api__pb2.Payload.FromString, - ) + _registered_method=True) self.CommitOrAbort = channel.unary_unary( '/api.Dgraph/CommitOrAbort', request_serializer=api__pb2.TxnContext.SerializeToString, response_deserializer=api__pb2.TxnContext.FromString, - ) + _registered_method=True) self.CheckVersion = channel.unary_unary( '/api.Dgraph/CheckVersion', request_serializer=api__pb2.Check.SerializeToString, response_deserializer=api__pb2.Version.FromString, - ) + _registered_method=True) class DgraphServicer(object): @@ -108,6 +133,7 @@ def add_DgraphServicer_to_server(servicer, server): generic_handler = grpc.method_handlers_generic_handler( 'api.Dgraph', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) + server.add_registered_method_handlers('api.Dgraph', rpc_method_handlers) # This class is part of an EXPERIMENTAL API. @@ -126,11 +152,21 @@ def Login(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/api.Dgraph/Login', + return grpc.experimental.unary_unary( + request, + target, + '/api.Dgraph/Login', api__pb2.LoginRequest.SerializeToString, api__pb2.Response.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def Query(request, @@ -143,11 +179,21 @@ def Query(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/api.Dgraph/Query', + return grpc.experimental.unary_unary( + request, + target, + '/api.Dgraph/Query', api__pb2.Request.SerializeToString, api__pb2.Response.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def Alter(request, @@ -160,11 +206,21 @@ def Alter(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/api.Dgraph/Alter', + return grpc.experimental.unary_unary( + request, + target, + '/api.Dgraph/Alter', api__pb2.Operation.SerializeToString, api__pb2.Payload.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def CommitOrAbort(request, @@ -177,11 +233,21 @@ def CommitOrAbort(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/api.Dgraph/CommitOrAbort', + return grpc.experimental.unary_unary( + request, + target, + '/api.Dgraph/CommitOrAbort', api__pb2.TxnContext.SerializeToString, api__pb2.TxnContext.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def CheckVersion(request, @@ -194,8 +260,18 @@ def CheckVersion(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/api.Dgraph/CheckVersion', + return grpc.experimental.unary_unary( + request, + target, + '/api.Dgraph/CheckVersion', api__pb2.Check.SerializeToString, api__pb2.Version.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) From 2f2e884ddb2cd2846d1dc880ebae5bfec819fc18 Mon Sep 17 00:00:00 2001 From: Matthew McNeely Date: Tue, 29 Jul 2025 14:36:56 -0400 Subject: [PATCH 09/14] Update dev dependencies for python 3.13+ --- pyproject.toml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 00d45ce..0ff5774 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,14 @@ dynamic = ["version"] version = { attr = "pydgraph.meta.VERSION" } [project.optional-dependencies] -dev = ["build>=1.2.2.post1", "grpcio-tools>=1.65.0,<1.66.0", "pytest>=8.3.3"] +dev = [ + "build>=1.2.2.post1", + "grpcio-tools>=1.65.0,<1.66.0; python_version<'3.13'", + # Python 3.13 requires grpcio-tools >=1.66.2 + "grpcio-tools>=1.66.2; python_version>='3.13'", + "pytest>=8.3.3", +] + [project.urls] "Homepage" = "https://github.com/hypermodeinc/pydgraph" From ab7ef0f05cfb14f103630eaad2e83918745fcb51 Mon Sep 17 00:00:00 2001 From: Matthew McNeely Date: Tue, 29 Jul 2025 14:39:19 -0400 Subject: [PATCH 10/14] Reorder steps for quicker grpc failures --- .github/workflows/ci-pydgraph-tests.yml | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci-pydgraph-tests.yml b/.github/workflows/ci-pydgraph-tests.yml index 11a6435..33feac1 100644 --- a/.github/workflows/ci-pydgraph-tests.yml +++ b/.github/workflows/ci-pydgraph-tests.yml @@ -31,20 +31,6 @@ jobs: path: pydgraph repository: hypermodeinc/pydgraph ref: ${{ github.ref }} - - name: Checkout Dgraph repo # needed for acl tests - uses: actions/checkout@v4 - with: - path: dgraph - repository: hypermodeinc/dgraph - ref: main - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version-file: dgraph/go.mod - - name: Build dgraph binary - run: cd dgraph && make docker-image # also builds dgraph binary - - name: Move dgraph binary to gopath - run: cd dgraph && mv dgraph/dgraph ~/go/bin/dgraph - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: @@ -59,5 +45,19 @@ jobs: cd pydgraph python scripts/protogen.py git diff --exit-code -- . + - name: Checkout Dgraph repo # needed for acl tests + uses: actions/checkout@v4 + with: + path: dgraph + repository: hypermodeinc/dgraph + ref: main + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version-file: dgraph/go.mod + - name: Build dgraph binary + run: cd dgraph && make docker-image # also builds dgraph binary + - name: Move dgraph binary to gopath + run: cd dgraph && mv dgraph/dgraph ~/go/bin/dgraph - name: Run tests run: cd pydgraph && DGRAPH_IMAGE_TAG=local bash scripts/local-test.sh From 866afe8713e3a7d19240d4f129ecd3ba08fef2a4 Mon Sep 17 00:00:00 2001 From: Matthew McNeely Date: Tue, 29 Jul 2025 14:51:59 -0400 Subject: [PATCH 11/14] Raise an error if attempting to generate protobufs using python 3.13 --- scripts/protogen.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/protogen.py b/scripts/protogen.py index 7ca9cd6..1592e9a 100644 --- a/scripts/protogen.py +++ b/scripts/protogen.py @@ -4,9 +4,18 @@ """Runs protoc with the gRPC plugin to generate messages and gRPC stubs.""" import os +import sys from grpc_tools import protoc +# Check Python version compatibility +if sys.version_info >= (3, 13): + print("ERROR: Python 3.13+ requires grpcio-tools >=1.66.2, which generates") + print("protobufs that are incompatible with older grpcio-tools versions.") + print("Please use Python 3.12 or lower to generate compatible protobufs.") + print("Exiting without generating protobufs.") + sys.exit(1) + dirpath = os.path.dirname(os.path.realpath(__file__)) protopath = os.path.realpath(os.path.join(dirpath, "../pydgraph/proto")) From 95874544706d9802c07614c058675b1eb6cf670e Mon Sep 17 00:00:00 2001 From: Matthew McNeely Date: Tue, 29 Jul 2025 14:52:16 -0400 Subject: [PATCH 12/14] Update README --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8124376..708025f 100644 --- a/README.md +++ b/README.md @@ -596,6 +596,8 @@ To build and install pydgraph locally, run pip install -e ".[dev]" ``` +#### Regenerating protobufs + If you have made changes to the `pydgraph/proto/api.proto` file, you need need to regenerate the source files generated by Protocol Buffer tools. To do that, install the [grpcio-tools][grpcio-tools] library and then run the following command: @@ -612,9 +614,13 @@ users with older grpcio versions, providing a graceful upgrade path. It also use eliminates Python 3.12+ deprecation warnings. The dev dependencies in `pyproject.toml` are pinned to the correct version (grpcio-tools 1.65.x) +If you are using python version 3.13 or higher, an error will be raised if you try to run +`scripts/protogen.py`. This is to prevent generating protobufs that are incompatible with older +grpcio-tools versions. + #### grpcio 1.65.0 is the minimum version -While we would prefer to support older grpcio versions, practical limitations prevent this: +Older grpcio versions have practical limitations: - **Compilation failures**: grpcio versions older than ~1.60.0 fail to compile from source on modern systems (macOS with recent Xcode, newer Linux distributions) due to C++ compiler compatibility From 8da09177ba1b5f559eff362145eaf3578169f206 Mon Sep 17 00:00:00 2001 From: Matthew McNeely Date: Tue, 29 Jul 2025 15:02:21 -0400 Subject: [PATCH 13/14] Update the conditional step comparison logic !3.13 is not future proof --- .github/workflows/ci-pydgraph-tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci-pydgraph-tests.yml b/.github/workflows/ci-pydgraph-tests.yml index 33feac1..6d2af1b 100644 --- a/.github/workflows/ci-pydgraph-tests.yml +++ b/.github/workflows/ci-pydgraph-tests.yml @@ -41,6 +41,8 @@ jobs: python -m pip install --upgrade pip python -m pip install .[dev] - name: Verify that updated protobufs are checked in + if: ${{ matrix.python-version == '3.9' || matrix.python-version == '3.10' || + matrix.python-version == '3.11' || matrix.python-version == '3.12' }} # Skip for Python 3.13+ due to grpcio-tools compatibility run: | cd pydgraph python scripts/protogen.py From 246ff57378011301b99cbc130bcfe21b88b878b2 Mon Sep 17 00:00:00 2001 From: Matthew McNeely Date: Wed, 30 Jul 2025 13:24:37 -0400 Subject: [PATCH 14/14] Update CHANGELOG.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecf8ed1..1b8f50e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). **Chore** -- Bumped in minimum grpcio version to 1.65.0 +- Bumped minimum grpcio version to 1.65.0 - Pinned the grpcio-tools version to 1.65.x - Updated generated modules following a grpc deps update