Skip to content

Commit

Permalink
Upgrade Python versions to 3.9–3.13 (tensorly#576)
Browse files Browse the repository at this point in the history
* Upgrade python versions

* pyupgrade recommendations

* Stick with py 3.12 for now

* py 3.13 is now out
  • Loading branch information
aarmey authored Oct 28, 2024
1 parent d4652c8 commit d32329e
Show file tree
Hide file tree
Showing 24 changed files with 41 additions and 59 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deploy_pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
python-version: '3.12'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
python-version: '3.12'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ jobs:
BACKEND: ['numpy', 'pytorch', 'paddle']
python-version: ['3.12']
include:
- BACKEND: 'numpy'
python-version: '3.8'
- BACKEND: 'numpy'
python-version: '3.9'
- BACKEND: 'numpy'
python-version: '3.11'
TENSORLY_TENALG_BACKEND: ['einsum']
- BACKEND: 'jax'
python-version: '3.12'
python-version: '3.13'
TENSORLY_TENALG_BACKEND: ['einsum']
- BACKEND: 'tensorflow'
python-version: '3.12'
Expand Down Expand Up @@ -67,7 +67,7 @@ jobs:
TENSORLY_BACKEND=${{matrix.BACKEND}} pytest -vv --cov tensorly --cov-report xml --durations=10 tensorly
- name: Check coverage with CodeCov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
verbose: true
5 changes: 2 additions & 3 deletions doc/conf.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# tensorly documentation build configuration file
#
Expand Down Expand Up @@ -75,9 +74,9 @@
master_doc = "index"

# General information about the project.
project = u'tensorly'
project = 'tensorly'
year = datetime.now().year
copyright = "2016 - {}, TensorLy Developers".format(year)
copyright = f"2016 - {year}, TensorLy Developers"
author = "Jean Kossaifi"

# The version info for the project you're documenting, acts as replacement for
Expand Down
4 changes: 2 additions & 2 deletions doc/minify.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
if ".min." in str(path):
continue
target_path = path.with_suffix(".min.js")
with open(path.as_posix(), "r") as f:
with open(path.as_posix()) as f:
text = f.read()
minified = jsmin(text, mangle=True, mangle_toplevel=True)
with open(target_path.as_posix(), "w") as f:
Expand All @@ -23,7 +23,7 @@
if ".min." in str(path):
continue
target_path = path.with_suffix(".min.css")
with open(path.as_posix(), "r") as f:
with open(path.as_posix()) as f:
text = f.read()
minified = cssmin(text)
with open(target_path.as_posix(), "w") as f:
Expand Down
6 changes: 3 additions & 3 deletions examples/decomposition/plot_nn_cp_hals.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@
# -----------------------
# First comparison option is processing time for each algorithm:

print(str("{:.2f}".format(time_mu)) + " " + "seconds")
print(str("{:.2f}".format(time_hals)) + " " + "seconds")
print(str("{:.2f}".format(time_exact_hals)) + " " + "seconds")
print(str(f"{time_mu:.2f}") + " " + "seconds")
print(str(f"{time_hals:.2f}") + " " + "seconds")
print(str(f"{time_exact_hals:.2f}") + " " + "seconds")

##############################################################################
# As it is expected, the exact solution takes much longer than the approximate
Expand Down
6 changes: 3 additions & 3 deletions examples/decomposition/plot_nn_tucker.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@
# To compare the various methods, first we may look at each algorithm
# processing time:

print("time for tensorly nntucker:" + " " + str("{:.2f}".format(time_mu)))
print("time for HALS with fista:" + " " + str("{:.2f}".format(time_fista)))
print("time for HALS with as:" + " " + str("{:.2f}".format(time_as)))
print("time for tensorly nntucker:" + " " + str(f"{time_mu:.2f}"))
print("time for HALS with fista:" + " " + str(f"{time_fista:.2f}"))
print("time for HALS with as:" + " " + str(f"{time_as:.2f}"))

##############################################################################
# All algorithms should run with about the same number of iterations on our
Expand Down
1 change: 0 additions & 1 deletion examples/decomposition/plot_parafac2.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-

"""
Demonstration of PARAFAC2
Expand Down
5 changes: 2 additions & 3 deletions examples/plot_tensor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
Basic tensor operations
=======================
Expand All @@ -13,12 +12,12 @@
###########################################################################
# A tensor is simply a numpy array
tensor = tl.tensor(np.arange(24).reshape((3, 4, 2)))
print("* original tensor:\n{}".format(tensor))
print(f"* original tensor:\n{tensor}")

###########################################################################
# Unfolding a tensor is easy
for mode in range(tensor.ndim):
print("* mode-{} unfolding:\n{}".format(mode, tl.unfold(tensor, mode)))
print(f"* mode-{mode} unfolding:\n{tl.unfold(tensor, mode)}")

###########################################################################
# Re-folding the tensor is as easy:
Expand Down
2 changes: 1 addition & 1 deletion examples/regression/plot_cp_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
ax.set_axis_off()

if i == 0:
ax.set_title("Learned\nrank = {}".format(rank))
ax.set_title(f"Learned\nrank = {rank}")

plt.suptitle("CP tensor regression")
plt.show()
6 changes: 3 additions & 3 deletions examples/regression/plot_tucker_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

for i, pattern in enumerate(patterns):

print("fitting pattern n.{}".format(i))
print(f"fitting pattern n.{i}")

# Generate the original image
weight_img = gen_image(
Expand All @@ -50,7 +50,7 @@
ax.set_title("Original\nweights")

for j, rank in enumerate(ranks):
print("fitting for rank = {}".format(rank))
print(f"fitting for rank = {rank}")

# Create a tensor Regressor estimator
estimator = TuckerRegressor(
Expand All @@ -69,7 +69,7 @@
ax.set_axis_off()

if i == 0:
ax.set_title("Learned\nrank = {}".format(rank))
ax.set_title(f"Learned\nrank = {rank}")

plt.suptitle("Tucker tensor regression")
plt.show()
6 changes: 2 additions & 4 deletions examples/sparse_parafac.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@
"approx_error = tl.norm(t - approx)\n",
"nonzero_elems_count = sum(t_shape)*r\n",
"\n",
"print('approx error: {}, non-zero elements in approx: {}'.format(approx_error,\\\n",
" nonzero_elems_count))"
"print(f'approx error: {approx_error}, non-zero elements in approx: {nonzero_elems_count}')"
]
},
{
Expand All @@ -82,8 +81,7 @@
"approx_error = tl.norm(t - approx_sp)\n",
"nonzero_elems_count = sum(t_shape)*r + sparsity*np.prod(t_shape)\n",
"\n",
"print('approx error: {}, non-zero elements in approx: {}'.format(approx_error,\\\n",
" nonzero_elems_count))"
"print(f'approx error: {approx_error}, non-zero elements in approx: {nonzero_elems_count}')"
]
},
{
Expand Down
2 changes: 1 addition & 1 deletion tensorly/backend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import sys


class dynamically_dispatched_class_attribute(object):
class dynamically_dispatched_class_attribute:
"""Enable dynamically dispatched attributes such as dtype
Parameters
Expand Down
2 changes: 1 addition & 1 deletion tensorly/backend/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def __name__(self):
return "Index"


class Backend(object):
class Backend:
_available_backends = dict()

def __init_subclass__(cls, backend_name, **kwargs):
Expand Down
8 changes: 2 additions & 6 deletions tensorly/contrib/decomposition/_tt_cross.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,10 @@ def tensor_train_cross(input_tensor, rank, tol=1e-4, n_iter_max=100, random_stat

# Initialize rank
if rank[0] != 1:
message = "Provided rank[0] == {} but boundary conditions dictate rank[0] == rank[-1] == 1.".format(
rank[0]
)
message = f"Provided rank[0] == {rank[0]} but boundary conditions dictate rank[0] == rank[-1] == 1."
raise ValueError(message)
if rank[-1] != 1:
message = "Provided rank[-1] == {} but boundary conditions dictate rank[0] == rank[-1] == 1.".format(
rank[-1]
)
message = f"Provided rank[-1] == {rank[-1]} but boundary conditions dictate rank[0] == rank[-1] == 1."
raise ValueError(message)

# list col_idx: column indices (right indices) for skeleton-decomposition: indicate which columns used in each core.
Expand Down
1 change: 0 additions & 1 deletion tensorly/contrib/decomposition/tests/test_tt_TTOI.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Testing of applying TTOI
Expand Down
2 changes: 1 addition & 1 deletion tensorly/contrib/sparse/backend/numpy_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
_MIN_SPARSE_VERSION = Version("0.4.1+10.g81eccee")
if Version(sparse.__version__) < _MIN_SPARSE_VERSION:
raise ImportError(
"numpy sparse backend requires `sparse` version >= %r" % _MIN_SPARSE_VERSION
f"NumPy sparse backend requires `sparse` version >= {_MIN_SPARSE_VERSION!r}"
)


Expand Down
8 changes: 2 additions & 6 deletions tensorly/random/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,14 +212,10 @@ def random_tt(shape, rank, full=False, random_state=None, **context):

# Initialization
if rank[0] != 1:
message = "Provided rank[0] == {} but boundaring conditions dictatate rank[0] == rank[-1] == 1.".format(
rank[0]
)
message = f"Provided rank[0] == {rank[0]} but boundaring conditions dictatate rank[0] == rank[-1] == 1."
raise ValueError(message)
if rank[-1] != 1:
message = "Provided rank[-1] == {} but boundaring conditions dictatate rank[0] == rank[-1] == 1.".format(
rank[-1]
)
message = f"Provided rank[-1] == {rank[-1]} but boundaring conditions dictatate rank[0] == rank[-1] == 1."
raise ValueError(message)

rns = T.check_random_state(random_state)
Expand Down
4 changes: 2 additions & 2 deletions tensorly/tenalg/proximal.py
Original file line number Diff line number Diff line change
Expand Up @@ -550,8 +550,8 @@ def unimodality_prox(tensor):
)
# Next line finds mutual peak points
values = tl.tensor(
tl.to_numpy((tensor - monotone_decreasing >= 0))
* tl.to_numpy((tensor - monotone_increasing >= 0)),
tl.to_numpy(tensor - monotone_decreasing >= 0)
* tl.to_numpy(tensor - monotone_increasing >= 0),
**tl.context(tensor),
)

Expand Down
4 changes: 2 additions & 2 deletions tensorly/tenalg/tests/test_batched_tensordot.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

def test_batched_tensordot():
shape = [3, 4, 2]
vecs = [random.random_tensor((s)) for s in shape]
tensor = random.random_tensor((shape))
vecs = [random.random_tensor(s) for s in shape]
tensor = random.random_tensor(shape)

# Equivalence with inner product when contracting with self along all modes
res = tensordot(tensor, tensor, modes=3) # [[0, 1, 2], [0, 1, 2]])
Expand Down
2 changes: 1 addition & 1 deletion tensorly/tenalg/tests/test_outer_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def test_outer_product():

X = tl.tensor(rng.random_sample((4, 5, 6)))
Y = tl.tensor(rng.random_sample((3, 4)))
Z = tl.tensor(rng.random_sample((2)))
Z = tl.tensor(rng.random_sample(2))
tdot = outer([X, Y, Z])
true_dot = tenalg.tensordot(X, Y, ())
true_dot = tenalg.tensordot(true_dot, Z, ())
Expand Down
8 changes: 2 additions & 6 deletions tensorly/tt_tensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,14 +260,10 @@ def validate_tt_rank(

# Initialization
if rank[0] != 1:
message = "Provided rank[0] == {} but boundary conditions dictate rank[0] == rank[-1] == 1.".format(
rank[0]
)
message = f"Provided rank[0] == {rank[0]} but boundary conditions dictate rank[0] == rank[-1] == 1."
raise ValueError(message)
if rank[-1] != 1:
message = "Provided rank[-1] == {} but boundary conditions dictate rank[0] == rank[-1] == 1.".format(
rank[-1]
)
message = f"Provided rank[-1] == {rank[-1]} but boundary conditions dictate rank[0] == rank[-1] == 1."
raise ValueError(message)

if allow_overparametrization:
Expand Down
4 changes: 2 additions & 2 deletions tensorly/utils/deprecation.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def deprecated(deprecated_by, msg="", use_deprecated=True):
if False, the new class/function will be used along with the deprecation warning for the old name
"""

class DeprecatedBy(object):
class DeprecatedBy:
def __init__(self):
self.deprecated_by = deprecated_by
self.use_deprecated = use_deprecated
Expand Down Expand Up @@ -67,7 +67,7 @@ def __init__(wrapped_self, *args, **kwargs):
return DeprecatedBy()


class DefineDeprecated(object):
class DefineDeprecated:
"""Creates a dummy class or function that returns the class/fun it is deprecated by,
along with a warning
Expand Down
2 changes: 1 addition & 1 deletion tensorly/utils/tests/test_deprecation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


def test_deprecated():
class Dummy(object):
class Dummy:
def __init__(self, arg=1):
self.arg = arg + 1

Expand Down

0 comments on commit d32329e

Please sign in to comment.