Raise MissingFileSystem instead of AttributeError when diffing reports without source files - #201
Raise MissingFileSystem instead of AttributeError when diffing reports without source files#201Eljees wants to merge 1 commit into
Conversation
|
Ping — this has been open since 6 August with no review yet. Diffing two reports built without a filesystem crashes with
Happy to close it if you would rather handle #171 another way. |
Fixes #171.
Problem
Diffing two reports that were constructed without a filesystem crashes with
Cobertura.__init__leavesself.filesystemasNonewhen no source is given, andCoberturaDiff.file_source()reaches straight past the public accessor intoself.coberturaN.filesystem.has_file(filename).Why the existing error path was unreachable
Coberturaalready has a dedicated exception and a helpful message for exactly this situation —Cobertura.MissingFileSystem, raised by_raise_MissingFileSystem()and used byfile_source():CoberturaDiff.file_source()simply bypassed it by touching.filesystemdirectly, so the user got a bareAttributeErrorfrom deep inside the library instead of the message the author had already written.Fix
Add
Cobertura._filesystem_has_file(), which raisesMissingFileSystemwhen there is no filesystem and otherwise delegates to it, and call it from the two places inCoberturaDiff.file_source()that reached into.filesystemdirectly. No new semantics: this only routes an existing crash into the existing error path.Tests
test_diff_file_source_without_filesystemintests/test_cobertura_diff.py, parametrised over a file present in both reports and one present in only one of them. It fails onmasterwith theAttributeErrorabove and passes with the change.The test builds
Coberturadirectly rather than throughtests/utils.py::make_cobertura, because that helper always passes a filesystem — going through it, the test would be green either way.Also in this PR
CHANGES.mdentry under## Unreleased.README.md: theTextReporterDeltaexample constructs bothCoberturaobjects without a filesystem and then callsdelta.generate(), which is precisely the crash this PR fixes — so the example as written could not have worked. Updated it to passfilesystem_factory('source1'/'source2'), matching thepycobertura diffinvocation shown just above it.blackleaves every file in this PR unchanged.AI-assisted: I used Claude to help trace the call path and to draft the patch and the test. I reviewed every line, ran the new test against unpatched
masterfirst to confirm it fails without the fix, and ran the suite locally; the analysis and the runs are mine.