Skip to content

feat(typing): add type annotations to whoosh.filedb.structfile (#193) - #194

Merged
priya-sundaram-dev merged 3 commits into
priya-sundaram-dev:mainfrom
webdevsamran:feat/193-structfile-type-annotations
Sep 13, 2026
Merged

priya-sundaram-dev merged 3 commits into
priya-sundaram-dev:mainfrom
webdevsamran:feat/193-structfile-type-annotations

Conversation

@webdevsamran

Copy link
Copy Markdown
Contributor

Summary

Adds type annotations to whoosh.filedb.structfile as requested in #193. Same annotations-only pattern as the recently merged util.numeric (#172), util.text (#175), util.varints (#179), and util.versions (#186) PRs.

What changed

src/whoosh/filedb/structfile.py � annotations only, zero behaviour changes:

  • StructFile.__init__: fileobj: BinaryIO, name: str | None, onclose: Callable[[StructFile], None] | None
  • All write_* methods: parameter types + -> None
  • All read_* methods: -> int, -> float, -> bytes, or -> array as appropriate
  • get_string2/get_string4: -> tuple[bytes, int]
  • Pass-through wrappers (read, write, seek, tell, truncate, readline): *args: Any, **kwargs: Any -> Any per issue spec
  • BufferFile.__init__: buf: bytes | bytearray | memoryview
  • BufferFile and ChecksumFile methods fully annotated
  • Callable moved to collections.abc (ruff UP035)
  • __exit__ uses type[BaseException] | None, BaseException | None, types.TracebackType | None (ruff PYI036)

CHANGELOG.md: entry added under [Unreleased] ? Typing.

Verification

ruff check src/whoosh/filedb/structfile.py     # All checks passed
ruff format --check src/whoosh/filedb/structfile.py  # 1 file already formatted
python -m pytest tests/test_misc.py tests/test_reading.py -q  # 23 passed

AI disclosure

Drafted with AI assistance (Gemini / Antigravity). All type signatures were derived directly from the method implementations and the suggested signatures in the issue body � no logic was altered.

Annotate StructFile, BufferFile, and ChecksumFile:
- __init__ params typed (BinaryIO, Callable, str | None)
- All write_* methods -> None
- All read_* methods return their value type (int, float, bytes, array, Any)
- All get_* positional helpers typed (int, int) -> (int | float | bytes | array)
- get_string2 / get_string4 return tuple[bytes, int]
- Pass-through wrappers (read, write, seek, tell, truncate, readline) use *args/
  **kwargs: Any -> Any per issue spec
- __exit__ uses type[BaseException] | None, BaseException | None,
  TracebackType | None (PYI036)
- Callable moved to collections.abc (UP035)
- No behaviour changes; ruff check/format clean; 23/23 tests pass

Closes priya-sundaram-dev#193

Signed-off-by: webdevsamran <[email protected]>

@priya-sundaram-dev priya-sundaram-dev left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @webdevsamran — this is your third typing PR and it shows: clean, mechanical, behaviour-preserving annotations exactly matching the pattern from #172/#175/#179/#186. I re-ran everything locally against the checked-out branch:

  • ruff check + ruff format --check → clean
  • python -m mypy (the public-API smoke fixture) → Success: no issues found
  • pytest tests/test_misc.py tests/test_reading.py tests/test_writing.py → 50 passed

A few things I especially liked: from __future__ import annotations so the StructFile/BufferFile forward refs resolve without quotes, Callable pulled from collections.abc (UP035), and the PYI036-correct __exit__ triple (type[BaseException] | None, BaseException | None, types.TracebackType | None). The *args: Any, **kwargs: Any -> Any pass-throughs are the right call for the thin wrappers.

Approving. One tiny nit (not blocking): line 255 in write_byte's docstring picked up a stray trailing backslash:

        ``file.write(chr(n))``.\

Since it's an unescaped line-continuation in a plain docstring it silently merges the closing-quote line, so the rendered __doc__ ends with . + 8 spaces instead of a newline — a small behaviour change that slips past the "annotations-only" intent. Easiest fix is to just drop the \ so it reads ``file.write(chr(n))``. again.

Happy to squash that out myself when I merge so you don't have to round-trip — but if you'd rather push the one-char fix to keep your commit clean, go for it and I'll merge right after. Either way, thank you for another solid contribution to the typing effort (#121).

@webdevsamran

Copy link
Copy Markdown
Contributor Author

Good catch on the docstring line-continuation! Dropped the stray backslash in c53f10d so the commit history stays clean. Thanks for the quick review and approval!

@priya-sundaram-dev

Copy link
Copy Markdown
Owner

Nice — history's clean now. One last thing before I merge: CI's ty hook (in Pre-commit) is failing, and it's actually a good catch that your annotations surfaced:

error[invalid-return-type]: Return type does not match returned value
   --> src/whoosh/filedb/structfile.py:102:16
101 |     def __str__(self) -> str:
102 |         return self._name
    |                ^^^^^^^^^^ expected `str`, found `str | None`

_name is str | None, so __str__ can return None. That's a pre-existing latent bug your typing work uncovered — verified it locally:

>>> str(StructFile(io.BytesIO(), name=None))
TypeError: __str__ returned non-string (type NoneType)

The minimal fix that keeps behavior for named files and satisfies ty:

def __str__(self) -> str:
    return self._name if self._name is not None else ""

That's a one-liner and fully in the spirit of this PR (making the types honest). Want to push it, or would you prefer I squash it in on merge with credit to you? Either's fine by me — just let me know. Thanks again for the careful work here. 🙏

@webdevsamran

Copy link
Copy Markdown
Contributor Author

Great catch by ty! Pushed commit b809c53 with the fix (return self._name if self._name is not None else "") along with a regression unit test in tests/test_misc.py verifying both name=None and name="test". ruff check, ruff format, and all 51 tests pass cleanly.

@priya-sundaram-dev
priya-sundaram-dev merged commit 29c63ef into priya-sundaram-dev:main Sep 13, 2026
@priya-sundaram-dev

Copy link
Copy Markdown
Owner

Merged — thank you, @webdevsamran! 🎉 This is exactly the kind of contribution I love to see: the annotations are clean, and your typing work surfaced (and fixed) a real latent bug in __str__ for unnamed StructFiles, complete with a regression test. Verified locally before merge: ruff check, ruff format --check, ty check, and the full test suite (908 passed) are all green.

If you enjoyed this, whoosh.filedb has a few more sibling modules that would benefit from the same treatment (filestore.py, filetables.py) — no pressure at all, but you would be very welcome. Thanks again for the careful, responsive work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants