Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions .github/workflows/pyslurm.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: PySlurm

env:
SLURM_DOCKER_IMAGE: giovtorres/slurm-docker:25.11.2
SLURM_DOCKER_IMAGE: giovtorres/slurm-docker:25.11.4-rl10

on:
push:
Expand All @@ -17,15 +17,22 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version:
- "3.12"
include:
- slurm-image: giovtorres/slurm-docker:25.11.4-rl10
python-version: "3.12"
- slurm-image: giovtorres/slurm-docker:25.11.4-rl9
python-version: "3.9"
- slurm-image: giovtorres/slurm-docker:25.11.4-rl8
python-version: "3.6"
fail-fast: false
env:
SLURM_DOCKER_IMAGE: ${{ matrix.slurm-image }}
steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Pull Slurm container
run: docker pull ${{ env.SLURM_DOCKER_IMAGE }}
run: docker pull ${{ matrix.slurm-image }}

- name: Start Slurm container
run: docker compose up -d
Expand Down
5 changes: 4 additions & 1 deletion pyslurm.spec
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Name: python-pyslurm
Version: 25.11.0
Version: 25.11.2
%define rel 1
Release: %{rel}%{?dist}
Summary: Python interface to Slurm
Expand Down Expand Up @@ -39,5 +39,8 @@ pyslurm is a Python interface to Slurm
%doc README.md

%changelog
* Sat Apr 12 2026 Giovanni Torres <giovtorres@users.noreply.github.com> - 25.11.2-1
- Fix Python 3.6 package metadata (UNKNOWN-0.0.0) by reading version from setup.py

* Sun Mar 22 2026 Giovanni Torres <giovtorres@users.noreply.github.com> - 25.11.0-1
- Initial package
6 changes: 5 additions & 1 deletion pyslurm/core/job/submission.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,11 @@ def _validate_cpu_freq(freq):


def _validate_batch_script(script, args=None):
if Path(script).is_file():
try:
_is_file = Path(script).is_file()
except (ValueError, OSError):
_is_file = False
if _is_file:
# First assume the caller is passing a path to a script and we try
# to load it.
script = Path(script).read_text()
Expand Down
9 changes: 5 additions & 4 deletions pyslurm/slurm/extra.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ cdef extern from *:
ctypedef struct conmgr_fd_t


# https://github.com/SchedMD/slurm/blob/slurm-24-11-0-1/src/common/slurm_protocol_defs.h#L286
# https://github.com/SchedMD/slurm/blob/slurm-25-11-4-1/src/common/slurm_protocol_defs.h
ctypedef struct slurm_msg_t:
slurm_addr_t address
void *auth_cred
Expand All @@ -115,13 +115,14 @@ ctypedef struct slurm_msg_t:
bool restrict_uid_set
uint32_t body_offset
buf_t *buffer
persist_conn_t *conn
conmgr_fd_t *conmgr_fd
void *pcon
void *conmgr_con
void *data
uint16_t flags
uint8_t hash_index
char *tls_cert
void *tls_conn
void *conn
bool conn_is_mtls
uint16_t msg_type
uint16_t protocol_version
forward_t forward
Expand Down
2 changes: 1 addition & 1 deletion pyslurm/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
# The last Number "Z" is the current Pyslurm patch version, which should be
# incremented each time a new release is made (except when migrating to a new
# Slurm Major release, then set it back to 0)
__version__ = "25.11.0"
__version__ = "25.11.2"
8 changes: 4 additions & 4 deletions pyslurm/xcollections.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ cdef class MultiClusterMap:
elif isinstance(other, dict):
out = self.copy()
for cluster, data in self._iter_clusters_dict(other):
out.data[cluster] = self.data[cluster] | data
out.data[cluster] = {**self.data[cluster], **data}
return out
return NotImplemented

Expand All @@ -354,7 +354,7 @@ cdef class MultiClusterMap:
elif isinstance(other, dict):
out = self.copy()
for cluster, data in self._iter_clusters_dict(other):
out.data[cluster] = data | self.data[cluster]
out.data[cluster] = {**data, **self.data[cluster]}
return out
return NotImplemented

Expand All @@ -363,10 +363,10 @@ cdef class MultiClusterMap:
for cluster in other.clusters():
if not cluster in self.data:
self.data[cluster] = {}
self.data[cluster] |= other.data[cluster]
self.data[cluster].update(other.data[cluster])
else:
for cluster, data in self._iter_clusters_dict(other):
self.data[cluster] |= data
self.data[cluster].update(data)
return self

def copy(self):
Expand Down
1 change: 1 addition & 0 deletions scripts/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ if [ "$SKIP_BUILD" = false ]; then
docker exec "$CONTAINER_NAME" bash -c "
python3 -m venv $VENV_PATH 2>/dev/null || true
source $VENV_PATH/bin/activate
python3 -m pip install -q --upgrade pip
pip install -q --disable-pip-version-check -r /pyslurm/test_requirements.txt
cd /pyslurm
scripts/build.sh -j $BUILD_JOBS -d
Expand Down
56 changes: 37 additions & 19 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import os
import sys
from pathlib import Path
from setuptools import setup, Extension
from setuptools import find_packages, setup, Extension

try:
from packaging.version import Version
Expand All @@ -16,22 +16,25 @@
SLURM_LIB = "libslurmfull"


def get_slurm_version():
def get_version_string():
with (TOPDIR / "pyslurm/version.py").open() as f:
for line in f.read().splitlines():
if line.startswith("__version__"):
V = Version(line.split('"')[1])
if not hasattr(V, "major") or not hasattr(V, "minor"):
(V.major, V.minor) = V._version.release[0:2]
return f"{V.major}.{V.minor}"
return line.split('"')[1]
raise RuntimeError("Cannot get version string.")


SLURM_VERSION = get_slurm_version()
def get_slurm_version():
V = Version(get_version_string())
if not hasattr(V, "major") or not hasattr(V, "minor"):
(V.major, V.minor) = V._version.release[0:2]
return f"{V.major}.{V.minor}"


class SlurmConfig():
SLURM_VERSION = get_slurm_version()


class SlurmConfig:
def __init__(self):
self._lib_dir = Path("/usr/lib64")
self._lib = None
Expand Down Expand Up @@ -69,8 +72,9 @@ def lib_dir(self, path):

if not self._lib:
searched = "\n- ".join(self._lib_dir_search_paths)
raise RuntimeError("Cannot locate Slurm library. Searched paths: "
f"\n- {searched}")
raise RuntimeError(
f"Cannot locate Slurm library. Searched paths: \n- {searched}"
)

@property
def inc_full_dir(self):
Expand All @@ -96,7 +100,7 @@ def check_version(self):
for line in f:
if line.find("#define SLURM_VERSION_NUMBER") == 0:
self._version = line.split(" ")[2].strip()
print("Detected Slurm version - "f"{self.version}")
print(f"Detected Slurm version - {self.version}")

if not self._version:
raise RuntimeError("Unable to detect Slurm version")
Expand All @@ -112,9 +116,7 @@ def check_version(self):


def find_files_with_extension(path, extensions):
files = [p
for p in Path(path).glob("**/*")
if p.suffix in extensions]
files = [p for p in Path(path).glob("**/*") if p.suffix in extensions]
return files


Expand Down Expand Up @@ -152,7 +154,6 @@ def parse_slurm_args():
def cythongen():
print("Cythonizing sources...")
try:
from Cython.Distutils import build_ext
from Cython.Build import cythonize
from Cython.Compiler.Version import version as cython_version
except ImportError as e:
Expand All @@ -177,9 +178,18 @@ def parse_setuppy_commands():
cleanup_build()
return False

build_cmd = ('build', 'build_ext', 'build_py', 'build_clib',
'build_scripts', 'bdist_wheel', 'build_src', 'bdist_egg',
'develop', 'editable_wheel')
build_cmd = (
"build",
"build_ext",
"build_py",
"build_clib",
"build_scripts",
"bdist_wheel",
"build_src",
"bdist_egg",
"develop",
"editable_wheel",
)

for cmd in build_cmd:
if cmd == args[0]:
Expand All @@ -202,7 +212,15 @@ def setup_package():
slurm.check_version()
ext_modules = get_extensions()

setup(ext_modules=ext_modules)
setup(
name="pyslurm",
version=get_version_string(),
packages=find_packages(
include=["pyslurm*"],
exclude=["pyslurm.pydefines", "pyslurm.slurm"],
),
ext_modules=ext_modules,
)


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion test_requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pytest>=8.0
pytest>=7.0
setuptools>=59.2.0
wheel>=0.37.0
Cython>=0.29.37
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/test_reservation.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def test_create_instance():
assert resv.duration == 2 * 60 * 24
assert resv.end_time == resv.start_time + (2 * 60 * 60 * 24)

start = datetime.fromisoformat("2022-04-03T06:00:00")
start = datetime(2022, 4, 3, 6, 0, 0)
end = resv.end_time
resv.start_time = int(start.timestamp())

Expand Down