diff --git a/packages/google-cloud-bigquery/README.rst b/packages/google-cloud-bigquery/README.rst index 22ccc2718bd4..fe968b968578 100644 --- a/packages/google-cloud-bigquery/README.rst +++ b/packages/google-cloud-bigquery/README.rst @@ -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`. diff --git a/packages/google-cloud-bigquery/docs/README.rst b/packages/google-cloud-bigquery/docs/README.rst index 22ccc2718bd4..fe968b968578 100644 --- a/packages/google-cloud-bigquery/docs/README.rst +++ b/packages/google-cloud-bigquery/docs/README.rst @@ -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`. diff --git a/packages/google-cloud-bigquery/google/cloud/bigquery/__init__.py b/packages/google-cloud-bigquery/google/cloud/bigquery/__init__.py index b9a71add39b2..7eb460f55a99 100644 --- a/packages/google-cloud-bigquery/google/cloud/bigquery/__init__.py +++ b/packages/google-cloud-bigquery/google/cloud/bigquery/__init__.py @@ -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 @@ -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__) diff --git a/packages/google-cloud-bigquery/google/cloud/bigquery/_versions_helpers.py b/packages/google-cloud-bigquery/google/cloud/bigquery/_versions_helpers.py index 1dc1848957fb..63801b74ec9a 100644 --- a/packages/google-cloud-bigquery/google/cloud/bigquery/_versions_helpers.py +++ b/packages/google-cloud-bigquery/google/cloud/bigquery/_versions_helpers.py @@ -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") @@ -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.""" diff --git a/packages/google-cloud-bigquery/google/cloud/bigquery/client.py b/packages/google-cloud-bigquery/google/cloud/bigquery/client.py index 4967bcdb1134..8ce6d044842c 100644 --- a/packages/google-cloud-bigquery/google/cloud/bigquery/client.py +++ b/packages/google-cloud-bigquery/google/cloud/bigquery/client.py @@ -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 diff --git a/packages/google-cloud-bigquery/google/cloud/bigquery/model.py b/packages/google-cloud-bigquery/google/cloud/bigquery/model.py index 16581be5a492..89d371b714a6 100644 --- a/packages/google-cloud-bigquery/google/cloud/bigquery/model.py +++ b/packages/google-cloud-bigquery/google/cloud/bigquery/model.py @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/packages/google-cloud-bigquery/google/cloud/bigquery/schema.py b/packages/google-cloud-bigquery/google/cloud/bigquery/schema.py index 0e6112dda5f6..441c4c687bb7 100644 --- a/packages/google-cloud-bigquery/google/cloud/bigquery/schema.py +++ b/packages/google-cloud-bigquery/google/cloud/bigquery/schema.py @@ -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() diff --git a/packages/google-cloud-bigquery/google/cloud/bigquery/table.py b/packages/google-cloud-bigquery/google/cloud/bigquery/table.py index 6f6042e3ceac..f00240134ab3 100644 --- a/packages/google-cloud-bigquery/google/cloud/bigquery/table.py +++ b/packages/google-cloud-bigquery/google/cloud/bigquery/table.py @@ -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." @@ -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 @@ -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) @@ -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: diff --git a/packages/google-cloud-bigquery/noxfile.py b/packages/google-cloud-bigquery/noxfile.py index 88dc5bd2daf1..b18e42cd24db 100644 --- a/packages/google-cloud-bigquery/noxfile.py +++ b/packages/google-cloud-bigquery/noxfile.py @@ -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"] 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. @@ -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 @@ -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) @@ -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) @@ -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.""" @@ -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.""" diff --git a/packages/google-cloud-bigquery/pyproject.toml b/packages/google-cloud-bigquery/pyproject.toml index b0936b70c72b..45010c912089 100644 --- a/packages/google-cloud-bigquery/pyproject.toml +++ b/packages/google-cloud-bigquery/pyproject.toml @@ -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 = [ @@ -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", @@ -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", diff --git a/packages/google-cloud-bigquery/samples/desktopapp/noxfile.py b/packages/google-cloud-bigquery/samples/desktopapp/noxfile.py index db2333e5a511..c48f37cc7ec9 100644 --- a/packages/google-cloud-bigquery/samples/desktopapp/noxfile.py +++ b/packages/google-cloud-bigquery/samples/desktopapp/noxfile.py @@ -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"] diff --git a/packages/google-cloud-bigquery/samples/desktopapp/noxfile_config.py b/packages/google-cloud-bigquery/samples/desktopapp/noxfile_config.py index 315bd5be8cd9..7c7adf771442 100644 --- a/packages/google-cloud-bigquery/samples/desktopapp/noxfile_config.py +++ b/packages/google-cloud-bigquery/samples/desktopapp/noxfile_config.py @@ -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 diff --git a/packages/google-cloud-bigquery/samples/geography/noxfile.py b/packages/google-cloud-bigquery/samples/geography/noxfile.py index db2333e5a511..c48f37cc7ec9 100644 --- a/packages/google-cloud-bigquery/samples/geography/noxfile.py +++ b/packages/google-cloud-bigquery/samples/geography/noxfile.py @@ -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"] diff --git a/packages/google-cloud-bigquery/samples/geography/noxfile_config.py b/packages/google-cloud-bigquery/samples/geography/noxfile_config.py index 315bd5be8cd9..7c7adf771442 100644 --- a/packages/google-cloud-bigquery/samples/geography/noxfile_config.py +++ b/packages/google-cloud-bigquery/samples/geography/noxfile_config.py @@ -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 diff --git a/packages/google-cloud-bigquery/samples/magics/noxfile.py b/packages/google-cloud-bigquery/samples/magics/noxfile.py index db2333e5a511..c48f37cc7ec9 100644 --- a/packages/google-cloud-bigquery/samples/magics/noxfile.py +++ b/packages/google-cloud-bigquery/samples/magics/noxfile.py @@ -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"] diff --git a/packages/google-cloud-bigquery/samples/magics/noxfile_config.py b/packages/google-cloud-bigquery/samples/magics/noxfile_config.py index 982751b8bfd1..7c7adf771442 100644 --- a/packages/google-cloud-bigquery/samples/magics/noxfile_config.py +++ b/packages/google-cloud-bigquery/samples/magics/noxfile_config.py @@ -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 diff --git a/packages/google-cloud-bigquery/samples/notebooks/noxfile.py b/packages/google-cloud-bigquery/samples/notebooks/noxfile.py index db2333e5a511..c48f37cc7ec9 100644 --- a/packages/google-cloud-bigquery/samples/notebooks/noxfile.py +++ b/packages/google-cloud-bigquery/samples/notebooks/noxfile.py @@ -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"] diff --git a/packages/google-cloud-bigquery/samples/notebooks/noxfile_config.py b/packages/google-cloud-bigquery/samples/notebooks/noxfile_config.py index 315bd5be8cd9..7c7adf771442 100644 --- a/packages/google-cloud-bigquery/samples/notebooks/noxfile_config.py +++ b/packages/google-cloud-bigquery/samples/notebooks/noxfile_config.py @@ -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 diff --git a/packages/google-cloud-bigquery/samples/snippets/noxfile.py b/packages/google-cloud-bigquery/samples/snippets/noxfile.py index db2333e5a511..c48f37cc7ec9 100644 --- a/packages/google-cloud-bigquery/samples/snippets/noxfile.py +++ b/packages/google-cloud-bigquery/samples/snippets/noxfile.py @@ -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"] diff --git a/packages/google-cloud-bigquery/samples/snippets/noxfile_config.py b/packages/google-cloud-bigquery/samples/snippets/noxfile_config.py index 7d2e02346071..7c7adf771442 100644 --- a/packages/google-cloud-bigquery/samples/snippets/noxfile_config.py +++ b/packages/google-cloud-bigquery/samples/snippets/noxfile_config.py @@ -22,7 +22,10 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7"], + "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 # build specific Cloud project. You can also use your own string diff --git a/packages/google-cloud-bigquery/setup.cfg b/packages/google-cloud-bigquery/setup.cfg index 11a5971e3f2a..d0815e7ed31f 100644 --- a/packages/google-cloud-bigquery/setup.cfg +++ b/packages/google-cloud-bigquery/setup.cfg @@ -15,7 +15,7 @@ # limitations under the License. [pytype] -python_version = 3.10 +python_version = 3.11 inputs = google/cloud/ exclude = diff --git a/packages/google-cloud-bigquery/testing/constraints-3.10.txt b/packages/google-cloud-bigquery/testing/constraints-3.10.txt deleted file mode 100644 index 4f8a652e1312..000000000000 --- a/packages/google-cloud-bigquery/testing/constraints-3.10.txt +++ /dev/null @@ -1,27 +0,0 @@ -google-api-core==2.28.0 -google-auth==2.14.1 -google-cloud-core==2.4.1 -google-resumable-media==2.0.0 -packaging==24.2.0 -python-dateutil==2.8.2 -requests==2.33.0 -google-cloud-bigquery-storage==2.43.0 -grpcio==1.59.0 -grpcio-status==1.59.0 -pyarrow==6.0.0 -pandas==1.3.5 -pandas-gbq==0.26.1 -db-dtypes==1.0.4 -ipywidgets==7.7.1 -ipykernel==6.2.0 -geopandas==0.9.0 -Shapely==1.8.4 -ipython==7.23.1 -bigquery-magics==0.6.0 -matplotlib==3.10.3 -tqdm==4.66.3 -opentelemetry-api==1.16.0 -opentelemetry-sdk==1.16.0 -opentelemetry-instrumentation==0.41b0 -proto-plus==1.26.1 -protobuf==6.33.5 \ No newline at end of file diff --git a/packages/google-cloud-bigquery/testing/constraints-3.11.txt b/packages/google-cloud-bigquery/testing/constraints-3.11.txt index e69de29bb2d1..00fb10fe6417 100644 --- a/packages/google-cloud-bigquery/testing/constraints-3.11.txt +++ b/packages/google-cloud-bigquery/testing/constraints-3.11.txt @@ -0,0 +1,27 @@ +google-api-core==2.28.0 +google-auth==2.14.1 +google-cloud-core==2.4.1 +google-resumable-media==2.0.0 +packaging==24.2.0 +python-dateutil==2.8.2 +requests==2.33.0 +google-cloud-bigquery-storage==2.43.0 +grpcio==1.59.0 +grpcio-status==1.59.0 +pyarrow==10.0.1 +pandas==1.5.0 +pandas-gbq==0.26.1 +db-dtypes==1.0.5 +ipywidgets==7.7.1 +ipykernel==6.2.0 +geopandas==0.9.0 +Shapely==1.8.5 +ipython==7.23.1 +bigquery-magics==0.6.0 +matplotlib==3.10.3 +tqdm==4.66.3 +opentelemetry-api==1.16.0 +opentelemetry-sdk==1.16.0 +opentelemetry-instrumentation==0.41b0 +proto-plus==1.26.1 +protobuf==6.33.5 diff --git a/packages/google-cloud-bigquery/tests/unit/test_table.py b/packages/google-cloud-bigquery/tests/unit/test_table.py index 0e142a59db94..41a5eecace84 100644 --- a/packages/google-cloud-bigquery/tests/unit/test_table.py +++ b/packages/google-cloud-bigquery/tests/unit/test_table.py @@ -4194,11 +4194,7 @@ def test_to_dataframe_no_tqdm_no_progress_bar(self): user_warnings = [ warning for warning in warned if warning.category is UserWarning ] - # With pandas < 1.5, pandas.ArrowDtype is not supported - # and len(user_warnings) = 3. - # We raise warnings because range columns have to be converted to object. - # With higher pandas versions and noextra tests, len(user_warnings) = 0 - self.assertIn(len(user_warnings), [0, 3]) + self.assertEqual(len(user_warnings), 0) self.assertEqual(len(df), 4) @mock.patch("google.cloud.bigquery._tqdm_helpers.tqdm", new=None) @@ -4229,11 +4225,7 @@ def test_to_dataframe_no_tqdm(self): user_warnings = [ warning for warning in warned if warning.category is UserWarning ] - # With pandas < 1.5, pandas.ArrowDtype is not supported - # and len(user_warnings) = 4. - # We raise warnings because range columns have to be converted to object. - # With higher pandas versions and noextra tests, len(user_warnings) = 1 - self.assertIn(len(user_warnings), [1, 4]) + self.assertEqual(len(user_warnings), 1) # Even though the progress bar won't show, downloading the dataframe # should still work. @@ -4419,64 +4411,30 @@ def test_to_dataframe_w_dtypes_mapper(self): create_bqstorage_client=False, bool_dtype=pandas.BooleanDtype(), int_dtype=pandas.Int32Dtype(), - float_dtype=( - pandas.Float64Dtype() - if hasattr(pandas, "Float64Dtype") - else pandas.StringDtype() - ), + float_dtype=pandas.Float64Dtype(), string_dtype=pandas.StringDtype(), - date_dtype=( - pandas.ArrowDtype(pyarrow.date32()) - if hasattr(pandas, "ArrowDtype") - else None - ), - datetime_dtype=( - pandas.ArrowDtype(pyarrow.timestamp("us")) - if hasattr(pandas, "ArrowDtype") - else None - ), - time_dtype=( - pandas.ArrowDtype(pyarrow.time64("us")) - if hasattr(pandas, "ArrowDtype") - else None - ), - timestamp_dtype=( - pandas.ArrowDtype(pyarrow.timestamp("us", tz="UTC")) - if hasattr(pandas, "ArrowDtype") - else None + date_dtype=pandas.ArrowDtype(pyarrow.date32()), + datetime_dtype=pandas.ArrowDtype(pyarrow.timestamp("us")), + time_dtype=pandas.ArrowDtype(pyarrow.time64("us")), + timestamp_dtype=pandas.ArrowDtype(pyarrow.timestamp("us", tz="UTC")), + range_date_dtype=pandas.ArrowDtype( + pyarrow.struct([("start", pyarrow.date32()), ("end", pyarrow.date32())]) ), - range_date_dtype=( - pandas.ArrowDtype( - pyarrow.struct( - [("start", pyarrow.date32()), ("end", pyarrow.date32())] - ) - ) - if hasattr(pandas, "ArrowDtype") - else None - ), - 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")), + ] ) - if hasattr(pandas, "ArrowDtype") - else None ), - 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")), + ] ) - if hasattr(pandas, "ArrowDtype") - else None ), ) @@ -4499,135 +4457,92 @@ def test_to_dataframe_w_dtypes_mapper(self): self.assertEqual(list(df.miles), [1.77, 6.66, 2.0]) self.assertEqual(df.miles.dtype.name, "Float64") - if hasattr(pandas, "ArrowDtype"): - self.assertEqual( - list(df.date), - [ - datetime.date(1999, 12, 1), - datetime.date(4567, 6, 14), - datetime.date(9999, 12, 31), - ], - ) - self.assertEqual(df.date.dtype.name, "date32[day][pyarrow]") - - self.assertEqual( - list(df.datetime), - [ - datetime.datetime(1999, 12, 31, 0, 0), - datetime.datetime(4567, 12, 31, 0, 0), - datetime.datetime(9999, 12, 31, 23, 59, 59, 999999), - ], - ) - self.assertEqual(df.datetime.dtype.name, "timestamp[us][pyarrow]") - - self.assertEqual( - list(df.time), - [ - datetime.time(0, 0), - datetime.time(12, 0, 0, 232413), - datetime.time(23, 59, 59, 999999), - ], - ) - self.assertEqual(df.time.dtype.name, "time64[us][pyarrow]") - - self.assertEqual( - list(df.timestamp), - [ - datetime.datetime(2015, 6, 9, 8, 0, tzinfo=datetime.timezone.utc), - datetime.datetime(4567, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - datetime.datetime( - 9999, 12, 31, 12, 59, 59, 999999, tzinfo=datetime.timezone.utc - ), - ], - ) - self.assertEqual(df.timestamp.dtype.name, "timestamp[us, tz=UTC][pyarrow]") + self.assertEqual( + list(df.date), + [ + datetime.date(1999, 12, 1), + datetime.date(4567, 6, 14), + datetime.date(9999, 12, 31), + ], + ) + self.assertEqual(df.date.dtype.name, "date32[day][pyarrow]") - self.assertEqual( - list(df.range_timestamp), - [ - { - "start": datetime.datetime( - 2015, 6, 9, 8, 0, 0, tzinfo=datetime.timezone.utc - ), - "end": datetime.datetime( - 2015, 6, 11, 5, 18, 20, tzinfo=datetime.timezone.utc - ), - }, - { - "start": datetime.datetime( - 2015, 6, 9, 8, 0, 0, tzinfo=datetime.timezone.utc - ), - "end": None, - }, - {"start": None, "end": None}, - ], - ) + self.assertEqual( + list(df.datetime), + [ + datetime.datetime(1999, 12, 31, 0, 0), + datetime.datetime(4567, 12, 31, 0, 0), + datetime.datetime(9999, 12, 31, 23, 59, 59, 999999), + ], + ) + self.assertEqual(df.datetime.dtype.name, "timestamp[us][pyarrow]") - self.assertEqual( - list(df.range_datetime), - [ - { - "start": datetime.datetime(2009, 6, 17, 13, 45, 30), - "end": datetime.datetime(2019, 7, 17, 13, 45, 30), - }, - {"start": datetime.datetime(2009, 6, 17, 13, 45, 30), "end": None}, - {"start": None, "end": None}, - ], - ) + self.assertEqual( + list(df.time), + [ + datetime.time(0, 0), + datetime.time(12, 0, 0, 232413), + datetime.time(23, 59, 59, 999999), + ], + ) + self.assertEqual(df.time.dtype.name, "time64[us][pyarrow]") - self.assertEqual( - list(df.range_date), - [ - { - "start": datetime.date(2020, 10, 1), - "end": datetime.date(2021, 10, 2), - }, - {"start": datetime.date(2020, 10, 1), "end": None}, - {"start": None, "end": None}, - ], - ) - else: - self.assertEqual( - list(df.date), - [ - pandas.Timestamp("1999-12-01 00:00:00"), - pandas.Timestamp("2229-03-27 01:41:45.161793536"), - pandas.Timestamp("1816-03-29 05:56:08.066277376"), - ], - ) - self.assertEqual(df.date.dtype.name, "datetime64[ns]") + self.assertEqual( + list(df.timestamp), + [ + datetime.datetime(2015, 6, 9, 8, 0, tzinfo=datetime.timezone.utc), + datetime.datetime(4567, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + datetime.datetime( + 9999, 12, 31, 12, 59, 59, 999999, tzinfo=datetime.timezone.utc + ), + ], + ) + self.assertEqual(df.timestamp.dtype.name, "timestamp[us, tz=UTC][pyarrow]") - self.assertEqual( - list(df.datetime), - [ - datetime.datetime(1999, 12, 31, 0, 0), - datetime.datetime(4567, 12, 31, 0, 0), - datetime.datetime(9999, 12, 31, 23, 59, 59, 999999), - ], - ) - self.assertEqual(df.datetime.dtype.name, "object") + self.assertEqual( + list(df.range_timestamp), + [ + { + "start": datetime.datetime( + 2015, 6, 9, 8, 0, 0, tzinfo=datetime.timezone.utc + ), + "end": datetime.datetime( + 2015, 6, 11, 5, 18, 20, tzinfo=datetime.timezone.utc + ), + }, + { + "start": datetime.datetime( + 2015, 6, 9, 8, 0, 0, tzinfo=datetime.timezone.utc + ), + "end": None, + }, + {"start": None, "end": None}, + ], + ) - self.assertEqual( - list(df.time), - [ - datetime.time(0, 0), - datetime.time(12, 0, 0, 232413), - datetime.time(23, 59, 59, 999999), - ], - ) - self.assertEqual(df.time.dtype.name, "object") + self.assertEqual( + list(df.range_datetime), + [ + { + "start": datetime.datetime(2009, 6, 17, 13, 45, 30), + "end": datetime.datetime(2019, 7, 17, 13, 45, 30), + }, + {"start": datetime.datetime(2009, 6, 17, 13, 45, 30), "end": None}, + {"start": None, "end": None}, + ], + ) - self.assertEqual( - list(df.timestamp), - [ - datetime.datetime(2015, 6, 9, 8, 0, tzinfo=datetime.timezone.utc), - datetime.datetime(4567, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - datetime.datetime( - 9999, 12, 31, 12, 59, 59, 999999, tzinfo=datetime.timezone.utc - ), - ], - ) - self.assertEqual(df.timestamp.dtype.name, "object") + self.assertEqual( + list(df.range_date), + [ + { + "start": datetime.date(2020, 10, 1), + "end": datetime.date(2021, 10, 2), + }, + {"start": datetime.date(2020, 10, 1), "end": None}, + {"start": None, "end": None}, + ], + ) def test_to_dataframe_w_none_dtypes_mapper(self): pandas = pytest.importorskip("pandas")