Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
1b9c441
Fix __roi_query: check roi.end instead of roi.begin for upper-bound-o…
Feb 11, 2026
d99372a
Fix __roi_query: use half-open interval [begin, end) instead of BETWEEN
Feb 11, 2026
bb33cb1
Fix read_nodes: remove duplicate attr_filter application
Feb 11, 2026
d8fe16b
Fix read_edges: remove duplicate attr_filter application
Feb 11, 2026
d0b2dde
Fix write_nodes to pass through caller's fail_if_exists value
Feb 11, 2026
17f01b6
fix fail_if_exists flag on write_nodes
Feb 11, 2026
1f4fa7b
remove duplicate file
Feb 11, 2026
9f635b1
move code into a src directory to modernize this package
Feb 11, 2026
1e08cc9
update git ignore to ignore daisy logs
Feb 11, 2026
20ce725
ruff formatting and linting
Feb 11, 2026
8d3547d
add flag and tests for symetric edge fetching
Feb 11, 2026
09a9fce
add symetric edge fetching to SQLGraphProviders
Feb 11, 2026
59542c8
throw error when both roi and nodes passed to read edges.
Feb 11, 2026
92bebc5
handle read edges cases better.
Feb 11, 2026
213c3d8
add uv.lock to gitignore
Feb 11, 2026
4523594
Connect to postgresql db with environment variables if available.
Feb 11, 2026
dde9049
Add bulk write api and tests
Feb 11, 2026
0d61ab7
Generalize the bulk write api to all graph providers
Feb 11, 2026
39a9f80
make tests more reliable with a context manager to handle closing con…
Feb 11, 2026
02f9cec
add and use a `bulk_write_mode` context manager for bulk writes
Feb 11, 2026
3cc4754
add test for node exclusion on upper bound of ROI
Feb 11, 2026
5c5489c
ints should be stored as bigint. cost is small and makes dealing with…
Feb 11, 2026
2cece20
ruff formatting and linting
Feb 11, 2026
f655129
fix mypy errors
Feb 11, 2026
c8a4306
fix mypy workflow file
Feb 11, 2026
8c4b9a2
Pass ty checks
Feb 11, 2026
e2e8a0e
pass ty linting on arrays
Feb 11, 2026
aacfbc8
switch from mypy to ty
Feb 11, 2026
ad1a0fc
pass tests on zarr v3
pattonw May 14, 2025
e60b7ef
use `tmp_path` fixture over legacy `tmpdir`
pattonw May 14, 2025
4333319
get rid of zarr.attrs import
Feb 11, 2026
baac4b4
remove num_codecs pin
Feb 12, 2026
3c878f7
fix ty checks
Feb 12, 2026
1d339d2
bump version and fix ruff formatting
pattonw Feb 13, 2026
ab03354
update test suite to drop old python versions and add newer versions
pattonw Feb 13, 2026
0e05195
resolve ty errors
pattonw Feb 13, 2026
06f2046
remove custom ty error handling
pattonw Feb 13, 2026
d5b3e7d
update dependencies to pass python 3.13 tests
pattonw Feb 13, 2026
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
2 changes: 1 addition & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12"]
python-version: ["3.11", "3.12", "3.13"]
resolution: ["highest", "lowest-direct"]

services:
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/mypy.yaml → .github/workflows/ty.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
name: mypy
name: ty

on: [push, pull_request]

jobs:
static-analysis:
name: Python mypy
name: Python ty
runs-on: ubuntu-latest
steps:
- name: Setup checkout
uses: actions/checkout@master
- name: Install uv
uses: astral-sh/setup-uv@main
- name: mypy
run: uv run --extra dev mypy funlib/persistence tests
- name: ty
run: uv run --extra dev ty check src tests
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,5 @@ dmypy.json
.vscode/

*.sw[pmno]
daisy_logs
uv.lock
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[![tests](https://github.com/funkelab/funlib.persistence/actions/workflows/tests.yaml/badge.svg)](https://github.com/funkelab/funlib.persistence/actions/workflows/tests.yaml)
[![ruff](https://github.com/funkelab/funlib.persistence/actions/workflows/ruff.yaml/badge.svg)](https://github.com/funkelab/funlib.persistence/actions/workflows/ruff.yaml)
[![mypy](https://github.com/funkelab/funlib.persistence/actions/workflows/mypy.yaml/badge.svg)](https://github.com/funkelab/funlib.persistence/actions/workflows/mypy.yaml)
[![ty](https://github.com/funkelab/funlib.persistence/actions/workflows/ty.yaml/badge.svg)](https://github.com/funkelab/funlib.persistence/actions/workflows/ty.yaml)
[![pypi](https://github.com/funkelab/funlib.persistence/actions/workflows/publish.yaml/badge.svg)](https://pypi.org/project/funlib.persistence/)

# funlib.persistence
Expand Down
5 changes: 0 additions & 5 deletions funlib/persistence/arrays/lazy_ops.py

This file was deleted.

206 changes: 0 additions & 206 deletions funlib/persistence/graphs/pgsql_graph_database.py

This file was deleted.

18 changes: 6 additions & 12 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,21 @@ authors = [
]
dynamic = ['version']

requires-python = ">=3.10"
requires-python = ">=3.11"
classifiers = ["Programming Language :: Python :: 3"]
keywords = []

dependencies = [
"zarr>=2,<3",
# ImportError: cannot import name 'cbuffer_sizes' from 'numcodecs.blosc'
# We can pin zarr to >2.18.7 but then we have to drop python 3.10
# pin numcodecs to avoid breaking change
"numcodecs>0.13,<0.16.0",
"iohub>=0.2.0b0",
"zarr>=3,<4",
"iohub>=0.3.0a5",
"funlib.geometry>=0.3.0",
"networkx>=3.0.0",
"pymongo>=4.0.0",
"numpy>=2.0.0",
"pydantic>=2.0.0",
"dask>=2024.0.0",
"toml>=0.10.0",
"psycopg2-binary>=2.9.5",
"psycopg2-binary>=2.9.11",
]

[tool.setuptools.dynamic]
Expand All @@ -40,10 +36,10 @@ version = { attr = "funlib.persistence.__version__" }
[project.optional-dependencies]
dev = [
"coverage>=7.7.1",
"mypy>=1.15.0",
"pytest>=8.3.5",
"pytest-mock>=3.14.0",
"ruff>=0.11.2",
"ty>=0.0.16",
"types-networkx",
"types-psycopg2",
"types-toml",
Expand All @@ -56,10 +52,8 @@ lint.select = ["F", "W", "I001"]
[tool.setuptools.package-data]
"funlib.persistence" = ["py.typed"]

[tool.mypy]
explicit_package_bases = true

# # module specific overrides
[[tool.mypy.overrides]]
module = ["zarr.*", "iohub.*"]
ignore_missing_imports = true

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .arrays import Array, open_ds, prepare_ds, open_ome_ds, prepare_ome_ds # noqa

__version__ = "0.6.1"
__version__ = "0.7.0"
__version_info__ = tuple(int(i) for i in __version__.split("."))
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
import dask.array as da
import numpy as np
from dask.array.optimization import fuse_slice
from zarr import Array as ZarrArray

from funlib.geometry import Coordinate, Roi
from zarr import Array as ZarrArray

from .freezable import Freezable
from .lazy_ops import LazyOp
Expand Down Expand Up @@ -135,7 +134,7 @@ def attrs(self) -> dict:

@property
def chunk_shape(self) -> Coordinate:
return Coordinate(self.data.chunksize)
return Coordinate(self.data.chunksize) # ty: ignore[unresolved-attribute]

def uncollapsed_dims(self, physical: bool = False) -> list[bool]:
"""
Expand Down Expand Up @@ -344,18 +343,21 @@ def __getitem__(self, key) -> np.ndarray:
else:
return self.data[key].compute()

def __setitem__(self, key, value: np.ndarray):
"""Set the data of this array within the given ROI.
def __setitem__(self, key: Roi | slice | tuple, value: np.ndarray | float | int):
"""Set the data of this array.

Args:

key (`class:Roi`):
key (`class:Roi` or any numpy compatible key):

The ROI to write to.
The region to write to. Can be a `Roi` for world-unit indexing,
or any numpy-compatible key (e.g. ``np.s_[:]``, a slice, a tuple
of slices).

value (``ndarray``):
value (``ndarray`` or scalar):

The value to write.
The value to write. Can be a numpy array or a scalar that will
be broadcast.
"""

if self.is_writeable:
Expand Down Expand Up @@ -474,7 +476,7 @@ def _is_slice(self, lazy_op: LazyOp, writeable: bool = False) -> bool:
elif isinstance(lazy_op, list) and all([isinstance(a, int) for a in lazy_op]):
return True
elif isinstance(lazy_op, tuple) and all(
[self._is_slice(a, writeable) for a in lazy_op]
[self._is_slice(a, writeable) for a in lazy_op] # type: ignore[arg-type] # ty can't narrow parameterized tuple iteration
):
return True
elif (
Expand Down Expand Up @@ -508,7 +510,7 @@ def validate(self, strict: bool = False):
)

def to_pixel_space(
self, world_loc: Roi | Coordinate | Sequence[int | float]
self, world_loc: Roi | Coordinate | Sequence[int | float] | np.ndarray
) -> Roi | Coordinate | np.ndarray:
"""Convert a point or roi in world space into the pixel space of this array.
Works on sequences of floats by returning a numpy array that is not guaranteed
Expand Down Expand Up @@ -539,7 +541,7 @@ def to_pixel_space(
)

def to_world_space(
self, pixel_loc: Roi | Coordinate | Sequence[int | float]
self, pixel_loc: Roi | Coordinate | Sequence[int | float] | np.ndarray
) -> Roi | Coordinate:
"""Convert a point or roi from pixel space in this array to the world
coordinate system defined by this array's roi and voxel size.
Expand Down
Loading