diff --git a/easybuild/easyconfigs/p/Python/Python-3.10.4-GCCcore-11.3.0-bare.eb b/easybuild/easyconfigs/p/Python/Python-3.10.4-GCCcore-11.3.0-bare.eb index a8c15654825d..402289f9c764 100644 --- a/easybuild/easyconfigs/p/Python/Python-3.10.4-GCCcore-11.3.0-bare.eb +++ b/easybuild/easyconfigs/p/Python/Python-3.10.4-GCCcore-11.3.0-bare.eb @@ -11,7 +11,15 @@ toolchainopts = {'pic': True} source_urls = ['https://www.python.org/ftp/%(namelower)s/%(version)s/'] sources = [SOURCE_TGZ] -checksums = ['f3bcc65b1d5f1dc78675c746c98fcee823c038168fc629c5935b044d0911ad28'] + +# Like patches, but these will only be applied if EasyBuild is configured to filter $LD_LIBRARY_PATH +# In that scenario, ctypes needs to be patched since it heavily relies on $LD_LIBRARY_PATH to find libraries +patch_ctypes_ld_library_path = 'Python-3.11.5-custom-ctypes.patch' + +checksums = [ + {'Python-3.10.4.tgz': 'f3bcc65b1d5f1dc78675c746c98fcee823c038168fc629c5935b044d0911ad28'}, + {'Python-3.11.5-custom-ctypes.patch': 'b29c22f47587460149e05296ff09b29bf790a83e2b3b13fb2f42f5f236ad8ea7'} +] builddependencies = [ ('UnZip', '6.0'), diff --git a/easybuild/easyconfigs/p/Python/Python-3.10.4-GCCcore-11.3.0.eb b/easybuild/easyconfigs/p/Python/Python-3.10.4-GCCcore-11.3.0.eb index 0e403f9e2889..761064ed09d7 100644 --- a/easybuild/easyconfigs/p/Python/Python-3.10.4-GCCcore-11.3.0.eb +++ b/easybuild/easyconfigs/p/Python/Python-3.10.4-GCCcore-11.3.0.eb @@ -10,7 +10,15 @@ toolchainopts = {'pic': True} source_urls = ['https://www.python.org/ftp/%(namelower)s/%(version)s/'] sources = [SOURCE_TGZ] -checksums = ['f3bcc65b1d5f1dc78675c746c98fcee823c038168fc629c5935b044d0911ad28'] + +# Like patches, but these will only be applied if EasyBuild is configured to filter $LD_LIBRARY_PATH +# In that scenario, ctypes needs to be patched since it heavily relies on $LD_LIBRARY_PATH to find libraries +patch_ctypes_ld_library_path = 'Python-3.11.5-custom-ctypes.patch' + +checksums = [ + {'Python-3.10.4.tgz': 'f3bcc65b1d5f1dc78675c746c98fcee823c038168fc629c5935b044d0911ad28'}, + {'Python-3.11.5-custom-ctypes.patch': 'b29c22f47587460149e05296ff09b29bf790a83e2b3b13fb2f42f5f236ad8ea7'} +] builddependencies = [ ('UnZip', '6.0'), diff --git a/easybuild/easyconfigs/p/Python/Python-3.10.8-GCCcore-12.2.0-bare.eb b/easybuild/easyconfigs/p/Python/Python-3.10.8-GCCcore-12.2.0-bare.eb index 695a65cfdb50..a7b6a7240ee2 100644 --- a/easybuild/easyconfigs/p/Python/Python-3.10.8-GCCcore-12.2.0-bare.eb +++ b/easybuild/easyconfigs/p/Python/Python-3.10.8-GCCcore-12.2.0-bare.eb @@ -11,7 +11,15 @@ toolchainopts = {'pic': True} source_urls = ['https://www.python.org/ftp/%(namelower)s/%(version)s/'] sources = [SOURCE_TGZ] -checksums = ['f400c3fb394b8bef1292f6dc1292c5fadc3533039a5bc0c3e885f3e16738029a'] + +# Like patches, but these will only be applied if EasyBuild is configured to filter $LD_LIBRARY_PATH +# In that scenario, ctypes needs to be patched since it heavily relies on $LD_LIBRARY_PATH to find libraries +patch_ctypes_ld_library_path = 'Python-3.11.5-custom-ctypes.patch' + +checksums = [ + {'Python-3.10.8.tgz': 'f400c3fb394b8bef1292f6dc1292c5fadc3533039a5bc0c3e885f3e16738029a'}, + {'Python-3.11.5-custom-ctypes.patch': 'b29c22f47587460149e05296ff09b29bf790a83e2b3b13fb2f42f5f236ad8ea7'} +] builddependencies = [ ('UnZip', '6.0'), diff --git a/easybuild/easyconfigs/p/Python/Python-3.10.8-GCCcore-12.2.0.eb b/easybuild/easyconfigs/p/Python/Python-3.10.8-GCCcore-12.2.0.eb index 8d99285f8092..4e412ca3e865 100644 --- a/easybuild/easyconfigs/p/Python/Python-3.10.8-GCCcore-12.2.0.eb +++ b/easybuild/easyconfigs/p/Python/Python-3.10.8-GCCcore-12.2.0.eb @@ -10,7 +10,15 @@ toolchainopts = {'pic': True} source_urls = ['https://www.python.org/ftp/%(namelower)s/%(version)s/'] sources = [SOURCE_TGZ] -checksums = ['f400c3fb394b8bef1292f6dc1292c5fadc3533039a5bc0c3e885f3e16738029a'] + +# Like patches, but these will only be applied if EasyBuild is configured to filter $LD_LIBRARY_PATH +# In that scenario, ctypes needs to be patched since it heavily relies on $LD_LIBRARY_PATH to find libraries +patch_ctypes_ld_library_path = 'Python-3.11.5-custom-ctypes.patch' + +checksums = [ + {'Python-3.10.8.tgz': 'f400c3fb394b8bef1292f6dc1292c5fadc3533039a5bc0c3e885f3e16738029a'}, + {'Python-3.11.5-custom-ctypes.patch': 'b29c22f47587460149e05296ff09b29bf790a83e2b3b13fb2f42f5f236ad8ea7'} +] builddependencies = [ ('UnZip', '6.0'), diff --git a/easybuild/easyconfigs/p/Python/Python-3.11.2-GCCcore-12.2.0-bare.eb b/easybuild/easyconfigs/p/Python/Python-3.11.2-GCCcore-12.2.0-bare.eb index 9dc98d9f22d2..da627837df66 100644 --- a/easybuild/easyconfigs/p/Python/Python-3.11.2-GCCcore-12.2.0-bare.eb +++ b/easybuild/easyconfigs/p/Python/Python-3.11.2-GCCcore-12.2.0-bare.eb @@ -11,7 +11,15 @@ toolchainopts = {'pic': True} source_urls = ['https://www.python.org/ftp/%(namelower)s/%(version)s/'] sources = [SOURCE_TGZ] -checksums = ['2411c74bda5bbcfcddaf4531f66d1adc73f247f529aee981b029513aefdbf849'] + +# Like patches, but these will only be applied if EasyBuild is configured to filter $LD_LIBRARY_PATH +# In that scenario, ctypes needs to be patched since it heavily relies on $LD_LIBRARY_PATH to find libraries +patch_ctypes_ld_library_path = 'Python-3.11.5-custom-ctypes.patch' + +checksums = [ + {'Python-3.11.2.tgz': '2411c74bda5bbcfcddaf4531f66d1adc73f247f529aee981b029513aefdbf849'}, + {'Python-3.11.5-custom-ctypes.patch': 'b29c22f47587460149e05296ff09b29bf790a83e2b3b13fb2f42f5f236ad8ea7'} +] builddependencies = [ ('UnZip', '6.0'), diff --git a/easybuild/easyconfigs/p/Python/Python-3.11.3-GCCcore-12.3.0.eb b/easybuild/easyconfigs/p/Python/Python-3.11.3-GCCcore-12.3.0.eb index 09dc30f2178b..8cfeee10ab12 100644 --- a/easybuild/easyconfigs/p/Python/Python-3.11.3-GCCcore-12.3.0.eb +++ b/easybuild/easyconfigs/p/Python/Python-3.11.3-GCCcore-12.3.0.eb @@ -10,7 +10,15 @@ toolchainopts = {'pic': True} source_urls = ['https://www.python.org/ftp/%(namelower)s/%(version)s/'] sources = [SOURCE_TGZ] -checksums = ['1a79f3df32265d9e6625f1a0b31c28eb1594df911403d11f3320ee1da1b3e048'] + +# Like patches, but these will only be applied if EasyBuild is configured to filter $LD_LIBRARY_PATH +# In that scenario, ctypes needs to be patched since it heavily relies on $LD_LIBRARY_PATH to find libraries +patch_ctypes_ld_library_path = 'Python-3.11.5-custom-ctypes.patch' + +checksums = [ + {'Python-3.11.3.tgz': '1a79f3df32265d9e6625f1a0b31c28eb1594df911403d11f3320ee1da1b3e048'}, + {'Python-3.11.5-custom-ctypes.patch': 'b29c22f47587460149e05296ff09b29bf790a83e2b3b13fb2f42f5f236ad8ea7'} +] builddependencies = [ ('UnZip', '6.0'), diff --git a/easybuild/easyconfigs/p/Python/Python-3.11.5-GCCcore-13.2.0.eb b/easybuild/easyconfigs/p/Python/Python-3.11.5-GCCcore-13.2.0.eb index 80e5335b710b..e118977eb2ff 100644 --- a/easybuild/easyconfigs/p/Python/Python-3.11.5-GCCcore-13.2.0.eb +++ b/easybuild/easyconfigs/p/Python/Python-3.11.5-GCCcore-13.2.0.eb @@ -10,7 +10,15 @@ toolchainopts = {'pic': True} source_urls = ['https://www.python.org/ftp/%(namelower)s/%(version)s/'] sources = [SOURCE_TGZ] -checksums = ['a12a0a013a30b846c786c010f2c19dd36b7298d888f7c4bd1581d90ce18b5e58'] + +# Like patches, but these will only be applied if EasyBuild is configured to filter $LD_LIBRARY_PATH +# In that scenario, ctypes needs to be patched since it heavily relies on $LD_LIBRARY_PATH to find libraries +patch_ctypes_ld_library_path = 'Python-3.11.5-custom-ctypes.patch' + +checksums = [ + {'Python-3.11.5.tgz': 'a12a0a013a30b846c786c010f2c19dd36b7298d888f7c4bd1581d90ce18b5e58'}, + {'Python-3.11.5-custom-ctypes.patch': 'b29c22f47587460149e05296ff09b29bf790a83e2b3b13fb2f42f5f236ad8ea7'} +] builddependencies = [ ('UnZip', '6.0'), diff --git a/easybuild/easyconfigs/p/Python/Python-3.11.5-custom-ctypes.patch b/easybuild/easyconfigs/p/Python/Python-3.11.5-custom-ctypes.patch new file mode 100644 index 000000000000..f81e77962d26 --- /dev/null +++ b/easybuild/easyconfigs/p/Python/Python-3.11.5-custom-ctypes.patch @@ -0,0 +1,162 @@ +Ctypes heavily relies on LD_LIBRARY_PATH in it's find_library, ctypes.CDLL, ctypes.cdll.LoadLibrary functions. +This patch is meant for systems where LD_LIBRARY_PATH is filtered. It will rely on LIBRARY_PATH instead. +It makes the following essential changes: +- Whereever find_library searched LD_LIBRARY_PATH, LIBRARY_PATH will be searched instead +- find_library is adapted so that it returns the full library path, not just the library name, which replaces + https://github.com/easybuilders/easybuild-easyblocks/pull/3352 +- The internal function _findLib_gcc, one of the functions called by find_library to locate libraries, is adapted + so that it also works when called by full library name (e.g. libfoo.so.1) instead of the short name (foo) only + This is necessary since CDLL is typically called by full name, and needs to be able to call find_library 9see below) +- The initialization of CDLL is adapted so that it calls find_library. Then, it overwrites the name + with the full library path. This defers all the library localization issues to the (patched) find_library +Authors: Danilo Gonzalez (DoItNow group), Caspar van Leeuwen (SURF) and Alan O'cais (CECAM) +diff -Nru Python-3.11.5.orig/Lib/ctypes/__init__.py Python-3.11.5/Lib/ctypes/__init__.py +--- Python-3.11.5.orig/Lib/ctypes/__init__.py 2025-10-13 15:58:38.405564000 +0200 ++++ Python-3.11.5/Lib/ctypes/__init__.py 2025-10-13 16:01:08.717507706 +0200 +@@ -14,6 +14,9 @@ + + from struct import calcsize as _calcsize + ++# Add util to use find_library capabilities ++from ctypes import util ++ + if __version__ != _ctypes_version: + raise Exception("Version number mismatch", __version__, _ctypes_version) + +@@ -349,6 +352,12 @@ + flags |= _FUNCFLAG_USE_ERRNO + if use_last_error: + flags |= _FUNCFLAG_USE_LASTERROR ++ # define CDLL instance name as fullpath ++ if _os.name == "posix": ++ if name: ++ fullpath = util.find_library(name) ++ if fullpath is not None: ++ self._name = fullpath + if _sys.platform.startswith("aix"): + """When the name contains ".a(" and ends with ")", + e.g., "libFOO.a(libFOO.so)" - this is taken to be an +diff -Nru Python-3.11.5.orig/Lib/ctypes/util.py Python-3.11.5/Lib/ctypes/util.py +--- Python-3.11.5.orig/Lib/ctypes/util.py 2025-10-13 15:58:38.306949000 +0200 ++++ Python-3.11.5/Lib/ctypes/util.py 2025-10-13 17:17:07.589997890 +0200 +@@ -99,12 +99,19 @@ + with open(filename, 'br') as thefile: + return thefile.read(4) == elf_header + +- def _findLib_gcc(name): ++ def _findLib_gcc(name, name_is_fullname=False): + # Run GCC's linker with the -t (aka --trace) option and examine the + # library name it prints out. The GCC command will fail because we + # haven't supplied a proper program with main(), but that does not + # matter. +- expr = os.fsencode(r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name)) ++ # If the name is a full library name (e.g. libfoo.so), this function calls gcc with -l: instead of ++ # -l and uses a slightly more strict regular expression to avoid matching the error ++ # '/path/to/ld: cannot find -l:libfoo.so: No such file or directory' ++ # since we only want a regex match if the library exists ++ if name_is_fullname: ++ expr = os.fsencode(r'^[^\(\)\s]*%s[^\(\)\s]*' % re.escape(name)) ++ else: ++ expr = os.fsencode(r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name)) + + c_compiler = shutil.which('gcc') + if not c_compiler: +@@ -115,7 +122,10 @@ + + temp = tempfile.NamedTemporaryFile() + try: +- args = [c_compiler, '-Wl,-t', '-o', temp.name, '-l' + name] ++ if name_is_fullname: ++ args = [c_compiler, '-Wl,-t', '-o', temp.name, '-l:' + name] ++ else: ++ args = [c_compiler, '-Wl,-t', '-o', temp.name, '-l' + name] + + env = dict(os.environ) + env['LC_ALL'] = 'C' +@@ -136,7 +146,12 @@ + # Raised if the file was already removed, which is the normal + # behaviour of GCC if linking fails + pass +- res = re.findall(expr, trace) ++ # If name_is_fullname, the regex in expr starts wity ^. ++ # Use re.MULTILINE, to make surethat ^ matches the start of EACH line in trace ++ if name_is_fullname: ++ res = re.findall(expr, trace, re.MULTILINE) ++ else: ++ res = re.findall(expr, trace) + if not res: + return None + +@@ -146,8 +161,11 @@ + # shared objects. See bpo-41976 for more details + if not _is_elf(file): + continue +- return os.fsdecode(file) +- ++ file = os.fsdecode(file) ++ # Avoid returning CUDA stubs libraries, as those are not intended for runtime use ++ if re.search(r'cuda.*stubs', file, re.IGNORECASE): ++ continue ++ return file + + if sys.platform == "sunos5": + # use /usr/ccs/bin/dump on solaris +@@ -283,7 +301,8 @@ + abi_type = mach_map.get(machine, 'libc6') + + # XXX assuming GLIBC's ldconfig (with option -p) +- regex = r'\s+(lib%s\.[^\s]+)\s+\(%s' ++ # Regular expresion that captures complete line of ldconfig -p output that matches with library name. ++ regex = r'\s+(lib%s\.[^\s]+)\s+\(%s\)\s+=>\s+(\S+)' + regex = os.fsencode(regex % (re.escape(name), abi_type)) + try: + with subprocess.Popen(['/sbin/ldconfig', '-p'], +@@ -293,7 +312,8 @@ + env={'LC_ALL': 'C', 'LANG': 'C'}) as p: + res = re.search(regex, p.stdout.read()) + if res: +- return os.fsdecode(res.group(1)) ++ # return the regex second group, that is the full path to the library ++ return os.fsdecode(res.group(2)) + except OSError: + pass + +@@ -301,10 +321,17 @@ + # See issue #9998 for why this is needed + expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) + cmd = ['ld', '-t'] +- libpath = os.environ.get('LD_LIBRARY_PATH') ++ # use LIBRARY_PATH instead of LD_LIBRARY_PATH to use EB provided shared libraries ++ libpath = os.environ.get('LIBRARY_PATH') + if libpath: + for d in libpath.split(':'): +- cmd.extend(['-L', d]) ++ # Avoid picking up CUDA stubs libraries, as those are not intended for runtime use ++ parts = d.split('/') ++ # We want to add 'd' in all cases EXCEPT if the path contains both CUDA (as partial ++ # directory name) and stubs (as full directory name). I.e. /my/bar/stubs and /my/cudafoo ++ # will be added to cmd, but /my/cudafoo/bar/stubs won't be ++ if not (any('cuda' in p.lower() for p in parts) and 'stubs' in parts): ++ cmd.extend(['-L', d]) + cmd.extend(['-o', os.devnull, '-l%s' % name]) + result = None + try: +@@ -325,9 +352,15 @@ + return result + + def find_library(name): +- # See issue #9998 +- return _findSoname_ldconfig(name) or \ +- _get_soname(_findLib_gcc(name)) or _get_soname(_findLib_ld(name)) ++ # Redefine find_library function, it will return the provided name if ++ # path exist, else it will use the set of functions to find the full library path. ++ # it will return the one that has a match. ++ if os.path.isabs(name) and os.path.exists(name): ++ return name ++ else: ++ return _findSoname_ldconfig(name) or \ ++ _findLib_gcc(name) or _findLib_ld(name) or \ ++ _findLib_gcc(name, name_is_fullname=True) + + ################################################################ + # test code diff --git a/easybuild/easyconfigs/p/Python/Python-3.12.3-GCCcore-13.3.0.eb b/easybuild/easyconfigs/p/Python/Python-3.12.3-GCCcore-13.3.0.eb index 9f6d1a682342..089eeb31808d 100644 --- a/easybuild/easyconfigs/p/Python/Python-3.12.3-GCCcore-13.3.0.eb +++ b/easybuild/easyconfigs/p/Python/Python-3.12.3-GCCcore-13.3.0.eb @@ -11,9 +11,15 @@ toolchainopts = {'pic': True} source_urls = ['https://www.python.org/ftp/%(namelower)s/%(version)s/'] sources = [SOURCE_TGZ] patches = ['Python-3.12.3_avoid-tkinter-build.patch'] + +# Like patches, but these will only be applied if EasyBuild is configured to filter $LD_LIBRARY_PATH +# In that scenario, ctypes needs to be patched since it heavily relies on $LD_LIBRARY_PATH to find libraries +patch_ctypes_ld_library_path = 'Python-3.11.5-custom-ctypes.patch' + checksums = [ {'Python-3.12.3.tgz': 'a6b9459f45a6ebbbc1af44f5762623fa355a0c87208ed417628b379d762dddb0'}, {'Python-3.12.3_avoid-tkinter-build.patch': '34fa44ca67fc08d41c58db2e289317f12f32777a352a982dca2e63459fc089e3'}, + {'Python-3.11.5-custom-ctypes.patch': 'b29c22f47587460149e05296ff09b29bf790a83e2b3b13fb2f42f5f236ad8ea7'} ] builddependencies = [ diff --git a/easybuild/easyconfigs/p/Python/Python-3.13.1-GCCcore-14.2.0.eb b/easybuild/easyconfigs/p/Python/Python-3.13.1-GCCcore-14.2.0.eb index 2d8219710f0b..4f44ede9666b 100644 --- a/easybuild/easyconfigs/p/Python/Python-3.13.1-GCCcore-14.2.0.eb +++ b/easybuild/easyconfigs/p/Python/Python-3.13.1-GCCcore-14.2.0.eb @@ -10,14 +10,21 @@ toolchainopts = {'pic': True} source_urls = ['https://www.python.org/ftp/%(namelower)s/%(version)s/'] sources = [SOURCE_TGZ] + patches = [ 'Python-3.12.3_avoid-tkinter-build.patch', 'Python-3.13.1_runshared-ld-preload.patch', ] + +# Like patches, but these will only be applied if EasyBuild is configured to filter $LD_LIBRARY_PATH +# In that scenario, ctypes needs to be patched since it heavily relies on $LD_LIBRARY_PATH to find libraries +patch_ctypes_ld_library_path = 'Python-3.11.5-custom-ctypes.patch' + checksums = [ {'Python-3.13.1.tgz': '1513925a9f255ef0793dbf2f78bb4533c9f184bdd0ad19763fd7f47a400a7c55'}, {'Python-3.12.3_avoid-tkinter-build.patch': '34fa44ca67fc08d41c58db2e289317f12f32777a352a982dca2e63459fc089e3'}, {'Python-3.13.1_runshared-ld-preload.patch': 'ca9ec56c71aafa881e7ddf6fba23fbecc016be48c2d912e5ccd92962ddd38edf'}, + {'Python-3.11.5-custom-ctypes.patch': 'b29c22f47587460149e05296ff09b29bf790a83e2b3b13fb2f42f5f236ad8ea7'}, ] builddependencies = [ diff --git a/easybuild/easyconfigs/p/Python/Python-3.9.5-GCCcore-10.3.0-bare.eb b/easybuild/easyconfigs/p/Python/Python-3.9.5-GCCcore-10.3.0-bare.eb index 25d4981ffe0b..1e58b588274f 100644 --- a/easybuild/easyconfigs/p/Python/Python-3.9.5-GCCcore-10.3.0-bare.eb +++ b/easybuild/easyconfigs/p/Python/Python-3.9.5-GCCcore-10.3.0-bare.eb @@ -11,7 +11,15 @@ toolchainopts = {'pic': True} source_urls = ['https://www.python.org/ftp/%(namelower)s/%(version)s/'] sources = [SOURCE_TGZ] -checksums = ['e0fbd5b6e1ee242524430dee3c91baf4cbbaba4a72dd1674b90fda87b713c7ab'] + +# Like patches, but these will only be applied if EasyBuild is configured to filter $LD_LIBRARY_PATH +# In that scenario, ctypes needs to be patched since it heavily relies on $LD_LIBRARY_PATH to find libraries +patch_ctypes_ld_library_path = 'Python-3.11.5-custom-ctypes.patch' + +checksums = [ + {'Python-3.9.5.tgz': 'e0fbd5b6e1ee242524430dee3c91baf4cbbaba4a72dd1674b90fda87b713c7ab'}, + {'Python-3.11.5-custom-ctypes.patch': 'b29c22f47587460149e05296ff09b29bf790a83e2b3b13fb2f42f5f236ad8ea7'} +] builddependencies = [ ('UnZip', '6.0'), diff --git a/easybuild/easyconfigs/p/Python/Python-3.9.5-GCCcore-10.3.0.eb b/easybuild/easyconfigs/p/Python/Python-3.9.5-GCCcore-10.3.0.eb index 613bc37bfc08..abe22e570006 100644 --- a/easybuild/easyconfigs/p/Python/Python-3.9.5-GCCcore-10.3.0.eb +++ b/easybuild/easyconfigs/p/Python/Python-3.9.5-GCCcore-10.3.0.eb @@ -10,7 +10,15 @@ toolchainopts = {'pic': True} source_urls = ['https://www.python.org/ftp/%(namelower)s/%(version)s/'] sources = [SOURCE_TGZ] -checksums = ['e0fbd5b6e1ee242524430dee3c91baf4cbbaba4a72dd1674b90fda87b713c7ab'] + +# Like patches, but these will only be applied if EasyBuild is configured to filter $LD_LIBRARY_PATH +# In that scenario, ctypes needs to be patched since it heavily relies on $LD_LIBRARY_PATH to find libraries +patch_ctypes_ld_library_path = 'Python-3.11.5-custom-ctypes.patch' + +checksums = [ + {'Python-3.9.5.tgz': 'e0fbd5b6e1ee242524430dee3c91baf4cbbaba4a72dd1674b90fda87b713c7ab'}, + {'Python-3.11.5-custom-ctypes.patch': 'b29c22f47587460149e05296ff09b29bf790a83e2b3b13fb2f42f5f236ad8ea7'} +] builddependencies = [ ('UnZip', '6.0'), diff --git a/easybuild/easyconfigs/p/Python/Python-3.9.6-GCCcore-11.2.0-bare.eb b/easybuild/easyconfigs/p/Python/Python-3.9.6-GCCcore-11.2.0-bare.eb index d568ea3f8c84..5a65708adb55 100644 --- a/easybuild/easyconfigs/p/Python/Python-3.9.6-GCCcore-11.2.0-bare.eb +++ b/easybuild/easyconfigs/p/Python/Python-3.9.6-GCCcore-11.2.0-bare.eb @@ -11,7 +11,15 @@ toolchainopts = {'pic': True} source_urls = ['https://www.python.org/ftp/%(namelower)s/%(version)s/'] sources = [SOURCE_TGZ] -checksums = ['d0a35182e19e416fc8eae25a3dcd4d02d4997333e4ad1f2eee6010aadc3fe866'] + +# Like patches, but these will only be applied if EasyBuild is configured to filter $LD_LIBRARY_PATH +# In that scenario, ctypes needs to be patched since it heavily relies on $LD_LIBRARY_PATH to find libraries +patch_ctypes_ld_library_path = 'Python-3.11.5-custom-ctypes.patch' + +checksums = [ + {'Python-3.9.6.tgz': 'd0a35182e19e416fc8eae25a3dcd4d02d4997333e4ad1f2eee6010aadc3fe866'}, + {'Python-3.11.5-custom-ctypes.patch': 'b29c22f47587460149e05296ff09b29bf790a83e2b3b13fb2f42f5f236ad8ea7'} +] builddependencies = [ ('UnZip', '6.0'), diff --git a/easybuild/easyconfigs/p/Python/Python-3.9.6-GCCcore-11.2.0.eb b/easybuild/easyconfigs/p/Python/Python-3.9.6-GCCcore-11.2.0.eb index 8f2efa940cc1..ba72e7aa74c3 100644 --- a/easybuild/easyconfigs/p/Python/Python-3.9.6-GCCcore-11.2.0.eb +++ b/easybuild/easyconfigs/p/Python/Python-3.9.6-GCCcore-11.2.0.eb @@ -10,7 +10,15 @@ toolchainopts = {'pic': True} source_urls = ['https://www.python.org/ftp/%(namelower)s/%(version)s/'] sources = [SOURCE_TGZ] -checksums = ['d0a35182e19e416fc8eae25a3dcd4d02d4997333e4ad1f2eee6010aadc3fe866'] + +# Like patches, but these will only be applied if EasyBuild is configured to filter $LD_LIBRARY_PATH +# In that scenario, ctypes needs to be patched since it heavily relies on $LD_LIBRARY_PATH to find libraries +patch_ctypes_ld_library_path = 'Python-3.11.5-custom-ctypes.patch' + +checksums = [ + {'Python-3.9.6.tgz': 'd0a35182e19e416fc8eae25a3dcd4d02d4997333e4ad1f2eee6010aadc3fe866'}, + {'Python-3.11.5-custom-ctypes.patch': 'b29c22f47587460149e05296ff09b29bf790a83e2b3b13fb2f42f5f236ad8ea7'} +] builddependencies = [ ('UnZip', '6.0'), diff --git a/test/easyconfigs/easyconfigs.py b/test/easyconfigs/easyconfigs.py index 003f9726f382..c4f671c9736b 100644 --- a/test/easyconfigs/easyconfigs.py +++ b/test/easyconfigs/easyconfigs.py @@ -1254,6 +1254,28 @@ def test_pr_sha256_checksums(self): def is_bundle(ec): return ec['easyblock'] in bundle_easyblocks or ec['name'] == 'Clang-AOMP' ecs = [ec.copy() if is_bundle(ec) else ec for ec in retained_changed_ecs] + + # remove checksum for patch_ctypes_ld_library_path for Python easyconfigs, if present; + # this patch gets added automatically to list of patches by Python easyblock constructor, + # and causes check_sha256_checksums to fail because an extra checksum is found + for ec in ecs: + ec_fn = os.path.basename(ec.path) + if ec['name'] == 'Python': + patch_ctypes_ld_library_path = ec.get('patch_ctypes_ld_library_path') + if patch_ctypes_ld_library_path: + checksums = ec.get_ref('checksums') + if not isinstance(checksums, list): + self.fail(f"Don't know how to handle non-list value type for checksums in {ec_fn}") + idx_match = None + for idx, entry in enumerate(checksums): + if patch_ctypes_ld_library_path in entry: + idx_match = idx + break + if idx_match: + del checksums[idx] + else: + self.fail(f"No checksum found for {patch_ctypes_ld_library_path} in {ec_fn}") + checksum_issues = check_sha256_checksums(ecs, whitelist=whitelist) self.assertTrue(len(checksum_issues) == 0, "No checksum issues:\n%s" % '\n'.join(checksum_issues))