diff --git a/src/azure-cli-core/azure/cli/core/aaz/_poller.py b/src/azure-cli-core/azure/cli/core/aaz/_poller.py index 0e6f3653b56..08066325c4f 100644 --- a/src/azure-cli-core/azure/cli/core/aaz/_poller.py +++ b/src/azure-cli-core/azure/cli/core/aaz/_poller.py @@ -62,6 +62,10 @@ def __init__(self, polling_generator, result_callback): self._done = None self._exception = None + # MSAL lazily imports requests when the credential is created on the polling thread, + # which can raise _DeadlockError (seen on Python 3.14). Import it here on the main thread first. + import requests # pylint: disable=unused-import + self._done = threading.Event() self._thread = threading.Thread( target=with_current_context(self._start), diff --git a/src/azure-cli-core/azure/cli/core/tests/test_aaz_poller.py b/src/azure-cli-core/azure/cli/core/tests/test_aaz_poller.py new file mode 100644 index 00000000000..a0b244e2dc3 --- /dev/null +++ b/src/azure-cli-core/azure/cli/core/tests/test_aaz_poller.py @@ -0,0 +1,35 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +import sys +import threading +import unittest +from unittest import mock + +from azure.cli.core.aaz._poller import AAZLROPoller + + +class TestAAZLROPoller(unittest.TestCase): + + def test_requests_imported_before_polling_thread(self): + loaded = [] + real_start = threading.Thread.start + + def start(thread): + loaded.append("requests" in sys.modules) + real_start(thread) + + def polling_generator(): + yield from () + + with mock.patch.dict(sys.modules), mock.patch.object(threading.Thread, "start", start): + for name in [n for n in sys.modules if n == "requests" or n.startswith("requests.")]: + del sys.modules[name] + AAZLROPoller(polling_generator=polling_generator(), result_callback=None).wait() + + self.assertEqual(loaded, [True]) + + +if __name__ == "__main__": + unittest.main()