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
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, macos-14]
python-version: ['3.10', '3.11', '3.12', '3.13']
os: [ubuntu-latest, macos-15]
python-version: ['3.11', '3.12', '3.13', '3.14']

steps:
- uses: actions/checkout@v4
Expand Down
4 changes: 2 additions & 2 deletions benchmark/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import psutil
import logging
import threading
from typing import List, Tuple, Dict, Any, Optional
from typing import List, Dict
from dataclasses import dataclass

# Default configuration
Expand Down Expand Up @@ -123,7 +123,7 @@ def _get_process_memory(self) -> float:
process = psutil.Process(os.getpid())
return process.memory_info().rss / 1024 / 1024

def _find_cachesim_binary(self) -> Optional[str]:
def _find_cachesim_binary(self) -> str | None:
"""Find the cachesim binary in common locations."""
possible_paths = [
"./src/libCacheSim/build/bin/cachesim",
Expand Down
2 changes: 1 addition & 1 deletion docs/src/en/developer.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ that links keep working in local builds and under the locale fallback.

| Workflow | Trigger | What it does |
|---|---|---|
| `.github/workflows/build.yml` | changes under `src/`, `libcachesim/`, `tests/` | Builds and tests on Ubuntu and macOS (Intel and Apple Silicon) across Python 3.10–3.13, and separately builds the docs |
| `.github/workflows/build.yml` | changes under `src/`, `libcachesim/`, `tests/` | Builds and tests on Ubuntu and macOS (Apple Silicon) across Python 3.11–3.14, and separately builds the docs |
| `.github/workflows/docs.yml` | changes under `docs/` | Builds with `--strict` and deploys to GitHub Pages on `main` |
| `.github/workflows/pypi-release.yml` | published release, or manual dispatch | Builds wheels with cibuildwheel and publishes to PyPI |

Expand Down
2 changes: 1 addition & 1 deletion docs/src/en/getting_started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
| | |
|---|---|
| **OS** | Linux / macOS |
| **Python** | 3.10 -- 3.13 |
| **Python** | 3.11 -- 3.14 |
| **Architecture** | x86_64 / aarch64 |

Windows is not supported.
Expand Down
2 changes: 1 addition & 1 deletion docs/src/en/getting_started/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This guide will help you get started with libCacheSim.
## Prerequisites

- OS: Linux / macOS
- Python: 3.10 -- 3.13
- Python: 3.11 -- 3.14

## Installation

Expand Down
2 changes: 1 addition & 1 deletion docs/src/zh/developer.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ cd docs && mkdocs build --clean --strict

| 工作流 | 触发条件 | 作用 |
|---|---|---|
| `.github/workflows/build.yml` | `src/`、`libcachesim/`、`tests/` 下的改动 | 在 Ubuntu 和 macOS(Intel 与 Apple Silicon)上针对 Python 3.10–3.13 构建并测试,同时单独构建文档 |
| `.github/workflows/build.yml` | `src/`、`libcachesim/`、`tests/` 下的改动 | 在 Ubuntu 和 macOS(Apple Silicon)上针对 Python 3.11–3.14 构建并测试,同时单独构建文档 |
| `.github/workflows/docs.yml` | `docs/` 下的改动 | 以 `--strict` 构建,并在 `main` 分支上部署到 GitHub Pages |
| `.github/workflows/pypi-release.yml` | 发布 release,或手动触发 | 用 cibuildwheel 构建 wheel 并发布到 PyPI |

Expand Down
2 changes: 1 addition & 1 deletion docs/src/zh/getting_started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
| | |
|---|---|
| **操作系统** | Linux / macOS |
| **Python** | 3.10 -- 3.13 |
| **Python** | 3.11 -- 3.14 |
| **架构** | x86_64 / aarch64 |

不支持 Windows。
Expand Down
2 changes: 1 addition & 1 deletion docs/src/zh/getting_started/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
## 前置条件

- 操作系统:Linux / macOS
- Python:3.10 -- 3.13
- Python:3.11 -- 3.14

## 安装

Expand Down
86 changes: 43 additions & 43 deletions libcachesim/__init__.pyi

Large diffs are not rendered by default.

11 changes: 5 additions & 6 deletions libcachesim/_s3_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import re
import shutil
from pathlib import Path
from typing import Optional, Union
from urllib.parse import urlparse

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -48,7 +47,7 @@ class _DataLoader:
}

def __init__(
self, bucket_name: str = DEFAULT_BUCKET, cache_dir: Optional[Union[str, Path]] = None, use_auth: bool = False
self, bucket_name: str = DEFAULT_BUCKET, cache_dir: str | Path | None = None, use_auth: bool = False
):
self.bucket_name = self._validate_bucket_name(bucket_name)
self.cache_dir = Path(cache_dir) if cache_dir else self.DEFAULT_CACHE_DIR
Expand Down Expand Up @@ -201,7 +200,7 @@ def _download(self, key: str, dest: Path) -> None:
temp.unlink()
raise RuntimeError(f"Download failed for s3://{self.bucket_name}/{key}: {e}")

def load(self, key: str, force: bool = False, mode: str = "rb") -> Union[bytes, str]:
def load(self, key: str, force: bool = False, mode: str = "rb") -> bytes | str:
path = self._cache_path(key)
if not path.exists() or force:
self._download(key, path)
Expand All @@ -221,7 +220,7 @@ def is_cached(self, key: str) -> bool:
except ValueError:
return False

def clear_cache(self, key: Optional[str] = None) -> None:
def clear_cache(self, key: str | None = None) -> None:
if key:
try:
path = self._cache_path(key)
Expand Down Expand Up @@ -270,7 +269,7 @@ def list_s3_objects(self, prefix: str = "", delimiter: str = "/") -> dict:
_data_loader = _DataLoader()


def set_cache_dir(cache_dir: Union[str, Path]) -> None:
def set_cache_dir(cache_dir: str | Path) -> None:
"""
Set the global cache directory for S3 downloads.

Expand Down Expand Up @@ -300,7 +299,7 @@ def get_cache_dir() -> Path:
return _data_loader.cache_dir


def clear_cache(s3_path: Optional[str] = None) -> None:
def clear_cache(s3_path: str | None = None) -> None:
"""
Clear cached files.

Expand Down
8 changes: 4 additions & 4 deletions libcachesim/cache.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from abc import ABC
import logging
from typing import Callable, Optional
from typing import Callable
from .libcachesim_python import (
CommonCacheParams,
Request,
Expand Down Expand Up @@ -65,7 +65,7 @@ def __init__(self, _cache: Cache, admissioner: AdmissionerBase = None):
def get(self, req: Request) -> bool:
return self._cache.get(req)

def find(self, req: Request, update_cache: bool = True) -> Optional[CacheObject]:
def find(self, req: Request, update_cache: bool = True) -> CacheObject | None:
return self._cache.find(req, update_cache)

def can_insert(self, req: Request) -> bool:
Expand Down Expand Up @@ -431,7 +431,7 @@ def __init__(
admissioner=admissioner
)

def insert(self, req: Request) -> Optional[CacheObject]:
def insert(self, req: Request) -> CacheObject | None:
return super().insert(req)


Expand Down Expand Up @@ -974,7 +974,7 @@ def __init__(
cache_miss_hook: Callable,
cache_eviction_hook: Callable,
cache_remove_hook: Callable,
cache_free_hook: Optional[Callable] = None,
cache_free_hook: Callable | None = None,
cache_name: str = "PythonHookCache",
default_ttl: int = 86400 * 300,
hashpower: int = 24,
Expand Down
17 changes: 8 additions & 9 deletions libcachesim/synthetic_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import numpy as np
import random
from typing import Optional, Union, Any
from collections.abc import Iterator
from .libcachesim_python import Request, ReqOp

Expand Down Expand Up @@ -44,10 +43,10 @@ def __init__(
obj_size: int = 4000,
time_span: int = 86400 * 7,
start_obj_id: int = 0,
seed: Optional[int] = None,
seed: int | None = None,
alpha: float = 1.0,
dist: str = "zipf",
num_objects: Optional[int] = None,
num_objects: int | None = None,
):
"""
Initialize synthetic reader.
Expand Down Expand Up @@ -92,7 +91,7 @@ def __init__(
random.seed(seed)

# Lazy generation: generate object IDs only when needed
self._obj_ids: Optional[np.ndarray] = None
self._obj_ids: np.ndarray | None = None

@property
def obj_ids(self) -> np.ndarray:
Expand Down Expand Up @@ -226,7 +225,7 @@ def __next__(self) -> Request:

return self.read_one_req()

def __getitem__(self, key: Union[int, slice]) -> Union[Request, SyntheticReaderSliceIterator]:
def __getitem__(self, key: int | slice) -> Request | SyntheticReaderSliceIterator:
"""Support index and slice access"""
if isinstance(key, slice):
# Handle slice
Expand Down Expand Up @@ -309,7 +308,7 @@ def __init__(
obj_size: int = 4000,
time_span: int = 86400 * 7,
start_obj_id: int = 0,
seed: Optional[int] = None,
seed: int | None = None,
):
"""Initialize base request generator."""
if num_objects <= 0 or num_requests <= 0:
Expand Down Expand Up @@ -362,7 +361,7 @@ def __init__(
obj_size: int = 4000,
time_span: int = 86400 * 7,
start_obj_id: int = 0,
seed: Optional[int] = None,
seed: int | None = None,
):
"""Initialize Zipf request generator."""
if alpha < 0:
Expand Down Expand Up @@ -390,7 +389,7 @@ def create_zipf_requests(
obj_size: int = 4000,
time_span: int = 86400 * 7,
start_obj_id: int = 0,
seed: Optional[int] = None,
seed: int | None = None,
) -> _ZipfRequestGenerator:
"""Create a Zipf-distributed request generator.

Expand Down Expand Up @@ -423,7 +422,7 @@ def create_uniform_requests(
obj_size: int = 4000,
time_span: int = 86400 * 7,
start_obj_id: int = 0,
seed: Optional[int] = None,
seed: int | None = None,
) -> _UniformRequestGenerator:
"""Create a uniform-distributed request generator.

Expand Down
8 changes: 4 additions & 4 deletions libcachesim/trace_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from __future__ import annotations

import logging
from typing import overload, Union, Optional, Any
from typing import overload
from collections.abc import Iterator
from urllib.parse import urlparse

Expand Down Expand Up @@ -105,9 +105,9 @@ def __init__(self, trace: Reader) -> None: ...

def __init__(
self,
trace: Union[Reader, str],
trace: Reader | str,
trace_type: TraceType = TraceType.UNKNOWN_TRACE,
reader_init_params: Optional[ReaderInitParam] = None,
reader_init_params: ReaderInitParam | None = None,
):
if isinstance(trace, Reader):
self._reader = trace
Expand Down Expand Up @@ -375,7 +375,7 @@ def __next__(self) -> Request:
raise StopIteration
return req

def __getitem__(self, key: Union[int, slice]) -> Union[Request, TraceReaderSliceIterator]:
def __getitem__(self, key: int | slice) -> Request | TraceReaderSliceIterator:
if isinstance(key, slice):
# Handle slice
total_len = self._reader.get_num_of_req()
Expand Down
9 changes: 3 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ name = "libcachesim"
version = "0.3.5"
description="Python bindings for libCacheSim"
readme = "README.md"
requires-python = ">=3.10"
requires-python = ">=3.11"
keywords = ["performance", "cache", "simulator"]
classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"numpy>=1.20.0",
Expand Down Expand Up @@ -77,7 +77,7 @@ strip = false
manylinux-x86_64-image = "quay.io/pypa/manylinux_2_34_x86_64"
manylinux-aarch64-image = "quay.io/pypa/manylinux_2_34_aarch64"

build = ["cp39-*", "cp310-*", "cp311-*", "cp312-*", "cp313-*"]
build = ["cp311-*", "cp312-*", "cp313-*", "cp314-*"]
skip = ["*-win32", "*-manylinux_i686", "*-musllinux*", "pp*"]

# Set the environment variable for the wheel build step.
Expand Down Expand Up @@ -126,7 +126,4 @@ ignore = [
"B007",
# f-string format
"UP032",
# Can remove once 3.10+ is the minimum Python version
"UP007",
"UP045"
]
Loading