azure-storage-blob 12.23.1__py3-none-any.whl → 12.24.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. azure/storage/blob/_blob_client.py +34 -10
  2. azure/storage/blob/_blob_client_helpers.py +7 -3
  3. azure/storage/blob/_blob_service_client.py +1 -1
  4. azure/storage/blob/_container_client.py +2 -2
  5. azure/storage/blob/_container_client_helpers.py +4 -4
  6. azure/storage/blob/_deserialize.py +2 -2
  7. azure/storage/blob/_encryption.py +2 -0
  8. azure/storage/blob/_generated/_azure_blob_storage.py +1 -1
  9. azure/storage/blob/_generated/_configuration.py +2 -2
  10. azure/storage/blob/_generated/_serialization.py +265 -150
  11. azure/storage/blob/_generated/aio/_azure_blob_storage.py +1 -1
  12. azure/storage/blob/_generated/aio/_configuration.py +2 -2
  13. azure/storage/blob/_generated/aio/operations/_append_blob_operations.py +22 -4
  14. azure/storage/blob/_generated/aio/operations/_blob_operations.py +116 -26
  15. azure/storage/blob/_generated/aio/operations/_block_blob_operations.py +40 -6
  16. azure/storage/blob/_generated/aio/operations/_container_operations.py +36 -18
  17. azure/storage/blob/_generated/aio/operations/_page_blob_operations.py +32 -9
  18. azure/storage/blob/_generated/aio/operations/_service_operations.py +16 -8
  19. azure/storage/blob/_generated/models/_azure_blob_storage_enums.py +1 -0
  20. azure/storage/blob/_generated/operations/_append_blob_operations.py +34 -8
  21. azure/storage/blob/_generated/operations/_blob_operations.py +166 -51
  22. azure/storage/blob/_generated/operations/_block_blob_operations.py +62 -12
  23. azure/storage/blob/_generated/operations/_container_operations.py +54 -36
  24. azure/storage/blob/_generated/operations/_page_blob_operations.py +49 -18
  25. azure/storage/blob/_generated/operations/_service_operations.py +24 -16
  26. azure/storage/blob/_list_blobs_helper.py +1 -1
  27. azure/storage/blob/_models.py +4 -3
  28. azure/storage/blob/_serialize.py +1 -0
  29. azure/storage/blob/_shared/avro/schema.py +1 -0
  30. azure/storage/blob/_shared/base_client.py +8 -8
  31. azure/storage/blob/_shared/base_client_async.py +5 -5
  32. azure/storage/blob/_shared/models.py +5 -2
  33. azure/storage/blob/_shared/policies.py +6 -7
  34. azure/storage/blob/_shared/policies_async.py +1 -1
  35. azure/storage/blob/_shared/request_handlers.py +2 -3
  36. azure/storage/blob/_shared/response_handlers.py +2 -2
  37. azure/storage/blob/_shared/uploads.py +4 -4
  38. azure/storage/blob/_shared/uploads_async.py +4 -4
  39. azure/storage/blob/_shared_access_signature.py +0 -1
  40. azure/storage/blob/_version.py +1 -1
  41. azure/storage/blob/aio/_blob_client_async.py +36 -13
  42. azure/storage/blob/aio/_blob_service_client_async.py +7 -3
  43. azure/storage/blob/aio/_container_client_async.py +4 -4
  44. azure/storage/blob/aio/_lease_async.py +1 -1
  45. azure/storage/blob/aio/_list_blobs_helper.py +1 -2
  46. azure/storage/blob/aio/_models.py +1 -2
  47. {azure_storage_blob-12.23.1.dist-info → azure_storage_blob-12.24.0.dist-info}/METADATA +9 -9
  48. azure_storage_blob-12.24.0.dist-info/RECORD +84 -0
  49. {azure_storage_blob-12.23.1.dist-info → azure_storage_blob-12.24.0.dist-info}/WHEEL +1 -1
  50. azure_storage_blob-12.23.1.dist-info/RECORD +0 -84
  51. {azure_storage_blob-12.23.1.dist-info → azure_storage_blob-12.24.0.dist-info}/LICENSE +0 -0
  52. {azure_storage_blob-12.23.1.dist-info → azure_storage_blob-12.24.0.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,4 @@
1
+ # pylint: disable=too-many-lines
1
2
  # --------------------------------------------------------------------------
2
3
  #
3
4
  # Copyright (c) Microsoft Corporation. All rights reserved.
@@ -24,7 +25,6 @@
24
25
  #
25
26
  # --------------------------------------------------------------------------
26
27
 
27
- # pylint: skip-file
28
28
  # pyright: reportUnnecessaryTypeIgnoreComment=false
29
29
 
30
30
  from base64 import b64decode, b64encode
@@ -52,7 +52,6 @@ from typing import (
52
52
  MutableMapping,
53
53
  Type,
54
54
  List,
55
- Mapping,
56
55
  )
57
56
 
58
57
  try:
@@ -91,6 +90,8 @@ class RawDeserializer:
91
90
  :param data: Input, could be bytes or stream (will be decoded with UTF8) or text
92
91
  :type data: str or bytes or IO
93
92
  :param str content_type: The content type.
93
+ :return: The deserialized data.
94
+ :rtype: object
94
95
  """
95
96
  if hasattr(data, "read"):
96
97
  # Assume a stream
@@ -112,7 +113,7 @@ class RawDeserializer:
112
113
  try:
113
114
  return json.loads(data_as_str)
114
115
  except ValueError as err:
115
- raise DeserializationError("JSON is invalid: {}".format(err), err)
116
+ raise DeserializationError("JSON is invalid: {}".format(err), err) from err
116
117
  elif "xml" in (content_type or []):
117
118
  try:
118
119
 
@@ -155,6 +156,11 @@ class RawDeserializer:
155
156
  Use bytes and headers to NOT use any requests/aiohttp or whatever
156
157
  specific implementation.
157
158
  Headers will tested for "content-type"
159
+
160
+ :param bytes body_bytes: The body of the response.
161
+ :param dict headers: The headers of the response.
162
+ :returns: The deserialized data.
163
+ :rtype: object
158
164
  """
159
165
  # Try to use content-type from headers if available
160
166
  content_type = None
@@ -184,15 +190,30 @@ class UTC(datetime.tzinfo):
184
190
  """Time Zone info for handling UTC"""
185
191
 
186
192
  def utcoffset(self, dt):
187
- """UTF offset for UTC is 0."""
193
+ """UTF offset for UTC is 0.
194
+
195
+ :param datetime.datetime dt: The datetime
196
+ :returns: The offset
197
+ :rtype: datetime.timedelta
198
+ """
188
199
  return datetime.timedelta(0)
189
200
 
190
201
  def tzname(self, dt):
191
- """Timestamp representation."""
202
+ """Timestamp representation.
203
+
204
+ :param datetime.datetime dt: The datetime
205
+ :returns: The timestamp representation
206
+ :rtype: str
207
+ """
192
208
  return "Z"
193
209
 
194
210
  def dst(self, dt):
195
- """No daylight saving for UTC."""
211
+ """No daylight saving for UTC.
212
+
213
+ :param datetime.datetime dt: The datetime
214
+ :returns: The daylight saving time
215
+ :rtype: datetime.timedelta
216
+ """
196
217
  return datetime.timedelta(hours=1)
197
218
 
198
219
 
@@ -235,24 +256,26 @@ except ImportError:
235
256
  _FLATTEN = re.compile(r"(?<!\\)\.")
236
257
 
237
258
 
238
- def attribute_transformer(key, attr_desc, value):
259
+ def attribute_transformer(key, attr_desc, value): # pylint: disable=unused-argument
239
260
  """A key transformer that returns the Python attribute.
240
261
 
241
262
  :param str key: The attribute name
242
263
  :param dict attr_desc: The attribute metadata
243
264
  :param object value: The value
244
265
  :returns: A key using attribute name
266
+ :rtype: str
245
267
  """
246
268
  return (key, value)
247
269
 
248
270
 
249
- def full_restapi_key_transformer(key, attr_desc, value):
271
+ def full_restapi_key_transformer(key, attr_desc, value): # pylint: disable=unused-argument
250
272
  """A key transformer that returns the full RestAPI key path.
251
273
 
252
- :param str _: The attribute name
274
+ :param str key: The attribute name
253
275
  :param dict attr_desc: The attribute metadata
254
276
  :param object value: The value
255
277
  :returns: A list of keys using RestAPI syntax.
278
+ :rtype: list
256
279
  """
257
280
  keys = _FLATTEN.split(attr_desc["key"])
258
281
  return ([_decode_attribute_map_key(k) for k in keys], value)
@@ -265,19 +288,26 @@ def last_restapi_key_transformer(key, attr_desc, value):
265
288
  :param dict attr_desc: The attribute metadata
266
289
  :param object value: The value
267
290
  :returns: The last RestAPI key.
291
+ :rtype: str
268
292
  """
269
293
  key, value = full_restapi_key_transformer(key, attr_desc, value)
270
294
  return (key[-1], value)
271
295
 
272
296
 
273
297
  def _create_xml_node(tag, prefix=None, ns=None):
274
- """Create a XML node."""
298
+ """Create a XML node.
299
+
300
+ :param str tag: The tag name
301
+ :param str prefix: The prefix
302
+ :param str ns: The namespace
303
+ :return: The XML node
304
+ :rtype: xml.etree.ElementTree.Element
305
+ """
275
306
  if prefix and ns:
276
307
  ET.register_namespace(prefix, ns)
277
308
  if ns:
278
309
  return ET.Element("{" + ns + "}" + tag)
279
- else:
280
- return ET.Element(tag)
310
+ return ET.Element(tag)
281
311
 
282
312
 
283
313
  class Model(object):
@@ -291,7 +321,7 @@ class Model(object):
291
321
 
292
322
  def __init__(self, **kwargs: Any) -> None:
293
323
  self.additional_properties: Optional[Dict[str, Any]] = {}
294
- for k in kwargs:
324
+ for k in kwargs: # pylint: disable=consider-using-dict-items
295
325
  if k not in self._attribute_map:
296
326
  _LOGGER.warning("%s is not a known attribute of class %s and will be ignored", k, self.__class__)
297
327
  elif k in self._validation and self._validation[k].get("readonly", False):
@@ -300,13 +330,23 @@ class Model(object):
300
330
  setattr(self, k, kwargs[k])
301
331
 
302
332
  def __eq__(self, other: Any) -> bool:
303
- """Compare objects by comparing all attributes."""
333
+ """Compare objects by comparing all attributes.
334
+
335
+ :param object other: The object to compare
336
+ :returns: True if objects are equal
337
+ :rtype: bool
338
+ """
304
339
  if isinstance(other, self.__class__):
305
340
  return self.__dict__ == other.__dict__
306
341
  return False
307
342
 
308
343
  def __ne__(self, other: Any) -> bool:
309
- """Compare objects by comparing all attributes."""
344
+ """Compare objects by comparing all attributes.
345
+
346
+ :param object other: The object to compare
347
+ :returns: True if objects are not equal
348
+ :rtype: bool
349
+ """
310
350
  return not self.__eq__(other)
311
351
 
312
352
  def __str__(self) -> str:
@@ -326,7 +366,11 @@ class Model(object):
326
366
 
327
367
  @classmethod
328
368
  def _create_xml_node(cls):
329
- """Create XML node."""
369
+ """Create XML node.
370
+
371
+ :returns: The XML node
372
+ :rtype: xml.etree.ElementTree.Element
373
+ """
330
374
  try:
331
375
  xml_map = cls._xml_map # type: ignore
332
376
  except AttributeError:
@@ -346,7 +390,9 @@ class Model(object):
346
390
  :rtype: dict
347
391
  """
348
392
  serializer = Serializer(self._infer_class_models())
349
- return serializer._serialize(self, keep_readonly=keep_readonly, **kwargs) # type: ignore
393
+ return serializer._serialize( # type: ignore # pylint: disable=protected-access
394
+ self, keep_readonly=keep_readonly, **kwargs
395
+ )
350
396
 
351
397
  def as_dict(
352
398
  self,
@@ -380,12 +426,15 @@ class Model(object):
380
426
 
381
427
  If you want XML serialization, you can pass the kwargs is_xml=True.
382
428
 
429
+ :param bool keep_readonly: If you want to serialize the readonly attributes
383
430
  :param function key_transformer: A key transformer function.
384
431
  :returns: A dict JSON compatible object
385
432
  :rtype: dict
386
433
  """
387
434
  serializer = Serializer(self._infer_class_models())
388
- return serializer._serialize(self, key_transformer=key_transformer, keep_readonly=keep_readonly, **kwargs) # type: ignore
435
+ return serializer._serialize( # type: ignore # pylint: disable=protected-access
436
+ self, key_transformer=key_transformer, keep_readonly=keep_readonly, **kwargs
437
+ )
389
438
 
390
439
  @classmethod
391
440
  def _infer_class_models(cls):
@@ -395,7 +444,7 @@ class Model(object):
395
444
  client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)}
396
445
  if cls.__name__ not in client_models:
397
446
  raise ValueError("Not Autorest generated code")
398
- except Exception:
447
+ except Exception: # pylint: disable=broad-exception-caught
399
448
  # Assume it's not Autorest generated (tests?). Add ourselves as dependencies.
400
449
  client_models = {cls.__name__: cls}
401
450
  return client_models
@@ -408,6 +457,7 @@ class Model(object):
408
457
  :param str content_type: JSON by default, set application/xml if XML.
409
458
  :returns: An instance of this model
410
459
  :raises: DeserializationError if something went wrong
460
+ :rtype: ModelType
411
461
  """
412
462
  deserializer = Deserializer(cls._infer_class_models())
413
463
  return deserializer(cls.__name__, data, content_type=content_type) # type: ignore
@@ -426,9 +476,11 @@ class Model(object):
426
476
  and last_rest_key_case_insensitive_extractor)
427
477
 
428
478
  :param dict data: A dict using RestAPI structure
479
+ :param function key_extractors: A key extractor function.
429
480
  :param str content_type: JSON by default, set application/xml if XML.
430
481
  :returns: An instance of this model
431
482
  :raises: DeserializationError if something went wrong
483
+ :rtype: ModelType
432
484
  """
433
485
  deserializer = Deserializer(cls._infer_class_models())
434
486
  deserializer.key_extractors = ( # type: ignore
@@ -448,7 +500,7 @@ class Model(object):
448
500
  return {}
449
501
  result = dict(cls._subtype_map[key])
450
502
  for valuetype in cls._subtype_map[key].values():
451
- result.update(objects[valuetype]._flatten_subtype(key, objects))
503
+ result.update(objects[valuetype]._flatten_subtype(key, objects)) # pylint: disable=protected-access
452
504
  return result
453
505
 
454
506
  @classmethod
@@ -456,6 +508,11 @@ class Model(object):
456
508
  """Check the class _subtype_map for any child classes.
457
509
  We want to ignore any inherited _subtype_maps.
458
510
  Remove the polymorphic key from the initial data.
511
+
512
+ :param dict response: The initial data
513
+ :param dict objects: The class objects
514
+ :returns: The class to be used
515
+ :rtype: class
459
516
  """
460
517
  for subtype_key in cls.__dict__.get("_subtype_map", {}).keys():
461
518
  subtype_value = None
@@ -501,11 +558,13 @@ def _decode_attribute_map_key(key):
501
558
  inside the received data.
502
559
 
503
560
  :param str key: A key string from the generated code
561
+ :returns: The decoded key
562
+ :rtype: str
504
563
  """
505
564
  return key.replace("\\.", ".")
506
565
 
507
566
 
508
- class Serializer(object):
567
+ class Serializer(object): # pylint: disable=too-many-public-methods
509
568
  """Request object model serializer."""
510
569
 
511
570
  basic_types = {str: "str", int: "int", bool: "bool", float: "float"}
@@ -560,13 +619,16 @@ class Serializer(object):
560
619
  self.key_transformer = full_restapi_key_transformer
561
620
  self.client_side_validation = True
562
621
 
563
- def _serialize(self, target_obj, data_type=None, **kwargs):
622
+ def _serialize( # pylint: disable=too-many-nested-blocks, too-many-branches, too-many-statements, too-many-locals
623
+ self, target_obj, data_type=None, **kwargs
624
+ ):
564
625
  """Serialize data into a string according to type.
565
626
 
566
- :param target_obj: The data to be serialized.
627
+ :param object target_obj: The data to be serialized.
567
628
  :param str data_type: The type to be serialized from.
568
629
  :rtype: str, dict
569
630
  :raises: SerializationError if serialization fails.
631
+ :returns: The serialized data.
570
632
  """
571
633
  key_transformer = kwargs.get("key_transformer", self.key_transformer)
572
634
  keep_readonly = kwargs.get("keep_readonly", False)
@@ -592,12 +654,14 @@ class Serializer(object):
592
654
 
593
655
  serialized = {}
594
656
  if is_xml_model_serialization:
595
- serialized = target_obj._create_xml_node()
657
+ serialized = target_obj._create_xml_node() # pylint: disable=protected-access
596
658
  try:
597
- attributes = target_obj._attribute_map
659
+ attributes = target_obj._attribute_map # pylint: disable=protected-access
598
660
  for attr, attr_desc in attributes.items():
599
661
  attr_name = attr
600
- if not keep_readonly and target_obj._validation.get(attr_name, {}).get("readonly", False):
662
+ if not keep_readonly and target_obj._validation.get( # pylint: disable=protected-access
663
+ attr_name, {}
664
+ ).get("readonly", False):
601
665
  continue
602
666
 
603
667
  if attr_name == "additional_properties" and attr_desc["key"] == "":
@@ -633,7 +697,8 @@ class Serializer(object):
633
697
  if isinstance(new_attr, list):
634
698
  serialized.extend(new_attr) # type: ignore
635
699
  elif isinstance(new_attr, ET.Element):
636
- # If the down XML has no XML/Name, we MUST replace the tag with the local tag. But keeping the namespaces.
700
+ # If the down XML has no XML/Name,
701
+ # we MUST replace the tag with the local tag. But keeping the namespaces.
637
702
  if "name" not in getattr(orig_attr, "_xml_map", {}):
638
703
  splitted_tag = new_attr.tag.split("}")
639
704
  if len(splitted_tag) == 2: # Namespace
@@ -664,17 +729,17 @@ class Serializer(object):
664
729
  except (AttributeError, KeyError, TypeError) as err:
665
730
  msg = "Attribute {} in object {} cannot be serialized.\n{}".format(attr_name, class_name, str(target_obj))
666
731
  raise SerializationError(msg) from err
667
- else:
668
- return serialized
732
+ return serialized
669
733
 
670
734
  def body(self, data, data_type, **kwargs):
671
735
  """Serialize data intended for a request body.
672
736
 
673
- :param data: The data to be serialized.
737
+ :param object data: The data to be serialized.
674
738
  :param str data_type: The type to be serialized from.
675
739
  :rtype: dict
676
740
  :raises: SerializationError if serialization fails.
677
741
  :raises: ValueError if data is None
742
+ :returns: The serialized request body
678
743
  """
679
744
 
680
745
  # Just in case this is a dict
@@ -703,7 +768,7 @@ class Serializer(object):
703
768
  attribute_key_case_insensitive_extractor,
704
769
  last_rest_key_case_insensitive_extractor,
705
770
  ]
706
- data = deserializer._deserialize(data_type, data)
771
+ data = deserializer._deserialize(data_type, data) # pylint: disable=protected-access
707
772
  except DeserializationError as err:
708
773
  raise SerializationError("Unable to build a model: " + str(err)) from err
709
774
 
@@ -712,9 +777,11 @@ class Serializer(object):
712
777
  def url(self, name, data, data_type, **kwargs):
713
778
  """Serialize data intended for a URL path.
714
779
 
715
- :param data: The data to be serialized.
780
+ :param str name: The name of the URL path parameter.
781
+ :param object data: The data to be serialized.
716
782
  :param str data_type: The type to be serialized from.
717
783
  :rtype: str
784
+ :returns: The serialized URL path
718
785
  :raises: TypeError if serialization fails.
719
786
  :raises: ValueError if data is None
720
787
  """
@@ -728,21 +795,20 @@ class Serializer(object):
728
795
  output = output.replace("{", quote("{")).replace("}", quote("}"))
729
796
  else:
730
797
  output = quote(str(output), safe="")
731
- except SerializationError:
732
- raise TypeError("{} must be type {}.".format(name, data_type))
733
- else:
734
- return output
798
+ except SerializationError as exc:
799
+ raise TypeError("{} must be type {}.".format(name, data_type)) from exc
800
+ return output
735
801
 
736
802
  def query(self, name, data, data_type, **kwargs):
737
803
  """Serialize data intended for a URL query.
738
804
 
739
- :param data: The data to be serialized.
805
+ :param str name: The name of the query parameter.
806
+ :param object data: The data to be serialized.
740
807
  :param str data_type: The type to be serialized from.
741
- :keyword bool skip_quote: Whether to skip quote the serialized result.
742
- Defaults to False.
743
808
  :rtype: str, list
744
809
  :raises: TypeError if serialization fails.
745
810
  :raises: ValueError if data is None
811
+ :returns: The serialized query parameter
746
812
  """
747
813
  try:
748
814
  # Treat the list aside, since we don't want to encode the div separator
@@ -759,19 +825,20 @@ class Serializer(object):
759
825
  output = str(output)
760
826
  else:
761
827
  output = quote(str(output), safe="")
762
- except SerializationError:
763
- raise TypeError("{} must be type {}.".format(name, data_type))
764
- else:
765
- return str(output)
828
+ except SerializationError as exc:
829
+ raise TypeError("{} must be type {}.".format(name, data_type)) from exc
830
+ return str(output)
766
831
 
767
832
  def header(self, name, data, data_type, **kwargs):
768
833
  """Serialize data intended for a request header.
769
834
 
770
- :param data: The data to be serialized.
835
+ :param str name: The name of the header.
836
+ :param object data: The data to be serialized.
771
837
  :param str data_type: The type to be serialized from.
772
838
  :rtype: str
773
839
  :raises: TypeError if serialization fails.
774
840
  :raises: ValueError if data is None
841
+ :returns: The serialized header
775
842
  """
776
843
  try:
777
844
  if data_type in ["[str]"]:
@@ -780,21 +847,20 @@ class Serializer(object):
780
847
  output = self.serialize_data(data, data_type, **kwargs)
781
848
  if data_type == "bool":
782
849
  output = json.dumps(output)
783
- except SerializationError:
784
- raise TypeError("{} must be type {}.".format(name, data_type))
785
- else:
786
- return str(output)
850
+ except SerializationError as exc:
851
+ raise TypeError("{} must be type {}.".format(name, data_type)) from exc
852
+ return str(output)
787
853
 
788
854
  def serialize_data(self, data, data_type, **kwargs):
789
855
  """Serialize generic data according to supplied data type.
790
856
 
791
- :param data: The data to be serialized.
857
+ :param object data: The data to be serialized.
792
858
  :param str data_type: The type to be serialized from.
793
- :param bool required: Whether it's essential that the data not be
794
- empty or None
795
859
  :raises: AttributeError if required data is None.
796
860
  :raises: ValueError if data is None
797
861
  :raises: SerializationError if serialization fails.
862
+ :returns: The serialized data.
863
+ :rtype: str, int, float, bool, dict, list
798
864
  """
799
865
  if data is None:
800
866
  raise ValueError("No value for given attribute")
@@ -805,7 +871,7 @@ class Serializer(object):
805
871
  if data_type in self.basic_types.values():
806
872
  return self.serialize_basic(data, data_type, **kwargs)
807
873
 
808
- elif data_type in self.serialize_type:
874
+ if data_type in self.serialize_type:
809
875
  return self.serialize_type[data_type](data, **kwargs)
810
876
 
811
877
  # If dependencies is empty, try with current data class
@@ -821,11 +887,10 @@ class Serializer(object):
821
887
  except (ValueError, TypeError) as err:
822
888
  msg = "Unable to serialize value: {!r} as type: {!r}."
823
889
  raise SerializationError(msg.format(data, data_type)) from err
824
- else:
825
- return self._serialize(data, **kwargs)
890
+ return self._serialize(data, **kwargs)
826
891
 
827
892
  @classmethod
828
- def _get_custom_serializers(cls, data_type, **kwargs):
893
+ def _get_custom_serializers(cls, data_type, **kwargs): # pylint: disable=inconsistent-return-statements
829
894
  custom_serializer = kwargs.get("basic_types_serializers", {}).get(data_type)
830
895
  if custom_serializer:
831
896
  return custom_serializer
@@ -841,23 +906,26 @@ class Serializer(object):
841
906
  - basic_types_serializers dict[str, callable] : If set, use the callable as serializer
842
907
  - is_xml bool : If set, use xml_basic_types_serializers
843
908
 
844
- :param data: Object to be serialized.
909
+ :param obj data: Object to be serialized.
845
910
  :param str data_type: Type of object in the iterable.
911
+ :rtype: str, int, float, bool
912
+ :return: serialized object
846
913
  """
847
914
  custom_serializer = cls._get_custom_serializers(data_type, **kwargs)
848
915
  if custom_serializer:
849
916
  return custom_serializer(data)
850
917
  if data_type == "str":
851
918
  return cls.serialize_unicode(data)
852
- return eval(data_type)(data) # nosec
919
+ return eval(data_type)(data) # nosec # pylint: disable=eval-used
853
920
 
854
921
  @classmethod
855
922
  def serialize_unicode(cls, data):
856
923
  """Special handling for serializing unicode strings in Py2.
857
924
  Encode to UTF-8 if unicode, otherwise handle as a str.
858
925
 
859
- :param data: Object to be serialized.
926
+ :param str data: Object to be serialized.
860
927
  :rtype: str
928
+ :return: serialized object
861
929
  """
862
930
  try: # If I received an enum, return its value
863
931
  return data.value
@@ -871,8 +939,7 @@ class Serializer(object):
871
939
  return data
872
940
  except NameError:
873
941
  return str(data)
874
- else:
875
- return str(data)
942
+ return str(data)
876
943
 
877
944
  def serialize_iter(self, data, iter_type, div=None, **kwargs):
878
945
  """Serialize iterable.
@@ -882,15 +949,13 @@ class Serializer(object):
882
949
  serialization_ctxt['type'] should be same as data_type.
883
950
  - is_xml bool : If set, serialize as XML
884
951
 
885
- :param list attr: Object to be serialized.
952
+ :param list data: Object to be serialized.
886
953
  :param str iter_type: Type of object in the iterable.
887
- :param bool required: Whether the objects in the iterable must
888
- not be None or empty.
889
954
  :param str div: If set, this str will be used to combine the elements
890
955
  in the iterable into a combined string. Default is 'None'.
891
- :keyword bool do_quote: Whether to quote the serialized result of each iterable element.
892
956
  Defaults to False.
893
957
  :rtype: list, str
958
+ :return: serialized iterable
894
959
  """
895
960
  if isinstance(data, str):
896
961
  raise SerializationError("Refuse str type as a valid iter type.")
@@ -945,9 +1010,8 @@ class Serializer(object):
945
1010
 
946
1011
  :param dict attr: Object to be serialized.
947
1012
  :param str dict_type: Type of object in the dictionary.
948
- :param bool required: Whether the objects in the dictionary must
949
- not be None or empty.
950
1013
  :rtype: dict
1014
+ :return: serialized dictionary
951
1015
  """
952
1016
  serialization_ctxt = kwargs.get("serialization_ctxt", {})
953
1017
  serialized = {}
@@ -971,7 +1035,7 @@ class Serializer(object):
971
1035
 
972
1036
  return serialized
973
1037
 
974
- def serialize_object(self, attr, **kwargs):
1038
+ def serialize_object(self, attr, **kwargs): # pylint: disable=too-many-return-statements
975
1039
  """Serialize a generic object.
976
1040
  This will be handled as a dictionary. If object passed in is not
977
1041
  a basic type (str, int, float, dict, list) it will simply be
@@ -979,6 +1043,7 @@ class Serializer(object):
979
1043
 
980
1044
  :param dict attr: Object to be serialized.
981
1045
  :rtype: dict or str
1046
+ :return: serialized object
982
1047
  """
983
1048
  if attr is None:
984
1049
  return None
@@ -1003,7 +1068,7 @@ class Serializer(object):
1003
1068
  return self.serialize_decimal(attr)
1004
1069
 
1005
1070
  # If it's a model or I know this dependency, serialize as a Model
1006
- elif obj_type in self.dependencies.values() or isinstance(attr, Model):
1071
+ if obj_type in self.dependencies.values() or isinstance(attr, Model):
1007
1072
  return self._serialize(attr)
1008
1073
 
1009
1074
  if obj_type == dict:
@@ -1034,56 +1099,61 @@ class Serializer(object):
1034
1099
  try:
1035
1100
  enum_obj(result) # type: ignore
1036
1101
  return result
1037
- except ValueError:
1102
+ except ValueError as exc:
1038
1103
  for enum_value in enum_obj: # type: ignore
1039
1104
  if enum_value.value.lower() == str(attr).lower():
1040
1105
  return enum_value.value
1041
1106
  error = "{!r} is not valid value for enum {!r}"
1042
- raise SerializationError(error.format(attr, enum_obj))
1107
+ raise SerializationError(error.format(attr, enum_obj)) from exc
1043
1108
 
1044
1109
  @staticmethod
1045
- def serialize_bytearray(attr, **kwargs):
1110
+ def serialize_bytearray(attr, **kwargs): # pylint: disable=unused-argument
1046
1111
  """Serialize bytearray into base-64 string.
1047
1112
 
1048
- :param attr: Object to be serialized.
1113
+ :param str attr: Object to be serialized.
1049
1114
  :rtype: str
1115
+ :return: serialized base64
1050
1116
  """
1051
1117
  return b64encode(attr).decode()
1052
1118
 
1053
1119
  @staticmethod
1054
- def serialize_base64(attr, **kwargs):
1120
+ def serialize_base64(attr, **kwargs): # pylint: disable=unused-argument
1055
1121
  """Serialize str into base-64 string.
1056
1122
 
1057
- :param attr: Object to be serialized.
1123
+ :param str attr: Object to be serialized.
1058
1124
  :rtype: str
1125
+ :return: serialized base64
1059
1126
  """
1060
1127
  encoded = b64encode(attr).decode("ascii")
1061
1128
  return encoded.strip("=").replace("+", "-").replace("/", "_")
1062
1129
 
1063
1130
  @staticmethod
1064
- def serialize_decimal(attr, **kwargs):
1131
+ def serialize_decimal(attr, **kwargs): # pylint: disable=unused-argument
1065
1132
  """Serialize Decimal object to float.
1066
1133
 
1067
- :param attr: Object to be serialized.
1134
+ :param decimal attr: Object to be serialized.
1068
1135
  :rtype: float
1136
+ :return: serialized decimal
1069
1137
  """
1070
1138
  return float(attr)
1071
1139
 
1072
1140
  @staticmethod
1073
- def serialize_long(attr, **kwargs):
1141
+ def serialize_long(attr, **kwargs): # pylint: disable=unused-argument
1074
1142
  """Serialize long (Py2) or int (Py3).
1075
1143
 
1076
- :param attr: Object to be serialized.
1144
+ :param int attr: Object to be serialized.
1077
1145
  :rtype: int/long
1146
+ :return: serialized long
1078
1147
  """
1079
1148
  return _long_type(attr)
1080
1149
 
1081
1150
  @staticmethod
1082
- def serialize_date(attr, **kwargs):
1151
+ def serialize_date(attr, **kwargs): # pylint: disable=unused-argument
1083
1152
  """Serialize Date object into ISO-8601 formatted string.
1084
1153
 
1085
1154
  :param Date attr: Object to be serialized.
1086
1155
  :rtype: str
1156
+ :return: serialized date
1087
1157
  """
1088
1158
  if isinstance(attr, str):
1089
1159
  attr = isodate.parse_date(attr)
@@ -1091,11 +1161,12 @@ class Serializer(object):
1091
1161
  return t
1092
1162
 
1093
1163
  @staticmethod
1094
- def serialize_time(attr, **kwargs):
1164
+ def serialize_time(attr, **kwargs): # pylint: disable=unused-argument
1095
1165
  """Serialize Time object into ISO-8601 formatted string.
1096
1166
 
1097
1167
  :param datetime.time attr: Object to be serialized.
1098
1168
  :rtype: str
1169
+ :return: serialized time
1099
1170
  """
1100
1171
  if isinstance(attr, str):
1101
1172
  attr = isodate.parse_time(attr)
@@ -1105,30 +1176,32 @@ class Serializer(object):
1105
1176
  return t
1106
1177
 
1107
1178
  @staticmethod
1108
- def serialize_duration(attr, **kwargs):
1179
+ def serialize_duration(attr, **kwargs): # pylint: disable=unused-argument
1109
1180
  """Serialize TimeDelta object into ISO-8601 formatted string.
1110
1181
 
1111
1182
  :param TimeDelta attr: Object to be serialized.
1112
1183
  :rtype: str
1184
+ :return: serialized duration
1113
1185
  """
1114
1186
  if isinstance(attr, str):
1115
1187
  attr = isodate.parse_duration(attr)
1116
1188
  return isodate.duration_isoformat(attr)
1117
1189
 
1118
1190
  @staticmethod
1119
- def serialize_rfc(attr, **kwargs):
1191
+ def serialize_rfc(attr, **kwargs): # pylint: disable=unused-argument
1120
1192
  """Serialize Datetime object into RFC-1123 formatted string.
1121
1193
 
1122
1194
  :param Datetime attr: Object to be serialized.
1123
1195
  :rtype: str
1124
1196
  :raises: TypeError if format invalid.
1197
+ :return: serialized rfc
1125
1198
  """
1126
1199
  try:
1127
1200
  if not attr.tzinfo:
1128
1201
  _LOGGER.warning("Datetime with no tzinfo will be considered UTC.")
1129
1202
  utc = attr.utctimetuple()
1130
- except AttributeError:
1131
- raise TypeError("RFC1123 object must be valid Datetime object.")
1203
+ except AttributeError as exc:
1204
+ raise TypeError("RFC1123 object must be valid Datetime object.") from exc
1132
1205
 
1133
1206
  return "{}, {:02} {} {:04} {:02}:{:02}:{:02} GMT".format(
1134
1207
  Serializer.days[utc.tm_wday],
@@ -1141,12 +1214,13 @@ class Serializer(object):
1141
1214
  )
1142
1215
 
1143
1216
  @staticmethod
1144
- def serialize_iso(attr, **kwargs):
1217
+ def serialize_iso(attr, **kwargs): # pylint: disable=unused-argument
1145
1218
  """Serialize Datetime object into ISO-8601 formatted string.
1146
1219
 
1147
1220
  :param Datetime attr: Object to be serialized.
1148
1221
  :rtype: str
1149
1222
  :raises: SerializationError if format invalid.
1223
+ :return: serialized iso
1150
1224
  """
1151
1225
  if isinstance(attr, str):
1152
1226
  attr = isodate.parse_datetime(attr)
@@ -1172,13 +1246,14 @@ class Serializer(object):
1172
1246
  raise TypeError(msg) from err
1173
1247
 
1174
1248
  @staticmethod
1175
- def serialize_unix(attr, **kwargs):
1249
+ def serialize_unix(attr, **kwargs): # pylint: disable=unused-argument
1176
1250
  """Serialize Datetime object into IntTime format.
1177
1251
  This is represented as seconds.
1178
1252
 
1179
1253
  :param Datetime attr: Object to be serialized.
1180
1254
  :rtype: int
1181
1255
  :raises: SerializationError if format invalid
1256
+ :return: serialied unix
1182
1257
  """
1183
1258
  if isinstance(attr, int):
1184
1259
  return attr
@@ -1186,11 +1261,11 @@ class Serializer(object):
1186
1261
  if not attr.tzinfo:
1187
1262
  _LOGGER.warning("Datetime with no tzinfo will be considered UTC.")
1188
1263
  return int(calendar.timegm(attr.utctimetuple()))
1189
- except AttributeError:
1190
- raise TypeError("Unix time object must be valid Datetime object.")
1264
+ except AttributeError as exc:
1265
+ raise TypeError("Unix time object must be valid Datetime object.") from exc
1191
1266
 
1192
1267
 
1193
- def rest_key_extractor(attr, attr_desc, data):
1268
+ def rest_key_extractor(attr, attr_desc, data): # pylint: disable=unused-argument
1194
1269
  key = attr_desc["key"]
1195
1270
  working_data = data
1196
1271
 
@@ -1211,7 +1286,9 @@ def rest_key_extractor(attr, attr_desc, data):
1211
1286
  return working_data.get(key)
1212
1287
 
1213
1288
 
1214
- def rest_key_case_insensitive_extractor(attr, attr_desc, data):
1289
+ def rest_key_case_insensitive_extractor( # pylint: disable=unused-argument, inconsistent-return-statements
1290
+ attr, attr_desc, data
1291
+ ):
1215
1292
  key = attr_desc["key"]
1216
1293
  working_data = data
1217
1294
 
@@ -1232,17 +1309,29 @@ def rest_key_case_insensitive_extractor(attr, attr_desc, data):
1232
1309
  return attribute_key_case_insensitive_extractor(key, None, working_data)
1233
1310
 
1234
1311
 
1235
- def last_rest_key_extractor(attr, attr_desc, data):
1236
- """Extract the attribute in "data" based on the last part of the JSON path key."""
1312
+ def last_rest_key_extractor(attr, attr_desc, data): # pylint: disable=unused-argument
1313
+ """Extract the attribute in "data" based on the last part of the JSON path key.
1314
+
1315
+ :param str attr: The attribute to extract
1316
+ :param dict attr_desc: The attribute description
1317
+ :param dict data: The data to extract from
1318
+ :rtype: object
1319
+ :returns: The extracted attribute
1320
+ """
1237
1321
  key = attr_desc["key"]
1238
1322
  dict_keys = _FLATTEN.split(key)
1239
1323
  return attribute_key_extractor(dict_keys[-1], None, data)
1240
1324
 
1241
1325
 
1242
- def last_rest_key_case_insensitive_extractor(attr, attr_desc, data):
1326
+ def last_rest_key_case_insensitive_extractor(attr, attr_desc, data): # pylint: disable=unused-argument
1243
1327
  """Extract the attribute in "data" based on the last part of the JSON path key.
1244
1328
 
1245
1329
  This is the case insensitive version of "last_rest_key_extractor"
1330
+ :param str attr: The attribute to extract
1331
+ :param dict attr_desc: The attribute description
1332
+ :param dict data: The data to extract from
1333
+ :rtype: object
1334
+ :returns: The extracted attribute
1246
1335
  """
1247
1336
  key = attr_desc["key"]
1248
1337
  dict_keys = _FLATTEN.split(key)
@@ -1279,7 +1368,7 @@ def _extract_name_from_internal_type(internal_type):
1279
1368
  return xml_name
1280
1369
 
1281
1370
 
1282
- def xml_key_extractor(attr, attr_desc, data):
1371
+ def xml_key_extractor(attr, attr_desc, data): # pylint: disable=unused-argument,too-many-return-statements
1283
1372
  if isinstance(data, dict):
1284
1373
  return None
1285
1374
 
@@ -1331,22 +1420,21 @@ def xml_key_extractor(attr, attr_desc, data):
1331
1420
  if is_iter_type:
1332
1421
  if is_wrapped:
1333
1422
  return None # is_wrapped no node, we want None
1334
- else:
1335
- return [] # not wrapped, assume empty list
1423
+ return [] # not wrapped, assume empty list
1336
1424
  return None # Assume it's not there, maybe an optional node.
1337
1425
 
1338
1426
  # If is_iter_type and not wrapped, return all found children
1339
1427
  if is_iter_type:
1340
1428
  if not is_wrapped:
1341
1429
  return children
1342
- else: # Iter and wrapped, should have found one node only (the wrap one)
1343
- if len(children) != 1:
1344
- raise DeserializationError(
1345
- "Tried to deserialize an array not wrapped, and found several nodes '{}'. Maybe you should declare this array as wrapped?".format(
1346
- xml_name
1347
- )
1430
+ # Iter and wrapped, should have found one node only (the wrap one)
1431
+ if len(children) != 1:
1432
+ raise DeserializationError(
1433
+ "Tried to deserialize an array not wrapped, and found several nodes '{}'. Maybe you should declare this array as wrapped?".format( # pylint: disable=line-too-long
1434
+ xml_name
1348
1435
  )
1349
- return list(children[0]) # Might be empty list and that's ok.
1436
+ )
1437
+ return list(children[0]) # Might be empty list and that's ok.
1350
1438
 
1351
1439
  # Here it's not a itertype, we should have found one element only or empty
1352
1440
  if len(children) > 1:
@@ -1363,7 +1451,7 @@ class Deserializer(object):
1363
1451
 
1364
1452
  basic_types = {str: "str", int: "int", bool: "bool", float: "float"}
1365
1453
 
1366
- valid_date = re.compile(r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}" r"\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?")
1454
+ valid_date = re.compile(r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?")
1367
1455
 
1368
1456
  def __init__(self, classes: Optional[Mapping[str, type]] = None):
1369
1457
  self.deserialize_type = {
@@ -1403,11 +1491,12 @@ class Deserializer(object):
1403
1491
  :param str content_type: Swagger "produces" if available.
1404
1492
  :raises: DeserializationError if deserialization fails.
1405
1493
  :return: Deserialized object.
1494
+ :rtype: object
1406
1495
  """
1407
1496
  data = self._unpack_content(response_data, content_type)
1408
1497
  return self._deserialize(target_obj, data)
1409
1498
 
1410
- def _deserialize(self, target_obj, data):
1499
+ def _deserialize(self, target_obj, data): # pylint: disable=inconsistent-return-statements
1411
1500
  """Call the deserializer on a model.
1412
1501
 
1413
1502
  Data needs to be already deserialized as JSON or XML ElementTree
@@ -1416,12 +1505,13 @@ class Deserializer(object):
1416
1505
  :param object data: Object to deserialize.
1417
1506
  :raises: DeserializationError if deserialization fails.
1418
1507
  :return: Deserialized object.
1508
+ :rtype: object
1419
1509
  """
1420
1510
  # This is already a model, go recursive just in case
1421
1511
  if hasattr(data, "_attribute_map"):
1422
1512
  constants = [name for name, config in getattr(data, "_validation", {}).items() if config.get("constant")]
1423
1513
  try:
1424
- for attr, mapconfig in data._attribute_map.items():
1514
+ for attr, mapconfig in data._attribute_map.items(): # pylint: disable=protected-access
1425
1515
  if attr in constants:
1426
1516
  continue
1427
1517
  value = getattr(data, attr)
@@ -1440,13 +1530,13 @@ class Deserializer(object):
1440
1530
 
1441
1531
  if isinstance(response, str):
1442
1532
  return self.deserialize_data(data, response)
1443
- elif isinstance(response, type) and issubclass(response, Enum):
1533
+ if isinstance(response, type) and issubclass(response, Enum):
1444
1534
  return self.deserialize_enum(data, response)
1445
1535
 
1446
1536
  if data is None or data is CoreNull:
1447
1537
  return data
1448
1538
  try:
1449
- attributes = response._attribute_map # type: ignore
1539
+ attributes = response._attribute_map # type: ignore # pylint: disable=protected-access
1450
1540
  d_attrs = {}
1451
1541
  for attr, attr_desc in attributes.items():
1452
1542
  # Check empty string. If it's not empty, someone has a real "additionalProperties"...
@@ -1476,9 +1566,8 @@ class Deserializer(object):
1476
1566
  except (AttributeError, TypeError, KeyError) as err:
1477
1567
  msg = "Unable to deserialize to object: " + class_name # type: ignore
1478
1568
  raise DeserializationError(msg) from err
1479
- else:
1480
- additional_properties = self._build_additional_properties(attributes, data)
1481
- return self._instantiate_model(response, d_attrs, additional_properties)
1569
+ additional_properties = self._build_additional_properties(attributes, data)
1570
+ return self._instantiate_model(response, d_attrs, additional_properties)
1482
1571
 
1483
1572
  def _build_additional_properties(self, attribute_map, data):
1484
1573
  if not self.additional_properties_detection:
@@ -1505,6 +1594,8 @@ class Deserializer(object):
1505
1594
 
1506
1595
  :param str target: The target object type to deserialize to.
1507
1596
  :param str/dict data: The response data to deserialize.
1597
+ :return: The classified target object and its class name.
1598
+ :rtype: tuple
1508
1599
  """
1509
1600
  if target is None:
1510
1601
  return None, None
@@ -1516,7 +1607,7 @@ class Deserializer(object):
1516
1607
  return target, target
1517
1608
 
1518
1609
  try:
1519
- target = target._classify(data, self.dependencies) # type: ignore
1610
+ target = target._classify(data, self.dependencies) # type: ignore # pylint: disable=protected-access
1520
1611
  except AttributeError:
1521
1612
  pass # Target is not a Model, no classify
1522
1613
  return target, target.__class__.__name__ # type: ignore
@@ -1531,10 +1622,12 @@ class Deserializer(object):
1531
1622
  :param str target_obj: The target object type to deserialize to.
1532
1623
  :param str/dict data: The response data to deserialize.
1533
1624
  :param str content_type: Swagger "produces" if available.
1625
+ :return: Deserialized object.
1626
+ :rtype: object
1534
1627
  """
1535
1628
  try:
1536
1629
  return self(target_obj, data, content_type=content_type)
1537
- except:
1630
+ except: # pylint: disable=bare-except
1538
1631
  _LOGGER.debug(
1539
1632
  "Ran into a deserialization error. Ignoring since this is failsafe deserialization", exc_info=True
1540
1633
  )
@@ -1552,10 +1645,12 @@ class Deserializer(object):
1552
1645
 
1553
1646
  If raw_data is something else, bypass all logic and return it directly.
1554
1647
 
1555
- :param raw_data: Data to be processed.
1556
- :param content_type: How to parse if raw_data is a string/bytes.
1648
+ :param obj raw_data: Data to be processed.
1649
+ :param str content_type: How to parse if raw_data is a string/bytes.
1557
1650
  :raises JSONDecodeError: If JSON is requested and parsing is impossible.
1558
1651
  :raises UnicodeDecodeError: If bytes is not UTF8
1652
+ :rtype: object
1653
+ :return: Unpacked content.
1559
1654
  """
1560
1655
  # Assume this is enough to detect a Pipeline Response without importing it
1561
1656
  context = getattr(raw_data, "context", {})
@@ -1579,14 +1674,21 @@ class Deserializer(object):
1579
1674
  def _instantiate_model(self, response, attrs, additional_properties=None):
1580
1675
  """Instantiate a response model passing in deserialized args.
1581
1676
 
1582
- :param response: The response model class.
1583
- :param d_attrs: The deserialized response attributes.
1677
+ :param Response response: The response model class.
1678
+ :param dict attrs: The deserialized response attributes.
1679
+ :param dict additional_properties: Additional properties to be set.
1680
+ :rtype: Response
1681
+ :return: The instantiated response model.
1584
1682
  """
1585
1683
  if callable(response):
1586
1684
  subtype = getattr(response, "_subtype_map", {})
1587
1685
  try:
1588
- readonly = [k for k, v in response._validation.items() if v.get("readonly")]
1589
- const = [k for k, v in response._validation.items() if v.get("constant")]
1686
+ readonly = [
1687
+ k for k, v in response._validation.items() if v.get("readonly") # pylint: disable=protected-access
1688
+ ]
1689
+ const = [
1690
+ k for k, v in response._validation.items() if v.get("constant") # pylint: disable=protected-access
1691
+ ]
1590
1692
  kwargs = {k: v for k, v in attrs.items() if k not in subtype and k not in readonly + const}
1591
1693
  response_obj = response(**kwargs)
1592
1694
  for attr in readonly:
@@ -1596,7 +1698,7 @@ class Deserializer(object):
1596
1698
  return response_obj
1597
1699
  except TypeError as err:
1598
1700
  msg = "Unable to deserialize {} into model {}. ".format(kwargs, response) # type: ignore
1599
- raise DeserializationError(msg + str(err))
1701
+ raise DeserializationError(msg + str(err)) from err
1600
1702
  else:
1601
1703
  try:
1602
1704
  for attr, value in attrs.items():
@@ -1605,15 +1707,16 @@ class Deserializer(object):
1605
1707
  except Exception as exp:
1606
1708
  msg = "Unable to populate response model. "
1607
1709
  msg += "Type: {}, Error: {}".format(type(response), exp)
1608
- raise DeserializationError(msg)
1710
+ raise DeserializationError(msg) from exp
1609
1711
 
1610
- def deserialize_data(self, data, data_type):
1712
+ def deserialize_data(self, data, data_type): # pylint: disable=too-many-return-statements
1611
1713
  """Process data for deserialization according to data type.
1612
1714
 
1613
1715
  :param str data: The response string to be deserialized.
1614
1716
  :param str data_type: The type to deserialize to.
1615
1717
  :raises: DeserializationError if deserialization fails.
1616
1718
  :return: Deserialized object.
1719
+ :rtype: object
1617
1720
  """
1618
1721
  if data is None:
1619
1722
  return data
@@ -1627,7 +1730,11 @@ class Deserializer(object):
1627
1730
  if isinstance(data, self.deserialize_expected_types.get(data_type, tuple())):
1628
1731
  return data
1629
1732
 
1630
- is_a_text_parsing_type = lambda x: x not in ["object", "[]", r"{}"]
1733
+ is_a_text_parsing_type = lambda x: x not in [ # pylint: disable=unnecessary-lambda-assignment
1734
+ "object",
1735
+ "[]",
1736
+ r"{}",
1737
+ ]
1631
1738
  if isinstance(data, ET.Element) and is_a_text_parsing_type(data_type) and not data.text:
1632
1739
  return None
1633
1740
  data_val = self.deserialize_type[data_type](data)
@@ -1647,14 +1754,14 @@ class Deserializer(object):
1647
1754
  msg = "Unable to deserialize response data."
1648
1755
  msg += " Data: {}, {}".format(data, data_type)
1649
1756
  raise DeserializationError(msg) from err
1650
- else:
1651
- return self._deserialize(obj_type, data)
1757
+ return self._deserialize(obj_type, data)
1652
1758
 
1653
1759
  def deserialize_iter(self, attr, iter_type):
1654
1760
  """Deserialize an iterable.
1655
1761
 
1656
1762
  :param list attr: Iterable to be deserialized.
1657
1763
  :param str iter_type: The type of object in the iterable.
1764
+ :return: Deserialized iterable.
1658
1765
  :rtype: list
1659
1766
  """
1660
1767
  if attr is None:
@@ -1671,6 +1778,7 @@ class Deserializer(object):
1671
1778
  :param dict/list attr: Dictionary to be deserialized. Also accepts
1672
1779
  a list of key, value pairs.
1673
1780
  :param str dict_type: The object type of the items in the dictionary.
1781
+ :return: Deserialized dictionary.
1674
1782
  :rtype: dict
1675
1783
  """
1676
1784
  if isinstance(attr, list):
@@ -1681,11 +1789,12 @@ class Deserializer(object):
1681
1789
  attr = {el.tag: el.text for el in attr}
1682
1790
  return {k: self.deserialize_data(v, dict_type) for k, v in attr.items()}
1683
1791
 
1684
- def deserialize_object(self, attr, **kwargs):
1792
+ def deserialize_object(self, attr, **kwargs): # pylint: disable=too-many-return-statements
1685
1793
  """Deserialize a generic object.
1686
1794
  This will be handled as a dictionary.
1687
1795
 
1688
1796
  :param dict attr: Dictionary to be deserialized.
1797
+ :return: Deserialized object.
1689
1798
  :rtype: dict
1690
1799
  :raises: TypeError if non-builtin datatype encountered.
1691
1800
  """
@@ -1720,11 +1829,10 @@ class Deserializer(object):
1720
1829
  pass
1721
1830
  return deserialized
1722
1831
 
1723
- else:
1724
- error = "Cannot deserialize generic object with type: "
1725
- raise TypeError(error + str(obj_type))
1832
+ error = "Cannot deserialize generic object with type: "
1833
+ raise TypeError(error + str(obj_type))
1726
1834
 
1727
- def deserialize_basic(self, attr, data_type):
1835
+ def deserialize_basic(self, attr, data_type): # pylint: disable=too-many-return-statements
1728
1836
  """Deserialize basic builtin data type from string.
1729
1837
  Will attempt to convert to str, int, float and bool.
1730
1838
  This function will also accept '1', '0', 'true' and 'false' as
@@ -1732,6 +1840,7 @@ class Deserializer(object):
1732
1840
 
1733
1841
  :param str attr: response string to be deserialized.
1734
1842
  :param str data_type: deserialization data type.
1843
+ :return: Deserialized basic type.
1735
1844
  :rtype: str, int, float or bool
1736
1845
  :raises: TypeError if string format is not valid.
1737
1846
  """
@@ -1743,24 +1852,23 @@ class Deserializer(object):
1743
1852
  if data_type == "str":
1744
1853
  # None or '', node <a/> is empty string.
1745
1854
  return ""
1746
- else:
1747
- # None or '', node <a/> with a strong type is None.
1748
- # Don't try to model "empty bool" or "empty int"
1749
- return None
1855
+ # None or '', node <a/> with a strong type is None.
1856
+ # Don't try to model "empty bool" or "empty int"
1857
+ return None
1750
1858
 
1751
1859
  if data_type == "bool":
1752
1860
  if attr in [True, False, 1, 0]:
1753
1861
  return bool(attr)
1754
- elif isinstance(attr, str):
1862
+ if isinstance(attr, str):
1755
1863
  if attr.lower() in ["true", "1"]:
1756
1864
  return True
1757
- elif attr.lower() in ["false", "0"]:
1865
+ if attr.lower() in ["false", "0"]:
1758
1866
  return False
1759
1867
  raise TypeError("Invalid boolean value: {}".format(attr))
1760
1868
 
1761
1869
  if data_type == "str":
1762
1870
  return self.deserialize_unicode(attr)
1763
- return eval(data_type)(attr) # nosec
1871
+ return eval(data_type)(attr) # nosec # pylint: disable=eval-used
1764
1872
 
1765
1873
  @staticmethod
1766
1874
  def deserialize_unicode(data):
@@ -1768,6 +1876,7 @@ class Deserializer(object):
1768
1876
  as a string.
1769
1877
 
1770
1878
  :param str data: response string to be deserialized.
1879
+ :return: Deserialized string.
1771
1880
  :rtype: str or unicode
1772
1881
  """
1773
1882
  # We might be here because we have an enum modeled as string,
@@ -1781,8 +1890,7 @@ class Deserializer(object):
1781
1890
  return data
1782
1891
  except NameError:
1783
1892
  return str(data)
1784
- else:
1785
- return str(data)
1893
+ return str(data)
1786
1894
 
1787
1895
  @staticmethod
1788
1896
  def deserialize_enum(data, enum_obj):
@@ -1794,6 +1902,7 @@ class Deserializer(object):
1794
1902
  :param str data: Response string to be deserialized. If this value is
1795
1903
  None or invalid it will be returned as-is.
1796
1904
  :param Enum enum_obj: Enum object to deserialize to.
1905
+ :return: Deserialized enum object.
1797
1906
  :rtype: Enum
1798
1907
  """
1799
1908
  if isinstance(data, enum_obj) or data is None:
@@ -1804,9 +1913,9 @@ class Deserializer(object):
1804
1913
  # Workaround. We might consider remove it in the future.
1805
1914
  try:
1806
1915
  return list(enum_obj.__members__.values())[data]
1807
- except IndexError:
1916
+ except IndexError as exc:
1808
1917
  error = "{!r} is not a valid index for enum {!r}"
1809
- raise DeserializationError(error.format(data, enum_obj))
1918
+ raise DeserializationError(error.format(data, enum_obj)) from exc
1810
1919
  try:
1811
1920
  return enum_obj(str(data))
1812
1921
  except ValueError:
@@ -1822,6 +1931,7 @@ class Deserializer(object):
1822
1931
  """Deserialize string into bytearray.
1823
1932
 
1824
1933
  :param str attr: response string to be deserialized.
1934
+ :return: Deserialized bytearray
1825
1935
  :rtype: bytearray
1826
1936
  :raises: TypeError if string format invalid.
1827
1937
  """
@@ -1834,6 +1944,7 @@ class Deserializer(object):
1834
1944
  """Deserialize base64 encoded string into string.
1835
1945
 
1836
1946
  :param str attr: response string to be deserialized.
1947
+ :return: Deserialized base64 string
1837
1948
  :rtype: bytearray
1838
1949
  :raises: TypeError if string format invalid.
1839
1950
  """
@@ -1849,8 +1960,9 @@ class Deserializer(object):
1849
1960
  """Deserialize string into Decimal object.
1850
1961
 
1851
1962
  :param str attr: response string to be deserialized.
1852
- :rtype: Decimal
1963
+ :return: Deserialized decimal
1853
1964
  :raises: DeserializationError if string format invalid.
1965
+ :rtype: decimal
1854
1966
  """
1855
1967
  if isinstance(attr, ET.Element):
1856
1968
  attr = attr.text
@@ -1865,6 +1977,7 @@ class Deserializer(object):
1865
1977
  """Deserialize string into long (Py2) or int (Py3).
1866
1978
 
1867
1979
  :param str attr: response string to be deserialized.
1980
+ :return: Deserialized int
1868
1981
  :rtype: long or int
1869
1982
  :raises: ValueError if string format invalid.
1870
1983
  """
@@ -1877,6 +1990,7 @@ class Deserializer(object):
1877
1990
  """Deserialize ISO-8601 formatted string into TimeDelta object.
1878
1991
 
1879
1992
  :param str attr: response string to be deserialized.
1993
+ :return: Deserialized duration
1880
1994
  :rtype: TimeDelta
1881
1995
  :raises: DeserializationError if string format invalid.
1882
1996
  """
@@ -1887,14 +2001,14 @@ class Deserializer(object):
1887
2001
  except (ValueError, OverflowError, AttributeError) as err:
1888
2002
  msg = "Cannot deserialize duration object."
1889
2003
  raise DeserializationError(msg) from err
1890
- else:
1891
- return duration
2004
+ return duration
1892
2005
 
1893
2006
  @staticmethod
1894
2007
  def deserialize_date(attr):
1895
2008
  """Deserialize ISO-8601 formatted string into Date object.
1896
2009
 
1897
2010
  :param str attr: response string to be deserialized.
2011
+ :return: Deserialized date
1898
2012
  :rtype: Date
1899
2013
  :raises: DeserializationError if string format invalid.
1900
2014
  """
@@ -1910,6 +2024,7 @@ class Deserializer(object):
1910
2024
  """Deserialize ISO-8601 formatted string into time object.
1911
2025
 
1912
2026
  :param str attr: response string to be deserialized.
2027
+ :return: Deserialized time
1913
2028
  :rtype: datetime.time
1914
2029
  :raises: DeserializationError if string format invalid.
1915
2030
  """
@@ -1924,6 +2039,7 @@ class Deserializer(object):
1924
2039
  """Deserialize RFC-1123 formatted string into Datetime object.
1925
2040
 
1926
2041
  :param str attr: response string to be deserialized.
2042
+ :return: Deserialized RFC datetime
1927
2043
  :rtype: Datetime
1928
2044
  :raises: DeserializationError if string format invalid.
1929
2045
  """
@@ -1939,14 +2055,14 @@ class Deserializer(object):
1939
2055
  except ValueError as err:
1940
2056
  msg = "Cannot deserialize to rfc datetime object."
1941
2057
  raise DeserializationError(msg) from err
1942
- else:
1943
- return date_obj
2058
+ return date_obj
1944
2059
 
1945
2060
  @staticmethod
1946
2061
  def deserialize_iso(attr):
1947
2062
  """Deserialize ISO-8601 formatted string into Datetime object.
1948
2063
 
1949
2064
  :param str attr: response string to be deserialized.
2065
+ :return: Deserialized ISO datetime
1950
2066
  :rtype: Datetime
1951
2067
  :raises: DeserializationError if string format invalid.
1952
2068
  """
@@ -1976,8 +2092,7 @@ class Deserializer(object):
1976
2092
  except (ValueError, OverflowError, AttributeError) as err:
1977
2093
  msg = "Cannot deserialize datetime object."
1978
2094
  raise DeserializationError(msg) from err
1979
- else:
1980
- return date_obj
2095
+ return date_obj
1981
2096
 
1982
2097
  @staticmethod
1983
2098
  def deserialize_unix(attr):
@@ -1985,6 +2100,7 @@ class Deserializer(object):
1985
2100
  This is represented as seconds.
1986
2101
 
1987
2102
  :param int attr: Object to be serialized.
2103
+ :return: Deserialized datetime
1988
2104
  :rtype: Datetime
1989
2105
  :raises: DeserializationError if format invalid
1990
2106
  """
@@ -1996,5 +2112,4 @@ class Deserializer(object):
1996
2112
  except ValueError as err:
1997
2113
  msg = "Cannot deserialize to unix datetime object."
1998
2114
  raise DeserializationError(msg) from err
1999
- else:
2000
- return date_obj
2115
+ return date_obj