Skip to content

Commit ad7eaed

Browse files
authored
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
1 parent a3a01a2 commit ad7eaed

File tree

1 file changed

+82
-40
lines changed

1 file changed

+82
-40
lines changed

Lib/test/pythoninfo.py

Lines changed: 82 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,17 @@ def add(self, key, value):
2323
if key in self.info:
2424
raise ValueError("duplicate key: %r" % key)
2525

26-
if isinstance(value, str):
26+
if value is None:
27+
return
28+
29+
if not isinstance(value, int):
30+
if not isinstance(value, str):
31+
# convert other objects like sys.flags to string
32+
value = str(value)
33+
2734
value = value.strip()
2835
if not value:
2936
return
30-
elif value is None:
31-
return
32-
elif not isinstance(value, int):
33-
raise TypeError("value type must be str, int or None")
3437

3538
self.info[key] = value
3639

@@ -52,25 +55,47 @@ def copy_attributes(info_add, obj, name_fmt, attributes, *, formatter=None):
5255
info_add(name, value)
5356

5457

55-
def collect_sys(info_add):
56-
def format_attr(attr, value):
57-
if attr == 'flags':
58-
# convert sys.flags tuple to string
59-
return str(value)
60-
else:
61-
return value
58+
def call_func(info_add, name, mod, func_name, *, formatter=None):
59+
try:
60+
func = getattr(mod, func_name)
61+
except AttributeError:
62+
return
63+
value = func()
64+
if formatter is not None:
65+
value = formatter(value)
66+
info_add(name, value)
6267

68+
69+
def collect_sys(info_add):
6370
attributes = (
6471
'_framework',
72+
'abiflags',
73+
'api_version',
74+
'builtin_module_names',
6575
'byteorder',
76+
'dont_write_bytecode',
6677
'executable',
6778
'flags',
79+
'float_info',
80+
'float_repr_style',
81+
'hash_info',
82+
'hexversion',
83+
'implementation',
84+
'int_info',
6885
'maxsize',
6986
'maxunicode',
87+
'path',
88+
'platform',
89+
'prefix',
90+
'thread_info',
7091
'version',
92+
'version_info',
93+
'winver',
7194
)
72-
copy_attributes(info_add, sys, 'sys.%s', attributes,
73-
formatter=format_attr)
95+
copy_attributes(info_add, sys, 'sys.%s', attributes)
96+
97+
call_func(info_add, 'sys.androidapilevel', sys, 'getandroidapilevel')
98+
call_func(info_add, 'sys.windowsversion', sys, 'getwindowsversion')
7499

75100
encoding = sys.getfilesystemencoding()
76101
if hasattr(sys, 'getfilesystemencodeerrors'):
@@ -89,15 +114,6 @@ def format_attr(attr, value):
89114
encoding = '%s/%s' % (encoding, errors)
90115
info_add('sys.%s.encoding' % name, encoding)
91116

92-
if hasattr(sys, 'hash_info'):
93-
alg = sys.hash_info.algorithm
94-
bits = 64 if sys.maxsize > 2**32 else 32
95-
alg = '%s (%s bits)' % (alg, bits)
96-
info_add('sys.hash_info', alg)
97-
98-
if hasattr(sys, 'getandroidapilevel'):
99-
info_add('sys.androidapilevel', sys.getandroidapilevel())
100-
101117

102118
def collect_platform(info_add):
103119
import platform
@@ -121,20 +137,27 @@ def collect_locale(info_add):
121137
def collect_os(info_add):
122138
import os
123139

124-
if hasattr(os, 'getrandom'):
125-
# PEP 524: Check is system urandom is initialized
126-
try:
127-
os.getrandom(1, os.GRND_NONBLOCK)
128-
state = 'ready (initialized)'
129-
except BlockingIOError as exc:
130-
state = 'not seeded yet (%s)' % exc
131-
info_add('os.getrandom', state)
140+
def format_attr(attr, value):
141+
if attr in ('supports_follow_symlinks', 'supports_fd',
142+
'supports_effective_ids'):
143+
return str(sorted(func.__name__ for func in value))
144+
else:
145+
return value
146+
147+
attributes = (
148+
'name',
149+
'supports_bytes_environ',
150+
'supports_effective_ids',
151+
'supports_fd',
152+
'supports_follow_symlinks',
153+
)
154+
copy_attributes(info_add, os, 'os.%s', attributes, formatter=format_attr)
132155

133156
info_add("os.cwd", os.getcwd())
134157

135-
if hasattr(os, 'getuid'):
136-
info_add("os.uid", os.getuid())
137-
info_add("os.gid", os.getgid())
158+
call_func(info_add, 'os.uid', os, 'getuid')
159+
call_func(info_add, 'os.gid', os, 'getgid')
160+
call_func(info_add, 'os.uname', os, 'uname')
138161

139162
if hasattr(os, 'getgroups'):
140163
groups = os.getgroups()
@@ -157,9 +180,7 @@ def collect_os(info_add):
157180
if cpu_count:
158181
info_add('os.cpu_count', cpu_count)
159182

160-
if hasattr(os, 'getloadavg'):
161-
load = os.getloadavg()
162-
info_add('os.loadavg', str(load))
183+
call_func(info_add, 'os.loadavg', os, 'getloadavg')
163184

164185
# Get environment variables: filter to list
165186
# to not leak sensitive information
@@ -194,6 +215,20 @@ def collect_os(info_add):
194215
or (uname.startswith("VS") and uname.endswith("COMNTOOLS"))):
195216
info_add('os.environ[%s]' % name, value)
196217

218+
if hasattr(os, 'umask'):
219+
mask = os.umask(0)
220+
os.umask(mask)
221+
info_add("os.umask", '%03o' % mask)
222+
223+
if hasattr(os, 'getrandom'):
224+
# PEP 524: Check if system urandom is initialized
225+
try:
226+
os.getrandom(1, os.GRND_NONBLOCK)
227+
state = 'ready (initialized)'
228+
except BlockingIOError as exc:
229+
state = 'not seeded yet (%s)' % exc
230+
info_add('os.getrandom', state)
231+
197232

198233
def collect_readline(info_add):
199234
try:
@@ -255,12 +290,20 @@ def collect_tkinter(info_add):
255290
def collect_time(info_add):
256291
import time
257292

293+
attributes = (
294+
'altzone',
295+
'daylight',
296+
'timezone',
297+
'tzname',
298+
)
299+
copy_attributes(info_add, time, 'time.%s', attributes)
300+
258301
if not hasattr(time, 'get_clock_info'):
259302
return
260303

261304
for clock in ('time', 'perf_counter'):
262305
tinfo = time.get_clock_info(clock)
263-
info_add('time.%s' % clock, str(tinfo))
306+
info_add('time.%s' % clock, tinfo)
264307

265308

266309
def collect_sysconfig(info_add):
@@ -305,8 +348,7 @@ def format_attr(attr, value):
305348
if attr.startswith('OP_'):
306349
return '%#8x' % value
307350
else:
308-
# Convert OPENSSL_VERSION_INFO tuple to str
309-
return str(value)
351+
return value
310352

311353
attributes = (
312354
'OPENSSL_VERSION',

0 commit comments

Comments
 (0)