Skip to content

Commit ace618b

Browse files
fix(bigframes): resolve session-scoped API method logging (#18076)
Fixes an issue where API method calls on DataFrame and Series objects were recorded into global state instead of their specific session, preventing cross-session and cross-test logging interference. - Updated `log_adapter._find_session` to detect active sessions directly from DataFrame and Series instances. - Added recursion safeguards during session property lookup in `log_adapter`. Fixes #<545233537> 🦕 --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent 68bdaba commit ace618b

3 files changed

Lines changed: 21 additions & 19 deletions

File tree

packages/bigframes/bigframes/core/logging/log_adapter.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,14 @@ def wrapper(*args, **kwargs):
172172
base_name = custom_base_name
173173

174174
full_method_name = f"{base_name.lower()}-{api_method_name}"
175-
# Track directly called methods
176-
if len(_call_stack) == 0:
177-
session = _find_session(*args, **kwargs)
178-
add_api_method(full_method_name, session=session)
179-
180175
_call_stack.append(full_method_name)
181176

182177
try:
178+
# Track directly called methods
179+
if len(_call_stack) == 1:
180+
session = _find_session(*args, **kwargs)
181+
add_api_method(full_method_name, session=session)
182+
183183
return method(*args, **kwargs)
184184
except (NotImplementedError, TypeError) as e:
185185
# Log method parameters that are implemented in pandas but either missing (TypeError)
@@ -220,12 +220,12 @@ def wrapped(*args, **kwargs):
220220
property_name = prop.__name__
221221
full_property_name = f"{class_name.lower()}-{property_name.lower()}"
222222

223-
if len(_call_stack) == 0:
224-
session = _find_session(*args, **kwargs)
225-
add_api_method(full_property_name, session=session)
226-
227223
_call_stack.append(full_property_name)
228224
try:
225+
if len(_call_stack) == 1:
226+
session = _find_session(*args, **kwargs)
227+
add_api_method(full_property_name, session=session)
228+
229229
return prop(*args, **kwargs)
230230
finally:
231231
_call_stack.pop()
@@ -309,21 +309,23 @@ def _is_session_initialized(session):
309309
Because the method logger could get called before Session.__init__ has a
310310
chance to run, we use the globals in that case.
311311
"""
312-
return hasattr(session, "_api_methods_lock") and hasattr(session, "_api_methods")
312+
return hasattr(session, "_api_methods_lock") and isinstance(
313+
getattr(session, "_api_methods", None), list
314+
)
313315

314316

315317
def _find_session(*args, **kwargs):
316318
# This function cannot import Session at the top level because Session
317319
# imports log_adapter.
318320
from bigframes.session import Session
319321

320-
session = args[0] if args else None
321-
if (
322-
session is not None
323-
and isinstance(session, Session)
324-
and _is_session_initialized(session)
325-
):
326-
return session
322+
for arg in args:
323+
if isinstance(arg, Session) and _is_session_initialized(arg):
324+
return arg
325+
if hasattr(arg, "__dict__") and "_block" in arg.__dict__:
326+
session = getattr(arg, "_session", None)
327+
if isinstance(session, Session) and _is_session_initialized(session):
328+
return session
327329

328330
session = kwargs.get("session")
329331
if (

packages/bigframes/bigframes/dataframe.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ def __getattr__(self, key: str):
753753
# https://github.com/googleapis/python-bigquery-dataframes/issues/728
754754
# and
755755
# https://nedbatchelder.com/blog/201010/surprising_getattr_recursion.html
756-
if key == "_block":
756+
if "_block" not in self.__dict__ or key == "_block":
757757
raise AttributeError(key)
758758

759759
if key in self._block.column_labels:

packages/bigframes/bigframes/series.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1737,7 +1737,7 @@ def __getattr__(self, key: str):
17371737
# https://github.com/googleapis/python-bigquery-dataframes/issues/728
17381738
# and
17391739
# https://nedbatchelder.com/blog/201010/surprising_getattr_recursion.html
1740-
if key == "_block":
1740+
if "_block" not in self.__dict__ or key == "_block":
17411741
raise AttributeError(key)
17421742
elif hasattr(pandas.Series, key):
17431743
log_adapter.submit_pandas_labels(

0 commit comments

Comments
 (0)