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
14 changes: 6 additions & 8 deletions .github/workflows/pr_code_check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [windows-latest, macos-latest, ubuntu-latest]
python-version: ["3.9", "3.12"]
platform: [windows-latest, ubuntu-latest, macos-15-intel, macos-15]
python-version: ["3.9", "3.12", "3.14", "3.15"]

runs-on: ${{ matrix.platform }}

Expand All @@ -35,16 +35,14 @@ jobs:
- name: Upgrade pip
run: python -m pip install --upgrade pip

- name: Installing dependencies
uses: py-actions/py-dependency-install@v4
with:
path: "requirements.txt"

- name: Add requirements
run: python -m pip install --upgrade setuptools wheel build packaging

- name: Build and install
run: pip install --verbose .

- name: Check optional dependency and PyTorch wheel policy logic
run: python -m unittest discover -s scripts/tests -p "test_*.py"

- name: Smoke test
run: python -c "import os, tempfile; os.chdir(tempfile.gettempdir()); import easygraph as eg; G = eg.Graph(); G.add_edge(1, 2); assert G.number_of_nodes() == 2; assert G.number_of_edges() == 1"
run: python scripts/wheel_smoke.py
18 changes: 15 additions & 3 deletions .github/workflows/wheel_publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
# sdist used to compile in user local environment
- name: Build sdist
run: pipx run build --sdist
Expand All @@ -24,13 +26,13 @@ jobs:
# macos-15-intel is for the x86_64
# note: Apple has discontinued support for the x86_64 (Intel) architecture
os: [ ubuntu-latest, windows-latest, macos-15, macos-15-intel]
# modify python version in project.toml
# modify Python versions in pyproject.toml
steps:
# 检出代码
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: true
submodules: recursive

- uses: actions/setup-python@v5

Expand All @@ -41,8 +43,18 @@ jobs:
run: python -m pip install --upgrade pip setuptools wheel build packaging


- name: Build wheels
# cibuildwheel 4 supports Python 3.15 but no longer supports Python 3.8.
- name: Build Python 3.8-3.13 wheels
uses: pypa/cibuildwheel@v2.23.3
env:
CIBW_BUILD: "cp38-* cp39-* cp310-* cp311-* cp312-* cp313-*"
with:
output-dir: dist/

- name: Build Python 3.14-3.15 wheels
uses: pypa/cibuildwheel@v4.3.0
env:
CIBW_BUILD: "cp314-* cp315-*"
with:
output-dir: dist/

Expand Down
7 changes: 6 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
include README.md
include CMakeLists.txt
recursive-include cpp_easygraph *
include scripts/wheel_smoke.py
include scripts/check_pytorch_support.py
include scripts/PYTHON_RELEASE.md
recursive-include scripts/tests *.py
include easygraph/_torch_compatibility.json
recursive-include cpp_easygraph *
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ It bridges the gap between EasyGraph and higher-order relationships. EasyHypergr

## Supported Versions

``3.8 <= Python <= 3.14`` is required.
``3.8 <= Python < 3.16`` is required.

## Installation With pip
```
Expand Down Expand Up @@ -146,9 +146,15 @@ If prebuilt EasyGraph wheels are not supported for your platform (OS / CPU arch,

## Hint

EasyGraph uses 1.12.1 <= [PyTorch](https://pytorch.org/get-started/locally/) < 2.0 for machine learning functions.
Note that this does not prevent your from running non-machine learning functions normally, if there is no PyTorch in your environment.
But you will receive some warnings which remind you some unavailable modules when they depend on it.
EasyGraph automatically installs a compatible PyTorch version when a compatible
stable wheel is listed in its release policy for your Python version, OS and CPU
on PyPI. Otherwise, core graph algorithms and the C++ backend remain available,
and importing EasyGraph shows one message linking to the [official PyTorch
installer](https://pytorch.org/get-started/locally/). Install PyTorch from there
and restart Python to enable its features. Additional graph-learning packages
may require `pip install 'Python-EasyGraph[torch]'` or their own installation
instructions. Maintainers can refresh the policy for a new Python release using
[the release checklist](scripts/PYTHON_RELEASE.md).

# Simple Example

Expand Down
16 changes: 10 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Install

- **Prerequisites**

``3.8 <= Python <= 3.11`` is required.
``3.8 <= Python < 3.16`` is required.

.. Installation with ``pip`` (outdated)

Expand All @@ -80,11 +80,15 @@ If prebuilt EasyGraph wheels are not supported for your platform (OS / CPU arch,

- **Hint**

EasyGraph uses 1.12.1 <= `PyTorch <https://pytorch.org/get-started/locally/>`_ < 2.0 for machine
learning functions.
Note that this does not prevent your from running non-machine learning functions normally,
if there is no PyTorch in your environment.
But you will receive some warnings which remind you some unavailable modules when they depend on it.
EasyGraph automatically installs a compatible PyTorch version when its release
policy lists a compatible stable wheel for your Python version, OS and CPU
on PyPI. Otherwise, core graph algorithms and the C++ backend remain available.
Importing EasyGraph shows one message with the
`official PyTorch installer <https://pytorch.org/get-started/locally/>`_.
Install PyTorch there and restart Python to enable its features. Additional
graph-learning packages may need ``Python-EasyGraph[torch]`` or their own
installation instructions. See ``scripts/PYTHON_RELEASE.md`` for the
repeatable release checklist.

Simple Example
--------------
Expand Down
10 changes: 9 additions & 1 deletion easygraph/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
import easygraph.readwrite
import easygraph.utils

from easygraph._optional import HAS_TORCH as _HAS_TORCH
from easygraph._optional import require_torch as _require_torch
from easygraph._optional import warn_missing_torch as _warn_missing_torch
from easygraph.classes import *
from easygraph.convert import *
from easygraph.datapipe import *
Expand All @@ -25,5 +28,10 @@
from easygraph.utils import *


_warn_missing_torch()


def __getattr__(name):
print(f"attr {name} doesn't exist!")
if not _HAS_TORCH and name in {"Hypergraph", "BaseHypergraph", "load_structure"}:
_require_torch(name)
raise AttributeError("module 'easygraph' has no attribute {!r}".format(name))
58 changes: 58 additions & 0 deletions easygraph/_optional.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"""Shared handling for optional machine-learning dependencies."""

import sys
import warnings

from contextlib import contextmanager


PYTORCH_INSTALL_URL = "https://pytorch.org/get-started/locally/"

try:
import torch as _torch
except ModuleNotFoundError as error:
if error.name != "torch":
raise
_torch = None

HAS_TORCH = _torch is not None


def require_torch(feature="This feature"):
if _torch is None:
raise ImportError(
"{} requires PyTorch. Install a build for your Python version and "
"platform using {}, then restart Python.".format(
feature, PYTORCH_INSTALL_URL
)
)
return _torch


def warn_missing_torch():
if not HAS_TORCH:
warnings.warn(
"EasyGraph: PyTorch is not installed for Python {}.{}. Core graph "
"algorithms and the C++ backend remain available. For PyTorch-based "
"features, install a compatible build using {} and restart Python.".format(
sys.version_info.major, sys.version_info.minor, PYTORCH_INSTALL_URL
),
UserWarning,
stacklevel=2,
)


@contextmanager
def optional_torch_modules():
"""Allow absent optional packages, while preserving unrelated import errors."""
try:
yield
except ModuleNotFoundError as error:
if error.name not in {
"torch",
"torch_geometric",
"torch_scatter",
"torch_sparse",
"sklearn",
}:
raise
Loading
Loading