Skip to content
Open
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
52 changes: 42 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,30 @@ on: ["push", "pull_request"]
permissions: {}

jobs:
test-build-helpers:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
python-version:
- "3.10"
- "3.14"
os:
- ubuntu-latest
- macos-latest
- windows-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
python-version: ${{ matrix.python-version }}
no-project: true
- run: uvx pytest build_helpers

test-linux-macos:
needs: [test-build-helpers]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
Expand All @@ -25,6 +48,7 @@ jobs:
- uses: ./.github/bottleneck-action

test-windows:
needs: [test-build-helpers]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
Expand All @@ -39,23 +63,24 @@ jobs:
os:
- windows-latest
- windows-2022
include:
- os: windows-11-arm
architecture: arm64
python-version: "3.11"
- os: windows-11-arm
architecture: arm64
python-version: "3.14"
- os: windows-11-arm
architecture: arm64
python-version: "3.14t"
# include:
# - os: windows-11-arm
# architecture: arm64
# python-version: "3.11"
# - os: windows-11-arm
# architecture: arm64
# python-version: "3.14"
# - os: windows-11-arm
# architecture: arm64
# python-version: "3.14t"
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: ./.github/bottleneck-action

test-pyversions:
needs: [test-build-helpers]
runs-on: ubuntu-latest
strategy:
fail-fast: false
Expand Down Expand Up @@ -92,6 +117,7 @@ jobs:
- test-windows
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
Expand Down Expand Up @@ -127,6 +153,12 @@ jobs:
fetch-depth: 0
persist-credentials: false

- name: Setup MSVC (32-bit)
if: ${{ startsWith(runner.os, 'windows') && matrix.archs == 'x86' }}
uses: bus1/cabuild/action/msdevshell@e22aba57d6e74891d059d66501b6b5aed8123c4d # v1
with:
architecture: 'x86'

- name: Build wheels
uses: pypa/cibuildwheel@8d2b08b68458a16aeb24b64e68a09ab1c8e82084 # v3.4.1
env:
Expand Down
20 changes: 0 additions & 20 deletions MANIFEST.in

This file was deleted.

65 changes: 0 additions & 65 deletions Makefile

This file was deleted.

8 changes: 1 addition & 7 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -125,18 +125,12 @@ Unit tests pytest
Documentation sphinx, numpydoc
======================== ============================================================================

To install Bottleneck on Linux, Mac OS X, et al.:
To install Bottleneck:

.. code-block:: console

$ pip install .

To install bottleneck on Windows, first install MinGW and add it to your
system path. Then install Bottleneck with the command:

.. code-block:: console

$ python setup.py install --compiler=mingw32

Unit tests
==========
Expand Down
11 changes: 5 additions & 6 deletions bottleneck/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,10 @@
test = PytestTester(__name__)
del PytestTester

from ._version import get_versions # noqa: E402

__version__ = get_versions()["version"]
del get_versions
def __getitem__(key: str):
if key == "__version__":
from importlib.metadata import version

from . import _version # noqa: E402

__version__ = _version.get_versions()["version"]
return version("bottleneck")
raise AttributeError
5 changes: 5 additions & 0 deletions bottleneck/src/bottleneck.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
#include <numpy/arrayobject.h>
#include <bn_config.h>

#ifdef Py_LIMITED_API
#define PyTuple_GET_ITEM PyTuple_GetItem
#define PyTuple_GET_SIZE PyTuple_Size
#endif

/* THREADS=1 releases the GIL but increases function call
* overhead. THREADS=0 does not release the GIL but keeps
* function call overhead low. Curly brackets are for C89
Expand Down
File renamed without changes.
File renamed without changes.
28 changes: 0 additions & 28 deletions bottleneck/tests/test_template.py

This file was deleted.

Empty file added build_helpers/__init__.py
Empty file.
57 changes: 41 additions & 16 deletions bottleneck/src/bn_config.py → build_helpers/config.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#!/usr/bin/env python3
"""Based on numpy's approach to exposing compiler features via a config header.
Unfortunately that file is not exposed, so re-implement the portions we need.
"""

import os
import textwrap
from pathlib import Path

OPTIONAL_FUNCTION_ATTRIBUTES = [
("HAVE_ATTRIBUTE_OPTIMIZE_OPT_3", '__attribute__((optimize("O3")))')
Expand Down Expand Up @@ -90,25 +91,27 @@ def check_gcc_function_attribute(cmd, attribute, name):
return cmd.try_compile(body, None, None) != 0


def create_config_h(config):
dirname = os.path.dirname(__file__)
config_h = os.path.join(dirname, "bn_config.h")

if (
os.path.exists(config_h)
and os.stat(__file__).st_mtime < os.stat(config_h).st_mtime
):
return
def create_config_h(config, output_dir: Path):
config_h = output_dir / "bn_config.h"
# this_script = Path(__file__)
# if (
# config_h.exists()
# and this_script.stat().st_mtime < config_h.stat().st_mtime
# ):
# return

output = []

for config_attr, func_attr in OPTIONAL_FUNCTION_ATTRIBUTES:
if check_gcc_function_attribute(config, func_attr, config_attr.lower()):
output.append((config_attr, "1"))
else:
output.append((config_attr, "0"))
if config is not None:
for config_attr, func_attr in OPTIONAL_FUNCTION_ATTRIBUTES:
if check_gcc_function_attribute(config, func_attr, config_attr.lower()):
output.append((config_attr, "1"))
else:
output.append((config_attr, "0"))

inline_alias = check_inline(config)
inline_alias = check_inline(config)
else:
inline_alias = ""

with open(config_h, "w") as f:
for setting in output:
Expand All @@ -118,3 +121,25 @@ def create_config_h(config):
f.write("/* undef inline */\n")
else:
f.write(f"#define inline {inline_alias}\n")
print(f"wrote {config_h}")


def main(argv: list[str] | None = None) -> int:
from argparse import ArgumentParser

parser = ArgumentParser()
parser.add_argument(
"-o",
dest="output_dir",
help="output directory",
)
args = parser.parse_args(argv)
create_config_h(
config=None,
output_dir=Path(args.output_dir),
)
return 0


if __name__ == "__main__":
raise SystemExit(main())
21 changes: 21 additions & 0 deletions build_helpers/get_numpy_include_dir.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# adapted from scipy's meson.build
import os
from contextlib import suppress

import numpy as np


def main(argv: list[str] | None = None) -> int:
assert not argv
incdir = np.get_include()

with suppress(Exception):
# when things are split across drives on Windows,
# there is no relative path and an exception gets raised.
incdir = os.path.relpath(np.get_include())
print(incdir)
return 0


if __name__ == "__main__":
raise SystemExit(main())
Loading
Loading