Skip to content
Merged
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
78 changes: 53 additions & 25 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,41 +11,69 @@ on:

jobs:
build:

name: Python ${{ matrix.python-version }} (${{ matrix.backend }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10"]
cython: ['python -m pip install -q cython', 'echo "No Cython"']
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
# PySpike treats Cython as an optional accelerator. Both install paths
# need to work and produce a passing test suite:
#
# cython -- `pip install .` uses pip's isolated build env, which
# installs Cython per pyproject.toml's build-system
# requires. setup.py compiles the .pyx sources into
# .so modules and the fast path is used at runtime.
#
# no-cython -- `pip install --no-build-isolation .` with Cython
# deliberately absent. setup.py's `try: import Cython`
# raises ImportError, no extensions are built, and
# each pyspike module falls back to python_backend.py
# via its own `try/except ImportError`.
backend: [cython, no-cython]

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install libblas-dev
sudo apt-get install liblapack-dev
sudo apt-get install gfortran
python -m pip install --upgrade pip
python -m pip install flake8 pytest nose numpy scipy
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Install Cython
run: |
${{ matrix.cython }}
- name: Install package
sudo apt-get install -y libblas-dev liblapack-dev gfortran

- name: Upgrade pip
run: python -m pip install --upgrade pip

- name: Install PySpike — with Cython (build isolation)
if: matrix.backend == 'cython'
run: pip install .

- name: Install PySpike — without Cython (pure-Python fallback)
if: matrix.backend == 'no-cython'
run: |
python SetupNoPrompt.py build_ext --inplace
# - name: Lint with flake8
# run: |
# # stop the build if there are Python syntax errors or undefined names
# flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
# flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
# Provide only the bare build prereqs Cython is not among them, so
# setup.py's `try: from Cython.Distutils import build_ext` fails and
# no C extensions are produced. --no-build-isolation makes pip use
# this env instead of provisioning a fresh one (which would install
# Cython per pyproject.toml).
pip install "setuptools>=77" wheel "numpy>=1.25"
pip install --no-build-isolation .
# Sanity check: the compiled extension must NOT be importable.
python -c "
try:
from pyspike.cython import cython_distances
except ImportError:
print('OK: cython_distances absent, runtime will use python_backend')
else:
raise SystemExit('FAIL: cython_distances was built despite no-cython matrix')
"

- name: Install test dependencies
run: pip install pytest scipy

- name: Test with PyTest
run: |
python -m pytest
run: python -m pytest
9 changes: 9 additions & 0 deletions Changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
PySpike v0.9
* Modernized packaging: project metadata moved into pyproject.toml
* Fixed `pip install pyspike` failing in modern pip's isolated build
environment with "ModuleNotFoundError: No module named 'numpy'" (#84)
* Python 3.12 and 3.13 support: replaced pkg_resources (which depends on
setuptools, no longer shipped in default venvs from 3.12 onwards) with
stdlib importlib.metadata for __version__ lookup
* Dropped support for Python 3.7 and 3.8 (both end-of-life)

PySpike v0.8
* Support Adaptive versions of distances (Minimum Relevant Time Scale)
* Support Rate Independent Adaptive spike distance
Expand Down
10 changes: 8 additions & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
include *.rst
include *.txt
include pyspike/cython/*.c
include directionality/cython/*.c
include License.txt
include Changelog
include pyproject.toml

# Cython sources — required so `pip install` from sdist can regenerate
# the .c files and build the extension modules.
recursive-include pyspike/cython *.pyx *.pxd

recursive-include examples *.py *.txt
recursive-include test *.py *.txt
recursive-include doc *
5 changes: 0 additions & 5 deletions SetupNoPrompt.py

This file was deleted.

4 changes: 2 additions & 2 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ def setup(app):
# built documents.
#
# The short X.Y version.
version = '0.8'
version = '0.9'
# The full version, including alpha/beta/rc tags.
release = '0.8.0'
release = '0.9.0'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
53 changes: 53 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
[build-system]
# setuptools >=77 supports the SPDX-string form `license = "BSD-2-Clause"`
# in [project] (PEP 639). numpy and Cython are required because setup.py
# calls numpy.get_include() and compiles .pyx sources for the C extensions.
requires = [
"setuptools>=77",
"wheel",
"Cython>=3.0",
"numpy>=1.25",
]
build-backend = "setuptools.build_meta"

[project]
name = "pyspike"
version = "0.9.0"
description = "A Python library for the numerical analysis of spike train similarity"
readme = "Readme.rst"
requires-python = ">=3.9"
license = "BSD-2-Clause"
license-files = ["License.txt"]
authors = [
{ name = "Mario Mulansky", email = "mario.mulansky@gmx.net" },
]
keywords = ["data analysis", "spike", "neuroscience"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Science/Research",
"Topic :: Scientific/Engineering",
"Topic :: Scientific/Engineering :: Information Analysis",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
dependencies = [
"numpy",
]

[project.urls]
Homepage = "https://github.com/mariomulansky/PySpike"
Repository = "https://github.com/mariomulansky/PySpike"
Issues = "https://github.com/mariomulansky/PySpike/issues"

[tool.setuptools]
include-package-data = true

[tool.setuptools.packages.find]
exclude = ["doc*", "test*", "examples*"]
# Cython .c files are generated at build time (.gitignore excludes them) and
# the resulting .so files are placed automatically. No package_data needed
# for the wheel; MANIFEST.in handles inclusion of .pyx sources in the sdist.
24 changes: 9 additions & 15 deletions pyspike/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,17 @@
spike_train_order_bi, spike_train_order_multi, \
optimal_spike_train_sorting, permutate_matrix

# define the __version__ following
# http://stackoverflow.com/questions/17583443
from pkg_resources import get_distribution, DistributionNotFound
import os.path
# Expose the installed version via importlib.metadata (stdlib since 3.8).
# Previously this used pkg_resources, which depends on setuptools — and from
# Python 3.12 onwards venvs no longer ship setuptools by default, so the old
# import would fail at runtime in fresh 3.12+ environments.
from importlib.metadata import version as _get_version, PackageNotFoundError

try:
_dist = get_distribution('pyspike')
# Normalize case for Windows systems
dist_loc = os.path.normcase(_dist.location)
here = os.path.normcase(__file__)
if not here.startswith(os.path.join(dist_loc, 'pyspike')):
# not installed, but there is another version that *is*
raise DistributionNotFound
except DistributionNotFound:
__version__ = 'Please install this project with setup.py'
else:
__version__ = _dist.version
__version__ = _get_version("pyspike")
except PackageNotFoundError:
# Running from a source checkout that hasn't been installed.
__version__ = "0.0.0+unknown"

disable_backend_warning = False

Expand Down
2 changes: 0 additions & 2 deletions setup.cfg

This file was deleted.

Loading
Loading