diff --git a/.gitignore b/.gitignore index e5784971e9df..e91532cd62ff 100644 --- a/.gitignore +++ b/.gitignore @@ -234,3 +234,5 @@ numpy/core/src/umath/loops_autovec.dispatch.c # multiarray module numpy/core/src/multiarray/argfunc.dispatch.c numpy/core/src/multiarray/arraytypes.h + +.pybuild/ diff --git a/LICENSE.txt b/LICENSE.txt index 014d51c98dfa..2dfbf61c056e 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -28,3 +28,27 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +The NumPy repository and source distributions bundle several libraries that are +compatibly licensed. We list these here. + +Name: lapack-lite +Files: numpy/linalg/lapack_lite/* +License: BSD-3-Clause + For details, see numpy/linalg/lapack_lite/LICENSE.txt + +Name: tempita +Files: tools/npy_tempita/* +License: MIT + For details, see tools/npy_tempita/license.txt + +Name: dragon4 +Files: numpy/core/src/multiarray/dragon4.c +License: MIT + For license text, see numpy/core/src/multiarray/dragon4.c + +Name: libdivide +Files: numpy/core/include/numpy/libdivide/* +License: Zlib + For license text, see numpy/core/include/numpy/libdivide/LICENSE.txt diff --git a/debian/.gitignore b/debian/.gitignore new file mode 100644 index 000000000000..1da6a4de8c8a --- /dev/null +++ b/debian/.gitignore @@ -0,0 +1,7 @@ +*.substvars +*debhelper* +.debhelper +files +python3-numpy +python-numpy-doc +tmp diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 000000000000..f3967a01119b --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +python-numpy (100:1.25.2-1) UNRELEASED; urgency=medium + + * https://github.com/numpy/numpy/releases/tag/v1.25.2 + + -- Wong Hoi Sing Edison Sun, 24 Dec 2023 23:47:25 +0800 diff --git a/debian/control b/debian/control new file mode 100644 index 000000000000..46bb769bbca2 --- /dev/null +++ b/debian/control @@ -0,0 +1,53 @@ +Source: python-numpy +Section: python +Priority: optional +Standards-Version: 4.5.0 +Maintainer: Wong Hoi Sing Edison +Homepage: https://github.com/numpy/numpy/tags +Vcs-Browser: https://github.com/alvistack/numpy-numpy +Vcs-Git: https://github.com/alvistack/numpy-numpy.git +Build-Depends: + debhelper, + debhelper-compat (= 10), + dh-python, + cython3, + fdupes, + gfortran, + liblapack-dev, + libopenblas-dev, + python3-dev, + python3-numpy , + python3-setuptools, + +Package: python3-numpy +Architecture: amd64 +Description: Fast array facility to the Python 3 language + Numpy contains a powerful N-dimensional array object, sophisticated + (broadcasting) functions, tools for integrating C/C++ and Fortran code, + and useful linear algebra, Fourier transform, and random number + capabilities. +Depends: + ${misc:Depends}, + ${shlibs:Depends}, + python3, + python3-pkg-resources, +Suggests: + gcc, + gfortran, + python-numpy-doc, + python3-dev, + python3-pytest, +Provides: + ${numpy3:Provides}, + ${python3:Provides}, + dh-sequence-numpy3, + python3-f2py, + python3-numpy-dev, + +Package: python-numpy-doc +Section: doc +Architecture: all +Description: NumPy documentation + This package contains documentation for Numpy and f2py. +Depends: + ${misc:Depends}, diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 000000000000..12900b4193ce --- /dev/null +++ b/debian/copyright @@ -0,0 +1,21 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ + +Files: debian/* +Copyright: 2024 Wong Hoi Sing Edison +License: Apache-2.0 + +License: Apache-2.0 + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + . + http://www.apache.org/licenses/LICENSE-2.0 + . + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + . + The complete text of the Apache version 2.0 license + can be found in "/usr/share/common-licenses/Apache-2.0". diff --git a/debian/dh_numpy3 b/debian/dh_numpy3 new file mode 100644 index 000000000000..8af6e983fcf1 --- /dev/null +++ b/debian/dh_numpy3 @@ -0,0 +1,58 @@ +#!/usr/bin/perl -w + +# Copyright © 2010 Piotr Ożarowski +# Copyright © 2012 Jakub Wilk +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +use strict; +use Debian::Debhelper::Dh_Lib; + +init(options => { + "strict" => \$dh{STRICT}, +}); + +my %data; + +open(FILE, '<', '/usr/share/numpy3/versions') or error("cannot read version data: $!\n"); +while () { + chomp; + next unless /^[^#]/; + my ($key, $value) = split; + $data{$key} = $value; +} +close FILE; + +unless ($data{'abi'} and $data{'api'} and $data{'api-min-version'}) { + error("cannot parse version data file"); +} + +foreach my $package (@{$dh{DOPACKAGES}}) { + my $numpy_dep; + if (package_arch($package) eq 'all') { + $numpy_dep = 'python3-numpy'; + } elsif ($dh{STRICT}) { + $numpy_dep = "python3-numpy-api$data{'api'}"; + } else { + $numpy_dep = "python3-numpy (>= $data{'api-min-version'}), python3-numpy-abi$data{'abi'}"; + } + addsubstvar($package, "python3:Depends", $numpy_dep); +} + +exit 0 diff --git a/debian/dh_numpy3.1 b/debian/dh_numpy3.1 new file mode 100644 index 000000000000..0fadecd50abf --- /dev/null +++ b/debian/dh_numpy3.1 @@ -0,0 +1,15 @@ +.TH DH_NUMPY3 1 "2012-01-29" "Numpy" +.SH NAME +dh_numpy3 \- adds Numpy depends to python:Depends substvar +.SH SYNOPSIS +\fBdh_numpy3\fR [\fIdebhelper\ options\fR] +.SH DESCRIPTION +dh_numpy3 adds information about the correct versioned depends on python3-numpy to python3:Depends substvar. +.PP +This is needed because some Python extensions require strict versioned depends on python3-numpy, and using this helper script is the easiest and most consistent way to get them. +.PP +The helper script uses the information stored in /usr/share/numpy3/versions, and the architecture type of the package, to generate the Depends information; for a detailed description of how the dependencies are generated, please refer to /usr/share/doc/python3-numpy/README.DebianMaints . +.SH "SEE ALSO" +\fIdebhelper\fR(7) +.PP +This program is not a part of debhelper (and it's provided by python-numpy). diff --git a/debian/numpy3.pm b/debian/numpy3.pm new file mode 100644 index 000000000000..e3c2f9e4d6f3 --- /dev/null +++ b/debian/numpy3.pm @@ -0,0 +1,8 @@ +#!/usr/bin/perl +use warnings; +use strict; +use Debian::Debhelper::Dh_Lib; + +insert_before("dh_gencontrol", "dh_numpy3"); + +1 diff --git a/debian/python-numpy-doc.lintian-overrides b/debian/python-numpy-doc.lintian-overrides new file mode 100644 index 000000000000..06954a567497 --- /dev/null +++ b/debian/python-numpy-doc.lintian-overrides @@ -0,0 +1,3 @@ +python-numpy-doc: copyright-without-copyright-notice +python-numpy-doc: initial-upload-closes-no-bugs +python-numpy-doc: zero-byte-file-in-doc-directory diff --git a/debian/python3-numpy.install b/debian/python3-numpy.install new file mode 100644 index 000000000000..02662563c870 --- /dev/null +++ b/debian/python3-numpy.install @@ -0,0 +1,5 @@ +debian/dh_numpy3 usr/bin +debian/numpy3.pm usr/share/perl5/Debian/Debhelper/Sequence/ +debian/versions usr/share/numpy3/ +usr/bin/* +usr/lib/python*/*-packages/* diff --git a/debian/python3-numpy.lintian-overrides b/debian/python3-numpy.lintian-overrides new file mode 100644 index 000000000000..7f9f57347aca --- /dev/null +++ b/debian/python3-numpy.lintian-overrides @@ -0,0 +1,8 @@ +python3-numpy: copyright-without-copyright-notice +python3-numpy: initial-upload-closes-no-bugs +python3-numpy: missing-prerequisite-for-gfortran-module +python3-numpy: no-manual-page +python3-numpy: python-module-in-wrong-location +python3-numpy: shared-library-lacks-prerequisites +python3-numpy: unusual-interpreter +python3-numpy: zero-byte-file-in-doc-directory diff --git a/debian/rules b/debian/rules new file mode 100755 index 000000000000..95e541ca2cfd --- /dev/null +++ b/debian/rules @@ -0,0 +1,51 @@ +#!/usr/bin/make -f + +SHELL := /bin/bash + +export DH_VERBOSE=1 + +PY3VERS=$(shell py3versions -vr) +PY3DEF=$(shell py3versions -dv) +PY3LIBPATH := $(shell python3 -c "from distutils.command.build import build ; from distutils.core import Distribution ; b = build(Distribution()) ; b.finalize_options() ; print (b.build_platlib)") + +# Look at #634012 to understand why is needed and what will happen if we set +# compat to 9 +unexport LDFLAGS +export ATLAS=None + +# https://github.com/numpy/numpy/pull/20695 +export NPY_DISABLE_SVML=1 + +%: + dh $@ --with python3 --buildsystem=pybuild + +override_dh_auto_clean: + +override_dh_installman: + dh_installman -ppython-numpy-doc debian/dh_numpy3.1 + +override_dh_install: + # install numpy.i into the include directory + cp -a tools/swig/numpy.i debian/tmp/usr/lib/python$(PY3DEF)/dist-packages/numpy/core/include/numpy + + dh_install + + # create symlinks for .h files + set -e; for i in $(PY3DEF); do \ + ABITAG=`python$$i -c "import sys; print(sys.abiflags)"`; \ + [ -d $(CURDIR)/debian/python3-numpy/usr/include/python$$i$$ABITAG ] || \ + mkdir -p $(CURDIR)/debian/python3-numpy/usr/include/python$$i$$ABITAG; \ + dh_link -ppython3-numpy usr/lib/python3/dist-packages/numpy/core/include/numpy usr/include/python$$i$$ABITAG/numpy; \ + done + +override_dh_gencontrol: + python3 debian/versions3.helper >> debian/python3-numpy.substvars + dh_gencontrol + +override_dh_auto_test: + +override_dh_auto_install: + dh_auto_install + + # Install for Python 3 + python3 setup.py install --root=$(CURDIR)/debian/tmp --install-layout=deb; \ diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 000000000000..163aaf8d82b6 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/source/lintian-overrides b/debian/source/lintian-overrides new file mode 100644 index 000000000000..1f057dbec289 --- /dev/null +++ b/debian/source/lintian-overrides @@ -0,0 +1,5 @@ +python-numpy source: file-without-copyright-information +python-numpy source: no-debian-changes +python-numpy source: source-contains-prebuilt-windows-binary +python-numpy source: source-is-missing +python-numpy source: source-package-encodes-python-version diff --git a/debian/versions b/debian/versions new file mode 100644 index 000000000000..477d49506152 --- /dev/null +++ b/debian/versions @@ -0,0 +1,15 @@ +# ABI version. +# This number must be changed every time C_ABI_VERSION changes. +# It's should be normally equal to C_ABI_VERSION - 0x1000000. +# Check numpy/core/setup_common.py +abi 9 + +# Minor API version. +# This number must be changed every time C_API_VERSION changes. +# It's should be normally equal to C_API_VERSION. +# Description of the changes at numpy/core/code_generators/cversions.txt +api 16 + +# Minimum version of Numpy that shares this minor API version. +# This version must be updated every time C_API_VERSION changes. +api-min-version 1:1.23.0 diff --git a/debian/versions3.helper b/debian/versions3.helper new file mode 100644 index 000000000000..cb3b42c70754 --- /dev/null +++ b/debian/versions3.helper @@ -0,0 +1,24 @@ +#!/usr/bin/python + +''' +Check if debian/versions is sane and generate substvars for numpy:Provides. +''' + +import os + +def main(): + data = {} + file = open('debian/versions', 'r') + try: + for line in file: + line = line.strip() + if not line or line.startswith('#'): + continue + key, value = line.split(None, 1) + data[key] = value + finally: + file.close() + print('numpy3:Provides=python3-numpy-abi%s, python3-numpy-api%s' % (data['abi'], data['api'])) + +if __name__ == '__main__': + main() diff --git a/numpy/_version.py b/numpy/_version.py index 565eb317bf17..27510850787b 100644 --- a/numpy/_version.py +++ b/numpy/_version.py @@ -1,658 +1,21 @@ -# This file helps to compute a version number in source trees obtained from -# git-archive tarball (such as those provided by githubs download-from-tag -# feature). Distribution tarballs (built by setup.py sdist) and build -# directories (produced by setup.py build) will contain a much shorter file -# that just contains the computed version number. +# This file was generated by 'versioneer.py' (0.26) from +# revision-control system data, or from the parent directory name of an +# unpacked source archive. Distribution tarballs contain a pre-generated copy +# of this file. -# This file is released into the public domain. -# Generated by versioneer-0.26 -# https://github.com/python-versioneer/python-versioneer +import json -"""Git implementation of _version.py.""" - -import errno -import os -import re -import subprocess -import sys -from typing import Callable, Dict -import functools - - -def get_keywords(): - """Get the keywords needed to look up the version information.""" - # these strings will be replaced by git during git-archive. - # setup.py/versioneer.py will grep for the variable names, so they must - # each be defined on a line of their own. _version.py will just call - # get_keywords(). - git_refnames = "$Format:%d$" - git_full = "$Format:%H$" - git_date = "$Format:%ci$" - keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} - return keywords - - -class VersioneerConfig: - """Container for Versioneer configuration parameters.""" - - -def get_config(): - """Create, populate and return the VersioneerConfig() object.""" - # these strings are filled in when 'setup.py versioneer' creates - # _version.py - cfg = VersioneerConfig() - cfg.VCS = "git" - cfg.style = "pep440" - cfg.tag_prefix = "v" - cfg.parentdir_prefix = "numpy-" - cfg.versionfile_source = "numpy/_version.py" - cfg.verbose = False - return cfg - - -class NotThisMethod(Exception): - """Exception raised if a method is not valid for the current scenario.""" - - -LONG_VERSION_PY: Dict[str, str] = {} -HANDLERS: Dict[str, Dict[str, Callable]] = {} - - -def register_vcs_handler(vcs, method): # decorator - """Create decorator to mark a method as the handler of a VCS.""" - def decorate(f): - """Store f in HANDLERS[vcs][method].""" - if vcs not in HANDLERS: - HANDLERS[vcs] = {} - HANDLERS[vcs][method] = f - return f - return decorate - - -def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, - env=None): - """Call the given command(s).""" - assert isinstance(commands, list) - process = None - - popen_kwargs = {} - if sys.platform == "win32": - # This hides the console window if pythonw.exe is used - startupinfo = subprocess.STARTUPINFO() - startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW - popen_kwargs["startupinfo"] = startupinfo - - for command in commands: - try: - dispcmd = str([command] + args) - # remember shell=False, so use git.cmd on windows, not just git - process = subprocess.Popen([command] + args, cwd=cwd, env=env, - stdout=subprocess.PIPE, - stderr=(subprocess.PIPE if hide_stderr - else None), **popen_kwargs) - break - except OSError: - e = sys.exc_info()[1] - if e.errno == errno.ENOENT: - continue - if verbose: - print("unable to run %s" % dispcmd) - print(e) - return None, None - else: - if verbose: - print("unable to find command, tried %s" % (commands,)) - return None, None - stdout = process.communicate()[0].strip().decode() - if process.returncode != 0: - if verbose: - print("unable to run %s (error)" % dispcmd) - print("stdout was %s" % stdout) - return None, process.returncode - return stdout, process.returncode - - -def versions_from_parentdir(parentdir_prefix, root, verbose): - """Try to determine the version from the parent directory name. - - Source tarballs conventionally unpack into a directory that includes both - the project name and a version string. We will also support searching up - two directory levels for an appropriately named parent directory - """ - rootdirs = [] - - for _ in range(3): - dirname = os.path.basename(root) - if dirname.startswith(parentdir_prefix): - return {"version": dirname[len(parentdir_prefix):], - "full-revisionid": None, - "dirty": False, "error": None, "date": None} - rootdirs.append(root) - root = os.path.dirname(root) # up a level - - if verbose: - print("Tried directories %s but none started with prefix %s" % - (str(rootdirs), parentdir_prefix)) - raise NotThisMethod("rootdir doesn't start with parentdir_prefix") - - -@register_vcs_handler("git", "get_keywords") -def git_get_keywords(versionfile_abs): - """Extract version information from the given file.""" - # the code embedded in _version.py can just fetch the value of these - # keywords. When used from setup.py, we don't want to import _version.py, - # so we do it with a regexp instead. This function is not used from - # _version.py. - keywords = {} - try: - with open(versionfile_abs, "r") as fobj: - for line in fobj: - if line.strip().startswith("git_refnames ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["refnames"] = mo.group(1) - if line.strip().startswith("git_full ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["full"] = mo.group(1) - if line.strip().startswith("git_date ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["date"] = mo.group(1) - except OSError: - pass - return keywords - - -@register_vcs_handler("git", "keywords") -def git_versions_from_keywords(keywords, tag_prefix, verbose): - """Get version information from git keywords.""" - if "refnames" not in keywords: - raise NotThisMethod("Short version file found") - date = keywords.get("date") - if date is not None: - # Use only the last line. Previous lines may contain GPG signature - # information. - date = date.splitlines()[-1] - - # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant - # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 - # -like" string, which we must then edit to make compliant), because - # it's been around since git-1.5.3, and it's too difficult to - # discover which version we're using, or to work around using an - # older one. - date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) - refnames = keywords["refnames"].strip() - if refnames.startswith("$Format"): - if verbose: - print("keywords are unexpanded, not using") - raise NotThisMethod("unexpanded keywords, not a git-archive tarball") - refs = {r.strip() for r in refnames.strip("()").split(",")} - # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of - # just "foo-1.0". If we see a "tag: " prefix, prefer those. - TAG = "tag: " - tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} - if not tags: - # Either we're using git < 1.8.3, or there really are no tags. We use - # a heuristic: assume all version tags have a digit. The old git %d - # expansion behaves like git log --decorate=short and strips out the - # refs/heads/ and refs/tags/ prefixes that would let us distinguish - # between branches and tags. By ignoring refnames without digits, we - # filter out many common branch names like "release" and - # "stabilization", as well as "HEAD" and "master". - tags = {r for r in refs if re.search(r'\d', r)} - if verbose: - print("discarding '%s', no digits" % ",".join(refs - tags)) - if verbose: - print("likely tags: %s" % ",".join(sorted(tags))) - for ref in sorted(tags): - # sorting will prefer e.g. "2.0" over "2.0rc1" - if ref.startswith(tag_prefix): - r = ref[len(tag_prefix):] - # Filter out refs that exactly match prefix or that don't start - # with a number once the prefix is stripped (mostly a concern - # when prefix is '') - if not re.match(r'\d', r): - continue - if verbose: - print("picking %s" % r) - return {"version": r, - "full-revisionid": keywords["full"].strip(), - "dirty": False, "error": None, - "date": date} - # no suitable tags, so version is "0+unknown", but full hex is still there - if verbose: - print("no suitable tags, using unknown + full revision id") - return {"version": "0+unknown", - "full-revisionid": keywords["full"].strip(), - "dirty": False, "error": "no suitable tags", "date": None} - - -@register_vcs_handler("git", "pieces_from_vcs") -def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command): - """Get version from 'git describe' in the root of the source tree. - - This only gets called if the git-archive 'subst' keywords were *not* - expanded, and _version.py hasn't already been rewritten with a short - version string, meaning we're inside a checked out source tree. - """ - GITS = ["git"] - if sys.platform == "win32": - GITS = ["git.cmd", "git.exe"] - - # GIT_DIR can interfere with correct operation of Versioneer. - # It may be intended to be passed to the Versioneer-versioned project, - # but that should not change where we get our version from. - env = os.environ.copy() - env.pop("GIT_DIR", None) - runner = functools.partial(runner, env=env) - - _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, - hide_stderr=not verbose) - if rc != 0: - if verbose: - print("Directory %s not under git control" % root) - raise NotThisMethod("'git rev-parse --git-dir' returned error") - - # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] - # if there isn't one, this yields HEX[-dirty] (no NUM) - describe_out, rc = runner(GITS, [ - "describe", "--tags", "--dirty=", "--always", "--long", - "--match", f"{tag_prefix}[[:digit:]]*" - ], cwd=root) - # --long was added in git-1.5.5 - if describe_out is None: - raise NotThisMethod("'git describe' failed") - describe_out = describe_out.strip() - full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) - if full_out is None: - raise NotThisMethod("'git rev-parse' failed") - full_out = full_out.strip() - - pieces = {} - pieces["long"] = full_out - pieces["short"] = full_out[:7] # maybe improved later - pieces["error"] = None - - branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], - cwd=root) - # --abbrev-ref was added in git-1.6.3 - if rc != 0 or branch_name is None: - raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") - branch_name = branch_name.strip() - - if branch_name == "HEAD": - # If we aren't exactly on a branch, pick a branch which represents - # the current commit. If all else fails, we are on a branchless - # commit. - branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) - # --contains was added in git-1.5.4 - if rc != 0 or branches is None: - raise NotThisMethod("'git branch --contains' returned error") - branches = branches.split("\n") - - # Remove the first line if we're running detached - if "(" in branches[0]: - branches.pop(0) - - # Strip off the leading "* " from the list of branches. - branches = [branch[2:] for branch in branches] - if "master" in branches: - branch_name = "master" - elif not branches: - branch_name = None - else: - # Pick the first branch that is returned. Good or bad. - branch_name = branches[0] - - pieces["branch"] = branch_name - - # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] - # TAG might have hyphens. - git_describe = describe_out - - # look for -dirty suffix - dirty = git_describe.endswith("-dirty") - pieces["dirty"] = dirty - if dirty: - git_describe = git_describe[:git_describe.rindex("-dirty")] - - # now we have TAG-NUM-gHEX or HEX - - if "-" in git_describe: - # TAG-NUM-gHEX - mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) - if not mo: - # unparsable. Maybe git-describe is misbehaving? - pieces["error"] = ("unable to parse git-describe output: '%s'" - % describe_out) - return pieces - - # tag - full_tag = mo.group(1) - if not full_tag.startswith(tag_prefix): - if verbose: - fmt = "tag '%s' doesn't start with prefix '%s'" - print(fmt % (full_tag, tag_prefix)) - pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" - % (full_tag, tag_prefix)) - return pieces - pieces["closest-tag"] = full_tag[len(tag_prefix):] - - # distance: number of commits since tag - pieces["distance"] = int(mo.group(2)) - - # commit: short hex revision ID - pieces["short"] = mo.group(3) - - else: - # HEX: no tags - pieces["closest-tag"] = None - out, rc = runner(GITS, ["rev-list", "HEAD", "--left-right"], cwd=root) - pieces["distance"] = len(out.split()) # total number of commits - - # commit date: see ISO-8601 comment in git_versions_from_keywords() - date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip() - # Use only the last line. Previous lines may contain GPG signature - # information. - date = date.splitlines()[-1] - pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) - - return pieces - - -def plus_or_dot(pieces): - """Return a + if we don't already have one, else return a .""" - if "+" in pieces.get("closest-tag", ""): - return "." - return "+" - - -def render_pep440(pieces): - """Build up version string, with post-release "local version identifier". - - Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you - get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty - - Exceptions: - 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"] or pieces["dirty"]: - rendered += plus_or_dot(pieces) - rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) - if pieces["dirty"]: - rendered += ".dirty" - else: - # exception #1 - rendered = "0+untagged.%d.g%s" % (pieces["distance"], - pieces["short"]) - if pieces["dirty"]: - rendered += ".dirty" - return rendered - - -def render_pep440_branch(pieces): - """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . - - The ".dev0" means not master branch. Note that .dev0 sorts backwards - (a feature branch will appear "older" than the master branch). - - Exceptions: - 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"] or pieces["dirty"]: - if pieces["branch"] != "master": - rendered += ".dev0" - rendered += plus_or_dot(pieces) - rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) - if pieces["dirty"]: - rendered += ".dirty" - else: - # exception #1 - rendered = "0" - if pieces["branch"] != "master": - rendered += ".dev0" - rendered += "+untagged.%d.g%s" % (pieces["distance"], - pieces["short"]) - if pieces["dirty"]: - rendered += ".dirty" - return rendered - - -def pep440_split_post(ver): - """Split pep440 version string at the post-release segment. - - Returns the release segments before the post-release and the - post-release version number (or -1 if no post-release segment is present). - """ - vc = str.split(ver, ".post") - return vc[0], int(vc[1] or 0) if len(vc) == 2 else None - - -def render_pep440_pre(pieces): - """TAG[.postN.devDISTANCE] -- No -dirty. - - Exceptions: - 1: no tags. 0.post0.devDISTANCE - """ - if pieces["closest-tag"]: - if pieces["distance"]: - # update the post release segment - tag_version, post_version = pep440_split_post(pieces["closest-tag"]) - rendered = tag_version - if post_version is not None: - rendered += ".post%d.dev%d" % (post_version + 1, pieces["distance"]) - else: - rendered += ".post0.dev%d" % (pieces["distance"]) - else: - # no commits, use the tag as the version - rendered = pieces["closest-tag"] - else: - # exception #1 - rendered = "0.post0.dev%d" % pieces["distance"] - return rendered - - -def render_pep440_post(pieces): - """TAG[.postDISTANCE[.dev0]+gHEX] . - - The ".dev0" means dirty. Note that .dev0 sorts backwards - (a dirty tree will appear "older" than the corresponding clean one), - but you shouldn't be releasing software with -dirty anyways. - - Exceptions: - 1: no tags. 0.postDISTANCE[.dev0] - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"] or pieces["dirty"]: - rendered += ".post%d" % pieces["distance"] - if pieces["dirty"]: - rendered += ".dev0" - rendered += plus_or_dot(pieces) - rendered += "g%s" % pieces["short"] - else: - # exception #1 - rendered = "0.post%d" % pieces["distance"] - if pieces["dirty"]: - rendered += ".dev0" - rendered += "+g%s" % pieces["short"] - return rendered - - -def render_pep440_post_branch(pieces): - """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . - - The ".dev0" means not master branch. - - Exceptions: - 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"] or pieces["dirty"]: - rendered += ".post%d" % pieces["distance"] - if pieces["branch"] != "master": - rendered += ".dev0" - rendered += plus_or_dot(pieces) - rendered += "g%s" % pieces["short"] - if pieces["dirty"]: - rendered += ".dirty" - else: - # exception #1 - rendered = "0.post%d" % pieces["distance"] - if pieces["branch"] != "master": - rendered += ".dev0" - rendered += "+g%s" % pieces["short"] - if pieces["dirty"]: - rendered += ".dirty" - return rendered - - -def render_pep440_old(pieces): - """TAG[.postDISTANCE[.dev0]] . - - The ".dev0" means dirty. - - Exceptions: - 1: no tags. 0.postDISTANCE[.dev0] - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"] or pieces["dirty"]: - rendered += ".post%d" % pieces["distance"] - if pieces["dirty"]: - rendered += ".dev0" - else: - # exception #1 - rendered = "0.post%d" % pieces["distance"] - if pieces["dirty"]: - rendered += ".dev0" - return rendered - - -def render_git_describe(pieces): - """TAG[-DISTANCE-gHEX][-dirty]. - - Like 'git describe --tags --dirty --always'. - - Exceptions: - 1: no tags. HEX[-dirty] (note: no 'g' prefix) - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"]: - rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) - else: - # exception #1 - rendered = pieces["short"] - if pieces["dirty"]: - rendered += "-dirty" - return rendered - - -def render_git_describe_long(pieces): - """TAG-DISTANCE-gHEX[-dirty]. - - Like 'git describe --tags --dirty --always -long'. - The distance/hash is unconditional. - - Exceptions: - 1: no tags. HEX[-dirty] (note: no 'g' prefix) - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) - else: - # exception #1 - rendered = pieces["short"] - if pieces["dirty"]: - rendered += "-dirty" - return rendered - - -def render(pieces, style): - """Render the given version pieces into the requested style.""" - if pieces["error"]: - return {"version": "unknown", - "full-revisionid": pieces.get("long"), - "dirty": None, - "error": pieces["error"], - "date": None} - - if not style or style == "default": - style = "pep440" # the default - - if style == "pep440": - rendered = render_pep440(pieces) - elif style == "pep440-branch": - rendered = render_pep440_branch(pieces) - elif style == "pep440-pre": - rendered = render_pep440_pre(pieces) - elif style == "pep440-post": - rendered = render_pep440_post(pieces) - elif style == "pep440-post-branch": - rendered = render_pep440_post_branch(pieces) - elif style == "pep440-old": - rendered = render_pep440_old(pieces) - elif style == "git-describe": - rendered = render_git_describe(pieces) - elif style == "git-describe-long": - rendered = render_git_describe_long(pieces) - else: - raise ValueError("unknown style '%s'" % style) - - return {"version": rendered, "full-revisionid": pieces["long"], - "dirty": pieces["dirty"], "error": None, - "date": pieces.get("date")} +version_json = ''' +{ + "date": "2023-07-30T18:52:43-0600", + "dirty": false, + "error": null, + "full-revisionid": "ea677928332c37e8052b4d599bf6ee52cf363cf9", + "version": "1.25.2" +} +''' # END VERSION_JSON def get_versions(): - """Get version information or return default if unable to do so.""" - # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have - # __file__, we can work backwards from there to the root. Some - # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which - # case we can only use expanded keywords. - - cfg = get_config() - verbose = cfg.verbose - - try: - return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, - verbose) - except NotThisMethod: - pass - - try: - root = os.path.realpath(__file__) - # versionfile_source is the relative path from the top of the source - # tree (where the .git directory might live) to this file. Invert - # this to find the root from __file__. - for _ in cfg.versionfile_source.split('/'): - root = os.path.dirname(root) - except NameError: - return {"version": "0+unknown", "full-revisionid": None, - "dirty": None, - "error": "unable to find root of source tree", - "date": None} - - try: - pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) - return render(pieces, cfg.style) - except NotThisMethod: - pass - - try: - if cfg.parentdir_prefix: - return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) - except NotThisMethod: - pass - - return {"version": "0+unknown", "full-revisionid": None, - "dirty": None, - "error": "unable to compute version", "date": None} + return json.loads(version_json) diff --git a/python-numpy.spec b/python-numpy.spec new file mode 100644 index 000000000000..1f98c72eeeff --- /dev/null +++ b/python-numpy.spec @@ -0,0 +1,197 @@ +# Copyright 2024 Wong Hoi Sing Edison +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +%global debug_package %{nil} + +%global source_date_epoch_from_changelog 0 + +%global _lto_cflags %{?_lto_cflags} -ffat-lto-objects + +Name: python-numpy +Epoch: 100 +Version: 1.25.2 +Release: 1%{?dist} +Summary: Fundamental package for array computing with Python +License: BSD-3-Clause +URL: https://github.com/numpy/numpy/tags +Source0: %{name}_%{version}.orig.tar.gz +BuildRequires: fdupes +BuildRequires: gcc +BuildRequires: gcc-c++ +BuildRequires: gcc-gfortran +BuildRequires: git +BuildRequires: lapack-devel +BuildRequires: openblas-devel +BuildRequires: python-rpm-macros +BuildRequires: python3-Cython3 +BuildRequires: python3-devel +BuildRequires: python3-setuptools + +%description +NumPy is the fundamental package for scientific computing with Python. + +%prep +%autosetup -T -c -n %{name}_%{version}-%{release} +tar -zx -f %{S:0} --strip-components=1 -C . + +%build +export CFLAGS="%{optflags} -fno-strict-aliasing" +%{__python3} setup.py build + +%install +export CFLAGS="%{optflags} -fno-strict-aliasing" +%{__python3} setup.py install --root %{buildroot} +find %{buildroot}%{python3_sitearch} -type f -name '*.pyc' -exec rm -rf {} \; +fdupes -qnrps %{buildroot}%{python3_sitearch} + +%check + +%if 0%{?suse_version} > 1500 +%package -n python%{python3_version_nodots}-numpy +Summary: Fundamental package for array computing with Python +Requires: python3 +Provides: python3-numpy = %{epoch}:%{version}-%{release} +Provides: python3dist(numpy) = %{epoch}:%{version}-%{release} +Provides: python%{python3_version}-numpy = %{epoch}:%{version}-%{release} +Provides: python%{python3_version}dist(numpy) = %{epoch}:%{version}-%{release} +Provides: python%{python3_version_nodots}-numpy = %{epoch}:%{version}-%{release} +Provides: python%{python3_version_nodots}dist(numpy) = %{epoch}:%{version}-%{release} + +%description -n python%{python3_version_nodots}-numpy +NumPy is the fundamental package for scientific computing with Python. + +%package -n python%{python3_version_nodots}-numpy-devel +Summary: Development files for numpy applications +Requires: lapack-devel +Requires: openblas-devel +Requires: python3-devel +Requires: python%{python3_version_nodots}-numpy = %{epoch}:%{version}-%{release} +Provides: python3-numpy-devel = %{epoch}:%{version}-%{release} +Provides: python3dist(numpy-devel) = %{epoch}:%{version}-%{release} +Provides: python%{python3_version}-numpy-devel = %{epoch}:%{version}-%{release} +Provides: python%{python3_version}dist(numpy-devel) = %{epoch}:%{version}-%{release} +Provides: python%{python3_version_nodots}-numpy-devel = %{epoch}:%{version}-%{release} +Provides: python%{python3_version_nodots}dist(numpy-devel) = %{epoch}:%{version}-%{release} + +%description -n python%{python3_version_nodots}-numpy-devel +This package contains files for developing applications using numpy. + +%files -n python%{python3_version_nodots}-numpy +%license LICENSE.txt +%{_bindir}/* +%{python3_sitearch}/* +%exclude %{python3_sitearch}/numpy/core/include/ +%exclude %{python3_sitearch}/numpy/core/lib/libnpymath.a +%exclude %{python3_sitearch}/numpy/random/lib/libnpyrandom.a +%exclude %{python3_sitearch}/numpy/distutils/*/*.c +%exclude %{python3_sitearch}/numpy/f2py/src/ + +%files -n python%{python3_version_nodots}-numpy-devel +%{python3_sitearch}/numpy/core/include/ +%{python3_sitearch}/numpy/core/lib/libnpymath.a +%{python3_sitearch}/numpy/random/lib/libnpyrandom.a +%{python3_sitearch}/numpy/distutils/*/*.c +%{python3_sitearch}/numpy/f2py/src/ +%endif + +%if 0%{?sle_version} > 150000 +%package -n python3-numpy +Summary: Fundamental package for array computing with Python +Requires: python3 +Provides: python3-numpy = %{epoch}:%{version}-%{release} +Provides: python3dist(numpy) = %{epoch}:%{version}-%{release} +Provides: python%{python3_version}-numpy = %{epoch}:%{version}-%{release} +Provides: python%{python3_version}dist(numpy) = %{epoch}:%{version}-%{release} +Provides: python%{python3_version_nodots}-numpy = %{epoch}:%{version}-%{release} +Provides: python%{python3_version_nodots}dist(numpy) = %{epoch}:%{version}-%{release} + +%description -n python3-numpy +NumPy is the fundamental package for scientific computing with Python. + +%package -n python3-numpy-devel +Summary: Development files for numpy applications +Requires: lapack-devel +Requires: openblas-devel +Requires: python3-devel +Requires: python3-numpy = %{epoch}:%{version}-%{release} +Provides: python3-numpy-devel = %{epoch}:%{version}-%{release} +Provides: python3dist(numpy-devel) = %{epoch}:%{version}-%{release} +Provides: python%{python3_version}-numpy-devel = %{epoch}:%{version}-%{release} +Provides: python%{python3_version}dist(numpy-devel) = %{epoch}:%{version}-%{release} +Provides: python%{python3_version_nodots}-numpy-devel = %{epoch}:%{version}-%{release} +Provides: python%{python3_version_nodots}dist(numpy-devel) = %{epoch}:%{version}-%{release} + +%description -n python3-numpy-devel +This package contains files for developing applications using numpy. + +%files -n python3-numpy +%license LICENSE.txt +%{_bindir}/* +%{python3_sitearch}/* +%exclude %{python3_sitearch}/numpy/core/include/ +%exclude %{python3_sitearch}/numpy/core/lib/libnpymath.a +%exclude %{python3_sitearch}/numpy/random/lib/libnpyrandom.a +%exclude %{python3_sitearch}/numpy/distutils/*/*.c +%exclude %{python3_sitearch}/numpy/f2py/src/ + +%files -n python3-numpy-devel +%{python3_sitearch}/numpy/core/include/ +%{python3_sitearch}/numpy/core/lib/libnpymath.a +%{python3_sitearch}/numpy/random/lib/libnpyrandom.a +%{python3_sitearch}/numpy/distutils/*/*.c +%{python3_sitearch}/numpy/f2py/src/ +%endif + +%if !(0%{?suse_version} > 1500) && !(0%{?sle_version} > 150000) +%package -n python3-numpy +Summary: Fundamental package for array computing with Python +Requires: python3 +Provides: python3-numpy = %{epoch}:%{version}-%{release} +Provides: python3dist(numpy) = %{epoch}:%{version}-%{release} +Provides: python%{python3_version}-numpy = %{epoch}:%{version}-%{release} +Provides: python%{python3_version}dist(numpy) = %{epoch}:%{version}-%{release} +Provides: python%{python3_version_nodots}-numpy = %{epoch}:%{version}-%{release} +Provides: python%{python3_version_nodots}dist(numpy) = %{epoch}:%{version}-%{release} + +%description -n python3-numpy +NumPy is the fundamental package for scientific computing with Python. + +%package -n python3-numpy-f2py +Summary: f2py for numpy +Requires: python3-devel +Requires: python3-numpy = %{epoch}:%{version}-%{release} +Provides: f2py = %{epoch}:%{version}-%{release} +Provides: numpy-f2py = %{epoch}:%{version}-%{release} +Provides: python3-f2py = %{epoch}:%{version}-%{release} +Provides: python3-numpy-f2py = %{epoch}:%{version}-%{release} +Provides: python3dist(numpy-f2py) = %{epoch}:%{version}-%{release} +Provides: python%{python3_version}-numpy-f2py = %{epoch}:%{version}-%{release} +Provides: python%{python3_version}dist(numpy-f2py) = %{epoch}:%{version}-%{release} +Provides: python%{python3_version_nodots}-numpy-f2py = %{epoch}:%{version}-%{release} +Provides: python%{python3_version_nodots}dist(numpy-f2py) = %{epoch}:%{version}-%{release} + +%description -n python3-numpy-f2py +This package includes a version of f2py that works properly with NumPy. + +%files -n python3-numpy +%license LICENSE.txt +%{python3_sitearch}/* +%exclude %{python3_sitearch}/numpy/f2py + +%files -n python3-numpy-f2py +%{_bindir}/* +%{python3_sitearch}/numpy/f2py +%endif + +%changelog diff --git a/setup.py b/setup.py index c924bb999ebc..61178e0a6a78 100755 --- a/setup.py +++ b/setup.py @@ -379,7 +379,7 @@ def parse_setuppy_commands(): good_commands = ('develop', 'sdist', 'build', 'build_ext', 'build_py', 'build_clib', 'build_scripts', 'bdist_wheel', 'bdist_rpm', 'bdist_wininst', 'bdist_msi', 'bdist_mpkg', 'build_src', - 'bdist_egg') + 'bdist_egg', 'config') for command in good_commands: if command in args: