Skip to content

[#709] preserve options in chaining obj.metadata(opt1=val1)(opt2=val2) #716

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions irods/manager/metadata_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,37 @@ def use_timestamps(self):
return getattr(self, "_use_ts", False)

__kw = {} # default (empty) keywords
_admin = False
_use_ts = False

def _updated_keywords(self, opts):
kw_ = self.__kw.copy()
kw_.update(opts)
return kw_

def __call__(self, admin=False, timestamps=False, **irods_kw_opt):
if admin:
irods_kw_opt.update([(kw.ADMIN_KW, "")])
__generate_new_options = staticmethod(lambda obj, from_kw: { 'admin':obj._admin,
'timestamps':obj._use_ts,
**from_kw })

def get_api_keywords(self): return self.__kw.copy()

def __call__(self, **kw_opt):
# Make a new shallow copy of the manager object, but update options from parameter list.
new_self = copy.copy(self)
new_self._use_ts = timestamps
new_self.__kw = irods_kw_opt
new_options = new_self.__kw = self.__generate_new_options(new_self, kw_opt)

# Update the flags that do bookkeeping in the returned(new) manager object.
if (timestamps:=new_options.pop('timestamps',None)) is not None:
new_self._use_ts = timestamps
if (admin:=new_options.pop('admin',None)) is not None:
new_self._admin = admin

# Update the ADMIN_KW flag in the returned(new) object.
if new_self._admin:
new_options[kw.ADMIN_KW] = ""
else:
new_options.pop(kw.ADMIN_KW, None)

return new_self

@staticmethod
Expand Down
9 changes: 7 additions & 2 deletions irods/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,14 @@ def __init__(self, operation, avu, **kw):

class iRODSMetaCollection:

def __call__(self, admin=False, timestamps=False, **opts):
def __call__(self, **opts):
"""Optional parameters in **opts are:

admin (default: False): apply ADMIN_KW to future metadata operations.
timestamps (default: False): attach (ctime,mtime) timestamp attributes to AVUs received from iRODS.
"""
x = copy.copy(self)
x._manager = (x._manager)(admin, timestamps, **opts)
x._manager = (x._manager)(**opts)
x._reset_metadata()
return x

Expand Down
22 changes: 22 additions & 0 deletions irods/test/meta_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,28 @@ def test_xml_mode_addresses_odd_metadata_characters__issue_582(self):
# in use, with the "odd" characters being present in the metadata value.
del obj.metadata[attr_str]

def test_cascading_changes_of_metadata_manager_options__issue_709(self):
d = None
try:
d = self.sess.data_objects.create(f'{self.coll.path}/issue_709_test_1')
m = d.metadata
self.assertEqual(m._manager._admin,False)

m2 = m(admin = True)
self.assertEqual(m2._manager._use_ts,False)
self.assertEqual(m2._manager._admin,True)

m3 = m2(timestamps = True)
self.assertEqual(m3._manager._use_ts, True)
self.assertEqual(m3._manager._admin, True)
self.assertEqual(m3._manager.get_api_keywords().get(kw.ADMIN_KW), "")

m4 = m3(admin = False)
self.assertEqual(m4._manager._use_ts, True)
self.assertEqual(m4._manager.get_api_keywords().get(kw.ADMIN_KW), None)
Comment on lines +815 to +817
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I take it the following assertion is left out intentionally?

self.assertEqual(m4._manager._admin, False)

Does L817 cover it somehow? Seems like the ADMIN_KW is None because of m3(admin = False). Is that true? Are they related?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can put that in. Not sure why it got left out.

finally:
if d:
d.unlink(force=True)

if __name__ == "__main__":
# let the tests find the parent irods lib
Expand Down