mirror of
https://github.com/python/cpython.git
synced 2025-09-03 15:31:08 +00:00
bpo-30871: pythoninfo: more sys, os, time data (#3130)
* bpo-30871: pythoninfo: more sys, os, time data PythonInfo now converts types other than intger to string by default. * fix typo
This commit is contained in:
parent
a3a01a2fce
commit
ad7eaed543
1 changed files with 82 additions and 40 deletions
|
@ -23,14 +23,17 @@ class PythonInfo:
|
||||||
if key in self.info:
|
if key in self.info:
|
||||||
raise ValueError("duplicate key: %r" % key)
|
raise ValueError("duplicate key: %r" % key)
|
||||||
|
|
||||||
if isinstance(value, str):
|
if value is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not isinstance(value, int):
|
||||||
|
if not isinstance(value, str):
|
||||||
|
# convert other objects like sys.flags to string
|
||||||
|
value = str(value)
|
||||||
|
|
||||||
value = value.strip()
|
value = value.strip()
|
||||||
if not value:
|
if not value:
|
||||||
return
|
return
|
||||||
elif value is None:
|
|
||||||
return
|
|
||||||
elif not isinstance(value, int):
|
|
||||||
raise TypeError("value type must be str, int or None")
|
|
||||||
|
|
||||||
self.info[key] = value
|
self.info[key] = value
|
||||||
|
|
||||||
|
@ -52,25 +55,47 @@ def copy_attributes(info_add, obj, name_fmt, attributes, *, formatter=None):
|
||||||
info_add(name, value)
|
info_add(name, value)
|
||||||
|
|
||||||
|
|
||||||
def collect_sys(info_add):
|
def call_func(info_add, name, mod, func_name, *, formatter=None):
|
||||||
def format_attr(attr, value):
|
try:
|
||||||
if attr == 'flags':
|
func = getattr(mod, func_name)
|
||||||
# convert sys.flags tuple to string
|
except AttributeError:
|
||||||
return str(value)
|
return
|
||||||
else:
|
value = func()
|
||||||
return value
|
if formatter is not None:
|
||||||
|
value = formatter(value)
|
||||||
|
info_add(name, value)
|
||||||
|
|
||||||
|
|
||||||
|
def collect_sys(info_add):
|
||||||
attributes = (
|
attributes = (
|
||||||
'_framework',
|
'_framework',
|
||||||
|
'abiflags',
|
||||||
|
'api_version',
|
||||||
|
'builtin_module_names',
|
||||||
'byteorder',
|
'byteorder',
|
||||||
|
'dont_write_bytecode',
|
||||||
'executable',
|
'executable',
|
||||||
'flags',
|
'flags',
|
||||||
|
'float_info',
|
||||||
|
'float_repr_style',
|
||||||
|
'hash_info',
|
||||||
|
'hexversion',
|
||||||
|
'implementation',
|
||||||
|
'int_info',
|
||||||
'maxsize',
|
'maxsize',
|
||||||
'maxunicode',
|
'maxunicode',
|
||||||
|
'path',
|
||||||
|
'platform',
|
||||||
|
'prefix',
|
||||||
|
'thread_info',
|
||||||
'version',
|
'version',
|
||||||
|
'version_info',
|
||||||
|
'winver',
|
||||||
)
|
)
|
||||||
copy_attributes(info_add, sys, 'sys.%s', attributes,
|
copy_attributes(info_add, sys, 'sys.%s', attributes)
|
||||||
formatter=format_attr)
|
|
||||||
|
call_func(info_add, 'sys.androidapilevel', sys, 'getandroidapilevel')
|
||||||
|
call_func(info_add, 'sys.windowsversion', sys, 'getwindowsversion')
|
||||||
|
|
||||||
encoding = sys.getfilesystemencoding()
|
encoding = sys.getfilesystemencoding()
|
||||||
if hasattr(sys, 'getfilesystemencodeerrors'):
|
if hasattr(sys, 'getfilesystemencodeerrors'):
|
||||||
|
@ -89,15 +114,6 @@ def collect_sys(info_add):
|
||||||
encoding = '%s/%s' % (encoding, errors)
|
encoding = '%s/%s' % (encoding, errors)
|
||||||
info_add('sys.%s.encoding' % name, encoding)
|
info_add('sys.%s.encoding' % name, encoding)
|
||||||
|
|
||||||
if hasattr(sys, 'hash_info'):
|
|
||||||
alg = sys.hash_info.algorithm
|
|
||||||
bits = 64 if sys.maxsize > 2**32 else 32
|
|
||||||
alg = '%s (%s bits)' % (alg, bits)
|
|
||||||
info_add('sys.hash_info', alg)
|
|
||||||
|
|
||||||
if hasattr(sys, 'getandroidapilevel'):
|
|
||||||
info_add('sys.androidapilevel', sys.getandroidapilevel())
|
|
||||||
|
|
||||||
|
|
||||||
def collect_platform(info_add):
|
def collect_platform(info_add):
|
||||||
import platform
|
import platform
|
||||||
|
@ -121,20 +137,27 @@ def collect_locale(info_add):
|
||||||
def collect_os(info_add):
|
def collect_os(info_add):
|
||||||
import os
|
import os
|
||||||
|
|
||||||
if hasattr(os, 'getrandom'):
|
def format_attr(attr, value):
|
||||||
# PEP 524: Check is system urandom is initialized
|
if attr in ('supports_follow_symlinks', 'supports_fd',
|
||||||
try:
|
'supports_effective_ids'):
|
||||||
os.getrandom(1, os.GRND_NONBLOCK)
|
return str(sorted(func.__name__ for func in value))
|
||||||
state = 'ready (initialized)'
|
else:
|
||||||
except BlockingIOError as exc:
|
return value
|
||||||
state = 'not seeded yet (%s)' % exc
|
|
||||||
info_add('os.getrandom', state)
|
attributes = (
|
||||||
|
'name',
|
||||||
|
'supports_bytes_environ',
|
||||||
|
'supports_effective_ids',
|
||||||
|
'supports_fd',
|
||||||
|
'supports_follow_symlinks',
|
||||||
|
)
|
||||||
|
copy_attributes(info_add, os, 'os.%s', attributes, formatter=format_attr)
|
||||||
|
|
||||||
info_add("os.cwd", os.getcwd())
|
info_add("os.cwd", os.getcwd())
|
||||||
|
|
||||||
if hasattr(os, 'getuid'):
|
call_func(info_add, 'os.uid', os, 'getuid')
|
||||||
info_add("os.uid", os.getuid())
|
call_func(info_add, 'os.gid', os, 'getgid')
|
||||||
info_add("os.gid", os.getgid())
|
call_func(info_add, 'os.uname', os, 'uname')
|
||||||
|
|
||||||
if hasattr(os, 'getgroups'):
|
if hasattr(os, 'getgroups'):
|
||||||
groups = os.getgroups()
|
groups = os.getgroups()
|
||||||
|
@ -157,9 +180,7 @@ def collect_os(info_add):
|
||||||
if cpu_count:
|
if cpu_count:
|
||||||
info_add('os.cpu_count', cpu_count)
|
info_add('os.cpu_count', cpu_count)
|
||||||
|
|
||||||
if hasattr(os, 'getloadavg'):
|
call_func(info_add, 'os.loadavg', os, 'getloadavg')
|
||||||
load = os.getloadavg()
|
|
||||||
info_add('os.loadavg', str(load))
|
|
||||||
|
|
||||||
# Get environment variables: filter to list
|
# Get environment variables: filter to list
|
||||||
# to not leak sensitive information
|
# to not leak sensitive information
|
||||||
|
@ -194,6 +215,20 @@ def collect_os(info_add):
|
||||||
or (uname.startswith("VS") and uname.endswith("COMNTOOLS"))):
|
or (uname.startswith("VS") and uname.endswith("COMNTOOLS"))):
|
||||||
info_add('os.environ[%s]' % name, value)
|
info_add('os.environ[%s]' % name, value)
|
||||||
|
|
||||||
|
if hasattr(os, 'umask'):
|
||||||
|
mask = os.umask(0)
|
||||||
|
os.umask(mask)
|
||||||
|
info_add("os.umask", '%03o' % mask)
|
||||||
|
|
||||||
|
if hasattr(os, 'getrandom'):
|
||||||
|
# PEP 524: Check if system urandom is initialized
|
||||||
|
try:
|
||||||
|
os.getrandom(1, os.GRND_NONBLOCK)
|
||||||
|
state = 'ready (initialized)'
|
||||||
|
except BlockingIOError as exc:
|
||||||
|
state = 'not seeded yet (%s)' % exc
|
||||||
|
info_add('os.getrandom', state)
|
||||||
|
|
||||||
|
|
||||||
def collect_readline(info_add):
|
def collect_readline(info_add):
|
||||||
try:
|
try:
|
||||||
|
@ -255,12 +290,20 @@ def collect_tkinter(info_add):
|
||||||
def collect_time(info_add):
|
def collect_time(info_add):
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
attributes = (
|
||||||
|
'altzone',
|
||||||
|
'daylight',
|
||||||
|
'timezone',
|
||||||
|
'tzname',
|
||||||
|
)
|
||||||
|
copy_attributes(info_add, time, 'time.%s', attributes)
|
||||||
|
|
||||||
if not hasattr(time, 'get_clock_info'):
|
if not hasattr(time, 'get_clock_info'):
|
||||||
return
|
return
|
||||||
|
|
||||||
for clock in ('time', 'perf_counter'):
|
for clock in ('time', 'perf_counter'):
|
||||||
tinfo = time.get_clock_info(clock)
|
tinfo = time.get_clock_info(clock)
|
||||||
info_add('time.%s' % clock, str(tinfo))
|
info_add('time.%s' % clock, tinfo)
|
||||||
|
|
||||||
|
|
||||||
def collect_sysconfig(info_add):
|
def collect_sysconfig(info_add):
|
||||||
|
@ -305,8 +348,7 @@ def collect_ssl(info_add):
|
||||||
if attr.startswith('OP_'):
|
if attr.startswith('OP_'):
|
||||||
return '%#8x' % value
|
return '%#8x' % value
|
||||||
else:
|
else:
|
||||||
# Convert OPENSSL_VERSION_INFO tuple to str
|
return value
|
||||||
return str(value)
|
|
||||||
|
|
||||||
attributes = (
|
attributes = (
|
||||||
'OPENSSL_VERSION',
|
'OPENSSL_VERSION',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue