Skip to content

Increase test coverage for filecmp - #159663

Open
Bolotnyj wants to merge 31 commits into
python:mainfrom
Bolotnyj:feature/filecmp-coverage
Open

Bolotnyj wants to merge 31 commits into
python:mainfrom
Bolotnyj:feature/filecmp-coverage

Conversation

@Bolotnyj

@Bolotnyj Bolotnyj commented Oct 18, 2026 •

Copy link
Copy Markdown

Added new unit tests to improve test coverage for the filecmp module.

Changes:

  • Added test_cache_overflow_and_hit to FileCompareTestCase.
  • Created a new isolated test class DirCmpImplementationTests to test dircmp internals through the public API (without relying on implementation details like phase2 or phase4_closure).
  • Added test_dircmp_os_errors_in_processing to verify OSError handling.
  • Added test_dircmp_different_types_and_funny_types to check type handling behavior.
  • Added test_dircmp_closure_and_report_funnies to verify recursive closure processing and report output.
  • Replaced boilerplate try/finally blocks with standard self.addCleanup() calls for reliable resource cleanups.

@bedevere-app bedevere-app Bot added awaiting review tests Tests in the Lib/test dir labels Oct 18, 2026
@bedevere-app

bedevere-app Bot commented Oct 18, 2026

Copy link
Copy Markdown

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@Bolotnyj Bolotnyj changed the title [skip issue] Increase test coverage for filecmp module skip issue Increase test coverage for filecmp module Oct 18, 2026
@Bolotnyj Bolotnyj changed the title skip issue Increase test coverage for filecmp module skip issue test_filecmp: Increase test coverage for filecmp module Oct 18, 2026
@Bolotnyj Bolotnyj changed the title skip issue test_filecmp: Increase test coverage for filecmp module gh-122409: Increase test coverage for filecmp module Oct 18, 2026
@Bolotnyj Bolotnyj changed the title gh-122409: Increase test coverage for filecmp module gh-122410: Increase test coverage for filecmp module Oct 18, 2026
@Bolotnyj Bolotnyj changed the title gh-122410: Increase test coverage for filecmp module skip issue test_filecmp: Increase test coverage for filecmp module Oct 18, 2026
@Bolotnyj Bolotnyj changed the title skip issue test_filecmp: Increase test coverage for filecmp module test_filecmp: Increase test coverage for filecmp module Oct 18, 2026
@picnixz

picnixz commented Oct 19, 2026

Copy link
Copy Markdown
Member

Please don't just change the issue title. Simply wait for a maintainer to add corresponding labels if necessary.

@@ -0,0 +1 @@
Added new unit tests to improve test coverage for the filecmp module.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There is no need for that NEWS entry.

@picnixz picnixz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  • Don't put the tests just after the setUp() method, it doesn't make sense. Please be more mindful of existing code.
  • What are we exactly testing and for which reason exactly as well? phase2() looks like a private (despite its public name) method which doesn't make sense to test specifically (it's not documented in https://docs.python.org/3/library/filecmp.html).
  • Are we simply testing incomplete findings that only occur in phase2()? we usually don't test implementation details like that though.
  • A lot of your tests seem to share a common setup. Why not extending setUp() or simply create a new class just for testing phase2?

Comment thread Lib/test/test_filecmp.py Outdated
if os.path.exists(d_path):
os.rmdir(d_path)

def test_dircmp_invalid_attribute_error(self):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why should we add this test? it's a useless test IMO.

Comment thread Lib/test/test_filecmp.py Outdated
Comment on lines +163 to +172
try:
with patch("os.stat", side_effect=fake_stat):
dc = filecmp.dircmp(self.dir, self.dir_same)
dc.phase2()
self.assertIn(trigger_file, dc.common_funny)
finally:
for d in (self.dir, self.dir_same):
p = os.path.join(d, trigger_file)
if os.path.exists(p):
os.remove(p)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use self.addCleanup and a shutil.rmtree call.

Comment thread Lib/test/test_filecmp.py Outdated

self.assertIn(file_diff_type, dc.common_funny)
self.assertIn(file_funny_type, dc.common_funny)
finally:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

likewise

@bedevere-app

bedevere-app Bot commented Oct 19, 2026

Copy link
Copy Markdown

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@picnixz picnixz changed the title test_filecmp: Increase test coverage for filecmp module Increase test coverage for filecmp module Oct 19, 2026
@picnixz picnixz changed the title Increase test coverage for filecmp module Increase test coverage for filecmp Oct 19, 2026
@Bolotnyj

Copy link
Copy Markdown
Author

Picnixz, I have taken your words into account and will correct the errors.

@Bolotnyj

Copy link
Copy Markdown
Author

I have made the requested changes; please review again.

@bedevere-app

bedevere-app Bot commented Oct 21, 2026

Copy link
Copy Markdown

Thanks for making the requested changes!

@picnixz: please review the changes made to this pull request.

@bedevere-app
bedevere-app Bot requested a review from picnixz October 21, 2026 10:45
Comment thread Lib/test/test_filecmp.py Outdated
Comment on lines +7 to +8
import stat
import io

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Pleae keep the list of imports sorted with the existing ones.

Comment thread Lib/test/test_filecmp.py Resolved
Comment thread Lib/test/test_filecmp.py Outdated

class DirCmpImplementationTests(unittest.TestCase):
def setUp(self):
tmpdir = tempfile.gettempdir()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For the the tempdir, I suggest that you use os_helper.temp_dir() instead.

Comment thread Lib/test/test_filecmp.py Outdated
subdir_path = os.path.join(self.dir, 'subdir')
os.mkdir(subdir_path)
dir_file_path = os.path.join(self.dir, "file")
with open(dir_file_path, 'w', encoding="utf-8") as output:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

To reduce all those checks, can you acutlaly use pathlib.Path objects so that you can directly do dir_file_path.write_text(data) or subdir_path.mkdir(parents=True, exist_ok=True) as well?

Comment thread Lib/test/test_filecmp.py Resolved
Comment thread Lib/test/test_filecmp.py Resolved
Comment thread Lib/test/test_filecmp.py Outdated
_ = dc.subdirs
dc.phase4_closure()

with patch("sys.stdout", new=io.StringIO()) as mock_stdout:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use support.captured_stdout() instead here.

Comment thread Lib/test/test_filecmp.py Outdated
Comment on lines +529 to +530
self.assertIn("Common funny cases", output)
self.assertIn("Trouble with common files", output)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Leave those assertions out of the context.

Comment thread Lib/test/test_filecmp.py Outdated

with patch("sys.stdout", new=io.StringIO()) as mock_stdout:
dc.report()
output = mock_stdout.getvalue()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

And this one as well

Fix PEP 8 formatting

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
@picnixz

picnixz commented Oct 31, 2026

Copy link
Copy Markdown
Member

Yeah, but I don't think we really need to achieve 100%. Is there a way to test phase4 without directly invoking it? (and without some weird tests)

@Bolotnyj

Copy link
Copy Markdown
Author

I will try to get this done as soon as possible.

@picnixz

picnixz commented Oct 31, 2026

Copy link
Copy Markdown
Member

You don't need to rush. If it's too complex or if you can't find a simple way of testing it, I can also accept the test as is. Adding tests for common_funny is already a good contribution!

@Bolotnyj

Copy link
Copy Markdown
Author

I will try to find a solution. Even if I don’t, I’ll still gain some experience. I simply want to contribute as much as I can to Python, as I genuinely love this language. @picnixz, I also want to thank you for such quick responses and high-quality reviews—you’ve been a great help!

@Bolotnyj

Bolotnyj commented Nov 1, 2026

Copy link
Copy Markdown
Author

@picnixz Yes, this was difficult for me. Please accept the tests as is.

Comment thread Lib/test/test_filecmp.py Resolved
Comment thread Lib/test/test_filecmp.py Resolved
Comment thread Lib/test/test_filecmp.py Resolved
Comment thread Lib/test/test_filecmp.py Resolved
Comment thread Lib/test/test_filecmp.py Resolved
Bolotnyj and others added 3 commits November 2, 2026 12:40
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
@picnixz

picnixz commented Nov 2, 2026

Copy link
Copy Markdown
Member

The enterContext() trick is solely for the setUp(). The other CM usages need to be with a with+block

@picnixz

picnixz commented Nov 2, 2026

Copy link
Copy Markdown
Member

You have a lint error (likely because of whitespaces/tabs)

Comment thread Lib/test/test_filecmp.py Resolved
Comment thread Lib/test/test_filecmp.py
Comment on lines +427 to +431
Path(self.dir_diff_file, 'file2').write_text('Different contents.\n')

# Test dircmp behavior when os.stat raises OSError on specific files.
# Structure contains 'error_trigger_file.txt' in both directories.
def test_dircmp_os_errors_in_processing(self):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
Path(self.dir_diff_file, 'file2').write_text('Different contents.\n')
# Test dircmp behavior when os.stat raises OSError on specific files.
# Structure contains 'error_trigger_file.txt' in both directories.
def test_dircmp_os_errors_in_processing(self):
Path(self.dir_diff_file, 'file2').write_text('Different contents.\n')
def tearDown(self):
filecmp.clear_cache()
# Test dircmp behavior when os.stat raises OSError on specific files.
# Structure contains 'error_trigger_file.txt' in both directories.
def test_dircmp_os_errors_in_processing(self):

Comment thread Lib/test/test_filecmp.py

return st

with patch("os.stat", side_effect=fake_stat_types):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Usually, side_effect is used for raising exceptions. For replacing functions, I believe we can use patch(name, new_callable) or wraps= directly. I never remember exactly what's the exact form though.

Comment thread Lib/test/test_filecmp.py

with patch("os.stat", side_effect=fake_stat_types):
dc = filecmp.dircmp(self.dir, self.dir_same)
dc.common_funny

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
dc.common_funny

No need for accessing common_funny here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I tried moving it out, but the test fails. filecmp.dircmp uses lazy properties, so it doesn't actually call os.stat until we access dc.common_funny. We have to keep this access inside the with patch block, otherwise the mock uninstalls too early.

Registered the cache cleanup via addCleanup to keep the test environment isolated.

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
@picnixz

picnixz commented Nov 2, 2026

Copy link
Copy Markdown
Member

There are a few bits I want to edit so Iwill do it myself so that it's easier. Once you're done editing on your side, I'll directly push to your branch and then we can get this merged.

@picnixz

picnixz commented Nov 2, 2026

Copy link
Copy Markdown
Member

Once I pushed to your branch, don't forget to update your local fork by pulling first (so that if you want to later add more things, you can do it; but remember to never force-push)

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants