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