Skip to content

Commit a2f5633

Browse files
d-w-moorealanking
authored andcommitted
[#434] metadata calls now require AVU fields to be nonzero-length strings
AVU add and set operations will henceforth require attribute and value arguments to be nonzero-length and exactly of type str (ie. Python string). Only the units field may have a value that is zero-length or, equivalently, of type None. (Semantically, either one is the same as omitting the units.) If an irods.meta.iRODSMeta object is used in the call, the above restrictions apply to the corresponding fields of that object.
1 parent 09b826d commit a2f5633

2 files changed

Lines changed: 36 additions & 3 deletions

File tree

irods/message/__init__.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
IntegerProperty, LongProperty, ArrayProperty,
2020
SubmessageProperty)
2121

22+
class Bad_AVU_Field(Exception):
23+
pass
24+
2225
_TUPLE_LIKE_TYPES = (tuple, list)
2326

2427
def _qxml_server_version( var ):
@@ -670,9 +673,29 @@ class MetadataRequest(Message):
670673

671674
def __init__(self, *args, **metadata_opts):
672675
super(MetadataRequest, self).__init__()
673-
for i in range(len(args)):
674-
if args[i]:
675-
setattr(self, 'arg%d' % i, args[i])
676+
677+
NoneType = type(None)
678+
def field_name(i) : return ("attribute", "value", "unit")[i-3]
679+
680+
# We now enforce these requirements of the scalars (ie. AVU fields) submitted to the metadata call:
681+
# * All fields must each be of type str, except that the units field can be the None object.
682+
# * Attribute and Value must be of type str (a Python string) as well as nonzero length.
683+
for i,arg in enumerate(args):
684+
error = None
685+
686+
# Raise usage error if any of the AVU fields (args 3 to 5 inclusive) do not meet the above constraints.
687+
if i in (3,4,5):
688+
if type(arg) not in ({str, UNICODE} if i<5 else {str, UNICODE, NoneType}):
689+
error = Bad_AVU_Field("AVU %s (%r) has incorrect type. AVU fields must be strings, except for units, which could be None." % (field_name(i),arg))
690+
elif i<5 and not(arg):
691+
error = Bad_AVU_Field("AVU %s (%r) is zero-length." % (field_name(i), arg))
692+
if error is not None:
693+
raise error
694+
695+
# If there is no error, set the attribute in the request message.
696+
if arg not in {None, b'', ''}:
697+
setattr(self, 'arg%d' % i, arg)
698+
676699
self.KeyValPair_PI = StringStringMap(metadata_opts)
677700

678701
arg0 = StringProperty()

irods/test/meta_test.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
from irods.session import iRODSSession
1515
from six.moves import range
1616
from six import PY3
17+
from irods.message import Bad_AVU_Field
18+
1719

1820

1921
class TestMeta(unittest.TestCase):
@@ -442,6 +444,14 @@ def units():
442444
if d: d.unlink(force = True)
443445
helpers.remove_unused_metadata(session)
444446

447+
def test_nonstring_as_AVU_value_raises_an_error__issue_434(self):
448+
with self.assertRaisesRegexp(Bad_AVU_Field,'incorrect type'):
449+
self.coll.metadata.set("an_attribute",0)
450+
451+
def test_empty_string_as_AVU_value_raises_an_error__issue_434(self):
452+
with self.assertRaisesRegexp(Bad_AVU_Field,'zero-length'):
453+
self.coll.metadata.set("an_attribute","")
454+
445455
if __name__ == '__main__':
446456
# let the tests find the parent irods lib
447457
sys.path.insert(0, os.path.abspath('../..'))

0 commit comments

Comments
 (0)