From 5ebcfc2526932a2d38640f2f49cbea5817c76f7c Mon Sep 17 00:00:00 2001 From: Felix Yan Date: Sat, 17 Jul 2021 03:22:07 +0800 Subject: [PATCH 01/31] Use platformdirs instead of appdirs Use the better maintained `platformdirs` instead of `appdirs`. --- setup.py | 2 +- src/zeep/cache.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 9f5f4d48b..2a19e2c44 100755 --- a/setup.py +++ b/setup.py @@ -3,11 +3,11 @@ from setuptools import setup install_requires = [ - "appdirs>=1.4.0", "attrs>=17.2.0", "cached-property>=1.3.0", "isodate>=0.5.4", "lxml>=4.6.0", + "platformdirs>=1.4.0", "requests>=2.7.0", "requests-toolbelt>=0.7.1", "requests-file>=1.5.1", diff --git a/src/zeep/cache.py b/src/zeep/cache.py index eebb39d12..e484cdc97 100644 --- a/src/zeep/cache.py +++ b/src/zeep/cache.py @@ -7,7 +7,7 @@ import typing from contextlib import contextmanager -import appdirs +import platformdirs import pytz # The sqlite3 is not available on Google App Engine so we handle the @@ -176,7 +176,7 @@ def _is_expired(value, timeout): def _get_default_cache_path(): - path = appdirs.user_cache_dir("zeep", False) + path = platformdirs.user_cache_dir("zeep", False) try: os.makedirs(path) except OSError as exc: From 7807cb01197c80abb547f689b856e4581e447a83 Mon Sep 17 00:00:00 2001 From: Florian Apolloner Date: Tue, 18 May 2021 17:20:43 +0200 Subject: [PATCH 02/31] Fixed import errors. --- src/zeep/loader.py | 12 ++++++------ src/zeep/proxy.py | 4 ++-- tests/test_loader.py | 2 +- tests/test_wsdl.py | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/zeep/loader.py b/src/zeep/loader.py index 69723fd75..9bf979acd 100644 --- a/src/zeep/loader.py +++ b/src/zeep/loader.py @@ -2,11 +2,10 @@ import typing from urllib.parse import urljoin, urlparse, urlunparse -from exceptions import DTDForbidden, EntitiesForbidden from lxml import etree -from lxml.etree import fromstring, XMLParser, XMLSyntaxError, Resolver +from lxml.etree import Resolver, XMLParser, XMLSyntaxError, fromstring -from zeep.exceptions import XMLSyntaxError +from zeep.exceptions import DTDForbidden, EntitiesForbidden, XMLSyntaxError from zeep.settings import Settings @@ -48,11 +47,13 @@ def parse_xml(content: str, transport, base_url=None, settings=None): ) parser.resolvers.add(ImportResolver(transport)) try: - elementtree = fromstring(content, parser=parser,base_url=base_url) + elementtree = fromstring(content, parser=parser, base_url=base_url) docinfo = elementtree.getroottree().docinfo if docinfo.doctype: if settings.forbid_dtd: - raise DTDForbidden(docinfo.doctype, docinfo.system_url, docinfo.public_id) + raise DTDForbidden( + docinfo.doctype, docinfo.system_url, docinfo.public_id + ) if settings.forbid_entities: for dtd in docinfo.internalDTD, docinfo.externalDTD: if dtd is None: @@ -60,7 +61,6 @@ def parse_xml(content: str, transport, base_url=None, settings=None): for entity in dtd.iterentities(): raise EntitiesForbidden(entity.name, entity.content) - return elementtree except etree.XMLSyntaxError as exc: raise XMLSyntaxError( diff --git a/src/zeep/proxy.py b/src/zeep/proxy.py index 0b5e7ea7f..bbcd6377a 100644 --- a/src/zeep/proxy.py +++ b/src/zeep/proxy.py @@ -99,11 +99,11 @@ def __getitem__(self, key): raise AttributeError("Service has no operation %r" % key) def __iter__(self): - """ Return iterator over the services and their callables. """ + """Return iterator over the services and their callables.""" return iter(self._operations.items()) def __dir__(self): - """ Return the names of the operations. """ + """Return the names of the operations.""" return list(itertools.chain(dir(super()), self._operations)) diff --git a/tests/test_loader.py b/tests/test_loader.py index 4ab54559d..c50d8d0e0 100644 --- a/tests/test_loader.py +++ b/tests/test_loader.py @@ -1,8 +1,8 @@ import pytest -from exceptions import DTDForbidden, EntitiesForbidden from pytest import raises as assert_raises from tests.utils import DummyTransport +from zeep.exceptions import DTDForbidden, EntitiesForbidden from zeep.loader import parse_xml from zeep.settings import Settings diff --git a/tests/test_wsdl.py b/tests/test_wsdl.py index 27cbe0fa0..6edfd14da 100644 --- a/tests/test_wsdl.py +++ b/tests/test_wsdl.py @@ -3,12 +3,12 @@ import pytest import requests_mock -from exceptions import DTDForbidden, EntitiesForbidden from lxml import etree from pretend import stub from tests.utils import DummyTransport, assert_nodes_equal from zeep import Client, Settings, wsdl +from zeep.exceptions import DTDForbidden, EntitiesForbidden from zeep.transports import Transport From 0704fb57e9ca6a571a7ccec067d23fa9d037ae5d Mon Sep 17 00:00:00 2001 From: Vasco Henriques Date: Mon, 23 Nov 2020 14:46:00 +0000 Subject: [PATCH 03/31] Added support for namespaces in SOAP 11 Fault node --- src/zeep/wsdl/bindings/soap.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/zeep/wsdl/bindings/soap.py b/src/zeep/wsdl/bindings/soap.py index 44cd44034..139d2020b 100644 --- a/src/zeep/wsdl/bindings/soap.py +++ b/src/zeep/wsdl/bindings/soap.py @@ -322,15 +322,15 @@ def process_error(self, doc, operation): ) def get_text(name): - child = fault_node.find(name) + child = fault_node.find(name, namespaces=fault_node.nsmap) if child is not None: - return child.text + return child.text raise Fault( message=get_text("faultstring"), code=get_text("faultcode"), actor=get_text("faultactor"), - detail=fault_node.find("detail"), + detail=fault_node.find("detail", namespaces=fault_node.nsmap), ) def _set_http_headers(self, serialized, operation): From 2ac0f5b12760796e98f9b6b5e94110c63e21985d Mon Sep 17 00:00:00 2001 From: Vasco Henriques Date: Mon, 23 Nov 2020 14:49:17 +0000 Subject: [PATCH 04/31] Removed whitespace typo in soap.py --- src/zeep/wsdl/bindings/soap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zeep/wsdl/bindings/soap.py b/src/zeep/wsdl/bindings/soap.py index 139d2020b..81b70b091 100644 --- a/src/zeep/wsdl/bindings/soap.py +++ b/src/zeep/wsdl/bindings/soap.py @@ -324,7 +324,7 @@ def process_error(self, doc, operation): def get_text(name): child = fault_node.find(name, namespaces=fault_node.nsmap) if child is not None: - return child.text + return child.text raise Fault( message=get_text("faultstring"), From ae6ad1520b1249f3aee5bb26d310291eed44296c Mon Sep 17 00:00:00 2001 From: Vasco Henriques Date: Thu, 26 Nov 2020 10:29:19 +0000 Subject: [PATCH 05/31] Added SOAP 11 Binding tests for Faults namespaces --- tests/test_wsdl_soap.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/test_wsdl_soap.py b/tests/test_wsdl_soap.py index 7a2810899..1a4040306 100644 --- a/tests/test_wsdl_soap.py +++ b/tests/test_wsdl_soap.py @@ -62,6 +62,37 @@ def test_soap11_process_error(): assert exc.subcodes is None assert "detail-message" in etree.tostring(exc.detail).decode("utf-8") + responseWithNamespaceInFault = load_xml( + """ + + + + fault-code-withNamespace + fault-string-withNamespace + + + detail-message-withNamespace + detail-code-withNamespace + + + + + + """ + ) + + try: + binding.process_error(responseWithNamespaceInFault, None) + assert False + except Fault as exc: + assert exc.message == "fault-string-withNamespace" + assert exc.code == "fault-code-withNamespace" + assert exc.actor is None + assert exc.subcodes is None + assert "detail-message-withNamespace" in etree.tostring(exc.detail).decode("utf-8") + def test_soap12_process_error(): response = """ From ec8d2965bc5c5a8e91ea92c1c17aa36db7903899 Mon Sep 17 00:00:00 2001 From: henrik molnes Date: Tue, 3 Nov 2020 11:28:48 +0100 Subject: [PATCH 06/31] Update plugins.rst Added information about headers not present in soap enevelop in egress plugin --- docs/plugins.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/plugins.rst b/docs/plugins.rst index 5dbf434a0..d6e37c7ca 100644 --- a/docs/plugins.rst +++ b/docs/plugins.rst @@ -27,7 +27,10 @@ Writing a plugin is really simple and best explained via an example. The plugin can implement two methods: ``ingress`` and ``egress``. Both methods -should always return an envelop (lxml element) and the http headers. +should always return an envelop (lxml element) and the http headers. The +envelope in the ``egress`` plugin will only contain the body of the soap message. +This is important to remember if you want to inspect or do something +with the headers. To register this plugin you need to pass it to the client. Plugins are always executed sequentially. From bd81e0b0418cf56a409379d9b8fe5b204fad97e5 Mon Sep 17 00:00:00 2001 From: Louis Sautier Date: Sun, 15 Aug 2021 03:08:21 +0200 Subject: [PATCH 07/31] Get rid of six --- src/zeep/wsse/username.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/zeep/wsse/username.py b/src/zeep/wsse/username.py index bb9b4cd04..da448b445 100644 --- a/src/zeep/wsse/username.py +++ b/src/zeep/wsse/username.py @@ -2,8 +2,6 @@ import hashlib import os -import six - from zeep import ns from zeep.wsse import utils @@ -108,7 +106,7 @@ def _create_password_digest(self): nonce = os.urandom(16) timestamp = utils.get_timestamp(self.created, self.zulu_timestamp) - if isinstance(self.password, six.string_types): + if isinstance(self.password, str): password = self.password.encode("utf-8") else: password = self.password From 53be04855f546e3b5a30125d2538d158bbc34431 Mon Sep 17 00:00:00 2001 From: Michael van Tellingen Date: Sun, 15 Aug 2021 18:52:39 +0200 Subject: [PATCH 08/31] Fix formatting --- tests/test_wsdl_soap.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_wsdl_soap.py b/tests/test_wsdl_soap.py index 1a4040306..b8a40b28c 100644 --- a/tests/test_wsdl_soap.py +++ b/tests/test_wsdl_soap.py @@ -91,7 +91,9 @@ def test_soap11_process_error(): assert exc.code == "fault-code-withNamespace" assert exc.actor is None assert exc.subcodes is None - assert "detail-message-withNamespace" in etree.tostring(exc.detail).decode("utf-8") + assert "detail-message-withNamespace" in etree.tostring(exc.detail).decode( + "utf-8" + ) def test_soap12_process_error(): From 436c1aa886c5fe63ee7bf7130a58986438131087 Mon Sep 17 00:00:00 2001 From: Michael van Tellingen Date: Sun, 15 Aug 2021 18:57:35 +0200 Subject: [PATCH 09/31] Update changelog --- CHANGES | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGES b/CHANGES index a73f9a635..37c963fb1 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +4.1.0 (2021-08-15) +------------------ + - Remove last dependency on `six` (#1250) + - Use `platformdirs` instead of the `appsdirs` dependency (#1244) + - Fix settings context manager when an exception is raised (#1193) + - Don't render decimals using scientific notation (#1191) + - Remove dependency on `defusedxml` (deprecated) (#1179) + 4.0.0 (2020-10-12) ------------------ - Drop support for Python 2.7, 3.3, 3.4 and 3.5 From 6655f0fca935ac16591f10b0ea614e8426e08461 Mon Sep 17 00:00:00 2001 From: Michael van Tellingen Date: Sun, 15 Aug 2021 18:57:54 +0200 Subject: [PATCH 10/31] Update CHANGES --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 37c963fb1..f0819203b 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,7 @@ - Don't render decimals using scientific notation (#1191) - Remove dependency on `defusedxml` (deprecated) (#1179) + 4.0.0 (2020-10-12) ------------------ - Drop support for Python 2.7, 3.3, 3.4 and 3.5 From 28bb5efc2549959eb730ca969fa593e54753a1bf Mon Sep 17 00:00:00 2001 From: Michael van Tellingen Date: Sun, 15 Aug 2021 19:00:09 +0200 Subject: [PATCH 11/31] Add Python 3.9 to tests --- .github/workflows/python-test.yml | 2 +- tox.ini | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 61b9abab4..2e82c6cd1 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -23,7 +23,7 @@ jobs: max-parallel: 4 matrix: platform: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["3.6", "3.7", "3.8"] + python-version: ["3.6", "3.7", "3.8", "3.9"] steps: - name: Install system dependencies diff --git a/tox.ini b/tox.ini index 20c4889b4..3a36b4a7e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,11 +1,12 @@ [tox] -envlist = py{36,37,38}-{mac,linux,windows},pypy +envlist = py{36,37,38,39}-{mac,linux,windows},pypy [gh-actions] python = 3.6: py36 3.7: py37 3.8: py38 + 3.9: py39 [testenv] @@ -16,11 +17,11 @@ platform = extras = test {mac,linux}: xmlsec - py{36,37,38}: async + py{36,37,38,39}: async deps = - py{36,37,38}: aioresponses==0.5.0 - py{36,37,38}: aiohttp==3.4.4 - py{36,37,38}: pytest-asyncio==0.11.0 + py{36,37,38,39}: aioresponses==0.5.0 + py{36,37,38,39}: aiohttp==3.4.4 + py{36,37,38,39}: pytest-asyncio==0.11.0 commands = coverage run --parallel -m pytest {posargs} From a483c3d06768188d127a1ccadb486b7a4647cee3 Mon Sep 17 00:00:00 2001 From: Louis Sautier Date: Sun, 15 Aug 2021 03:47:22 +0200 Subject: [PATCH 12/31] Include pyproject.toml in sdist to avoid pytest warnings Running tests from the current tarballs results in "PytestUnknownMarkWarning: Unknown pytest.mark.requests". The marker is defined in pyproject.toml which is missing. --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index 2f6e6ce75..d96cc94ce 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,6 +7,7 @@ include CHANGES include CONTRIBUTORS.rst include LICENSE include README.rst +include pyproject.toml include setup.cfg include setup.py From 015588deb5d617aff4405cc74595dac38398ccdd Mon Sep 17 00:00:00 2001 From: Dmitry Vasilyev Date: Thu, 1 Apr 2021 04:45:25 +0400 Subject: [PATCH 13/31] Update soap.py Fix 400 Bad Request response to RenewRequest because Action and other addressing data is missing in the header. https://github.com/mvantellingen/python-zeep/issues/1205 --- src/zeep/wsdl/bindings/soap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zeep/wsdl/bindings/soap.py b/src/zeep/wsdl/bindings/soap.py index 81b70b091..c2fd764f0 100644 --- a/src/zeep/wsdl/bindings/soap.py +++ b/src/zeep/wsdl/bindings/soap.py @@ -81,7 +81,7 @@ def _create(self, operation, args, kwargs, client=None, options=None): if not options: options = client.service._binding_options - if operation_obj.abstract.wsa_action: + if operation_obj.abstract.wsa_action or operation_obj.soapaction: envelope, http_headers = wsa.WsAddressingPlugin().egress( envelope, http_headers, operation_obj, options ) From aedbb066a765fe03b6948c9f1478f237bbab862a Mon Sep 17 00:00:00 2001 From: Michael van Tellingen Date: Sun, 15 Aug 2021 19:06:31 +0200 Subject: [PATCH 14/31] Revert "Update soap.py" This reverts commit 015588deb5d617aff4405cc74595dac38398ccdd. --- src/zeep/wsdl/bindings/soap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zeep/wsdl/bindings/soap.py b/src/zeep/wsdl/bindings/soap.py index c2fd764f0..81b70b091 100644 --- a/src/zeep/wsdl/bindings/soap.py +++ b/src/zeep/wsdl/bindings/soap.py @@ -81,7 +81,7 @@ def _create(self, operation, args, kwargs, client=None, options=None): if not options: options = client.service._binding_options - if operation_obj.abstract.wsa_action or operation_obj.soapaction: + if operation_obj.abstract.wsa_action: envelope, http_headers = wsa.WsAddressingPlugin().egress( envelope, http_headers, operation_obj, options ) From 221d9236c038d3a6fad3d06b157c1f2b627eac24 Mon Sep 17 00:00:00 2001 From: backbord Date: Tue, 17 Nov 2020 11:26:10 +0100 Subject: [PATCH 15/31] Improve handling of str values for Duration Passing a str to `Duration.xmlvalue(value)` will result in a properly formatted iso duration. --- src/zeep/xsd/types/builtins.py | 4 +++- tests/test_xsd_builtins.py | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/zeep/xsd/types/builtins.py b/src/zeep/xsd/types/builtins.py index e3e05c657..d57068eea 100644 --- a/src/zeep/xsd/types/builtins.py +++ b/src/zeep/xsd/types/builtins.py @@ -124,10 +124,12 @@ def pythonvalue(self, value): class Duration(BuiltinType): _default_qname = xsd_ns("duration") - accepted_types = [isodate.duration.Duration, str] + accepted_types = [isodate.duration.Duration, datetime.timedelta, str] @check_no_collection def xmlvalue(self, value): + if isinstance(value, str): + value = isodate.parse_duration(value) return isodate.duration_isoformat(value) @treat_whitespace("collapse") diff --git a/tests/test_xsd_builtins.py b/tests/test_xsd_builtins.py index a34ef8b1d..9d76dea50 100644 --- a/tests/test_xsd_builtins.py +++ b/tests/test_xsd_builtins.py @@ -139,6 +139,10 @@ def test_xmlvalue(self): instance = builtins.Duration() value = isodate.parse_duration("P0Y1347M0D") assert instance.xmlvalue(value) == "P1347M" + assert instance.xmlvalue("P0Y1347M0D") == "P1347M" + assert instance.xmlvalue(datetime.timedelta(days=1347)) == "P1347D" + with pytest.raises(ValueError): + instance.xmlvalue("P15T") def test_pythonvalue(self): instance = builtins.Duration() From b44d732f9ecaa97261c2a636b44497f944a17d09 Mon Sep 17 00:00:00 2001 From: colm29 Date: Mon, 22 Mar 2021 21:22:52 +0000 Subject: [PATCH 16/31] Pass digest method when signing timestamp node --- src/zeep/wsse/signature.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zeep/wsse/signature.py b/src/zeep/wsse/signature.py index 143ca0f5f..c4aec758e 100644 --- a/src/zeep/wsse/signature.py +++ b/src/zeep/wsse/signature.py @@ -244,7 +244,7 @@ def _signature_prepare(envelope, key, signature_method, digest_method): _sign_node(ctx, signature, envelope.find(QName(soap_env, "Body")), digest_method) timestamp = security.find(QName(ns.WSU, "Timestamp")) if timestamp != None: - _sign_node(ctx, signature, timestamp) + _sign_node(ctx, signature, timestamp, digest_method) ctx.sign(signature) # Place the X509 data inside a WSSE SecurityTokenReference within From 15d0f522c51657359c2c144d77bc8fa6b3278ac7 Mon Sep 17 00:00:00 2001 From: colm29 Date: Thu, 25 Mar 2021 22:43:14 +0000 Subject: [PATCH 17/31] Expand sign timestamp test for different signature digest methods --- tests/test_wsse_signature.py | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/tests/test_wsse_signature.py b/tests/test_wsse_signature.py index 2f3e730eb..921f9e6ba 100644 --- a/tests/test_wsse_signature.py +++ b/tests/test_wsse_signature.py @@ -35,7 +35,16 @@ @skip_if_no_xmlsec -def test_sign_timestamp_if_present(): +@pytest.mark.parametrize("digest_method,expected_digest_href", DIGEST_METHODS_TESTDATA) +@pytest.mark.parametrize( + "signature_method,expected_signature_href", SIGNATURE_METHODS_TESTDATA +) +def test_sign_timestamp_if_present( + digest_method, + signature_method, + expected_digest_href, + expected_signature_href, +): envelope = load_xml( """ Date: Sun, 15 Aug 2021 19:13:19 +0200 Subject: [PATCH 18/31] Update changelog --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index f0819203b..37d54d591 100644 --- a/CHANGES +++ b/CHANGES @@ -2,9 +2,11 @@ ------------------ - Remove last dependency on `six` (#1250) - Use `platformdirs` instead of the `appsdirs` dependency (#1244) + - Pass digest method when signing timestamp node(#1201) - Fix settings context manager when an exception is raised (#1193) - Don't render decimals using scientific notation (#1191) - Remove dependency on `defusedxml` (deprecated) (#1179) + - Improve handling of str values for Duration (#1165) 4.0.0 (2020-10-12) From f87f42f16ac5587010b833f5bcb511c85c837e30 Mon Sep 17 00:00:00 2001 From: Michael van Tellingen Date: Sun, 15 Aug 2021 19:14:22 +0200 Subject: [PATCH 19/31] format... --- tests/test_wsse_signature.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_wsse_signature.py b/tests/test_wsse_signature.py index 921f9e6ba..ae3c353f7 100644 --- a/tests/test_wsse_signature.py +++ b/tests/test_wsse_signature.py @@ -40,10 +40,10 @@ "signature_method,expected_signature_href", SIGNATURE_METHODS_TESTDATA ) def test_sign_timestamp_if_present( - digest_method, - signature_method, - expected_digest_href, - expected_signature_href, + digest_method, + signature_method, + expected_digest_href, + expected_signature_href, ): envelope = load_xml( """ From 1e55eeb6b0b992e90234296b1a1392253528dfef Mon Sep 17 00:00:00 2001 From: Michael van Tellingen Date: Sun, 15 Aug 2021 20:25:43 +0200 Subject: [PATCH 20/31] =?UTF-8?q?Bump=20version:=204.0.0=20=E2=86=92=204.1?= =?UTF-8?q?.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- docs/conf.py | 2 +- docs/index.rst | 2 +- setup.py | 2 +- src/zeep/__init__.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 7ce9369a3..c107a2010 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 4.0.0 +current_version = 4.1.0 commit = true tag = true tag_name = {new_version} diff --git a/docs/conf.py b/docs/conf.py index 6d785ed70..f006c1af0 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -62,7 +62,7 @@ # built documents. # # The short X.Y version. -version = '4.0.0' +version = '4.1.0' release = version # The language for content autogenerated by Sphinx. Refer to documentation diff --git a/docs/index.rst b/docs/index.rst index 260ae88f9..b32949c9a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -106,7 +106,7 @@ See ``python -mzeep --help`` for more information about this command. .. note:: Zeep follows `semver`_ for versioning, however bugs can always occur. So as always pin the version of zeep you tested with - (e.g. ``zeep==4.0.0``'). + (e.g. ``zeep==4.1.0``'). .. _semver: http://semver.org/ diff --git a/setup.py b/setup.py index 2a19e2c44..cb51ac46d 100755 --- a/setup.py +++ b/setup.py @@ -50,7 +50,7 @@ setup( name="zeep", - version="4.0.0", + version="4.1.0", description="A modern/fast Python SOAP client based on lxml / requests", long_description=long_description, author="Michael van Tellingen", diff --git a/src/zeep/__init__.py b/src/zeep/__init__.py index a179b9872..eee2f6fb6 100644 --- a/src/zeep/__init__.py +++ b/src/zeep/__init__.py @@ -4,4 +4,4 @@ from zeep.transports import Transport # noqa from zeep.xsd.valueobjects import AnyObject # noqa -__version__ = "4.0.0" +__version__ = "4.1.0" From 42fbc41244730ea6f702154e8e1b46e8ebbfaa64 Mon Sep 17 00:00:00 2001 From: Michael van Tellingen Date: Sun, 15 Aug 2021 20:53:41 +0200 Subject: [PATCH 21/31] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 16e1c6a6d..f3af7b4f1 100644 --- a/README.rst +++ b/README.rst @@ -5,7 +5,7 @@ Zeep: Python SOAP client A fast and modern Python SOAP client Highlights: - * Compatible with Python 3.6, 3.7, 3.8 and PyPy + * Compatible with Python 3.6, 3.7, 3.8, 3.9 and PyPy * Build on top of lxml and requests * Support for Soap 1.1, Soap 1.2 and HTTP bindings * Support for WS-Addressing headers From 4e16b7726b5027e83d0dbe911bd45f153b7a09dc Mon Sep 17 00:00:00 2001 From: Michael van Tellingen Date: Sun, 15 Aug 2021 20:54:15 +0200 Subject: [PATCH 22/31] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 0dd79b773..db6c7c6a7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2016-2017 Michael van Tellingen +Copyright (c) 2016-2021 Michael van Tellingen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 25701f0b69ee46914179070b7e8906ea3e521480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Thu, 11 Nov 2021 08:55:41 +0100 Subject: [PATCH 23/31] Use stdlib functools.cached_property if available Python 3.8+ provides a functools.cached_property in the stdlib that is thread-safe, i.e. equivalent to threaded_cached_property. Use it instead of adding third-party dependencies whenever available. --- setup.py | 2 +- src/zeep/wsdl/attachments.py | 6 +++++- src/zeep/xsd/elements/indicators.py | 6 +++++- src/zeep/xsd/types/any.py | 6 +++++- src/zeep/xsd/types/complex.py | 6 +++++- 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index cb51ac46d..8ef81b6ac 100755 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ install_requires = [ "attrs>=17.2.0", - "cached-property>=1.3.0", + "cached-property>=1.3.0; python_version<'3.8'", "isodate>=0.5.4", "lxml>=4.6.0", "platformdirs>=1.4.0", diff --git a/src/zeep/wsdl/attachments.py b/src/zeep/wsdl/attachments.py index 037e43906..075bee591 100644 --- a/src/zeep/wsdl/attachments.py +++ b/src/zeep/wsdl/attachments.py @@ -6,7 +6,11 @@ import base64 -from cached_property import cached_property +try: + from functools import cached_property +except ImportError: + from cached_property import cached_property + from requests.structures import CaseInsensitiveDict diff --git a/src/zeep/xsd/elements/indicators.py b/src/zeep/xsd/elements/indicators.py index 40325dad2..e9ef2c4d3 100644 --- a/src/zeep/xsd/elements/indicators.py +++ b/src/zeep/xsd/elements/indicators.py @@ -16,7 +16,11 @@ import typing from collections import OrderedDict, defaultdict, deque -from cached_property import threaded_cached_property +try: + from functools import cached_property as threaded_cached_property +except ImportError: + from cached_property import threaded_cached_property + from lxml import etree from zeep.exceptions import UnexpectedElementError, ValidationError diff --git a/src/zeep/xsd/types/any.py b/src/zeep/xsd/types/any.py index b4525e44c..17f244e1d 100644 --- a/src/zeep/xsd/types/any.py +++ b/src/zeep/xsd/types/any.py @@ -1,7 +1,11 @@ import logging import typing -from cached_property import threaded_cached_property +try: + from functools import cached_property as threaded_cached_property +except ImportError: + from cached_property import threaded_cached_property + from lxml import etree from zeep.utils import qname_attr diff --git a/src/zeep/xsd/types/complex.py b/src/zeep/xsd/types/complex.py index 8141bc168..b2ed9bf0c 100644 --- a/src/zeep/xsd/types/complex.py +++ b/src/zeep/xsd/types/complex.py @@ -4,7 +4,11 @@ from collections import OrderedDict, deque from itertools import chain -from cached_property import threaded_cached_property +try: + from functools import cached_property as threaded_cached_property +except ImportError: + from cached_property import threaded_cached_property + from lxml import etree from zeep.exceptions import UnexpectedElementError, XMLParseError From c7d916cbac8817ba4be81751ee590c6fe52b3f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sat, 9 Oct 2021 12:54:34 +0200 Subject: [PATCH 24/31] Close internal session when transport is deleted --- src/zeep/transports.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/zeep/transports.py b/src/zeep/transports.py index 70185d82f..f9b46f77b 100644 --- a/src/zeep/transports.py +++ b/src/zeep/transports.py @@ -37,6 +37,7 @@ def __init__(self, cache=None, timeout=300, operation_timeout=None, session=None self.operation_timeout = operation_timeout self.logger = logging.getLogger(__name__) + self.__close_session = not session self.session = session or requests.Session() self.session.mount("file://", FileAdapter()) self.session.headers["User-Agent"] = "Zeep/%s (www.python-zeep.org)" % ( @@ -154,6 +155,10 @@ def settings(self, timeout=None): yield self.operation_timeout = old_timeout + def __del__(self): + if self.__close_session: + self.session.close() + class AsyncTransport(Transport): """Asynchronous Transport class using httpx. From f98da13f7c6e247cf6e333ffbc8bf1be9cbb44d6 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 19 Sep 2021 23:49:58 +0300 Subject: [PATCH 25/31] Add support for Python 3.10 --- .github/workflows/python-test.yml | 11 +++++++---- README.rst | 2 +- setup.py | 4 +++- tox.ini | 11 ++++++----- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 2e82c6cd1..399c4ff1b 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -9,7 +9,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Set up Python 3.7 - uses: actions/setup-python@v1 + uses: actions/setup-python@v2 with: python-version: 3.7 - name: Install dependencies @@ -23,7 +23,10 @@ jobs: max-parallel: 4 matrix: platform: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["3.6", "3.7", "3.8", "3.9"] + python-version: ["3.6", "3.7", "3.8", "3.9", "3.10-dev"] + # TODO: Remove Windows exclusion when binary wheel available for lxml + exclude: + - { platform: windows-latest, python-version: "3.10-dev" } steps: - name: Install system dependencies @@ -37,7 +40,7 @@ jobs: brew install libxmlsec1 libxslt pkgconfig - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 + uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - name: Install dependencies @@ -65,7 +68,7 @@ jobs: name: coverage-data path: . - name: Set up Python 3.7 - uses: actions/setup-python@v1 + uses: actions/setup-python@v2 with: python-version: 3.7 - name: Install dependencies diff --git a/README.rst b/README.rst index f3af7b4f1..6a05eca49 100644 --- a/README.rst +++ b/README.rst @@ -5,7 +5,7 @@ Zeep: Python SOAP client A fast and modern Python SOAP client Highlights: - * Compatible with Python 3.6, 3.7, 3.8, 3.9 and PyPy + * Compatible with Python 3.6, 3.7, 3.8, 3.9, 3.10 and PyPy3 * Build on top of lxml and requests * Support for Soap 1.1, Soap 1.2 and HTTP bindings * Support for WS-Addressing headers diff --git a/setup.py b/setup.py index 8ef81b6ac..04ed3dea9 100755 --- a/setup.py +++ b/setup.py @@ -55,7 +55,7 @@ long_description=long_description, author="Michael van Tellingen", author_email="michaelvantellingen@gmail.com", - url="http://docs.python-zeep.org", + url="https://docs.python-zeep.org", python_requires=">=3.6", install_requires=install_requires, tests_require=tests_require, @@ -74,10 +74,12 @@ "Development Status :: 5 - Production/Stable", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", ], diff --git a/tox.ini b/tox.ini index 3a36b4a7e..221f1e653 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{36,37,38,39}-{mac,linux,windows},pypy +envlist = py{36,37,38,39,310}-{mac,linux,windows},pypy [gh-actions] python = @@ -7,6 +7,7 @@ python = 3.7: py37 3.8: py38 3.9: py39 + 3.10: py310 [testenv] @@ -17,11 +18,11 @@ platform = extras = test {mac,linux}: xmlsec - py{36,37,38,39}: async + py{36,37,38,39,310}: async deps = - py{36,37,38,39}: aioresponses==0.5.0 - py{36,37,38,39}: aiohttp==3.4.4 - py{36,37,38,39}: pytest-asyncio==0.11.0 + py{36,37,38,39,310}: aioresponses==0.5.0 + py{36,37,38,39,310}: aiohttp==3.4.4 + py{36,37,38,39,310}: pytest-asyncio==0.11.0 commands = coverage run --parallel -m pytest {posargs} From 1db30cbb318b34afc7744f85523953d3a4fe7665 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 19 Sep 2021 23:54:08 +0300 Subject: [PATCH 26/31] fail-fast: false --- .github/workflows/python-test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 399c4ff1b..902c15e77 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -20,6 +20,7 @@ jobs: test: runs-on: ${{ matrix.platform }} strategy: + fail-fast: false max-parallel: 4 matrix: platform: [ubuntu-latest, macos-latest, windows-latest] From 8a788765a0e301abeceef254ec9f8f26a811cacd Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 20 Sep 2021 00:00:31 +0300 Subject: [PATCH 27/31] Bump pytest pin to support Python 3.10 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 04ed3dea9..dfa79a586 100755 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ "pytest-cov==2.8.1", "pytest-httpx", "pytest-asyncio", - "pytest==6.0.1", + "pytest==6.2.5", "requests_mock>=0.7.0", # Linting "isort==5.3.2", From 84f968ce0e22ec1ee4e7cd2e127c182df73ce9e8 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 20 Sep 2021 00:18:15 +0300 Subject: [PATCH 28/31] Bump aiohttp pin to support Python 3.10 --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 221f1e653..f6d1331ec 100644 --- a/tox.ini +++ b/tox.ini @@ -21,7 +21,7 @@ extras = py{36,37,38,39,310}: async deps = py{36,37,38,39,310}: aioresponses==0.5.0 - py{36,37,38,39,310}: aiohttp==3.4.4 + py{36,37,38,39,310}: aiohttp==3.7.4 py{36,37,38,39,310}: pytest-asyncio==0.11.0 commands = coverage run --parallel -m pytest {posargs} From 1ddd118956870f9c68a24c9494207dc17441b416 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 20 Sep 2021 00:28:03 +0300 Subject: [PATCH 29/31] Remove redundant backport and code --- setup.py | 1 - tests/conftest.py | 4 ---- tests/test_main.py | 3 ++- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/setup.py b/setup.py index dfa79a586..4cf9073b9 100755 --- a/setup.py +++ b/setup.py @@ -27,7 +27,6 @@ tests_require = [ "coverage[toml]==5.2.1", "freezegun==0.3.15", - "mock==2.0.0", "pretend==1.0.9", "pytest-cov==2.8.1", "pytest-httpx", diff --git a/tests/conftest.py b/tests/conftest.py index 64c9bf951..4bd41de06 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,10 +2,6 @@ import pytest -# Don't try to test asyncio since it is py3 only syntax -if sys.version_info < (3, 5): - collect_ignore = ["test_asyncio_transport.py"] - pytest.register_assert_rewrite("tests.utils") diff --git a/tests/test_main.py b/tests/test_main.py index bffc7230f..f45048202 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -1,4 +1,5 @@ -from mock import patch +from unittest.mock import patch + from pretend import stub from zeep import __main__, client From f1920301b17e4fd42d5fb13603cd889f19255c29 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 5 Oct 2021 16:04:58 +0300 Subject: [PATCH 30/31] Test on Python 3.10 final --- .github/workflows/python-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 902c15e77..6ee31cbc3 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -24,10 +24,10 @@ jobs: max-parallel: 4 matrix: platform: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["3.6", "3.7", "3.8", "3.9", "3.10-dev"] + python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"] # TODO: Remove Windows exclusion when binary wheel available for lxml exclude: - - { platform: windows-latest, python-version: "3.10-dev" } + - { platform: windows-latest, python-version: "3.10" } steps: - name: Install system dependencies From 2f35b7d29355ba646f5e3c6e9925033d5d6df8bb Mon Sep 17 00:00:00 2001 From: Dmitry Ryzhikov Date: Fri, 17 Dec 2021 22:33:19 +0100 Subject: [PATCH 31/31] Minor AsyncTransport cleanup Remove unused session argument. Remove import of unused and not installed libs: aioresponses, aiohttp. --- src/zeep/transports.py | 1 - tests/test_async_transport.py | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/zeep/transports.py b/src/zeep/transports.py index f9b46f77b..0841e2f16 100644 --- a/src/zeep/transports.py +++ b/src/zeep/transports.py @@ -175,7 +175,6 @@ def __init__( cache=None, timeout=300, operation_timeout=None, - session=None, verify_ssl=True, proxy=None, ): diff --git a/tests/test_async_transport.py b/tests/test_async_transport.py index 940b48a3c..f5e8d1b0a 100644 --- a/tests/test_async_transport.py +++ b/tests/test_async_transport.py @@ -1,6 +1,4 @@ -import aiohttp import pytest -from aioresponses import aioresponses from lxml import etree from pretend import stub from pytest_httpx import HTTPXMock