Skip to content

Conversation

@bhatt4982
Copy link
Contributor

No description provided.

@bhatt4982 bhatt4982 requested a review from a team as a code owner December 1, 2025 11:13
@gemini-code-assist
Copy link

Summary of Changes

Hello @bhatt4982, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request establishes the foundational structure for a new Python wrapper around the Go Spanner client shared library. The primary goal is to offer a performant and Pythonic way to interact with Google Cloud Spanner. It introduces core components for managing connection pools, defines the necessary interoperability mechanisms with the Go library using ctypes, and sets up a robust development environment with automated testing and build processes.

Highlights

  • New Python Wrapper for Go Spanner Client: Introduced a new Python wrapper (spannerlib-python) designed to provide a high-performance, idiomatic Python interface for Google Cloud Spanner by wrapping the official Go Client Shared library. This leverages Go's performance with Python's ease of use.
  • Core Pool Class Implementation: Added the Pool class, which serves as the primary entry point for managing connections to the Spanner database. It handles the lifecycle of connection pools, including creation and graceful closure, and implements the context manager protocol for resource management.
  • Ctypes-based Go Interoperability Layer: Developed a robust internal module (google.cloud.spannerlib.internal) using ctypes to facilitate seamless communication with the underlying Go shared library. This includes custom Message, GoString, and GoSlice structures for data exchange and error handling, as well as a singleton SpannerLib class to manage the native library.
  • Automated Build and Test Workflow: Integrated nox for comprehensive development workflow automation, covering code formatting (black, isort), linting (flake8), unit testing, and system testing against a Spanner emulator. A build-shared-lib.sh script was also added to manage the compilation and copying of platform-specific native binaries.
  • Comprehensive Testing Suite: Included extensive unit tests for the internal ctypes interop, error handling, and the Pool class, alongside system tests to validate end-to-end functionality against a Spanner emulator.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

The pull request introduces the Pool class and its associated tests, along with the foundational AbstractLibraryObject, SpannerLib (for interacting with the Go shared library), and Message (for C interop) classes. The changes also include necessary build scripts, configuration files (pyproject.toml, noxfile.py), and documentation (README.md).

Overall, the new components are well-structured and include unit and system tests, which is commendable. However, there are several areas for improvement related to maintainability, robustness, and adherence to Python best practices, particularly concerning logging, error handling, type hinting, and resource management.

Key areas for attention include:

  • Logging Configuration: Avoid configuring basicConfig at the library root to prevent interference with user applications.
  • Error Handling: Ensure consistent and informative error propagation, especially when re-raising exceptions.
  • Type Hinting: Address type: ignore comments by resolving underlying issues or providing specific justifications.
  • Resource Management: Refine __del__ implementations and ctypes interactions for better memory safety and clarity.
  • Build Scripts & Configuration: Review hardcoded values and ensure paths are robust.

Addressing these points will enhance the library's stability, ease of use, and integration into larger Python projects.

assert "Unexpected error: Something weird happened" in msg

def test_close_pool_success(
self, mock_lib_instance, setup_spannerlib_method, mock_msg_data

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While pylint: disable=redefined-outer-name can be necessary, it's often a sign that variable naming or fixture usage could be improved to avoid shadowing. Consider renaming the mock_msg_data parameter in this test method to avoid the conflict.


# 3. Assertions
mock_lib_instance.close_pool.assert_called_once_with(100)
assert pool._is_disposed is True # pylint: disable=protected-access

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Directly accessing protected members like _is_disposed is generally discouraged. Consider if there's a more public or intended way to interact with this attribute for testing purposes, or if the test itself could be refactored.


def test_close_pool_propagates_lib_error(
self, mock_lib_instance, setup_spannerlib_method, mock_msg_data
): # pylint: disable=redefined-outer-name

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While pylint: disable=redefined-outer-name can be necessary, it's often a sign that variable naming or fixture usage could be improved to avoid shadowing. Consider renaming the mock_msg_data parameter in this test method to avoid the conflict.

assert "Failed to release" in str(exc_info.value)

def test_close_pool_wraps_unexpected_error(
self, mock_lib_instance, setup_spannerlib_method

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While pylint: disable=redefined-outer-name can be necessary, it's often a sign that variable naming or fixture usage could be improved to avoid shadowing. Consider renaming the mock_msg_data parameter in this test method to avoid the conflict.

@gemini-code-assist
Copy link

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

@bhatt4982 bhatt4982 force-pushed the psd-03-pool branch 2 times, most recently from ad49d51 to 7ad76dc Compare December 3, 2025 05:46
@bhatt4982
Copy link
Contributor Author

/gemini review
ignore protected-access issues

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the spannerlib-python wrapper, including the core Pool class, FFI bindings to the Go shared library, and a comprehensive set of unit and system tests. The overall structure is well-thought-out, with good use of ctypes for interoperability and safety mechanisms like context managers and finalizers to prevent resource leaks.

I've found a critical bug in the error handling that would cause a NameError, a high-severity issue where system tests would fail due to a name mismatch with the documentation, and a couple of medium-severity issues related to dependency and version declarations. My detailed comments provide suggestions to fix these issues.

@bhatt4982 bhatt4982 force-pushed the psd-03-pool branch 2 times, most recently from 3ebfedf to fc1c516 Compare December 3, 2025 08:23
@bhatt4982 bhatt4982 changed the base branch from main to psd-02-loadlib December 3, 2025 13:39
@bhatt4982 bhatt4982 changed the title Chore: Python-Spanner-Driver - Added Pool class and relevant tests Chore: Python-Spanner-Driver | Spannerlib Wrapper | Added Pool class and relevant tests Dec 3, 2025
Copy link
Collaborator

@olavloite olavloite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, except for the logging. The library should not log at info level for things that are very normal (such as successfully opening a pool).

(Feel free to address in a follow-up PR)

…sts (#659)

* feat: introduce Connection class and enable Pool to create and manage connections

* Chore: Python-Spanner-Driver | Spannerlib Wrapper | Added Execute, ExecuteBatch and WriteMutation methods and relevant tests... (#660)

* feat: Introduce `Rows` class and add `execute`, `execute_batch`, and `write_mutations` methods to `Connection`.

* feat: Add SQL execution, batch DML, and mutation writing methods to Connection and expose Rows object.

* Chore: Python-Spanner-Driver - Added Rows class, its methods and relevant tests... (#661)

* test: add system tests for query, batch DML, and mutation operations, including emulator setup.

* feat: Add `next()`, `metadata()`, `result_set_stats()`, and `update_count()` methods to the `Rows` class for fetching data and statistics, including unit tests.

* test: Add system tests for `Rows` class covering metadata, stats, update count, and row iteration.

* Chore: Python-Spanner-Driver - Added transaction functions in Connection class and relevant tests... (#662)

* feat: Add transaction management with `begin_transaction`, `commit`, and `rollback` methods and their respective tests.

* feat: add system and unit tests for transaction mutation writes, including commit and rollback scenarios.

* feat: `update_count`  returns -1 instead of 0 when row count stats are unavailable and updates the corresponding test.

* refactor: remove direct Pool argument from Rows constructor and access via Connection.

* feat: Add `IF NOT EXISTS` to `CREATE TABLE` and `IF EXISTS` to `DROP TABLE` statements, removing explicit exception handling.

* feat: `write_mutations` now returns `None` for buffered mutations, updating its return type and related tests.
@bhatt4982 bhatt4982 merged commit 95383be into psd-02-loadlib Dec 4, 2025
28 checks passed
@bhatt4982 bhatt4982 deleted the psd-03-pool branch December 4, 2025 13:51
bhatt4982 added a commit that referenced this pull request Dec 4, 2025
…dle spannerlib library interaction (#657)

* feat: Add initial Python wrapper for Spanner library,
including internal message structures, error handling,
and a protocol definition.

* refactor: Introduce `_load_library` for library initialization, remove `_get_lib_path`, and update related tests.

* Chore: Python-Spanner-Driver | Spannerlib Wrapper | Added Pool class and relevant tests (#658)

* feat: Introduce AbstractLibraryObject and Pool modules with their unit and system tests, replacing placeholder tests.

* Chore: Python-Spanner-Driver - Added Connection class and relevant tests (#659)

* feat: introduce Connection class and enable Pool to create and manage connections

* Chore: Python-Spanner-Driver | Spannerlib Wrapper | Added Execute, ExecuteBatch and WriteMutation methods and relevant tests... (#660)

* feat: Introduce `Rows` class and add `execute`, `execute_batch`, and `write_mutations` methods to `Connection`.

* feat: Add SQL execution, batch DML, and mutation writing methods to Connection and expose Rows object.

* Chore: Python-Spanner-Driver - Added Rows class, its methods and relevant tests... (#661)

* test: add system tests for query, batch DML, and mutation operations, including emulator setup.

* feat: Add `next()`, `metadata()`, `result_set_stats()`, and `update_count()` methods to the `Rows` class for fetching data and statistics, including unit tests.

* test: Add system tests for `Rows` class covering metadata, stats, update count, and row iteration.

* Chore: Python-Spanner-Driver - Added transaction functions in Connection class and relevant tests... (#662)

* feat: Add transaction management with `begin_transaction`, `commit`, and `rollback` methods and their respective tests.

* feat: add system and unit tests for transaction mutation writes, including commit and rollback scenarios.

* feat: `update_count`  returns -1 instead of 0 when row count stats are unavailable and updates the corresponding test.

* refactor: remove direct Pool argument from Rows constructor and access via Connection.

* feat: Add `IF NOT EXISTS` to `CREATE TABLE` and `IF EXISTS` to `DROP TABLE` statements, removing explicit exception handling.

* feat: `write_mutations` now returns `None` for buffered mutations, updating its return type and related tests.

* Update spannerlib/wrappers/spannerlib-python/spannerlib-python/google/cloud/spannerlib/internal/message.py

Co-authored-by: Knut Olav Løite <[email protected]>

* feat: Remove Python 3.8 fallback for `importlib.resources` and few docstring update

* feat: Enhance SpannerLibError messages to include gRPC status names and add corresponding tests.

* test: update SpannerLibError repr test message and code values

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Knut Olav Løite <[email protected]>
bhatt4982 added a commit that referenced this pull request Dec 4, 2025
* chore: Create setup for SpannerLib-Python project

* Chore: Python-Spanner-Driver | Spannerlib Wrapper | Added code to handle spannerlib library interaction (#657)

* feat: Add initial Python wrapper for Spanner library,
including internal message structures, error handling,
and a protocol definition.

* Chore: Python-Spanner-Driver | Spannerlib Wrapper | Added Pool class and relevant tests (#658)

* feat: Introduce AbstractLibraryObject and Pool modules with their unit and system tests, replacing placeholder tests.

* Chore: Python-Spanner-Driver - Added Connection class and relevant tests (#659)

* feat: introduce Connection class and enable Pool to create and manage connections

* Chore: Python-Spanner-Driver | Spannerlib Wrapper | Added Execute, ExecuteBatch and WriteMutation methods and relevant tests... (#660)

* feat: Introduce `Rows` class and add `execute`, `execute_batch`, and `write_mutations` methods to `Connection`.

* feat: Add SQL execution, batch DML, and mutation writing methods to Connection and expose Rows object.

* Chore: Python-Spanner-Driver - Added Rows class, its methods and relevant tests... (#661)

* test: add system tests for query, batch DML, and mutation operations, including emulator setup.

* feat: Add `next()`, `metadata()`, `result_set_stats()`, and `update_count()` methods to the `Rows` class for fetching data and statistics, including unit tests.

* test: Add system tests for `Rows` class covering metadata, stats, update count, and row iteration.

* Chore: Python-Spanner-Driver - Added transaction functions in Connection class and relevant tests... (#662)

* feat: Add transaction management with `begin_transaction`, `commit`, and `rollback` methods and their respective tests.

* feat: add system and unit tests for transaction mutation writes, including commit and rollback scenarios.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants