Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 75 additions & 26 deletions Lib/test/pythoninfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import warnings


MS_WINDOWS = (sys.platform == "win32")


def normalize_text(text):
if text is None:
return None
Expand Down Expand Up @@ -894,8 +897,30 @@ def collect_subprocess(info_add):
copy_attributes(info_add, subprocess, 'subprocess.%s', ('_USE_POSIX_SPAWN',))


def winreg_query(path):
try:
import winreg
except ImportError:
return None

key, path = path.split('\\', 1)
sub_key, value = path.rsplit('\\', 1)
if key == "HKEY_LOCAL_MACHINE":
key = winreg.HKEY_LOCAL_MACHINE
else:
raise ValueError(f"unknown key {key!r}")

try:
access = winreg.KEY_READ | winreg.KEY_WOW64_64KEY
with winreg.OpenKey(key, sub_key, access=access) as key_handle:
result, _ = winreg.QueryValueEx(key_handle, value)
return result
except OSError:
return None


def collect_windows(info_add):
if sys.platform != "win32":
if not MS_WINDOWS:
# Code specific to Windows
return

Expand Down Expand Up @@ -980,19 +1005,10 @@ def collect_windows(info_add):
info_add('windows.ver', line)

# windows.developer_mode: get AllowDevelopmentWithoutDevLicense registry
import winreg
try:
key = winreg.OpenKey(
winreg.HKEY_LOCAL_MACHINE,
r"SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock")
subkey = "AllowDevelopmentWithoutDevLicense"
try:
value, value_type = winreg.QueryValueEx(key, subkey)
finally:
winreg.CloseKey(key)
except OSError:
pass
else:
value = winreg_query(r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows"
r"\CurrentVersion\AppModelUnlock"
r"\AllowDevelopmentWithoutDevLicense")
if value is not None:
info_add('windows.developer_mode', "enabled" if value else "disabled")


Expand Down Expand Up @@ -1025,38 +1041,71 @@ def collect_libregrtest_utils(info_add):
info_add('libregrtests.build_info', ' '.join(utils.get_build_info()))


def linux_get_uptime():
# Use CLOCK_BOOTTIME if available
def uptime_boottime():
# Use CLOCK_BOOTTIME
import time
try:
return time.clock_gettime(time.CLOCK_BOOTTIME)
except (AttributeError, OSError):
pass
return None


# Otherwise, parse the first member of /proc/uptime
uptime = read_first_line("/proc/uptime")
if not uptime:
def uptime_linux():
# Parse the first member of /proc/uptime
line = read_first_line("/proc/uptime")
if not line:
return
try:
parts = uptime.split()
parts = line.split()
if not parts:
return
return float(parts[0])
except ValueError:
return


def uptime_windows():
try:
import _winapi
except ImportError:
return None
else:
return _winapi.GetTickCount64() / 1000.


def get_uptime():
for func in (uptime_boottime, uptime_linux, uptime_windows):
uptime = func()
if uptime is not None:
return uptime
return None


def get_machine_id():
if MS_WINDOWS:
machine_guid = winreg_query(r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft"
r"\Cryptography\MachineGuid")
if machine_guid:
return machine_guid

machine_id = read_first_line("/etc/machine-id")
if machine_id:
return machine_id

return None


def collect_linux(info_add):
boot_id = read_first_line("/proc/sys/kernel/random/boot_id")
if boot_id:
info_add('linux.boot_id', boot_id)
info_add('system.boot_id', boot_id)

# https://www.freedesktop.org/software/systemd/man/latest/machine-id.html
machine_id = read_first_line("/etc/machine-id")
machine_id = get_machine_id()
if machine_id:
info_add('linux.machine_id', machine_id)
info_add('system.machine_id', machine_id)

uptime = linux_get_uptime()
uptime = get_uptime()
if uptime is not None:
# truncate microseconds
uptime = int(uptime)
Expand All @@ -1065,7 +1114,7 @@ def collect_linux(info_add):
uptime = str(datetime.timedelta(seconds=uptime))
except ImportError:
uptime = f'{uptime} sec'
info_add('linux.uptime', uptime)
info_add('system.uptime', uptime)


def collect_info(info):
Expand Down
16 changes: 16 additions & 0 deletions Modules/_winapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2960,6 +2960,21 @@ _winapi_CopyFile2_impl(PyObject *module, LPCWSTR existing_file_name,
}


/*[clinic input]
_winapi.GetTickCount64

Number of milliseconds that have elapsed since the system was started.
[clinic start generated code]*/

static PyObject *
_winapi_GetTickCount64_impl(PyObject *module)
/*[clinic end generated code: output=cb33c0568f0b3ed1 input=77ed6539ac7d6590]*/
{
ULONGLONG ticks = GetTickCount64();
return PyLong_FromUnsignedLongLong(ticks);
}


static PyMethodDef winapi_functions[] = {
_WINAPI_CLOSEHANDLE_METHODDEF
_WINAPI_CONNECTNAMEDPIPE_METHODDEF
Expand Down Expand Up @@ -3006,6 +3021,7 @@ static PyMethodDef winapi_functions[] = {
_WINAPI__MIMETYPES_READ_WINDOWS_REGISTRY_METHODDEF
_WINAPI_NEEDCURRENTDIRECTORYFOREXEPATH_METHODDEF
_WINAPI_COPYFILE2_METHODDEF
_WINAPI_GETTICKCOUNT64_METHODDEF
{NULL, NULL}
};

Expand Down
20 changes: 19 additions & 1 deletion Modules/clinic/_winapi.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading