DFReader, mavutil: support use as context managers - #1235
Merged
peterbarker merged 3 commits intoJul 31, 2026
Conversation
DFReader_binary and DFReader_text pin an open file and an mmap until close() is called, but offer no __enter__/__exit__, so callers cannot use a with-statement and commonly leak the handles (see ArduPilot/ardupilot#32533).
All mavfile subclasses expose close(), so a with-statement is the natural way to scope a connection or log reader. mavlink_connection() callers get this for the DFReader returns via the matching DFReader change.
mgwedd
force-pushed
the
feature/context-manager-support
branch
from
July 29, 2026 07:15
f833795 to
0b373b7
Compare
mgwedd
marked this pull request as ready for review
July 29, 2026 07:15
khancyr
approved these changes
Jul 30, 2026
khancyr
left a comment
Contributor
There was a problem hiding this comment.
LGTM
small changes. exit will call the mavfile override closing method so we are good.
Still work on py3.9
test are simple but OK
Contributor
|
Merged, thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
__enter__/__exit__to the two base classes that already have aclose()contract:DFReader.DFReader— coversDFReader_binaryandDFReader_textmavutil.mavfile— covers every connection type and log readerreturned by
mavlink_connection()so callers can scope a reader or connection with a plain
withstatement:
Why
DFReader_binary.__init__opens the log file and mmaps its descriptor,so each reader pins a filehandle until
close()is called. Since thereis no context manager support, callers either remember to call
close()manually, wrap the reader in
contextlib.closing, or — most commonly —just leak the handle. ArduPilot's own autotest suite and Replay checker
did the latter for years (ArduPilot/ardupilot#32533, fixed in
ArduPilot/ardupilot#33839. It had to use
contextlib.closingbecause this class can't be used in awithblock).This PR fixes the issue for all subclasses and downstream consumers.
Testing
New
tests/test_context_manager.py(runs in the existing pytest suite,no new fixtures — reuses
tests/test.BIN):DFReader_binaryused in awithblock: reads a message, then bothfilehandleanddata_mapreport closed on exit.mavlink_connection()on a dataflash log: same via the dispatch path.mavlink_connection('udpout:...'): socket is open inside the block,closed (fileno == -1) on exit.
All three pass locally on Python 3.13 (macOS);
flake8clean with therepo config.
No behavior change for existing callers —
close()semantics areuntouched, and
__exit__returnsNoneso exceptions propagate.