Refactor Arrhenius class to use composition instead of inheritance#462
Refactor Arrhenius class to use composition instead of inheritance#462
Conversation
Co-authored-by: K20shores <[email protected]>
…mechanism handling Co-authored-by: K20shores <[email protected]>
Co-authored-by: K20shores <[email protected]>
Arrhenius
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #462 +/- ##
=======================================
Coverage 83.63% 83.63%
=======================================
Files 48 48
Lines 4093 4093
=======================================
Hits 3423 3423
Misses 670 670 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
ARRHENIUS_REFACTOR_SUMMARY.md
Outdated
There was a problem hiding this comment.
This needs to be removed
There was a problem hiding this comment.
Removed the ARRHENIUS_REFACTOR_SUMMARY.md file as requested. 71b3842
test_arrhenius_refactor.py
Outdated
There was a problem hiding this comment.
All tests should be placed into musica/test. Since this is testing the mechanism_configuration submodule, put this test into musica/test/mechanism_configuration/test_arrhenius.py
There was a problem hiding this comment.
Moved test file to musica/test/mechanism_configuration/test_arrhenius.py as requested and made it pytest compatible. 71b3842
test_arrhenius_refactor.py
Outdated
| def main(): | ||
| """Run all tests.""" | ||
| print("Testing refactored Arrhenius class...") | ||
|
|
||
| try: | ||
| test_arrhenius_composition() | ||
| test_arrhenius_property_delegation() | ||
| test_arrhenius_ea_conversion() | ||
| test_arrhenius_reactants_products() | ||
| test_arrhenius_serialize() | ||
| test_arrhenius_serialize_static() | ||
| test_arrhenius_gas_phase_types() | ||
|
|
||
| print("\n🎉 All tests passed! Arrhenius refactoring is working correctly.") | ||
| return True | ||
|
|
||
| except Exception as e: | ||
| print(f"\n❌ Test failed: {e}") | ||
| import traceback | ||
| traceback.print_exc() | ||
| return False | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| success = main() | ||
| sys.exit(0 if success else 1) No newline at end of file |
There was a problem hiding this comment.
| def main(): | |
| """Run all tests.""" | |
| print("Testing refactored Arrhenius class...") | |
| try: | |
| test_arrhenius_composition() | |
| test_arrhenius_property_delegation() | |
| test_arrhenius_ea_conversion() | |
| test_arrhenius_reactants_products() | |
| test_arrhenius_serialize() | |
| test_arrhenius_serialize_static() | |
| test_arrhenius_gas_phase_types() | |
| print("\n🎉 All tests passed! Arrhenius refactoring is working correctly.") | |
| return True | |
| except Exception as e: | |
| print(f"\n❌ Test failed: {e}") | |
| import traceback | |
| traceback.print_exc() | |
| return False | |
| if __name__ == "__main__": | |
| success = main() | |
| sys.exit(0 if success else 1) | |
| def main(): | |
| """Run all tests.""" | |
| print("Testing refactored Arrhenius class...") | |
| try: | |
| test_arrhenius_composition() | |
| test_arrhenius_property_delegation() | |
| test_arrhenius_ea_conversion() | |
| test_arrhenius_reactants_products() | |
| test_arrhenius_serialize() | |
| test_arrhenius_serialize_static() | |
| test_arrhenius_gas_phase_types() | |
| print("\n🎉 All tests passed! Arrhenius refactoring is working correctly.") | |
| return True | |
| except Exception as e: | |
| print(f"\n❌ Test failed: {e}") | |
| import traceback | |
| traceback.print_exc() | |
| return False | |
| if __name__ == "__main__": | |
| success = main() | |
| sys.exit(0 if success else 1) |
All of our tests should be written with and compatible with pytest, and we should also be able to call the script directly and have pytest run it with
if __name__ == '__main__':
pytest.main([__file__])
There was a problem hiding this comment.
Updated test structure to be pytest compatible with if __name__ == '__main__': pytest.main([__file__]) pattern as suggested. 71b3842
…proper location with pytest compatibility Co-authored-by: K20shores <[email protected]>
| Returns: | ||
| Dict: A dictionary representation of the Arrhenius object. | ||
| """ | ||
| serialize_dict = { |
There was a problem hiding this comment.
This dictionary is the same as in the serialize_static function. Put that in one place so it isn't duplicated
There was a problem hiding this comment.
Extracted the common serialization dictionary creation logic into a _create_serialize_dict() helper method to eliminate duplication between serialize() and serialize_static() methods. 3495218
| # Add the musica module to the path for testing | ||
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) |
There was a problem hiding this comment.
| # Add the musica module to the path for testing | |
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) | |
| # Add the musica module to the path for testing | |
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) |
All tests should be run after running pip install -e .. Remove this sys path modification and let the test fail without catching the exception of musica can't be imported
There was a problem hiding this comment.
Removed the sys.path modification. Tests now assume proper pip install -e . installation and will fail cleanly if musica cannot be imported. 3495218
| arr2.gas_phase = gas | ||
| assert arr2.gas_phase == "gas" | ||
|
|
||
| print("✓ Gas phase type handling working correctly") |
There was a problem hiding this comment.
Remove all prints like this throughout this test file. pytest should handle success/failure display
There was a problem hiding this comment.
Removed all print statements throughout the test file. pytest will now handle all success/failure display appropriately. 3495218
Co-authored-by: K20shores <[email protected]>
|
@copilot the tests are failing with this error: |
…rsion in Reactions Co-authored-by: K20shores <[email protected]>
... Fixed the test failures with commit 255dfbc. The main issues were:
The composition pattern is preserved while ensuring compatibility with the existing C++ backend infrastructure. |
Co-authored-by: K20shores <[email protected]>
There was a problem hiding this comment.
Remove this file. All of the functionality is tested elsewhere
There was a problem hiding this comment.
Removed the test file as requested. 8ea66cb
Co-authored-by: K20shores <[email protected]>
This PR refactors the
Arrheniusclass inmusica.mechanism_configurationto use composition instead of inheritance from_Arrhenius, addressing the architectural improvement requested in issue #446.Key Changes
🏗️ Architecture Refactoring
class Arrhenius(_Arrhenius):toclass Arrhenius:self._instance = _Arrhenius()🔧 Property Delegation
All attributes now use
@propertydecorators that delegate to the internal instance:🧪 Type Conversion System
Automatic conversion between Python and C++ objects for reactants/products:
📊 Serialization Updates
serialize()now uses only Python-visible data as requestedserialize_static()for C++_Arrheniusobjects⚡ Parameter Validation
Maintains mutually exclusive
CandEaparameters with proper BOLTZMANN conversion:Files Modified
musica/mechanism_configuration/arrhenius.py- Main refactoring with composition patternmusica/mechanism_configuration/mechanism_configuration.py- Updated call site for dual object supporttest_arrhenius_refactor.py- Comprehensive test suite validating all functionalityARRHENIUS_REFACTOR_SUMMARY.md- Detailed implementation documentationTesting
Created comprehensive test suite covering:
Benefits
All acceptance criteria from the issue have been met while maintaining full backward compatibility with the existing codebase.
Fixes #446.
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.