-
Notifications
You must be signed in to change notification settings - Fork 92
Fixed to retain static items when reloading(#57404) #1812
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop_v2.0.0
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request fixes issue #57404 by implementing functionality to retain static items (values starting with '=') when reloading item type mappings. The fix ensures that configuration values marked as static are preserved during the reload operation rather than being overwritten.
Changes:
- Added retrieval of existing item type mapping at the start of the reload process
- Introduced logic to merge static values from old mapping into new mapping before updating
- Implemented a new utility method
update_mapping_without_staticto handle the static value preservation logic
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 10 comments.
| File | Description |
|---|---|
| modules/weko-records/weko_records/api.py | Added item_type_mapping retrieval and integration with new update_mapping_without_static method in the reload method; implemented new update_mapping_without_static class method with nested helper function to recursively find and preserve static values |
| modules/weko-records/tests/test_api.py | Added unit test test_update_mapping_without_static to verify the static value preservation logic with various scenarios including nested dictionaries and non-existent paths |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if key not in temp: | ||
| is_exist_field = False | ||
| break | ||
| temp = temp[key] | ||
| if is_exist_field: |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code doesn't check if temp[key] is a dictionary before attempting to access it in the next iteration. If an intermediate value in the path is not a dictionary (e.g., it's a string or list), this will raise a TypeError when trying to use it as a dictionary in the next iteration. Consider adding a type check: if key not in temp or not isinstance(temp[key], dict):
| if key not in temp: | |
| is_exist_field = False | |
| break | |
| temp = temp[key] | |
| if is_exist_field: | |
| # Ensure the current container is a dict and contains the key, | |
| # and that the next value is also a dict (since it will be traversed). | |
| if not isinstance(temp, dict) or key not in temp or not isinstance(temp[key], dict): | |
| is_exist_field = False | |
| break | |
| temp = temp[key] | |
| if is_exist_field and isinstance(temp, dict): |
| result = [] | ||
| if isinstance(d,dict): | ||
| for key, value in d.items(): | ||
| result+=find_static_value(value,f"{path}.{key}" if path!="" else key) |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing space around comparison operators. For consistency with PEP 8 and the rest of the codebase, add spaces: if path != "" else key
| result+=find_static_value(value,f"{path}.{key}" if path!="" else key) | |
| result+=find_static_value(value,f"{path}.{key}" if path != "" else key) |
| if isinstance(d,dict): | ||
| for key, value in d.items(): | ||
| result+=find_static_value(value,f"{path}.{key}" if path!="" else key) | ||
| elif isinstance(d,str): | ||
| if d.startswith("="): | ||
| result.append((path,d)) |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing space around augmented assignment operator. For consistency with PEP 8, add spaces: result += find_static_value(...)
| if isinstance(d,dict): | |
| for key, value in d.items(): | |
| result+=find_static_value(value,f"{path}.{key}" if path!="" else key) | |
| elif isinstance(d,str): | |
| if d.startswith("="): | |
| result.append((path,d)) | |
| if isinstance(d, dict): | |
| for key, value in d.items(): | |
| result += find_static_value(value, f"{path}.{key}" if path != "" else key) | |
| elif isinstance(d, str): | |
| if d.startswith("="): | |
| result.append((path, d)) |
| >>> find_static_value(data) | ||
| [('a.b', '=static')] | ||
| """ | ||
| result = [] |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trailing whitespace after result = []. Remove the trailing space for cleaner code.
| result = [] | |
| result = [] |
| def test_update_mapping_without_static(self): | ||
| old_data={ | ||
| "str_not_static":"b", | ||
| "str_static":"=str_static_value", | ||
| "dict_not_static":{"a":"b"}, | ||
| "dict_static":{"not_static":"a","static":"=dict_static_value"}, | ||
| "not_exist_path":{"not_static":"a","static":"=not_exist_static_value"}, | ||
| } | ||
|
|
||
| new_data={ | ||
| "str_not_static":"b", | ||
| "str_static":"c", | ||
| "dict_not_static":{"a":"b"}, | ||
| "dict_static":{"not_static":"a","static":"b"}, | ||
| } | ||
|
|
||
| test = { | ||
| "str_not_static":"b", | ||
| "str_static":"=str_static_value", | ||
| "dict_not_static":{"a":"b"}, | ||
| "dict_static":{"not_static":"a","static":"=dict_static_value"} | ||
| } | ||
|
|
||
| result = ItemTypes.update_mapping_without_static(old_data,new_data) | ||
| assert result==test |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test doesn't verify the edge case where an intermediate path exists but is not a dictionary (e.g., {'a': 'string_value'} when trying to access a.b). This could lead to a TypeError at runtime. Consider adding a test case to ensure the method handles this scenario gracefully.
| def test_update_mapping_without_static(self): | ||
| old_data={ | ||
| "str_not_static":"b", | ||
| "str_static":"=str_static_value", | ||
| "dict_not_static":{"a":"b"}, | ||
| "dict_static":{"not_static":"a","static":"=dict_static_value"}, | ||
| "not_exist_path":{"not_static":"a","static":"=not_exist_static_value"}, | ||
| } | ||
|
|
||
| new_data={ | ||
| "str_not_static":"b", | ||
| "str_static":"c", | ||
| "dict_not_static":{"a":"b"}, | ||
| "dict_static":{"not_static":"a","static":"b"}, | ||
| } | ||
|
|
||
| test = { | ||
| "str_not_static":"b", | ||
| "str_static":"=str_static_value", | ||
| "dict_not_static":{"a":"b"}, | ||
| "dict_static":{"not_static":"a","static":"=dict_static_value"} | ||
| } | ||
|
|
||
| result = ItemTypes.update_mapping_without_static(old_data,new_data) | ||
| assert result==test |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test doesn't verify that the method handles empty dictionaries correctly. Consider adding test cases for edge cases like old_data = {} and new_data = {}.
| update_mapping = cls.update_mapping_without_static(item_type_mapping.get(_prop_id,{}),mapping_dict.get(_property_id)) \ | ||
| if item_type_mapping else mapping_dict.get(_property_id) |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The line continuation with backslash could be improved for readability. Consider wrapping the conditional expression in parentheses instead of using a backslash, which is the preferred style in Python. This would make the code more maintainable and avoid potential issues with trailing whitespace after the backslash.
| update_mapping = cls.update_mapping_without_static(item_type_mapping.get(_prop_id,{}),mapping_dict.get(_property_id)) \ | |
| if item_type_mapping else mapping_dict.get(_property_id) | |
| update_mapping = ( | |
| cls.update_mapping_without_static( | |
| item_type_mapping.get(_prop_id, {}), | |
| mapping_dict.get(_property_id), | |
| ) | |
| if item_type_mapping | |
| else mapping_dict.get(_property_id) | |
| ) |
| def test_update_mapping_without_static(self): | ||
| old_data={ | ||
| "str_not_static":"b", | ||
| "str_static":"=str_static_value", | ||
| "dict_not_static":{"a":"b"}, | ||
| "dict_static":{"not_static":"a","static":"=dict_static_value"}, | ||
| "not_exist_path":{"not_static":"a","static":"=not_exist_static_value"}, | ||
| } | ||
|
|
||
| new_data={ | ||
| "str_not_static":"b", | ||
| "str_static":"c", | ||
| "dict_not_static":{"a":"b"}, | ||
| "dict_static":{"not_static":"a","static":"b"}, | ||
| } | ||
|
|
||
| test = { | ||
| "str_not_static":"b", | ||
| "str_static":"=str_static_value", | ||
| "dict_not_static":{"a":"b"}, | ||
| "dict_static":{"not_static":"a","static":"=dict_static_value"} | ||
| } | ||
|
|
||
| result = ItemTypes.update_mapping_without_static(old_data,new_data) | ||
| assert result==test |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test verifies that static values with non-existent paths are ignored (see "not_exist_path" in old_data), which correctly validates the documented behavior. However, consider adding a test case to verify deeper nesting levels (3+ levels deep) to ensure the path traversal logic works correctly for more complex structures.
| result+=find_static_value(value,f"{path}.{key}" if path!="" else key) | ||
| elif isinstance(d,str): | ||
| if d.startswith("="): | ||
| result.append((path,d)) |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing space around comparison operators in tuple unpacking. For consistency with PEP 8, format as: result.append((path, d))
| result.append((path,d)) | |
| result.append((path, d)) |
| is_exist_field = False | ||
| break | ||
| temp = temp[key] | ||
| if is_exist_field: |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the docstring, "Only existing paths in mapping_prop will be updated; missing paths are ignored." However, the code doesn't check if the final key exists before updating it. If keys[-1] doesn't exist in temp, the code will still create it. Consider adding: if is_exist_field and keys[-1] in temp: to align with the documented behavior.
| if is_exist_field: | |
| if is_exist_field and keys[-1] in temp: |
No description provided.