Unverified Commit 1aabdcbc authored by Mayank Mittal's avatar Mayank Mittal Committed by GitHub

Adds support for property attributes inside configclass (#953)

# Description

This MR adds support for property attributes in the
`omni.isaac.lab.utils.configclass` decorator. Earlier, the configclass
decorator failed to parse the property attributes correctly and made
them instance variables instead.

## Type of change

- Bug fix (non-breaking change which fixes an issue)

## Checklist

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there
parent 788a061d
[package]
# Note: Semantic Versioning is used: https://semver.org/
version = "0.22.7"
version = "0.22.8"
# Description
title = "Isaac Lab framework for Robot Learning"
......
Changelog
---------
0.22.8 (2024-09-06)
~~~~~~~~~~~~~~~~~~~
Added
^^^^^
* Added support for property attributes in the :meth:``omni.isaac.lab.utils.configclass`` method.
Earlier, the configclass decorator failed to parse the property attributes correctly and made them
instance variables instead.
0.22.7 (2024-09-05)
~~~~~~~~~~~~~~~~~~~
......
......@@ -334,8 +334,10 @@ def _custom_post_init(obj):
continue
# get data member
value = getattr(obj, key)
# duplicate data members
if not callable(value):
# check annotation
ann = obj.__class__.__dict__.get(key)
# duplicate data members that are mutable
if not callable(value) and not isinstance(ann, property):
setattr(obj, key, deepcopy(value))
......@@ -372,6 +374,7 @@ def _skippable_class_member(key: str, value: Any, hints: dict | None = None) ->
* Manually-added special class functions: From :obj:`_CONFIGCLASS_METHODS`.
* Members that are already present in the type annotations.
* Functions bounded to class object or class.
* Properties bounded to class object.
Args:
key: The class member name.
......@@ -401,6 +404,9 @@ def _skippable_class_member(key: str, value: Any, hints: dict | None = None) ->
signature = inspect.signature(value)
if "self" in signature.parameters or "cls" in signature.parameters:
return True
# skip property methods
if isinstance(value, property):
return True
# Otherwise, don't skip
return False
......
......@@ -307,6 +307,14 @@ class ClassFunctionImplementedDemoCfg:
def class_method(cls, value: int) -> ClassFunctionImplementedDemoCfg:
return cls(a=value)
@property
def a_proxy(self) -> int:
return self.a
@a_proxy.setter
def a_proxy(self, value: int):
self.a = value
"""
Dummy configuration: Nested dictionaries
......@@ -642,7 +650,7 @@ class TestConfigClass(unittest.TestCase):
self.assertEqual(cfg.a, 10)
def test_class_function_impl_config(self):
"""Tests having class and static function defined in the class instance."""
"""Tests having class function defined in the class instance."""
cfg = ClassFunctionImplementedDemoCfg()
# check that the annotations are correct
......@@ -659,6 +667,25 @@ class TestConfigClass(unittest.TestCase):
# check value is correct
self.assertEqual(new_cfg2.a, 20)
def test_class_property_impl_config(self):
"""Tests having class property defined in the class instance."""
cfg = ClassFunctionImplementedDemoCfg()
# check that the annotations are correct
self.assertDictEqual(cfg.__annotations__, {"a": "int"})
# check all methods are callable
cfg.instance_method()
# check value is correct
self.assertEqual(cfg.a, 5)
self.assertEqual(cfg.a_proxy, 5)
# set through property
cfg.a_proxy = 10
self.assertEqual(cfg.a, 10)
self.assertEqual(cfg.a_proxy, 10)
def test_dict_conversion_functions_config(self):
"""Tests conversion of config with functions into dictionary."""
cfg = FunctionsDemoCfg()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment