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
7 changes: 2 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.9 - 3.14"
python-version: "3.10 - 3.14"
update-environment: true

- name: Upgrade pip
Expand Down Expand Up @@ -146,7 +146,6 @@ jobs:
- { runner: windows-latest, platform: windows, archs: "auto32" }
- { runner: windows-11-arm, platform: windows, archs: "ARM64" }
python-version:
- "3.9"
- "3.10"
- "3.11"
- "3.12"
Expand All @@ -157,8 +156,6 @@ jobs:
- "pypy-3.11"
exclude:
# Exclude unsupported Python versions
- python-version: "3.9"
target: { archs: "ARM64" }
- python-version: "3.10"
target: { archs: "ARM64" }
- python-version: "pypy-3.11"
Expand Down Expand Up @@ -387,7 +384,7 @@ jobs:
if: startsWith(github.ref, 'refs/tags/')
uses: actions/setup-python@v6
with:
python-version: "3.9 - 3.14"
python-version: "3.10 - 3.14"
update-environment: true

- name: Upgrade pip
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/tests-with-pydebug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,13 @@ jobs:
matrix:
runner: [ubuntu-latest, macos-latest, windows-latest]
python-version:
- "3.9"
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "3.14"
python-abiflags: ["d", "td"]
exclude:
- python-version: "3.9"
python-abiflags: "td"
- python-version: "3.10"
python-abiflags: "td"
- python-version: "3.11"
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ jobs:
matrix:
runner: [ubuntu-latest, macos-latest, windows-latest]
python-version:
- "3.9"
- "3.10"
- "3.11"
- "3.12"
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Removed

-
- Drop Python 3.9 support by [@XuehaiPan](https://github.com/XuehaiPan) in [#272](https://github.com/metaopt/optree/pull/272).

------

Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,13 @@ python3 -m cibuildwheel --platform=linux --output-dir=wheelhouse --config-file=p
It will build wheel binaries for all supported CPython versions. The outputs will be placed in the `wheelhouse` directory.

To build a wheel for a specific CPython version, you can use the [`CIBW_BUILD`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-skip) environment variable.
For example, the following command will build a wheel for Python 3.9:
For example, the following command will build a wheel for Python 3.10:

```bash
CIBW_BUILD="cp39*manylinux*" python3 -m cibuildwheel --platform=linux --output-dir=wheelhouse --config-file=pyproject.toml
CIBW_BUILD="cp310*manylinux*" python3 -m cibuildwheel --platform=linux --output-dir=wheelhouse --config-file=pyproject.toml
```

You can change `cp39*` to `cp312*` to build for Python 3.12. See <https://cibuildwheel.readthedocs.io/en/stable/options> for more options.
You can change `cp310*` to `cp312*` to build for Python 3.12. See <https://cibuildwheel.readthedocs.io/en/stable/options> for more options.

## Documentation

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# OpTree

![Python 3.9+](https://img.shields.io/badge/Python-3.9%2B-brightgreen)
![Python 3.10+](https://img.shields.io/badge/Python-3.10%2B-brightgreen)
[![PyPI](https://img.shields.io/pypi/v/optree?logo=pypi)](https://pypi.org/project/optree)
![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/metaopt/optree/build.yml?label=build&logo=github)
![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/metaopt/optree/tests.yml?label=tests&logo=github)
Expand Down Expand Up @@ -71,7 +71,7 @@ export pybind11_DIR="/path/to/custom/pybind11"
pip3 install .
```

Compiling from source requires Python 3.9+, a C++ compiler (`g++` / `clang++` / `icpx` / `cl.exe`) that supports C++20, and a `cmake` installation.
Compiling from source requires Python 3.10+, a C++ compiler (`g++` / `clang++` / `icpx` / `cl.exe`) that supports C++20, and a `cmake` installation.

--------------------------------------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ def matches_pytree_typing_alias(

return all(
matches_pytree_typing_alias(arg, pat, recursive_pattern, recursive_ref_names)
for arg, pat in zip(annotation_args, pattern_args)
for arg, pat in zip(annotation_args, pattern_args, strict=True)
)

for pytree_alias, pytree_instance in tuple(PyTree.__instances__.items()):
Expand Down
4 changes: 2 additions & 2 deletions include/optree/pymacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ limitations under the License.

#include <pybind11/pybind11.h>

#if !(defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x03090000) // Python 3.9
# error "Python 3.9 or newer is required."
#if !(defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x030A0000) // Python 3.10
# error "Python 3.10 or newer is required."
#endif

#if !(defined(PYBIND11_VERSION_HEX) && PYBIND11_VERSION_HEX >= 0x020C00F0) // pybind11 2.12.0
Expand Down
27 changes: 10 additions & 17 deletions optree/accessors.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from __future__ import annotations

import dataclasses
import sys
from collections.abc import Iterable, Mapping, Sequence
from typing import TYPE_CHECKING, Any, ClassVar, Generic, Literal, TypeVar, overload
from typing_extensions import Self # Python 3.11+
Expand Down Expand Up @@ -47,10 +46,7 @@
]


SLOTS = {'slots': True} if sys.version_info >= (3, 10) else {} # Python 3.10+


@dataclasses.dataclass(init=True, repr=False, eq=False, frozen=True, **SLOTS)
@dataclasses.dataclass(init=True, repr=False, eq=False, frozen=True, slots=True)
class PyTreeEntry:
"""Base class for path entries."""

Expand Down Expand Up @@ -122,9 +118,6 @@ def codify(self, /, node: str = '') -> str:
return f'{node}[<flat index {self.entry!r}>]' # should be overridden


del SLOTS


_T = TypeVar('_T')
_T_co = TypeVar('_T_co', covariant=True)
_KT_co = TypeVar('_KT_co', covariant=True)
Expand All @@ -134,7 +127,7 @@ def codify(self, /, node: str = '') -> str:
class AutoEntry(PyTreeEntry):
"""A generic path entry class that determines the entry type on creation automatically."""

__slots__: ClassVar[tuple[()]] = ()
__slots__: ClassVar[tuple[()]] = () # type: ignore[misc]

def __new__( # type: ignore[misc]
cls,
Expand Down Expand Up @@ -184,7 +177,7 @@ def __new__( # type: ignore[misc]
class GetItemEntry(PyTreeEntry):
"""A generic path entry class for nodes that access their children by :meth:`__getitem__`."""

__slots__: ClassVar[tuple[()]] = ()
__slots__: ClassVar[tuple[()]] = () # type: ignore[misc]

def __call__(self, obj: Any, /) -> Any:
"""Get the child object."""
Expand All @@ -198,7 +191,7 @@ def codify(self, /, node: str = '') -> str:
class GetAttrEntry(PyTreeEntry):
"""A generic path entry class for nodes that access their children by :meth:`__getattr__`."""

__slots__: ClassVar[tuple[()]] = ()
__slots__: ClassVar[tuple[()]] = () # type: ignore[misc]

entry: str

Expand All @@ -219,13 +212,13 @@ def codify(self, /, node: str = '') -> str:
class FlattenedEntry(PyTreeEntry): # pylint: disable=too-few-public-methods
"""A fallback path entry class for flattened objects."""

__slots__: ClassVar[tuple[()]] = ()
__slots__: ClassVar[tuple[()]] = () # type: ignore[misc]


class SequenceEntry(GetItemEntry, Generic[_T_co]):
"""A path entry class for sequences."""

__slots__: ClassVar[tuple[()]] = ()
__slots__: ClassVar[tuple[()]] = () # type: ignore[misc]

entry: int
type: builtins.type[Sequence[_T_co]]
Expand All @@ -247,7 +240,7 @@ def __repr__(self, /) -> str:
class MappingEntry(GetItemEntry, Generic[_KT_co, _VT_co]):
"""A path entry class for mappings."""

__slots__: ClassVar[tuple[()]] = ()
__slots__: ClassVar[tuple[()]] = () # type: ignore[misc]

entry: _KT_co
type: builtins.type[Mapping[_KT_co, _VT_co]]
Expand All @@ -269,7 +262,7 @@ def __repr__(self, /) -> str:
class NamedTupleEntry(SequenceEntry[_T]):
"""A path entry class for namedtuple objects."""

__slots__: ClassVar[tuple[()]] = ()
__slots__: ClassVar[tuple[()]] = () # type: ignore[misc]

entry: int
type: builtins.type[NamedTuple[_T]] # type: ignore[type-arg]
Expand Down Expand Up @@ -299,7 +292,7 @@ def codify(self, /, node: str = '') -> str:
class StructSequenceEntry(SequenceEntry[_T]):
"""A path entry class for PyStructSequence objects."""

__slots__: ClassVar[tuple[()]] = ()
__slots__: ClassVar[tuple[()]] = () # type: ignore[misc]

entry: int
type: builtins.type[StructSequence[_T]]
Expand Down Expand Up @@ -329,7 +322,7 @@ def codify(self, /, node: str = '') -> str:
class DataclassEntry(GetAttrEntry):
"""A path entry class for dataclasses."""

__slots__: ClassVar[tuple[()]] = ()
__slots__: ClassVar[tuple[()]] = () # type: ignore[misc]

entry: str | int # type: ignore[assignment]

Expand Down
Loading
Loading