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
4 changes: 2 additions & 2 deletions .github/workflows/pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.11'
python-version: '3.12'

- name: Install dependencies
run: pip install --upgrade setuptools numpy versioneer wheel
Expand Down Expand Up @@ -204,7 +204,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.11'
python-version: '3.12'

- name: Check SDist
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/slow-tests-issue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.11"
python-version: "3.12"
- name: Trigger the script
continue-on-error: true
working-directory: scripts/slowest_tests
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
if: ${{ needs.changes.outputs.changes == 'true' }}
strategy:
matrix:
python-version: ["3.11", "3.14"]
python-version: ["3.12", "3.14"]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
Expand All @@ -78,7 +78,7 @@ jobs:
matrix:
# default-mode: "NUMBA" is actually a no-op, to make sure we're testing default config settings
default-mode: ["CVM", "NUMBA", "FAST_COMPILE"]
python-version: ["3.11", "3.14"]
python-version: ["3.12", "3.14"]
os: ["ubuntu-latest"]
install-jax: [0]
install-torch: [0]
Expand All @@ -94,7 +94,7 @@ jobs:
- [ "tensor rewriting", "tests/tensor/rewriting" ]
- [ "tensor linalg", "tests/tensor/linalg" ]
exclude:
- python-version: "3.11"
- python-version: "3.12"
default-mode: "FAST_COMPILE"
include:
- part: ["doctests", "--doctest-modules pytensor --ignore=pytensor/misc/check_duplicate_key.py --ignore=pytensor/link --ignore=pytensor/ipython.py"]
Expand All @@ -117,7 +117,7 @@ jobs:
- part: ["pytorch link", "tests/link/pytorch"]
install-torch: 1
default-mode: "CVM"
python-version: "3.11"
python-version: "3.12"
os: "ubuntu-latest"
- part: ["xtensor", "tests/xtensor"]
install-xarray: 1
Expand All @@ -127,7 +127,7 @@ jobs:
- part: ["mlx link", "tests/link/mlx"]
install-mlx: 1
default-mode: "CVM"
python-version: "3.11"
python-version: "3.12"
os: "macos-15"
- part: ["macos smoke test", "tests/tensor/test_elemwise.py tests/tensor/test_math_scipy.py tests/tensor/test_blas.py"]
default-mode: "CVM"
Expand Down Expand Up @@ -223,7 +223,7 @@ jobs:
with:
fetch-depth: 0
persist-credentials: false
- name: Set up Python 3.11
- name: Set up Python 3.12
uses: mamba-org/setup-micromamba@add3a49764cedee8ee24e82dfde87f5bc2914462 # v2.0.7
with:
environment-name: pytensor-test
Expand All @@ -239,7 +239,7 @@ jobs:
python -c 'import pytensor; print(pytensor.config.__str__(print_doc=False))'
python -c 'import pytensor; assert pytensor.config.blas__ldflags != "", "Blas flags are empty"'
env:
PYTHON_VERSION: 3.11
PYTHON_VERSION: 3.12
- name: Download previous benchmark data
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
Expand Down
2 changes: 1 addition & 1 deletion doc/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ channels:
- conda-forge
- nodefaults
dependencies:
- python=3.11
- python=3.12
- gcc_linux-64
- gxx_linux-64
- numpy
Expand Down
2 changes: 1 addition & 1 deletion environment-osx-arm64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ name: pytensor-dev
channels:
- conda-forge
dependencies:
- python>=3.11
- python>=3.12
- compilers
- numpy>=2.0.0
- scipy>=1,<2
Expand Down
2 changes: 1 addition & 1 deletion environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ name: pytensor-dev
channels:
- conda-forge
dependencies:
- python>=3.11
- python>=3.12
- compilers
- numpy>=2.0.0
- scipy>=1,<2
Expand Down
5 changes: 2 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "pytensor"
dynamic = ['version']
requires-python = ">=3.11,<3.15"
requires-python = ">=3.12,<3.15"
authors = [{ name = "pymc-devs", email = "pymc.devs@gmail.com" }]
description = "Optimizing compiler for evaluating mathematical expressions on CPUs and GPUs."
readme = "README.rst"
Expand All @@ -30,7 +30,6 @@ classifiers = [
"Operating System :: Unix",
"Operating System :: MacOS",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
Expand Down Expand Up @@ -169,7 +168,7 @@ lines-after-imports = 2


[tool.mypy]
python_version = "3.11"
python_version = "3.12"
ignore_missing_imports = true
strict_equality = true
warn_redundant_casts = true
Expand Down
2 changes: 1 addition & 1 deletion pytensor/gradient.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def _match_tangent_dtype(var: Variable, tangent: Variable) -> Variable:


# TODO: Add `overload` variants
def as_list_or_tuple(
def as_list_or_tuple[V: Variable | None](
use_list: bool, use_tuple: bool, outputs: V | Sequence[V]
) -> V | list[V] | tuple[V, ...]:
"""Return either a single object or a list/tuple of objects.
Expand Down
6 changes: 3 additions & 3 deletions pytensor/graph/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def dprint(self, **kwargs):
return debugprint(self, **kwargs)


class Apply(Node, Generic[OpType]):
class Apply(Node, Generic[OpType]): # noqa: UP046
"""A `Node` representing the application of an operation to inputs.

Basically, an `Apply` instance is an object that represents the
Expand Down Expand Up @@ -345,7 +345,7 @@ def params_type(self):
return self.op.params_type


class Variable(Node, Generic[_TypeType, OptionalApplyType]):
class Variable(Node, Generic[_TypeType, OptionalApplyType]): # noqa: UP046
r"""
A :term:`Variable` is a node in an expression graph that represents a
variable.
Expand Down Expand Up @@ -677,7 +677,7 @@ def clone(self, **kwargs):
return cp


class NominalVariable(Generic[_TypeType, _IdType], AtomicVariable[_TypeType]):
class NominalVariable(Generic[_TypeType, _IdType], AtomicVariable[_TypeType]): # noqa: UP046
"""A variable that enables alpha-equivalent comparisons."""

__instances__: dict[tuple["Type", Hashable], "NominalVariable"] = {}
Expand Down
4 changes: 2 additions & 2 deletions pytensor/graph/rewriting/unify.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from dataclasses import dataclass
from numbers import Number
from types import UnionType
from typing import Any, TypeAlias
from typing import Any

import numpy as np
from cons.core import ConsError, _car, _cdr
Expand Down Expand Up @@ -262,7 +262,7 @@ class LiteralString:
value: str


OpPatternOpTypeType: TypeAlias = type[Op] | tuple[type[Op], ...] | UnionType
type OpPatternOpTypeType = type[Op] | tuple[type[Op], ...] | UnionType


@dataclass(unsafe_hash=True)
Expand Down
10 changes: 5 additions & 5 deletions pytensor/graph/traversal.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


@overload
def walk(
def walk[T: Node](
nodes: Iterable[T],
expand: Callable[[T], Iterable[T] | None],
bfs: bool = True,
Expand All @@ -29,15 +29,15 @@ def walk(


@overload
def walk(
def walk[T: Node](
nodes: Iterable[T],
expand: Callable[[T], Iterable[T] | None],
bfs: bool,
return_children: Literal[True],
) -> Generator[NodeAndChildren, None, None]: ...


def walk(
def walk[T: Node](
nodes: Iterable[T],
expand: Callable[[T], Iterable[T] | None],
bfs: bool = True,
Expand Down Expand Up @@ -511,7 +511,7 @@ def truncated_graph_inputs(
return truncated_inputs


def walk_toposort(
def walk_toposort[T: Node](
graphs: Iterable[T],
deps: Callable[[T], Iterable[T] | None],
) -> Generator[T, None, None]:
Expand Down Expand Up @@ -579,7 +579,7 @@ def compute_deps_cache(obj, deps_cache=deps_cache):
raise ValueError("graph contains cycles")


def general_toposort(
def general_toposort[T: Node](
outputs: Iterable[T],
deps: Callable[[T], Iterable[T] | None],
compute_deps_cache: Callable[[T], Iterable[T] | None] | None = None,
Expand Down
6 changes: 3 additions & 3 deletions pytensor/graph/type.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
D = TypeVar("D")


class Type(MetaObject, Generic[D]):
class Type(MetaObject, Generic[D]): # noqa: UP046
"""
Interface specification for variable type instances.

Expand All @@ -23,12 +23,12 @@ class Type(MetaObject, Generic[D]):

"""

variable_type: TypeAlias = Variable
variable_type: TypeAlias = Variable # noqa: UP040
"""
The `Type` that will be created by a call to `Type.make_variable`.
"""

constant_type: TypeAlias = Constant
constant_type: TypeAlias = Constant # noqa: UP040
"""
The `Type` that will be created by a call to `Type.make_constant`.
"""
Expand Down
2 changes: 1 addition & 1 deletion pytensor/graph/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def simple_extract_stack(
return trace


def add_tag_trace(thing: T, user_line: int | None = None) -> T:
def add_tag_trace[T: "Apply" | "Variable"](thing: T, user_line: int | None = None) -> T:
"""Add tag.trace to a node or variable.

The argument is returned after being affected (inplace).
Expand Down
4 changes: 2 additions & 2 deletions pytensor/link/numba/dispatch/linalg/solvers/lu_solve.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections.abc import Callable
from typing import Literal, TypeAlias
from typing import Literal

import numpy as np
from numba.core.extending import overload
Expand All @@ -21,7 +21,7 @@
)


_Trans: TypeAlias = Literal[0, 1, 2]
type _Trans = Literal[0, 1, 2]


def _getrs(
Expand Down
4 changes: 2 additions & 2 deletions pytensor/scalar/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from collections.abc import Callable
from itertools import chain
from textwrap import dedent
from typing import Any, TypeAlias
from typing import Any

import numpy as np

Expand Down Expand Up @@ -790,7 +790,7 @@ def get_scalar_type(dtype, cache: dict[str, ScalarType] = {}) -> ScalarType:
complex64: ScalarType = get_scalar_type("complex64")
complex128: ScalarType = get_scalar_type("complex128")

_ScalarTypes: TypeAlias = tuple[ScalarType, ...]
type _ScalarTypes = tuple[ScalarType, ...]
int_types: _ScalarTypes = (int8, int16, int32, int64)
uint_types: _ScalarTypes = (uint8, uint16, uint32, uint64)
float_types: _ScalarTypes = (float16, float32, float64)
Expand Down
3 changes: 1 addition & 2 deletions pytensor/tensor/random/variable.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import copy
import warnings
from functools import wraps
from typing import TypeAlias

import numpy as np

Expand All @@ -12,7 +11,7 @@
from pytensor.tensor.variable import TensorVariable


RNG_AND_DRAW: TypeAlias = tuple["RandomGeneratorVariable", TensorVariable]
type RNG_AND_DRAW = tuple["RandomGeneratorVariable", TensorVariable]


def warn_reuse(func):
Expand Down
5 changes: 1 addition & 4 deletions pytensor/tensor/reshape.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from collections.abc import Iterable, Sequence
from itertools import pairwise
from typing import TypeAlias

import numpy as np
from numpy.lib._array_utils_impl import normalize_axis_index, normalize_axis_tuple
Expand All @@ -16,9 +15,7 @@
from pytensor.tensor.variable import TensorVariable


ShapeValueType: TypeAlias = (
int | np.integer | ScalarVariable | TensorVariable | np.ndarray
)
type ShapeValueType = int | np.integer | ScalarVariable | TensorVariable | np.ndarray


class JoinDims(Op):
Expand Down
4 changes: 2 additions & 2 deletions pytensor/tensor/subtensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
T = TypeVar("T")


def flatten_index_variables(
def flatten_index_variables[T](
idx_vars: Sequence[T | None | slice],
) -> tuple[list[int | slice], list[T]]:
counter = 0
Expand Down Expand Up @@ -99,7 +99,7 @@ def flatten_index_variables(
return idx_list, flat_vars


def unflatten_index_variables(
def unflatten_index_variables[T](
flat_indices: Sequence[T],
idx_list: Sequence[slice | int],
) -> tuple[slice | T, ...]:
Expand Down
3 changes: 1 addition & 2 deletions pytensor/xtensor/random/variable.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import copy
from typing import TypeAlias

import numpy as np

Expand All @@ -17,7 +16,7 @@
from pytensor.xtensor.type import XTensorVariable


XRNG_AND_DRAW: TypeAlias = tuple["XRandomGeneratorVariable", XTensorVariable]
type XRNG_AND_DRAW = tuple["XRandomGeneratorVariable", XTensorVariable]

__all__ = [
"XRandomGeneratorSharedVariable",
Expand Down
Loading