From 36e6f61afe9567e63d2d0c081397fa5d8e0afcb4 Mon Sep 17 00:00:00 2001 From: Yan Li Date: Tue, 26 Mar 2024 17:28:15 +0800 Subject: [PATCH 01/12] update readme and steup.py to support python3.12 --- README.md | 9 +++++++-- setup.py | 5 ++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bfccf47..63c9875 100755 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ Please note you must use lsf.lsb_init before any other LSBLIB library routine in Supported operating systems: Linux 2.6 glibc 2.3 x86 64 bit: RHEL 6.2, RHEL6.4, RHEL6.5, RHEL6.8 - Linux 3.10 glibc 2.17 x86 64 bit: Red Hat 7.4, 7.5 + Linux 3.10 glibc 2.17 x86 64 bit: Red Hat 7.4, 7.5, 8.8, 8.9 Linux for Power Systems Servers 8 Little Endian (Linux 3.10, glibc 2.17): RHEL 7.4 Linux for Power Systems Servers 9 Little Endian (Linux 4.14, glibc 2.17): RHEL 7.5 @@ -58,7 +58,7 @@ Please note you must use lsf.lsb_init before any other LSBLIB library routine in Python2 and Python3 are all supported. The following versions are tested: - Python 2.6.6, 2.7.15, 3.0, 3.6.0, 3.7.0 + Python 2.6.6, 2.7.15, 3.0, 3.6.0, 3.7.0, 3.12.2 ## Compatibility @@ -74,6 +74,10 @@ Before compiling the library, set the LSF environment variables: `$ source profile.lsf` +If using python version higher than 3.10, distutils has been deprecated, install setuptools: + +`$ pip3 install setuptools` + To compile and install the library, go to the main source directory and type: @@ -90,6 +94,7 @@ or `$ python3 setup.py bdist_rpm` Resulting RPMs will be placed in the dist directory + ## Release Notes ### Release 1.0.6 diff --git a/setup.py b/setup.py index ef5e503..57992b7 100755 --- a/setup.py +++ b/setup.py @@ -8,7 +8,10 @@ # import os, sys, re import time -from distutils.core import setup, Extension +if sys.version_info >= (3,10): + from setuptools import setup, Extension +else: + from distutils.core import setup, Extension from distutils.command.bdist_rpm import bdist_rpm from distutils.command.install import INSTALL_SCHEMES From 32f498fda26bd8c980aa415ad0308423ccfbce8a Mon Sep 17 00:00:00 2001 From: Yan Li Date: Tue, 26 Mar 2024 18:15:09 +0800 Subject: [PATCH 02/12] update readme for installing SWIG3.0.12 in pip install --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 63c9875..19ef0c7 100755 --- a/README.md +++ b/README.md @@ -48,10 +48,13 @@ Please note you must use lsf.lsb_init before any other LSBLIB library routine in - SWIG - SWIG version 2.0, or later + SWIG version 2.0, or 3.0 The following versions are tested: SWIG: 2.0.10, 3.0.12 + + If isntalling SWIG with pip or pip3, please specify 3.0.12 version. + `$ pip3 install swig==3.0.12` - Python From adc66fee13c5f7fbd51083c21e6b58acaf055574 Mon Sep 17 00:00:00 2001 From: Peter Kang Date: Tue, 25 Feb 2025 10:16:11 -0800 Subject: [PATCH 03/12] add str2GpuJobData --- pythonlsf/lsf.i | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pythonlsf/lsf.i b/pythonlsf/lsf.i index d380025..25253a4 100644 --- a/pythonlsf/lsf.i +++ b/pythonlsf/lsf.i @@ -25,6 +25,7 @@ int fclose(FILE *f); #include "lsf.h" #include "lsbatch.h" #include "lib.table.h" +extern struct gpuJobData* str2GpuJobData(char *str); %} %pointer_functions(int, intp) @@ -47,6 +48,10 @@ int fclose(FILE *f); %array_functions(struct shareAcctInfoEnt, shareAcctInfoEntArray) #ifdef LSF_VERSION_101 %array_functions(struct gpuRusage, gpuRusageArray) +%array_functions(struct gpuJobHostData, gpuJobHostDataArray) +%array_functions(struct gpuTaskData, gpuTaskDataArray) +%array_functions(struct gpuData *, gpuDataArray) +%array_functions(struct migData, migDataArray) #endif %array_functions(LS_LONG_INT, LS_LONG_INTArray) %array_functions(guaranteedResourcePoolEnt, guaranteedResourcePoolEntArray) @@ -703,6 +708,9 @@ int get_lsb_errno() { char * get_lsb_sysmsg() { return lsb_sysmsg(); } +struct gpuJobData* get_str2GpuJobData(char *str) { + return str2GpuJobData(str); +} PyObject * get_pids_from_stream(struct jRusage * jrusage) { struct pidInfo *pidInfo; From 34e5b2dfbe3cd74bb4ad39b44f226b81ae6fc049 Mon Sep 17 00:00:00 2001 From: Yu-Ching Chen Date: Tue, 29 Apr 2025 08:37:40 -0700 Subject: [PATCH 04/12] 1335 update for compression and off_t type --- pythonlsf/Makefile | 2 +- pythonlsf/lsf.i | 1 + setup.py | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pythonlsf/Makefile b/pythonlsf/Makefile index b48b893..7df6577 100755 --- a/pythonlsf/Makefile +++ b/pythonlsf/Makefile @@ -14,7 +14,7 @@ PROJECT = _lsf.so OBJECTS = lsf_wrap.o CFLAGS = -m64 -fPIC -I$(PYTHON_INCLUDE) -I$(LSF_INCLUDE) -LDFLAGS = $(LSF_LIBDIR)/liblsf.a $(LSF_LIBDIR)/libbat.a $(LSF_LIBDIR)/libfairshareadjust.so $(LSF_LIBDIR)/liblsbstream.so -lc -lnsl +LDFLAGS = $(LSF_LIBDIR)/liblsf.a $(LSF_LIBDIR)/libbat.a $(LSF_LIBDIR)/libfairshareadjust.so $(LSF_LIBDIR)/liblsbstream.so -lc -lnsl -lz all: $(PROJECT) diff --git a/pythonlsf/lsf.i b/pythonlsf/lsf.i index 25253a4..18771e6 100644 --- a/pythonlsf/lsf.i +++ b/pythonlsf/lsf.i @@ -27,6 +27,7 @@ int fclose(FILE *f); #include "lib.table.h" extern struct gpuJobData* str2GpuJobData(char *str); %} +typedef long off_t; %pointer_functions(int, intp) %pointer_functions(float, floatp) diff --git a/setup.py b/setup.py index 57992b7..1476f9c 100755 --- a/setup.py +++ b/setup.py @@ -66,7 +66,7 @@ def set_gccflag_lsf_version(): xlc_path = os.path.join(path, 'xlc') if os.access(xlc_path, os.F_OK): found_xlc = True - os.environ["LDSHARED"] = "%s -pthread -shared -Wl,-z,relro" % xlc_path + os.environ["LDSHARED"] = "%s -pthread -shared -Wl,-z,-lz,relro" % xlc_path break if found_xlc == False: print(''' @@ -90,11 +90,11 @@ def set_gccflag_lsf_version(): if os.access(LSF_LIBDIR + "/liblsbstream.a", os.F_OK): lsf_static_lib = [ LSF_LIBDIR + '/liblsbstream.a'] - lsf_dynamic_lib = ['c', 'nsl', 'rt'] + lsf_dynamic_lib = ['c', 'nsl', 'rt', 'z'] warning_msg = "" else: lsf_static_lib = [] - lsf_dynamic_lib = ['c', 'nsl', 'lsbstream', 'lsf', 'bat', 'rt'] + lsf_dynamic_lib = ['c', 'nsl', 'lsbstream', 'lsf', 'bat', 'rt', 'z'] warning_msg = ''' Warning: The compatibility of the LSF Python API package is not guaranteed if you update LSF at a later time. This is because your current From 0f1e25ba5206cad5fbc2eb87680b71a6033e6ec9 Mon Sep 17 00:00:00 2001 From: Yu-Ching Chen Date: Tue, 29 Apr 2025 09:50:44 -0700 Subject: [PATCH 05/12] add RUN_RUSAGE for readstream.py with pid and pgids --- examples/readstream.py | 12 +++++++++++- pythonlsf/lsf.i | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/examples/readstream.py b/examples/readstream.py index 5ba9b57..60a4722 100644 --- a/examples/readstream.py +++ b/examples/readstream.py @@ -27,7 +27,17 @@ def display(eventrec): for i in range(0,numhosts): hoststr += lsf.stringArray_getitem(exechosts, i) + "" print("EVENT_JOB_FORCE jobid<%d>, execHost<%s>, username<%s>" %(jobid, hoststr, username)) - + elif eventrec.type == lsf.EVENT_JOB_RUN_RUSAGE: + jobid = eventrec.eventLog.jobRunRusageLog.jobid; + numpgids = eventrec.eventLog.jobRunRusageLog.jrusage.npgids; + for i in range(0,numpgids): + pgids = str(lsf.intArray_getitem(eventrec.eventLog.jobRunRusageLog.jrusage.pgid, i)) + " " + pgids = pgids[:-1] + numpids = eventrec.eventLog.jobRunRusageLog.jrusage.npids; + for i in range(0,numpids): + pids = str(lsf.pidInfoArray_getitem(eventrec.eventLog.jobRunRusageLog.jrusage.pidInfo, i).pid) + " "; + pids = pids[:-1] + print("EVENT_JOB_RUN_RUSAGE jobid<%d> pgids<%s> pids<%s>" %(jobid, pgids, pids)) else: print("event type is %d" %(eventrec.type)) diff --git a/pythonlsf/lsf.i b/pythonlsf/lsf.i index 18771e6..859437a 100644 --- a/pythonlsf/lsf.i +++ b/pythonlsf/lsf.i @@ -53,6 +53,7 @@ typedef long off_t; %array_functions(struct gpuTaskData, gpuTaskDataArray) %array_functions(struct gpuData *, gpuDataArray) %array_functions(struct migData, migDataArray) +%array_functions(struct pidInfo, pidInfoArray) #endif %array_functions(LS_LONG_INT, LS_LONG_INTArray) %array_functions(guaranteedResourcePoolEnt, guaranteedResourcePoolEntArray) From cb3321d2a072d88685cec3fb5bfa17f02eee0a17 Mon Sep 17 00:00:00 2001 From: Yu-Ching Chen Date: Wed, 6 Aug 2025 08:15:44 -0700 Subject: [PATCH 06/12] change build to be platform agnostic --- pythonlsf/Makefile | 2 +- setup.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pythonlsf/Makefile b/pythonlsf/Makefile index b48b893..1e19d9b 100755 --- a/pythonlsf/Makefile +++ b/pythonlsf/Makefile @@ -13,7 +13,7 @@ LSF_INCLUDE = $(LSF_LIBDIR)/../../include/lsf/ PROJECT = _lsf.so OBJECTS = lsf_wrap.o -CFLAGS = -m64 -fPIC -I$(PYTHON_INCLUDE) -I$(LSF_INCLUDE) +CFLAGS = -fPIC -I$(PYTHON_INCLUDE) -I$(LSF_INCLUDE) LDFLAGS = $(LSF_LIBDIR)/liblsf.a $(LSF_LIBDIR)/libbat.a $(LSF_LIBDIR)/libfairshareadjust.so $(LSF_LIBDIR)/liblsbstream.so -lc -lnsl all: $(PROJECT) diff --git a/setup.py b/setup.py index 57992b7..2f1ef6b 100755 --- a/setup.py +++ b/setup.py @@ -134,14 +134,13 @@ def set_gccflag_lsf_version(): # '-DLSF_SIMULATOR', '-DOS_HAS_THREAD -D_REENTRANT', gccflag_keyvaluet, gccflag_lsfversion], - extra_compile_args=['-m64', + extra_compile_args=[ '-I' + LSF_LIBDIR + '/../../include/lsf/', '-Wno-strict-prototypes', gccflag_keyvaluet, gccflag_lsfversion, '-DOS_HAS_THREAD -D_REENTRANT', #For multi-thread lib, lserrno '-Wp,-U_FORTIFY_SOURCE', #The flag needs -O option. Undefine it for warning. '-O0'], - extra_link_args=['-m64'], extra_objects=lsf_static_lib, libraries=lsf_dynamic_lib)], py_modules=['pythonlsf.lsf'], From 194891726fab351783b389220f07c4b8700a3abb Mon Sep 17 00:00:00 2001 From: Peter Kang Date: Tue, 14 Oct 2025 07:02:55 -0700 Subject: [PATCH 07/12] add hostGpuInfoArray, hostGpuInfoArray, hostGpuLoadArray --- examples/disp_gpu_host.py | 23 +++++++++++++++++++++++ pythonlsf/lsf.i | 5 +++++ 2 files changed, 28 insertions(+) create mode 100644 examples/disp_gpu_host.py diff --git a/examples/disp_gpu_host.py b/examples/disp_gpu_host.py new file mode 100644 index 0000000..c39cf97 --- /dev/null +++ b/examples/disp_gpu_host.py @@ -0,0 +1,23 @@ +from pythonlsf import lsf +if __name__ == '__main__': + if lsf.lsb_init("test") > 0: + exit -1; + num_hosts = lsf.new_intp() + lsf.intp_assign(num_hosts, 0) + hosts = lsf.ls_gethostgpuinfo(None, num_hosts, None, 0, 0) + hostGpuInfos = lsf.hostGpuInfoArray_frompointer(hosts) + for i in range(0, lsf.intp_value(num_hosts)): + hostGpuInfo = hostGpuInfos[i] + print("Host: {}". format(hostGpuInfo.hostName)) + numGpus = hostGpuInfos[i].gpuC + if numGpus <= 0: + continue + gpuAttrData = hostGpuInfo.gpuAttrV + gpuLoadData = hostGpuInfo.gpuLoadV + gpuAttrs = lsf.hostGpuAttrArray_frompointer(gpuAttrData) + gpuLoads = lsf.hostGpuLoadArray_frompointer(gpuLoadData) + print(" gBrand gModel gBusId gMode gUsedMem gStatus") + for j in range(0, numGpus): + print(" {} {} {} {} {} {} ". \ + format(gpuAttrs[j].gBrand, gpuAttrs[j].gModel, gpuAttrs[j].gBusId, + gpuLoads[j].gMode, gpuLoads[j].gUsedMem, gpuLoads[j].gStatus)) diff --git a/pythonlsf/lsf.i b/pythonlsf/lsf.i index 859437a..9052da7 100644 --- a/pythonlsf/lsf.i +++ b/pythonlsf/lsf.i @@ -200,6 +200,11 @@ static void stringArray_setitem(char * *ary, size_t index, char * value) { %array_class(struct _limitItem, limitItemArray) %array_class(struct _limitConsumer, limitConsumerArray) %array_class(struct _limitResource, limitResourceArray) +#ifdef LSF_VERSION_101 +%array_class(struct hostGpuInfo, hostGpuInfoArray) +%array_class(struct hostGpuAttr, hostGpuAttrArray) +%array_class(struct hostGpuLoad, hostGpuLoadArray) +#endif // handle int arrays %typemap(in) int [ANY] (int temp[$1_dim0]) { From 5addfaa00f899e00859c30f02c19b507b5ae93ba Mon Sep 17 00:00:00 2001 From: Peter Kang Date: Wed, 18 Feb 2026 11:51:39 -0800 Subject: [PATCH 08/12] set_limit_filter_flag() added for lsb_limitInfo() --- examples/disp_limit.py | 1 + pythonlsf/lsf.i | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/examples/disp_limit.py b/examples/disp_limit.py index c7bcead..ab715e8 100644 --- a/examples/disp_limit.py +++ b/examples/disp_limit.py @@ -28,4 +28,5 @@ def printLimit(): if __name__ == '__main__': print("LSF Clustername is : {}".format(lsf.ls_getclustername())) + lsf.set_limit_filter_flag(True) printLimit() diff --git a/pythonlsf/lsf.i b/pythonlsf/lsf.i index 9052da7..a18028d 100644 --- a/pythonlsf/lsf.i +++ b/pythonlsf/lsf.i @@ -26,6 +26,8 @@ int fclose(FILE *f); #include "lsbatch.h" #include "lib.table.h" extern struct gpuJobData* str2GpuJobData(char *str); +typedef int bool_t; +extern void setbConfigInfoFlag4Lib(bool_t bConfigInfo); %} typedef long off_t; @@ -247,6 +249,16 @@ static void stringArray_setitem(char * *ary, size_t index, char * value) { $1 = 0; } +%typemap(in) bool_t { + if (PyBool_Check($input)) { + $1 = (bool_t)(($input == Py_True) ? 1 : 0); + } else if (PyLong_Check($input)) { + $1 = (bool_t)PyLong_AsLong($input); + } else { + $1 = (bool_t)0; + } +} + /* The following routines are not wrapped because SWIG has issues generating proper code for them @@ -765,4 +777,8 @@ PyObject * get_host_info_all() { return result; } +void set_limit_filter_flag(bool_t bConfigInfo) { + setbConfigInfoFlag4Lib(bConfigInfo); +} + %} From e808d4ce1f87646f19b721d51261f10d35268834 Mon Sep 17 00:00:00 2001 From: Peter Kang Date: Thu, 26 Feb 2026 05:42:01 -0800 Subject: [PATCH 09/12] move *Array_frompointer() to frompointer() --- examples/disp_gpu.py | 5 ++++- examples/disp_gpu_host.py | 10 +++++++--- examples/disp_limit_all.py | 9 ++++++--- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/examples/disp_gpu.py b/examples/disp_gpu.py index 096d711..892e1e2 100644 --- a/examples/disp_gpu.py +++ b/examples/disp_gpu.py @@ -7,11 +7,14 @@ num_hosts = lsf.new_intp() lsf.intp_assign(num_hosts, 0) host_data = lsf.lsb_hostinfo_ex(host_names, num_hosts, "", 0) - all_host_data = lsf.hostInfoEntArray_frompointer(host_data) + all_host_data = lsf.hostInfoEntArray(lsf.intp_value(num_hosts)) + all_host_data = all_host_data.frompointer(host_data) for i in range(0, lsf.intp_value(num_hosts)): hostname = all_host_data[i].host print(hostname) gpudata = all_host_data[i].gpuData + if gpudata is None: + continue print("ngpus avail_shared_gpus avail_excl_gpus") print(" {} {} {}". \ format(gpudata.ngpus, gpudata.avail_shared_ngpus, gpudata.avail_excl_ngpus)) diff --git a/examples/disp_gpu_host.py b/examples/disp_gpu_host.py index c39cf97..cae2e3c 100644 --- a/examples/disp_gpu_host.py +++ b/examples/disp_gpu_host.py @@ -5,7 +5,9 @@ num_hosts = lsf.new_intp() lsf.intp_assign(num_hosts, 0) hosts = lsf.ls_gethostgpuinfo(None, num_hosts, None, 0, 0) - hostGpuInfos = lsf.hostGpuInfoArray_frompointer(hosts) + + hostGpuInfos = lsf.hostGpuInfoArray(lsf.intp_value(num_hosts)) + hostGpuInfos = hostGpuInfos.frompointer(hosts) for i in range(0, lsf.intp_value(num_hosts)): hostGpuInfo = hostGpuInfos[i] print("Host: {}". format(hostGpuInfo.hostName)) @@ -14,8 +16,10 @@ continue gpuAttrData = hostGpuInfo.gpuAttrV gpuLoadData = hostGpuInfo.gpuLoadV - gpuAttrs = lsf.hostGpuAttrArray_frompointer(gpuAttrData) - gpuLoads = lsf.hostGpuLoadArray_frompointer(gpuLoadData) + gpuAttrs = lsf.hostGpuAttrArray(numGpus) + gpuAttrs = gpuAttrs.frompointer(gpuAttrData) + gpuLoads = lsf.hostGpuLoadArray(numGpus) + gpuLoads = gpuLoads.frompointer(gpuLoadData) print(" gBrand gModel gBusId gMode gUsedMem gStatus") for j in range(0, numGpus): print(" {} {} {} {} {} {} ". \ diff --git a/examples/disp_limit_all.py b/examples/disp_limit_all.py index cc2fa2a..56ea773 100644 --- a/examples/disp_limit_all.py +++ b/examples/disp_limit_all.py @@ -3,12 +3,14 @@ def printLimitItem(name, item): print(name+' :') print(' consumerC : {}'.format(item.consumerC)) - consumers = lsf.limitConsumerArray_frompointer(item.consumerV) + consumers = lsf.limitConsumerArray(item.consumerC) + consumers = consumers.frompointer(item.consumerV) for j in range (item.consumerC) : print(' [{}] type : {}'.format(j, consumers[j].type)) print(' [{}] name : {}'.format(j, consumers[j].name)) print(' resourceC : {}'.format(item.resourceC)) - resources = lsf.limitResourceArray_frompointer(item.resourceV) + resources = lsf.limitResourceArray(item.resourceC) + resources= resources.frompointer(item.resourceV) for j in range (item.resourceC) : print(' [{}] name : {}'.format(j, resources[j].name)) print(' [{}] type : {}'.format(j, resources[j].type)) @@ -47,7 +49,8 @@ def printLimit(): # print usageC in the limit print('usageC : {}'.format(ent.usageC)) # print usageInfo in the limit - all_usageInfo = lsf.limitItemArray_frompointer(ent.usageInfo) + all_usageInfo = lsf.limitItemArray(ent.usageC) + all_usageInfo = all_usageInfo.frompointer(ent.usageInfo) for j in range (ent.usageC) : printLimitItem('usageInfo', all_usageInfo[j]) From bb5ef1b306048f49dbd3d99f595cc127c7bed956 Mon Sep 17 00:00:00 2001 From: Rob Davies Date: Tue, 21 Jan 2025 13:39:27 +0000 Subject: [PATCH 10/12] Added build wrapper so build_ext runs before build_py SWIG, run by build_ext, generates a shared object file and a python library. The latter needs to be generated before build_py is run so that build_py finds it. Unfortunately the default in setuptools is to run build_py before build_ext. The solution is to override the build class so that the build order can be changed. With this change, "pip install" works better, including when lsf-python-api is a dependency of another module. See: https://bugs.python.org/issue2624 https://bugs.python.org/issue1016626 https://stackoverflow.com/questions/12491328/python-distutils-not-include-the-swig-generated-module https://stackoverflow.com/questions/50239473/building-a-module-with-setuptools-and-swig Signed-off-by: Robert Davies --- setup.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 3e6d6bc..b3da42e 100755 --- a/setup.py +++ b/setup.py @@ -13,6 +13,7 @@ else: from distutils.core import setup, Extension from distutils.command.bdist_rpm import bdist_rpm +from distutils.command.build import build from distutils.command.install import INSTALL_SCHEMES class bdist_rpm_custom(bdist_rpm): @@ -28,6 +29,21 @@ def finalize_package_data (self): self.no_autoreq = 1 bdist_rpm.finalize_package_data(self) +# Build extensions before python modules, so the generated pythonlsf/lsf.py +# file is created before attempting to install it. This makes building with +# "pip" easier. +# See: +# https://bugs.python.org/issue2624 +# https://bugs.python.org/issue1016626 +# https://stackoverflow.com/questions/12491328/python-distutils-not-include-the-swig-generated-module +# https://stackoverflow.com/questions/50239473/building-a-module-with-setuptools-and-swig + +class build_ext_first(build): + def finalize_options(self): + super().finalize_options() + new_order = list(filter(lambda x: x[0] == 'build_ext', self.sub_commands)) + list(filter(lambda x: x[0] != 'build_ext', self.sub_commands)) + self.sub_commands[:] = new_order + def get_lsf_libdir(): try: _lsf_envdir = os.environ['LSF_ENVDIR'] @@ -144,7 +160,8 @@ def set_gccflag_lsf_version(): extra_objects=lsf_static_lib, libraries=lsf_dynamic_lib)], py_modules=['pythonlsf.lsf'], - cmdclass = { 'bdist_rpm': bdist_rpm_custom }, + cmdclass = { 'bdist_rpm': bdist_rpm_custom, + 'build': build_ext_first }, classifiers=["Development Status :: 2 - Pre-Alpha", "License :: OSI Approved :: Eclipse Public License", "Operating System :: OS Independent", From 600ef95891dfde3e9fc4aeefce9e8a807c2e5acd Mon Sep 17 00:00:00 2001 From: philip r brenan Date: Tue, 19 Aug 2025 23:16:33 +0100 Subject: [PATCH 11/12] Update README.md Corrected spelling of development --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 19ef0c7..3f744f4 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LSF Python API -These python wrappers allow customers to submit and control jobs and obtain status of queues, hosts and other LSF attributes from Python directly. They work with various versions of LSF and are maintained by LSF developement, though we take contributions from the Open Source community. +These python wrappers allow customers to submit and control jobs and obtain status of queues, hosts and other LSF attributes from Python directly. They work with various versions of LSF and are maintained by LSF development, though we take contributions from the Open Source community. If you plan or would like to contribute to the library, you must follow the DCO process in the attached [DCO Readme file](https://github.com/IBMSpectrumComputing/platform-python-lsf-api/blob/master/IBMDCO.md) in the root of this repository. It essentially requires you to provide a Sign Off line in the notes of your pull request stating that the work is clear of infinging work by others. Again, for more details, please see the DCO Readme file. @@ -179,3 +179,4 @@ IBM(R), the IBM logo and ibm.com(R) are trademarks of International Business Mac registered in many jurisdictions worldwide. Other product and service names might be trademarks of IBM or other companies. A current list of IBM trademarks is available on the Web at "Copyright and trademark information" at www.ibm.com/legal/copytrade.shtml. + From ff16de1baef8a8edc626e3ea70e02e73b6b32c54 Mon Sep 17 00:00:00 2001 From: philip r brenan Date: Tue, 19 Aug 2025 23:18:46 +0100 Subject: [PATCH 12/12] Update README.md Fixed spelling of "installing" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f744f4..a643d81 100755 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Please note you must use lsf.lsb_init before any other LSBLIB library routine in The following versions are tested: SWIG: 2.0.10, 3.0.12 - If isntalling SWIG with pip or pip3, please specify 3.0.12 version. + If installing SWIG with pip or pip3, please specify 3.0.12 version. `$ pip3 install swig==3.0.12` - Python