GeezerVison is showing github.com — fix: drop support for end-of-life Python 3.10 (#19015) · googleapis/google-cloud-python@13d691b
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: packages/pandas-gbq/CONTRIBUTING.rst +6-6Lines changed: 6 additions & 6 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -22,7 +22,7 @@ In order to add a feature: | 22 | 22 | documentation. | 23 | 23 |
| 24 | 24 | - The feature must work fully on the following CPython versions: | 25 | | - 3.10, 3.11, 3.12, 3.13 and 3.14 on both UNIX and Windows. | | 25 | + 3.11, 3.12, 3.13, 3.14 and 3.15 on both UNIX and Windows. | 26 | 26 |
| 27 | 27 | - The feature must not add unnecessary dependencies (where | 28 | 28 | "unnecessary" is of course subjective, but new dependencies should | @@ -195,11 +195,11 @@ configure them just like the System Tests. | 195 | 195 |
| 196 | 196 | # Run all tests in a folder | 197 | 197 | $ cd samples/snippets | 198 | | - $ nox -s py-3.10 | | 198 | + $ nox -s py-3.14 | 199 | 199 |
| 200 | 200 | # Run a single sample test | 201 | 201 | $ cd samples/snippets | 202 | | - $ nox -s py-3.10 -- -k <name of test> | | 202 | + $ nox -s py-3.14 -- -k <name of test> | 203 | 203 |
| 204 | 204 | ******************************************** | 205 | 205 | Note About ``README`` as it pertains to PyPI | @@ -221,25 +221,25 @@ Supported Python Versions | 221 | 221 |
| 222 | 222 | We support: | 223 | 223 |
| 224 | | -- `Python 3.10`_ | 225 | 224 | - `Python 3.11`_ | 226 | 225 | - `Python 3.12`_ | 227 | 226 | - `Python 3.13`_ | 228 | 227 | - `Python 3.14`_ | | 228 | +- `Python 3.15`_ | 229 | 229 |
| 230 | | -.. _Python 3.10: https://docs.python.org/3.10/ | 231 | 230 | .. _Python 3.11: https://docs.python.org/3.11/ | 232 | 231 | .. _Python 3.12: https://docs.python.org/3.12/ | 233 | 232 | .. _Python 3.13: https://docs.python.org/3.13/ | 234 | 233 | .. _Python 3.14: https://docs.python.org/3.14/ | | 234 | +.. _Python 3.15: https://docs.python.org/3.15/ | 235 | 235 |
| 236 | 236 |
| 237 | 237 | Supported versions can be found in our ``noxfile.py`` `config`_. | 238 | 238 |
| 239 | 239 | .. _config: https://github.com/googleapis/google-cloud-python/blob/main/packages/pandas-gbq/noxfile.py | 240 | 240 |
| 241 | 241 |
| 242 | | -We also explicitly decided to support Python 3 beginning with version 3.10. | | 242 | +We also explicitly decided to support Python 3 beginning with version 3.11. | 243 | 243 | Reasons for this include: | 244 | 244 |
| 245 | 245 | - Encouraging use of newest versions of Python 3 | |
Collapse file Copy file name to clipboardExpand all lines: packages/pandas-gbq/docs/conf.py -1Lines changed: 0 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 25 | 25 | # serve to show the default. | 26 | 26 |
| 27 | 27 | import os | 28 | | -import shlex | 29 | 28 | import sys | 30 | 29 |
| 31 | 30 | # If extensions (or modules to document with autodoc) are in another directory, | |
Collapse file Copy file name to clipboardExpand all lines: packages/pandas-gbq/noxfile.py +15-5Lines changed: 15 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 35 | 35 |
| 36 | 36 | DEFAULT_PYTHON_VERSION = "3.14" | 37 | 37 |
| 38 | | -UNIT_TEST_PYTHON_VERSIONS = [ | | 38 | +ALL_PYTHON = [ | 39 | 39 | "3.10", | 40 | 40 | "3.11", | 41 | 41 | "3.12", | | 44 | 44 | "3.15", | 45 | 45 | ] | 46 | 46 |
| | 47 | +UNIT_TEST_PYTHON_VERSIONS = [ | | 48 | + "3.11", | | 49 | + "3.12", | | 50 | + "3.13", | | 51 | + "3.14", | | 52 | + "3.15", | | 53 | +] | | 54 | + | 47 | 55 | UNIT_TEST_STANDARD_DEPENDENCIES = [ | 48 | 56 | "mock", | 49 | 57 | "asyncmock", | | 62 | 70 | "geopandas", | 63 | 71 | ] | 64 | 72 | UNIT_TEST_EXTRAS_BY_PYTHON = { | 65 | | - "3.10": [], | | 73 | + "3.11": [], # We need at least one "no extras" Python to test against. | 66 | 74 | } | 67 | 75 |
| 68 | 76 | SYSTEM_TEST_PYTHON_VERSIONS = ["3.12"] | @@ -264,10 +272,12 @@ def default(session): | 264 | 272 | ) | 265 | 273 |
| 266 | 274 |
| 267 | | -@nox.session(python=UNIT_TEST_PYTHON_VERSIONS) | | 275 | +@nox.session(python=ALL_PYTHON) | 268 | 276 | @_calculate_duration | 269 | 277 | def unit(session): | 270 | 278 | """Run the unit test suite.""" | | 279 | + if session.python not in UNIT_TEST_PYTHON_VERSIONS: | | 280 | + session.skip(f"Python {session.python} is not supported.") | 271 | 281 | default(session) | 272 | 282 |
| 273 | 283 |
| @@ -472,7 +482,7 @@ def cover(session): | 472 | 482 | session.run("coverage", "erase") | 473 | 483 |
| 474 | 484 |
| 475 | | -@nox.session(python="3.10") | | 485 | +@nox.session(python="3.11") | 476 | 486 | @_calculate_duration | 477 | 487 | def docs(session): | 478 | 488 | """Build the docs for this library.""" | @@ -508,7 +518,7 @@ def docs(session): | 508 | 518 | ) | 509 | 519 |
| 510 | 520 |
| 511 | | -@nox.session(python="3.10") | | 521 | +@nox.session(python="3.11") | 512 | 522 | @_calculate_duration | 513 | 523 | def docfx(session): | 514 | 524 | """Build the docfx yaml files for this library.""" | |
Collapse file Copy file name to clipboardExpand all lines: packages/pandas-gbq/pandas_gbq/__init__.py -11Lines changed: 0 additions & 11 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 3 | 3 | # license that can be found in the LICENSE file. | 4 | 4 |
| 5 | 5 | import logging | 6 | | -import sys | 7 | | -import warnings | 8 | 6 |
| 9 | 7 | from pandas_gbq import arrow | 10 | 8 | from pandas_gbq import version as pandas_gbq_version | | 13 | 11 |
| 14 | 12 | from .gbq import read_gbq, to_gbq # noqa | 15 | 13 |
| 16 | | -if sys.version_info < (3, 10): | 17 | | - warnings.warn( | 18 | | - "pandas-gbq no longer supports Python versions older than 3.10. " | 19 | | - f"Your Python version is {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}. " | 20 | | - "Please update to Python 3.10 or newer to ensure ongoing support. For more details, " | 21 | | - "see: https://cloud.google.com/python/docs/supported-python-versions", | 22 | | - FutureWarning, | 23 | | - ) | 24 | | - | 25 | 14 | logger = logging.Logger(__name__) | 26 | 15 |
| 27 | 16 | __version__ = pandas_gbq_version.__version__ | |
Collapse file Copy file name to clipboardExpand all lines: packages/pandas-gbq/setup.py +1-2Lines changed: 1 addition & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 88 | 88 | "License :: OSI Approved :: BSD License", | 89 | 89 | "Programming Language :: Python", | 90 | 90 | "Programming Language :: Python :: 3", | 91 | | - "Programming Language :: Python :: 3.10", | 92 | 91 | "Programming Language :: Python :: 3.11", | 93 | 92 | "Programming Language :: Python :: 3.12", | 94 | 93 | "Programming Language :: Python :: 3.13", | | 102 | 101 | packages=packages, | 103 | 102 | install_requires=dependencies, | 104 | 103 | extras_require=extras, | 105 | | - python_requires=">=3.10", | | 104 | + python_requires=">=3.11", | 106 | 105 | include_package_data=True, | 107 | 106 | zip_safe=False, | 108 | 107 | ) |
Collapse file Copy file name to clipboardExpand all lines: packages/pandas-gbq/testing/constraints-3.10.txt -23Lines changed: 0 additions & 23 deletions Collapse file Copy file name to clipboard +23Lines changed: 23 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +# This constraints file is used to check that lower bounds | | 2 | +# are correct in setup.py | | 3 | +# List *all* library dependencies and extras in this file. | | 4 | +# Pin the version to the lower bound. | | 5 | +# | | 6 | +# e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev", | | 7 | +# Then this file should have foo==1.14.0 | | 8 | +db-dtypes==1.1.1 | | 9 | +numpy==1.26.4 | | 10 | +pandas==1.5.3 | | 11 | +pyarrow==12.0.0 | | 12 | +pydata-google-auth==1.5.0 | | 13 | +psutil==5.9.8 | | 14 | +google-api-core==2.25.0 | | 15 | +google-auth==2.14.1 | | 16 | +google-auth-oauthlib==0.7.0 | | 17 | +google-cloud-bigquery==3.20.0 | | 18 | +packaging==22.0.0 | | 19 | +# Extras | | 20 | +google-cloud-bigquery-storage==2.29.0 | | 21 | +tqdm==4.23.0 | | 22 | +geopandas==0.14.4 | | 23 | +Shapely==1.8.5 |
Collapse file Copy file name to clipboardExpand all lines: packages/pandas-gbq/tests/unit/test_context.py -5Lines changed: 0 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -85,11 +85,6 @@ def test_read_gbq_should_use_dialect_with_query(monkeypatch, mock_bigquery_clien | 85 | 85 | def test_read_gbq_should_use_dialect_with_query_and_wait( | 86 | 86 | monkeypatch, mock_bigquery_client | 87 | 87 | ): | 88 | | - if not hasattr(mock_bigquery_client, "query_and_wait"): | 89 | | - pytest.skip( | 90 | | - f"google-cloud-bigquery {google.cloud.bigquery.__version__} does not have query_and_wait" | 91 | | - ) | 92 | | - | 93 | 88 | import pandas_gbq | 94 | 89 | import pandas_gbq.features | 95 | 90 |
| |
Collapse file Copy file name to clipboardExpand all lines: packages/pandas-gbq/tests/unit/test_gbq.py +4-32Lines changed: 4 additions & 32 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -58,10 +58,7 @@ def mock_row_iterator(mock_bigquery_client): | 58 | 58 | def generate_schema(): | 59 | 59 | if mock_bigquery_client.query.call_args: | 60 | 60 | query = mock_bigquery_client.query.call_args[0][0] | 61 | | - elif ( | 62 | | - hasattr(mock_bigquery_client, "query_and_wait") | 63 | | - and mock_bigquery_client.query_and_wait.call_args | 64 | | - ): | | 61 | + elif mock_bigquery_client.query_and_wait.call_args: | 65 | 62 | query = mock_bigquery_client.query_and_wait.call_args[0][0] | 66 | 63 | else: | 67 | 64 | query = "" | @@ -81,9 +78,7 @@ def default_bigquery_client(mock_bigquery_client, mock_query_job, mock_row_itera | 81 | 78 | mock_row_iterator.job = mock_query_job | 82 | 79 | mock_bigquery_client.list_rows.return_value = mock_row_iterator | 83 | 80 | mock_bigquery_client.query.return_value = mock_query_job | 84 | | - | 85 | | - if hasattr(mock_bigquery_client, "query_and_wait"): | 86 | | - mock_bigquery_client.query_and_wait.return_value = mock_row_iterator | | 81 | + mock_bigquery_client.query_and_wait.return_value = mock_row_iterator | 87 | 82 |
| 88 | 83 | # Mock out get_table. | 89 | 84 | def get_table(table_ref_or_id, **kwargs): | @@ -497,11 +492,6 @@ def test_read_gbq_with_inferred_project_id_with_query( | 497 | 492 | def test_read_gbq_with_inferred_project_id_with_query_and_wait( | 498 | 493 | monkeypatch, mock_bigquery_client | 499 | 494 | ): | 500 | | - if not hasattr(mock_bigquery_client, "query_and_wait"): | 501 | | - pytest.skip( | 502 | | - f"google-cloud-bigquery {google.cloud.bigquery.__version__} does not have query_and_wait" | 503 | | - ) | 504 | | - | 505 | 495 | monkeypatch.setattr( | 506 | 496 | pandas_gbq.features.FEATURES, | 507 | 497 | "_bigquery_installed_version", | @@ -540,11 +530,6 @@ def test_read_gbq_with_inferred_project_id_from_service_account_credentials_with | 540 | 530 | def test_read_gbq_with_inferred_project_id_from_service_account_credentials_with_query_and_wait( | 541 | 531 | monkeypatch, mock_bigquery_client, mock_service_account_credentials | 542 | 532 | ): | 543 | | - if not hasattr(mock_bigquery_client, "query_and_wait"): | 544 | | - pytest.skip( | 545 | | - f"google-cloud-bigquery {google.cloud.bigquery.__version__} does not have query_and_wait" | 546 | | - ) | 547 | | - | 548 | 533 | monkeypatch.setattr( | 549 | 534 | pandas_gbq.features.FEATURES, | 550 | 535 | "_bigquery_installed_version", | @@ -598,11 +583,6 @@ def test_read_gbq_with_max_results_ten_query(monkeypatch, mock_query_job): | 598 | 583 | def test_read_gbq_with_max_results_ten_query_and_wait( | 599 | 584 | monkeypatch, mock_bigquery_client | 600 | 585 | ): | 601 | | - if not hasattr(mock_bigquery_client, "query_and_wait"): | 602 | | - pytest.skip( | 603 | | - f"google-cloud-bigquery {google.cloud.bigquery.__version__} does not have query_and_wait" | 604 | | - ) | 605 | | - | 606 | 586 | monkeypatch.setattr( | 607 | 587 | pandas_gbq.features.FEATURES, | 608 | 588 | "_bigquery_installed_version", | @@ -966,15 +946,7 @@ def test_read_gbq_with_dry_run(mock_bigquery_client, mock_query_job): | 966 | 946 |
| 967 | 947 | dry_run_result = gbq.read_gbq("SELECT 1", project_id="my-project", dry_run=True) | 968 | 948 |
| 969 | | - # Check which method was called based on BigQuery version | 970 | | - if ( | 971 | | - hasattr(mock_bigquery_client, "query_and_wait") | 972 | | - and mock_bigquery_client.query_and_wait.called | 973 | | - ): | 974 | | - _, kwargs = mock_bigquery_client.query_and_wait.call_args | 975 | | - job_config = kwargs["job_config"] | 976 | | - else: | 977 | | - _, kwargs = mock_bigquery_client.query.call_args | 978 | | - job_config = kwargs["job_config"] | | 949 | + _, kwargs = mock_bigquery_client.query.call_args | | 950 | + job_config = kwargs["job_config"] | 979 | 951 | assert job_config.dry_run is True | 980 | 952 | assert dry_run_result["totalBytesProcessed"] == total_bytes_processed |
Collapse file Copy file name to clipboardExpand all lines: packages/pandas-gbq/tests/unit/test_query.py -20Lines changed: 0 additions & 20 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -26,11 +26,6 @@ def _make_connector(project_id: str = "some-project", **kwargs): | 26 | 26 | def test_query_and_wait_via_client_library_apierror_raises_genericgbqexception( | 27 | 27 | mock_bigquery_client, | 28 | 28 | ): | 29 | | - if not hasattr(mock_bigquery_client, "query_and_wait"): | 30 | | - pytest.skip( | 31 | | - f"google-cloud-bigquery {google.cloud.bigquery.__version__} does not have query_and_wait" | 32 | | - ) | 33 | | - | 34 | 29 | connector = _make_connector() | 35 | 30 | connector.client = mock_bigquery_client | 36 | 31 | mock_bigquery_client.query_and_wait.side_effect = ( | @@ -53,11 +48,6 @@ def test_query_and_wait_via_client_library_apierror_raises_genericgbqexception( | 53 | 48 | def test_query_and_wait_via_client_library_refresherror_raises_accessdenied_service_account( | 54 | 49 | mock_bigquery_client, | 55 | 50 | ): | 56 | | - if not hasattr(mock_bigquery_client, "query_and_wait"): | 57 | | - pytest.skip( | 58 | | - f"google-cloud-bigquery {google.cloud.bigquery.__version__} does not have query_and_wait" | 59 | | - ) | 60 | | - | 61 | 51 | connector = _make_connector() | 62 | 52 | connector.private_key = "abc" | 63 | 53 | connector.client = mock_bigquery_client | @@ -81,11 +71,6 @@ def test_query_and_wait_via_client_library_refresherror_raises_accessdenied_serv | 81 | 71 | def test_query_and_wait_via_client_library_refresherror_raises_accessdenied_user_credentials( | 82 | 72 | mock_bigquery_client, | 83 | 73 | ): | 84 | | - if not hasattr(mock_bigquery_client, "query_and_wait"): | 85 | | - pytest.skip( | 86 | | - f"google-cloud-bigquery {google.cloud.bigquery.__version__} does not have query_and_wait" | 87 | | - ) | 88 | | - | 89 | 74 | connector = _make_connector() | 90 | 75 | connector.client = mock_bigquery_client | 91 | 76 | mock_bigquery_client.query_and_wait.side_effect = ( | @@ -108,11 +93,6 @@ def test_query_and_wait_via_client_library_refresherror_raises_accessdenied_user | 108 | 93 | def test_query_and_wait_via_client_library_timeout_raises_querytimeout( | 109 | 94 | mock_bigquery_client, | 110 | 95 | ): | 111 | | - if not hasattr(mock_bigquery_client, "query_and_wait"): | 112 | | - pytest.skip( | 113 | | - f"google-cloud-bigquery {google.cloud.bigquery.__version__} does not have query_and_wait" | 114 | | - ) | 115 | | - | 116 | 96 | connector = _make_connector() | 117 | 97 | connector.client = mock_bigquery_client | 118 | 98 | connector.start = datetime.datetime(2020, 1, 1).timestamp() | |
|