platform: import _wmi on first use

オープン 初心者向け
#161,513 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
76/100
issue の種類
機能追加
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
python

調査の方向性

Lib/platform.py、特にモジュールレベルの _wmi のインポートと _wmi_query() を読んでください。issue には変更案と測定された挙動が含まれています。test_platform と test_wmi のテストを確認し、platform のインポート時に _wmi が読み込まれないこと、および指定された Windows ヘルパーが引き続き同じ値を返すことを確認してください。

索引モデルが issue の本文から書いたものです。

説明

OS-windows performance stdlib type-feature
Feature or enhancement

Lib/platform.py imports _wmi at module level on Windows. _wmi.pyd loads oleaut32.dll and propsys.dll (with _wmi.pyd itself and their dependencies, 7 more images in the process), but WMI is only queried by win32_ver(), version(), release(), uname() and the processor/machine helpers. Code that only imports platform, or calls python_version() or system(), pays for it anyway. pytest is one example: it imports platform on every run.

Moving the import into _wmi_query() (keeping the "unavailable" state so a failed import or query is not retried):

60 runs each, perf_counter around the import before after difference
import platform 18.6 ms 12.9 ms −5.5 ms [−6.0, −5.1]
import pytest 206 ms 196 ms −9.5 ms [−13.6, −4.7]

(python-build-standalone 3.14.4, Windows 11 26100.) win32_ver(), uname(), machine(), version() and processor() return the same values; test_platform and test_wmi pass.

The change, against main (2781ffe1f2):

diff --git a/Lib/platform.py b/Lib/platform.py
index c87bf2f..375acc2 100644
--- a/Lib/platform.py
+++ b/Lib/platform.py
@@ -114,10 +114,10 @@ import sys
 import functools
 import itertools
 lazy import warnings
-try:
-    import _wmi
-except ImportError:
-    _wmi = None
+# _wmi is imported on first use (see _wmi_query): loading it maps the OLE
+# and property-system DLLs, which most users of this module never need.
+# None means not imported yet, False means unavailable.
+_wmi = None
 
 ### Globals & Constants
 
@@ -332,6 +332,12 @@ def _syscmd_ver(system='', release='', version='',
 
 def _wmi_query(table, *keys):
     global _wmi
+    if _wmi is None:
+        try:
+            import _wmi as wmi
+        except ImportError:
+            wmi = False
+        _wmi = wmi
     if not _wmi:
         raise OSError("not supported")
     table = {
@@ -344,7 +350,7 @@ def _wmi_query(table, *keys):
             table,
         )).split("\0")
     except OSError:
-        _wmi = None
+        _wmi = False
         raise OSError("not supported")
     split_data = (i.partition("=") for i in data)
     dict_data = {i[0]: i[2] for i in split_data}

(PEP 810's lazy import doesn't fit here because the import sits in try/except ImportError.)

I used GitHub Copilot (Claude Opus 5.5 model) to trace this, build and time the prototype, and draft this issue. The measurements were run on my machine.

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

主要言語
Python
スター
77.9k
フォーク
37.1k
平均マージ
17時間 43分
マージ済み PR(30日)
675

環境構築

Codespaces で開く

このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

python/cpython のほかの issue

python/cpython の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。