%global upstream_name numba %global ver_f44 0.64.0 # f45+ moves to 0.68.0: the FIRST numba release that accepts Python 3.15, which # f45 and rawhide ship. Everything at or below 0.67.0 refuses 3.15 in setup.py # ("only versions >=3.10,<3.15 are supported"), invisibly to requires_python -- # the cap is enforced at build time, so it surfaces as a %%generate_buildrequires # failure rather than as an unsatisfiable dependency. # # 0.68.0 was 0.68.0rc1 when this split was written, and carrying two release # candidates was an open question for Morgan. Upstream shipped both finals # (numba 0.68.0, llvmlite 0.50.0), so the question is moot rather than decided # and nothing here is a prerelease any more. 0.68.0 classifies Python 3.15 # explicitly and declares requires_python >=3.10 with no upper cap. # # 0.68.0 requires llvmlite >=0.50.0dev0,<0.51, which is why this repo carries # python-llvmlite 0.50.0 as an override of Fedora's 0.48.0. %global ver_f45 0.68.0 # Which Source the chroot's Version corresponds to; used by %%prep. %if 0%{?fedora} >= 45 %global srcnum 1 %else %global srcnum 0 %endif Name: python-%{upstream_name} %if 0%{?fedora} >= 45 Version: %{ver_f45} %else Version: %{ver_f44} %endif Release: 5%{?dist} Summary: NumPy-aware just-in-time compiler for Python # Two-clause: the LICENSE file carries the redistribution and binary-form # conditions and no "neither the name" clause. License: BSD-2-Clause URL: https://numba.pydata.org/ # BOTH tarballs are declared so BOTH land in the SRPM. COPR builds one SRPM for # every chroot, before %%{fedora} is known, so a conditional Version alone leaves # the f45 chroot asking for a tarball the SRPM never fetched: # error: Bad file: numba-0.66.0.tar.gz: No such file or directory # Declaring both costs one extra download and makes the SRPM valid for either. # PyPI names the file after the UPSTREAM version, which has no tilde: the rpm # version 0.68.0~rc1 corresponds to the tarball numba-0.68.0rc1.tar.gz. Strip the # tilde for the filename, exactly as Fedora's python-llvmlite does with # %%{srcversion}, or Source1 404s. %global srcver_f45 %(echo '%{ver_f45}' | tr -d '~') # Tilde-stripped form of whatever Version this chroot resolved to, for %%prep. %global srcversion %(echo '%{version}' | tr -d '~') Source0: https://files.pythonhosted.org/packages/source/n/%{upstream_name}/%{upstream_name}-%{ver_f44}.tar.gz Source1: https://files.pythonhosted.org/packages/source/n/%{upstream_name}/%{upstream_name}-%{srcver_f45}.tar.gz BuildRequires: gcc BuildRequires: gcc-c++ BuildRequires: python3-devel BuildRequires: python3-setuptools # numba is locked to exactly one llvmlite minor, and the two distro releases ship # different ones, so the numba version has to follow the release rather than be # pinned once: # f44 llvmlite 0.46.0 -> numba 0.64.0 (llvmlite >=0.46.0dev0,<0.47) # f45 llvmlite 0.48.0 -> numba 0.66.0 (llvmlite >=0.48.0dev0,<0.49) # Measured from PyPI metadata, not guessed: 0.65.x wants <0.48 and 0.67.0 wants # >=0.49, so 0.66.0 is the only release that pairs with what f45 actually ships. # Before this, the f44 pin failed on f45 with "No match for argument: # python3-llvmlite < 0.47.0". # # UNRESOLVED on f45, and llvmlite was never the binding constraint there. f45 # ships **Python 3.15**, and numba's setup.py refuses it outright: # # RuntimeError: Cannot install on Python version 3.15.0; # only versions >=3.10,<3.15 are supported. (11019730) # # That guard is in setup.py, not in the wheel metadata -- PyPI advertises every # one of these releases as ">=3.10" with no ceiling -- so it is invisible to any # check that reads requires_python. Checked the sdists directly: # # numba 0.66.0 max_python 3.15 llvmlite [0.48.0dev0, 0.49) # numba 0.67.0 max_python 3.15 llvmlite [0.49, 0.50) # numba 0.68.0rc1 max_python 3.16 llvmlite [0.50.0dev0, 0.51) # # So no *released* numba works on Python 3.15. The only combination that does is # numba 0.68.0rc1 with llvmlite 0.50.0rc3 -- two prereleases, and llvmlite is a # Fedora package currently at 0.48.0, so taking it would be an incompatible # override in the sense of docs/PACKAGING-POLICY.md. That is Morgan's call, not # a mechanical bump; until it is made, do not resubmit this package on f45. # f44 is unaffected and 0.64.0-1.fc44 is published. # NOTE THE TILDE IN THE LOWER BOUND. rpm sorts 0.50.0~rc3 BELOW 0.50.0, so a pin # written ">= 0.50.0" excludes the very prerelease this repo ships and the buildroot # reports "No match for argument: python3-llvmlite >= 0.50.0" while that package is # sitting in the repo. Verified with rpmdev-vercmp: # 0.50.0~rc3 < 0.50.0 <- why ">= 0.50.0" failed # 0.50.0~rc3 > 0.50.0~rc1 <- why ">= 0.50.0~rc1" works # The upper bound needs no tilde: 0.51.0 is above every 0.50.x including the rcs. # When llvmlite 0.50.0 final lands, this bound keeps working unchanged. # # Read out of each numba's setup.py, not guessed: 0.68.0rc1 declares # min_llvmlite_version 0.50.0dev0 / max 0.51, and 0.64.0 declares [0.46, 0.47). # The f45 window moved with the numba bump; leaving it at [0.48, 0.49) made the # buildroot refuse our own llvmlite 0.50 with "cannot install both # python3-llvmlite-0.50.0~rc3 and python3-llvmlite-0.48.0-3.fc45 from fedora". %if 0%{?fedora} >= 45 BuildRequires: python3-llvmlite >= 0.50.0~rc1 BuildRequires: python3-llvmlite < 0.51.0 %else BuildRequires: python3-llvmlite >= 0.46.0 BuildRequires: python3-llvmlite < 0.47.0 %endif # setup.py's min_numpy_build_version is 2.0.0rc1; run-time range is [1.22, 2.5). BuildRequires: python3-numpy >= 2.0.0 # Only needed so %%check can import numba.misc.dump_style, which raises # ImportError without it. Also a Recommends below: it is what makes # numba's syntax-highlighted IR dumps work. BuildRequires: python3-pygments %global _description %{expand: Numba translates a subset of Python and NumPy code into fast machine code at run time, using LLVM. Decorating a function with @jit compiles it on first call; numerical code written in plain Python and NumPy can then run at speeds comparable to C or Fortran, without rewriting it in another language.} %description %_description %package -n python3-%{upstream_name} Summary: %{summary} # numba refuses to import against an llvmlite outside its supported window, so # the runtime bound matters as much as the build one. The generated dependency # already encodes it; this is here to make the coupling visible to anyone # reading the spec before bumping either package. %if 0%{?fedora} >= 45 Requires: python3-llvmlite >= 0.50.0~rc1 Requires: python3-llvmlite < 0.51.0 %else Requires: python3-llvmlite >= 0.46.0 Requires: python3-llvmlite < 0.47.0 %endif # Optional: without it numba works, but the highlighted IR/assembly dumps # (NUMBA_DUMP_*) raise ImportError instead of printing. Recommends: python3-pygments %description -n python3-%{upstream_name} %_description %prep # Source0 is the f44 tarball and Source1 the f45 one (see the note above # Source0). %%autosetup unpacks Source0 unconditionally, so on f45 it laid down # numba-0.64.0/ and then tried to cd into numba-0.66.0/ -- "Bad exit status # from ... (%%prep)" in 11018686. -T suppresses the default unpack, -b picks # the tarball that matches the Version this chroot resolved. # %%{version} may carry a tilde (0.68.0~rc1) while the tarball's top directory does # not (numba-0.68.0rc1), so -n must use the tilde-stripped form or %%autosetup fails # with "Directory not found". %autosetup -n %{upstream_name}-%{srcversion} -p1 -T -b %{srcnum} # Relax numba's llvmlite FLOOR so a 0.50 PRERELEASE can satisfy it, on f45+ only. # # Upstream declares min_llvmlite_version = "0.50.0dev0", which # %%pyproject_buildrequires turns into the generated dependency # python3dist(llvmlite) >= 0.50 # and rpm sorts EVERY 0.50 prerelease below that: our llvmlite ships Python # metadata 0.50.0rc3, which provides python3dist(llvmlite) = 0.50~rc3, and # 0.50~rc3 < 0.50. So the generated dep is unsatisfiable by any 0.50 rc, and the # build fails with "nothing provides requested (python3dist(llvmlite) < 0.51~~ # with python3dist(llvmlite) >= 0.50)" while that llvmlite sits in the repo. # # This is a floor relaxation on evidence, the same shape as the cap relaxations in # python-fury.spec and dicomanonymizer.spec, and it is proven by a FUNCTIONAL check: # %%check below compiles a function with @njit and prints both versions, so a pass # means numba 0.68.0rc1 actually works against llvmlite 0.50.0rc3 rather than merely # resolving against it. # # DELETE THIS when llvmlite 0.50.0 final lands (expected early October 2026): the # final's metadata is 0.50.0, which satisfies >= 0.50 unchanged, and the floor # should go back to upstream's own value. %if 0%{?fedora} >= 45 sed -i 's/min_llvmlite_version = "0\.50\.0dev0"/min_llvmlite_version = "0.50.0rc1"/' setup.py grep -q 'min_llvmlite_version = "0.50.0rc1"' setup.py || \ { echo "ERROR: the llvmlite floor relaxation did not apply -- upstream changed setup.py" >&2; exit 1; } %endif # TBB is picked up implicitly if its headers happen to be in the buildroot, # which would make the set of shipped extension modules depend on what else got # pulled in. Disable it explicitly so the build is reproducible. The OpenMP and # workqueue threading layers remain; adding tbb-devel plus dropping this line is # all that enabling it would take. export NUMBA_DISABLE_TBB=1 %generate_buildrequires %pyproject_buildrequires %build export NUMBA_DISABLE_TBB=1 %pyproject_wheel %install export NUMBA_DISABLE_TBB=1 %pyproject_install %pyproject_save_files -l %{upstream_name} %check # Import every installed module, which is what proves the extension modules # loaded and the generated Requires are complete. # # Excluded, each for a reason that is not a packaging defect: # numba.cuda / numba.roc — toolkit bindings that probe for a driver at import # numba.misc.gdb_print_extension — does "import gdb", which only resolves # inside a gdb session; there is no importable gdb module on the system # numba.tests.* — the test corpus, including # pycc_distutils_usecase/setup_*.py, which are setup.py scripts that import # sibling modules only present when run from their own directory # # Keep every -e on this one line. A backslash continuation here silently drops # the continued arguments: the macro expands only what is on its own line, and # the build then fails on modules you thought you had excluded. %pyproject_check_import -e 'numba.cuda*' -e 'numba.roc*' -e 'numba.testing*' -e 'numba.tests*' -e 'numba.misc.gdb_print_extension' # Importing numba proves almost nothing on its own -- the failure mode that # matters here is an llvmlite/LLVM mismatch, which only shows up when something # is actually compiled. So compile and run one function, and check the answer. # The full suite (python -m numba.runtests) takes well over an hour and is not # appropriate for a package build. # Run from %%{_builddir} so the unbuilt source tree is not on sys.path, and point # PYTHONPATH at the buildroot: %%pyproject_check_import arranges that itself, a # bare %%{python3} does not. cd %{_builddir} PYTHONPATH=%{buildroot}%{python3_sitearch} %{python3} -c " import numba, numpy as np @numba.njit def s(a): t = 0.0 for i in range(a.size): t += a[i] ** 2 return t x = np.arange(1000, dtype=np.float64) got, want = s(x), float((x ** 2).sum()) assert abs(got - want) < 1e-6, (got, want) print('numba', numba.__version__, 'JIT ok; llvmlite', __import__('llvmlite').__version__) " %files -n python3-%{upstream_name} -f %{pyproject_files} %doc README.rst CHANGE_LOG %license LICENSES.third-party %{_bindir}/numba %changelog * Sat Oct 03 2026 Morgan Hough - 0.68.0-5 - f45+ moves from 0.68.0~rc1 to the 0.68.0 final, and python-llvmlite from 0.50.0~rc3 to 0.50.0. Both upstreams shipped finals, so the open question about shipping two release candidates is moot rather than answered. - This is what actually fixes f45-aarch64 and rawhide-aarch64, where the last build (0.66.0-3, 11019730) died in %%generate_buildrequires with "Cannot install on Python version 3.15.0; only versions >=3.10,<3.15 are supported". That cap lives in setup.py, so it is enforced at build time and never appears as an unsatisfiable dependency -- which is why the failure looked like a packaging problem rather than an upstream support gap. - Verified rather than assumed: 0.68.0 carries the "Programming Language :: Python :: 3.15" classifier and requires_python >=3.10 with no upper bound. f44 stays on 0.64.0; it ships Python 3.14 and the split exists precisely so f44 is untouched by this. * Sun Sep 27 2026 Morgan Hough - 0.68.0~rc1-4 - f45+ moves to numba 0.68.0rc1, the first release that accepts Python 3.15, with python-llvmlite 0.50.0~rc3 added to this COPR to satisfy its llvmlite >=0.50.0dev0,<0.51 requirement. Lifts the f45 hold recorded at -3. - Why this stopped being "two prereleases and a risky override": measured on 2026-09-27, NOTHING in Fedora 45 requires python3-llvmlite -- checked under three provide names with a control query proving the query works. So the override's blast radius outside this repo is zero, unlike the opencv 5 case. - What it unblocks, and why it matters: babelbrain and python3-simnibs both BUILD on f45 today and neither can be INSTALLED, because both Requires: python3-numba and numba is absent from Fedora entirely. Verified by depsolving the published rpms: 2 unsatisfied each, python3-numba and python3.15dist(numba). python-cortech is blocked on the same thing. - %%prep: %%{version} now carries a tilde while the tarball directory does not, so Source1 and %%autosetup -n use a tilde-stripped %%{srcversion}. * Mon Sep 21 2026 Morgan Hough - 0.66.0-3 - %%prep unpacked the wrong tarball on f45. The release-conditional Version and the two Sources both worked (the SRPM was python-numba-0.66.0-2.fc45), but %%autosetup always unpacks Source0, so f45 got the 0.64.0 tree and then cd'd into a numba-0.66.0 that did not exist. Select the source with -T -b. * Sun Sep 20 2026 Morgan Hough - 0.66.0-1 - Follow the distro llvmlite instead of pinning one numba. f45 ships llvmlite 0.48.0 and the f44 pin (<0.47.0) failed there outright. numba 0.66.0 is the only release requiring >=0.48.0dev0,<0.49 -- 0.65.x caps at <0.48 and 0.67.0 needs >=0.49 -- so f45 gets 0.66.0 and f44 keeps 0.64.0 against llvmlite 0.46.0. Versions read from PyPI requires_dist, not inferred. * Mon Sep 14 2026 Morgan Hough - 0.64.0-1 - Initial package. numba is absent from Fedora entirely -- there is no python-numba or numba in dist-git -- and its absence is what makes both simnibs and babelbrain uninstallable in this COPR, despite each having built green since June. - Packaged at 0.64.0 rather than the current 0.67.0 deliberately. numba is locked to a single llvmlite minor; 0.64.0 wants llvmlite [0.46, 0.47) and Fedora 44 ships exactly 0.46.0, so this needs no new dependency at all. 0.67.0 would require llvmlite >= 0.49, and llvmlite is in turn pinned to a specific LLVM, so taking the newest numba would mean carrying a two-package chain. 0.64.0 is the newest release that avoids it and still supports Python 3.14. - Disable the TBB threading layer explicitly. setup.py enables it merely if TBB headers are visible, which would let an unrelated buildroot change alter the set of shipped extension modules. - %%check compiles and runs a jitted function rather than only importing, since an llvmlite/LLVM mismatch is invisible to an import and only appears when something is actually compiled. - Build-require and recommend pygments: numba.misc.dump_style raises ImportError without it, and it is what makes the NUMBA_DUMP_* highlighted dumps work.