Skip to content

Commit 189f147

Browse files
authored
chore: fix api coverage script in nightly build, ensure scripts tests run (#932)
* chore: fix api coverage script in nightly build, ensure scripts tests run * use consistent units for timestamp column * handle functions we cant inspect * skip python 3.9 * typo * fix skip
1 parent 2b355e2 commit 189f147

File tree

4 files changed

+79
-37
lines changed

4 files changed

+79
-37
lines changed

noxfile.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ def run_unit(session, install_test_extra):
195195
install_unittest_dependencies(session, install_test_extra, "-c", constraints_path)
196196

197197
# Run py.test against the unit tests.
198+
scripts_path = "scripts"
198199
tests_path = os.path.join("tests", "unit")
199200
third_party_tests_path = os.path.join("third_party", "bigframes_vendored")
200201
session.run(
@@ -209,6 +210,7 @@ def run_unit(session, install_test_extra):
209210
"--cov-fail-under=0",
210211
tests_path,
211212
third_party_tests_path,
213+
scripts_path,
212214
*session.posargs,
213215
)
214216

scripts/__init__.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright 2024 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.

scripts/publish_api_coverage.py

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,15 @@ def names_from_signature(signature):
107107

108108

109109
def calculate_missing_parameters(bigframes_function, target_function):
110-
bigframes_params = names_from_signature(inspect.signature(bigframes_function))
111-
target_params = names_from_signature(inspect.signature(target_function))
110+
# Some built-in functions can't be inspected. These raise a ValueError.
111+
try:
112+
bigframes_signature = inspect.signature(bigframes_function)
113+
target_signature = inspect.signature(target_function)
114+
except ValueError:
115+
return {}
116+
117+
bigframes_params = names_from_signature(bigframes_signature)
118+
target_params = names_from_signature(target_signature)
112119
return target_params - bigframes_params
113120

114121

@@ -164,13 +171,20 @@ def generate_pandas_api_coverage():
164171
token_type = "property"
165172

166173
is_in_bigframes = hasattr(bigframes_obj, member)
167-
requires_index = False
168-
requires_ordering = False
174+
requires_index = ""
175+
requires_ordering = ""
169176

170177
if is_in_bigframes:
171178
attr = getattr(bigframes_obj, member)
172-
requires_index = hasattr(attr, "_validations_requires_index")
173-
requires_ordering = hasattr(attr, "_validations_requires_ordering")
179+
180+
# TODO(b/361101138): Add check/documentation for partial
181+
# support (e.g. with some parameters).
182+
requires_index = (
183+
"Y" if hasattr(attr, "_validations_requires_index") else ""
184+
)
185+
requires_ordering = (
186+
"Y" if hasattr(attr, "_validations_requires_ordering") else ""
187+
)
174188

175189
api_patterns.append(
176190
[
@@ -279,9 +293,12 @@ def build_api_coverage_table(bigframes_version: str, release_version: str):
279293
sklearn_cov_df["module"] = "bigframes.ml"
280294
combined_df = pd.concat([pandas_cov_df, sklearn_cov_df])
281295
combined_df["timestamp"] = pd.Timestamp.now()
296+
# BigQuery only supports microsecond precision timestamps.
297+
combined_df["timestamp"] = combined_df["timestamp"].astype("datetime64[us]")
282298
combined_df["bigframes_version"] = bigframes_version
283299
combined_df["release_version"] = release_version
284-
return combined_df.infer_objects().convert_dtypes()
300+
combined_df = combined_df.infer_objects().convert_dtypes()
301+
return combined_df
285302

286303

287304
def format_api(api_names, is_in_bigframes, api_prefix):
@@ -313,16 +330,14 @@ def generate_api_coverage(df, api_prefix):
313330
api_prefix,
314331
),
315332
"Implemented": "",
316-
"Requires index": "",
317-
"Requires ordering": "",
333+
"Requires index": dataframe_apis["requires_index"],
334+
"Requires ordering": dataframe_apis["requires_ordering"],
318335
"Missing parameters": dataframe_apis["missing_parameters"],
319336
}
320337
)
321338
dataframe_table.loc[fully_implemented, "Implemented"] = "Y"
322339
dataframe_table.loc[partial_implemented, "Implemented"] = "P"
323340
dataframe_table.loc[not_implemented, "Implemented"] = "N"
324-
dataframe_table.loc[dataframe_apis["requires_index"], "Requires index"] = "Y"
325-
dataframe_table.loc[dataframe_apis["requires_ordering"], "Requires ordering"] = "Y"
326341
return dataframe_table
327342

328343

scripts/test_publish_api_coverage.py

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,48 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import sys
16+
1517
import pandas
16-
import publish_api_coverage
18+
import pytest
19+
20+
from . import publish_api_coverage
21+
22+
23+
@pytest.fixture
24+
def api_coverage_df():
25+
return publish_api_coverage.build_api_coverage_table("my_bf_ver", "my_release_ver")
1726

1827

19-
def test_api_coverage_produces_expected_schema():
20-
df = publish_api_coverage.build_api_coverage_table("my_bf_ver", "my_release_ver")
28+
def test_api_coverage_produces_expected_schema(api_coverage_df):
29+
if sys.version.split(".")[:2] == ["3", "9"]:
30+
pytest.skip(
31+
"Python 3.9 uses older pandas without good microsecond timestamp support."
32+
)
33+
2134
pandas.testing.assert_series_equal(
22-
df.dtypes,
35+
api_coverage_df.dtypes,
2336
pandas.Series(
24-
data=[
25-
"string",
26-
"string",
27-
"string",
28-
"boolean",
29-
"string",
30-
"string",
31-
"datetime64[ns]",
32-
"string",
33-
"string",
34-
],
35-
index=[
36-
"api",
37-
"pattern",
38-
"kind",
39-
"is_in_bigframes",
40-
"missing_parameters",
41-
"module",
42-
"timestamp",
43-
"bigframes_version",
44-
"release_version",
45-
],
37+
data={
38+
# Note to developer: if you update this test, you will also
39+
# need to update schema of the API coverage BigQuery table in
40+
# the bigframes-metrics project.
41+
"api": "string",
42+
"pattern": "string",
43+
"kind": "string",
44+
"is_in_bigframes": "boolean",
45+
"missing_parameters": "string",
46+
"requires_index": "string",
47+
"requires_ordering": "string",
48+
"module": "string",
49+
"timestamp": "datetime64[us]",
50+
"bigframes_version": "string",
51+
"release_version": "string",
52+
},
4653
),
4754
)
55+
56+
57+
def test_api_coverage_produces_missing_parameters(api_coverage_df):
58+
"""Make sure at least some functions have reported missing parameters."""
59+
assert (api_coverage_df["missing_parameters"].str.len() > 0).any()

0 commit comments

Comments
 (0)