Add name filter to attribute setter on Segment#598
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a filter_name parameter to the set_attrs_on_every_element method in Segment, enabling filtering elements by name in addition to type. This provides a more convenient API for setting attributes on specific named elements.
Key changes:
- Added
filter_nameparameter toset_attrs_on_every_elementmethod - Updated filtering logic to support name-based filtering alongside type filtering
- Ensured recursive calls pass the
filter_nameparameter to nested segments - Updated CHANGELOG to document the new feature
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| cheetah/accelerator/segment.py | Added filter_name parameter to set_attrs_on_every_element, updated filtering logic and recursive calls, and documented the new parameter |
| CHANGELOG.md | Added entry documenting the new filter_name feature |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| filter_name: str | None = None, | ||
| is_recursive: bool = True, | ||
| **kwargs: dict[str, Any], | ||
| ) -> None: | ||
| """ | ||
| Set attributes on every element of a specific type in the segment. | ||
|
|
||
| :param filter_type: Type of the elements to set the attributes for. | ||
| :param filter_name: Names of the elements to set the attributes for. | ||
| :param is_recursive: If `True`, the this method is applied to nested `Segment`s | ||
| as well. If `False`, only the elements directly in the top-level `Segment` | ||
| are considered. | ||
| :param kwargs: Attributes to set and their values. | ||
| """ | ||
| for element in self.elements: | ||
| if filter_type is None or isinstance(element, filter_type): | ||
| if (filter_type is None or isinstance(element, filter_type)) and ( | ||
| filter_name is None or element.name == filter_name | ||
| ): | ||
| for key, value in kwargs.items(): | ||
| setattr(element, key, value) | ||
| elif is_recursive and isinstance(element, Segment): | ||
| element.set_attrs_on_every_element( | ||
| filter_type=filter_type, is_recursive=True, **kwargs | ||
| filter_type=filter_type, | ||
| filter_name=filter_name, | ||
| is_recursive=True, | ||
| **kwargs, | ||
| ) |
There was a problem hiding this comment.
The new filter_name parameter lacks test coverage. Since the existing function set_attrs_on_every_element has test coverage in tests/test_segment.py (see test_attr_setting_by_element_type_convenience_method), the new functionality should also be tested.
Consider adding a test that:
- Creates a segment with elements having specific names
- Calls
set_attrs_on_every_elementwith thefilter_nameparameter - Verifies that only elements matching the specified name have their attributes modified
- Tests the recursive behavior with nested segments
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| def get_attr_from_every_element( | ||
| self, | ||
| filter_type: type[Element] | tuple[type[Element]] | None = None, | ||
| filter_name: str | None = None, |
There was a problem hiding this comment.
Inconsistent type annotation for filter_name parameter. In get_attr_from_every_element, it's typed as str | None, but in set_attrs_on_every_element (line 622), it's typed as str | tuple[str] | None. These should be consistent. The setter allows a tuple to support multiple names, and the getter should do the same for consistency.
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
| def get_attr_from_every_element( | ||
| self, | ||
| filter_type: type[Element] | tuple[type[Element]] | None = None, | ||
| filter_name: str | None = None, | ||
| is_recursive: bool = True, | ||
| ) -> list[Any]: | ||
| """ | ||
| Get an attribute from every element type in the segment filtered by type and/or | ||
| name. | ||
| :param filter_type: Type of the elements to get the attribute from. | ||
| :param filter_name: Name of the elements to get the attribute from. | ||
| :param is_recursive: If `True`, this method is applied to nested `Segment`s as | ||
| well. If `False`, only the elements directly in the top-level `Segment` are | ||
| considered. | ||
| :return: List of attributes from the filtered elements. | ||
| """ | ||
| attrs = [] | ||
| for element in self.elements: | ||
| if (filter_type is None or isinstance(element, filter_type)) and ( | ||
| filter_name is None or element.name in filter_name | ||
| ): | ||
| attrs.append(element) | ||
| elif is_recursive and isinstance(element, Segment): | ||
| attrs.extend( | ||
| element.get_attr_from_every_element( | ||
| filter_type=filter_type, | ||
| filter_name=filter_name, | ||
| is_recursive=True, | ||
| ) | ||
| ) | ||
| return attrs |
There was a problem hiding this comment.
The new filter_name parameter and get_attr_from_every_element method lack test coverage. There are existing tests for set_attrs_on_every_element with filter_type (line 57-86 in test_segment.py), but no tests for the new filtering by name functionality or the new getter method.
| if (filter_type is None or isinstance(element, filter_type)) and ( | ||
| filter_name is None or element.name in filter_name | ||
| ): | ||
| for key, value in kwargs.items(): | ||
| setattr(element, key, value) | ||
| elif is_recursive and isinstance(element, Segment): | ||
| element.set_attrs_on_every_element( | ||
| filter_type=filter_type, is_recursive=True, **kwargs | ||
| filter_type=filter_type, | ||
| filter_name=filter_name, | ||
| is_recursive=True, | ||
| **kwargs, | ||
| ) |
There was a problem hiding this comment.
Missing test coverage for the new filter_name parameter. While tests exist for filtering by type, the new name filtering functionality is not tested.
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
|
||
| ### 🚀 Features | ||
|
|
||
| - Add `filter_name` argument to the attribute setting convenience function of Segment, so it's possible to filter not only by type but also by name. (see #598) (@jank324) |
There was a problem hiding this comment.
Needs to be moved to new version
Description
Adds a
filter_nameargument to the attribute setting convenience function ofSegment, so it's possible to filter not only by type but also by name.Also adds a convince getter function with similar behaviour that gets a single attribute from the filtered elements in the segment.
Motivation and Context
We no longer have to write
and can instead write
Types of changes
Checklist
flake8(required).pytesttests pass (required).pyteston a machine with a CUDA GPU and made sure all tests pass (required).Note: We are using a maximum length of 88 characters per line.