%global pypi_name petsc4py %global ver_f43 3.23.6 %global ver_f44 3.24.6 %global ver_f45 3.25.4 # Which Source the chroot's Version corresponds to; used by %%prep. %if 0%{?fedora} >= 45 %global srcnum 1 %elif 0%{?fedora} == 43 %global srcnum 2 %else %global srcnum 0 %endif # petsc4py tracks PETSc release-for-release: 3.24.x binds PETSc 3.24.x, so the # series has to follow whatever PETSc the distro release ships: # f43 petsc 3.23.6 -> petsc4py 3.23.6 # f44 petsc 3.24.6 -> petsc4py 3.24.6 # f45 petsc 3.25.4 -> petsc4py 3.25.4 # f43 follows its own PETSc rather than getting a 3.24 rebuild: Fedora's f43 # sundials, dolfin, getdp and bout++ link libpetsc.so.3.23, so a COPR petsc # 3.24 there would strand them on upgrade. # Before this, the f44 pin failed on f45 with "No match for argument: # petsc-devel < 3.25". %if 0%{?fedora} >= 45 %global petsc_series 3.25 %elif 0%{?fedora} == 43 %global petsc_series 3.23 %else %global petsc_series 3.24 %endif # petsc4py expects a PETSc install prefix laid out as $PETSC_DIR/include and # $PETSC_DIR/lib/petsc/conf. Fedora does not ship one: the headers live in # %%{_includedir}/petsc, not %%{_includedir}. So assemble a symlink farm that # presents the expected shape, rather than patching upstream's search logic. %global petscroot %{_builddir}/petscroot Name: python-%{pypi_name} %if 0%{?fedora} >= 45 Version: %{ver_f45} %elif 0%{?fedora} == 43 Version: %{ver_f43} %else Version: %{ver_f44} %endif Release: 4%{?dist} Summary: Python bindings for PETSc # Two-clause: LICENSE.rst carries the redistribution conditions and no # "neither the name" clause. License: BSD-2-Clause URL: https://gitlab.com/petsc/petsc4py # Both tarballs, for the same reason as python-numba: COPR builds one SRPM for # all chroots before %%{fedora} is known, so a conditional Version alone makes # the f45 chroot ask for a tarball the SRPM never fetched. Source0: https://files.pythonhosted.org/packages/source/p/%{pypi_name}/%{pypi_name}-%{ver_f44}.tar.gz Source1: https://files.pythonhosted.org/packages/source/p/%{pypi_name}/%{pypi_name}-%{ver_f45}.tar.gz Source2: https://files.pythonhosted.org/packages/source/p/%{pypi_name}/%{pypi_name}-%{ver_f43}.tar.gz BuildRequires: gcc BuildRequires: python3-devel BuildRequires: python3-setuptools BuildRequires: python3-Cython >= 3 BuildRequires: python3-numpy # Upper bound must follow petsc_series too -- it was hardcoded at 3.25, which on # f45 produced the contradiction "petsc-devel >= 3.25" AND "petsc-devel < 3.25". %if 0%{?fedora} >= 45 BuildRequires: petsc-devel >= %{petsc_series} BuildRequires: petsc-devel < 3.26 %elif 0%{?fedora} == 43 BuildRequires: petsc-devel >= %{petsc_series} BuildRequires: petsc-devel < 3.24 %else BuildRequires: petsc-devel >= %{petsc_series} BuildRequires: petsc-devel < 3.25 %endif # Fedora's petsc is built with HDF5 support, so %%{_includedir}/petsc/ # petscviewerhdf5.h does #include . petsc-devel does not require # hdf5-devel itself, so compiling anything against those headers needs it # named here or the build dies on a missing hdf5.h. BuildRequires: hdf5-devel %global _description %{expand: petsc4py exposes PETSc -- the Portable, Extensible Toolkit for Scientific Computation -- to Python: distributed vectors and matrices, linear and nonlinear solvers, preconditioners and time steppers, driven from Python rather than C.} %description %_description %package -n python3-%{pypi_name} Summary: %{summary} # No explicit petsc bound is needed here, and it is worth saying why, because the # instinct in this repo is to add one. PETSc versions its soname per release # series: the built extension records NEEDED libpetsc.so.3.24, and petsc Provides # libpetsc.so.3.24()(64bit), so the automatic dependency already pins the series # and a 3.25 PETSc simply will not satisfy it. This is the opposite of VTK here, # which freezes every 9.x at libvtk*.so.1 and therefore needs the vtk(abi) guard. %description -n python3-%{pypi_name} %_description %prep # Source0 is the f44 tarball, Source1 the f45 one and Source2 the f43 one. %%autosetup unpacks Source0 # unconditionally, so on f45 it laid down the 3.24.6 tree and then tried to cd # into petsc4py-3.25.4/ -- the %%prep failure in 11018687. -T suppresses the # default unpack, -b picks the tarball matching this chroot's Version. %autosetup -n %{pypi_name}-%{version} -p1 -T -b %{srcnum} # The PETSC_DIR shim described above. include/ points at Fedora's petsc header # directory; lib/petsc/conf reaches petscvariables; the libpetsc symlinks give # the linker something to find under $PETSC_DIR/lib. rm -rf %{petscroot} mkdir -p %{petscroot}/lib ln -sfn %{_includedir}/petsc %{petscroot}/include ln -sfn %{_libdir}/petsc %{petscroot}/lib/petsc ln -sf %{_libdir}/libpetsc.so* %{petscroot}/lib/ %generate_buildrequires # PETSC_DIR must be set HERE too, not only in %%build. setup.py adds a # dependency on the PyPI "petsc" distribution -- which bundles and builds PETSc # itself -- for any package in its list whose _DIR is not a valid # directory. Without this export the generated BuildRequires asks for # python3dist(petsc), which Fedora's system PETSc does not provide and nothing # can satisfy. With it, upstream skips that dependency, which is precisely the # escape hatch intended for building against an existing PETSc. export PETSC_DIR=%{petscroot} export PETSC_ARCH= %pyproject_buildrequires %build # petsc4py locates PETSc through $PETSC_DIR/lib/petsc/conf/petscvariables. # Fedora installs that as /usr/lib/petsc/conf/petscvariables, so PETSC_DIR is # the prefix, and PETSC_ARCH is empty for a distro (non-in-tree) build. export PETSC_DIR=%{petscroot} export PETSC_ARCH= %pyproject_wheel %install export PETSC_DIR=%{petscroot} export PETSC_ARCH= %pyproject_install %pyproject_save_files -l %{pypi_name} %check export PETSC_DIR=%{petscroot} export PETSC_ARCH= # Importing is not enough. The failure this package can actually have is a # mismatch against the PETSc it links, which only shows up once the library is # initialised and something is computed -- so initialise PETSc, build a vector # and check the arithmetic. cd %{_builddir} PYTHONPATH=%{buildroot}%{python3_sitearch} %{python3} -c " import petsc4py petsc4py.init([]) from petsc4py import PETSc v = PETSc.Vec().createSeq(10) v.set(2.0) got = v.sum() assert abs(got - 20.0) < 1e-9, got print('petsc4py', petsc4py.__version__, 'ok; PETSc', '.'.join(map(str, PETSc.Sys.getVersion()))) " %files -n python3-%{pypi_name} -f %{pyproject_files} %doc README.rst CHANGES.rst %license LICENSE.rst %changelog * Sat Oct 10 2026 Morgan Hough - 3.25.4-4 - f43: build petsc4py 3.23.6 against Fedora's own petsc 3.23.6 (Source2), following the distro PETSc as f44 and f45 already do. Rebuilding petsc 3.24 for f43 instead would strand Fedora's sundials, dolfin, getdp and bout++, which link libpetsc.so.3.23. * Mon Sep 21 2026 Morgan Hough - 3.25.4-3 - %%prep unpacked the wrong tarball on f45: %%autosetup always unpacks Source0, so the f45 chroot got the 3.24.6 tree under a 3.25.4 Version. Select the source with -T -b. * Sun Sep 20 2026 Morgan Hough - 3.25.4-2 - Follow the distro PETSc instead of pinning one series. f45 ships petsc 3.25.4 and the f44 pin failed there with "No match for argument: petsc-devel < 3.25". petsc4py binds PETSc release-for-release, so f45 now builds 3.25.4 and f44 keeps 3.24.6. * Mon Sep 14 2026 Morgan Hough - 3.24.6-1 - Initial package. petsc4py is the last thing standing between simnibs and being installable: simnibs/simulation/fem.py does an unconditional "from petsc4py import PETSc", and simnibs/__init__.py imports that module, so without it "import simnibs" fails outright -- every CLI tool included, not merely the FEM solver. There is no scipy fallback, so demoting the dependency would produce a package that installs and cannot be used. - Fedora has no petsc4py. It was retired as a standalone package ("Obsoleted by petsc since 3.14.2-3"), but Fedora's petsc ships no Python bindings subpackage, so that obsoletion points at nothing and the dependency is unsatisfiable by anything in the distribution. - Pinned to 3.24.6 to match Fedora 44's petsc 3.24.6 exactly; petsc4py tracks PETSc release-for-release. - No explicit petsc version bound, deliberately. PETSc versions its soname per series -- the extension records NEEDED libpetsc.so.3.24 -- so the automatic dependency already keeps a 3.25 PETSc from satisfying it. Unlike VTK here, which freezes all of 9.x at libvtk*.so.1 and needs the vtk(abi) guard. - %%check initialises PETSc and computes with a vector rather than only importing, since a library mismatch is invisible to an import. - Export PETSC_DIR in %%generate_buildrequires as well as %%build: setup.py otherwise adds a dependency on the PyPI "petsc" distribution, which builds PETSc from source and which nothing in Fedora provides. - Build against a symlink farm rather than %%{_prefix}. petsc4py wants $PETSC_DIR/include/petscversion.h, and Fedora puts its headers in %%{_includedir}/petsc, so pointing PETSC_DIR at /usr fails the version probe. - BuildRequire hdf5-devel: Fedora's petsc is built with HDF5, its installed headers include , and petsc-devel does not pull hdf5-devel in.