Skip to content

Commit 472f990

Browse files
committed
[_709] orthogonal options when chaining obj.metadata(opt1=val1)(opt2=val2)
In other words, setting opt2 = val2 does not reset opt1 back to its default value.
1 parent d83169d commit 472f990

File tree

3 files changed

+53
-7
lines changed

3 files changed

+53
-7
lines changed

irods/manager/metadata_manager.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,37 @@ def use_timestamps(self):
3333
return getattr(self, "_use_ts", False)
3434

3535
__kw = {} # default (empty) keywords
36+
_admin = False
37+
_use_ts = False
3638

3739
def _updated_keywords(self, opts):
3840
kw_ = self.__kw.copy()
3941
kw_.update(opts)
4042
return kw_
4143

42-
def __call__(self, admin=False, timestamps=False, **irods_kw_opt):
43-
if admin:
44-
irods_kw_opt.update([(kw.ADMIN_KW, "")])
44+
__generate_new_options = staticmethod(lambda obj, from_kw: { 'admin':obj._admin,
45+
'timestamps':obj._use_ts,
46+
**from_kw })
47+
48+
def get_api_keywords(self): return self.__kw.copy()
49+
50+
def __call__(self, **kw_opt):
51+
# Make a new shallow copy of the manager object, but update options from parameter list.
4552
new_self = copy.copy(self)
46-
new_self._use_ts = timestamps
47-
new_self.__kw = irods_kw_opt
53+
new_options = new_self.__kw = self.__generate_new_options(new_self, kw_opt)
54+
55+
# Update the flags that do bookkeeping in the returned(new) manager object.
56+
if (timestamps:=new_options.pop('timestamps',None)) is not None:
57+
new_self._use_ts = timestamps
58+
if (admin:=new_options.pop('admin',None)) is not None:
59+
new_self._admin = admin
60+
61+
# Update the ADMIN_KW flag in the returned(new) object.
62+
if new_self._admin:
63+
new_options[kw.ADMIN_KW] = ""
64+
else:
65+
new_options.pop(kw.ADMIN_KW, None)
66+
4867
return new_self
4968

5069
@staticmethod

irods/meta.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,14 @@ def __init__(self, operation, avu, **kw):
8989

9090
class iRODSMetaCollection:
9191

92-
def __call__(self, admin=False, timestamps=False, **opts):
92+
def __call__(self, **opts):
93+
"""Optional parameters in **opts are:
94+
95+
admin (default: False): apply ADMIN_KW to future metadata operations.
96+
timestamps (default: False): attach (ctime,mtime) timestamp attributes to AVUs received from iRODS.
97+
"""
9398
x = copy.copy(self)
94-
x._manager = (x._manager)(admin, timestamps, **opts)
99+
x._manager = (x._manager)(**opts)
95100
x._reset_metadata()
96101
return x
97102

irods/test/meta_test.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,28 @@ def test_xml_mode_addresses_odd_metadata_characters__issue_582(self):
796796
# in use, with the "odd" characters being present in the metadata value.
797797
del obj.metadata[attr_str]
798798

799+
def test_cascading_changes_of_metadata_manager_options__issue_709(self):
800+
d = None
801+
try:
802+
d = self.sess.data_objects.create(f'{self.coll.path}/issue_709_test_1')
803+
m = d.metadata
804+
self.assertEqual(m._manager._admin,False)
805+
806+
m2 = m(admin = True)
807+
self.assertEqual(m2._manager._use_ts,False)
808+
self.assertEqual(m2._manager._admin,True)
809+
810+
m3 = m2(timestamps = True)
811+
self.assertEqual(m3._manager._use_ts, True)
812+
self.assertEqual(m3._manager._admin, True)
813+
self.assertEqual(m3._manager.get_api_keywords().get(kw.ADMIN_KW), "")
814+
815+
m4 = m3(admin = False)
816+
self.assertEqual(m4._manager._use_ts, True)
817+
self.assertEqual(m4._manager.get_api_keywords().get(kw.ADMIN_KW), None)
818+
finally:
819+
if d:
820+
d.unlink(force=True)
799821

800822
if __name__ == "__main__":
801823
# let the tests find the parent irods lib

0 commit comments

Comments
 (0)