%global srcname primer3 %global pypiname primer3-py # The bundled libprimer3, from its own libprimer3_release() string. %global libprimer3_version 2.6.1 Name: python-%{pypiname} Version: 2.4.0 Release: 1%{?dist} Summary: Primer design and oligo thermodynamics, bound to libprimer3 License: GPL-2.0-or-later URL: https://github.com/libnano/primer3-py # GitHub tag archive rather than the PyPI sdist: the sdist omits # tests/thermo_standard_values.json, the gold-standard thermodynamic values the # four regression cases compare against. Note the tag archive's root directory # uses the hyphenated project name, not the sdist's underscored one. Source0: %{url}/archive/refs/tags/v%{version}/%{pypiname}-%{version}.tar.gz BuildRequires: python3-devel BuildRequires: pyproject-rpm-macros BuildRequires: gcc # The extension modules are Cython. BuildRequires: python3-Cython # %%check BuildRequires: python3-pytest %global _description %{expand: primer3-py binds libprimer3, the library behind Primer3, as a Python extension: design PCR primers under constraints on length, melting temperature, GC content and product size, and compute oligo thermodynamics -- hairpins, homodimers, heterodimers and end stability -- without shelling out to a command-line tool. It is packaged here because DnaChisel's primer specifications need it, and because pydna and dnacauldron both want it.} %description %_description %package -n python3-%{pypiname} Summary: %{summary} %py_provides python3-%{srcname} # libprimer3 is compiled into this package from source under # primer3/src/libprimer3/, and it cannot be unbundled. Fedora's primer3 2.4.0 # ships three programs -- primer3_core, oligotm and ntdpal -- and nothing else: # no shared library, no headers, no -devel subpackage, so there is nothing to # link against. Upstream's own ABOUT.txt also records that these sources were # "modified to make the library more amenable to Python bindings", and the copy # here is release 2.6.1 against Fedora's 2.4.0, so even a Fedora -devel would # not be a drop-in. Unbundling becomes possible only if Fedora's primer3 grows a # library, and would still need upstream to build against an unmodified one. Provides: bundled(primer3) = %{libprimer3_version} %description -n python3-%{pypiname} %_description %prep %autosetup -p1 -n %{pypiname}-%{version} # Cython~=3.3.0 (3.1.0 in 2.3.1) means >=3.3.0,<3.4.0; Fedora has 3.2.4. The pin is a build # requirement rather than a runtime one, and nothing in the generated extension # depends on a 3.1-only feature, so widen it to the major series. grep -q '"Cython~=3.3.0",' pyproject.toml || { echo "Cython pin not as expected" >&2; exit 1; } sed -i 's/"Cython~=3.3.0",/"Cython>=3.1",/' pyproject.toml %generate_buildrequires %pyproject_buildrequires %build %pyproject_wheel %install %pyproject_install %pyproject_save_files -l %{srcname} %check # The two compiled extensions have to be put back into the source tree before # the suite runs. tests/ is a package, so pytest prepends the source root to # sys.path ahead of the PYTHONPATH %%pytest sets, and "import primer3" then finds # primer3/ in the source directory -- which has the .pyx and .c sources but not # the built .so files. Every case that touches p3helpers or thermoanalysis fails # to collect. Copying the built modules across is enough; nothing is rebuilt. cp -p %{buildroot}%{python3_sitearch}/%{srcname}/p3helpers*.so %{srcname}/ cp -p %{buildroot}%{python3_sitearch}/%{srcname}/thermoanalysis*.so %{srcname}/ # Upstream's suite. Note it exercises the bundled library two ways: through the # extensions above, and by running the ntthal and oligotm programs built from the # bundled sources, comparing their output against primer3's own reference files. # Those are the bundled binaries, not Fedora's primer3. %pytest -q tests %files -n python3-%{pypiname} -f %{pyproject_files} %doc README.md %changelog * Fri Oct 23 2026 Morgan Hough - 2.4.0-1 - Update to 2.4.0 (upstream v2.4.0, 2026-10-21). libprimer3 stays 2.6.1 with post-2.6.1 fixes backported by upstream: the Owczarzy Mg2+ correction was losing its length term to integer division (Tm moves by up to several degrees for short oligos), three single-mismatch stack enthalpies were corrected, a one-byte out-of-bounds write in the loop-table parser is fixed, interval starts below PRIMER_FIRST_BASE_INDEX are clamped, and a pair-region narrowing no longer discards valid product sizes. Python 3.15 supported. Thermodynamic results can change; %%check compares against upstream's gold-standard values for this version. - The Cython pin moved to ~=3.3.0 (3.2.4 in Fedora 44); the %%prep rewrite follows it. The first Copr build failed there on every chroot. * Sun Sep 27 2026 Morgan Hough - 2.3.1-1 - Initial package: primer3-py 2.3.1. Net-new to Fedora, and the first package in this repository that is not noarch. - Bundles libprimer3 2.6.1 and declares Provides: bundled(primer3). This is not avoidable: Fedora's primer3 ships only primer3_core, oligotm and ntdpal, with no library or headers to link against, and upstream's copy is both newer than Fedora's 2.4.0 and modified for the bindings. The route to unbundling runs through a primer3-devel subpackage in Fedora that does not exist yet. - %%prep widens the Cython build pin from ~=3.1.0 to >=3.1; Fedora has 3.2.4. - Sourced from the GitHub tag. The sdist omits tests/thermo_standard_values.json, so the four thermodynamic regression cases cannot run from PyPI -- they compare computed hairpin, homodimer, heterodimer and end-stability values against upstream's recorded reference set, which is exactly the check worth keeping on a bundled numerical library. - %%check copies the two built extension modules back into the source tree first. tests/ is a package, so pytest puts the source root ahead of PYTHONPATH and imports primer3/ from there, where only the .pyx and .c sources live. - Unblocks the three DnaChisel primer tests this repository currently skips.