@@ -154,6 +154,7 @@ def __init__(
154154 unicast : bool = False ,
155155 ip_version : IPVersion | None = None ,
156156 apple_p2p : bool = False ,
157+ use_asyncio : bool | None = None ,
157158 ) -> None :
158159 """Creates an instance of the Zeroconf class, establishing
159160 multicast communications, listening and reaping threads.
@@ -169,6 +170,14 @@ def __init__(
169170 :param ip_version: IP versions to support. If `choice` is a list, the default is detected
170171 from it. Otherwise defaults to V4 only for backward compatibility.
171172 :param apple_p2p: use AWDL interface (only macOS)
173+ :param use_asyncio: explicitly control whether to attach to the running
174+ asyncio event loop (``True``) or run an internal thread with its
175+ own loop (``False``). ``None`` (default) keeps the historic
176+ behavior: attach if an event loop is running, otherwise start a
177+ thread. Set to ``False`` when running inside an environment that
178+ already has an event loop (e.g. Jupyter) but you want blocking
179+ semantics. ``True`` raises :class:`RuntimeError` immediately if no
180+ running event loop is found, instead of falling back to the thread.
172181 """
173182 if ip_version is None :
174183 ip_version = autodetect_ip_version (interfaces )
@@ -178,7 +187,11 @@ def __init__(
178187 if apple_p2p and sys .platform != "darwin" :
179188 raise RuntimeError ("Option `apple_p2p` is not supported on non-Apple platforms." )
180189
190+ if use_asyncio is True and get_running_loop () is None :
191+ raise RuntimeError ("use_asyncio=True requires a running asyncio event loop" )
192+
181193 self .unicast = unicast
194+ self ._use_asyncio = use_asyncio
182195 listen_socket , respond_sockets = create_sockets (interfaces , unicast , ip_version , apple_p2p = apple_p2p )
183196 log .debug ("Listen socket %s, respond sockets %s" , listen_socket , respond_sockets )
184197
@@ -216,7 +229,7 @@ def started(self) -> bool:
216229
217230 def start (self ) -> None :
218231 """Start Zeroconf."""
219- self .loop = get_running_loop ()
232+ self .loop = None if self . _use_asyncio is False else get_running_loop ()
220233 if self .loop :
221234 self .engine .setup (self .loop , None )
222235 return
0 commit comments