Skip to content

Bridge checker: read a MATLAB transpose as a transpose; bridge sqlitedb's 8 public statics - #91

Merged
stevevanhooser merged 3 commits into
mainfrom
claude/bridge-checker-transpose-fix
Oct 23, 2026
Merged

stevevanhooser merged 3 commits into
mainfrom
claude/bridge-checker-transpose-fix

Conversation

@stevevanhooser

@stevevanhooser stevevanhooser commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up to #90.

The checker bug

_strip_comment and _outside_brackets in bin/check_bridge_coverage.py treated an unquoted ' as the start of a string unless the previous output character was an identifier. After a closing bracket, that output character has already been blanked to a space. So in sqlitedb.m's run_sql_noOpen, the transpose in

try varargin = reshape(varargin,[],numRows)'; catch, end %#ok<NASGU>

was read as opening a string, and the end went uncounted. Every method after that line in the block was attributed to nothing, including the whole methods (Static, Access=public) block, so the missing check never saw its 8 public methods. close_db was hidden too, but its entry still resolved because did.database also defines one.

Fix: a ' is now a transpose when the source character before it is an identifier character, a closing bracket, . or another '. Regression tests are in tests/test_bridge_contract.py. They fail without the fix and pass with it.

The 8 entries the fix exposes

MATLAB Python Notes
dispatchCustomFileHandler _dispatch_custom_file_handler Same arity rule; uses inspect.signature where MATLAB uses nargin
handlerTakesContext ~ (inlined) Divergence, see below
filesAreIdentical ~ (inlined in _open_series_member) Sizes first, then bytes
isSafeUid _is_safe_uid A separate copy of did.file.is_safe_uid, not a delegate, despite what its docstring says
containsTraversal ~ Replaced by resolve-then-_is_within
isAbsolutePath ~ os.path.isabs
isRemoteLocation _is_remote_location No strtrim on the type
isWithin _is_within commonpath vs. a prefix match

Divergence found, recorded but not fixed here. MATLAB's fetchSeriesMemberBytes never asks a two-argument customFileHandler for a series member, because such a handler only sees the manifest's location. Python's _open_series_member has no such gate. It asks any handler, and catches a re-fetched manifest afterwards with the same-bytes check. A two-argument handler that returns some other file is accepted in Python, where MATLAB would never have called it. Changing that is a behaviour port, so it belongs in its own PR.

CI

#90 has merged. The branch's merge of #90 is now a no-op, and against main this PR changes only bin/check_bridge_coverage.py, the implementations bridge YAML and tests/test_bridge_contract.py. All checks pass, including "Bridge coverage vs DID-matlab" with 0 problems.


Generated by Claude Code

…USY/READONLY retry

Brings the three entries bin/check_bridge_coverage.py reported against
DID-matlab main back in sync.

timestamp (new, DID-matlab bb29861): did.fun.timestamp(raw=None) returns
the current UTC time as 'yyyy-mm-ddTHH:MM:SS.fffZ' and clamps a ':60'
leap second (with or without a fraction or trailing Z) to ':59.999' with
MATLAB's regex.

document (bb29861): Document stamps base.datestamp with
did.fun.timestamp(). The private _utc_timestamp it replaces had a looser
clamp (':60.123' -> ':59.999123'), so it is removed.

sqlitedb (decd155, da83fa3): 30 s busy timeout on open; do_run_sql_query
retries BUSY/READONLY with MATLAB's backoff schedule, reopening the
connection first for READONLY (poisoned handle / DBMOVED); exhausted
retries print the filesystem diagnostics. Because SQLiteDB groups writes
into transactions where mksqlite autocommits, the statement retry runs
only with no transaction open, and COMMIT is retried (never reopened)
through a new _commit(). Deviations are recorded in the bridge entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Dn4gCNCU2jUGdmfPVCAGK
…db's public statics

_strip_comment and _outside_brackets treated every unquoted ' as a
string opener unless the previous *output* character was an identifier.
After a closing bracket that character had already been blanked to a
space, so `reshape(varargin,[],numRows)'; catch, end` in sqlitedb.m's
run_sql_noOpen opened a string, the `end` went uncounted, and every
method after it in the block was attributed to nothing. That included
the whole `methods (Static, Access=public)` block, so the "missing" check
never saw its eight public methods. close_db was masked as well, but
did.database defines one, so its entry still resolved.

A quote is now a transpose when the source character before it is an
identifier character, a closing bracket, '.', or another quote.

With the parser fixed, the eight methods need entries:
dispatchCustomFileHandler, isSafeUid, isRemoteLocation and isWithin map
to existing private helpers. handlerTakesContext, filesAreIdentical,
containsTraversal and isAbsolutePath are inlined or replaced in Python;
their entries say where and how. Writing them turned up one real
divergence, recorded on handlerTakesContext and not fixed here: Python
offers a series-member fetch to a two-argument handler, where MATLAB
never asks one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Dn4gCNCU2jUGdmfPVCAGK
#91's bridge coverage job reports the same three drift problems #90
fixes. Merging that branch here makes this PR's check meaningful now; the
merge is a no-op once #90 lands on main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Dn4gCNCU2jUGdmfPVCAGK

Copy link
Copy Markdown
Contributor Author

The first run's "Bridge coverage vs DID-matlab" failure wasn't caused by this PR. It was the 3 drift problems (timestamp, document, sqlitedb) that every PR currently hits on main, and that #90 fixes. I merged #90's branch in as 52e50c7, so this PR's check now covers the full set. Locally that gives 0 problems. The merge adds nothing once #90 lands. Merge #90 first, or merge this one alone and it brings #90's change with it.


Generated by Claude Code

@stevevanhooser
stevevanhooser merged commit 379ae56 into main Oct 23, 2026
7 checks passed
@stevevanhooser
stevevanhooser deleted the claude/bridge-checker-transpose-fix branch October 23, 2026 22:43
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