Repository navigation
platform module functions execute for a long time if user has no permissions to WMI #112278
Description
Activity
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Nov 20, 2023 It's very hard to work around this or avoid the delay. Even if you do not use
platformin your code, or usesys/osreplacements likeos.nameorsys.getwindowsversion()it sooner or later turns out that theplatformmodule is used by some 3rd party library you import because it is widely used in Python's world.As an example, merely importing aiohttp or SQLAlchemy in a session over SSH on Windows Server 2019 using Python 3.12:
Python 3.12.0 (tags/v3.12.0:0fb18b0, Oct 2 2023, 13:03:39) [MSC v.1935 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import timeit >>> timeit.timeit('import aiohttp', number=1) 10.157976499991491Python 3.12.0 (tags/v3.12.0:0fb18b0, Oct 2 2023, 13:03:39) [MSC v.1935 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import timeit >>> timeit.timeit('import sqlalchemy', number=1) 10.204078600043431cc @zooba as the original author
bumping this, it is a serious issue in my project
I think we can replace the
platform._wmi_querywith the dummy implementation when first failure, this can reduce the time costs to nearly 5 seconds, (just one timeout when connect to WMI):PS C:\Users\xxxxx\Source\cpython> .\python.bat -m timeit -s "import platform" -n 1 -r 1 "platform.system()" Running Debug|x64 interpreter... 1 loop, best of 1: 5.12 sec per loopThen I think we should set the timeout for the connection to WMI. But https://learn.microsoft.com/en-us/windows/win32/api/wbemcli/nf-wbemcli-iwbemlocator-connectserver said that the timeout can only be set to "2 minutes or less" and there seems to no other way to set it to a custom value. So using a
Eventobject to simulate the timeout may be a solution.This should be backported to 3.12 as well, but they're right in the middle of getting 3.12.1 ready and I don't think this is that urgent. Monkeypatch
platform._wmi_queryearly in your app if you need to suppress it.Reacted by Marcin GozdalikThank you for fixing this! For 3.12.1 we will use the runtime hooks feature from pyinstaller to override the
_wmi_queryfunction before anything else is run.The timeout is too short - I'm getting failures on some of my test machines. It wouldn't surprise me if it's due to them being slower, and so COM takes longer to load and initialize on its first use.
We can either make the timeout longer (I'd suggest 1 second), or add a second event that sets just before the connection attempt. That way we can wait for everything to load with a long timeout, but only wait for the connection with a short timeout.
The timeout is too short - I'm getting failures on some of my test machines. It wouldn't surprise me if it's due to them being slower, and so COM takes longer to load and initialize on its first use.
We can either make the timeout longer (I'd suggest 1 second), or add a second event that sets just before the connection attempt. That way we can wait for everything to load with a long timeout, but only wait for the connection with a short timeout.
Increasing the timeout to 1 second will lead to
_wmi_querytaking more than 1 second to call without WMI permission, even if the COM has loaded and initialized. Therefore, I think the second approach is better.- added a commit that references this issue
on Dec 8, 2023 Thanks for the PR! That makes the backport a bit more complicated, but I think once we've seen it's stable in 3.13 then we can just backport the entire file - nothing else should've changed here for 3.13.
- added3.12only security fixesonly security fixes3.13only security fixesonly security fixes
on Dec 11, 2023 5 remaining items
- added a commit that references this issue
on Dec 15, 2023 - added a commit that references this issue
on Apr 12, 2024 If the fix in #117818 reduces/fixes the occasional errors we've been getting in CI, then I'll consider this issue complete and close it.
Reviews/manual testing appreciated.
Bug report
Bug description:
From Python 3.12, probably since #89545 was implemented, the invocation of functions from
platformmodules takes a multiple of 5 seconds if the user has no permissions to perform WMI queries. It can be reproduced by connecting to a Windows machine using SSH and executing a Python script from cmd or ps. Access to WMI for remote sessions is turned off by default but this probably can be achieved also by removing permissions usingwmimgmt.mscapplication.For example, the execution of the
systemfunction in Python 3.12:and the same in Python 3.11:
(
timeitused with-n 1 -r 1to avoid using cache in the platform module. When results get cached then of course it works fast).The delay comes from de33df2#diff-cb1ba6039236dca71c97ea898f2798c60262c30614192862259889f839e4d503R323 which takes 5 seconds and raises
OSError:[WinError -2147217405] Windows Error 0x80041003.platform.systemapparently calls it twice. This applies to all functions from the module that makes WMI queries.Windows version used for tests:
Edition: Windows Server 2016 Standard
Version: 1607
OS Build: 14393.6452
CPython versions tested on:
3.12
Operating systems tested on:
Windows
Linked PRs