bpo-30871: pythoninfo: more sys, os, time data (#3130) · python/cpython@ad7eaed (original) (raw)

`@@ -23,14 +23,17 @@ def add(self, key, value):

`

23

23

`if key in self.info:

`

24

24

`raise ValueError("duplicate key: %r" % key)

`

25

25

``

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

+

27

34

`value = value.strip()

`

28

35

`if not value:

`

29

36

`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")

`

34

37

``

35

38

`self.info[key] = value

`

36

39

``

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

`

52

55

`info_add(name, value)

`

53

56

``

54

57

``

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)

`

62

67

``

``

68

+

``

69

`+

def collect_sys(info_add):

`

63

70

`attributes = (

`

64

71

`'_framework',

`

``

72

`+

'abiflags',

`

``

73

`+

'api_version',

`

``

74

`+

'builtin_module_names',

`

65

75

`'byteorder',

`

``

76

`+

'dont_write_bytecode',

`

66

77

`'executable',

`

67

78

`'flags',

`

``

79

`+

'float_info',

`

``

80

`+

'float_repr_style',

`

``

81

`+

'hash_info',

`

``

82

`+

'hexversion',

`

``

83

`+

'implementation',

`

``

84

`+

'int_info',

`

68

85

`'maxsize',

`

69

86

`'maxunicode',

`

``

87

`+

'path',

`

``

88

`+

'platform',

`

``

89

`+

'prefix',

`

``

90

`+

'thread_info',

`

70

91

`'version',

`

``

92

`+

'version_info',

`

``

93

`+

'winver',

`

71

94

` )

`

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')

`

74

99

``

75

100

`encoding = sys.getfilesystemencoding()

`

76

101

`if hasattr(sys, 'getfilesystemencodeerrors'):

`

`@@ -89,15 +114,6 @@ def format_attr(attr, value):

`

89

114

`encoding = '%s/%s' % (encoding, errors)

`

90

115

`info_add('sys.%s.encoding' % name, encoding)

`

91

116

``

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

``

-

101

117

``

102

118

`def collect_platform(info_add):

`

103

119

`import platform

`

`@@ -121,20 +137,27 @@ def collect_locale(info_add):

`

121

137

`def collect_os(info_add):

`

122

138

`import os

`

123

139

``

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)

`

132

155

``

133

156

`info_add("os.cwd", os.getcwd())

`

134

157

``

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')

`

138

161

``

139

162

`if hasattr(os, 'getgroups'):

`

140

163

`groups = os.getgroups()

`

`@@ -157,9 +180,7 @@ def collect_os(info_add):

`

157

180

`if cpu_count:

`

158

181

`info_add('os.cpu_count', cpu_count)

`

159

182

``

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')

`

163

184

``

164

185

`# Get environment variables: filter to list

`

165

186

`# to not leak sensitive information

`

`@@ -194,6 +215,20 @@ def collect_os(info_add):

`

194

215

`or (uname.startswith("VS") and uname.endswith("COMNTOOLS"))):

`

195

216

`info_add('os.environ[%s]' % name, value)

`

196

217

``

``

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

+

197

232

``

198

233

`def collect_readline(info_add):

`

199

234

`try:

`

`@@ -255,12 +290,20 @@ def collect_tkinter(info_add):

`

255

290

`def collect_time(info_add):

`

256

291

`import time

`

257

292

``

``

293

`+

attributes = (

`

``

294

`+

'altzone',

`

``

295

`+

'daylight',

`

``

296

`+

'timezone',

`

``

297

`+

'tzname',

`

``

298

`+

)

`

``

299

`+

copy_attributes(info_add, time, 'time.%s', attributes)

`

``

300

+

258

301

`if not hasattr(time, 'get_clock_info'):

`

259

302

`return

`

260

303

``

261

304

`for clock in ('time', 'perf_counter'):

`

262

305

`tinfo = time.get_clock_info(clock)

`

263

``

`-

info_add('time.%s' % clock, str(tinfo))

`

``

306

`+

info_add('time.%s' % clock, tinfo)

`

264

307

``

265

308

``

266

309

`def collect_sysconfig(info_add):

`

`@@ -305,8 +348,7 @@ def format_attr(attr, value):

`

305

348

`if attr.startswith('OP_'):

`

306

349

`return '%#8x' % value

`

307

350

`else:

`

308

``

`-

Convert OPENSSL_VERSION_INFO tuple to str

`

309

``

`-

return str(value)

`

``

351

`+

return value

`

310

352

``

311

353

`attributes = (

`

312

354

`'OPENSSL_VERSION',

`