Repository: minio/minio-py
Pull request #920 (2020-05-08 05:47:08)

fix pylint errors in xml_marshal.py


Patch:
diff --git a/Makefile b/Makefile
index 2d966f9..4d3c76b 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 
 check:
 	@which pylint >/dev/null || pip install --user --upgrade pylint
-	@if python --version | grep -qi 'python 3'; then pylint --reports=no minio/compat.py minio/copy_conditions.py minio/definitions.py minio/helpers.py minio/parsers.py minio/post_policy.py minio/signer.py minio/thread_pool.py minio/__init__.py minio/select; fi
+	@if python --version | grep -qi 'python 3'; then pylint --reports=no minio/compat.py minio/copy_conditions.py minio/definitions.py minio/helpers.py minio/parsers.py minio/post_policy.py minio/signer.py minio/thread_pool.py minio/__init__.py minio/xml_marshal.py minio/select; fi
 	@if python --version | grep -qi 'python 3'; then pylint --reports=no minio/api.py; fi
 
 	@which isort >/dev/null || pip install --user --upgrade isort
diff --git a/minio/api.py b/minio/api.py
index 4e5c2d7..9a2e1cc 100644
--- a/minio/api.py
+++ b/minio/api.py
@@ -75,10 +75,10 @@ from .signer import (_SIGN_V4_ALGORITHM, _UNSIGNED_PAYLOAD,
                      generate_credential_string, post_presign_signature,
                      presign_v4, sign_v4)
 from .thread_pool import ThreadPool
-from .xml_marshal import (xml_marshal_bucket_constraint,
+from .xml_marshal import (marshal_bucket_notifications,
+                          marshal_complete_multipart,
+                          xml_marshal_bucket_constraint,
                           xml_marshal_bucket_encryption,
-                          xml_marshal_bucket_notifications,
-                          xml_marshal_complete_multipart_upload,
                           xml_marshal_delete_objects, xml_marshal_select,
                           xml_to_dict)
 
@@ -502,7 +502,7 @@ class Minio:  # pylint: disable=too-many-public-methods
         is_valid_bucket_name(bucket_name, False)
         is_valid_notification_config(notifications)
 
-        content = xml_marshal_bucket_notifications(notifications)
+        content = marshal_bucket_notifications(notifications)
         headers = {
             'Content-Length': str(len(content)),
             'Content-Md5': get_md5_base64digest(content)
@@ -529,7 +529,7 @@ class Minio:  # pylint: disable=too-many-public-methods
         """
         is_valid_bucket_name(bucket_name, False)
 
-        content_bytes = xml_marshal_bucket_notifications({})
+        content_bytes = marshal_bucket_notifications({})
         headers = {
             'Content-Length': str(len(content_bytes)),
             'Content-Md5': get_md5_base64digest(content_bytes)
@@ -1857,7 +1857,7 @@ class Minio:  # pylint: disable=too-many-public-methods
         for part in sorted(uploaded_parts.keys()):
             ordered_parts.append(uploaded_parts[part])
 
-        data = xml_marshal_complete_multipart_upload(ordered_parts)
+        data = marshal_complete_multipart(ordered_parts)
         sha256_hex = get_sha256_hexdigest(data)
         md5_base64 = get_md5_base64digest(data)
 
diff --git a/minio/xml_marshal.py b/minio/xml_marshal.py
index d7a441f..0f34e40 100644
--- a/minio/xml_marshal.py
+++ b/minio/xml_marshal.py
@@ -34,48 +34,43 @@ from collections import defaultdict
 _S3_NAMESPACE = 'http://s3.amazonaws.com/doc/2006-03-01/'
 
 
-def Element(tag, with_namespace=False):
+def Element(tag, with_namespace=False):  # pylint: disable=invalid-name
+    """Create ElementTree.Element with tag and namespace."""
     if with_namespace:
         return ET.Element(tag, {'xmlns': _S3_NAMESPACE})
     return ET.Element(tag)
 
 
-def SubElement(parent, tag, text=None):
-    subElement = ET.SubElement(parent, tag)
+def SubElement(parent, tag, text=None):  # pylint: disable=invalid-name
+    """Create ElementTree.SubElement on parent with tag and text."""
+    element = ET.SubElement(parent, tag)
     if text is not None:
-        subElement.text = text
-    return subElement
+        element.text = text
+    return element
 
 
-def get_xml_data(element):
+def _get_xml_data(element):
+    """Get XML data of ElementTree.Element."""
     data = io.BytesIO()
     ET.ElementTree(element).write(data, encoding=None, xml_declaration=False)
     return data.getvalue()
 
 
-def xml_to_dict(in_xml):
-    # Converts xml to dict
-    elem = ET.XML(in_xml)
-    return etree_to_dict(elem)
-
-
-def etree_to_dict(elem):
-    # Converts ElementTree object to dict
-    ns = '{' + _S3_NAMESPACE + '}'
+def _etree_to_dict(elem):
+    """Converts ElementTree object to dict."""
+    ns = '{' + _S3_NAMESPACE + '}'  # pylint: disable=invalid-name
     elem.tag = elem.tag.replace(ns, '')
 
-    d = {elem.tag: {} if elem.attrib else None}
+    d = {elem.tag: {} if elem.attrib else None}  # pylint: disable=invalid-name
     children = list(elem)
     if children:
-        dd = defaultdict(list)
-        if children[0].tag.replace(ns, '') == 'Rule':
-            for dc in map(etree_to_dict, children):
-                for k, v in dc.items():
-                    dd[k].append([v])
-        else:
-            for dc in map(etree_to_dict, children):
-                for k, v in dc.items():
-                    dd[k].append(v)
+        dd = defaultdict(list)  # pylint: disable=invalid-name
+        is_rule = children[0].tag.replace(ns, "") == "Rule"
+        # pylint: disable=invalid-name
+        for dc in map(_etree_to_dict, children):
+            for k, v in dc.items():  # pylint: disable=invalid-name
+                dd[k].append([v] if is_rule else v)
+        # pylint: disable=invalid-name
         d = {elem.tag: {k: v[0] if len(v) == 1 else v for k, v in dd.items()}}
     if elem.attrib:
         d[elem.tag].update(('@' + k, v) for k, v in elem.attrib.items())
@@ -89,7 +84,15 @@ def etree_to_dict(elem):
     return d
 
 
+def xml_to_dict(in_xml):
+    """Convert XML to dict."""
+    elem = ET.XML(in_xml)
+    return _etree_to_dict(elem)
+
+
 def xml_marshal_bucket_encryption(rules):
+    """Encode bucket encryption to XML."""
+
     root = Element('ServerSideEncryptionConfiguration')
 
     if rules:
@@ -105,7 +108,7 @@ def xml_marshal_bucket_encryption(rules):
         if kms_text:
             SubElement(apply_element, 'KMSMasterKeyID', kms_text)
 
-    return get_xml_data(root)
+    return _get_xml_data(root)
 
 
 def xml_marshal_bucket_constraint(region):
@@ -117,10 +120,12 @@ def xml_marshal_bucket_constraint(region):
     """
     root = Element('CreateBucketConfiguration', with_namespace=True)
     SubElement(root, 'LocationConstraint', region)
-    return get_xml_data(root)
+    return _get_xml_data(root)
 
 
 def xml_marshal_select(req):
+    """Encode select request to XML."""
+
     def bool_to_str(value):
         return "true" if value else "false"
 
@@ -219,10 +224,10 @@ def xml_marshal_select(req):
         bool_to_str(req.request_progress.enabled),
     )
 
-    return get_xml_data(root)
+    return _get_xml_data(root)
 
 
-def xml_marshal_complete_multipart_upload(uploaded_parts):
+def marshal_complete_multipart(uploaded_parts):
     """
     Marshal's complete multipart upload request based on *uploaded_parts*.
 
@@ -235,10 +240,10 @@ def xml_marshal_complete_multipart_upload(uploaded_parts):
         SubElement(part, 'PartNumber', str(uploaded_part.part_number))
         SubElement(part, 'ETag', '"' + uploaded_part.etag + '"')
 
-    return get_xml_data(root)
+    return _get_xml_data(root)
 
 
-def xml_marshal_bucket_notifications(notifications):
+def marshal_bucket_notifications(notifications):
     """
     Marshals the notifications structure for sending to S3 compatible storage
 
@@ -250,7 +255,12 @@ def xml_marshal_bucket_notifications(notifications):
                 'Id': 'string',
                 'Arn': 'string',
                 'Events': [
-                    's3:ReducedRedundancyLostObject'|'s3:ObjectCreated:*'|'s3:ObjectCreated:Put'|'s3:ObjectCreated:Post'|'s3:ObjectCreated:Copy'|'s3:ObjectCreated:CompleteMultipartUpload'|'s3:ObjectRemoved:*'|'s3:ObjectRemoved:Delete'|'s3:ObjectRemoved:DeleteMarkerCreated',
+                    's3:ReducedRedundancyLostObject'|'s3:ObjectCreated:*'|
+                    's3:ObjectCreated:Put'|'s3:ObjectCreated:Post'|
+                    's3:ObjectCreated:Copy'|
+                    's3:ObjectCreated:CompleteMultipartUpload'|
+                    's3:ObjectRemoved:*'|'s3:ObjectRemoved:Delete'|
+                    's3:ObjectRemoved:DeleteMarkerCreated',
                 ],
                 'Filter': {
                     'Key': {
@@ -269,7 +279,12 @@ def xml_marshal_bucket_notifications(notifications):
                 'Id': 'string',
                 'Arn': 'string',
                 'Events': [
-                    's3:ReducedRedundancyLostObject'|'s3:ObjectCreated:*'|'s3:ObjectCreated:Put'|'s3:ObjectCreated:Post'|'s3:ObjectCreated:Copy'|'s3:ObjectCreated:CompleteMultipartUpload'|'s3:ObjectRemoved:*'|'s3:ObjectRemoved:Delete'|'s3:ObjectRemoved:DeleteMarkerCreated',
+                    's3:ReducedRedundancyLostObject'|'s3:ObjectCreated:*'|
+                    's3:ObjectCreated:Put'|'s3:ObjectCreated:Post'|
+                    's3:ObjectCreated:Copy'|
+                    's3:ObjectCreated:CompleteMultipartUpload'|
+                    's3:ObjectRemoved:*'|'s3:ObjectRemoved:Delete'|
+                    's3:ObjectRemoved:DeleteMarkerCreated',
                 ],
                 'Filter': {
                     'Key': {
@@ -288,7 +303,12 @@ def xml_marshal_bucket_notifications(notifications):
                 'Id': 'string',
                 'Arn': 'string',
                 'Events': [
-                    's3:ReducedRedundancyLostObject'|'s3:ObjectCreated:*'|'s3:ObjectCreated:Put'|'s3:ObjectCreated:Post'|'s3:ObjectCreated:Copy'|'s3:ObjectCreated:CompleteMultipartUpload'|'s3:ObjectRemoved:*'|'s3:ObjectRemoved:Delete'|'s3:ObjectRemoved:DeleteMarkerCreated',
+                    's3:ReducedRedundancyLostObject'|'s3:ObjectCreated:*'|
+                    's3:ObjectCreated:Put'|'s3:ObjectCreated:Post'|
+                    's3:ObjectCreated:Copy'|
+                    's3:ObjectCreated:CompleteMultipartUpload'|
+                    's3:ObjectRemoved:*'|'s3:ObjectRemoved:Delete'|
+                    's3:ObjectRemoved:DeleteMarkerCreated',
                 ],
                 'Filter': {
                     'Key': {
@@ -323,7 +343,7 @@ def xml_marshal_bucket_notifications(notifications):
         notifications.get('CloudFunctionConfigurations', [])
     )
 
-    return get_xml_data(root)
+    return _get_xml_data(root)
 
 
 NOTIFICATIONS_ARN_FIELDNAME_MAP = {
@@ -380,4 +400,4 @@ def xml_marshal_delete_objects(object_names):
     for object_name in object_names:
         SubElement(SubElement(root, 'Object'), 'Key', object_name)
 
-    return get_xml_data(root)
+    return _get_xml_data(root)


Test patch:
diff --git a/tests/unit/generate_xml_test.py b/tests/unit/generate_xml_test.py
index 64e48da..30d6915 100644
--- a/tests/unit/generate_xml_test.py
+++ b/tests/unit/generate_xml_test.py
@@ -22,8 +22,8 @@ from minio.definitions import UploadPart
 from minio.select.options import (CSVInput, CSVOutput, InputSerialization,
                                   OutputSerialization, RequestProgress,
                                   SelectObjectOptions)
-from minio.xml_marshal import (xml_marshal_bucket_constraint,
-                               xml_marshal_complete_multipart_upload,
+from minio.xml_marshal import (marshal_complete_multipart,
+                               xml_marshal_bucket_constraint,
                                xml_marshal_select)
 
 
@@ -61,7 +61,7 @@ class GenerateRequestTest(TestCase):
                        'acbd18db4cc2f85cedef654fccc4a4d8',
                        None, 0),
         ]
-        actual_string = xml_marshal_complete_multipart_upload(etags)
+        actual_string = marshal_complete_multipart(etags)
         eq_(expected_string, actual_string)
 
     def test_xml_marshal_select(self):