Skip to content

deps: Add support for Python 3.13 for everything but remote functions #1307

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
14cefcd
chore: Add support for Python 3.13
arwas11 Jan 21, 2025
e8e4811
Merge branch 'main' into update-to-python-3-13
arwas11 Jan 21, 2025
9f65105
Merge remote-tracking branch 'origin/main' into update-to-python-3-13
arwas11 Jan 22, 2025
c998c11
update contibuting.rst with the the new version
arwas11 Jan 22, 2025
0a46d4a
skip sklearn import
arwas11 Jan 22, 2025
8414fad
Merge branch 'main' into update-to-python-3-13
arwas11 Jan 23, 2025
d75a1b3
Merge remote-tracking branch 'origin/main' into update-to-python-3-13
arwas11 Jan 23, 2025
db78d65
Merge remote-tracking branch 'origin/update-to-python-3-13' into upda…
arwas11 Jan 23, 2025
4c9e4a6
skip api coverage tests because of sklearn NameError
arwas11 Jan 24, 2025
1bd284d
Merge remote-tracking branch 'origin/main' into update-to-python-3-13
arwas11 Jan 24, 2025
678b676
skip remote function tests
arwas11 Jan 24, 2025
25bc738
skip all remote function tests and doctests
arwas11 Jan 24, 2025
106af9a
update doctest python version to 3.12 in noxfile
arwas11 Jan 28, 2025
cf91455
Merge branch 'main' into update-to-python-3-13
arwas11 Jan 28, 2025
57f7227
Update noxfile.py
tswast Jan 28, 2025
213eaeb
Merge branch 'main' into update-to-python-3-13
tswast Jan 28, 2025
875f59a
Merge branch 'main' into update-to-python-3-13
arwas11 Jan 28, 2025
3fca9ab
Merge branch 'main' into update-to-python-3-13
arwas11 Jan 28, 2025
366e4f8
fix the system_pre-release error
arwas11 Jan 28, 2025
a389687
Merge remote-tracking branch 'origin/update-to-python-3-13' into upda…
arwas11 Jan 28, 2025
102f2cb
Merge branch 'main' into update-to-python-3-13
arwas11 Jan 28, 2025
ad9110b
Merge branch 'main' into update-to-python-3-13
arwas11 Jan 28, 2025
d3279d6
Merge remote-tracking branch 'origin/main' into update-to-python-3-13
tswast Jan 29, 2025
66f584d
skip remote functions notebooks on 3.13 tests
tswast Jan 29, 2025
770fef2
🦉 Updates from OwlBot post-processor
gcf-owl-bot[bot] Jan 29, 2025
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/unittest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-22.04
strategy:
matrix:
python: ['3.9', '3.10', '3.11', '3.12']
python: ['3.9', '3.10', '3.11', '3.12', '3.13']
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
10 changes: 6 additions & 4 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ In order to add a feature:
documentation.

- The feature must work fully on the following CPython versions:
3.9, 3.10, 3.11 and 3.12 on both UNIX and Windows.
3.9, 3.10, 3.11, 3.12 and 3.13 on both UNIX and Windows.

- The feature must not add unnecessary dependencies (where
"unnecessary" is of course subjective, but new dependencies should
Expand Down Expand Up @@ -72,7 +72,7 @@ We use `nox <https://nox.readthedocs.io/en/latest/>`__ to instrument our tests.

- To run a single unit test::

$ nox -s unit-3.12 -- -k <name of test>
$ nox -s unit-3.13 -- -k <name of test>


.. note::
Expand Down Expand Up @@ -143,12 +143,12 @@ Running System Tests
$ nox -s system

# Run a single system test
$ nox -s system-3.12 -- -k <name of test>
$ nox -s system-3.13 -- -k <name of test>


.. note::

System tests are only configured to run under Python 3.9, 3.11 and 3.12.
System tests are only configured to run under Python 3.9, 3.11, 3.12 and 3.13.
For expediency, we do not run them in older versions of Python 3.

This alone will not run the tests. You'll need to change some local
Expand Down Expand Up @@ -262,11 +262,13 @@ We support:
- `Python 3.10`_
- `Python 3.11`_
- `Python 3.12`_
- `Python 3.13`_

.. _Python 3.9: https://docs.python.org/3.9/
.. _Python 3.10: https://docs.python.org/3.10/
.. _Python 3.11: https://docs.python.org/3.11/
.. _Python 3.12: https://docs.python.org/3.12/
.. _Python 3.13: https://docs.python.org/3.13/


Supported versions can be found in our ``noxfile.py`` `config`_.
Expand Down
13 changes: 13 additions & 0 deletions bigframes/core/expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import typing
from typing import Mapping, TypeVar, Union

import pandas as pd

import bigframes.core.identifiers as ids
import bigframes.dtypes as dtypes
import bigframes.operations
Expand Down Expand Up @@ -253,6 +255,17 @@ def is_bijective(self) -> bool:
# () <-> value
return True

def __eq__(self, other):
if not isinstance(other, ScalarConstantExpression):
return False

# With python 3.13 and the pre-release version of pandas,
# NA == NA is NA instead of True
if pd.isna(self.value) and pd.isna(other.value): # type: ignore
return self.dtype == other.dtype

return self.value == other.value and self.dtype == other.dtype


@dataclasses.dataclass(frozen=True)
class UnboundVariableExpression(Expression):
Expand Down
2 changes: 1 addition & 1 deletion bigframes/session/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1482,7 +1482,7 @@ def read_gbq_function(
2 TestCad$123456Str
dtype: string

Another use case is to define your own remote funtion and use it later.
Another use case is to define your own remote function and use it later.
For example, define the remote function:

>>> @bpd.remote_function()
Expand Down
14 changes: 14 additions & 0 deletions notebooks/getting_started/getting_started_bq_dataframes.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1448,6 +1448,20 @@
"Running your own Python functions (or being able to bring your packages) and using them at scale is a challenge many data scientists face. BigQuery DataFrames makes it easy to deploy [remote functions](https://cloud.google.com/python/docs/reference/bigframes/latest/bigframes.pandas#bigframes_pandas_remote_function) that run scalar Python functions at BigQuery scale. These functions are persisted as [BigQuery remote functions](https://cloud.google.com/bigquery/docs/remote-functions) that you can then re-use."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"\n",
"# Python 3.13 is not yet a supported runtime for remote functions.\n",
"# See: https://cloud.google.com/functions/docs/runtime-support#python for the supported runtimes.\n",
"if sys.version_info >= (3, 13, 0):\n",
" sys.exit(0)"
]
},
{
"cell_type": "markdown",
"metadata": {
Expand Down
14 changes: 14 additions & 0 deletions notebooks/location/regionalized.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1339,6 +1339,20 @@
"# Using the Remote Functions"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"\n",
"# Python 3.13 is not yet a supported runtime for remote functions.\n",
"# See: https://cloud.google.com/functions/docs/runtime-support#python for the supported runtimes.\n",
"if sys.version_info >= (3, 13, 0):\n",
" sys.exit(0)"
]
},
{
"attachments": {},
"cell_type": "markdown",
Expand Down
15 changes: 15 additions & 0 deletions notebooks/remote_functions/remote_function.ipynb
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "bcff4fc4",
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"\n",
"# Python 3.13 is not yet a supported runtime for remote functions.\n",
"# See: https://cloud.google.com/functions/docs/runtime-support#python for the supported runtimes.\n",
"if sys.version_info >= (3, 13, 0):\n",
" sys.exit(0)"
]
},
{
"cell_type": "code",
"execution_count": 19,
Expand Down
14 changes: 14 additions & 0 deletions notebooks/remote_functions/remote_function_usecases.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@
"# limitations under the License."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"\n",
"# Python 3.13 is not yet a supported runtime for remote functions.\n",
"# See: https://cloud.google.com/functions/docs/runtime-support#python for the supported runtimes.\n",
"if sys.version_info >= (3, 13, 0):\n",
" sys.exit(0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@
"</table>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"\n",
"# Python 3.13 is not yet a supported runtime for remote functions.\n",
"# See: https://cloud.google.com/functions/docs/runtime-support#python for the supported runtimes.\n",
"if sys.version_info >= (3, 13, 0):\n",
" sys.exit(0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
70 changes: 42 additions & 28 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@
import shutil
import time
from typing import Dict, List
import warnings

import nox
import nox.sessions

BLACK_VERSION = "black==22.3.0"
ISORT_VERSION = "isort==5.12.0"

# TODO: switch to 3.13 once remote functions / cloud run adds a runtime for it (internal issue 333742751)
LATEST_FULLY_SUPPORTED_PYTHON = "3.12"

# pytest-retry is not yet compatible with pytest 8.x.
# https://github.com/str0zzapreti/pytest-retry/issues/32
PYTEST_VERSION = "pytest<8.0.0dev"
Expand All @@ -47,7 +49,7 @@

DEFAULT_PYTHON_VERSION = "3.10"

UNIT_TEST_PYTHON_VERSIONS = ["3.9", "3.10", "3.11", "3.12"]
UNIT_TEST_PYTHON_VERSIONS = ["3.9", "3.10", "3.11", "3.12", "3.13"]
UNIT_TEST_STANDARD_DEPENDENCIES = [
"mock",
"asyncmock",
Expand All @@ -57,15 +59,14 @@
"pytest-asyncio",
"pytest-mock",
]
UNIT_TEST_EXTERNAL_DEPENDENCIES: List[str] = []
UNIT_TEST_LOCAL_DEPENDENCIES: List[str] = []
UNIT_TEST_DEPENDENCIES: List[str] = []
UNIT_TEST_EXTRAS: List[str] = []
UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {"3.12": ["polars"]}

# There are 4 different ibis-framework 9.x versions we want to test against.
# 3.10 is needed for Windows tests.
SYSTEM_TEST_PYTHON_VERSIONS = ["3.9", "3.10", "3.11", "3.12"]
SYSTEM_TEST_PYTHON_VERSIONS = ["3.9", "3.10", "3.12", "3.13"]
SYSTEM_TEST_STANDARD_DEPENDENCIES = [
"jinja2",
"mock",
Expand Down Expand Up @@ -169,14 +170,6 @@ def install_unittest_dependencies(session, install_test_extra, *constraints):
standard_deps = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_DEPENDENCIES
session.install(*standard_deps, *constraints)

if UNIT_TEST_EXTERNAL_DEPENDENCIES:
msg = (
"'unit_test_external_dependencies' is deprecated. Instead, please "
"use 'unit_test_dependencies' or 'unit_test_local_dependencies'."
)
warnings.warn(msg, DeprecationWarning)
session.install(*UNIT_TEST_EXTERNAL_DEPENDENCIES, *constraints)

if UNIT_TEST_LOCAL_DEPENDENCIES:
session.install(*UNIT_TEST_LOCAL_DEPENDENCIES, *constraints)

Expand Down Expand Up @@ -375,7 +368,7 @@ def system(session: nox.sessions.Session):
)


@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS[-1])
@nox.session(python=LATEST_FULLY_SUPPORTED_PYTHON)
def system_noextras(session: nox.sessions.Session):
"""Run the system test suite."""
run_system(
Expand All @@ -386,7 +379,7 @@ def system_noextras(session: nox.sessions.Session):
)


@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS[-1])
@nox.session(python=LATEST_FULLY_SUPPORTED_PYTHON)
def doctest(session: nox.sessions.Session):
"""Run the system test suite."""
run_system(
Expand Down Expand Up @@ -762,27 +755,48 @@ def notebook(session: nox.Session):
"notebooks/apps/synthetic_data_generation.ipynb",
]

# TODO: remove exception for Python 3.13 cloud run adds a runtime for it (internal issue 333742751)
# TODO: remove exception for Python 3.13 if nbmake adds support for
# sys.exit(0) or pytest.skip(...).
# See: https://github.com/treebeardtech/nbmake/issues/134
if session.python == "3.13":
denylist.extend(
[
"notebooks/getting_started/getting_started_bq_dataframes.ipynb",
"notebooks/remote_functions/remote_function_usecases.ipynb",
"notebooks/remote_functions/remote_function_vertex_claude_model.ipynb",
"notebooks/remote_functions/remote_function.ipynb",
]
)

# Convert each Path notebook object to a string using a list comprehension.
notebooks = [str(nb) for nb in notebooks_list]

# Remove tests that we choose not to test.
notebooks = list(filter(lambda nb: nb not in denylist, notebooks))

# Regionalized notebooks
notebooks_reg = {
"regionalized.ipynb": [
"asia-southeast1",
"eu",
"europe-west4",
"southamerica-west1",
"us",
"us-central1",
]
}
notebooks_reg = {
os.path.join("notebooks/location", nb): regions
for nb, regions in notebooks_reg.items()
}
# TODO: remove exception for Python 3.13 cloud run adds a runtime for it (internal issue 333742751)
# TODO: remove exception for Python 3.13 if nbmake adds support for
# sys.exit(0) or pytest.skip(...).
# See: https://github.com/treebeardtech/nbmake/issues/134
if session.python == "3.13":
notebooks_reg = {}
else:
notebooks_reg = {
"regionalized.ipynb": [
"asia-southeast1",
"eu",
"europe-west4",
"southamerica-west1",
"us",
"us-central1",
]
}
notebooks_reg = {
os.path.join("notebooks/location", nb): regions
for nb, regions in notebooks_reg.items()
}

# The pytest --nbmake exits silently with "no tests ran" message if
# one of the notebook paths supplied does not exist. Let's make sure that
Expand Down
4 changes: 2 additions & 2 deletions owlbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
# ----------------------------------------------------------------------------
templated_files = common.py_library(
default_python_version="3.10",
unit_test_python_versions=["3.9", "3.10", "3.11", "3.12"],
system_test_python_versions=["3.9", "3.11", "3.12"],
unit_test_python_versions=["3.9", "3.10", "3.11", "3.12", "3.13"],
system_test_python_versions=["3.9", "3.11", "3.12", "3.13"],
cov_level=35,
intersphinx_dependencies={
"pandas": "https://pandas.pydata.org/pandas-docs/stable/",
Expand Down
8 changes: 8 additions & 0 deletions scripts/test_publish_api_coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ def api_coverage_df():
return publish_api_coverage.build_api_coverage_table("my_bf_ver", "my_release_ver")


@pytest.mark.skipif(
sys.version_info >= (3, 13),
reason="Issues with installing sklearn for this test in python 3.13",
)
def test_api_coverage_produces_expected_schema(api_coverage_df):
if sys.version.split(".")[:2] == ["3", "9"]:
pytest.skip(
Expand Down Expand Up @@ -54,6 +58,10 @@ def test_api_coverage_produces_expected_schema(api_coverage_df):
)


@pytest.mark.skipif(
sys.version_info >= (3, 13),
reason="Issues with installing sklearn for this test in python 3.13",
)
def test_api_coverage_produces_missing_parameters(api_coverage_df):
"""Make sure at least some functions have reported missing parameters."""
assert (api_coverage_df["missing_parameters"].str.len() > 0).any()
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Operating System :: OS Independent",
"Topic :: Internet",
],
Expand Down
7 changes: 7 additions & 0 deletions tests/system/large/test_remote_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import math # must keep this at top level to test udf referring global import
import os.path
import shutil
import sys
import tempfile
import textwrap

Expand Down Expand Up @@ -47,6 +48,12 @@
_team_euler = "Team Euler"


pytestmark = pytest.mark.skipif(
sys.version_info >= (3, 13),
reason="Runtime 'python313' is not supported yet. Skip for now.",
)


def cleanup_remote_function_assets(
bigquery_client, cloudfunctions_client, remote_udf, ignore_failures=True
):
Expand Down
Loading