From 4f37105277e9c3d86c44ad385ad0f5e9b7768a85 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 14 Dec 2017 15:41:06 +0100 Subject: [PATCH] pythoninfo: sync with master (#4844) --- Lib/test/pythoninfo.py | 105 ++++++++++++++++++++++++++++++++--------- 1 file changed, 84 insertions(+), 21 deletions(-) diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index c238ef7b75..9ca26c9970 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -1,5 +1,5 @@ """ -Collect various informations about Python to help debugging test failures. +Collect various information about Python to help debugging test failures. """ from __future__ import print_function import errno @@ -40,7 +40,7 @@ class PythonInfo: def get_infos(self): """ - Get informations as a key:value dictionary where values are strings. + Get information as a key:value dictionary where values are strings. """ return {key: str(value) for key, value in self.info.items()} @@ -56,6 +56,14 @@ def copy_attributes(info_add, obj, name_fmt, attributes, *, formatter=None): info_add(name, value) +def copy_attr(info_add, name, mod, attr_name): + try: + value = getattr(mod, attr_name) + except AttributeError: + return + info_add(name, value) + + def call_func(info_add, name, mod, func_name, *, formatter=None): try: func = getattr(mod, func_name) @@ -143,6 +151,11 @@ def collect_locale(info_add): info_add('locale.encoding', locale.getpreferredencoding(False)) +def collect_builtins(info_add): + info_add('builtins.float.float_format', float.__getformat__("float")) + info_add('builtins.float.double_format', float.__getformat__("double")) + + def collect_os(info_add): import os @@ -162,17 +175,16 @@ def collect_os(info_add): ) copy_attributes(info_add, os, 'os.%s', attributes, formatter=format_attr) - info_add("os.cwd", os.getcwd()) + call_func(info_add, 'os.cwd', os, 'getcwd') call_func(info_add, 'os.uid', os, 'getuid') call_func(info_add, 'os.gid', os, 'getgid') call_func(info_add, 'os.uname', os, 'uname') - if hasattr(os, 'getgroups'): - groups = os.getgroups() - groups = map(str, groups) - groups = ', '.join(groups) - info_add("os.groups", groups) + def format_groups(groups): + return ', '.join(map(str, groups)) + + call_func(info_add, 'os.groups', os, 'getgroups', formatter=format_groups) if hasattr(os, 'getlogin'): try: @@ -184,11 +196,7 @@ def collect_os(info_add): else: info_add("os.login", login) - if hasattr(os, 'cpu_count'): - cpu_count = os.cpu_count() - if cpu_count: - info_add('os.cpu_count', cpu_count) - + call_func(info_add, 'os.cpu_count', os, 'cpu_count') call_func(info_add, 'os.loadavg', os, 'getloadavg') # Get environment variables: filter to list @@ -219,7 +227,9 @@ def collect_os(info_add): ) for name, value in os.environ.items(): uname = name.upper() - if (uname in ENV_VARS or uname.startswith(("PYTHON", "LC_")) + if (uname in ENV_VARS + # Copy PYTHON* and LC_* variables + or uname.startswith(("PYTHON", "LC_")) # Visual Studio: VS140COMNTOOLS or (uname.startswith("VS") and uname.endswith("COMNTOOLS"))): info_add('os.environ[%s]' % name, value) @@ -313,12 +323,10 @@ def collect_time(info_add): ) copy_attributes(info_add, time, 'time.%s', attributes) - if not hasattr(time, 'get_clock_info'): - return - - for clock in ('time', 'perf_counter'): - tinfo = time.get_clock_info(clock) - info_add('time.%s' % clock, tinfo) + if hasattr(time, 'get_clock_info'): + for clock in ('time', 'perf_counter'): + tinfo = time.get_clock_info(clock) + info_add('time.%s' % clock, tinfo) def collect_sysconfig(info_add): @@ -331,7 +339,6 @@ def collect_sysconfig(info_add): 'CCSHARED', 'CFLAGS', 'CFLAGSFORSHARED', - 'PY_LDFLAGS', 'CONFIG_ARGS', 'HOST_GNU_TYPE', 'MACHDEP', @@ -339,6 +346,7 @@ def collect_sysconfig(info_add): 'OPT', 'PY_CFLAGS', 'PY_CFLAGS_NODIST', + 'PY_LDFLAGS', 'Py_DEBUG', 'Py_ENABLE_SHARED', 'SHELL', @@ -422,6 +430,54 @@ def collect_decimal(info_add): copy_attributes(info_add, _decimal, '_decimal.%s', attributes) +def collect_testcapi(info_add): + try: + import _testcapi + except ImportError: + return + + call_func(info_add, 'pymem.allocator', _testcapi, 'pymem_getallocatorsname') + copy_attr(info_add, 'pymem.with_pymalloc', _testcapi, 'WITH_PYMALLOC') + + +def collect_resource(info_add): + try: + import resource + except ImportError: + return + + limits = [attr for attr in dir(resource) if attr.startswith('RLIMIT_')] + for name in limits: + key = getattr(resource, name) + value = resource.getrlimit(key) + info_add('resource.%s' % name, value) + + +def collect_test_socket(info_add): + try: + from test import test_socket + except ImportError: + return + + # all check attributes like HAVE_SOCKET_CAN + attributes = [name for name in dir(test_socket) + if name.startswith('HAVE_')] + copy_attributes(info_add, test_socket, 'test_socket.%s', attributes) + + +def collect_test_support(info_add): + try: + from test import support + except ImportError: + return + + attributes = ('IPV6_ENABLED',) + copy_attributes(info_add, support, 'test_support.%s', attributes) + + call_func(info_add, 'test_support._is_gui_available', support, '_is_gui_available') + call_func(info_add, 'test_support.python_is_optimized', support, 'python_is_optimized') + + def collect_info(info): error = False info_add = info.add @@ -430,6 +486,7 @@ def collect_info(info): # collect_os() should be the first, to check the getrandom() status collect_os, + collect_builtins, collect_gdb, collect_locale, collect_platform, @@ -444,6 +501,12 @@ def collect_info(info): collect_zlib, collect_expat, collect_decimal, + collect_testcapi, + collect_resource, + + # Collecting from tests should be last as they have side effects. + collect_test_socket, + collect_test_support, ): try: collect_func(info_add) -- 2.40.0