From f6db681db9d7e944588c060bb1fb503101990c50 Mon Sep 17 00:00:00 2001 From: Javier Otero Date: Mon, 22 Feb 2021 17:57:57 +0100 Subject: [PATCH 1/3] Add support for undefined data descriptors --- reframe/utility/__init__.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/reframe/utility/__init__.py b/reframe/utility/__init__.py index 824d0e1092..7b1f7471e8 100644 --- a/reframe/utility/__init__.py +++ b/reframe/utility/__init__.py @@ -287,9 +287,12 @@ def attrs(obj): # Look for descriptors for cls in type(obj).mro(): - for attr, value in cls.__dict__.items(): - if inspect.isdatadescriptor(value): - ret[attr] = getattr(obj, attr) + for attr in cls.__dict__: + if inspect.isdatadescriptor(cls.__dict__[attr]): + try: + ret[attr] = getattr(obj, attr) + except AttributeError: + pass return ret From 7bc436eb5db4ed6d792b89266eff2ce6444ce2cf Mon Sep 17 00:00:00 2001 From: Javier Otero Date: Mon, 22 Feb 2021 18:11:00 +0100 Subject: [PATCH 2/3] Add unit test --- unittests/test_utility.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/unittests/test_utility.py b/unittests/test_utility.py index 0524b7aea6..86388d1d3f 100644 --- a/unittests/test_utility.py +++ b/unittests/test_utility.py @@ -658,9 +658,14 @@ def test_repr_default(): def test_attrs(): - class C: + class B: z = fields.TypedField(int) + def __init__(self, x, y): + self.x = x + self.y = y + + class C(B): def __init__(self, x, y): self._x = x self.y = y @@ -676,6 +681,13 @@ def x(self): class D(C): pass + # Test undefined descriptors are not returned + b = B(-1, 0) + b_attrs = util.attrs(b) + assert b_attrs['x'] == -1 + assert b_attrs['y'] == 0 + assert 'z' not in b_attrs + c = C(1, 2) c_attrs = util.attrs(c) assert c_attrs['x'] == 1 From b2c58cef089dfb9c64dea59e07d59d3d6b54b60e Mon Sep 17 00:00:00 2001 From: Javier Otero Date: Tue, 23 Feb 2021 10:33:16 +0100 Subject: [PATCH 3/3] Expand comments on attrs function --- reframe/utility/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/reframe/utility/__init__.py b/reframe/utility/__init__.py index 7b1f7471e8..62c5352a4e 100644 --- a/reframe/utility/__init__.py +++ b/reframe/utility/__init__.py @@ -275,7 +275,9 @@ def repr(obj, htchar=' ', lfchar='\n', indent=4, basic_offset=0): def attrs(obj): '''Inspect object and return its attributes and their values. - This function returns also any descriptors found at the owner class. + This function returns also any descriptors found at the owner class, + with the exception of descriptors without an assigned value, which are + expected to raise an ``AttributeError``. :arg obj: The object to inspect. :returns: an iterator over ``(attr_name, value)`` tuples @@ -292,6 +294,7 @@ def attrs(obj): try: ret[attr] = getattr(obj, attr) except AttributeError: + # Pass if the descriptor does not have an assigned value pass return ret