Hello community, here is the log from the commit of package python-msrest for openSUSE:Factory checked in at 2019-10-10 14:32:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-msrest (Old) and /work/SRC/openSUSE:Factory/.python-msrest.new.2352 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-msrest" Thu Oct 10 14:32:07 2019 rev:8 rq:735764 version:0.6.10 Changes: -------- --- /work/SRC/openSUSE:Factory/python-msrest/python-msrest.changes 2019-05-14 13:39:15.124213494 +0200 +++ /work/SRC/openSUSE:Factory/.python-msrest.new.2352/python-msrest.changes 2019-10-10 14:32:08.868373959 +0200 @@ -1,0 +2,12 @@ +Fri Oct 4 12:22:07 UTC 2019 - John Paul Adrian Glaubitz <[email protected]> + +- New upstream release + + Version 0.6.20 + + For detailed information about changes see the + HISTORY.txt file provided with this package +- Drop patches to support older versions of setuptools as + SLE-12 is now shipping with a recent enough version + + m_drop-compatible-releases-operator.patch + + m_drop-extras-require.patch + +------------------------------------------------------------------- Old: ---- m_drop-compatible-releases-operator.patch m_drop-extras-require.patch msrest-0.6.6.tar.gz New: ---- msrest-0.6.10.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-msrest.spec ++++++ --- /var/tmp/diff_new_pack.cQjkw8/_old 2019-10-10 14:32:09.332372877 +0200 +++ /var/tmp/diff_new_pack.cQjkw8/_new 2019-10-10 14:32:09.340372859 +0200 @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-msrest -Version: 0.6.6 +Version: 0.6.10 Release: 0 Summary: AutoRest swagger generator Python client runtime License: MIT @@ -26,8 +26,6 @@ Url: https://pypi.python.org/pypi/msrest Source: https://files.pythonhosted.org/packages/source/m/msrest/msrest-%{version}.tar.gz Source1: LICENSE.md -Patch0: m_drop-compatible-releases-operator.patch -Patch1: m_drop-extras-require.patch BuildRequires: %{python_module setuptools} BuildRequires: fdupes BuildRequires: python-rpm-macros @@ -53,8 +51,6 @@ %prep %setup -q -n msrest-%{version} -%patch0 -p1 -%patch1 -p1 cp %{SOURCE1} LICENSE.md %build ++++++ msrest-0.6.6.tar.gz -> msrest-0.6.10.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/PKG-INFO new/msrest-0.6.10/PKG-INFO --- old/msrest-0.6.6/PKG-INFO 2019-03-22 02:35:53.000000000 +0100 +++ new/msrest-0.6.10/PKG-INFO 2019-09-04 20:04:43.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: msrest -Version: 0.6.6 +Version: 0.6.10 Summary: AutoRest swagger generator Python client runtime. Home-page: https://github.com/Azure/msrest-for-python Author: Microsoft Corporation @@ -27,6 +27,48 @@ Release History --------------- + 2019-09-04 Version 0.6.10 + +++++++++++++++++++++++++ + + **Features** + + - XML mode now supports OpenAPI additional properties # 174 + + **Bugfixes** + + - Accept "is_xml" kwargs to force XML serialization #178 + - Disable XML deserialization if received element is not an ElementTree #178 + - A "null" enum deserialize as None, and not "None" anymore #173 + - Fix some UTF8 encoding issue in Python 2.7 and XML mode #172 + + + 2019-07-24 Version 0.6.9 + ++++++++++++++++++++++++ + + **Features** + + - Accept extensions of JSON mimetype as valid JSON #167 + + 2019-06-24 Version 0.6.8 + ++++++++++++++++++++++++ + + **BugFixes** + + - Impossible to serialize XML if model contains UTF8 characters on Python 2.7 #165 + - Impossible to deserialize a HTTP response as XML if body contains UTF8 characters on Python 2.7 #165 + - Loading a serialized configuration fails with NameError on NoOptionError #162 + + Thanks to cclauss for the contribution + + 2019-06-12 Version 0.6.7 + ++++++++++++++++++++++++ + + **Features** + + - Add DomainCredentials credentials for EventGrid + + Thanks to kalyanaj for the contribution + 2019-03-21 Version 0.6.6 ++++++++++++++++++++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/README.rst new/msrest-0.6.10/README.rst --- old/msrest-0.6.6/README.rst 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/README.rst 2019-09-04 20:03:33.000000000 +0200 @@ -20,6 +20,48 @@ Release History --------------- +2019-09-04 Version 0.6.10 ++++++++++++++++++++++++++ + +**Features** + +- XML mode now supports OpenAPI additional properties # 174 + +**Bugfixes** + +- Accept "is_xml" kwargs to force XML serialization #178 +- Disable XML deserialization if received element is not an ElementTree #178 +- A "null" enum deserialize as None, and not "None" anymore #173 +- Fix some UTF8 encoding issue in Python 2.7 and XML mode #172 + + +2019-07-24 Version 0.6.9 +++++++++++++++++++++++++ + +**Features** + +- Accept extensions of JSON mimetype as valid JSON #167 + +2019-06-24 Version 0.6.8 +++++++++++++++++++++++++ + +**BugFixes** + +- Impossible to serialize XML if model contains UTF8 characters on Python 2.7 #165 +- Impossible to deserialize a HTTP response as XML if body contains UTF8 characters on Python 2.7 #165 +- Loading a serialized configuration fails with NameError on NoOptionError #162 + +Thanks to cclauss for the contribution + +2019-06-12 Version 0.6.7 +++++++++++++++++++++++++ + +**Features** + +- Add DomainCredentials credentials for EventGrid + +Thanks to kalyanaj for the contribution + 2019-03-21 Version 0.6.6 ++++++++++++++++++++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/msrest/authentication.py new/msrest-0.6.10/msrest/authentication.py --- old/msrest-0.6.6/msrest/authentication.py 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/msrest/authentication.py 2019-09-04 20:03:33.000000000 +0200 @@ -250,4 +250,22 @@ self._topic_key_header: topic_key, } ) - \ No newline at end of file + +class DomainCredentials(ApiKeyCredentials): + """Event Grid domain authentication. + + :param str domain_key: The Event Grid domain key + """ + + _domain_key_header = 'aeg-sas-key' + + def __init__(self, domain_key): + # type: (str) -> None + if not domain_key: + raise ValueError("Domain key cannot be None") + super(DomainCredentials, self).__init__( + in_headers={ + self._domain_key_header: domain_key, + } + ) + \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/msrest/exceptions.py new/msrest-0.6.10/msrest/exceptions.py --- old/msrest-0.6.6/msrest/exceptions.py 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/msrest/exceptions.py 2019-09-04 20:03:33.000000000 +0200 @@ -55,7 +55,11 @@ class ClientException(Exception): - """Base exception for all Client Runtime exceptions.""" + """Base exception for all Client Runtime exceptions. + + :param str message: Description of exception. + :param Exception inner_exception: Nested exception (optional). + """ def __init__(self, message, inner_exception=None, *args, **kwargs): # type: (str, Any, str, str) -> None @@ -80,7 +84,12 @@ class ValidationError(ClientException): - """Request parameter validation failed.""" + """Request parameter validation failed. + + :param str rule: Validation rule. + :param str target: Target value for the rule. + :param str value: Value that was invalid. + """ _messages = { "min_length": "must have length greater than {!r}.", @@ -133,6 +142,7 @@ :param requests.Response response: Server response :param str resp_type: Objects type to deserialize response. :param args: Additional args to pass to exception object. + :ivar Model error: Deserialized error model. """ _DEFAULT_MESSAGE = "Unknown error" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/msrest/pipeline/universal.py new/msrest-0.6.10/msrest/pipeline/universal.py --- old/msrest-0.6.6/msrest/pipeline/universal.py 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/msrest/pipeline/universal.py 2019-09-04 20:03:33.000000000 +0200 @@ -32,6 +32,7 @@ import xml.etree.ElementTree as ET import platform import codecs +import re from typing import Mapping, Any, Optional, AnyStr, Union, IO, cast, TYPE_CHECKING # pylint: disable=unused-import @@ -129,10 +130,9 @@ class RawDeserializer(SansIOHTTPPolicy): - JSON_MIMETYPES = [ - 'application/json', - 'text/json' # Because we're open minded people... - ] + # Accept "text" because we're open minded people... + JSON_REGEXP = re.compile(r'^(application|text)/([a-z+.]+\+)?json$') + # Name used in context CONTEXT_NAME = "deserialized_data" @@ -165,13 +165,21 @@ if content_type is None: return data - if content_type in cls.JSON_MIMETYPES: + if cls.JSON_REGEXP.match(content_type): try: return json.loads(data_as_str) except ValueError as err: raise DeserializationError("JSON is invalid: {}".format(err), err) elif "xml" in (content_type or []): try: + + try: + if isinstance(data, unicode): # type: ignore + # If I'm Python 2.7 and unicode XML will scream if I try a "fromstring" on unicode string + data_as_str = data_as_str.encode(encoding="utf-8") # type: ignore + except NameError: + pass + return ET.fromstring(data_as_str) except ET.ParseError: # It might be because the server has an issue, and returned JSON with diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/msrest/polling/poller.py new/msrest-0.6.10/msrest/polling/poller.py --- old/msrest-0.6.6/msrest/polling/poller.py 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/msrest/polling/poller.py 2019-09-04 20:03:33.000000000 +0200 @@ -145,7 +145,7 @@ """Start the long running operation. On completion, runs any callbacks. - :param callable update_cmd: The API reuqest to check the status of + :param callable update_cmd: The API request to check the status of the operation. """ try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/msrest/serialization.py new/msrest-0.6.10/msrest/serialization.py --- old/msrest-0.6.6/msrest/serialization.py 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/msrest/serialization.py 2019-09-04 20:03:33.000000000 +0200 @@ -51,8 +51,10 @@ try: basestring # type: ignore + unicode_str = unicode # type: ignore except NameError: basestring = str # type: ignore + unicode_str = str # type: ignore _LOGGER = logging.getLogger(__name__) @@ -150,8 +152,7 @@ _validation = {} # type: Dict[str, Dict[str, Any]] def __init__(self, **kwargs): - if not self.is_xml_model(): - self.additional_properties = {} + self.additional_properties = {} for k in kwargs: if k not in self._attribute_map: _LOGGER.warning("%s is not a known attribute of class %s and will be ignored", k, self.__class__) @@ -175,8 +176,6 @@ @classmethod def enable_additional_properties_sending(cls): - if cls.is_xml_model(): - raise ValueError("XML model are not compatible with additionalProperties") cls._attribute_map['additional_properties'] = {'key': '', 'type': '{object}'} @classmethod @@ -422,15 +421,6 @@ self.key_transformer = full_restapi_key_transformer self.client_side_validation = True - @staticmethod - def _create_serialized_base(target_obj): - """Create the base for this serialization. - - - For JSON, it's a simple empty dict - - For XML, it's an element (with namespace if needed) - """ - return {} if not target_obj.is_xml_model() else target_obj._create_xml_node() - def _serialize(self, target_obj, data_type=None, **kwargs): """Serialize data into a string according to type. @@ -463,7 +453,9 @@ except KeyError: is_xml_model_serialization = kwargs.setdefault("is_xml", target_obj.is_xml_model()) - serialized = self._create_serialized_base(target_obj) # Could be JSON or XML + serialized = {} + if is_xml_model_serialization: + serialized = target_obj._create_xml_node() try: attributes = target_obj._attribute_map for attr, attr_desc in attributes.items(): @@ -478,7 +470,7 @@ try: ### Extract sub-data to serialize from model ### orig_attr = getattr(target_obj, attr) - if target_obj.is_xml_model(): + if is_xml_model_serialization: pass # Don't provide "transformer" for XML for now. Keep "orig_attr" else: # JSON keys, orig_attr = key_transformer(attr, attr_desc.copy(), orig_attr) @@ -513,7 +505,7 @@ xml_desc.get('prefix', None), xml_desc.get('ns', None) ) - local_node.text = str(new_attr) + local_node.text = unicode_str(new_attr) serialized.append(local_node) else: # JSON for k in reversed(keys): @@ -552,13 +544,20 @@ # Just in case this is a dict internal_data_type = data_type.strip('[]{}') internal_data_type = self.dependencies.get(internal_data_type, None) + try: + is_xml_model_serialization = kwargs["is_xml"] + except KeyError: + if internal_data_type and issubclass(internal_data_type, Model): + is_xml_model_serialization = kwargs.setdefault("is_xml", internal_data_type.is_xml_model()) + else: + is_xml_model_serialization = False if internal_data_type and not isinstance(internal_data_type, Enum): try: deserializer = Deserializer(self.dependencies) # Since it's on serialization, it's almost sure that format is not JSON REST # We're not able to deal with additional properties for now. deserializer.additional_properties_detection = False - if issubclass(internal_data_type, Model) and internal_data_type.is_xml_model(): + if is_xml_model_serialization: deserializer.key_extractors = [ attribute_key_case_insensitive_extractor, ] @@ -726,8 +725,8 @@ Serializes objects to str, int, float or bool. Possible kwargs: - - is_xml bool : If set, adapt basic serializers without the need for basic_types_serializers - basic_types_serializers dict[str, callable] : If set, use the callable as serializer + - is_xml bool : If set, use xml_basic_types_serializers :param data: Object to be serialized. :param str data_type: Type of object in the iterable. @@ -746,13 +745,16 @@ :param data: Object to be serialized. :rtype: str """ - try: + try: # If I received an enum, return its value return data.value except AttributeError: pass + try: if isinstance(data, unicode): - return data.encode(encoding='utf-8') + # Don't change it, JSON and XML ElementTree are totally able + # to serialize correctly u'' strings + return data except NameError: return str(data) else: @@ -1105,6 +1107,9 @@ if 'xml' not in attr_desc: return None + if isinstance(data, dict): + return None + xml_desc = attr_desc['xml'] xml_name = xml_desc['name'] xml_ns = xml_desc.get('ns', None) @@ -1306,10 +1311,13 @@ if "additional_properties" in attribute_map and attribute_map.get("additional_properties", {}).get("key") != '': # Check empty string. If it's not empty, someone has a real "additionalProperties" return None - known_json_keys = {_decode_attribute_map_key(_FLATTEN.split(desc['key'])[0]) - for desc in attribute_map.values() if desc['key'] != ''} - present_json_keys = set(data.keys()) - missing_keys = present_json_keys - known_json_keys + if isinstance(data, ET.Element): + data = {el.tag: el.text for el in data} + + known_keys = {_decode_attribute_map_key(_FLATTEN.split(desc['key'])[0]) + for desc in attribute_map.values() if desc['key'] != ''} + present_keys = set(data.keys()) + missing_keys = present_keys - known_keys return {key: data[key] for key in missing_keys} def _classify_target(self, target, data): @@ -1602,12 +1610,15 @@ def deserialize_enum(data, enum_obj): """Deserialize string into enum object. - :param str data: response string to be deserialized. + If the string is not a valid enum value it will be returned as-is + and a warning will be logged. + + :param str data: Response string to be deserialized. If this value is + None or invalid it will be returned as-is. :param Enum enum_obj: Enum object to deserialize to. :rtype: Enum - :raises: DeserializationError if string is not valid enum value. """ - if isinstance(data, enum_obj): + if isinstance(data, enum_obj) or data is None: return data if isinstance(data, Enum): data = data.value diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/msrest/universal_http/requests.py new/msrest-0.6.10/msrest/universal_http/requests.py --- old/msrest-0.6.6/msrest/universal_http/requests.py 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/msrest/universal_http/requests.py 2019-09-04 20:03:33.000000000 +0200 @@ -33,6 +33,11 @@ from typing import TYPE_CHECKING, List, Callable, Iterator, Any, Union, Dict, Optional # pylint: disable=unused-import import warnings +try: + from configparser import NoOptionError +except ImportError: + from ConfigParser import NoOptionError # type: ignore + from oauthlib import oauth2 import requests from requests.models import CONTENT_CHUNK_SIZE diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/msrest/version.py new/msrest-0.6.10/msrest/version.py --- old/msrest-0.6.6/msrest/version.py 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/msrest/version.py 2019-09-04 20:03:33.000000000 +0200 @@ -25,4 +25,4 @@ # -------------------------------------------------------------------------- #: version of this package. Use msrest.__version__ instead -msrest_version = "0.6.6" +msrest_version = "0.6.10" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/msrest.egg-info/PKG-INFO new/msrest-0.6.10/msrest.egg-info/PKG-INFO --- old/msrest-0.6.6/msrest.egg-info/PKG-INFO 2019-03-22 02:35:53.000000000 +0100 +++ new/msrest-0.6.10/msrest.egg-info/PKG-INFO 2019-09-04 20:04:43.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: msrest -Version: 0.6.6 +Version: 0.6.10 Summary: AutoRest swagger generator Python client runtime. Home-page: https://github.com/Azure/msrest-for-python Author: Microsoft Corporation @@ -27,6 +27,48 @@ Release History --------------- + 2019-09-04 Version 0.6.10 + +++++++++++++++++++++++++ + + **Features** + + - XML mode now supports OpenAPI additional properties # 174 + + **Bugfixes** + + - Accept "is_xml" kwargs to force XML serialization #178 + - Disable XML deserialization if received element is not an ElementTree #178 + - A "null" enum deserialize as None, and not "None" anymore #173 + - Fix some UTF8 encoding issue in Python 2.7 and XML mode #172 + + + 2019-07-24 Version 0.6.9 + ++++++++++++++++++++++++ + + **Features** + + - Accept extensions of JSON mimetype as valid JSON #167 + + 2019-06-24 Version 0.6.8 + ++++++++++++++++++++++++ + + **BugFixes** + + - Impossible to serialize XML if model contains UTF8 characters on Python 2.7 #165 + - Impossible to deserialize a HTTP response as XML if body contains UTF8 characters on Python 2.7 #165 + - Loading a serialized configuration fails with NameError on NoOptionError #162 + + Thanks to cclauss for the contribution + + 2019-06-12 Version 0.6.7 + ++++++++++++++++++++++++ + + **Features** + + - Add DomainCredentials credentials for EventGrid + + Thanks to kalyanaj for the contribution + 2019-03-21 Version 0.6.6 ++++++++++++++++++++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/setup.py new/msrest-0.6.10/setup.py --- old/msrest-0.6.6/setup.py 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/setup.py 2019-09-04 20:03:33.000000000 +0200 @@ -28,7 +28,7 @@ setup( name='msrest', - version='0.6.6', + version='0.6.10', author='Microsoft Corporation', packages=find_packages(exclude=["tests", "tests.*"]), url=("https://github.com/Azure/msrest-for-python"), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/tests/asynctests/test_polling.py new/msrest-0.6.10/tests/asynctests/test_polling.py --- old/msrest-0.6.6/tests/asynctests/test_polling.py 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/tests/asynctests/test_polling.py 2019-09-04 20:03:33.000000000 +0200 @@ -110,7 +110,7 @@ @pytest.fixture def client(): # We need a ServiceClientAsync instance, but the poller itself don't use it, so we don't need - # Something functionnal + # Something functional return ServiceClientAsync(Configuration("http://example.org")) @pytest.mark.asyncio diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/tests/storage_models/list_service_sas_response.py new/msrest-0.6.10/tests/storage_models/list_service_sas_response.py --- old/msrest-0.6.6/tests/storage_models/list_service_sas_response.py 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/tests/storage_models/list_service_sas_response.py 2019-09-04 20:03:33.000000000 +0200 @@ -18,7 +18,7 @@ Variables are only populated by the server, and will be ignored when sending a request. - :ivar service_sas_token: List service SAS credentials of speicific + :ivar service_sas_token: List service SAS credentials of specific resource. :vartype service_sas_token: str """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/tests/storage_models/service_sas_parameters.py new/msrest-0.6.10/tests/storage_models/service_sas_parameters.py --- old/msrest-0.6.6/tests/storage_models/service_sas_parameters.py 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/tests/storage_models/service_sas_parameters.py 2019-09-04 20:03:33.000000000 +0200 @@ -13,7 +13,7 @@ class ServiceSasParameters(Model): - """The parameters to list service SAS credentials of a speicific resource. + """The parameters to list service SAS credentials of a specific resource. :param canonicalized_resource: The canonical path to the signed resource. :type canonicalized_resource: str diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/tests/storage_models/storage_account_check_name_availability_parameters.py new/msrest-0.6.10/tests/storage_models/storage_account_check_name_availability_parameters.py --- old/msrest-0.6.6/tests/storage_models/storage_account_check_name_availability_parameters.py 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/tests/storage_models/storage_account_check_name_availability_parameters.py 2019-09-04 20:03:33.000000000 +0200 @@ -13,7 +13,7 @@ class StorageAccountCheckNameAvailabilityParameters(Model): - """The parameters used to check the availabity of the storage account name. + """The parameters used to check the availability of the storage account name. Variables are only populated by the server, and will be ignored when sending a request. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/tests/test_auth.py new/msrest-0.6.10/tests/test_auth.py --- old/msrest-0.6.6/tests/test_auth.py 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/tests/test_auth.py 2019-09-04 20:03:33.000000000 +0200 @@ -43,7 +43,8 @@ OAuthTokenAuthentication, ApiKeyCredentials, CognitiveServicesCredentials, - TopicCredentials + TopicCredentials, + DomainCredentials ) from requests import Request, PreparedRequest @@ -133,6 +134,12 @@ prep_req = session.prepare_request(self.request) self.assertDictContainsSubset({'aeg-sas-key' : 'mytopickey'}, prep_req.headers) + def test_eventgrid_domain_auth(self): + auth = DomainCredentials("mydomainkey") + session = auth.signed_session() + prep_req = session.prepare_request(self.request) + self.assertDictContainsSubset({'aeg-sas-key' : 'mydomainkey'}, prep_req.headers) + if __name__ == '__main__': unittest.main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/tests/test_polling.py new/msrest-0.6.10/tests/test_polling.py --- old/msrest-0.6.6/tests/test_polling.py 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/tests/test_polling.py 2019-09-04 20:03:33.000000000 +0200 @@ -107,7 +107,7 @@ @pytest.fixture def client(): # We need a ServiceClient instance, but the poller itself don't use it, so we don't need - # Something functionnal + # Something functional return ServiceClient(None, Configuration("http://example.org")) def test_poller(client): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/tests/test_serialization.py new/msrest-0.6.10/tests/test_serialization.py --- old/msrest-0.6.6/tests/test_serialization.py 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/tests/test_serialization.py 2019-09-04 20:03:33.000000000 +0200 @@ -1,4 +1,5 @@ -#-------------------------------------------------------------------------- +# -*- coding: utf-8 -*- +#-------------------------------------------------------------------------- # # Copyright (c) Microsoft Corporation. All rights reserved. # @@ -162,6 +163,32 @@ self.assertEqual(len(cm.output), 1) self.assertIn("not a known attribute", cm.output[0]) + @unittest.skipIf(sys.version_info < (3,4), "assertLogs not supported before 3.4") + def test_empty_enum_logs(self): + class StatusType(str, Enum): + success = "success" + failed = "failed" + + d = Deserializer({"StatusType": StatusType}) + + with self.assertRaises(AssertionError): + with self.assertLogs('msrest.serialization', level='WARNING') as cm: + result = d(StatusType, "failed") + self.assertEqual(len(cm.output), 0) + self.assertEqual(result, StatusType.failed) + + with self.assertRaises(AssertionError): + with self.assertLogs('msrest.serialization', level='WARNING') as cm: + result = d(StatusType, None) + self.assertEqual(len(cm.output), 0) + self.assertEqual(result, None) + + with self.assertLogs('msrest.serialization', level='WARNING') as cm: + result = d(StatusType, "aborted") + self.assertEqual(result, 'aborted') + self.assertEqual(len(cm.output), 1) + self.assertTrue("Deserializer is not able to find aborted as valid enum" in cm.output[0]) + def test_response(self): data = { @@ -1259,10 +1286,11 @@ https://github.com/Azure/msrest-for-python/pull/121 """ - if sys.version_info > (3,): - long_type = int - else: + try: long_type = long + except NameError: + long_type = int + class TestModel(Model): _attribute_map = {'data': {'key': 'data', 'type': 'object'}} @@ -1273,6 +1301,27 @@ 'data': {'id': long_type(1)} } + def test_json_with_xml_map(self): + basic_json = {'age': 37, 'country': 'france'} + + class XmlModel(Model): + _attribute_map = { + 'age': {'key': 'age', 'type': 'int', 'xml':{'name': 'Age'}}, + 'country': {'key': 'country', 'type': 'str', 'xml':{'name': 'country', 'attr': True}}, + } + _xml_map = { + 'name': 'Data' + } + + mymodel = XmlModel( + age=37, + country="france", + ) + + s = Serializer({"XmlModel": XmlModel}) + rawxml = s.body(mymodel, 'XmlModel', is_xml=False) + + assert rawxml==basic_json class TestRuntimeDeserialized(unittest.TestCase): @@ -2196,10 +2245,11 @@ https://github.com/Azure/msrest-for-python/pull/121 """ - if sys.version_info > (3,): - long_type = int - else: + try: long_type = long + except NameError: + long_type = int + class TestModel(Model): _attribute_map = {'data': {'key': 'data', 'type': 'object'}} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/tests/test_universal_pipeline.py new/msrest-0.6.10/tests/test_universal_pipeline.py --- old/msrest-0.6.6/tests/test_universal_pipeline.py 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/tests/test_universal_pipeline.py 2019-09-04 20:03:33.000000000 +0200 @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- #-------------------------------------------------------------------------- # # Copyright (c) Microsoft Corporation. All rights reserved. @@ -120,11 +121,16 @@ return self._body return Response(None, MockResponse(body, content_type)) + # I deserialize XML response = build_response(b"<groot/>", content_type="application/xml") raw_deserializer.on_response(None, response, stream=False) result = response.context["deserialized_data"] assert result.tag == "groot" + # The basic deserializer works with unicode XML + result = raw_deserializer.deserialize_from_text(u'<groot language="français"/>', content_type="application/xml") + assert result.attrib["language"] == u"français" + # Catch some weird situation where content_type is XML, but content is JSON response = build_response(b'{"ugly": true}', content_type="application/xml") raw_deserializer.on_response(None, response, stream=False) @@ -144,6 +150,12 @@ raw_deserializer.on_response(None, response, stream=False) result = response.context["deserialized_data"] assert result["success"] is True + + # Simple JSON with complex content_type + response = build_response(b'{"success": true}', content_type="application/vnd.microsoft.appconfig.kv+json") + raw_deserializer.on_response(None, response, stream=False) + result = response.context["deserialized_data"] + assert result["success"] is True # JSON with UTF-8 BOM response = build_response(b'\xef\xbb\xbf{"success": true}', content_type="application/json; charset=utf-8") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/msrest-0.6.6/tests/test_xml_serialization.py new/msrest-0.6.10/tests/test_xml_serialization.py --- old/msrest-0.6.6/tests/test_xml_serialization.py 2019-03-22 02:34:37.000000000 +0100 +++ new/msrest-0.6.10/tests/test_xml_serialization.py 2019-09-04 20:03:33.000000000 +0200 @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- #-------------------------------------------------------------------------- # # Copyright (c) Microsoft Corporation. All rights reserved. @@ -83,6 +84,24 @@ assert result.empty_string == "" assert result.not_set is None + def test_basic_unicode(self): + """Test a XML with unicode.""" + basic_xml = u"""<?xml version="1.0" encoding="utf-8"?> + <Data language="français"/>""" + + class XmlModel(Model): + _attribute_map = { + 'language': {'key': 'language', 'type': 'str', 'xml':{'name': 'language', 'attr': True}}, + } + _xml_map = { + 'name': 'Data' + } + + s = Deserializer({"XmlModel": XmlModel}) + result = s(XmlModel, basic_xml, "application/xml") + + assert result.language == u"français" + def test_add_prop(self): """Test addProp as a dict. """ @@ -403,6 +422,35 @@ assert [apple.name for apple in result.good_apples] == ["granny", "fuji"] + def test_basic_additional_properties(self): + """Test an ultra basic XML.""" + basic_xml = """<?xml version="1.0"?> + <Metadata> + <number>1</number> + <name>bob</name> + </Metadata>""" + + class XmlModel(Model): + + _attribute_map = { + 'additional_properties': {'key': '', 'type': '{str}', 'xml': {'name': 'additional_properties'}}, + 'encrypted': {'key': 'Encrypted', 'type': 'str', 'xml': {'name': 'Encrypted', 'attr': True}}, + } + _xml_map = { + 'name': 'Metadata' + } + + def __init__(self, **kwargs): + super(XmlModel, self).__init__(**kwargs) + self.additional_properties = kwargs.get('additional_properties', None) + self.encrypted = kwargs.get('encrypted', None) + + s = Deserializer({"XmlModel": XmlModel}) + result = s(XmlModel, basic_xml, "application/xml") + + assert result.additional_properties == {'name': 'bob', 'number': '1'} + assert result.encrypted is None + def test_basic_namespace(self): """Test an ultra basic XML.""" basic_xml = """<?xml version="1.0"?> @@ -452,6 +500,51 @@ assert_xml_equals(rawxml, basic_xml) + def test_basic_unicode(self): + """Test a XML with unicode.""" + basic_xml = ET.fromstring(u"""<?xml version="1.0" encoding="utf-8"?> + <Data language="français"/>""".encode("utf-8")) + + class XmlModel(Model): + _attribute_map = { + 'language': {'key': 'language', 'type': 'str', 'xml':{'name': 'language', 'attr': True}}, + } + _xml_map = { + 'name': 'Data' + } + + mymodel = XmlModel( + language=u"français" + ) + + s = Serializer({"XmlModel": XmlModel}) + rawxml = s.body(mymodel, 'XmlModel') + + assert_xml_equals(rawxml, basic_xml) + + def test_nested_unicode(self): + + class XmlModel(Model): + _attribute_map = { + 'message_text': {'key': 'MessageText', 'type': 'str', 'xml': {'name': 'MessageText'}}, + } + + _xml_map = { + 'name': 'Message' + } + + mymodel_no_unicode = XmlModel(message_text=u'message1') + s = Serializer({"XmlModel": XmlModel}) + body = s.body(mymodel_no_unicode, 'XmlModel') + xml_content = ET.tostring(body, encoding="utf8") + assert xml_content == b"<?xml version='1.0' encoding='utf8'?>\n<Message><MessageText>message1</MessageText></Message>" + + mymodel_with_unicode = XmlModel(message_text=u'message1㚈') + s = Serializer({"XmlModel": XmlModel}) + body = s.body(mymodel_with_unicode, 'XmlModel') + xml_content = ET.tostring(body, encoding="utf8") + assert xml_content == b"<?xml version='1.0' encoding='utf8'?>\n<Message><MessageText>message1\xe3\x9a\x88</MessageText></Message>" + @pytest.mark.skipif(sys.version_info < (3,6), reason="Dict ordering not guaranted before 3.6, makes this complicated to test.") def test_add_prop(self): @@ -835,3 +928,435 @@ assert_xml_equals(rawxml, basic_xml) + def test_basic_is_xml(self): + """Test an ultra basic XML.""" + basic_xml = ET.fromstring("""<?xml version="1.0"?> + <Data country="france"> + <Age>37</Age> + </Data>""") + + class XmlModel(Model): + _attribute_map = { + 'age': {'key': 'age', 'type': 'int', 'xml':{'name': 'Age'}}, + 'country': {'key': 'country', 'type': 'str', 'xml':{'name': 'country', 'attr': True}}, + } + _xml_map = { + 'name': 'Data' + } + + mymodel = XmlModel( + age=37, + country="france", + ) + + s = Serializer({"XmlModel": XmlModel}) + rawxml = s.body(mymodel, 'XmlModel', is_xml=True) + + assert_xml_equals(rawxml, basic_xml) + + def test_basic_unicode_is_xml(self): + """Test a XML with unicode.""" + basic_xml = ET.fromstring(u"""<?xml version="1.0" encoding="utf-8"?> + <Data language="français"/>""".encode("utf-8")) + + class XmlModel(Model): + _attribute_map = { + 'language': {'key': 'language', 'type': 'str', 'xml':{'name': 'language', 'attr': True}}, + } + _xml_map = { + 'name': 'Data' + } + + mymodel = XmlModel( + language=u"français" + ) + + s = Serializer({"XmlModel": XmlModel}) + rawxml = s.body(mymodel, 'XmlModel', is_xml=True) + + assert_xml_equals(rawxml, basic_xml) + + + @pytest.mark.skipif(sys.version_info < (3,6), + reason="Dict ordering not guaranted before 3.6, makes this complicated to test.") + def test_add_prop_is_xml(self): + """Test addProp as a dict. + """ + basic_xml = ET.fromstring("""<?xml version="1.0"?> + <Data> + <Metadata> + <Key1>value1</Key1> + <Key2>value2</Key2> + </Metadata> + </Data>""") + + class XmlModel(Model): + _attribute_map = { + 'metadata': {'key': 'Metadata', 'type': '{str}', 'xml': {'name': 'Metadata'}}, + } + _xml_map = { + 'name': 'Data' + } + + mymodel = XmlModel( + metadata={ + 'Key1': 'value1', + 'Key2': 'value2', + } + ) + + s = Serializer({"XmlModel": XmlModel}) + rawxml = s.body(mymodel, 'XmlModel', is_xml=True) + + assert_xml_equals(rawxml, basic_xml) + + def test_object_is_xml(self): + """Test serialize object as is. + """ + basic_xml = ET.fromstring("""<?xml version="1.0"?> + <Data country="france"> + <Age>37</Age> + </Data>""") + + s = Serializer() + rawxml = s.body(basic_xml, 'object', is_xml=True) + + # It should actually be the same object, should not even try to touch it + assert rawxml is basic_xml + + @pytest.mark.skipif(sys.version_info < (3,6), + reason="Unstable before python3.6 for some reasons") + def test_type_basic_is_xml(self): + """Test some types.""" + basic_xml = ET.fromstring("""<?xml version="1.0"?> + <Data> + <Age>37</Age> + <Enabled>true</Enabled> + </Data>""") + + class XmlModel(Model): + _attribute_map = { + 'age': {'key': 'age', 'type': 'int', 'xml':{'name': 'Age'}}, + 'enabled': {'key': 'enabled', 'type': 'bool', 'xml':{'name': 'Enabled'}}, + } + _xml_map = { + 'name': 'Data' + } + + mymodel = XmlModel( + age=37, + enabled=True + ) + + s = Serializer({"XmlModel": XmlModel}) + rawxml = s.body(mymodel, 'XmlModel', is_xml=True) + + assert_xml_equals(rawxml, basic_xml) + + def test_direct_array_is_xml(self): + """Test an ultra basic XML.""" + basic_xml = ET.fromstring("""<?xml version="1.0"?> + <bananas> + <Data country="france"/> + </bananas> + """) + + class XmlModel(Model): + _attribute_map = { + 'country': {'key': 'country', 'type': 'str', 'xml':{'name': 'country', 'attr': True}}, + } + _xml_map = { + 'name': 'Data' + } + + mymodel = XmlModel( + country="france" + ) + + s = Serializer({"XmlModel": XmlModel}) + rawxml = s.body( + [mymodel], + '[XmlModel]', + serialization_ctxt={'xml': {'name': 'bananas', 'wrapped': True}}, + is_xml=True + ) + + assert_xml_equals(rawxml, basic_xml) + + def test_list_wrapped_basic_types_is_xml(self): + """Test XML list and wrap, items is basic type and there is no itemsName. + """ + + basic_xml = ET.fromstring("""<?xml version="1.0"?> + <AppleBarrel> + <GoodApples> + <GoodApples>granny</GoodApples> + <GoodApples>fuji</GoodApples> + </GoodApples> + </AppleBarrel>""") + + class AppleBarrel(Model): + _attribute_map = { + 'good_apples': {'key': 'GoodApples', 'type': '[str]', 'xml': {'name': 'GoodApples', 'wrapped': True}}, + } + _xml_map = { + 'name': 'AppleBarrel' + } + + mymodel = AppleBarrel( + good_apples=['granny', 'fuji'] + ) + + s = Serializer({"AppleBarrel": AppleBarrel}) + rawxml = s.body(mymodel, 'AppleBarrel', is_xml=True) + + assert_xml_equals(rawxml, basic_xml) + + def test_list_not_wrapped_basic_types_is_xml(self): + """Test XML list and no wrap, items is basic type and there is no itemsName. + """ + + basic_xml = ET.fromstring("""<?xml version="1.0"?> + <AppleBarrel> + <GoodApples>granny</GoodApples> + <GoodApples>fuji</GoodApples> + </AppleBarrel>""") + + class AppleBarrel(Model): + _attribute_map = { + 'good_apples': {'key': 'GoodApples', 'type': '[str]', 'xml': {'name': 'GoodApples'}}, + } + _xml_map = { + 'name': 'AppleBarrel' + } + + mymodel = AppleBarrel( + good_apples=['granny', 'fuji'] + ) + + s = Serializer({"AppleBarrel": AppleBarrel}) + rawxml = s.body(mymodel, 'AppleBarrel', is_xml=True) + + assert_xml_equals(rawxml, basic_xml) + + def test_list_wrapped_items_name_complex_types_is_xml(self): + """Test XML list and wrap, items is ref and there is itemsName. + """ + + basic_xml = ET.fromstring("""<?xml version="1.0"?> + <AppleBarrel> + <GoodApples> + <Apple name="granny"/> + <Apple name="fuji"/> + </GoodApples> + </AppleBarrel>""") + + class AppleBarrel(Model): + _attribute_map = { + # Pomme should be ignored, since it's invalid to define itemsName for a $ref type + 'good_apples': {'key': 'GoodApples', 'type': '[Apple]', 'xml': {'name': 'GoodApples', 'wrapped': True, 'itemsName': 'Pomme'}}, + } + _xml_map = { + 'name': 'AppleBarrel' + } + + class Apple(Model): + _attribute_map = { + 'name': {'key': 'name', 'type': 'str', 'xml':{'name': 'name', 'attr': True}}, + } + _xml_map = { + 'name': 'Apple' + } + + mymodel = AppleBarrel( + good_apples=[ + Apple(name='granny'), + Apple(name='fuji') + ] + ) + + s = Serializer({"AppleBarrel": AppleBarrel, "Apple": Apple}) + rawxml = s.body(mymodel, 'AppleBarrel', is_xml=True) + + assert_xml_equals(rawxml, basic_xml) + + def test_list_not_wrapped_items_name_complex_types_is_xml(self): + """Test XML list and wrap, items is ref and there is itemsName. + """ + + basic_xml = ET.fromstring("""<?xml version="1.0"?> + <AppleBarrel> + <Apple name="granny"/> + <Apple name="fuji"/> + </AppleBarrel>""") + + class AppleBarrel(Model): + _attribute_map = { + # Pomme should be ignored, since it's invalid to define itemsName for a $ref type + 'good_apples': {'key': 'GoodApples', 'type': '[Apple]', 'xml': {'name': 'GoodApples', 'itemsName': 'Pomme'}}, + } + _xml_map = { + 'name': 'AppleBarrel' + } + + class Apple(Model): + _attribute_map = { + 'name': {'key': 'name', 'type': 'str', 'xml':{'name': 'name', 'attr': True}}, + } + _xml_map = { + 'name': 'Apple' + } + + mymodel = AppleBarrel( + good_apples=[ + Apple(name='granny'), + Apple(name='fuji') + ] + ) + + s = Serializer({"AppleBarrel": AppleBarrel, "Apple": Apple}) + rawxml = s.body(mymodel, 'AppleBarrel', is_xml=True) + + assert_xml_equals(rawxml, basic_xml) + + def test_list_wrapped_complex_types_is_xml(self): + """Test XML list and wrap, items is ref and there is no itemsName. + """ + + basic_xml = ET.fromstring("""<?xml version="1.0"?> + <AppleBarrel> + <GoodApples> + <Apple name="granny"/> + <Apple name="fuji"/> + </GoodApples> + </AppleBarrel>""") + + class AppleBarrel(Model): + _attribute_map = { + 'good_apples': {'key': 'GoodApples', 'type': '[Apple]', 'xml': {'name': 'GoodApples', 'wrapped': True}}, + } + _xml_map = { + 'name': 'AppleBarrel' + } + + class Apple(Model): + _attribute_map = { + 'name': {'key': 'name', 'type': 'str', 'xml':{'name': 'name', 'attr': True}}, + } + _xml_map = { + 'name': 'Apple' + } + + mymodel = AppleBarrel( + good_apples=[ + Apple(name='granny'), + Apple(name='fuji') + ] + ) + + s = Serializer({"AppleBarrel": AppleBarrel, "Apple": Apple}) + rawxml = s.body(mymodel, 'AppleBarrel', is_xml=True) + + assert_xml_equals(rawxml, basic_xml) + + def test_list_not_wrapped_complex_types_is_xml(self): + """Test XML list and wrap, items is ref and there is no itemsName. + """ + + basic_xml = ET.fromstring("""<?xml version="1.0"?> + <AppleBarrel> + <Apple name="granny"/> + <Apple name="fuji"/> + </AppleBarrel>""") + + class AppleBarrel(Model): + _attribute_map = { + # Name is ignored if "wrapped" is False + 'good_apples': {'key': 'GoodApples', 'type': '[Apple]', 'xml': {'name': 'GoodApples'}}, + } + _xml_map = { + 'name': 'AppleBarrel' + } + + class Apple(Model): + _attribute_map = { + 'name': {'key': 'name', 'type': 'str', 'xml':{'name': 'name', 'attr': True}}, + } + _xml_map = { + 'name': 'Apple' + } + + mymodel = AppleBarrel( + good_apples=[ + Apple(name='granny'), + Apple(name='fuji') + ] + ) + + s = Serializer({"AppleBarrel": AppleBarrel, "Apple": Apple}) + rawxml = s.body(mymodel, 'AppleBarrel', is_xml=True) + + assert_xml_equals(rawxml, basic_xml) + + @pytest.mark.skipif(sys.version_info < (3,6), + reason="Unstable before python3.6 for some reasons") + def test_two_complex_same_type_is_xml(self): + """Two different attribute are same type + """ + + basic_xml = ET.fromstring("""<?xml version="1.0"?> + <AppleBarrel> + <EuropeanApple name="granny"/> + <USAApple name="fuji"/> + </AppleBarrel>""") + + class AppleBarrel(Model): + _attribute_map = { + 'eu_apple': {'key': 'EuropeanApple', 'type': 'Apple', 'xml': {'name': 'EuropeanApple'}}, + 'us_apple': {'key': 'USAApple', 'type': 'Apple', 'xml': {'name': 'USAApple'}}, + } + _xml_map = { + 'name': 'AppleBarrel' + } + + class Apple(Model): + _attribute_map = { + 'name': {'key': 'name', 'type': 'str', 'xml':{'name': 'name', 'attr': True}}, + } + _xml_map = { + } + + mymodel = AppleBarrel( + eu_apple=Apple(name='granny'), + us_apple=Apple(name='fuji'), + ) + + s = Serializer({"AppleBarrel": AppleBarrel, "Apple": Apple}) + rawxml = s.body(mymodel, 'AppleBarrel', is_xml=True) + + assert_xml_equals(rawxml, basic_xml) + + + def test_basic_namespace_is_xml(self): + """Test an ultra basic XML.""" + basic_xml = ET.fromstring("""<?xml version="1.0"?> + <Data xmlns:fictional="http://characters.example.com"> + <fictional:Age>37</fictional:Age> + </Data>""") + + class XmlModel(Model): + _attribute_map = { + 'age': {'key': 'age', 'type': 'int', 'xml':{'name': 'Age', 'prefix':'fictional','ns':'http://characters.example.com'}}, + } + _xml_map = { + 'name': 'Data' + } + + mymodel = XmlModel( + age=37, + ) + + s = Serializer({"XmlModel": XmlModel}) + rawxml = s.body(mymodel, 'XmlModel', is_xml=True) + + assert_xml_equals(rawxml, basic_xml) \ No newline at end of file
