Skip to content

feat: add pandas-gbq capability helper - #17957

Open
shuoweil wants to merge 10 commits into
mainfrom
shuowei-gbq-version-helper
Open

feat: add pandas-gbq capability helper#17957
shuoweil wants to merge 10 commits into
mainfrom
shuowei-gbq-version-helper

Conversation

@shuoweil

@shuoweil shuoweil commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Introduces PandasGBQVersions in _versions_helpers.py to support backend delegation and telemetry:

  1. Capability Detection: Adds PandasGBQVersions with installed_version, delegation_api_version, and is_delegation_supported properties.
  2. Safe Fallback: Handles missing, outdated, or corrupted pandas-gbq installations gracefully by defaulting to version 0.0.0 / delegation version 0.
  3. Unit Tests: Adds full unit test coverage for cached access, valid versions, uninstalled modules, and corrupted environments in test__versions_helpers.py.

Fixes #<540939659> 🦕

@shuoweil shuoweil self-assigned this Jul 30, 2026
@shuoweil
shuoweil requested review from a team as code owners July 30, 2026 21:06
@shuoweil
shuoweil requested review from GarrettWu, sycai and tswast and removed request for a team July 30, 2026 21:06

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

Copy link
Copy Markdown
Contributor

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 PandasGBQVersions helper class to manage versioning and delegation API support for the pandas-gbq package, along with comprehensive unit tests. However, the properties installed_version and delegation_api_version check for cached values but fail to actually assign and store the parsed values into their respective cache variables (self._installed_version and self._delegation_api_version), defeating the caching mechanism.

Comment thread packages/google-cloud-bigquery/google/cloud/bigquery/_versions_helpers.py Outdated
Comment thread packages/google-cloud-bigquery/google/cloud/bigquery/_versions_helpers.py Outdated
@parthea

parthea commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

@shuoweil , Please see #17958 (comment) for the all-tests and mypy-status checks

@shuoweil

Copy link
Copy Markdown
Contributor Author

@shuoweil , Please see #17958 (comment) for the all-tests and mypy-status checks

Thanks, Anthonios.

@shuoweil
shuoweil marked this pull request as draft July 31, 2026 19:30
@shuoweil

Copy link
Copy Markdown
Contributor Author

I need to merge #17964 first. It contains testcase fixed.

shuoweil and others added 10 commits August 3, 2026 23:15
…_helpers.py

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…_helpers.py

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@shuoweil
shuoweil force-pushed the shuowei-gbq-version-helper branch from 1431979 to 8d6425a Compare August 3, 2026 23:29
@shuoweil
shuoweil marked this pull request as ready for review August 4, 2026 00:13
@shuoweil
shuoweil requested review from GarrettWu, sycai and tswast August 4, 2026 00:13
@parthea parthea assigned tswast and unassigned shuoweil Aug 4, 2026
return self._installed_version

@property
def delegation_api_version(self) -> int:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe we should use packaing.version.Version instead of int for the return type? Will the delegation api version follow the version format of major.minor.patch ?

Comment on lines +126 to +127
with mock.patch.dict(sys.modules, {"google.cloud.bigquery_storage": None}):
with mock.patch.dict(cloud.__dict__):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: shall we chain the context managers with a single with? Same suggestion applies to other places.

def test_pandas_gbq_is_delegation_supported_true():
versions = _versions_helpers.PandasGBQVersions()
versions._delegation_api_version = 1
assert versions.is_delegation_supported is True

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

super nit: let's place an empty line above the assertion.

def test_pandas_gbq_is_delegation_supported_false():
versions = _versions_helpers.PandasGBQVersions()
versions._delegation_api_version = 0
assert versions.is_delegation_supported is False

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

super nit: let's add an empty line above the assertion.

Comment on lines +253 to +255
def __init__(self):
self._installed_version = None
self._delegation_api_version = None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[No action need in this PR] It seems we are following the existing pattern in the codebase, but it is not very "Pythonic" as it uses classes excessively.

I think ideally we should replace all these classes and lazy evaluations with top-level functions and eager evaluations. We should also return None in case the package is not import-able.

We may consider creating a bug for a codebase cleanup, and loop in @tswast for his thoughts on this.

def test_installed_pandas_gbq_version_returns_cached():
versions = _versions_helpers.PandasGBQVersions()
versions._installed_version = object()
assert versions.installed_version is versions._installed_version

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

super nit: let's place an empty line above to demarcate "action" and "assert" blocks: go/unit-testing-practices?polyglot=java#structure

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.

4 participants