[Python-checkins] pythoninfo: sync with master (#4843)

Victor Stinner webhook-mailer at python.org
Wed Dec 13 17:23:44 EST 2017


https://github.com/python/cpython/commit/2316c686400841fe1131583820d5b14417a0e089
commit: 2316c686400841fe1131583820d5b14417a0e089
branch: 2.7
author: Victor Stinner <victor.stinner at gmail.com>
committer: GitHub <noreply at github.com>
date: 2017-12-13T23:23:40+01:00
summary:

pythoninfo: sync with master (#4843)

files:
M Lib/test/pythoninfo.py
M Lib/test/test_socket.py

diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py
index 8b029330a2e..4ce06e00eb9 100644
--- a/Lib/test/pythoninfo.py
+++ b/Lib/test/pythoninfo.py
@@ -1,7 +1,8 @@
 """
-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
 import re
 import sys
 import traceback
@@ -26,8 +27,8 @@ def add(self, key, value):
         if value is None:
             return
 
-        if not isinstance(value, (int, long)):
-            if not isinstance(value, basestring):
+        if not isinstance(value, int):
+            if not isinstance(value, str):
                 # convert other objects like sys.flags to string
                 value = str(value)
 
@@ -39,7 +40,7 @@ def add(self, key, value):
 
     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()}
 
@@ -55,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)
@@ -68,6 +77,8 @@ def call_func(info_add, name, mod, func_name, formatter=None):
 
 def collect_sys(info_add):
     attributes = (
+        '_framework',
+        'abiflags',
         'api_version',
         'builtin_module_names',
         'byteorder',
@@ -76,20 +87,28 @@ def collect_sys(info_add):
         'flags',
         'float_info',
         'float_repr_style',
+        'hash_info',
         'hexversion',
-        'maxint',
+        'implementation',
+        'int_info',
         'maxsize',
         'maxunicode',
         'path',
         'platform',
         'prefix',
+        'thread_info',
         'version',
         'version_info',
         'winver',
     )
     copy_attributes(info_add, sys, 'sys.%s', attributes)
 
+    call_func(info_add, 'sys.androidapilevel', sys, 'getandroidapilevel')
+    call_func(info_add, 'sys.windowsversion', sys, 'getwindowsversion')
+
     encoding = sys.getfilesystemencoding()
+    if hasattr(sys, 'getfilesystemencodeerrors'):
+        encoding = '%s/%s' % (encoding, sys.getfilesystemencodeerrors())
     info_add('sys.filesystem_encoding', encoding)
 
     for name in ('stdin', 'stdout', 'stderr'):
@@ -129,26 +148,43 @@ def collect_platform(info_add):
 def collect_locale(info_add):
     import locale
 
-    info_add('locale.encoding', locale.getpreferredencoding(True))
+    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
 
-    attributes = ('name',)
-    copy_attributes(info_add, os, 'os.%s', attributes)
+    def format_attr(attr, value):
+        if attr in ('supports_follow_symlinks', 'supports_fd',
+                    'supports_effective_ids'):
+            return str(sorted(func.__name__ for func in value))
+        else:
+            return value
 
-    info_add("os.cwd", os.getcwd())
+    attributes = (
+        'name',
+        'supports_bytes_environ',
+        'supports_effective_ids',
+        'supports_fd',
+        'supports_follow_symlinks',
+    )
+    copy_attributes(info_add, os, 'os.%s', attributes, formatter=format_attr)
+
+    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:
@@ -160,6 +196,7 @@ def collect_os(info_add):
         else:
             info_add("os.login", login)
 
+    call_func(info_add, 'os.cpu_count', os, 'cpu_count')
     call_func(info_add, 'os.loadavg', os, 'getloadavg')
 
     # Get environment variables: filter to list
@@ -190,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)
@@ -200,13 +239,20 @@ def collect_os(info_add):
         os.umask(mask)
         info_add("os.umask", '%03o' % mask)
 
-    try:
-        cpu_count = os.sysconf('SC_NPROCESSORS_ONLN')
-    except (AttributeError, ValueError):
-        pass
-    else:
-        if cpu_count:
-            info_add('os.sysconf(SC_NPROCESSORS_ONLN)', cpu_count)
+    if hasattr(os, 'getrandom'):
+        # PEP 524: Check if system urandom is initialized
+        try:
+            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)
+        except OSError as exc:
+            # Python was compiled on a more recent Linux version
+            # than the current Linux kernel: ignore OSError(ENOSYS)
+            if exc.errno != errno.ENOSYS:
+                raise
 
 
 def collect_readline(info_add):
@@ -216,7 +262,7 @@ def collect_readline(info_add):
         return
 
     def format_attr(attr, value):
-        if isinstance(value, (int, long)):
+        if isinstance(value, int):
             return "%#x" % value
         else:
             return value
@@ -224,6 +270,7 @@ def format_attr(attr, value):
     attributes = (
         "_READLINE_VERSION",
         "_READLINE_RUNTIME_VERSION",
+        "_READLINE_LIBRARY_VERSION",
     )
     copy_attributes(info_add, readline, 'readline.%s', attributes,
                     formatter=format_attr)
@@ -256,11 +303,11 @@ def collect_tkinter(info_add):
         copy_attributes(info_add, _tkinter, 'tkinter.%s', attributes)
 
     try:
-        import Tkinter
+        import tkinter
     except ImportError:
         pass
     else:
-        tcl = Tkinter.Tcl()
+        tcl = tkinter.Tcl()
         patchlevel = tcl.call('info', 'patchlevel')
         info_add('tkinter.info_patchlevel', patchlevel)
 
@@ -276,6 +323,11 @@ def collect_time(info_add):
     )
     copy_attributes(info_add, time, 'time.%s', attributes)
 
+    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):
     import sysconfig
@@ -287,7 +339,6 @@ def collect_sysconfig(info_add):
         'CCSHARED',
         'CFLAGS',
         'CFLAGSFORSHARED',
-        'PY_LDFLAGS',
         'CONFIG_ARGS',
         'HOST_GNU_TYPE',
         'MACHDEP',
@@ -295,6 +346,7 @@ def collect_sysconfig(info_add):
         'OPT',
         'PY_CFLAGS',
         'PY_CFLAGS_NODIST',
+        'PY_LDFLAGS',
         'Py_DEBUG',
         'Py_ENABLE_SHARED',
         'SHELL',
@@ -368,15 +420,62 @@ def collect_expat(info_add):
     copy_attributes(info_add, expat, 'expat.%s', attributes)
 
 
-def collect_multiprocessing(info_add):
+def collect_decimal(info_add):
+    try:
+        import _decimal
+    except ImportError:
+        return
+
+    attributes = ('__libmpdec_version__',)
+    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:
-        import multiprocessing
+        from test import test_socket
     except ImportError:
         return
 
-    cpu_count = multiprocessing.cpu_count()
-    if cpu_count:
-        info_add('multiprocessing.cpu_count', cpu_count)
+    # 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):
@@ -384,10 +483,12 @@ def collect_info(info):
     info_add = info.add
 
     for collect_func in (
-        collect_expat,
+        # collect_os() should be the first, to check the getrandom() status
+        collect_os,
+
+        collect_builtins,
         collect_gdb,
         collect_locale,
-        collect_os,
         collect_platform,
         collect_readline,
         collect_socket,
@@ -398,7 +499,14 @@ def collect_info(info):
         collect_time,
         collect_tkinter,
         collect_zlib,
-        collect_multiprocessing,
+        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)
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 1126fc2b77b..ca53899418c 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -35,7 +35,7 @@ def try_address(host, port=0, family=socket.AF_INET):
 
 HOST = test_support.HOST
 MSG = b'Michael Gilfix was here\n'
-SUPPORTS_IPV6 = socket.has_ipv6 and try_address('::1', family=socket.AF_INET6)
+SUPPORTS_IPV6 = test_support.IPV6_ENABLED
 
 try:
     import thread



More information about the Python-checkins mailing list