Skip to content

Answer what shape a file is, without reading it - #156

Merged
martin-s-a merged 3 commits into
mainfrom
bind-the-shape-queries
Sep 20, 2026
Merged

martin-s-a merged 3 commits into
mainfrom
bind-the-shape-queries

Conversation

@martin-s-a

Copy link
Copy Markdown
Contributor

Item 3a of the backlog, and the half of the batch source work that carries no
threads and no GIL.

Sizing the destination of a batch read means knowing the shape of one image or
volume before allocating anything. rexlib gained query_extents and
query_core_extents in gigabit-clowns/rexlib#461; this binds them.

>>> image.query_extents(path)        # slowest axis first, the whole file
(120, 4096, 4096)
>>> image.query_core_extents(path)   # the axes it stacks along left out
(4096, 4096)

The second is the one that matters: its documentation upstream calls it "the
shape of a single image or volume, which is what the destination of a batch
carries beside its leading extent", so none of that arithmetic has to be
reproduced here.

Three choices worth naming

Extents come back as tuples, built explicitly rather than let through as
lists. A shape is a tuple everywhere else in this package after #153, and a
query that answered with a list would be the odd one out for no reason.

The wrapper takes the path first. C++ has query_extents(formats, path);
the Python layer is query_extents(path, manager=None). This is the first
place the second layer reorders arguments rather than only defaulting them,
and it is the point of the layer: leaving the manager first would force every
caller to fetch one, which is exactly what defaulting exists to avoid. The
binding underneath keeps the C++ order with both arguments required.

The overloads over a reader provider are not here. They take an
image_reader_provider&, and nothing binds a provider yet — that arrives with
3b, which binds the whole chain. Worth noting for then: those take a non-const
reference where the format manager ones take a const one, since a caching
provider mutates as it opens.

The submodule moves

external/rexlib goes from 741b262 to 43bbffec. Not incidental — the code
here now needs a rexlib that has these functions, and CI overriding the pin
with git submodule update --remote would hide that from anyone cloning and
building by the README.

Checked

  • Compiles clean under g++ -std=c++20 -fsyntax-only -Wall -Wextra -Wpedantic
    against the updated submodule.
  • ruff check . passes; 47 tests collect under tests/em/image/.
  • The tests assert only what is verifiable without knowing a format's internals:
    that a written file reports the extents it was written with, that both
    answers are tuples, that the core is the tail of the whole whatever the rank,
    and that what comes back sizes a destination. The failure case is
    RuntimeError for the same reason as the neighbouring tests — a file no
    format claims reaches invalid_operation_error, which derives from
    std::logic_error.

🤖 Generated with Claude Code

Sizing the destination of a batch read means knowing the shape of one image
or volume, and rexlib now answers that without the caller opening anything.
The manager is defaulted the way it is for read and write, so a caller asks
about a path and nothing else, and the extents come back as a tuple to agree
with every other shape this package reports.

The overloads over a reader provider are left until the provider is bound.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@martin-s-a martin-s-a self-assigned this Sep 20, 2026
@martin-s-a martin-s-a added the enhancement New feature or request label Sep 20, 2026
@martin-s-a
martin-s-a enabled auto-merge (squash) September 20, 2026 16:26
@sonarqubecloud

Copy link
Copy Markdown

@martin-s-a
martin-s-a merged commit 4d56188 into main Sep 20, 2026
36 checks passed
@martin-s-a
martin-s-a deleted the bind-the-shape-queries branch September 20, 2026 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants