[GRASS-git] [OSGeo/grass] 65618d: grass.gunittest: Inherit more from unittest classe...
Edouard Choinière
noreply at github.com
Wed Aug 27 03:49:25 PDT 2025
Branch: refs/heads/main
Home: https://github.com/OSGeo/grass
Commit: 65618d02f3e961676d8f8ed85a5369dd34fe89be
https://github.com/OSGeo/grass/commit/65618d02f3e961676d8f8ed85a5369dd34fe89be
Author: Edouard Choinière <27212526+echoix at users.noreply.github.com>
Date: 2025-08-27 (Wed, 27 Aug 2025)
Changed paths:
M python/grass/gunittest/result.py
M python/grass/gunittest/runner.py
Log Message:
-----------
grass.gunittest: Inherit more from unittest classes (#6256)
Python is one of the few languages that allows multiple inheritance. That means that even we override two classes, one of which is is the base class of another, and we want the second class to use both our overridden class and overridden base class: it is possible. That is the case in our gunittest code.
Python uses a MRO (method resolution order) to know from which class call the function in this case. This order ignores duplicate classes if it happens. Python will handle at runtime an error when instantiating the class if there is a cycle in the base classes that can’t exist (this isn’t our case here). The `super()` call is where it makes the sense the most in Python, in multiple inheritance situations.
This PR is a follow up of some of my previous PRs (like #6200) that synced some gunittest code from unittest code so that the contents of the functions are exactly the same or similar.
Starting from there, classes, like the TextTestResult, were made subclasses of our overridden base class, AND unittest’s class. Then, replace all function implementations that are exactly the same as the unittest classe with a super() call. If there’s nothing else that remains apart from a super() call, it is useless to keep it, so remove the function.
With these removed, assignments to attributes that are used only by the unittest class can be simplified out, as done by the base class.
I simplified the GrassTestRunner class, in particular the only method run(), to use a call to the base classes instead of merging our code into the upstream code. That means our timing call is done before and after the base class call (that already does some timing calls, especially since 3.12 added durations natively. This means that our whole test call might be a little less precise (as it includes some time taken by the unittest call), but we don’t have to keep the implementation updated for each Python version.
Finished off with some typing annotations to make type checkers understand that our overridden classes are accepted as inputs. I also made a base implementation of the setTimes method, and called it with super() where appropriate in our classes (instead of defining it multiple times).
When developing, I stepped through function calls in the debugger to make sure the correct method resolution order was used, and to see which base implementations of functions were called and in which order.
* gunittest: Copy over _SubTest to allow creating derived classes
* gunittest: Apply ruff fixes to _SubTest
* gunittest: Prepare TextTestResult for multiple inheritance by syncing its implementation with unittest.TextTestResult
* gunittest: Make TextTestResult derive from grass.gunittest.result.TestResult and unittest.TextTestResult using multiple inheritance
* gunittest: Remove TextTestResult methods that have no changes with unittest's implementation
* gunittest: Remove setting TextTestResult attributes already handled with unittest's implementation
* grass.gunittest: Remove addSubTest() and _SubTest() class, as not needed to override
* grass.gunittest: Remove setting unused self._newline attribute
* grass.gunittest: Reorder MultiTestResult arguments passed to super call
* grass.gunittest: Add type annotations to TestResult, TextTestResult, KeyValueTestResult, and MultiTestResult classes
* grass.gunittest: Remove unnecessary pass since docstring is present
* grass.gunittest: Make GrassTestRunner a subclass of unittest.TextTestRunner
* grass.gunittest: Adjust typing annotation for TextTestResult's stream argument
* grass.gunittest: Fix ruff issue RUF021
* grass.gunittest: Simplify GrassTestRunner to count test duration after calling the base run() implementation
* grass.gunittest: Implement setTimes in TestResult class
* Apply suggestions from code review
* Apply suggestions from code review
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
To unsubscribe from these emails, change your notification settings at https://github.com/OSGeo/grass/settings/notifications
More information about the grass-commit
mailing list