Skip to content

Commit ee0cf2c

Browse files
authored
[Done] Test with newer Python, deprecation fixes, drop Py3.7 support (#747)
* Bump dependencies and update actions files * Fix warnings * WIP * Try with tables 3.7 on py3.10 * Some int32 fixes for windows
1 parent 597f183 commit ee0cf2c

File tree

13 files changed

+68
-51
lines changed

13 files changed

+68
-51
lines changed

.github/workflows/test-conda.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ jobs:
1010
fail-fast: false
1111
matrix:
1212
os: [ubuntu-latest, macos-latest, windows-latest]
13-
python: [3.8, 3.9, "3.10"]
13+
python: [3.8, 3.9, "3.10", "3.11"]
1414

1515
steps:
1616
- uses: actions/checkout@v2
1717

1818
- name: Setup Conda
19-
uses: s-weigand/setup-conda@v1.0.5
19+
uses: s-weigand/setup-conda@v1
2020
with:
2121
activate-conda: false
2222
conda-channels: conda-forge

.github/workflows/test-pip.yml

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,27 @@ jobs:
1010
fail-fast: false
1111
matrix:
1212
include:
13-
# 2018
14-
- python: 3.7
15-
display_name: "2018"
16-
deps: "numpy==1.16.* scipy==1.3.* matplotlib==2.2.* pandas==0.23.* tables==3.5.* scikit-learn==0.20.* pyyaml numba==0.45.* llvmlite==0.29.* looseversion>=1.0.1"
17-
# 2019
18-
- python: 3.8
13+
- python: "3.8"
1914
display_name: "2019"
20-
deps: "numpy==1.18.* scipy==1.4.* matplotlib==3.1.* pandas==0.25.* tables==3.6.* scikit-learn==0.22.* pyyaml numba==0.47.* llvmlite==0.31.* looseversion>=1.0.1"
21-
# 2020
22-
- python: 3.9
15+
deps: "numpy==1.18.* scipy==1.4.* matplotlib==3.1.* pandas==1.0.* tables==3.6.* scikit-learn==0.22.* numba==0.47.* llvmlite==0.31.*"
16+
- python: "3.9"
2317
display_name: "2020"
24-
deps: "numpy==1.19.* scipy==1.5.* matplotlib==3.3.* pandas==1.1.* tables==3.6.* scikit-learn==0.24.* pyyaml numba==0.53.* llvmlite==0.36.* looseversion>=1.0.1"
25-
# 2021 (use Py3.9 & numpy==1.20 due to numba compatibility)
26-
- python: 3.9
18+
deps: "numpy==1.19.* scipy==1.5.* matplotlib==3.3.* pandas==1.1.* tables==3.6.* scikit-learn==0.24.* numba==0.53.* llvmlite==0.36.*"
19+
- python: "3.10"
2720
display_name: "2021"
28-
deps: "numpy==1.20.* scipy==1.7.* matplotlib==3.5.* pandas==1.3.* tables==3.6.* scikit-learn==1.0.* pyyaml numba==0.54.* llvmlite==0.37.* looseversion>=1.0.1"
29-
# most recent
30-
- python: '3.x'
31-
display_name: "latest, no optional deps"
32-
deps: "numpy scipy matplotlib pandas pyyaml looseversion"
21+
deps: "numpy==1.22.* scipy==1.7.* matplotlib==3.5.* pandas==1.3.* tables==3.7.* scikit-learn==1.0.* numba==0.55.* llvmlite==0.38.*"
22+
- python: "3.11"
23+
display_name: "2022"
24+
deps: "numpy==1.24.* scipy==1.9.* matplotlib==3.6.* pandas==2.0.* tables==3.8.* scikit-learn==1.1.* numba==0.57.* llvmlite==0.40.*"
25+
- python: "3.12"
26+
display_name: "2023, no numba" # no numba support yet
27+
deps: "numpy==1.26.* scipy==1.11.* matplotlib==3.8.* pandas==2.1.* tables==3.9.* scikit-learn==1.3.*"
3328

3429
steps:
35-
- uses: actions/checkout@v2
30+
- uses: actions/checkout@v4
3631

3732
- name: Set up Python ${{ matrix.python }}
38-
uses: actions/setup-python@v2
33+
uses: actions/setup-python@v5
3934
with:
4035
python-version: ${{ matrix.python }}
4136

@@ -45,9 +40,8 @@ jobs:
4540
- name: Install python dependencies
4641
shell: bash
4742
run: |
48-
pip install --disable-pip-version-check --upgrade pip wheel
49-
pip install --no-build-isolation pytest ${{ matrix.numpy }};
50-
pip install --no-build-isolation ${{ matrix.deps }};
43+
pip install --disable-pip-version-check --upgrade pip setuptools wheel
44+
pip install -v -e .[test] ${{ matrix.deps }};
5145
pip list
5246
5347
- name: Run tests

doc/releases/v0.6.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
v0.6.2
2+
------
3+
4+
trackpy v0.6.2 includes version compatability fixes with newer library versions.
5+
Also it drops support for Python 3.7 and earlier, NumPy 1.17 and earlier, Pandas 0.x,
6+
and SciPy 1.2 and earlier.
7+
8+
19
v0.6.1
210
------
311

setup.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,11 @@
2525
author = "Trackpy Contributors",
2626
author_email = "[email protected]",
2727
url = "https://github.com/soft-matter/trackpy",
28-
install_requires = ['numpy>=1.14', 'scipy>=1.1', 'pandas>=0.22', 'pyyaml', 'matplotlib', "looseversion>=1.0.1"],
29-
python_requires=">=3.7",
28+
install_requires = ['numpy>=1.18', 'scipy>=1.4', 'pandas>=1', 'pyyaml', 'matplotlib', "looseversion>=1.0.1"],
29+
extras_require={"test": "pytest"},
30+
python_requires=">=3.8",
3031
classifiers=[
3132
"Programming Language :: Python :: 3",
32-
"Programming Language :: Python :: 3.7",
33-
"Programming Language :: Python :: 3.8",
34-
"Programming Language :: Python :: 3.9",
35-
"Programming Language :: Python :: 3.10",
3633
],
3734
packages = ['trackpy', 'trackpy.refine', 'trackpy.linking', 'trackpy.locate_functions'],
3835
long_description = descr,

trackpy/linking/linking.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,9 @@ def link(f, search_range, pos_columns=None, t_column='frame', **kwargs):
181181

182182
# copy the dataframe
183183
f = f.copy()
184-
# coerce t_column to integer type
184+
# coerce t_column to integer type (use np.int64 to avoid 32-bit on windows)
185185
if not np.issubdtype(f[t_column].dtype, np.integer):
186-
f[t_column] = f[t_column].astype(int)
186+
f[t_column] = f[t_column].astype(np.int64)
187187
# sort on the t_column
188188
pandas_sort(f, t_column, inplace=True)
189189

trackpy/refine/least_squares.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import functools
12
import logging
23
import warnings
34
import numpy as np
@@ -457,6 +458,16 @@ def prepare_subimages(coords, groups, frame_nos, reader, radius):
457458
return images, meshes, masks
458459

459460

461+
def ignore_clip_warnings(func):
462+
@functools.wraps(func)
463+
def wrapper(*args, **kwargs):
464+
with warnings.catch_warnings():
465+
warnings.filterwarnings("ignore", ".*outside bounds during a minimize step.*", RuntimeWarning, "scipy.optimize.*")
466+
return func(*args, **kwargs)
467+
return wrapper
468+
469+
470+
@ignore_clip_warnings
460471
def refine_leastsq(f, reader, diameter, separation=None, fit_function='gauss',
461472
param_mode=None, param_val=None, constraints=None,
462473
bounds=None, compute_error=False, pos_columns=None,

trackpy/tests/test_feature_saving.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def _skip_if_no_pytables():
3636
raise unittest.SkipTest('pytables not installed. Skipping.')
3737

3838
# https://github.com/soft-matter/trackpy/issues/643
39-
if tables.get_hdf5_version() == "1.8.5-patch1":
39+
if tables.hdf5_version == "1.8.5-patch1":
4040
raise unittest.SkipTest('this pytables version has an incompatible HDF5 version. Skipping.')
4141

4242
class FeatureSavingTester:

trackpy/tests/test_leastsq.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,14 @@
1111
from trackpy.refine.least_squares import (dimer, trimer, tetramer, dimer_global,
1212
FitFunctions, vect_from_params)
1313
from trackpy.tests.common import assert_coordinates_close, StrictTestCase
14-
from scipy.optimize.slsqp import approx_jacobian
14+
import warnings
15+
16+
with warnings.catch_warnings():
17+
warnings.simplefilter("ignore")
18+
try:
19+
from scipy.optimize.slsqp import approx_jacobian
20+
except ImportError:
21+
approx_jacobian = None
1522

1623

1724
EPSILON = 1E-7
@@ -923,6 +930,8 @@ def get_residual(self, ff, n, params, groups=None):
923930

924931
def compare_jacobian(self, fit_function, ndim, isotropic, n, groups=None,
925932
custom_param_mode=None):
933+
if approx_jacobian is None:
934+
raise SkipTest("This test requires a function that is deprecated in Scipy 2.0")
926935
ff = FitFunctions(fit_function, ndim, isotropic)
927936
param_mode = {param: 'var' for param in ff.params}
928937
param_mode['background'] = 'cluster'

trackpy/tests/test_linking.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -618,15 +618,16 @@ def f_iter(f, first_frame, last_frame):
618618
res['particle'] = -1
619619
for t, ids in link_iter(f_iter(f, 0, int(f['frame'].max())),
620620
search_range, *args, **kwargs):
621-
res.loc[res['frame'] == t, 'particle'] = ids
621+
if ids:
622+
res.loc[res['frame'] == t, 'particle'] = ids
622623
return pandas_sort(res, ['particle', 'frame']).reset_index(drop=True)
623624

624625
def test_output_dtypes(self):
625626
N = 5
626627
f = DataFrame({'x': np.arange(N), 'y': np.ones(N),
627628
'frame': np.arange(N)})
628629
# Integer-typed input
629-
f['frame'] = f['frame'].astype(int)
630+
f['frame'] = f['frame'].astype(np.int64)
630631
actual = self.link(f, 5)
631632

632633
# Particle and frame columns should be integer typed

trackpy/tests/test_motion.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def random_walk(N):
2020
def conformity(df):
2121
""" Organize toy data to look like real data. Be strict about dtypes:
2222
particle is a float and frame is an integer."""
23-
df['frame'] = df['frame'].astype(int)
23+
df['frame'] = df['frame'].astype(np.int64) # pandas maps to int32 on windows!
2424
df['particle'] = df['particle'].astype(float)
2525
df['x'] = df['x'].astype(float)
2626
df['y'] = df['y'].astype(float)

0 commit comments

Comments
 (0)