diff --git a/projects/python3.functions.cmake b/projects/python3.functions.cmake index 0051e5d9ec029cbba002b7bf1b964bd141d5e766..498c53c4a6f4d7b39f0bbe8d9fbb0998b8ff3382 100644 --- a/projects/python3.functions.cmake +++ b/projects/python3.functions.cmake @@ -9,57 +9,120 @@ function (superbuild_python_write_reqs path) endforeach () endfunction () -function (superbuild_install_superbuild_python3) - if (USE_SYSTEM_python3) - return () - endif() - - set(options) - set(values - DESTINATION_SUBDIR - BUNDLE - LIBSUFFIX) - set(multivalues - MODULES) - cmake_parse_arguments(_install_superbuild_python "${options}" "${values}" "${multivalues}" ${ARGN}) - +function (_superbuild_install_superbuild_python3_module_list var) set(modules __future__ + _abc + _ast + _asyncio + _bisect + _blake2 _bootlocale + _bz2 + _codecs + _codecs_cn + _codecs_hk + _codecs_iso2022 + _codecs_jp + _codecs_kr + _codecs_tw + _collections _collections_abc _compat_pickle _compression + _contextvars + _crypt + _csv + _ctypes + _datetime + _dbm + _decimal _dummy_thread + _elementtree + _frozen_importlib + _frozen_importlib_external + _functools + _gdbm + _hashlib + _heapq + _imp + _io + _json + _locale + _lsprof _lzma _markupbase + _md5 + _msi + _multibytecodec + _multiprocessing + _opcode + _operator _osx_support + _overlapped + _pickle + _posixshmem + _posixsubprocess _py_abc + _pydatetime _pydecimal _pyio + _pylong + _queue + _random + _scproxy + _sha1 + _sha2 + _sha3 + _signal _sitebuiltins + _socket + _sqlite3 + _sre + _stat + _statistics + _string _strptime - _sysconfigdata__linux_x86_64-linux-gnu + _struct + _symtable _sysconfigdata__darwin_darwin + _sysconfigdata__linux_x86_64-linux-gnu + _thread _threading_local + _tokenize + _tracemalloc + _typing + _uuid + _warnings + _weakref _weakrefset + _winapi + _wmi + _zoneinfo abc aifc antigravity argparse + array ast asynchat asyncio asyncore + atexit + audioop base64 bdb + binascii binhex bisect + builtins bz2 cProfile calendar cgi cgitb chunk + cmath cmd code codecs @@ -91,6 +154,9 @@ function (superbuild_install_superbuild_python3) encodings ensurepip enum + errno + faulthandler + fcntl filecmp fileinput fnmatch @@ -98,11 +164,14 @@ function (superbuild_install_superbuild_python3) fractions ftplib functools + gc genericpath getopt getpass gettext glob + graphlib + grp gzip hashlib heapq @@ -117,6 +186,7 @@ function (superbuild_install_superbuild_python3) inspect io ipaddress + itertools json keyword lib2to3 @@ -127,11 +197,18 @@ function (superbuild_install_superbuild_python3) macpath mailbox mailcap + marshal + math mimetypes + mmap modulefinder + msilib + msvcrt multiprocessing netrc + nis nntplib + nt ntpath nturl2path numbers @@ -139,6 +216,7 @@ function (superbuild_install_superbuild_python3) operator optparse os + ossaudiodev pathlib pdb pickle @@ -148,24 +226,30 @@ function (superbuild_install_superbuild_python3) platform plistlib poplib + posix posixpath pprint profile pstats pty + pwd py_compile pyclbr pydoc pydoc_data + pyexpat queue quopri random re + readline reprlib + resource rlcompleter runpy sched secrets + select selectors shelve shlex @@ -177,6 +261,7 @@ function (superbuild_install_superbuild_python3) sndhdr socket socketserver + spwd sqlite3 sre_compile sre_constants @@ -191,19 +276,24 @@ function (superbuild_install_superbuild_python3) sunau symbol symtable + sys sysconfig + syslog tabnanny tarfile telnetlib tempfile + termios test textwrap this threading + time timeit tkinter token tokenize + tomllib trace traceback tracemalloc @@ -212,6 +302,7 @@ function (superbuild_install_superbuild_python3) turtledemo types typing + unicodedata unittest urllib uu @@ -221,12 +312,16 @@ function (superbuild_install_superbuild_python3) wave weakref webbrowser + winreg + winsound wsgiref xdrlib xml xmlrpc zipapp zipfile + zipimport + zlib zoneinfo ) @@ -235,6 +330,25 @@ function (superbuild_install_superbuild_python3) _ssl) endif () + set("${var}" "${modules}" PARENT_SCOPE) +endfunction () + +function (superbuild_install_superbuild_python3) + if (USE_SYSTEM_python3) + return () + endif() + + set(options) + set(values + DESTINATION_SUBDIR + BUNDLE + LIBSUFFIX) + set(multivalues + MODULES) + cmake_parse_arguments(_install_superbuild_python "${options}" "${values}" "${multivalues}" ${ARGN}) + + _superbuild_install_superbuild_python3_module_list(modules) + if (WIN32) superbuild_windows_install_python( MODULE_DESTINATION "/" diff --git a/selftest/tests/CMakeLists.txt b/selftest/tests/CMakeLists.txt index 37c456f89e9807817914d15fc4356ae2f7094de4..48339249cb15354854c7e2188cc8f5db51b941bb 100644 --- a/selftest/tests/CMakeLists.txt +++ b/selftest/tests/CMakeLists.txt @@ -45,6 +45,19 @@ if (UNIX AND NOT APPLE AND NOT USE_SYSTEM_python3) ) endif () +if (TARGET "python3" AND + NOT USE_SYSTEM_python3 AND + python3_SOURCE_SELECTION VERSION_GREATER_EQUAL "3.10") + add_test( + NAME python3-packaged-modules-list + COMMAND + "${CMAKE_COMMAND}" + "-Dopenssl_enabled=${openssl_enabled}" + "-Dsuperbuild_python_executable=${superbuild_python_executable}" + "-Dsuperbuild_python_version=${superbuild_python_version}" + -P "${CMAKE_CURRENT_SOURCE_DIR}/python-module-list.cmake") +endif () + function (add_license_test package) if (NOT TARGET "${package}") return () diff --git a/selftest/tests/python-builtin-modules.py b/selftest/tests/python-builtin-modules.py new file mode 100755 index 0000000000000000000000000000000000000000..22f62396d938afdd8278abb72153d90824e03617 --- /dev/null +++ b/selftest/tests/python-builtin-modules.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python3 +import sys +import importlib + +missing = set() +working = set() +known_broken = set([ + '_curses', # missing dep + '_curses_panel', # missing dep + '_gdbm', # databases; missing dep + '_hashlib', # missing dep + '_ssl', # tested elsewhere + '_tkinter', # missing dep + 'curses', # missing dep + 'nis', # Solaris + 'readline', # missing dep + 'ssl', # tested elsewhere + 'tkinter', # missing dep + 'turtle', # missing dep +]) +if sys.platform != 'linux': + known_broken.update(set([ + 'ossaudiodev', + 'spwd', + ])) +if sys.platform != 'darwin': + known_broken.update(set([ + '_dbm', # databases; missing dep + '_scproxy', # urllib helper + ])) +if sys.platform == 'win32': + known_broken.update(set([ + '_crypt', + '_posixshmem', + '_posixsubprocess', + 'crypt', + 'fcntl', + 'grp', + 'idlelib', + 'posix', + 'pty', + 'pwd', + 'resource', + 'syslog', + 'termios', + 'tty', + 'turtledemo', + ])) +else: + known_broken.update(set([ + '_msi', + '_overlapped', # asyncio impl detail + '_winapi', + '_wmi', + 'msilib', + 'msvcrt', + 'nt', + 'winreg', + 'winsound', + ])) + +uninstalled = set([ + '_aix_support', # unsupported platform + '_curses', # missing dep + '_curses_panel', # missing dep + '_ssl', # tested elsewhere +]) + +for name in sys.stdlib_module_names: + # `this` prints to stdout when imported. Skip it so it doesn't confuse + # things later. + if name == 'this': + working.add(name) + continue + try: + importlib.import_module(name) + working.add(name) + except ImportError: + missing.add(name) + +missing.difference_update(known_broken) + +if missing: + print(', '.join(missing), file=sys.stderr) + sys.exit(100) + +working.difference_update(uninstalled) + +print(';'.join(working)) diff --git a/selftest/tests/python-module-list.cmake b/selftest/tests/python-module-list.cmake new file mode 100644 index 0000000000000000000000000000000000000000..9fad46aef148390f1c6571cd449da9817d508893 --- /dev/null +++ b/selftest/tests/python-module-list.cmake @@ -0,0 +1,28 @@ +list(APPEND CMAKE_MODULE_PATH + "${CMAKE_CURRENT_LIST_DIR}/../../projects") +include(python3.functions) + +_superbuild_install_superbuild_python3_module_list(installed_modules) +execute_process( + COMMAND + "${superbuild_python_executable}" + "${CMAKE_CURRENT_LIST_DIR}/python-builtin-modules.py" + OUTPUT_VARIABLE working_modules + RESULT_VARIABLE res + ERROR_VARIABLE err + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE) +if (res EQUAL 100) + message(FATAL_ERROR + "Failed to import builtin modules: ${err}") +elseif (res) + message(FATAL_ERROR + "Failed to list builtin modules: ${err}") +endif () + +list(REMOVE_ITEM working_modules + ${installed_modules}) +foreach (working_module IN LISTS working_modules) + message(SEND_ERROR + "Builtin module ${working_module} is available but not listed for packaging") +endforeach ()