From af3d13ff15b3c350e4e0beb391d2bd79b96584da Mon Sep 17 00:00:00 2001 From: Shuowei Li Date: Wed, 3 Dec 2025 23:45:47 +0000 Subject: [PATCH 1/2] Fix: Defer TableWidget import to prevent ZMQ port conflicts --- bigframes/display/__init__.py | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/bigframes/display/__init__.py b/bigframes/display/__init__.py index 97248a0efb..a1a2cbcd5b 100644 --- a/bigframes/display/__init__.py +++ b/bigframes/display/__init__.py @@ -16,11 +16,24 @@ from __future__ import annotations -try: - import anywidget # noqa +from typing import Any - from bigframes.display.anywidget import TableWidget - __all__ = ["TableWidget"] -except Exception: - pass +def __getattr__(name: str) -> Any: + if name == "TableWidget": + try: + import anywidget # noqa + + from bigframes.display.anywidget import TableWidget + + return TableWidget + except Exception: + raise AttributeError( + f"module '{__name__}' has no attribute '{name}'. " + "TableWidget requires anywidget and traitlets to be installed. " + "Please `pip install anywidget traitlets` or `pip install 'bigframes[anywidget]'`." + ) + raise AttributeError(f"module '{__name__}' has no attribute '{name}'") + + +__all__ = ["TableWidget"] From ac7285ebbf08b159269c4c67a649e440e9a7a614 Mon Sep 17 00:00:00 2001 From: Shuowei Li Date: Thu, 4 Dec 2025 18:59:18 +0000 Subject: [PATCH 2/2] add docstring --- bigframes/display/__init__.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bigframes/display/__init__.py b/bigframes/display/__init__.py index a1a2cbcd5b..aa1371db56 100644 --- a/bigframes/display/__init__.py +++ b/bigframes/display/__init__.py @@ -20,6 +20,15 @@ def __getattr__(name: str) -> Any: + """Lazily import TableWidget to avoid ZMQ port conflicts. + + anywidget and traitlets eagerly initialize kernel communication channels on + import. This can lead to race conditions and ZMQ port conflicts when + multiple Jupyter kernels are started in parallel, such as during notebook + tests. By using __getattr__, we defer the import of TableWidget until it is + explicitly accessed, preventing premature initialization and avoiding port + collisions. + """ if name == "TableWidget": try: import anywidget # noqa