Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/google-cloud-bigquery/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ dependencies.

Supported Python Versions
^^^^^^^^^^^^^^^^^^^^^^^^^
Python >= 3.10
Python >= 3.11

Unsupported Python Versions
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Python <= 3.9.
Python <= 3.10.

The last version of this library compatible with Python 2.7 and 3.5 is
`google-cloud-bigquery==1.28.0`.
Expand Down
4 changes: 2 additions & 2 deletions packages/google-cloud-bigquery/docs/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ dependencies.

Supported Python Versions
^^^^^^^^^^^^^^^^^^^^^^^^^
Python >= 3.10
Python >= 3.11

Unsupported Python Versions
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Python <= 3.9.
Python <= 3.10.

The last version of this library compatible with Python 2.7 and 3.5 is
`google-cloud-bigquery==1.28.0`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
- :class:`~google.cloud.bigquery.table.Table` represents a single "relation".
"""

import sys
import warnings

import google.api_core as api_core
Expand Down Expand Up @@ -128,15 +127,6 @@
except ImportError:
bigquery_magics = None

if sys.version_info < (3, 10): # pragma: NO COVER
warnings.warn(
"The python-bigquery library no longer supports Python <= 3.9. "
f"Your Python version is {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}. We "
"recommend that you update soon to ensure ongoing support. For "
"more details, see: [Google Cloud Client Libraries Supported Python Versions policy](https://cloud.google.com/python/docs/supported-python-versions)",
FutureWarning,
)

api_core.check_python_version(__name__)
api_core.check_dependency_versions(__name__)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@
_MIN_BQ_STORAGE_VERSION = packaging.version.Version("2.0.0")
_BQ_STORAGE_OPTIONAL_READ_SESSION_VERSION = packaging.version.Version("2.6.0")
_MIN_PANDAS_VERSION = packaging.version.Version("1.1.0")

_MIN_PANDAS_VERSION_RANGE = packaging.version.Version("1.5.0")
_MIN_PYARROW_VERSION_RANGE = packaging.version.Version("10.0.1")
_MIN_PANDAS_GBQ_DELEGATION_VERSION = packaging.version.Version("1.0.0")


Expand Down Expand Up @@ -251,17 +248,6 @@ def try_import(self, raise_if_error: bool = False) -> Any:

PANDAS_VERSIONS = PandasVersions()

# Since RANGE support in pandas requires specific versions
# of both pyarrow and pandas, we make this a separate
# constant instead of as a property of PANDAS_VERSIONS
# or PYARROW_VERSIONS.
SUPPORTS_RANGE_PYARROW = (
PANDAS_VERSIONS.try_import() is not None
and PANDAS_VERSIONS.installed_version >= _MIN_PANDAS_VERSION_RANGE
and PYARROW_VERSIONS.try_import() is not None
and PYARROW_VERSIONS.installed_version >= _MIN_PYARROW_VERSION_RANGE
)


class PandasGBQVersions:
"""Version and delegation comparisons for pandas-gbq package."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@
] # for resumable media methods

if typing.TYPE_CHECKING: # pragma: NO COVER
# os.PathLike is only subscriptable in Python 3.9+, thus shielding with a condition.
PathType = Union[str, bytes, os.PathLike[str], os.PathLike[bytes], io.IOBase]
_DEFAULT_CHUNKSIZE = 100 * 1024 * 1024 # 100 MB
_MAX_MULTIPART_SIZE = 5 * 1024 * 1024
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
from typing import Any, Dict, Optional, Sequence, Union

import google.cloud._helpers # type: ignore
from google.cloud.bigquery import _helpers
from google.cloud.bigquery import standard_sql
from google.cloud.bigquery import _helpers, standard_sql
from google.cloud.bigquery.encryption_configuration import EncryptionConfiguration


Expand Down Expand Up @@ -252,7 +251,6 @@ def expires(self, value: Optional[datetime.datetime]):
value_to_store: Optional[str] = None
else:
value_to_store = str(google.cloud._helpers._millis_from_datetime(value))
# TODO: Consider using typing.TypedDict when only Python 3.8+ is supported.
self._properties["expirationTime"] = value_to_store # type: ignore

@property
Expand All @@ -262,7 +260,6 @@ def description(self) -> Optional[str]:

@description.setter
def description(self, value: Optional[str]):
# TODO: Consider using typing.TypedDict when only Python 3.8+ is supported.
self._properties["description"] = value # type: ignore

@property
Expand All @@ -272,7 +269,6 @@ def friendly_name(self) -> Optional[str]:

@friendly_name.setter
def friendly_name(self, value: Optional[str]):
# TODO: Consider using typing.TypedDict when only Python 3.8+ is supported.
self._properties["friendlyName"] = value # type: ignore

@property
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ class _DefaultSentinel(enum.Enum):

Uses enum so that pytype/mypy knows that this is the only possible value.
https://stackoverflow.com/a/60605919/101923

Literal[_DEFAULT_VALUE] is an alternative, but only added in Python 3.8.
https://docs.python.org/3/library/typing.html#typing.Literal
"""

DEFAULT_VALUE = object()
Expand Down
59 changes: 19 additions & 40 deletions packages/google-cloud-bigquery/google/cloud/bigquery/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,6 @@
"because the necessary `__from_arrow__` attribute is missing."
)

_RANGE_PYARROW_WARNING = (
"Unable to represent RANGE schema as struct using pandas ArrowDtype. Using "
"`object` instead. To use ArrowDtype, use pandas >= 1.5 and "
"pyarrow >= 10.0.1."
)

_TO_DATAFRAME_DEPRECATED = (
"Retrieving DataFrames via google-cloud-bigquery is deprecated. "
"For direct, optimized access, please call 'pandas_gbq.read_gbq()' directly."
Expand Down Expand Up @@ -822,7 +816,7 @@ def time_partitioning(self, value):
api_repr = value.to_api_repr()
elif value is not None:
raise ValueError(
"value must be google.cloud.bigquery.table.TimePartitioning " "or None"
"value must be google.cloud.bigquery.table.TimePartitioning or None"
)
self._properties[self._PROPERTY_TO_API_FIELD["time_partitioning"]] = api_repr

Expand Down Expand Up @@ -2839,43 +2833,29 @@ def to_dataframe(
time_dtype = db_dtypes.TimeDtype()

if range_date_dtype is DefaultPandasDTypes.RANGE_DATE_DTYPE:
if _versions_helpers.SUPPORTS_RANGE_PYARROW:
range_date_dtype = pandas.ArrowDtype(
pyarrow.struct(
[("start", pyarrow.date32()), ("end", pyarrow.date32())]
)
)
else:
warnings.warn(_RANGE_PYARROW_WARNING)
range_date_dtype = None
range_date_dtype = pandas.ArrowDtype(
pyarrow.struct([("start", pyarrow.date32()), ("end", pyarrow.date32())])
)

if range_datetime_dtype is DefaultPandasDTypes.RANGE_DATETIME_DTYPE:
if _versions_helpers.SUPPORTS_RANGE_PYARROW:
range_datetime_dtype = pandas.ArrowDtype(
pyarrow.struct(
[
("start", pyarrow.timestamp("us")),
("end", pyarrow.timestamp("us")),
]
)
range_datetime_dtype = pandas.ArrowDtype(
pyarrow.struct(
[
("start", pyarrow.timestamp("us")),
("end", pyarrow.timestamp("us")),
]
)
else:
warnings.warn(_RANGE_PYARROW_WARNING)
range_datetime_dtype = None
)

if range_timestamp_dtype is DefaultPandasDTypes.RANGE_TIMESTAMP_DTYPE:
if _versions_helpers.SUPPORTS_RANGE_PYARROW:
range_timestamp_dtype = pandas.ArrowDtype(
pyarrow.struct(
[
("start", pyarrow.timestamp("us", tz="UTC")),
("end", pyarrow.timestamp("us", tz="UTC")),
]
)
range_timestamp_dtype = pandas.ArrowDtype(
pyarrow.struct(
[
("start", pyarrow.timestamp("us", tz="UTC")),
("end", pyarrow.timestamp("us", tz="UTC")),
]
)
else:
warnings.warn(_RANGE_PYARROW_WARNING)
range_timestamp_dtype = None
)

if bool_dtype is not None and not hasattr(bool_dtype, "__from_arrow__"):
raise ValueError("bool_dtype", _NO_SUPPORTED_DTYPE)
Expand Down Expand Up @@ -3112,8 +3092,7 @@ def to_geodataframe(
)
if not geography_columns:
raise TypeError(
"There must be at least one GEOGRAPHY column"
" to create a GeoDataFrame"
"There must be at least one GEOGRAPHY column to create a GeoDataFrame"
)

if geography_column:
Expand Down
15 changes: 10 additions & 5 deletions packages/google-cloud-bigquery/noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

DEFAULT_PYTHON_VERSION = "3.14"
ALL_PYTHON = ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"]
UNIT_TEST_PYTHON_VERSIONS = ALL_PYTHON
UNIT_TEST_PYTHON_VERSIONS = ["3.11", "3.12", "3.13", "3.14", "3.15"]

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.

medium

Since Python 3.10 is no longer supported, we should remove "3.10" from ALL_PYTHON on line 41.

By doing so, we can keep UNIT_TEST_PYTHON_VERSIONS = ALL_PYTHON and avoid changing the @nox.session decorators to use ALL_PYTHON and adding manual session.skip checks in the unit and mypy sessions.

Suggested change
UNIT_TEST_PYTHON_VERSIONS = ["3.11", "3.12", "3.13", "3.14", "3.15"]
UNIT_TEST_PYTHON_VERSIONS = ALL_PYTHON

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No. That would break GitHub Actions.

CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute()
# Path to the centralized mypy configuration file at the repository root.
# Search upwards to support running nox from both monorepo packages and integration test goldens.
Expand Down Expand Up @@ -175,11 +175,14 @@ def default(session, install_extras=True):
)


@nox.session(python=UNIT_TEST_PYTHON_VERSIONS)
@nox.session(python=ALL_PYTHON)
@nox.parametrize("test_type", ["unit", "unit_noextras"])
@_calculate_duration
def unit(session, test_type):
"""Run the unit test suite."""
if session.python not in UNIT_TEST_PYTHON_VERSIONS:
session.skip(f"Python {session.python} is not supported.")

install_extras = True
if test_type == "unit_noextras":
# unit_noextras only runs on the oldest and newest Python versions
Expand All @@ -202,7 +205,7 @@ def unit(session, test_type):
# so that it continues to be an optional dependency.
# https://github.com/googleapis/google-cloud-python/issues/1877
if session.python == UNIT_TEST_PYTHON_VERSIONS[0]:
session.install("pyarrow==6.0.0", "numpy==1.22.0")
session.install("pyarrow==10.0.1", "numpy==1.23.2")

default(session, install_extras=install_extras)

Expand All @@ -211,6 +214,8 @@ def unit(session, test_type):
@_calculate_duration
def mypy(session):
"""Run type checks with mypy."""
if session.python not in UNIT_TEST_PYTHON_VERSIONS:
session.skip(f"Python {session.python} is not supported.")

session.install("-e", ".[all]")
session.install(MYPY_VERSION)
Expand Down Expand Up @@ -527,7 +532,7 @@ def blacken(session):
session.run("black", *BLACK_PATHS)


@nox.session(python="3.10")
@nox.session(python="3.11")
@_calculate_duration
def docs(session):
"""Build the docs."""
Expand Down Expand Up @@ -566,7 +571,7 @@ def docs(session):
)


@nox.session(python="3.10")
@nox.session(python="3.11")
@_calculate_duration
def docfx(session):
"""Build the docfx yaml files for this library."""
Expand Down
13 changes: 6 additions & 7 deletions packages/google-cloud-bigquery/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ build-backend = "setuptools.build_meta"
name = "google-cloud-bigquery"
authors = [{ name = "Google LLC", email = "googleapis-packages@google.com" }]
license = { text = "Apache 2.0" }
requires-python = ">=3.10"
requires-python = ">=3.11"
description = "Google BigQuery API client library"
readme = "README.rst"
classifiers = [
Expand All @@ -32,7 +32,6 @@ classifiers = [
"Intended Audience :: Developers",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
Expand Down Expand Up @@ -69,18 +68,18 @@ bqstorage = [
# https://github.com/grpc/grpc/pull/15254
"grpcio >= 1.59.0, < 2.0.0",
"grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'",
"pyarrow >= 4.0.0",
"pyarrow >= 10.0.1",
]
pandas = [
"pandas >= 1.3.0",
"pandas >= 1.5.0",
"pandas-gbq >= 0.26.1",
"grpcio >= 1.59.0, < 2.0.0",
"grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'",
"pyarrow >= 3.0.0",
"db-dtypes >= 1.0.4, < 2.0.0",
"pyarrow >= 10.0.1",
"db-dtypes >= 1.0.5, < 2.0.0",
]
ipywidgets = ["ipywidgets >= 7.7.1", "ipykernel >= 6.2.0"]
geopandas = ["geopandas >= 0.9.0, < 2.0.0", "Shapely >= 1.8.4, < 3.0.0"]
geopandas = ["geopandas >= 0.9.0, < 2.0.0", "Shapely >= 1.8.5, < 3.0.0"]
ipython = ["ipython >= 7.23.1", "bigquery-magics >= 0.6.0"]
matplotlib = [
"matplotlib >= 3.10.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def get_pytest_env_vars() -> Dict[str, str]:

# DO NOT EDIT - automatically generated.
# All versions used to test samples.
ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
ALL_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"]

# Any default versions that should be ignored.
IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
# You can opt out from the test for specific Python versions.
"ignored_versions": [
"2.7",
# TODO: Enable 3.10 once there is a geopandas/fiona release.
# https://github.com/Toblerity/Fiona/issues/1043
"3.10",
],
# An envvar key for determining the project id to use. Change it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def get_pytest_env_vars() -> Dict[str, str]:

# DO NOT EDIT - automatically generated.
# All versions used to test samples.
ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
ALL_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"]

# Any default versions that should be ignored.
IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
# You can opt out from the test for specific Python versions.
"ignored_versions": [
"2.7",
# TODO: Enable 3.10 once there is a geopandas/fiona release.
# https://github.com/Toblerity/Fiona/issues/1043
"3.10",
],
# An envvar key for determining the project id to use. Change it
Expand Down
2 changes: 1 addition & 1 deletion packages/google-cloud-bigquery/samples/magics/noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def get_pytest_env_vars() -> Dict[str, str]:

# DO NOT EDIT - automatically generated.
# All versions used to test samples.
ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
ALL_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"]

# Any default versions that should be ignored.
IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
# You can opt out from the test for specific Python versions.
"ignored_versions": [
"2.7",
"3.10",
],
# An envvar key for determining the project id to use. Change it
# to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def get_pytest_env_vars() -> Dict[str, str]:

# DO NOT EDIT - automatically generated.
# All versions used to test samples.
ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
ALL_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"]

# Any default versions that should be ignored.
IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
# You can opt out from the test for specific Python versions.
"ignored_versions": [
"2.7",
# TODO: Enable 3.10 once there is a geopandas/fiona release.
# https://github.com/Toblerity/Fiona/issues/1043
"3.10",
],
# An envvar key for determining the project id to use. Change it
Expand Down
Loading
Loading