From d596b53df637fe38d60db9a0b4e8972f5ae6e69d Mon Sep 17 00:00:00 2001 From: kamyar Date: Thu, 14 May 2015 20:30:12 +0430 Subject: [PATCH] Done. Now it is async! --- HACKING.rst | 785 ------------- LICENSE.txt | 165 --- MANIFEST.in | 41 - README.rst | 1 - TODO.txt | 2271 ------------------------------------ ez_setup.py | 332 ------ ez_setup_1_4_2.py | 388 ------ setup.cfg | 137 --- suds/__init__.py | 7 - suds/argparser.py | 2 +- suds/client.py | 16 +- suds/mx/__init__.py | 2 +- suds/mx/encoded.py | 2 +- suds/reader.py | 2 +- suds/resolver.py | 3 +- suds/sax/attribute.py | 4 +- suds/sax/date.py | 28 +- suds/sax/document.py | 4 +- suds/sax/element.py | 16 +- suds/sax/enc.py | 6 +- suds/sax/parser.py | 3 +- suds/sax/text.py | 2 +- suds/servicedefinition.py | 4 +- suds/serviceproxy.py | 6 +- suds/sudsobject.py | 6 +- suds/transport/__init__.py | 10 +- suds/transport/http.py | 4 +- suds/transport/https.py | 2 - suds/umx/core.py | 2 +- suds/wsdl.py | 46 +- suds/wsse.py | 7 +- suds/xsd/__init__.py | 4 +- suds/xsd/schema.py | 8 +- suds/xsd/sxbase.py | 15 +- suds/xsd/sxbuiltin.py | 18 +- test.py | 12 +- 36 files changed, 108 insertions(+), 4253 deletions(-) delete mode 100644 HACKING.rst delete mode 100644 LICENSE.txt delete mode 100644 MANIFEST.in delete mode 100644 README.rst delete mode 100644 TODO.txt delete mode 100644 ez_setup.py delete mode 100644 ez_setup_1_4_2.py delete mode 100644 setup.cfg diff --git a/HACKING.rst b/HACKING.rst deleted file mode 100644 index 217825bf..00000000 --- a/HACKING.rst +++ /dev/null @@ -1,785 +0,0 @@ -GENERAL DEVELOPMENT NOTES -================================================= - -Project's sources are accessible from a `Mercurial version control repository -`_ hosted at BitBucket. - -Project development should be tracked in the ``TODO.txt`` file. - -* Exact formatting is not important as long as its content is kept formatted - consistently. -* Done tasks should be marked as such and not deleted. - -Separate sections below: - -* `TOP-LEVEL PROJECT FILES & FOLDERS`_ -* `PYTHON COMPATIBILITY`_ -* `RELEASE PROCEDURE`_ -* `DEVELOPMENT & TESTING ENVIRONMENT`_ -* `PYTHON 2/3 SOURCE CODE COMPATIBILITY`_ -* `EXTERNAL DOCUMENTATION`_ -* `STANDARDS CONFORMANCE`_ -* `PROJECT IMPLEMENTATION NOTES`_ -* `REPRODUCING PROBLEMATIC USE CASES`_ - -For additional design, research & development project notes see the project's -``notes/`` folder. - - -TOP-LEVEL PROJECT FILES & FOLDERS -================================================= - -| .hg/ -| .hgignore -| .hgtags - -* Mercurial version control related data. - -| build/ -| dist/ -| suds_jurko.egg-info/ - -* Folders created during project setup procedure (build/install). - -| notes/ - -* Internal project design, research & development notes. - -| suds/ - -* Basic project source code. - -| tests/ - -* Project test code. - -| tools/ - -* Project development & setup utility scripts. Related internal Python modules - are located under its ``suds_devel/`` package folder. - -| MANIFEST.in - -* Build system configuration file listing the files to be included in the - project's source distribution packages in addition to those automatically - added to those packages by the used package preparation system. - -| HACKING.rst -| LICENSE.txt -| README.txt -| TODO.txt - -* Internal project documentation. - -| setup.cfg - -* Basic project Python configuration. - -| setup.py - -* Standard Python project setup script. - -* Usage examples: - - ``setup.py --help`` - show detailed usage information - ``setup.py --help-commands`` - show detailed ``setup.py`` command list - ``setup.py build`` - build the project - ``setup.py install`` - build & install the project - ``setup.py register`` - register a project release at PyPI - ``setup.py sdist`` - prepare a source distribution - ``setup.py upload`` - upload prepared packages to PyPI - -* Usage examples requiring ``setuptools``: - - ``setup.py develop`` - prepare the development environment (add the project folder to the Python - module search path) the same as if installed using ``easy_install -e`` or - ``pip install -e`` - ``setup.py test`` - run the project test suite (requires ``pytest``) - - -PYTHON COMPATIBILITY -================================================= - -Base sources should remain Python 2.x compatible. Since the original project -states aiming for Python 2.4 compatibility we do so as well. - -The Python 3.0 minor release is not supported. See `Python 3.0 support`_ -subsection below for more detailed information. - -Test & setup code needs to be implemented using Python 2 & 3 compatible source -code. Setup & setup related scripts need to be implemented so they do not rely -on other pre-installed libraries. - -These backward compatibility requirements do not affect internal development -operations such as ``setup.py`` support for uploading a new project distribution -package to PyPI. Such operations need to be supported on the latest Python 2 & 3 -releases only and no additional backward compatibility is either tested or -guaranteed for them. - -The following is a list of backward incompatible Python features not used in -this project to maintain backward compatibility: - -Features missing prior to Python 2.5 ------------------------------------- - -* ``any`` & ``all`` functions. -* ``with`` statement. -* BaseException class introduced and KeyboardInterrupt & SystemExit exception - classes stopped being Exception subclasses. - - * This means that code wanting to support Python versions prior to this - release needs to re-raise KeyboardInterrupt & SystemExit exceptions before - handling the generic 'Exception' case, unless it really wants to gobble up - those special infrastructural exceptions as well. - -* ``try``/``except``/``finally`` blocks. - - * Prior to this Python release, code like the following:: - - try: - A - except XXX: - B - finally: - C - - was considered illegal and needed to be written using nested ``try`` blocks - as in:: - - try: - try: - A - except XXX: - B - finally: - C - -* ``yield`` expression inside a ``try`` block with a ``finally`` clause. - - * Prior to this Python release, code like the following:: - - try: - yield x - finally: - do_something() - - is considered illegal, but can be replaced with legal code similar to the - following:: - - try: - yield x - except: - do_something() - raise - do_something() - -Features missing prior to Python 2.6 ------------------------------------- - -* ``bytes`` type. -* Byte literals, e.g. ``b"quack"``. -* Class decorators. -* ``fractions`` module. -* ``numbers`` module. -* String ``format()`` method. -* Using the ``with`` statement from Python 2.5.x requires the ``from __future__ - import with_statement``. - - -Features missing prior to Python 2.7 ------------------------------------- - -* Dictionary & set comprehensions. -* Set literals. - -Features missing in Python 3.0 & 3.1 ------------------------------------- - -* py2to3 conversion for source files with an explicitly specified UTF-8 BOM. - - -Python 3.0 support ------------------- - -Python 3.0 release has been marked as deprecated almost immediately after the -release 3.1. It is not expected that this Python release is actively used -anywhere in the wild. That said, if anyone really wants this version supported -- patches are welcome. - -At least the following problems have been found with Python 3.0: - -* None of the tools required to properly test our project (setuptools, pip, - virtualenv, tox, etc.) will work on it. -* When you attempt to setuptools project with Python 3.0, it attempts to use the - ``sys.stdout.detach()`` method introduced only in Python 3.1. This specific - issue could be worked around by using ``sys.stdout.buffer`` directly but the - actual fix has not been attempted. If anyone wants to take this route though - and work on supporting setuptools on Python 3.0 - be warned that it will most - likely have other issues after this one as well. -* When applying py2to3 to the project sources, Python will use the current - user's locale encoding instead of the one specified in the project sources, - thus causing the operation to fail on some source files containing different - unicode characters unless the user's environement uses some sort of unicode - encoding by default, e.g. will fail on some test scripts when run on Windows - with eastern European regional settings (uses the CP1250 encoding). - - -RELEASE PROCEDURE -================================================= - -1. Document the release correctly in ``README.rst``. - -2. Test the project build with the latest available ``setuptools`` project and - update the ``ez_setup.py`` ``setuptools`` installation script as needed. - - * Use the latest available & tested ``setuptools`` release. - * If a new ``setuptools`` release drops support for an older Python release, - update our ``setup.py`` script to use an older ``setuptools`` installation - script when run using the no longer supported Python release. - - * For example, ``setuptools`` version 2.0 dropped support for Python 2.4 & - 2.5 and so ``setup.py`` uses a separate ``ez_setup_1_4_2.py`` - ``setuptools`` installation script with Python versions older than 2.6. - -3. Version identification. - - * Official releases marked with no extra suffix after the basic version - number. - * Alfa releases marked with the suffix ``.a#``. - * Beta releases marked with the suffix ``.b#``. - * Release candidate releases marked with the suffix ``.rc#``. - * Development releases marked with the suffix ``.dev#``. - * Version ordering (as recognized by pip & setuptools):: - - 0.5.dev0 < 0.5.dev1 < 0.5.dev5 - < 0.5.a0.dev0 < 0.5.a0.dev5 < 0.5.a0 - < 0.5.a3.dev0 < 0.5.a3.dev5 < 0.5.a3 - < 0.5.b0.dev0 < 0.5.b0.dev5 < 0.5.b0 - < 0.5.b3.dev0 < 0.5.b3.dev5 < 0.5.b3 - < 0.5.rc0.dev0 < 0.5.rc0.dev5 < 0.5.rc0 - < 0.5.rc3.dev0 < 0.5.rc3.dev5 < 0.5.rc3 - < 0.5 - < 0.5.1.dev0 < ... - ... - < 0.5.1 - < 0.6.dev0 < ... - ... - < 0.6 - < 1.0.dev0 < ... - ... - < 1.0 - -4. Tag in Hg. - - * Name the tag like ``release-``, e.g. ``release-0.5``. - -5. Prepare official releases based only on tagged commits. - - * Official releases should always be prepared based on tagged revisions with - no local changes in the used sandbox. - * Prepare source distribution packages (both .zip & .tar.bz2 formats) and - upload the prepared source packages to PyPI. - - * Run ``setup.py sdist upload``. - - * Prepare wheel packages for Python 2 & 3 using the latest Python 2 & 3 - environments with the ``wheel`` package installed and upload them to PyPI. - - * Run ``setup.py bdist_wheel upload`` using both Python 2 & 3. - - * Upload the prepared source & wheel packages to the project site. - - * Use the BitBucket project web interface. - -6. Next development version identification. - - * If this was a development release. - - * Bump up the existing ``.dev#`` suffix, e.g. change ``0.8.dev2`` to - ``0.8.dev3``. - - * If this was a non-development release. - - * Bump up the forked project version counter (may add/remove/bump - alfa/beta/release-candidate mark suffixes as needed). - * Add the ``.dev0`` suffix, e.g. as in ``0.8.dev0``. - -7. Notify whomever the new release might concern. - - -DEVELOPMENT & TESTING ENVIRONMENT -================================================= - -In all command-line examples below pyX, pyXY & pyXYZ represent a Python -interpreter executable for a specific Python version X, X.Y & X.Y.Z -respectively. - -Setting up the development & testing environment ------------------------------------------------- - -``tools/setup_base_environments.py`` script should be used for setting up the -basic Python environments so they support testing our project. The script can be -configured from the main project Python configuration file ``setup.cfg``. It -implements all the backward compatibility tweaks and performs additional -required package installation that would otherwise need to be done manually in -order to be able to test our project in those environments. - -These exact requirements and their related version specific tweaks are not -documented elsewhere so anyone interested in the details should consult the -script's sources. - -The testing environment is generally set up as follows: - -1. Install clean target Python environments. -#. Update the project's ``setup.py`` configuration with information on your - installed Python environments. -#. Run the ``tools/setup_base_environments.py`` script. - -Some older Python environments may have slight issues caused by varying support -levels in different used Python packages, but the basic testing functionality -has been tested to make sure it works on as wide array of supported platforms as -possible. - -Examples of such issues: - -* Colors not getting displayed on a Windows console terminal, with possibly ANSI - color code escape sequences getting displayed instead. -* ``pip`` utility can not be run from the command-line using the ``py -m pip`` - syntax for some older versions. In such cases use the more portable ``py -c - "import pip;pip.main()"`` syntax instead. -* Some specific older Python versions (e.g. 2.4.3) have no SSL support and so - have to reuse installations downloaded by other Python versions. - -Running the project tests - ``tools/run_all_tests.py`` script -------------------------------------------------------------- - -``tools/run_all_tests.py`` script is a basic *poor man's tox* development script -that can be used for running the full project test suite using multiple Python -interpreter versions on a development machine. - -Intended to be replaced by a more portable ``tox`` based or similar automated -testing solution some time in the future. - -Can be configured by tweaking the main project Python configuration file -``setup.cfg``: - -* List of target Python environments. -* Each target Python environment's invocation command. - -Requires the target Python environment already be set up, and all the packages -required for running the project test suite installed. See the `Setting up the -development & testing environment`_ section for more detailed information. - -Automatically installs the project in editable mode in all tested Python -environments. - -Caveats: - -* This method does not allow you to provide any extra ``pytest`` options when - running the project test suite. - -Running the project tests - ``setup.py test`` command ------------------------------------------------------ - -Project tests can also be run for a specific Python environment by running the -project's ``setup.py`` script in that environment and invoking its ``test`` -command. E.g. run a command like one of the following ones from the top level -project folder:: - - py243 setup.py test - py27 setup.py test - py3 setup.py test - -Note that the ``setup.py`` script always needs to be called from the top level -project folder. - -For most Python versions, the target Python environment needs not be set up -prior to running this command. Where possible (e.g. not for Python 2.4.x or -3.1.x versions), any missing testing requirements will be installed -automatically, but not directly into the target environment but in the current -folder instead. This functionality should be considered a band-aid though, and -setting up the target environment can be better done as described in the -`Setting up the development & testing environment`_ section. - -The ``setup.py test`` command will build the project if needed and run its test -suite in the target Python environment. The project does not need to be -preinstalled into the target Python environment for this operation to work, and -neither will the operation leave it installed. - -Unless a more restricted test set is selected using ``pytest`` specific -command-line options, ``setup.py test`` command runs the complete project test -suite. - -Specific ``pytest`` command-line options may be provided by passing them all as -a single whitespace separated string tunnelled via the ``setup.py test`` -command's ``--pytest-args``/``-a`` command-line option. - -For example, the following command will run only tests containing ``binding`` in -their name, will stop on first failure and will automatically drop into Python's -post-mortem debugger on failure:: - - setup.py test -a "-k binding -x --pdb" - -Caveats: - -* This method does not currently allow passing ``pytest`` specific command-line - options containing embedded whitespace. -* When running the ``setup.py test`` command in a Windows Python 2.5 environment - without an included ctypes module (e.g. 64-bit CPython 2.5 distribution does - not include ctypes) and having it automatically install the colorama package - version older than 0.1.11, you will get benign error messages reporting - colorama's atexit handlers failing. Running the same command again avoids the - issue since the colorama package will then already be installed. Suggested - workaround is to use a colorama package version 0.3.2 or newer. - -Running the project tests - using ``pytest`` directly ------------------------------------------------------ - -To have greater control over the test suite and be able to specify additional -``pytest`` options on the command-line, or be able to run the tests on a -different project installation (e.g. official release installed directly from -PyPI), do the following: - -1. Install the project into the target Python environment. - - * Installing the project can be done by either installing it directly into the - target Python environment using one of the following commands (paths used - assume the commands are being run from the top level project folder):: - - setup.py install - easy_install . - pip install . - - Or the project can be installed in editable mode using one of the following - commands (so it does not need to be reinstalled after every source code - change):: - - setup.py develop - easy_install -e . - pip install -e . - - * The installation step can be skipped if running Python 2 based project - tests, and doing so from the top level project folder. - -2. Run tests using ``pytest``. - - * If using Python 2.x: - - * Run ``pytest`` from the project's top level or ``tests`` folder:: - - py2 -m pytest - - * If using Python 3.x: - - * Since the project uses py2to3 source conversion, you need to build the - project in order to generate the project's Python 3 sources before they - can be tested. If the project has been installed in editable mode, then - simply run the following from the top level project folder:: - - setup.py build - - and if it has not then rebuild and reinstall it using one of the following - commands:: - - setup.py develop - setup.py install - - Note that you might need to manually remove the build folder in order to - have its contents regenerated when wanting to run the test suite using a - different Python 3.x interpreter version, as those sources are regenerated - based solely on the original & processed source file timestamp information - and not the Python version used to process them. - - * Run ``pytest`` from the the project's ``tests`` folder:: - - py3 -m pytest - -Each specific test module can also be run directly as a script. - -Notes on the folder from which to run the tests: - -* When running tests from a folder other than the top level project folder, the - tested project version needs to first be installed in the used Python - environment. -* Python 2 tests can be run from the top level project folder, in which case - they will work even if the project has not been explicitly installed in the - used Python environment. And even if another project version has been - installed into the used Python environment, that one will be ignored and the - one in the current folder used instead. -* Python 3 tests can not be run from the top level project folder or they would - attempt and fail to use Python 2 based project sources found in the current - folder. - -See the ``pytest`` documentation for a detailed list of available command-line -options. Some interesting ones: - - -l show local variable state in tracebacks - --tb=short shorter traceback information for each failure - -x stop on first failure - --pdb enter Python debugger on failure - -Setting up multiple parallel Python interpreter versions on Windows -------------------------------------------------------------------- - -On Windows you might have a problem setting up multiple parallel Python -interpreter versions in case their major and minor version numbers match, e.g. -Python 2.4.3 & 2.4.4. In those cases, standard Windows installer will -automatically remove the previous installation instead of simply adding a new -one. In order to achieve such parallel setup we suggest the following steps: - -1. Install the first version in a dummy folder, and do so for the current user - only. -#. Copy the dummy target folder to the desired folder for the first - installation, e.g. Python243. -#. Uninstall the original version. -#. Set up a shortcut or a batch script (e.g. py243.cmd) for running this - interpreter without having to have it added to the system path. -#. Repeat the steps for the second installation. - -Installing Python for the current user only is necessary in order to make Python -install all of its files into the target folder and not move some of them into -shared system folders. - -Note that this will leave you without start menu or registry entries for these -Python installations. Registry entries should be needed only if you want to run -some external Python package installation tool requiring those entries in order -to determine where to install its package data. In that case you can set those -entries manually, e.g. by using a script similar to the one found at -``_. - - -PYTHON 2/3 SOURCE CODE COMPATIBILITY -================================================= - -These are notes related to maintaining Python 2/3 source code compatibility in -parts of this project that require it. - -Use the ``six `` Python 2/3 compatibility support -package to make the compatibility patches simpler. Where a solution provided by -``six`` can not be used, explicitly explain the reason why in a related code -comment. - -Do not use ``u"..."`` Python unicode literals since we wish to support Python -3.1 & 3.2 versions which do not support them. Useful site for easily converting -unicode strings to their ``unicode-escape`` encoded representation which can -then be used with the ``six.u()`` helper function: - - http://www.rapidmonkey.com/unicodeconverter - - -EXTERNAL DOCUMENTATION -================================================= - -* SOAP - - * http://www.w3.org/TR/soap - - * Version 1.1. - - * http://www.w3.org/TR/2000/NOTE-SOAP-20000508 - - * Version 1.2. - - * Part0: Primer - - * http://www.w3.org/TR/2007/REC-soap12-part0-20070427 - * Errata: http://www.w3.org/2007/04/REC-soap12-part0-20070427-errata.html - - * Part1: Messaging Framework - - * http://www.w3.org/TR/2007/REC-soap12-part1-20070427 - * Errata: http://www.w3.org/2007/04/REC-soap12-part1-20070427-errata.html - - * Part2: Adjuncts - - * http://www.w3.org/TR/2007/REC-soap12-part2-20070427 - * Errata: http://www.w3.org/2007/04/REC-soap12-part2-20070427-errata.html - - * Specification Assertions and Test Collection - - * http://www.w3.org/TR/2007/REC-soap12-testcollection-20070427 - * Errata: - http://www.w3.org/2007/04/REC-soap12-testcollection-20070427-errata.html - -* WS-I Basic Profile 1.1 - - * http://www.ws-i.org/Profiles/BasicProfile-1.1.html - -* WSDL 1.1 - - * http://www.w3.org/TR/wsdl - -* XML Schema - - * Part 0: Primer Second Edition - http://www.w3.org/TR/xmlschema-0 - - * Non-normative document intended to provide an easily readable description - of the XML Schema facilities, and is oriented towards quickly - understanding how to create schemas using the XML Schema language. - - * Part 1: Structures - http://www.w3.org/TR/xmlschema-1 - * Part 2: Datatypes - http://www.w3.org/TR/xmlschema-2 - - -STANDARDS CONFORMANCE -================================================= - -There seems to be no complete standards conformance overview for the suds -project. This section contains just some related notes, taken down while hacking -on this project. As more related information is uncovered, it should be added -here as well, and eventually this whole section should be moved to the project's -user documentation. - -Interpreting message parts defined by a WSDL schema ---------------------------------------------------- - -* Each message part is interpreted as a single parameter. - - * What we refer to here as a 'parameter' may not necessarily correspond 1-1 to - a Python function argument passed when using the suds library's Python - function interface for invoking web service operations. In some cases suds - may attempt to make the Python function interfaces more intuitive to the - user by automatically unwrapping a parameter as defined inside a WSDL schema - into multiple Python function arguments. - -* In order to achieve interoperability with existing software 'in the wild', - suds does not fully conform to the WSDL 1.1 specification with regard as to - how message parts are mapped to input data contained in SOAP XML web service - operation invocation request documents. - - * WSDL 1.1 standard states: - - * 2.3.1 Message Parts. - - * A message may have message parts referencing either an element or a type - defined in the WSDL's XSD schema. - * If a message has a message part referencing a type defined in the WSDL's - XSD schema, then that must be its only message part. - - * 3.5 soap:body. - - * If using document/literal binding and a message has a message part - referencing a type defined in the WSDL's XSD schema then that part - becomes the schema type of the enclosing SOAP envelope Body element. - - * Suds supports multiple message parts, each of which may be related either to - an element or a type. - * Suds uses message parts related to types, as if they were related to an - element, using the message part name as the representing XML element name in - the constructed related SOAP XML web service operation invocation request - document. - * WS-I Basic Profile 1.1 standard explicitly avoids the issue by stating the - following: - - * R2204 - A document/literal binding in a DESCRIPTION MUST refer, in each of - its soapbind:body element(s), only to wsdl:part element(s) that have been - defined using the element attribute. - - * Rationale. - - * No other software has been encountered implementing the exact - functionality specified in the WSDL 1.1 standard. - * Already done in the original suds implementation. - * Example software whose implementation matches our own. - - * SoapUI. - - * Tested with version 4.6.1. - - * WSDL analyzer & invoker at ``_. - -WSDL XSD schema interpretation ------------------------------- - -* ``minOccurs``/``maxOccurs`` attributes on ``all``, ``choice`` & ``sequence`` - schema elements are ignored. - - * Rationale. - - * Already done in the original suds implementation. - - * Extra notes. - - * SoapUI (tested with version 4.6.1). - - * For ``all``, ``choice`` & ``sequence`` schema elements with their - ``minOccurs`` attribute set to "0", does not explicitly mark elements - found in such containers as optional. - -* Supports sending multiple same-named web service operation parameters, but - only if they are specified next to each other in the constructed web service - operation invocation request document. - - * Done by passing a list or tuple of such values to the suds constructed - Python function representing the web service operation in question. - * Rationale. - - * Already done in the original suds implementation. - - * Extra notes. - - * Such same-named values break other web service related tools as well, e.g. - WSDL analyzer & invoker at ``_. - - -PROJECT IMPLEMENTATION NOTES -================================================= - -Sometimes we have a reason for implementing a feature in a certain way that may -not be obvious at first and which thus deserves an implementation comment -explaining the rationale behind it. In cases when such rationale would then be -duplicated at different places in code, and project implementation note should -be added and identified here, and its respective implementation locations marked -using a comment such as:: - - # See 'Project implementation note #42'. - -Project implementation note #1 -------------------------------- -``pytest`` test parametrizations must be defined so they get ordered the same in -different test processes. - -Doing otherwise may confuse the ``pytest`` ``xdist`` plugin used for running -parallel tests using multiple test processes (last tested using -``pytest 2.5.2``, ``xdist 1.10`` & ``execnet 1.2.0``) and may cause it to exit -with errors such as:: - - AssertionError: Different tests were collected between gw1 and gw0 - -Specifically, this means that ``pytest`` test parametrizations should not be -constructed using iteration over unordered collections such as sets or -dictionaries, at least not with Python's hash randomization feature enabled -(implemented as optional since Python 2.6.8, enabled by default since Python -3.3). - -See the following ``pytest`` issues for more detailed information: - -* `#301 `_ - serializing collection - process (per host) on xdist to avoid conflicts/collection errors -* `#437 `_ - different tests - collected on two nodes with xdist - - -REPRODUCING PROBLEMATIC USE CASES -================================================= - -Failing web service processing examples can be easily packaged as reproducible -test cases using the suds library 'message & reply injection' technique. - -Some things you can achieve using this technique (for examples, see existing -project unit tests): - -* Create a client object based on a fixed WSDL string. -* Have a client object send a fixed request string without having it construct - one based on the loaded WSDL schema and received arguments. -* Have a client object process a fixed reply string without having it send a - request to an actual external web service. diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index 32fa870e..00000000 --- a/LICENSE.txt +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 55d2b6df..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,41 +0,0 @@ -# Additional files to be included in the source distribution package (created -# by running 'setup.py sdist'). Theoretically we could avoid having to manually -# maintain this list by using a setuptools plugin that would automatically -# include all files under Mercurial version control, but the setuptools_hg we -# tried out did not work correctly with Python 3. - -# Top level project files. -include ez_setup.py -include ez_setup_1_4_2.py -include HACKING.rst -include LICENSE.txt -include TODO.txt - -# Notes. -include notes/*.rst -include notes/*.txt - -# Tests. -recursive-include tests *.py - -# Project development & setup tools. -include tools/*.cmd -include tools/*.py -include tools/*.txt -recursive-include tools/suds_devel *.py - -# Python 2 versions prior to some early 2.7.x release and Python 3 versions -# prior to some 3.2.x release had buggy disutils implementations that can -# result in our project's source distribution containing some extra unwanted -# files picked up from some of our local cache folders. This is a 3-layer fix -# to work around the problem: -# 1. We prune those folders just in case some of their content got added by -# mistake. -# 2. An extra include is here to silence distutils warnings in case the used -# distutils implementation is not buggy and therefore no extra files have -# been added and distutils can not find anything to prune. -# 3. To make the include actually include an existing file, setup.py -# constructs at least one such file to be included with a buggy distutils -# implementation. -include tools/__*/* -prune tools/__* diff --git a/README.rst b/README.rst deleted file mode 100644 index 859a1f85..00000000 --- a/README.rst +++ /dev/null @@ -1 +0,0 @@ -Trying to patch suds-jurko to work with asyncio. \ No newline at end of file diff --git a/TODO.txt b/TODO.txt deleted file mode 100644 index 39e89d44..00000000 --- a/TODO.txt +++ /dev/null @@ -1,2271 +0,0 @@ -PRIORITIZED: -================================================= - -(21.12.2011.) - -(+) * (Jurko) Prepare for the initial forked project release. -(+) * Add todo list. -(+) * Document how to access this forked project's development sources & -(+) released files. -(+) * Jurko's Mercurial repository hosted at BitBucket and accessible -(+) from 'http://bitbucket.org/jurko/suds'. -(+) * Already documented in README. -(+) * Add more details to HACKING. -(+) * Suds library Python 3 patches hosted in a Mercurial patch queue -(+) repository at BitBucket and accessible from -(+) 'http://bitbucket.org/bernh/suds-python-3-patches'. -(+) * Already documented in HACKING. -(+) * (Jurko) Minor stylistic changes & typo corrections. -(+) * Code. -(+) * 'tranparent' --> 'transparent'. -(+) * 'if tns' --> 'if tns'. -(+) * 'docuemnt' --> 'document'. -(+) * '('restriction', 'any', 'list',)' --> '('restriction', 'any', -(+) 'list')'. -(+) * And other unnecessary trailing tuple commas. -(+) * 'Qualfied' --> 'Qualified'. -(+) * 'Resolveds' --> 'Resolves'. -(+) * 'describe a port and it's list of methods' --> 'describe a port -(+) and its list of methods'. -(+) * 'dependancies' --> 'dependencies'. -(+) * 'imcoming' --> 'incoming'. -(+) * 'relavent' --> 'relevant'. -(+) * 'inidcat' --> 'indicat'. - -(22.12.2011.) - -(+) * (Jurko) Prepare for the initial forked project release. -(+) * Rename top level project documentation files to use the .txt extension -(+) to make them friendlier to Windows users. -(+) * Research release procedure. -(+) * Open PyPI account. -(+) * How to prepare a source distribution package. -(+) * Change author information. -(+) * Include tests. -(+) * Include all the top-level documentation files. -(+) * 'README'. -(+) * 'LICENSE'. -(+) * 'HACKING'. -(+) * 'TODO'. -(+) * Note the original project author in the package description. -(+) * Include correct license information. -(+) * See what the difference between author and maintainer -(+) information is and where it can be seen. -(+) * Try using 'setuptools_hg' to simplify specifying the project -(+) sources. -(+) * Failed when used under Python 3. -(+) * How to upload the prepared distribution packages. -(+) * Should upload a source distribution only. - -(23.12.2011.) - -(+) * (Jurko) Prepare for the initial forked project release. -(+) * Research release procedure. -(+) * How to upload the prepared distribution packages. -(+) * PyPI. - -(24.12.2011.) - -(+) * (Jurko) Prepare for the initial forked project release. -(+) * Research release procedure. -(+) * How to upload the prepared distribution packages. -(+) * BitBucket. -(+) * Document the project's official download URL. -(+) * Document how to access this forked project's development sources & -(+) released files. -(+) * Released project packages accessible from PyPI & BitBucket. -(+) * Installing the project using distribute or pip. -(+) * Document release procedure. -(+) * Version identification. -(+) * Remove the '(development)' suffix for official release builds. -(+) * Format ' jurko #', e.g. '0.4.1 jurko 1'. -(+) * Tag in Hg. -(+) * Name the tag like 'release-', e.g. -(+) 'release-0.4.1 jurko 1'. -(+) * Prepare official releases based only on tagged commits. -(+) * Prepare source distribution package, register the new release -(+) at PyPI and upload the prepared source package. -(+) * Run 'setup.py sdist register upload'. -(+) * Upload the prepared source package to the project site. -(+) * Archive the prepared source release locally if needed. -(+) * Next development version identification. -(+) * Bump up the forked project version counter. -(+) * Add back the '(development)' suffix. -(+) * Commit all local changes. -(+) * (Jurko) Constructing a SOAP request containing data stored in a sequence -(+) inside a choice. -(+) * Test scenario (syntax not precise). -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) * When 's' is None and 'a' is not - 'a' should be used. -(+) * When 'a' is None and 's' is not - 's' should be used. -(+) * When 's' is used, all of its child elements should be used independent -(+) of whether they are None or not. -(+) * Add related test. -(+) * (Jurko) Prepare the '0.4.1 jurko 1' release. -(+) * Follow the documented release procedure. -(+) * Update version information. -(+) * Tag in Hg. -(+) * Upload the source package. -(+) * Project site. -(+) * PyPI. -(+) * (Jurko) Fix getting a suds.client object's string representation when the -(+) client is initialized with the following WSDL. Calling 'str(client)' -(+) reports 'IndexError: list index out of range'. -(+) * WSDL. -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) -(+) * Research. -(+) * Caused by undocumented suds.client.Client behaviour - it was -(+) expecting a specifically formatted suds.__build__ string which was -(+) not the case with the forked project release. -(+) * Add a test. -(+) * Fix. -(+) * Plan preparing a patched release. -(+) * (Jurko) Prepare the '0.4.1 jurko 2' release. -(+) * Update release notes. -(+) * Follow the documented release procedure. -(+) * Update version information. -(+) * Tag in Hg. -(+) * Upload the source package. -(+) * Project site. -(+) * PyPI. - -(25.12.2011.) - -(+) * (Jurko) Printing out a list of function parameters should not print an -(+) additional trailing comma after the last parameter. -(+) * Research. -(+) * suds.servicedefinition.ServiceDescription.description() code needs -(+) to be changed. -(+) * Prepare test. -(+) * Update code. -(+) * (Jurko) 'suds.xsd.xsbasic.Enumeration' objects should list their value in -(+) their string representation. -(+) * Research. -(+) * Prepare test. -(+) * Update code. -(+) * (Jurko) 'suds.sudsobject.Metadata' __unicode__()/__str__()/__repr__() -(+) functions should not raise an AttributeError. -(+) * Research. -(+) * There should be no need to access a 'suds.sudsobject.Metadata' -(+) object's __metadata__ member as done for 'suds.sudsobjects.Facade' -(+) class instances. -(+) * Prepare test. -(+) * Update code. - -(26.12.2011.) - -(+) * (Jurko) Clean up suds.xsd.sxbasic.TypedContent.resolve(). -(+) * Research. -(+) * Base class resolve() behaviour. -(+) * Other resolve() functions in suds. -(+) * 'resolve()' related caching. -(+) * Clean up the SchemaObject resolve() implementations. -(+) * Caching not needed in TypedContent base classes. -(+) * Document. -(+) * Returns the same XSD node when the node does not have an -(+) explicitly specified external type. -(+) * When called for an XSD node with an explicitly specified external -(+) type returns that type's XSD node. -(+) * (Jurko) Clean up suds.xsd.sxbasic.TypedContent.resolve(). -(+) * Research WSDL structure related to the resolving type references. -(+) * 'type'. -(+) * 'ref'. -(+) * Prepare additional resolve() tests. -(+) * 'ref'. -(+) * Valid. -(+) * Recursive. -(+) * Invalid. -(+) * References to nodes referencing other nodes. -(+) * There seems to be no way to do this in WSDL so seems no -(+) reason to keep the complicated and potentially buggy -(+) recursive resolve() implementation. -(+) * Refactor the resolve() implementation to remove recursion. -(+) * Todo items obsoleted by this refactoring. -(+) * Prevent possible endless resolve() loops due to resolve() -(+) directly or indirectly returning the same TypedContent -(+) instance. -(+) * Refactor to cache the final resolved type instead of a possibly only -(+) partially resolved one when resolving without allowing resolving to -(+) builtin types. -(+) * Research. -(+) * Prepare test. -(+) * Update code. -(+) * (Jurko) Check and remove detected potential unused imports if they are no -(+) longer needed. -(+) * splitPrefix. -(+) * DefinitionsReader. -(+) * (Jurko) Prepare the '0.4.1 jurko 3' release. -(+) * Update release notes. -(+) * Follow the documented release procedure. -(+) * Update version information. -(+) * Tag in Hg. -(+) * Upload the source package. -(+) * Project site. -(+) * PyPI. -(+) * (Jurko) Look into suds.xsd.sxbase.SchemaObject.unbounded(). It seems to -(+) return True even when the object is bounded with a max value greater than -(+) 1. -(+) * Research. -(+) * Add tests. -(+) * 'min'. -(+) * 'max'. -(+) * 'optional'. -(+) * 'required'. -(+) * 'unbounded'. -(+) * Update code - rename unbounded to multi_occurrence. - -(27.12.2011.) - -(+) * (Jurko) Get calling a web service operation taking no parameters to work -(+) correctly. -(+) * Research. -(+) * Seems to work fine. The original problem triggering this task -(+) seems to have been caused by an invalid WSDL. -(+) * Add a task to add more detailed test cases for this. - -(17.04.2012.) - -(+) * (Jurko) Merge upstream changes from the original suds development -(+) repository. -(+) * (Jurko) Update embedded author values so they do not include non-ASCII -(+) characters causing problems with the 'distribute' based setup procedure -(+) which erroneously assumes they have been prepared using the user's local -(+) code-page. -(+) * (Jurko) Process received pull requests on BitBucket. -(+) * (Jurko) Prepare the '0.4.1 jurko 4' release. -(+) * Update release notes. -(+) * Follow the documented release procedure. -(+) * Update version information. -(+) * Tag in Hg. -(+) * Upload the source package. -(+) * Project site. -(+) * PyPI. - -(28.02.2013.) - -(+) * (Jurko) Merge changes prepared by Juraj Ivančić. -(+) * Update the original Hg repository containing Python 3 related fixes. -(+) * (Jurko) Process received pull requests. - -(01.03.2013.) - -(+) * (Jurko) Sync with external related repositories. -(+) * 'http://bitbucket.org/palday/suds'. - -(27.03.2013.) - -(+) * (Jurko) Fix buggy Python 3 support patch related to reading the cache -(+) version. -(+) * The cache version file should be read as a text and not as a binary -(+) file. -(+) * (Jurko) Fix test_enumeration_type_string_should_contain_its_value test -(+) under Python 2. -(+) * (Jurko) Test & fix Python 2.4 compatibility. -(+) * (Jurko) Fix input/output binding usage. -(+) * Incorrect binding was being used in several places. -(+) * Some of the uses related to processing the SOAP Fault error reporting -(+) element seem to be 'fake', needed only because of a a bit messy -(+) design. Planned to be fixed soon. - -(28.03.2013.) - -(+) * (Jurko) Add web service reply processing related unit tests. -(+) * (Jurko) Remove undocumented, untested & unused binding.replyfilter -(+) functionality. -(+) * (Jurko) Remove seeming unused SoapClient last_sent() and last_received() -(+) functionality. -(+) * (Jurko) Add a test for unicode Fault data processing. -(+) * (Jurko) Merge SoapClient failed() & succeeded() functions into the same -(+) process_reply() function. -(+) * (Jurko) Make binding classes no longer have anything to do with method -(+) independent Fault element processing. -(+) * (Jurko) Make reply XML processing check the namespace used for Envelope & -(+) Body elements. -(+) * (Jurko) Make SOAP Fault processing check the namespaces used for all -(+) relevant tags. -(+) * (Jurko) Make HTTP status code 200 XML replies containing a Fault element -(+) consistently reported as SOAP faults (plus issue a warning about the -(+) non-standard HTTP status code) both when reporting such faults using -(+) exceptions or by returning a (status, reason) tuple. -(+) * Currently this is done only when reporting them using exceptions. -(+) * (Jurko) Make plugins received() & parsed() calls now process both success -(+) & error replies. -(+) * (Jurko) SOAP fault reports with invalid Fault structure should not cause -(+) suds code to break with an 'invalid attribute' exception. -(+) * (Jurko) SOAP fault reports with no tag (optional) should not -(+) cause suds code to break with an 'invalid attribute' exception when run -(+) with the suds 'faults' option set to false. -(+) * (Jurko) Clean up message reply processing return codes with suds 'faults' -(+) option set to both true & false. -(+) * (Jurko) Reorganize SimClient injection keywords. -(+) * 'msg' - request message. -(+) * 'reply' - reply message ('msg' must not be set). -(+) * 'status' - HTTP status code accompanying the 'reply' message. -(+) * 'description' - description string accompanying the 'reply' message. -(+) * (Jurko) Check failing tests. -(+) * All tests now pass except for ones related to SOAP Fault unicode -(+) faultstring processing. - -(29.03.2013.) - -(+) * (Jurko) Sync with external related repositories. -(+) * 'http://bitbucket.org/blarghmatey/suds-blarghmatey'. -(+) * (Jurko) Additional SOAP web service reply tests. -(+) * (Jurko) Fix detected unicode problems. -(+) * Remove invalid WebFault fix merged from an external source. -(+) * All suds exception classes now contain unicode description messages. -(+) * Undo a hasty unicode related WebFault fix merged from an external -(+) source in revision 16b084e8eea6511981d171e63cada98b58720c38. -(+) * Rename smart_str class to byte_str and make it accept only string -(+) parameters. -(+) * Clean Python2/3 compatibility DocumentStore fix. -(+) * Now contains raw data instead of unicode strings. -(+) * This also fixes a problem where unicode data read from the -(+) DocumentStore would fail to be encoded using the default encoding, -(+) which would then get reported as 'document not found'. -(+) * SAX parser now accepts only byte string content instead of also -(+) accepting unicode strings containing latin1 characters only. -(+) * Make tests now specify their fixed WSDL & reply content as byte -(+) strings only. -(+) * Make all tests pass. -(+) * Python 2.4. -(+) * Python 2.7.3. -(+) * Python 3.2.3. -(+) * (Jurko) Remove Python 2/3 unicode encoding compatibility support assuming -(+) that its encoded unicode representations contain only latin1 characters. -(+) * SoapClient 'location' cleanup. -(+) * Should be stored as a unicode object instead of being converted -(+) from its byte representation assuming it was encoded using a -(+) specific encoding, e.g. if read from a WSDL schema, it should be -(+) decoded the same as the rest of the WSDL schema. -(+) * Remove str2bytes() & bytes2str(). -(+) * (Jurko) Remove the str_to_utf8_in_py2() Python 2/3 unicode encoding -(+) compatibility support function as it no longer seems to be needed. -(+) * (Jurko) Add tests for web service operation input & output element types. - -(30.03.2013.) - -(+) * (Jurko) Improve suds tests. - -(31.03.2013.) - -(+) * (Jurko) Add tests for wrapped suds operation input & output data. - -(01.04.2013.) - -(+) * (Jurko) Add tests for wrapped suds operation output data. -(+) * (Jurko) Merge patches sent in by Juraj Ivančić from PKE sistemi. -(+) * Add tests for disabled wrapped suds operation input & output data -(+) support. -(+) * Add code for disabling suds library wrapped parameter support. - -(02.04.2013.) - -(+) * (Jurko) Restriction support cleanup based on patches sent in by Juraj -(+) Ivančić from PKE sistemi. -(+) * Research. -(+) * Not enough time to research this thoroughly and come up with a -(+) complete and well tested solution. -(+) * Prepare and commit related tests. -(+) * Mark the tests as 'expected to fail' & comment the reasons. -(+) * Commit as a separate unfinished private branch. -(+) * (Jurko) Prepare the '0.4.1 jurko 5' release. -(+) * Update release notes. - -(08.05.2013.) - -(+) * (Jurko) Make suds construct SOAP requests with correct element namespaces -(+) when their XSD schema definition nodes reference other nodes with a -(+) different namespace. -(+) * Research. -(+) * Add test. -(+) * Implement. -(+) * Report back to Jens Arm from KabelDeutschland who reported the issue. -(+) * (Jurko) Support specifying a custom DocumentStore instance for a specific -(+) Client. -(+) * Support. -(+) * Update test code adding documents to the global DocumentStore instance -(+) to use a local one instead. -(+) * Cleanup. -(+) * DocumentStore.open() can return the bytes object directly instead -(+) of having to wrap it inside a BytesIO instance. -(+) * Remove unnecessary Cache functions. -(+) * getf() should be left in the FileCache class only. -(+) * putf() should be removed completely. -(+) * Add tests. -(+) * Separate DocumentStore instances must not share content. -(+) * Not specifying a DocumentStore instance uses the default global -(+) one. -(+) * Default content. -(+) * Updating content. -(+) * Accessing existing content. -(+) * Accessing missing content. - -(17.06.2013.) - -(+) * (Jurko) Upgrade the setup procedure to use the latest setuptools 0.7.2 -(+) release instead of the now deprecated 'distribute' Python package. -(+) * Research. -(+) * Implement. - -(18.06.2013.) - -(+) * (Jurko) Upgrade the setup procedure to use the latest setuptools 0.7.2 -(+) release instead of the now deprecated 'distribute' Python package. -(+) * Add automated setuptools installation (downloaded on-demand from -(+) PyPI). -(+) * Fix issues with installing on Python 2.4. -(+) * Add project installation troubleshooting notes to the main readme. -(+) * (Jurko) See how to allow using the setup script's 'test' option to run the -(+) project's pytest based test suite. - -(19.06.2013.) - -(+) * (Jurko) Resolve test failures caused by suds generating slightly different -(+) SOAP requests when using Python 3.3. -(+) * Tests should not depend on the order in which XML attributes are -(+) specified for a single XML element where this is not necessary. - -(11.11.2013.) - -(+) * (Jurko) Prepare the '0.4.1 jurko 5' release. -(+) * Follow the documented release procedure. -(+) * Update release notes. -(+) * Update version information. -(+) * Tag in Hg. -(+) * Upload the source package. -(+) * Project site. -(+) * PyPI. - -(18.11.2013.) - -(+) * (Jurko) Fix suds time-zone handling according to a pull request received -(+) on BitBucket from MDuggan1. -(+) * Research. -(+) * Suds assumes that all timezones have a full-hour offset from the -(+) UTC timezone and does not work correctly with those that do not. -(+) * This seems to be a suds specific problem and not a more -(+) general Python issue as some information on the net implies. -(+) * FixedOffsetTimezone. -(+) * datetime.tzinfo subclass. -(+) * Used only in test code. -(+) * Represents fixed offset timezones with no daylight saving -(+) time. -(+) * Start morphing the current suds & test code base towards the suggested -(+) patched code. - -(19.11.2013.) - -(+) * (Jurko) Fix suds time-zone handling according to a pull request received -(+) on BitBucket from MDuggan1. -(+) * Research. -(+) * Prepare date/time string parsing tests. - -(20.11.2013.) - -(+) * (Jurko) Start documenting the upcoming suds 0.4.1 jurko 6 release. -(+) * (Jurko) Fix suds time-zone handling according to a pull request received -(+) on BitBucket from MDuggan1. -(+) * Research. -(+) * Implement parsing. -(+) * DateTime no longer derived from Date & Time. -(+) * Date constructed from datetime.datetime should hold a datetime.date. -(+) * Research. -(+) * See if sax.date.Date("1900-01-01+02:00") should hold a timezone -(+) aware date object. -(+) * Related test: TestDate.testStringToValue(). -(+) * Timezone data. -(+) * See when we need to specify timezone information. -(+) * In tests when we create DateTime/Time objects. -(+) * Default timezone when parsing web service responses. -(+) * YAGNI - for now left to user code reading specific -(+) DateTime/Time objects. -(+) * Default timezone when constructing web service requests. -(+) * YAGNI - for now left to user code creating specific -(+) DateTime/Time objects. -(+) * Implement. -(+) * Contained datetime.DateTime/Time objects should hold their -(+) timezone information. -(+) * Research. -(+) * Test TestDate.testStringToValue_failure() fails on Python 2 but -(+) passed on Python 3. -(+) * Fixed by the latest implementation changes. - -(21.11.2013.) - -(+) * (Jurko) Fix suds time-zone handling according to a pull request received -(+) on BitBucket from MDuggan1. -(+) * Check for feedback from users requesting this patch. -(+) * Add tests. -(+) * FixedOffsetTimezone class. -(+) * Fix FixedOffsetTimezone.tzname() output string formatting bug with -(+) negative timezone offsets. -(+) * Add tests. -(+) * UtcTimezone class. -(+) * (Jurko) Remove support for timezone specifiers including seconds as such -(+) are not supported by either Python or the XSD data types specification. -(+) * Add/update tests. -(+) * Input like "+10:10:10" should be rejected. -(+) * Timezone offset timedelta objects containing more detailed than -(+) minute information. -(+) * Remove support. -(+) * (Jurko) Add tests making sure timezone indicator strings without a colon -(+) between hours and minutes are not accepted. -(+) * This leads to border cases like "+121" where you do not know whether -(+) this represents "+01:21" or "+12:01". - -(22.11.2013.) - -(+) * (Jurko) Remove date/time related test code duplication. -(+) * Date, DateTime & Time classes. -(+) * Clean up test function names. -(+) * Test construction from unexpected objects. -(+) * Test construction from datetime.date/datetime/time objects. -(+) * str() tests. -(+) * XDate & Date class. -(+) * XDateTime & DateTime class. -(+) * XTime & Time class. -(+) * Timezone handling checks in XDateTime & XTime classes. - -(23.11.2013.) - -(+) * (Jurko) Make converting datetime/time to string output subsecond -(+) information without trailing zeroes. -(+) * Test. -(+) * Implement. -(+) * Discard as the implementation complexity seems way too great and the -(+) gain does not seem to reciprocate the cost. -(+) * (Jurko) Update the project's versioning scheme to no longer have pip -(+) detect suds-jurko releases as 'prerelease' only due to our version tag -(+) formatting. -(+) * Accept that the original suds project has died and continue with the -(+) natural version number progression. -(+) * (Jurko) Plan a new release. -(+) * (Jurko) Update used setuptools version. -(+) * (Jurko) Remove unused project files inherited from the original suds -(+) project. - -(25.11.2013.) - -(+) * (Jurko) Test the project with different Python installations. -(+) * Python 2.4.3/x86, on Windows 7/SP1/x64. -(+) * Install. -(+) * 'setuptools'. -(+) * 'pip'. -(+) * Describe encountered problems in 'HACKING.txt'. -(+) * 'pytest'. -(+) * Describe encountered problems in 'HACKING.txt'. -(+) * Run tests. -(+) * Python 2.4.4/x86, on Windows 7/SP1/x64. -(+) * Install. -(+) * 'setuptools'. -(+) * 'pip'. -(+) * Describe encountered problems in 'HACKING.txt'. -(+) * 'pytest'. -(+) * Describe encountered problems in 'HACKING.txt'. -(+) * Run tests. -(+) * Python 2.7.6/x64, on Windows 7/SP1/x64. -(+) * Install. -(+) * 'setuptools'. -(+) * 'pip'. -(+) * 'pytest'. -(+) * Run tests. -(+) * Python 3.2.5/x64, on Windows 7/SP1/x64. -(+) * Install. -(+) * 'setuptools'. -(+) * 'pip'. -(+) * 'pytest'. -(+) * Run tests. -(+) * Python 3.3.3/x86, on Windows 7/SP1/x64. -(+) * Install. -(+) * 'setuptools'. -(+) * 'pip'. -(+) * 'pytest'. -(+) * Run tests. -(+) * Python 3.3.3/x64, on Windows 7/SP1/x64. -(+) * Install. -(+) * 'setuptools'. -(+) * 'pip'. -(+) * 'pytest'. -(+) * Run tests. -(+) * (Jurko) Document the test environment setup in HACKING.txt. -(+) * (Jurko) Prepare a new suds-jurko 0.5 release. - -(28.11.2013.) - -(+) * (Jurko) Look into a reported problem with how unicode data gets encoded -(+) inside a suds SOAP request with Python 2. Reported by Alexey Sveshnikov -(+) and mduggan1. -(+) * Get a reproducible use case from Alexey Sveshnikov. -(+) * Research. -(+) * Data in HTTP requests needs to be encoded as defined by the -(+) Content-Type header given in that request (ISO-8859-1 being the -(+) default). -(+) * Suds set the "Content-Type=text/xml; charset=utf-8" HTTP request -(+) header for all of its SOAP requests. -(+) * Python's http module (used internally by the urllib module) add -(+) the given message data to its existing data. Suds gives its -(+) message data to urllib as an utf-8 encoded bytes object. If -(+) existing message data is unicode, it will attempt to forcefully -(+) convert the given message data to unicode assuming all it contains -(+) is ASCII characters. -(+) * Suds message data is already a utf-8 encoded bytes object. -(+) * With Python-3 httplib's previous message data is a bytes and not a -(+) string object. -(+) * The reason why httplib's message content is converted to unicode -(+) is that with Python 2 the initial header is a unicode object -(+) u'POST /service HTTP/1.1' while with Python 3 it is a bytes object -(+) b'POST /service HTTP/1.1'. -(+) * Python 2. -(+) * Affects Python 2.7. -(+) * Does not affect Python 2.4. -(+) * Python 3. -(+) * Its httplib Request object automatically converts the -(+) passed URL to a bytes object (assumes it contains only -(+) ASCII characters) which then prevents all the other -(+) request data from being forcibly converted to unicode. - -(29.11.2013.) - -(+) * (Jurko) Look into a reported problem with how unicode data gets encoded -(+) inside a suds SOAP request with Python 2. Reported by Alexey Sveshnikov -(+) and mduggan1. -(+) * Reduce the reproducible use case. -(+) * Should not require an external web service. -(+) * Integrate into regular suds-jurko tests. -(+) * Make the reproducible test case not attempt to connect to the network -(+) if the test passes. -(+) * Fix the issue. -(+) * Confirm with Alexey Sveshnikov that it is ok with him to make the -(+) reproducible use case public. -(+) * Close related project pull requests on 'bitbucket.org'. -(+) * (Jurko) Add a test for handling actual non-ASCII unicode service location -(+) data. - -(30.11.2013.) - -(+) * (Jurko) See if the suds HttpTransport.open() method ever gets called. -(+) * Yup, transport open() methods get called from DocumentReader, e.g. -(+) when downloading a WSDL schema from the net. -(+) * It seems like Transport's open() & send() methods might be mergeable, -(+) but that would first require further research. For now - YAGNI. -(+) * (Jurko) Process pull requests received on 'bitbucket.org'. -(+) * Fix setup.py current working folder path comparison so it works with -(+) links in the path. Contributed by ryanpetrello. - -(23.12.2013.) - -(+) * (Jurko) Prepare a basic development script for running the full suds test -(+) suite using multiple Python interpreter versions. - -(26.12.2013.) - -(+) * (Jurko) Process patches sent in by Bouke Haarsma on BitBucket. -(+) * Unicode logging issue. -(+) * Research. -(+) * Prepare tests. -(+) * Merge. -(+) * Thorough code review. -(+) * Implement a cleaner fix for both Reply & Request classes. -(+) * Update release notes. -(+) * (Jurko) Fix possible typo in the suds.transport.Request string/unicode -(+) representation where there seems to be a missing space after a colon just -(+) before the URL information. -(+) * (Jurko) Remove unnecessary logger objects. -(+) * (Jurko) Process the project issue #2 reported on BitBucket by Arthur -(+) Clune, related to not being able to set the option cache location if the -(+) default cache location is not a writable folder. -(+) * Research. -(+) * Prepare tests. -(+) * Default cache. -(+) * Default ObjectCache instance should be created only if no other -(+) cache has been explicitly specified during suds.client.Client() -(+) construction. -(+) * Fix. -(+) * Update release notes. -(+) * Report back & close the project issue on BitBucket. - -(21.01.2014.) - -(+) * (Jurko) Process patch sent in by Bouke Haarsma on BitBucket to 'make sure -(+) all web service operation parameters are consumed'. -(+) * This patch has been worked on on a separate feature branch for close -(+) to a month now. -(+) * Update todo list. -(+) * Update release notes. -(+) * Commit. -(+) * Push changes to BitBucket. - -(23.01.2014.) - -(+) * (Jurko) Prepare internal documentation notes folder. -(+) * Add folder & add a descriptive readme.txt file to it. -(+) * Include in the source distribution folder. -(+) * Do not include it in the installation. -(+) * Note the new documentation notes folder in the project's HACKING.rst -(+) documentation. - -(24.01.2014.) - -(+) * (Jurko) Process Jurko's research & todo notes collected while working on -(+) reporting extra parameter errors. -(+) * (Jurko) Prepare a new suds-jurko 0.6 release. -(+) * Check release notes. -(+) * Test. -(+) * Update version tag. -(+) * Tag in Hg. -(+) * Update version information. -(+) * Retag in Hg -(+) * Package the release. -(+) * Distribute the new release. -(+) * PyPI. -(+) * BitBucket. -(+) * Notify Gauthier Bastien - see comments for commit -(+) 9da81de891958292850a242781b30a3493f617 on BitBucket. -(+) * Prepare project information for the next development cycle. - -(25.01.2014.) - -(+) * (Jurko) Look into issue #12 & the related pull request #22 reported on -(+) BitBucket - suds-jurko incorrectly returning a raw Fault() instead of a -(+) WebFault() object when faults=False. Reported as a regression against the -(+) base suds project. -(+) * Research. -(+) * Most likely introduced by commit -(+) '506c8362c81343f1f629906606db23daf8b426ec'. -(+) * Try to reproduce using an injected reply. -(+) * Test against the current HEAD commit. -(+) * Find a commit not that works correctly. -(+) * Status. -(+) * Could not reproduce the issue. Truly suds-jurko returns a -(+) suds.sudsobject.Fault object, but the original suds library -(+) implementation does not return a suds.WebFault object either. -(+) Further work on this can be done only once the exact desired -(+) behaviour is defined. -(+) * Ask for feedback containing a reproducible example. - -(26.01.2014.) - -(+) * (Jurko) Code cleanup. -(+) * Stylistic cleanup. -(+) * (Jurko) Process decimal type support patch sent in by pendletongp on -(+) BitBucket. -(+) * Research. -(+) * Where a Python type to SOAP representation transformation is -(+) performed. -(+) * Expected locations. -(+) * When constructing a web service operation invocation -(+) request, i.e. when marshaling Python data to a SOAP -(+) request XML (mx package). -(+) * Where a SOAP representation to Python type transformation is -(+) performed. -(+) * Expected locations. -(+) * When processing a web service operation reply, i.e. when -(+) unmarshaling Python data from a SOAP response XML (umx -(+) package). - -(28.01.2014.) - -(+) * (Jurko) Process decimal type support patch sent in by pendletongp on -(+) BitBucket. -(+) * Prepare tests. -(+) * Representation tests for different data types. -(+) * Transformation tests for different data types. -(+) * Thorough code review. -(+) * Add XFloat tests. - -(29.01.2014.) - -(+) * (Jurko) Update XFloat to correctly translate decimal.Decimal & -(+) numbers.Real (on Python 2.6+) values to their XSD value representation. -(+) Currently, inconsistently with how other types are handled, they get -(+) translated to the same decimal/fraction value which then gets changed to a -(+) string later on when actually writing it to an XML string. This works out -(+) fine for decimals in the end but not for rationals/fractions. -(+) * Research. -(+) * decimal.Decimal input values already get entered correctly into -(+) constructed SOAP XML requests. -(+) * It seems not all numbers.Real derived classes can be converted to -(+) their XSD value representation the same way. -(+) * Some examples. -(+) * float --> str(x) -(+) * fractions.Fraction --> str(float(x)) -(+) * decimals.Decimal --> str(x) -(+) * int --> str(x) -(+) * bool --> str(int(x)) -(+) * Adding support for them would pair down to simply listing all -(+) supported types explicitly and adding code for translating -(+) each of them separately. We can not possibly do this for 'all -(+) data types in the world' so the current implementation seems -(+) as good as any. -(+) * A user application requiring support for a specific type can -(+) always add it itself by implementing a replacement XFloat class -(+) and registering it using suds.xsd.xbuiltin.Factory.maptag(). -(+) * Discard the task. -(+) * Add a new development note document describing XType class usage for -(+) built-in XSD type value translation between Python objects and their -(+) XSD value representations. -(+) * (Jurko) Clean up different XType.translate() methods. See if there is any -(+) difference in them returning a string or any other Python object -(+) convertible to a string using str(). -(+) * If there is no difference, clean up the code to simply return the -(+) original value where possible. -(+) * (Jurko) Process decimal type support patch sent in by pendletongp on -(+) BitBucket. -(+) * Research. - -(30.01.2014.) - -(+) * (Jurko) Process decimal type support patch sent in by pendletongp on -(+) BitBucket. -(+) * Research. -(+) * XSD type value representation is incorrect. -(+) * Apply equivalent changes together with adding related unit tests. -(+) * Comment on the original issue #3 & patch request #19 on BitBucket. -(+) * Update release notes. -(+) * Later ideas to consider. -(+) * 'float' --> 'decimal.Decimal' conversion which has not been -(+) implemented in Python before Python 2.7. -(+) * YAGNI for now. -(+) * Update release notes. - -(31.01.2014.) - -(+) * (Jurko) Restore last_sent()/last_received() getters for last used SOAP -(+) request/response messages. -(+) * Research background. -(+) * Requested by. -(+) * andreebrazeau as BitBucket. -(+) * 'http://bitbucket.org/andreebrazeau'. -(+) * FerCesar at BitBucket. -(+) * 'http://bitbucket.org/FerCesar'. -(+) * Lucas Sampaio at BitBucket. -(+) * 'http://bitbucket.org/lucassmagal'. -(+) * Related links. -(+) * 'http://stackoverflow.com/questions/4426204/ -(+) how-can-i-output-what-suds-is-generating-receiving'. -(+) * 'http://jortel.fedorapeople.org/suds/doc/ -(+) suds.client.Client-class.html' -(+) * Code removed in commit 'f0034d6826c179625478bc19ae2a39a0b803fc3a'. - -(03.02.2014.) - -(+) * (Jurko) Restore last_sent()/last_received() getters for last used SOAP -(+) request/response messages. -(+) * Clean up related code. - -(05.02.2014.) - -(+) * (Jurko) Clean up SoapClient/SimClient related code a bit. -(+) * Generic code cleanup. -(+) * Mark private methods using leading underscores. -(+) * Remove RequestContext.original_envelope attribute. -(+) * Stop logging incorrect 'original_envelope' value. -(+) * Rename to _SoapClient/_SimClient. - -(06.02.2014.) - -(+) * (Jurko) Add tests for the functionality potentially affected by a planned -(+) _SoapClient/_SimClient refactoring. -(+) * Cache - update existing tests. -(+) * File operation failures. - -(07.02.2014.) - -(+) * (Jurko) Update FileCache duration handling. -(+) * Research. -(+) * Currently FileCache.__set_duration() implementation allows using -(+) only a single unit. -(+) * Check whether Python 2.4 datetime.timedelta class implementation -(+) allows it to be constructed from multiple units. -(+) * Store FileCache.duration as a datetime.timedelta instance. -(+) * Support for specifying FileCache durations with multiple time units. -(+) * Add tests. -(+) * Default suds.Client cache. -(+) * Already tested in test_default_cache_construction(). -(+) * Class. -(+) * Duration. -(+) * Default duration. -(+) * Set duration (<0, 0, >0, single/multiple duration arguments). -(+) * Exception on duration < 0. -(+) * YAGNI. Current implementation, using negative values as -(+) regular durations and simply adding them to a specific file -(+) timestamp to see whether it expired seems good enough as well -(+) as intuitive enough for the user. -(+) * Expiration after expiration time with duration > 0. -(+) * Not expiring after expiration time with duration = 0 -(+) * Not expiring before expiration time with duration > 0. -(+) * Not expiring before expiration time with duration = 0. -(+) * Duration testing for all FileCache derived classes - DocumentCache -(+) & ObjectCache. -(+) * FileCache and derived classes - one item expiring should not -(+) affect other unexpired items. -(+) * Update release notes. -(+) * (Jurko) Per process default FileCache folder randomization + removal on -(+) exit. -(+) * Research. -(+) * Related BitBucket issue #15. -(+) * Links from the BitBucket issue #15. -(+) * 'https://bugzilla.redhat.com/show_bug.cgi?id=978696'. -(+) * 'http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-2217'. - -(09.02.2014.) - -(+) * (Jurko) Per process default FileCache folder randomization + removal on -(+) exit - fix CVE-2013-2217. -(+) * Add tests. -(+) * Implement. -(+) * Update release notes. -(+) * Update related issues on BitBucket. -(+) * (Jurko) Extract all suds.client.Client related tests related to how it -(+) uses its worker cache/store/transport components into separate -(+) test_client.py test module. Modules like test_transport.py or -(+) test_cache.py should concentrate on testing that specific component -(+) functionality and not how the component gets used by suds.client.Client. -(+) * Test modules to check. -(+) * 'test_cache.py'. -(+) * 'test_client_cache.py'. -(+) * 'test_transport.py'. -(+) * Several transport usage tests already prepared in test_transport_1.py -(+) on Jurko's notebook. - -(10.02.2014.) - -(+) * (Jurko) Add tests for the functionality potentially affected by a planned -(+) _SoapClient/_SimClient refactoring. -(+) * Client's cache/store/transport usage. -(+) * WSDL access. -(+) * If an object is found in cache it should not be looked up in -(+) the given document store or transported. -(+) * If an object is found in a given document store it should not -(+) be transported. - -(14.02.2014.) - -(+) * (Jurko) Clean up test_client.py test module - extract all remaining -(+) suds.client.Client related tests related to how it uses its worker cache/ -(+) store/transport components. -(+) * Test modules to check. -(+) * 'test_transport_http.py'. -(+) * (Jurko) Update test_sending_non_ascii_data_to_unicode_URL() test to test -(+) both send() & open() transport operations. - -(17.02.2014.) - -(+) * (Jurko) Clean up Transport ASCII/Unicode URL/data handling. -(+) * Design desired behaviour. -(+) * URL may be specified as either a byte string or a unicode string. -(+) * URL input data may contain ASCII characters only. -(+) * URL stored internally as a native str type (byte string with -(+) Python versions prior to 3, unicode string with Python 3+). -(+) * Using it in a different format breaks the underlying -(+) HttpTransport httplib implementation under some Python -(+) versions. -(+) * Bytes data used directly. -(+) * Unicode data used directly with the underlying implementation -(+) converting the data to bytes or raising an error. -(+) * HttpTransport. -(+) * Python2 - converts to bytes if ASCII chars only. -(+) * Python2 - error for non-ASCII chars. -(+) * Python3 - error. -(+) * Fix suds.transport Reply & Request string representation. -(+) * Update suds.transport.Request. -(+) * Check for non-ASCII URL characters. -(+) * Hold it internally as a native str type. -(+) * Update suds.transport.http.HttpTransport. -(+) * Expects the suds.transport.Request to have already checked its URL -(+) content. -(+) * Document the desired design (docstrings). -(+) * Request. -(+) * Transport. -(+) * Update tests. -(+) * Request tests. -(+) * Bytes URL. -(+) * Must be used directly on Python 2. -(+) * Must be converted to str URL internally on Python 3. -(+) * Error if it includes non-ASCII character codes. -(+) * Unicode URL. -(+) * Must be converted to str URL internally on Python 2. -(+) * Must be used directly on Python 3. -(+) * Error if it includes non-ASCII character codes. -(+) * HttpTransport tests. -(+) * Sending data through the network. -(+) * Remove tests made redundant by the new Request testing. -(+) * Update release notes. - -(18.02.2014.) - -(+) * (Jurko) Add tests for the functionality potentially affected by a planned -(+) _SoapClient/_SimClient refactoring. -(+) * Client's cache/store/transport usage. -(+) * If an object is found in cache it should not be looked up in the -(+) given document store or transported. -(+) * WSDL document. -(+) * Imported XSD schema. -(+) * Included XSD schema. - -(19.02.2014.) - -(+) * (Jurko) Add a failing test illustrating a WSDL import detected when -(+) attempting to test importing a cached WSDL schema. -(+) * test_WSDL_import(). -(+) * (Jurko) Add tests for the functionality potentially affected by a planned -(+) _SoapClient/_SimClient refactoring. -(+) * Client's cache/store/transport usage. -(+) * If an object is found in cache it should not be looked up in the -(+) given document store or transported. -(+) * Imported WSDL document. -(+) * If an object is found in a given document store it should not be -(+) transported. -(+) * WSDL document. -(+) * Imported WSDL document. -(+) * Imported XSD schema. -(+) * Included XSD schema. -(+) * If an object is not cached or found in a given document store it -(+) should not transported. -(+) * WSDL document. -(+) * Imported WSDL document. -(+) * Imported XSD schema. -(+) * Included XSD schema. -(+) * Client's cache/store/transport usage. -(+) * Different cachingpolicy option values. -(+) * cachingpolicy == 0 - XML documents are cached. -(+) * Already tested. -(+) * cachingpolicy == 1 - final WSDL objects are cached. -(+) * Loading a WSDL object from cache should avoid attempting -(+) to fetch any additional external data either from the -(+) cache, the document store or the registered transport. - -(20.02.2014.) - -(+) * (Jurko) Add tests for the functionality potentially affected by a planned -(+) _SoapClient/_SimClient refactoring. -(+) * Transport. -(+) * Base Transport, Reply & Request classes already tested. -(+) * HttpTransport. -(+) * urllib2.HTTPError raised from urllib's open() operation. -(+) * ACCEPT/NO_CONTENT status handling - buggy but YAGNI for -(+) now. -(+) * Add a separate todo item to look into this at some -(+) later time. -(+) * Other HTTPError exceptions. -(+) * Other functionality already tested well enough. -(+) * _SoapClient - currently can only be tested via suds.client.Client. -(+) * Using Transport. -(+) * 'nosend' option avoids transport usage. -(+) * Sending data via & using data returned by transport. -(+) * Opening a WSDL already tested. -(+) * Sending a web service operation invocation request. -(+) * Handling transport errors. -(+) * This seems like a complex topic. Prepare a rough test and -(+) add a todo item to deal with this in more detail later on. -(+) * Embed a TODO comment next to the new test. - -(23.02.2014.) - -(+) * (Jurko) Refactor suds.transport.http module unit tests to make them -(+) clearer. - -(27.02.2014.) - -(+) * (Jurko) Fix the raw try:/except: exception handling suds which may eat up -(+) internal exceptions like SystemExit or KeyboardInterrupt but should not. -(+) * Just replace with Exception subclass catching. A more detailed -(+) exception class can be used later on if needed. - -(28.02.2014.) - -(+) * (Jurko) Fix Exception message used when attempting to construct a -(+) suds.sax.element.Element with a non-Element parent. It seems like someone -(+) forgot to apply % formatting there. -(+) * (Jurko) Extract existing XML comparison test utilities into a separate -(+) tests/test_utility.py module (CompareSAX class). - -(03.03.2014.) - -(+) * (Jurko) CompareSAX test utility improvements. -(+) * Use pytest assertions to report errors. -(+) * Add tests. -(+) * Extract tests into a separate module. -(+) * (Jurko) Fix the problem with different processes using different cache ids -(+) for matching documents, causing them not to be able to reuse each other's -(+) cache entries. Original suds implementation used the built-in hash -(+) function which should be replaced with a md5 hash. -(+) * On Python 3.3 and above hash function results are seeded with a random -(+) value for each process. -(+) * 32-bit & 64-bit Python implementations use different hash -(+) implementations giving different results. -(+) * Update readme. -(+) * Problem reported by Eugene Yakubovich at bitbucket. -(+) * See project related comments at: 'http://bitbucket.org/eyakubovich/ -(+) suds/commits/fec6efd9c10b48114bbd9c06847a264453a51620'. - -(04.03.2014.) - -(+) * (Jurko) suds.sax.enc module cleanup. -(+) * Code & comment cleanup. -(+) * Add unit tests. -(+) * (Jurko) Look into CDATA related encoding issues reported at BitBucket -(+) (issue #14 + pull requests #25 & #26). -(+) * Prepare tests. -(+) * Prepare profiling scripts for comparing different solutions. -(+) * Design input types. -(+) * Long input. -(+) * Replacements. -(+) * None. -(+) * Rare. -(+) * Lots. -(+) * CDATA. -(+) * None. -(+) * Short. -(+) * Long. -(+) * Short input. -(+) * Has replacements. -(+) * False. -(+) * True. -(+) * Has CDATA -(+) * False. -(+) * True. - -(05.03.2014.) - -(+) * (Jurko) Consider reimplementing suds.sax.enc.Encoder.decode() using -(+) xml.sax.saxutils.unescape() as suggested by Stephen Fuhry (fuhrysteve at -(+) BitBucket). -(+) * Profile using the prepared tests.profiling.profile_sax_encoder module. -(+) * Python 2.4.3. -(+) * About the same for data containing many replacements. -(+) * New solution much slower for data containing no replacements. -(+) * Python 3.3.3. -(+) * New solution a bit slower for data containing many -(+) replacements. -(+) * New solution much slower for data containing no replacements. -(+) * Discard the new solution as it works the same or worse than the -(+) current one. - -(20.03.2014.) - -(+) * (Jurko) Internal project development cleanup. -(+) * Setting up Python installations used for testing suds. -(+) * Research exact steps for installing required Python packages for -(+) each specific Python version used. -(+) * Prepare Windows batch script performing this operation en-masse. - -(23.03.2014.) - -(+) * (Jurko) Report 'except:' issues in setuptools project's ez_setup.py -(+) script. -(+) * (Jurko) Update the project setup procedure to use any preexisting -(+) setuptools installation of version >= 1.4 but install the latest -(+) compatible setuptools version if a suitable one is not already installed. -(+) * YAGNI - using an older and potentially untested setuptools version -(+) risks our project installation failing without the user 'doing -(+) anything wrong', and gains us only a bit lighter installation in some -(+) scenarios. -(+) * (Jurko) Update the project setup procedure to use setuptools 1.4.2 for -(+) Python versions prior to 2.6, and the latest setuptools version 3.3 for -(+) all newer Python versions. -(+) * Update the project's setup.py script. -(+) * Use setuptools 1.4.2 with Python < 2.6. -(+) * Use setuptools 3.3 with Python >= 2.6. -(+) * Update project hacking documentation. -(+) * Check for newer setuptools versions with every new suds release -(+) and update the project's setup.py script as needed. -(+) * Update release notes. - -(15.05.2014.) - -(+) * (Jurko) Process work done 'as time allowed' during the last two months. -(+) * Commit prepared basic environment setup scripts. -(+) * Mark related todo items now completed or rendered obsolete. -(+) * (Jurko) See if we can make the project setup.py script work when run from -(+) a folder other than the project's root folder. -(+) * Managed to improve the support a bit, but distutils still has issues -(+) regarding this. Should be checked again after a while to see if the -(+) situation has changed. -(+) * (Jurko) Internal project development cleanup. -(+) * Setting up Python installations used for testing suds. -(+) * Prepare a script for installing required Python packages. -(+) * Convert prepared Windows batch script to Python. -(+) * Required Python packages. -(+) * setuptools. -(+) * pip. -(+) * pytest. -(+) * Update project hacking documentation. -(+) * Allow setting up only specific Python versions. -(+) * Can be configured using setup.cfg for now. -(+) * Update to only install packages that have not already been -(+) installed. -(+) * Transformed to embedded TODO comments. -(+) * Make sure the prepared Python script runs using any of the -(+) suds project supported Python versions. -(+) * Collect all downloaded data under a single folder. -(+) * Targeted content. -(+) * ez_setup.py downloaded data. -(+) * easy_install downloaded data. -(+) * pip downloaded data. -(+) * See if using the pip download cache folder is useful at all -(+) since we already pre-download all the required installation -(+) packages and use them from there. -(+) * Prepare a test script installing suds into multiple Python versions. -(+) * Without setuptools preinstalled. -(+) * With setuptools preinstalled. -(+) * setuptools 1.4. -(+) * Latest compatible setuptools release. -(+) * setuptools 1.4.2 for Python releases prior to 2.6. -(+) * (Jurko) Plan preparing a wheel based distribution. -(+) * Test it. -(+) * Document. -(+) * Setting up the necessary development environment. -(+) * Release notes. -(+) * (Jurko) Find a cleaner way to install suds tests. Currently they get -(+) installed into a top-level 'tests' folder and so may cause conflicts with -(+) some other 'tests' package that might exist in the target Python -(+) environment. -(+) * Ideas to consider. -(+) * We want all suds users to have easy access to the suds test suite. -(+) * Suds users are programmers themselves, and so we want to make -(+) it easy for them to reproduce their issues as easily, -(+) concisely and directly as possible, and using existing suds -(+) tests seems like a perfect starting point for doing just that. -(+) * Placing the 'tests' folder under the 'suds' folder. -(+) * Placing the top level suds folder outside the egg folder (similar -(+) to how this is done for the pytest package), not having the egg -(+) folder added to the Python path and leaving the tests folder -(+) inside the egg folder. -(+) * Have setup.py install suds tests as a setuptools 'extra' - only if -(+) explicitly requested. -(+) * At first glance, this does not seem like something we would -(+) like done, as we want all suds users to have easy access to -(+) the suds test suite and not just those installing suds from -(+) its source distribution and providing some magic -(+) '--install-tests'-like command-line option. -(+) * Keep the tests in the source distribution and do not install them. -(+) This seems like the simplest way, so lets go with this for now. - -(16.05.2014.) - -(+) * (Jurko) Find a cleaner way to install suds tests. Currently they get -(+) installed into a top-level 'tests' folder and so may cause conflicts with -(+) some other 'tests' package that might exist in the target Python -(+) environment. -(+) * Update the tests so we no longer need to transform them using py2to3 -(+) in order to run them using Python 3. -(+) * Try using the six compatibility package. -(+) * Manual install. -(+) * Update setup.py. -(+) * Update tools/setup_base_environments.py. -(+) * Update tests. -(+) * Make the tests run using the 'currently installed' suds version. In -(+) order to test the current development version, user should install the -(+) project in development/editable mode using 'pip install -e' or -(+) 'setup.py develop'. -(+) * Running 'setup.py test' should still work using both Python 2 & 3. -(+) * Make project tests run from the root project folder use the correct -(+) installed Python 3 sources if run under Python 3 instead of using the -(+) ones from the current folder. -(+) * No easy way to do this for now. Should look into it again at some -(+) later time. -(+) * Update project release docs. -(+) * Update project HACKING.rst docs. -(+) * Using the 'six' Python 2/3 compatibility package. -(+) * Running project tests using Python 3 - current working folder. - -(22.05.2014.) - -(+) * (Jurko) Test using Python 3.4.1. - -(26.05.2014.) - -(+) * (Jurko) Remove code duplication between setup.py & -(+) tools/setup_base_environments.py, e.g. with regards to setting up the -(+) project's testing requirement packages (argparse, colorama, py, pytest). - -(29.05.2014.) - -(+) * (Jurko) Internal project development cleanup. -(+) * Re-implement the existing run_all_tests.cmd Windows batch script for -(+) running a full suds test suite on multiple Python versions in Python. -(+) * Read the list of target Python environments from the project's -(+) setup.cfg configuration file. -(+) * Make sure the prepared Python script runs using any of the suds -(+) project supported Python versions. -(+) * Add support for disabling testing a specific Python platform. -(+) * YAGNI for now. Can be done by commenting out appropriate -(+) environment definition sections in the main project 'setup.py' -(+) configuration file and will be affected later on by porting -(+) our testing system over to use the tox project. -(+) * Update HACKING.rst documentation. - -(14.06.2014.) - -(+) * (Jurko) Add basic suds.sax.element unit tests. - -(15.06.2014.) - -(+) * (Jurko) Add tests for suds.sax.element.Element string conversion. -(+) * (Jurko) Add tests for suds.sax.document.Document string conversion. -(+) * (Jurko) Fix suds.sax.document.Document str conversion bug. -(+) * (Jurko) Fix original suds project bug with suds.cache.DocumentCache not -(+) caching suds.sax.document.Document instances correctly, even though such -(+) instances get passed to it by the suds.reader.DocumentReader. -(+) * (Jurko) Fix problems with suds silently hiding plugin exceptions. -(+) * Add plugin unit testing module -(+) * Test that calling a plugin using PluginContainer passes any -(+) exceptions raised by the plugin. -(+) * Fix the PluginContained exception passing issue. -(+) * Close issue #42 at BitBucket. -(+) * Close pull request #33 at BitBucket. -(+) * (Jurko) Fix problem with decimal zero representations having a negative -(+) exponent, e.g. as it "0.0000". -(+) * Add tests. -(+) * Fix failing assert. -(+) * Close pull request #37. -(+) * Close issue #31. - -(23.06.2014.) - -(+) * (Jurko) Look at issue #49 at BitBucket - generated SOAP request containing -(+) a tag with a missing namespaces identifier. -(+) * Research. -(+) * Caused by incorrect XSD schema element form attribute handling -(+) when the element is actually just a reference to another top-level -(+) element. In such cases the the referenced and not the referencing -(+) element's form attribute value should be used. -(+) * Prepare a quick-fix plugin. -(+) * Report back to the BitBucket issue tracker. - -(24.06.2014.) - -(+) * (Jurko) SchemaObject.form_qualified cleanup. -(+) * Add tests for the schema element's form attribute handling. -(+) * Element with form attribute set to 'qualified'. -(+) * Schema with elementFormDefault set to 'qualified'. -(+) * Schema with elementFormDefault set to other than 'qualified'. -(+) * Schema with elementFormDefault unset. -(+) * Element with form attribute set to other than 'qualified'. -(+) * Schema with elementFormDefault set to 'qualified'. -(+) * Schema with elementFormDefault set to other than 'qualified'. -(+) * Schema with elementFormDefault unset. -(+) * Element with unset form attribute. -(+) * Schema with elementFormDefault set to 'qualified'. -(+) * Schema with elementFormDefault set to other than 'qualified'. -(+) * Schema with elementFormDefault unset. - -(26.06.2014.) - -(+) * (Jurko) Remove unnecessary 'history' list copying in -(+) suds.xsd.sxbase.SchemaObject.content(). -(+) * (Jurko) suds.xsd.deplist module cleanup. -(+) * Stylistic code & comment cleanup. -(+) * PEP8-ify. -(+) * Make pop() not ignore exceptions. -(+) * Make add() no longer return self. -(+) * Remove sorted member. -(+) * Order methods alphabetically. -(+) * Mark private operations & data as private. -(+) * Review the topological sort implementation. -(+) * `popped` list seems to be filled only for its elements to later be -(+) moved over to the `sorted` list. -(+) * Add topological sorting tests by extracting the existing embedded test -(+) into a stand-alone unit test module. -(+) * (Jurko) Look at BitBucket issue #50 - SOAP 1.2 compatibility. -(+) * (Jurko) Look at BitBucket issue #51 - complexType 'mixed' attribute. - -(27.06.2014.) - -(+) * (Jurko) suds.xsd.deplist module cleanup. -(+) * Reference cycle handling. -(+) * Research. -(+) * Document. -(+) * Test. -(+) * Review the topological sort implementation. -(+) * See if there is anything obvious to be made more efficient in it. -(+) * Simplify code by using a recursive implementation. -(+) * Refactor the DepList class into a single function dependency_sort() -(+) function taking a single dependency dictionary as input. -(+) * Refactor code. -(+) * Rename module to suds.xsd.depsort. -(+) * Update release notes. -(+) * DepList class replaced with a simple dependency_sort() function -(+) taking a single dependency dictionary as input. -(+) * The original implementation's interface was too heavy-weight -(+) with no added value. -(+) * Anything tried with the original interface outside the basic -(+) use-case covered by dependency_sort() was actually or could be -(+) easily broken. -(+) * suds.xsd.deplist module renamed to suds.xsd.depsort. -(+) * (Jurko) SchemaObject.form_qualified cleanup. -(+) * Add tests for the schema element's form attribute handling. -(+) * Reference elements. -(+) * Unqualified referencing qualified. -(+) * Referencing & referenced elements should have different -(+) namespaces. -(+) * Qualified referencing unqualified. - -(28.06.2014.) - -(+) * (Jurko) SchemaObject.form_qualified cleanup. -(+) * Fix detected issues. -(+) * Fix failing tests. -(+) * Mark tests as no longer expected to fail. -(+) * Update project release notes. -(+) * Report back to issue #49 on BitBucket. - -(29.06.2014.) - -(+) * (Jurko) SchemaObject.form_qualified cleanup followup. -(+) * Research the XSD specification on the element form attribute. -(+) * Correct suds's XSD element form attribute handling. -(+) * Reference elements are always qualified. -(+) * Top-level elements are always qualified. -(+) * Non-top-level non-reference elements are qualified based on their -(+) form attribute, and if they have no form attribute, their schema's -(+) elementFormDefault attribute is used instead, and if that one is -(+) not given either - they are considered unqualified. - -(30.06.2014.) - - * (Jurko) SchemaObject.form_qualified cleanup followup. - * Correct suds's XSD element form attribute handling. - * Qualified XSD elements are connected to a namespace. - * Unqualified XSD elements are not connected to any namespace. - * XML elements matching an unqualified XSD schema element do not - necessarily need to have no namespace specified. If their parent - element's default namespace is specified, then they still need to - explicitly specify their default namespace as an empty string. - * Test SOAP XML construction for qualified/unqualified elements with - and without the `prefix` suds option enabled. - * Document breaking changes between this fork and the original suds - project. - * DocumentStore interface changes. - * Choice support. - * SchemaObject.form_qualified should not have 'form_qualified'. That - seems like something related only to elements & attributes. - * SchemaObject.dependency() method seems too complicated - its interface - allows returning a list of dependencies, with a specific one amongst - them singled out as a dependency to be merged, when in fact it always - returns no dependencies or only a single dependency with that single - dependency to be merged. - * Rename to dereference() and have it return the referenced - SchemaObject - since that is in fact what this function already - does. - * SchemaObject.merge() is misnamed - it should be named - collect_referenced_data() since it is a completely different operation - from Schema.merge() and it actually only collects data from a - referenced object, if such an object exists. - * Look at issue #46 at BitBucket - form attribute on schema attributes - does not seem to be handled correctly. - * Schema 'attributeFormDefault' attribute handling. - * Schema attribute 'form' attribute handling. - - * (Jurko) Look at the Spyne project and its suds usage. - * Try running Spyne's test suite using the suds-jurko fork. - * Related links. - * 'https://spyne.ci.cloudbees.com/job/spyne/PYFLAV=2.7/ - lastCompletedBuild/testReport/spyne.test.interop.test_suds/ - TestSuds/'. - * 'https://github.com/arskom/spyne/blob/master/spyne/test/ - interop/test_suds.py'. - * Notes from the Spyne maintainer Burak Arslan. - * You can run Spyne tests against your suds locally. Just clone - the Spyne repo and edit setup.py to use suds-jurko instead of - suds here: - 'https://github.com/arskom/spyne/blob/master/setup.py#L344'. - * Send feedback back to the Spyne maintainer (burak.arslan at - arskom.com.tr). - * Try updating Spyne project test system so it can be easily configured - to use suds-jurko instead of the official suds release. - - * (Jurko) Try out virtualenv to make it easier to run tests using multiple - Python versions and to allow us to automate suds installation testing in - the future. - * Compatible virtualenv versions. - * virtualenv - 1.7.2 (last before 1.8) - last on Python 2.4. - * virtualenv - 1.9.1 (last before 1.10) - last on Python 2.5. - - * (Jurko) Internal project development cleanup. - * Prepare a full suds test suite subset that can be used for regular - development - select only a few platforms to test suds on regularly - and run the full test suite only 'when needed', e.g. before pushing - changes onto BitBucket or at the end of a single development session. - - * (Jurko) Add an XML comparison test utility supporting raw XML data - comparison with the following features. - * Important comparison features. - * How textual data is split between child elements. - * Child element ordering. - * Element/attribute namespace + name. - * Non-namespace declaration related attribute ordering. - * Unimportant comparison features. - * Leading/trailing textual data whitespace per line for mixed - content nodes containing at least one child element. - * Element/attribute namespace prefix. - * Namespace declaration related attribute ordering. - * Namespace declarations (no prefix). - * Namespace prefix declarations. - - * (Jurko) Add tests for the functionality potentially affected by a planned - _SoapClient/_SimClient refactoring. - * _SoapClient - currently can only be tested via suds.client.Client. - * 'prettyxml' option. - * 'retxml' option. - * _SimClient - currently can only be tested via suds.client.Client. - * Using Transport for sending an injected request. - * Not using Transport when a reply has been injected. - * _SimClient using injected request. - * _SimClient using injected reply. - * Success. - * Failure. - * Status & status description. - * 'nosend' option. - * With injected request data. - * With injected response data - ignored. - * 'retxml' option. - * 'prettyxml' option. - * RequestContext. - * Returned from _SoapClient. - * Returned from _SimClient. - * Processing an externally provided reply. - * Plugin processing. - * Variants. - * _SoapClient/_SimClient. - * _SimClient with injected reply/response. - * 'nosend' option + RequestContext reply. - * 'retxml'. - * 'prettyxml'. - * Fetched documents. - * document.loaded(url, bytes) --> bytes. - * document.parsed(url, document). - * Documents read from cache. - * document.parsed(url, document). - * Client initialized with WSDL. - * init.initialized(wsdl). - * SOAP requests. - * marshalled(document) - may modify document in-place. - * sending(bytes) --> bytes. - * SOAP replies. - * received(bytes) --> bytes. - * parsed(element) --> may modify document in-place. - * unmarshalled(result) --> result. - - * (Jurko) Refactor _SoapClient/_SimClient related code. - * Refactor. - * Already prepared as client_1.py on Jurko's notebook but need to - add relevant tests first. - * Test. - * _SoapClient subclasses modifying _init_invocation_context(), - _get_request() & _get_reply(). - * Update release notes. - * Client debug log messages changed. - * Removed the RequestContext.original_envelope attribute. - - * (Jurko) See why creating two suds.client.Client instances with the same - transport instance fails. It reports some 'Duplicate domain "suds.options" - found' error. - t = suds.transport.Transport() - tests.client_from_wsdl(tests.wsdl(""), transport=t) - tests.client_from_wsdl(tests.wsdl(""), transport=t) - - * (Jurko) Generic code cleanup. - * HttpTransport tests. - * Check for multiple build_opener() calls. - * Check for multiple urlopener.open() calls. - * Check what gets passed to the default built urlopener. Merge this - with externally specified urlopener testing. - * Add HttpTransport proxy configuration tests. - * See when the proxy member is set. - * See what the default proxy member value is for. - * See whether the proxy member is used at all with an externally - specified urlopener, and if so - if it is made redundant by using - such externally specified urlopeners. - * Add cachingpolicy option tests. - * Add default document store tests. - * Generic. - * suds.client.Client document store usage. - * See why exception raised when passing a transport to - suds.client.Client that is not a subclass of suds.transport.Transport - is formatted as it is. - * Class's string representation wrapped in a tuple. - * Uses class's repr() string representation. - * Double quotes used around the 'transport'. - * suds.store.defaultDocumentStore cleanup. - * See if this member should be marked as private. - * Rename to not use camelCase. - * DefinitionsReader.open() changes options on cached Definitions - instances. Make sure this does not break programs with multiple suds - Clients loading the same WSDL schema but using different options. - * Support for calling NoCache.purge() & NoCache.clear(). - * Consider making FileCache.clear() remove files matching both prefix & - suffix instead of only the prefix. - * Might be ok for explicitly called clears, but not for those called - due to the cache version information getting changed. This might - need to be worked around or commented/tested in code. - * Make FileCache, DocumentCache & ObjectCache all consistently remove or - not remove cache entries on failed access. Possibly do so for the base - Cache class as well. - * Make Cache.put() not return the cached data. - * FileCache.put() operations should not leave behind invalid files in - case of failed write operations. Possibly first store a valid file - under a temporary name and then rename it. - - * (Jurko) Restore last_sent()/last_received() getters for last used SOAP - request/response messages. - * Research. - * Difference between how _SoapClient & _SimClient stored their last - sent/received messages. - * Both stored them. - * _SimClient stored the simulated fault as its last received - message. - * Whether sent/received messages should be returned/logged before or - after being processed by registered plugins. - * _SoapClient stored the received reply after it got processed - by registered plugins. - * Sending with _SoapClient. - * Sending with _SimClient. - * Which plugins get called and when. - * Add back the removed code. - * Add tests. - * Notify people interested in this. - - * (Jurko) Clean up input argument/parameter & wrapped/unwrapped terminology - usage in code. - * Synchronize all usage both in code and in relevant 'notes/' documents. - - * (Jurko) Triage received issues & pull requests at BitBucket a bit and - prioritize them in relation to already existing todo items on this list. - - * (Jurko) Process Jurko's remaining research & todo notes collected while - working on reporting extra parameter errors. Some are redundant or have - already been dealt with so the list needs to be triaged first. - * Fix non-optional choice element handling - missing values should be - used as empty strings, same as for non-choice parameters - search for - tests xfailed with reason 'non-optional choice handling buggy'. - * Add tests: which type XSD schemas do not get unwrapped automatically, - e.g. simple types such as built-in type restrictions. - * Split up test_request_construction.py tests into parameter definition, - argument parsing & possibly partial binding specific request - construction tests. - * Add test: single parameter pointing to an element - parameter name - should be ignored. - * Add test: single parameter pointing to an element - with unwrapping. - * Add test: single parameter pointing to a type - with unwrapping. - * Add test: single parameter pointing to a built-in type - no - unwrapping. - * Add test: multiple parameters pointing to types & elements. - * Add tests: WSDL tests - XSD schema content. - * Add tests: WSDL tests - recognized operations. - * Add tests: WSDL tests - recognized services. - * Add test: document/literal, document/encoded, rpc/literal & - rpc/encoded should make no difference to input processing in theory - and should all recognize the same input parameter structure. - * Add tests: WSDL tests - recognized binding - input/output - for - different methods - document binding should be the default - see - whether literal should be the default binding style. - * Add test: named sequence/choice/all - there is no such thing - their - name attributes should be ignored. - * Research: consider input parameter elements with missing type - declarations to have the type "xsd:string" or "xsd:any" or something - similar - check the XSD specification. - * '' currently used - wrapped. - * ' ' currently used - unwrapped. - * Add test: unwrapped element reference input parameter. - * Add test: shema_object.resolve() & - shema_object.resolve(nobuiltin=True). - * Add test: explicitly marking an input parameter sequence as optional - should be recognized when unwrapping those input parameters - such - functions should report accepting 0 parameters. - * Add test: expected input argument count reporting with choice input - parameters explicitly marked optional. - * Add test: array parameters. - * Research: whether web service operations taking multiple input - parameter body-parts can have those body-parts simply reference other - elements, thus requiring us to resolve that reference before checking - whether the input parameter is optional (and possibly other places as - well - see Document.mkparam() which does no resolving for such web - service operations but does so for operations taking a single wrapper - input parameter structure). - * Research: see if the parameter type checked whether it is optional - inside Document.bodycontent() needs to have its ancestor elements - checked as well - this might be needed if this can actually be a - reference to some other, more deeply nested element. - * Research: can element references be chained - nope as they are allowed - to reference only top level elements and top level elements are - explicitly not allowed to use the ref attribute. - * Research: can element references be optional by themselves - yes, and - that is the only way they can be marked as optional since they may - only reference top-level elements and those are in turn not allowed to - use the minOccurs/maxOccurs attributes. - * Add test: extra array parameters - more than maxOccurs - possibly not - necessary if we want to allow suds to make such 'illegal' calls. - * Add test: missing regular parameters. - * Add test: missing non-optional choice parameters. - * Add test: missing optional choice parameters. - * Recognize missing optional values when specified as a lists/tuples - containing only values None and other such lists/tuples. - * Error when passed a list/tuple argument containing a list/tuple or - None. - * Research: web service operations taking multiple same-named parameters - - how they are and how they should be handled. - * Choice containing an empty sequence should be recognized as optional. - * Choice(a, sequence(b, c)) should set b to '' if it is not optional and - no value is given for it, but a value is given for c - same if b & c - roles are reversed. - * Research: suds does not seem to know how to handle minOccurs/maxOccurs - attributes specified on sequence & choice XSD schema XML elements - it - definitely does not recognize elements inside an optional choice or - sequence as optional - see how this affects input/output parameter - unwrapping. - * Add test: passing an array element value as an empty list. - * Add test: passing an array element value as a non-empty list. - * Add test: constructing requests with missing optional parameters - - should not be specified in the request. - * Add test: constructing requests with missing non-optional parameters - when the operation also takes some optional parameters - how this is - reported. - * Add test: constructing requests by using positional arguments when the - operation takes first optional input parameters and then non-optional - ones after that - initial positional arguments should be mapped to the - initial optional input parameters. - * Research: constructing requests with missing default parameters - see - whether this should be reported as an error or added to the request as - an empty value. - * Research: self.mkparam() call in Document.bodycontent() may return a - list in which case later setPrefix() method call on the returned - object will raise an AttributeError exception. - * Detecting and reporting multiple input parameter values specified for - a single input parameter choice group (empty choice group, simple - single choice, multiple independent choices, one choice group inside - another, one choice inside another but with additional elements - between them). - * Research: whether specifying an empty list or tuple for a parameter - should be treated the same as None - if so, add tests - possibly []/ - (,) really skips the parameter while None gets mapped to an empty - value for non-optional parameters.. - * Support for multiple same-named elements in a single input or output - structure - those directly back-to-back with each other can already be - set or accessed as arrays but we could need to support others as well. - * Constructing a request for a web service operation taking a single - empty all/choice/sequence parameter - should be the same as for - operations taking no parameters. - * Constructing requests for web service operations taking multiple - choice parameter groups (as positional and keyword arguments). - * Using a function with multiple choice parameter group values. - * TestExtraParameters.test_function_with_no_parameters() - why does - using WSDL '' not work - seems not to be - recognized as wrapped data but if the XML element has any data (e.g. a - space or a new-line) then it gets recognized correctly - smells like - this could be a bug. - * Web service operation taking multiple input parameter bodyparts. - * None of which is an empty sequence. - * At least one of which is an empty sequence. - * Unrelated issues noticed while working on this. - * Document.document() - returned temporary can be inlined. - * Core.process() - root local variable seems redundant. - * Document.bodycontent() - mkparam() does not seem to be able to - return None but if it does, it might mess up tracking which - argument got used and we should document when it does that. - * Parsing parameter values (interpreting positional & keyword - arguments, mapping them to internal web service operation - parameters, reporting duplicate parameter values, reporting - unrecognized parameters and skipping ignored or None choice item - parameters) should not be binding class specific, i.e. it should - be shared for both document & rpc bindings. - - * Code cleanup - * It seems suds ignores top-level element names & namespaces when - parsing server responses and instead just uses them by their index. - This seems wrong. Check the WSDL specification, SOAP message binding - and other related standards to see if the server must always return - its values in the correct order in which the corresponding output - message parts are defined in the WSDL. Plan updating suds to report - invalid server responses. - * Replace except: blocks with blocks catching specific exception types. - * suds.xsd.schema module imports suds.xsd.sxbuiltin.Factory as - BuiltinFactory but never used that reference. See if this interface is - perhaps documented as published and if not - remove it. - * Performance tuning - SchemaObject.str() should not use len(self) to - check whether it is empty. - * SchemaObject.str() - see whether any contained item information is - included if none of the items are instances of Content. - * TypedContent.qref() - see whether len(self) == 0 check for 'simple - types' can be improved. There should be no need to calculate the whole - length just to determine that the object is empty. - * Simple.mixed(), SimpleContent.mixed() - see if they really need to - return the current object length or if they can just check whether the - object is empty. - * suds.sudsobject.footprint() - see if the len() check is really needed - just to see if the object is empty. - * Check other len() usage in suds.sudsobject. - * Check all 'except:' blocks to see if they actually need to be such - catch-all blocks. - - * (Jurko) Look into issues #7 & #13 on BitBucket - problems loading a WSDL - containing a recursively defined XML schema. - -NON PRIORITIZED: -================================================= - - * suds.sudsobject.footprint() does some fancy recursive counting while all - it is actually used for is for detecting objects with footprint 0. This - could be optimized by replacing it with a function returning simply - whether a given object has a non-empty footprint and returning as soon as - it find something of value in it. - - * Add suds.sax.element related tests. - * append(). - * Add child element. - * Add child attribute. - * childAtPath(). - * With namespaces. - * With prefixes. - * Empty child name - as initial child - requested. - * Empty child name - as initial child - pass through. - * Empty child name - as indirect child - requested. - * Empty child name - as indirect child - pass through. - * Handling multiple children with matching names - is there a way to - specify an index. - * Add child by constructing it with a parent argument - should - automatically add the element to the parent's children list, while the - current implementation only makes the child know about the parent and - does not let the parent know about the child. - * Constructing an element with '/' in its name should not be allowed - since that character is used as a part separator. - * See if a way to escape such character usage is needed and if so - - how to do it. - * Handling multiple children with matching names. - * childrenAtPath(). - * Initializing a new element with a specific namespace. - - * Add suds.sax.document unit tests similar to those already added for - suds.sax.element. - * Some ideas on what to not forget. - * See suds.sax.element related tests & todo notes. - * childAtPath(). - * childrenAtPath(). - * No root element. - - * Look into CDATA related encoding issues reported at BitBucket (issue #14 + - pull requests #25 & #26). - * Current status: waiting for further feedback or progress on BitBucket. - * Implement a working solution satisfying the prepared tests. - * Use the prepared profiling script to make sure this change does - not degrade general suds performance. - * Get more feedback on a seemingly bad 'embedded CDATA section' test - included in the pull request #26 on BitBucket. - * Support for nested CDATA sections, in violation of the CDATA - related documentation found at - 'http://en.wikipedia.org/wiki/CDATA#Nesting' and - 'http://www.w3.org/TR/REC-xml/#sec-cdata-sect'. - * Decide how unclosed CDATA sections should be handled. - * Suggestion: raise an exception since this is not allowed in well - formed XML documents. - - * Resolving XSD schema elements currently returns an XSD schema type object - representing the element's type. Different elements with matching types - should possibly resolve to the same XSD schema type object but currently - do not. See if this behaviour should be corrected. - * Example. - * XSD schema: - - - * Test code: - schema = client.wsdl.schema - element_in = schema.elements["wi", "my-namespace"] - element_out = schema.elements["wo", "my-namespace"] - assert element_in.resolve() is element_out.resolve() - * Both elements should possibly resolve to the same XString - instance, but currently they resolve to two separate ones. - - * Optionally make suds check that the input parameters passed to its web - service proxy operations actually match their respective WSDL definitions. - * Current suds behaviour. - * Extra parameters are ignored. - * Parameters of invalid type are simply added into the generated - SOAP request as strings and left up to the web service - implementation to deal with and report as an error if the - constructed SOAP request turns out to be invalid. - * Having a local client-side check could make catching client side - programming bugs easier. - * Ideas. - * Make sure given values fit their respective type value domains, - e.g. integers, strings, regular expressions, restrictions, complex - types where a builtin was expected, complex type of an unexpected - structure, etc. - * Extra parameters are reported as errors. - * Missing non-optional parameters are reported as errors. - * Input message part has both element & type specified. - - * See how invalid schemas containing a ref-cycle are handled. - * They should be reported as invalid either when dereferencing them - (e.g. to determine an element's target namespace) or when building the - internal schema object tree and should not cause us to go into endless - recursion. - - * See how multi-occurrence input parameter elements are supposed to be - supported. - * With automated parameter unwrapping support. - * Without automated parameter unwrapping support. - - * Clean up & correct the choice support implementation. - * Choice parameters seem to be supported only for document/literal style - input parameters only. - * Add tests for this. - * Fix. - * See the currently disabled - 'xxxtest_choice_parameter_implementation_inconsistencies' unit test - demonstrating a problem with the current implementation. - - * _SoapClient 'location' cleanup. - * URL quoting, especially if specified externally by the caller instead - of having been read from a valid WSDL schema. - - * See how input parameter element for a document/literal web service - operation style gets handled when that element has 2 occurrences. - * See how this affects suds library's automated input data unwrapping. - * See how this sort of data is supposed to be entered anyway. - - * FileCache class fixes. - * Remove incorrectly created cache files, e.g. if one gets created but - then writing to it fails. - * Make sure reading a cache file does not crash the whole Python - interpreter process. - * Encountered when trying to read an empty cache file using a debug - Python version 3.2.3 on Windows 7 - triggered an internal Python - assertion failure. - - * Look into the 'suds.null' class. - * Research. - * See sources (grep for 'null'), old release notes (README.txt) and - commit messages. - * What it is for. - * Whether it can be replaced with None. - * If it serves some purpose see if it should be used for identifying - missing 'choice' structure members as well. - - * Make it simpler to run Py3 tests. - * Current status. - * May be run without additional pytest options by running 'setup.py - test' from the root project folder. - * This method will automatically download & install pytest from - PyPI if needed, but will leave their installations behind in - the project's root folder. - * May be run by first building the project by installing the - project, e.g. by running 'setup.py develop' and then running - 'pytest' from the project's 'tests' folder. - * Do some more thinking on this and, when done, update related HACKING - notes. - - * Generate suds Python library documentation (epydoc). - * Research. - * HTML. - * PDF. - * Decide how to maintain, generate & distribute this documentation. - * Update project HACKING notes to note the external software required - for generating the documentation. - * Update release procedure to include releasing the documentation. - * Once the official project documentation has been integrated into this - fork, go through existing internal project notes in our fork and see - how to integrate them into the official project documentation. - - * Research. - * Test how optional elements under a choice work. - * There are some comments & an additional patch related to this at - 'https://fedorahosted.org/suds/ticket/342'. - * Default element values. - * What they actually mean. - * From from 'http://www.w3.org/TR/xmlschema-0'. - * If the element does not appear it is not provided; if it - does appear and it is empty, its value is the specified - default value; otherwise its value is that given. - * How elements with default values inside a choice structure should - be handled. - * See what the suds.sudsobjects.Facade class is for. - * How to implement test cases requiring a test web service. - * See how to connect to a web service via a Proxy server requiring NTLM - authentication. - * There are some projects seen on the net implementing a NTLM - authentication handler for urllib. - * Testing this will require implementing a proxy server requiring - NTLM authentication and a web service or at least a web service - requiring NTLM authentication. - * Using pylint. - - * Implement an urllib connection handler allowing connecting using HTTPS - with client authentication. - * Prepare a test (will require a test web service). - * Implement. - - * Prepare additional test cases. - * Loading a WSDL from a file as in suds.client.Client( - "file://localhost/Folder/aaa.wsdl"). - * Path not containing spaces. - * Path containing spaces. - * Invalid element reference. - * Handing schema imports. - * With the same target namespace. - * With a different target namespace. - * Prepared SOAP operation invocation requests. - * With choice parameters. - * Calling a web service operation with no parameters. - * RPC binding style. - * Document binding style. - - * Process ideas collected from external projects using suds. - * Alternative choice implementation that would not automatically expand - all choice function parameters but instead take some more generic - 'choice' object parameter. - * This object would then know which of its data members is - 'currently specified'. - * See whether the Marshaller class should know about choice elements and - not add XML nodes for elements with the value 'None' if they are - contained directly inside a choice. - * For some more background information on this see Marshaller - related release notes & commit messages inherited from the - original 'suds' development project. - * See if the class 'suds.xsd.sxbasic.Complex' function sequence() should - return True if its only child is a sequence node. - * Typo corrections for the original project web site. - * 'docuemnt' --> 'document'. - * 'becuase' --> 'because'. - - * See whether standard and/or suds supports specifying message part - parameter element directly from an external schema. - * For example, 'integer' or 'string' elements defined in the - 'http://schemas.xmlsoap.org/soap/encoding/' namespace (stored - internally by suds in the store.py module). - - * See whether importing an external WSDL schema can benefit from that - schema's WSDL object already being cached. - * See if this has already been implemented, and if not - implement it. - - * Additional test ideas. - * External XSD usage (including both imported and included external XSD - schemas). - * All the different external XSD usage tests should be run in - scenarios when the external XSD gets used from an imported WSDL. - * Using an external XSD schema using another external XSD schema. - * Test pluggable sax character reference encoder support. - * Have tests plug in a custom character reference encoder and try it - out. - - * A HttpTransport.send() operation will return None if the web service - server responds with HTTP status code ACCEPTED (202) or NO_CONTENT (204), - but the _SoapClient method using this operation is not prepared to handle - this and will attempt to access the 'message' member on the returned - value. - * Failing tests have already been added for this. - * Alternative ideas on how to fix this. - * Continue returning None in these cases and fix up the calling - code. - * Raise a separate exception. - * Wrap this information in a regular suds.transport.Reply instance. - * Possibly handle this differently based based on whether the web - service operation invoked has any defined output message parts. - - * 'soapheaders' suds option usage cleanup. - * Add tests. - * SOAP headers given as a list/tuple. - * Strings. - * Elements. - * Initial. - * Middle. - * Last. - * Multiple. - * SOAP headers given as a dictionary. - * Strings. - * Elements - error. - * Unknown header handling. - * Too many when given as list/tuple. - * Unknown key when given as dictionary. - * Plugins modifying SOAP header elements should not affect future - requests constructed using those same headers. - * Note that Elements found in the soapheaders option need to be copied - into each request so any plugins updating that request's content would - not update the original SOAP header elements and thus affect all - future requests constructed using those same SOAP headers. - * Fix bug: Elements added to a soapheaders list before all expected - headers have been added, but later ones are ignored. - * Raise an exception in case of an unrecognized header. - * Unrecognized header name in a dictionary. - * Too many non-Element headers in a list/tuple. - * Better document the 'soapheaders' suds option. - * At first glance it seems suds does not use reply headers the same as - it does its request headers. See if SOAP web service HTTP bindings - allow output headers at all, and if so, how suds should support this. - * See if header elements can be marked as required, and if so, see if - suds should report an error if a required header value has not been - provided. - * See if header elements can be marked as optional and how suds should - handle this. - * See if header elements can have multiple occurrences, and if so, how - suds should support them. - * See how header values can be specified more easily for a single method - invocation. - - * See if input message parts defined using the 'type' attribute (as opposed - to those marked using the 'element' attribute) respect their optional/ - required status. PartElement class used to model such part's element - information seems to always return True from its optional() method. - * If this is wrong - add a test demonstrating the problem. - * If this is correct - see what the suspicious optional() method is for. - - * Look at suds.sax.element.Element.insert() - its documentation says it - accepts either an element or an attribute or a collection of elements or - attributes and adds it/them as a child/children under the current element. - * From glancing through the code it does not seem to work when passed a - collection of elements or attributes. - * Most likely it needs a check whether the passed objects parameter - is a list or a tuple before it wraps it inside a tuple. - * From glancing through the code it does not seems to work when passed - an Attribute. - * See what to do about this - either update the related function - documentation or update it to work as documented. - * See how similar functionality has been implemented in - suds.sax.element.Element.append(). - - * Look at suds.sax.element.Element.childAtPath() and see whether it should - return None or self if given an empty string or a string consisting only - of slashes. - * Currently it returns None in this case as if the given path could not - be found. - * Returning self or raising an exception seems consistent with the fact - that a non-empty path is interpreted relative to self. - - * suds.sax.element.Element.__childrenAtPath() seems smelly. See how it can - be simplified and made to work for paths not containing slashes as well as - those containing slashes. - * This should simplify the suds.sax.element.Element.childrenAtPath() - implementation as well. - - * suds.sax parser peculiarities to look into. - * Handling mixed content elements, i.e. those that have both child - elements and textual content. - * All the textual content is concatenated into a single string, - independent of how it distributed between child elements in the - original parsed XML string. - * As a consequence, converting the parsed XML document back into - an XML string will place all the element's textual content - before its child elements. - * The textual content has its whitespace trimmed. - * Note that this causes the ' 42 42 ' XML to - be parsed so that element's textual data is: '42 42' - where the whitespace outside the '42' markers is trimmed but - the whitespace between them is preserved. - - * See if we should make sure any plugin exceptions get logged correctly (as - was the case when suds.plugin.Method.__call__() was eating up all such - exception in the original suds project). - - * The original suds project's DocumentCache.put() implementation accepted - suds.sax.element.Element instances as input so we kept this behaviour for - now but that might have actually been a result of a bug. We should review - this and update related tests & implementation if we no longer wish to - support this. - * See the TestDocumentCache.test_cache_element() test in - 'test_sax_element.py'. - - * Improve the XML comparison test utilities. - * Add test utility tests. - * Make SAX comparison compare XML attributes - order is irrelevant. - * Support for comparing two XML data strings in more detail, with - explicitly enabling/disabling which differences to consider important. - * Some ideas on what might or might not be considered important. - * Leading/trailing textual data whitespace. - * Per element. - * Per block between child elements. - * Per input line. - * All whitespace blocks considered equivalent. - * Possibly consider leading/trailing textual data whitespace - unimportant only inside mixed content nodes containing at - least one child element. - * How a mixed content node's textual content is split between - its child elements. - * Attribute declaration order. - * Child element ordering. - * Namespace declarations (no prefix). - * Namespace prefix declarations. - * External references - to parse them or not. - * Extra elements on either side. - * XML node namespace prefixes. - * XML node namespaces. - * Input code-page. - * Extra data. - * Before XML. - * Surrounding top level XML nodes. - * Each feature importance might be enabled/disabled globally or - for a specific XML part only. - - * Add SOAP 1.2 support. - * Related links. - * Project's issue #50 on the BitBucket issue tracker: - https://bitbucket.org/jurko/suds/issue/50#comment-10940316 - * http://stackoverflow.com/questions/2370573/soap-1-2-python-client - - * Add support for the `mixed` attribute on `complexType` XSD schema - elements. - * They should allow the use of textual data, possibly in addition to - other child elements & attributes. - * Related link: - https://bitbucket.org/jurko/suds/issue/51#comment-10941116 diff --git a/ez_setup.py b/ez_setup.py deleted file mode 100644 index 10d299bf..00000000 --- a/ez_setup.py +++ /dev/null @@ -1,332 +0,0 @@ -#!/usr/bin/env python -"""Bootstrap setuptools installation - -To use setuptools in your package's setup.py, include this -file in the same directory and add this to the top of your setup.py:: - - from ez_setup import use_setuptools - use_setuptools() - -To require a specific version of setuptools, set a download -mirror, or use an alternate download directory, simply supply -the appropriate options to ``use_setuptools()``. - -This file can also be run as a script to install or upgrade setuptools. -""" -import os -import shutil -import sys -import tempfile -import zipfile -import optparse -import subprocess -import platform -import textwrap -import contextlib - -from distutils import log - -try: - from urllib.request import urlopen -except ImportError: - from urllib2 import urlopen - -try: - from site import USER_SITE -except ImportError: - USER_SITE = None - -DEFAULT_VERSION = "5.1" -DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/" - -def _python_cmd(*args): - """ - Return True if the command succeeded. - """ - args = (sys.executable,) + args - return subprocess.call(args) == 0 - - -def _install(archive_filename, install_args=()): - with archive_context(archive_filename): - # installing - log.warn('Installing Setuptools') - if not _python_cmd('setup.py', 'install', *install_args): - log.warn('Something went wrong during the installation.') - log.warn('See the error message above.') - # exitcode will be 2 - return 2 - - -def _build_egg(egg, archive_filename, to_dir): - with archive_context(archive_filename): - # building an egg - log.warn('Building a Setuptools egg in %s', to_dir) - _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) - # returning the result - log.warn(egg) - if not os.path.exists(egg): - raise IOError('Could not build the egg.') - - -class ContextualZipFile(zipfile.ZipFile): - """ - Supplement ZipFile class to support context manager for Python 2.6 - """ - - def __enter__(self): - return self - - def __exit__(self, type, value, traceback): - self.close() - - def __new__(cls, *args, **kwargs): - """ - Construct a ZipFile or ContextualZipFile as appropriate - """ - if hasattr(zipfile.ZipFile, '__exit__'): - return zipfile.ZipFile(*args, **kwargs) - return super(ContextualZipFile, cls).__new__(cls) - - -@contextlib.contextmanager -def archive_context(filename): - # extracting the archive - tmpdir = tempfile.mkdtemp() - log.warn('Extracting in %s', tmpdir) - old_wd = os.getcwd() - try: - os.chdir(tmpdir) - with ContextualZipFile(filename) as archive: - archive.extractall() - - # going in the directory - subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) - os.chdir(subdir) - log.warn('Now working in %s', subdir) - yield - - finally: - os.chdir(old_wd) - shutil.rmtree(tmpdir) - - -def _do_download(version, download_base, to_dir, download_delay): - egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg' - % (version, sys.version_info[0], sys.version_info[1])) - if not os.path.exists(egg): - archive = download_setuptools(version, download_base, - to_dir, download_delay) - _build_egg(egg, archive, to_dir) - sys.path.insert(0, egg) - - # Remove previously-imported pkg_resources if present (see - # https://bitbucket.org/pypa/setuptools/pull-request/7/ for details). - if 'pkg_resources' in sys.modules: - del sys.modules['pkg_resources'] - - import setuptools - setuptools.bootstrap_install_from = egg - - -def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, - to_dir=os.curdir, download_delay=15): - to_dir = os.path.abspath(to_dir) - rep_modules = 'pkg_resources', 'setuptools' - imported = set(sys.modules).intersection(rep_modules) - try: - import pkg_resources - except ImportError: - return _do_download(version, download_base, to_dir, download_delay) - try: - pkg_resources.require("setuptools>=" + version) - return - except pkg_resources.DistributionNotFound: - return _do_download(version, download_base, to_dir, download_delay) - except pkg_resources.VersionConflict as VC_err: - if imported: - msg = textwrap.dedent(""" - The required version of setuptools (>={version}) is not available, - and can't be installed while this script is running. Please - install a more recent version first, using - 'easy_install -U setuptools'. - - (Currently using {VC_err.args[0]!r}) - """).format(VC_err=VC_err, version=version) - sys.stderr.write(msg) - sys.exit(2) - - # otherwise, reload ok - del pkg_resources, sys.modules['pkg_resources'] - return _do_download(version, download_base, to_dir, download_delay) - -def _clean_check(cmd, target): - """ - Run the command to download target. If the command fails, clean up before - re-raising the error. - """ - try: - subprocess.check_call(cmd) - except subprocess.CalledProcessError: - if os.access(target, os.F_OK): - os.unlink(target) - raise - -def download_file_powershell(url, target): - """ - Download the file at url to target using Powershell (which will validate - trust). Raise an exception if the command cannot complete. - """ - target = os.path.abspath(target) - ps_cmd = ( - "[System.Net.WebRequest]::DefaultWebProxy.Credentials = " - "[System.Net.CredentialCache]::DefaultCredentials; " - "(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)" - % vars() - ) - cmd = [ - 'powershell', - '-Command', - ps_cmd, - ] - _clean_check(cmd, target) - -def has_powershell(): - if platform.system() != 'Windows': - return False - cmd = ['powershell', '-Command', 'echo test'] - with open(os.path.devnull, 'wb') as devnull: - try: - subprocess.check_call(cmd, stdout=devnull, stderr=devnull) - except Exception: - return False - return True - -download_file_powershell.viable = has_powershell - -def download_file_curl(url, target): - cmd = ['curl', url, '--silent', '--output', target] - _clean_check(cmd, target) - -def has_curl(): - cmd = ['curl', '--version'] - with open(os.path.devnull, 'wb') as devnull: - try: - subprocess.check_call(cmd, stdout=devnull, stderr=devnull) - except Exception: - return False - return True - -download_file_curl.viable = has_curl - -def download_file_wget(url, target): - cmd = ['wget', url, '--quiet', '--output-document', target] - _clean_check(cmd, target) - -def has_wget(): - cmd = ['wget', '--version'] - with open(os.path.devnull, 'wb') as devnull: - try: - subprocess.check_call(cmd, stdout=devnull, stderr=devnull) - except Exception: - return False - return True - -download_file_wget.viable = has_wget - -def download_file_insecure(url, target): - """ - Use Python to download the file, even though it cannot authenticate the - connection. - """ - src = urlopen(url) - try: - # Read all the data in one block. - data = src.read() - finally: - src.close() - - # Write all the data in one block to avoid creating a partial file. - with open(target, "wb") as dst: - dst.write(data) - -download_file_insecure.viable = lambda: True - -def get_best_downloader(): - downloaders = ( - download_file_powershell, - download_file_curl, - download_file_wget, - download_file_insecure, - ) - viable_downloaders = (dl for dl in downloaders if dl.viable()) - return next(viable_downloaders, None) - -def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, - to_dir=os.curdir, delay=15, downloader_factory=get_best_downloader): - """ - Download setuptools from a specified location and return its filename - - `version` should be a valid setuptools version number that is available - as an egg for download under the `download_base` URL (which should end - with a '/'). `to_dir` is the directory where the egg will be downloaded. - `delay` is the number of seconds to pause before an actual download - attempt. - - ``downloader_factory`` should be a function taking no arguments and - returning a function for downloading a URL to a target. - """ - # making sure we use the absolute path - to_dir = os.path.abspath(to_dir) - zip_name = "setuptools-%s.zip" % version - url = download_base + zip_name - saveto = os.path.join(to_dir, zip_name) - if not os.path.exists(saveto): # Avoid repeated downloads - log.warn("Downloading %s", url) - downloader = downloader_factory() - downloader(url, saveto) - return os.path.realpath(saveto) - -def _build_install_args(options): - """ - Build the arguments to 'python setup.py install' on the setuptools package - """ - return ['--user'] if options.user_install else [] - -def _parse_args(): - """ - Parse the command line for options - """ - parser = optparse.OptionParser() - parser.add_option( - '--user', dest='user_install', action='store_true', default=False, - help='install in user site package (requires Python 2.6 or later)') - parser.add_option( - '--download-base', dest='download_base', metavar="URL", - default=DEFAULT_URL, - help='alternative URL from where to download the setuptools package') - parser.add_option( - '--insecure', dest='downloader_factory', action='store_const', - const=lambda: download_file_insecure, default=get_best_downloader, - help='Use internal, non-validating downloader' - ) - parser.add_option( - '--version', help="Specify which version to download", - default=DEFAULT_VERSION, - ) - options, args = parser.parse_args() - # positional arguments are ignored - return options - -def main(): - """Install or upgrade setuptools and EasyInstall""" - options = _parse_args() - archive = download_setuptools( - version=options.version, - download_base=options.download_base, - downloader_factory=options.downloader_factory, - ) - return _install(archive, _build_install_args(options)) - -if __name__ == '__main__': - sys.exit(main()) diff --git a/ez_setup_1_4_2.py b/ez_setup_1_4_2.py deleted file mode 100644 index ba4c246b..00000000 --- a/ez_setup_1_4_2.py +++ /dev/null @@ -1,388 +0,0 @@ -#!python -"""Bootstrap setuptools installation - -If you want to use setuptools in your package's setup.py, just include this -file in the same directory with it, and add this to the top of your setup.py:: - - from ez_setup import use_setuptools - use_setuptools() - -If you want to require a specific version of setuptools, set a download -mirror, or use an alternate download directory, you can do so by supplying -the appropriate options to ``use_setuptools()``. - -This file can also be run as a script to install or upgrade setuptools. -""" -import os -import shutil -import sys -import tempfile -import tarfile -import optparse -import subprocess -import platform - -from distutils import log - -try: - from site import USER_SITE -except ImportError: - USER_SITE = None - -DEFAULT_VERSION = "1.4.2" -DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/" - -def _python_cmd(*args): - args = (sys.executable,) + args - return subprocess.call(args) == 0 - -def _check_call_py24(cmd, *args, **kwargs): - res = subprocess.call(cmd, *args, **kwargs) - class CalledProcessError(Exception): - pass - if not res == 0: - msg = "Command '%s' return non-zero exit status %d" % (cmd, res) - raise CalledProcessError(msg) -vars(subprocess).setdefault('check_call', _check_call_py24) - -def _install(tarball, install_args=()): - # extracting the tarball - tmpdir = tempfile.mkdtemp() - log.warn('Extracting in %s', tmpdir) - old_wd = os.getcwd() - try: - os.chdir(tmpdir) - tar = tarfile.open(tarball) - _extractall(tar) - tar.close() - - # going in the directory - subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) - os.chdir(subdir) - log.warn('Now working in %s', subdir) - - # installing - log.warn('Installing Setuptools') - if not _python_cmd('setup.py', 'install', *install_args): - log.warn('Something went wrong during the installation.') - log.warn('See the error message above.') - # exitcode will be 2 - return 2 - finally: - os.chdir(old_wd) - shutil.rmtree(tmpdir) - - -def _build_egg(egg, tarball, to_dir): - # extracting the tarball - tmpdir = tempfile.mkdtemp() - log.warn('Extracting in %s', tmpdir) - old_wd = os.getcwd() - try: - os.chdir(tmpdir) - tar = tarfile.open(tarball) - _extractall(tar) - tar.close() - - # going in the directory - subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) - os.chdir(subdir) - log.warn('Now working in %s', subdir) - - # building an egg - log.warn('Building a Setuptools egg in %s', to_dir) - _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) - - finally: - os.chdir(old_wd) - shutil.rmtree(tmpdir) - # returning the result - log.warn(egg) - if not os.path.exists(egg): - raise IOError('Could not build the egg.') - - -def _do_download(version, download_base, to_dir, download_delay): - egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg' - % (version, sys.version_info[0], sys.version_info[1])) - if not os.path.exists(egg): - tarball = download_setuptools(version, download_base, - to_dir, download_delay) - _build_egg(egg, tarball, to_dir) - sys.path.insert(0, egg) - - # Remove previously-imported pkg_resources if present (see - # https://bitbucket.org/pypa/setuptools/pull-request/7/ for details). - if 'pkg_resources' in sys.modules: - del sys.modules['pkg_resources'] - - import setuptools - setuptools.bootstrap_install_from = egg - - -def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, - to_dir=os.curdir, download_delay=15): - # making sure we use the absolute path - to_dir = os.path.abspath(to_dir) - was_imported = 'pkg_resources' in sys.modules or \ - 'setuptools' in sys.modules - try: - import pkg_resources - except ImportError: - return _do_download(version, download_base, to_dir, download_delay) - try: - pkg_resources.require("setuptools>=" + version) - return - except pkg_resources.VersionConflict: - e = sys.exc_info()[1] - if was_imported: - sys.stderr.write( - "The required version of setuptools (>=%s) is not available,\n" - "and can't be installed while this script is running. Please\n" - "install a more recent version first, using\n" - "'easy_install -U setuptools'." - "\n\n(Currently using %r)\n" % (version, e.args[0])) - sys.exit(2) - else: - del pkg_resources, sys.modules['pkg_resources'] # reload ok - return _do_download(version, download_base, to_dir, - download_delay) - except pkg_resources.DistributionNotFound: - return _do_download(version, download_base, to_dir, - download_delay) - -def _clean_check(cmd, target): - """ - Run the command to download target. If the command fails, clean up before - re-raising the error. - """ - try: - subprocess.check_call(cmd) - except subprocess.CalledProcessError: - if os.access(target, os.F_OK): - os.unlink(target) - raise - -def download_file_powershell(url, target): - """ - Download the file at url to target using Powershell (which will validate - trust). Raise an exception if the command cannot complete. - """ - target = os.path.abspath(target) - cmd = [ - 'powershell', - '-Command', - "(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)" % vars(), - ] - _clean_check(cmd, target) - -def has_powershell(): - if platform.system() != 'Windows': - return False - cmd = ['powershell', '-Command', 'echo test'] - devnull = open(os.path.devnull, 'wb') - try: - try: - subprocess.check_call(cmd, stdout=devnull, stderr=devnull) - except (KeyboardInterrupt, SystemExit): - raise - except Exception: - return False - finally: - devnull.close() - return True - -download_file_powershell.viable = has_powershell - -def download_file_curl(url, target): - cmd = ['curl', url, '--silent', '--output', target] - _clean_check(cmd, target) - -def has_curl(): - cmd = ['curl', '--version'] - devnull = open(os.path.devnull, 'wb') - try: - try: - subprocess.check_call(cmd, stdout=devnull, stderr=devnull) - except (KeyboardInterrupt, SystemExit): - raise - except Exception: - return False - finally: - devnull.close() - return True - -download_file_curl.viable = has_curl - -def download_file_wget(url, target): - cmd = ['wget', url, '--quiet', '--output-document', target] - _clean_check(cmd, target) - -def has_wget(): - cmd = ['wget', '--version'] - devnull = open(os.path.devnull, 'wb') - try: - try: - subprocess.check_call(cmd, stdout=devnull, stderr=devnull) - except (KeyboardInterrupt, SystemExit): - raise - except Exception: - return False - finally: - devnull.close() - return True - -download_file_wget.viable = has_wget - -def download_file_insecure(url, target): - """ - Use Python to download the file, even though it cannot authenticate the - connection. - """ - try: - from urllib.request import urlopen - except ImportError: - from urllib2 import urlopen - src = dst = None - try: - src = urlopen(url) - # Read/write all in one block, so we don't create a corrupt file - # if the download is interrupted. - data = src.read() - dst = open(target, "wb") - dst.write(data) - finally: - if src: - src.close() - if dst: - dst.close() - -download_file_insecure.viable = lambda: True - -def get_best_downloader(): - downloaders = [ - download_file_powershell, - download_file_curl, - download_file_wget, - download_file_insecure, - ] - - for dl in downloaders: - if dl.viable(): - return dl - -def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, - to_dir=os.curdir, delay=15, - downloader_factory=get_best_downloader): - """Download setuptools from a specified location and return its filename - - `version` should be a valid setuptools version number that is available - as an egg for download under the `download_base` URL (which should end - with a '/'). `to_dir` is the directory where the egg will be downloaded. - `delay` is the number of seconds to pause before an actual download - attempt. - - ``downloader_factory`` should be a function taking no arguments and - returning a function for downloading a URL to a target. - """ - # making sure we use the absolute path - to_dir = os.path.abspath(to_dir) - tgz_name = "setuptools-%s.tar.gz" % version - url = download_base + tgz_name - saveto = os.path.join(to_dir, tgz_name) - if not os.path.exists(saveto): # Avoid repeated downloads - log.warn("Downloading %s", url) - downloader = downloader_factory() - downloader(url, saveto) - return os.path.realpath(saveto) - - -def _extractall(self, path=".", members=None): - """Extract all members from the archive to the current working - directory and set owner, modification time and permissions on - directories afterwards. `path' specifies a different directory - to extract to. `members' is optional and must be a subset of the - list returned by getmembers(). - """ - import copy - import operator - from tarfile import ExtractError - directories = [] - - if members is None: - members = self - - for tarinfo in members: - if tarinfo.isdir(): - # Extract directories with a safe mode. - directories.append(tarinfo) - tarinfo = copy.copy(tarinfo) - tarinfo.mode = 448 # decimal for oct 0700 - self.extract(tarinfo, path) - - # Reverse sort directories. - if sys.version_info < (2, 4): - def sorter(dir1, dir2): - return cmp(dir1.name, dir2.name) - directories.sort(sorter) - directories.reverse() - else: - directories.sort(key=operator.attrgetter('name'), reverse=True) - - # Set correct owner, mtime and filemode on directories. - for tarinfo in directories: - dirpath = os.path.join(path, tarinfo.name) - try: - self.chown(tarinfo, dirpath) - self.utime(tarinfo, dirpath) - self.chmod(tarinfo, dirpath) - except ExtractError: - e = sys.exc_info()[1] - if self.errorlevel > 1: - raise - else: - self._dbg(1, "tarfile: %s" % e) - - -def _build_install_args(options): - """ - Build the arguments to 'python setup.py install' on the setuptools package - """ - install_args = [] - if options.user_install: - if sys.version_info < (2, 6): - log.warn("--user requires Python 2.6 or later") - raise SystemExit(1) - install_args.append('--user') - return install_args - -def _parse_args(): - """ - Parse the command line for options - """ - parser = optparse.OptionParser() - parser.add_option( - '--user', dest='user_install', action='store_true', default=False, - help='install in user site package (requires Python 2.6 or later)') - parser.add_option( - '--download-base', dest='download_base', metavar="URL", - default=DEFAULT_URL, - help='alternative URL from where to download the setuptools package') - parser.add_option( - '--insecure', dest='downloader_factory', action='store_const', - const=lambda: download_file_insecure, default=get_best_downloader, - help='Use internal, non-validating downloader' - ) - options, args = parser.parse_args() - # positional arguments are ignored - return options - -def main(version=DEFAULT_VERSION): - """Install or upgrade setuptools and EasyInstall""" - options = _parse_args() - tarball = download_setuptools(download_base=options.download_base, - downloader_factory=options.downloader_factory) - return _install(tarball, _build_install_args(options)) - -if __name__ == '__main__': - sys.exit(main()) diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 6e247b5b..00000000 --- a/setup.cfg +++ /dev/null @@ -1,137 +0,0 @@ -# ------------------------------------------------------------------------------ -# -# Main project configuration. -# -# ------------------------------------------------------------------------------ -# Specific scripts using this configuration may support interpolating values -# from other options inside the same section using the '%(option)s' syntax. The -# same syntax may also be used to interpolate additional values provided by the -# calling script instead of being read from the configuration file itself, e.g. -# value '%(__name__)s' always refers to the name of the current section. -# -# For example, if interpolation is enabled, configuration -# -# [demo-section] -# basic = Foo -# derived = %(basic value)s-Bar -# -# generates the following options located in the section 'demo-section': -# -# 'basic' with the value 'Foo' -# 'derived' with the value 'Foo-Bar' - - -# -------------------- -# --- Build system --- -# -------------------- - -[install] -# Added in the original project as a fix (trunk SVN revision 7) for a problem -# with missing .pyo files when building rpms with Python 2.4. -optimize = 1 - -[sdist] -# '.tar.bz2' source distribution format takes the least space while '.zip' is -# the only format supported out-of-the-box on Windows. -formats = bztar,zip - - -# -------------------------------------- -# --- Test & development environment --- -# -------------------------------------- - -# Target Python environments. -[env:2.4.4 x86] -command = py244.cmd -[env:2.4.3 x86] -command = py243.cmd -[env:2.5.4 x64] -command = py254.cmd -[env:2.5.4 x86] -command = py254_x86.cmd -[env:2.6.6 x64] -command = py266.cmd -[env:2.6.6 x86] -command = py266_x86.cmd -[env:2.7.6 x64] -command = py276.cmd -[env:2.7.6 x86] -command = py276_x86.cmd -[env:2.7.7 x64] -command = py277.cmd -[env:2.7.7 x86] -command = py277_x86.cmd -[env:2.7.8 x64] -command = py278.cmd -[env:2.7.8 x86] -command = py278_x86.cmd -[env:3.1.3 x64] -command = py313.cmd -[env:3.1.3 x86] -command = py313_x86.cmd -[env:3.2.5 x64] -command = py325.cmd -[env:3.2.5 x86] -command = py325_x86.cmd -[env:3.3.3 x64] -command = py333.cmd -[env:3.3.3 x86] -command = py333_x86.cmd -[env:3.3.5 x64] -command = py335.cmd -[env:3.3.5 x86] -command = py335_x86.cmd -[env:3.4.0 x64] -command = py340.cmd -[env:3.4.0 x86] -command = py340_x86.cmd -[env:3.4.1 x64] -command = py341.cmd -[env:3.4.1 x86] -command = py341_x86.cmd -[env:3.4.2 x64] -command = py342.cmd -[env:3.4.2 x86] -command = py342_x86.cmd - -[pytest] -# Folders 'pytest' unit testing framework should avoid when collecting test -# cases to run, e.g. internal build & version control system folders. -norecursedirs = .git .hg .svn build dist - -# Regular test modules have names matching 'test_*.py'. Modules whose names end -# with '__pytest_assert_rewrite_needed.py' contain testing utility -# implementations that need to be considered as test modules so pytest would -# apply its assertion rewriting on them or else they would not work correctly -# when tests are run with disabled Python assertions. -python_files = test_*.py *__pytest_assert_rewrite_needed.py - -[setup base environments - actions] -# Regular actions (True/False). -report environment configuration = False -report raw environment scan results = False - -# Setup actions (Yes/No/IfNeeded). -setup setuptools = IfNeeded -download installations = IfNeeded -install environments = Yes - -[setup base environments - folders] -# Regular relative paths are interpreted relative to the folder containing this -# configuration. An alternative base folder may be explicitly specified using -# the following syntax: -# // -# Where stands for the specified relative path, while -# stands for one of the following literals -# PROJECT-FOLDER - base project folder -# SCRIPT-FOLDER - folder containing the script reading this configuration -# INI-FOLDER - folder containing this configuration (default) -installation cache = SCRIPT-FOLDER//__down load__ -pip download cache = %(installation cache)s/__pip download cache__ -ez_setup folder = PROJECT-FOLDER//. - -[setup base environments - reuse pre-installed setuptools] -# Reusing pre-installed setuptools distributions (True/False). -old = False -best = True -future = True diff --git a/suds/__init__.py b/suds/__init__.py index e78481be..7c6235a8 100644 --- a/suds/__init__.py +++ b/suds/__init__.py @@ -127,13 +127,6 @@ def tostr(object, encoding=None): from io import BytesIO -# Idea from 'http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python'. -class UnicodeMixin(object): - if sys.version_info >= (3, 0): - # For Python 3, __str__() and __unicode__() should be identical. - __str__ = lambda x: x.__unicode__() - else: - __str__ = lambda x: str(x).encode("utf-8") # Used instead of byte literals as they are not supported on Python versions # prior to 2.6. diff --git a/suds/argparser.py b/suds/argparser.py index 84ac0262..ddb2198c 100644 --- a/suds/argparser.py +++ b/suds/argparser.py @@ -263,7 +263,7 @@ def __match_ancestry(self, ancestry): if len(stack) == 1: return stack[0], ancestry previous = stack[0] - for frame, n in zip(stack[1:], xrange(len(ancestry))): + for frame, n in zip(stack[1:], range(len(ancestry))): if frame.id() is not ancestry[n]: return previous, ancestry[n:] previous = frame diff --git a/suds/client.py b/suds/client.py index c5bf399c..64d80929 100644 --- a/suds/client.py +++ b/suds/client.py @@ -47,7 +47,7 @@ log = getLogger(__name__) -class Client(UnicodeMixin): +class Client(object): """ A lightweight web service client. @@ -122,10 +122,7 @@ def __init__(self, url, **kwargs): @asyncio.coroutine def connect(self): - df = Definitions(self.url, self.options) - yield from df.connect() - self.reader = DefinitionsReader(self.options, df.parse) - yield from self.reader.open(self.url) + self.reader = DefinitionsReader(self.options, Definitions) self.wsdl = yield from self.reader.open(self.url) self.factory = Factory(self.wsdl) self.service = ServiceSelector(self, self.wsdl.services) @@ -717,6 +714,7 @@ def invoke(self, args, kwargs): metrics.log.debug("method '%s' invoked: %s", method_name, timer) return result + @asyncio.coroutine def send(self, soapenv): """ Send SOAP message. @@ -754,13 +752,13 @@ def send(self, soapenv): try: timer = metrics.Timer() timer.start() - reply = self.options.transport.send(request) + reply = yield from self.options.transport.send(request) timer.stop() metrics.log.debug("waited %s on server reply", timer) except suds.transport.TransportError as e: content = e.fp and e.fp.read() or "" return self.process_reply(content, e.httpcode, tostr(e)) - return self.process_reply(reply.message, None, None) + return self.process_reply(reply, None, None) def process_reply(self, reply, status, description): """ @@ -868,8 +866,6 @@ def __headers(self): """ action = self.method.soap.action - if isinstance(action, str): - action = action.encode("utf-8") result = { "Content-Type": "text/xml; charset=utf-8", "SOAPAction": action} @@ -896,7 +892,7 @@ class _SimClient(_SoapClient): @classmethod def simulation(cls, kwargs): """Get whether injected data has been specified in I{kwargs}.""" - return kwargs.has_key(_SimClient.__injkey) + return _SimClient.__injkey in kwargs def invoke(self, args, kwargs): """ diff --git a/suds/mx/__init__.py b/suds/mx/__init__.py index c64c0f9d..562c5265 100644 --- a/suds/mx/__init__.py +++ b/suds/mx/__init__.py @@ -45,7 +45,7 @@ def __init__(self, tag=None, value=None, **kwargs): Object.__init__(self) self.tag = tag self.value = value - for k, v in kwargs.iteritems(): + for k, v in kwargs.items(): setattr(self, k, v) def __getattr__(self, name): diff --git a/suds/mx/encoded.py b/suds/mx/encoded.py index ec095368..1f1181ad 100644 --- a/suds/mx/encoded.py +++ b/suds/mx/encoded.py @@ -107,7 +107,7 @@ def cast(self, content): query = TypeQuery(aty) ref = query.execute(self.schema) if ref is None: - raise TypeNotFound(qref) + raise TypeNotFound(ref) for x in content.value: if isinstance(x, (list, tuple)): array.item.append(x) diff --git a/suds/reader.py b/suds/reader.py index b84465a0..bb02ca63 100644 --- a/suds/reader.py +++ b/suds/reader.py @@ -99,7 +99,7 @@ def open(self, url): wsdl = cache.get(id) if wsdl is None: wsdl = self.fn(url, self.options) - print(wsdl) + yield from wsdl.connect() cache.put(id, wsdl) else: # Cached WSDL Definitions objects may have been created with diff --git a/suds/resolver.py b/suds/resolver.py index 4f019689..a7b15d3d 100644 --- a/suds/resolver.py +++ b/suds/resolver.py @@ -326,6 +326,7 @@ def find(self, node, resolved=False, push=True): @rtype: L{xsd.sxbase.SchemaObject} """ name = node.name + self.node = node parent = self.top().resolved if parent is None: result, ancestry = self.query(name, node) @@ -355,7 +356,7 @@ def findattr(self, name, resolved=True): name = '@%s'%name parent = self.top().resolved if parent is None: - result, ancestry = self.query(name, node) + result, ancestry = self.query(name, self.node) else: result, ancestry = self.getchild(name, parent) if result is None: diff --git a/suds/sax/attribute.py b/suds/sax/attribute.py index 61c5ad7a..a1f99e81 100644 --- a/suds/sax/attribute.py +++ b/suds/sax/attribute.py @@ -23,7 +23,7 @@ from suds.sax.text import Text -class Attribute(UnicodeMixin): +class Attribute(object): """ An XML attribute object. @ivar parent: The node containing this attribute @@ -164,7 +164,7 @@ def __repr__(self): 'attr (prefix=%s, name=%s, value=(%s))' %\ (self.prefix, self.name, self.value) - def __unicode__(self): + def __str__(self): """ get an xml string representation """ n = self.qname() if self.hasText(): diff --git a/suds/sax/date.py b/suds/sax/date.py index 64187967..615ca29e 100644 --- a/suds/sax/date.py +++ b/suds/sax/date.py @@ -20,7 +20,7 @@ """Classes for conversion between XML dates and Python objects.""" -from suds import UnicodeMixin + import datetime import re @@ -47,7 +47,7 @@ _RE_DATETIME = re.compile(_PATTERN_DATETIME) -class Date(UnicodeMixin): +class Date(object): """ An XML date object supporting the xsd:date datatype. @@ -67,7 +67,7 @@ def __init__(self, value): self.value = value.date() elif isinstance(value, datetime.date): self.value = value - elif isinstance(value, basestring): + elif isinstance(value, str): self.value = self.__parse(value) else: raise ValueError("invalid type for Date(): %s" % type(value)) @@ -95,11 +95,11 @@ def __parse(value): raise ValueError("date data has invalid format '%s'" % (value,)) return _date_from_match(match_result) - def __unicode__(self): + def __str__(self): return self.value.isoformat() -class DateTime(UnicodeMixin): +class DateTime(object): """ An XML datetime object supporting the xsd:dateTime datatype. @@ -117,7 +117,7 @@ def __init__(self, value): """ if isinstance(value, datetime.datetime): self.value = value - elif isinstance(value, basestring): + elif isinstance(value, str): self.value = self.__parse(value) else: raise ValueError("invalid type for DateTime(): %s" % type(value)) @@ -153,11 +153,11 @@ def __parse(value): value += datetime.timedelta(microseconds=1) return value - def __unicode__(self): + def __str__(self): return self.value.isoformat() -class Time(UnicodeMixin): +class Time(object): """ An XML time object supporting the xsd:time datatype. @@ -175,7 +175,7 @@ def __init__(self, value): """ if isinstance(value, datetime.time): self.value = value - elif isinstance(value, basestring): + elif isinstance(value, str): self.value = self.__parse(value) else: raise ValueError("invalid type for Time(): %s" % type(value)) @@ -207,11 +207,11 @@ def __parse(value): time = _bump_up_time_by_microsecond(time) return time.replace(tzinfo=tzinfo) - def __unicode__(self): + def __str__(self): return self.value.isoformat() -class FixedOffsetTimezone(datetime.tzinfo, UnicodeMixin): +class FixedOffsetTimezone(datetime.tzinfo, object): """ A timezone with a fixed offset and no daylight savings adjustment. @@ -273,7 +273,7 @@ def tzname(self, dt): return "%+03d:%02d:%02d" % (hours, minutes, seconds) return "%+03d:%02d" % (hours, minutes) - def __unicode__(self): + def __str__(self): return "FixedOffsetTimezone %s" % (self.tzname(None),) @@ -295,7 +295,7 @@ def tzname(self, dt): """ return "UTC" - def __unicode__(self): + def __str__(self): return "UtcTimezone" @@ -347,7 +347,7 @@ def __is_daylight_time(self, dt): time_tuple = time.localtime(time.mktime(time_tuple)) return time_tuple.tm_isdst > 0 - def __unicode__(self): + def __str__(self): dt = datetime.datetime.now() return "LocalTimezone %s offset: %s dst: %s" % (self.tzname(dt), self.utcoffset(dt), self.dst(dt)) diff --git a/suds/sax/document.py b/suds/sax/document.py index e814bd9e..58eacf0b 100644 --- a/suds/sax/document.py +++ b/suds/sax/document.py @@ -23,7 +23,7 @@ from suds.sax.element import Element -class Document(UnicodeMixin): +class Document(object): """ An XML Document """ DECL = '' @@ -172,5 +172,5 @@ def plain(self): s.append(root.plain()) return ''.join(s) - def __unicode__(self): + def __str__(self): return self.str() diff --git a/suds/sax/element.py b/suds/sax/element.py index 99f7010f..8e2064de 100644 --- a/suds/sax/element.py +++ b/suds/sax/element.py @@ -24,7 +24,7 @@ from suds.sax.attribute import Attribute -class Element(UnicodeMixin): +class Element(object): """ An XML element object. @@ -675,7 +675,7 @@ def promotePrefixes(self): c.promotePrefixes() if self.parent is None: return - for p, u in self.nsprefixes.items(): + for p, u in self.nsprefixes.copy().items(): if p in self.parent.nsprefixes: pu = self.parent.nsprefixes[p] if pu == u: @@ -806,7 +806,7 @@ def str(self, indent=0): result.append("%s<%s" % (tab, self.qname())) result.append(self.nsdeclarations()) for a in self.attributes: - result.append(" %s" % (unicode(a),)) + result.append(" %s" % (str(a),)) if self.isempty(): result.append("/>") return "".join(result) @@ -831,7 +831,7 @@ def plain(self): """ result = ["<%s" % (self.qname(),), self.nsdeclarations()] for a in self.attributes: - result.append(" %s" % (unicode(a),)) + result.append(" %s" % (str(a),)) if self.isempty(): result.append("/>") return "".join(result) @@ -965,13 +965,13 @@ def __len__(self): return len(self.children) def __getitem__(self, index): - if isinstance(index, basestring): + if isinstance(index, str): return self.get(index) if index < len(self.children): return self.children[index] def __setitem__(self, index, value): - if isinstance(index, basestring): + if isinstance(index, str): self.set(index, value) else: if index < len(self.children) and isinstance(value, Element): @@ -984,7 +984,7 @@ def __eq__(self, rhs): def __repr__(self): return "Element (prefix=%s, name=%s)" % (self.prefix, self.name) - def __unicode__(self): + def __str__(self): return self.str() def __iter__(self): @@ -1011,7 +1011,7 @@ def __init__(self, parent): self.pos = 0 self.children = parent.children - def next(self): + def __next__(self): """ Get the next child. diff --git a/suds/sax/enc.py b/suds/sax/enc.py index f7505568..4d571c60 100644 --- a/suds/sax/enc.py +++ b/suds/sax/enc.py @@ -58,7 +58,7 @@ def encode(self, s): @rtype: str """ - if isinstance(s, basestring) and self.__needs_encoding(s): + if isinstance(s, str) and self.__needs_encoding(s): for x in self.encodings: s = re.sub(x[0], x[1], s) return s @@ -73,7 +73,7 @@ def decode(self, s): @rtype: str """ - if isinstance(s, basestring) and "&" in s: + if isinstance(s, str) and "&" in s: for x in self.decodings: s = s.replace(x[0], x[1]) return s @@ -88,7 +88,7 @@ def __needs_encoding(self, s): @rtype: boolean """ - if isinstance(s, basestring): + if isinstance(s, str): for c in self.special: if c in s: return True diff --git a/suds/sax/parser.py b/suds/sax/parser.py index 15146632..2fd94076 100644 --- a/suds/sax/parser.py +++ b/suds/sax/parser.py @@ -36,6 +36,7 @@ import sys from xml.sax import make_parser, InputSource, ContentHandler from xml.sax.handler import feature_external_ges +from io import StringIO class Handler(ContentHandler): @@ -126,7 +127,7 @@ def parse(self, file=None, string=None): source = file if file is None: source = InputSource(None) - source.setByteStream(suds.BytesIO(string)) + source.setByteStream(StringIO(string)) sax, handler = self.saxparser() sax.parse(source) timer.stop() diff --git a/suds/sax/text.py b/suds/sax/text.py index 08dc093e..33b668b7 100644 --- a/suds/sax/text.py +++ b/suds/sax/text.py @@ -19,7 +19,7 @@ """ from suds import * -from suds.sax import * +from suds import sax class Text(str): diff --git a/suds/servicedefinition.py b/suds/servicedefinition.py index 03573bc5..c2650d2a 100644 --- a/suds/servicedefinition.py +++ b/suds/servicedefinition.py @@ -26,7 +26,7 @@ log = getLogger(__name__) -class ServiceDefinition(UnicodeMixin): +class ServiceDefinition(object): """ A service definition provides an object used to generate a textual description of a service. @@ -232,7 +232,7 @@ def description(self): s.append('\n\n') return ''.join(s) - def __unicode__(self): + def __str__(self): try: return self.description() except Exception as e: diff --git a/suds/serviceproxy.py b/suds/serviceproxy.py index 278c1896..98701731 100644 --- a/suds/serviceproxy.py +++ b/suds/serviceproxy.py @@ -24,7 +24,7 @@ from suds.client import Client -class ServiceProxy(UnicodeMixin): +class ServiceProxy(object): """ A lightweight soap based web service proxy. @@ -69,8 +69,8 @@ def get_enum(self, name): """ return self.__client__.factory.create(name) - def __unicode__(self): - return unicode(self.__client__) + def __str__(self): + return str(self.__client__) def __getattr__(self, name): builtin = name.startswith('__') and name.endswith('__') diff --git a/suds/sudsobject.py b/suds/sudsobject.py index f4056018..decc2fce 100644 --- a/suds/sudsobject.py +++ b/suds/sudsobject.py @@ -135,7 +135,7 @@ def property(cls, name, value=None): return subclass(value) -class Object(UnicodeMixin): +class Object(object): def __init__(self): self.__keylist__ = [] @@ -178,7 +178,7 @@ def __contains__(self, name): def __repr__(self): return str(self) - def __unicode__(self): + def __str__(self): return self.__printer__.tostr(self) @@ -189,7 +189,7 @@ def __init__(self, sobject): self.keylist = self.__keylist(sobject) self.index = 0 - def next(self): + def __next__(self): keylist = self.keylist nkeys = len(self.keylist) while self.index < nkeys: diff --git a/suds/transport/__init__.py b/suds/transport/__init__.py index 0ed4e4e1..0617f140 100644 --- a/suds/transport/__init__.py +++ b/suds/transport/__init__.py @@ -18,7 +18,7 @@ """ -from suds import UnicodeMixin + import sys @@ -30,7 +30,7 @@ def __init__(self, reason, httpcode, fp=None): self.fp = fp -class Request(UnicodeMixin): +class Request(object): """ A transport request. @@ -65,7 +65,7 @@ def __init__(self, url, message=None): self.headers = {} self.message = message - def __unicode__(self): + def __str__(self): result = [u"URL: %s\nHEADERS: %s" % (self.url, self.headers)] if self.message is not None: result.append(u"MESSAGE:") @@ -90,7 +90,7 @@ def __set_URL(self, url): self.url = url.decode("ascii") -class Reply(UnicodeMixin): +class Reply(object): """ A transport reply. @@ -117,7 +117,7 @@ def __init__(self, code, headers, message): self.headers = headers self.message = message - def __unicode__(self): + def __str__(self): return u"""\ CODE: %s HEADERS: %s diff --git a/suds/transport/http.py b/suds/transport/http.py index dca58b13..2ee353a9 100644 --- a/suds/transport/http.py +++ b/suds/transport/http.py @@ -65,7 +65,7 @@ def open(self, request): res = yield from async_request('GET', request.url, headers=headers, cookies=dict(self.cookiejar)) reply = yield from res.content.read() log.debug('received:\n%s', reply) - return reply + return str(reply, encoding='utf-8') @asyncio.coroutine @@ -76,7 +76,7 @@ def send(self, request): res = yield from async_request('POST', request.url, data=msg, headers=headers, cookies=dict(self.cookiejar)) reply = yield from res.content.read() log.debug('received:\n%s', reply) - return reply + return str(reply, encoding='utf-8') def __deepcopy__(self): clone = self.__class__() diff --git a/suds/transport/https.py b/suds/transport/https.py index ece3a69d..0657076e 100644 --- a/suds/transport/https.py +++ b/suds/transport/https.py @@ -58,13 +58,11 @@ def __init__(self, **kwargs): HttpTransport.__init__(self, **kwargs) self.pm = urllib.request.HTTPPasswordMgrWithDefaultRealm() - @asyncio.coroutine def open(self, request): self.add_credentials(request) return HttpTransport.open(self, request) - @asyncio.coroutine def send(self, request): self.add_credentials(request) return HttpTransport.send(self, request) diff --git a/suds/umx/core.py b/suds/umx/core.py index 4db8eaa7..a8192451 100644 --- a/suds/umx/core.py +++ b/suds/umx/core.py @@ -95,7 +95,7 @@ def postprocess(self, content): return None else: return Text('', lang=lang) - if isinstance(content.text, basestring): + if isinstance(content.text, str): return Text(content.text, lang=lang) else: return content.text diff --git a/suds/wsdl.py b/suds/wsdl.py index 54e76e61..029bd552 100644 --- a/suds/wsdl.py +++ b/suds/wsdl.py @@ -47,45 +47,42 @@ class WObject(Object): """ - Base object for WSDL types. - + Base object for wsdl types. @ivar root: The XML I{root} element. @type root: L{Element} - """ - def __init__(self): + def __init__(self, root, definitions=None): """ @param root: An XML root element. @type root: L{Element} - + @param definitions: A definitions object. + @type definitions: L{Definitions} """ Object.__init__(self) + self.root = root + pmd = Metadata() + pmd.excludes = ['root'] + pmd.wrappers = dict(qname=repr) + self.__metadata__.__print__ = pmd - def parse(self, definitions): + def resolve(self, definitions): """ Resolve named references to other WSDL objects. - @param definitions: A definitions object. @type definitions: L{Definitions} - """ - pmd = Metadata() - pmd.excludes = ["root"] - pmd.wrappers = dict(qname=repr) - self.__metadata__.__print__ = pmd + pass class NamedObject(WObject): """ A B{named} WSDL object. - @ivar name: The name of the object. @type name: str @ivar qname: The I{qualified} name of the object. @type qname: (name, I{namespace-uri}). - """ def __init__(self, root, definitions): @@ -94,18 +91,12 @@ def __init__(self, root, definitions): @type root: L{Element} @param definitions: A definitions object. @type definitions: L{Definitions} - """ - WObject.__init__(self) - self.root = root - - def parse(self, definitions): - super().parse(definitions) - self.name = self.root.get("name") + WObject.__init__(self, root, definitions) + self.name = root.get('name') self.qname = (self.name, definitions.tns[1]) pmd = self.__metadata__.__print__ - pmd.wrappers["qname"] = repr - + pmd.wrappers['qname'] = repr class Definitions(WObject): @@ -140,8 +131,8 @@ class Definitions(WObject): Tag = "definitions" def __init__(self, url, options): - super().__init__() log.debug("reading WSDL at: %s ...", url) + Object.__init__(self) self.url = url self.reader = DocumentReader(options) self.id = objid(self) @@ -155,8 +146,6 @@ def __init__(self, url, options): self.bindings = {} self.services = [] - - def __call__(self): """ @param url: A URL to the WSDL. @@ -172,6 +161,7 @@ def __call__(self): def connect(self): d = yield from self.reader.open(self.url) self.root = d.root() + WObject.__init__(self, self.root) self.tns = self.mktns(self.root) self.add_children(self.root) self.children.sort() @@ -189,8 +179,6 @@ def connect(self): log.debug("WSDL at '%s' loaded:\n%s", self.url, self) - - def mktns(self, root): """Get/create the target namespace.""" tns = root.get("targetNamespace") @@ -389,7 +377,7 @@ def __init__(self, root, definitions): @type definitions: L{Definitions} """ - WObject.__init__(self) + WObject.__init__(self, root, definitions) self.definitions = definitions def contents(self): diff --git a/suds/wsse.py b/suds/wsse.py index 2a091d02..f0796dd7 100644 --- a/suds/wsse.py +++ b/suds/wsse.py @@ -25,11 +25,8 @@ from suds.sax.date import DateTime, UtcTimezone from datetime import datetime, timedelta -try: - from hashlib import md5 -except ImportError: - # Python 2.4 compatibility - from md5 import md5 +from hashlib import md5 + dsns = \ diff --git a/suds/xsd/__init__.py b/suds/xsd/__init__.py index c5d80154..39c2b1d8 100644 --- a/suds/xsd/__init__.py +++ b/suds/xsd/__init__.py @@ -59,8 +59,8 @@ def isqref(object): return (\ isinstance(object, tuple) and \ len(object) == 2 and \ - isinstance(object[0], basestring) and \ - isinstance(object[1], basestring)) + isinstance(object[0], str) and \ + isinstance(object[1], str)) class Filter: diff --git a/suds/xsd/schema.py b/suds/xsd/schema.py index 2066a2f0..afcd8b53 100644 --- a/suds/xsd/schema.py +++ b/suds/xsd/schema.py @@ -36,7 +36,7 @@ log = getLogger(__name__) -class SchemaCollection(UnicodeMixin): +class SchemaCollection(object): """ A collection of schema objects. @@ -157,14 +157,14 @@ def merge(self): def __len__(self): return len(self.children) - def __unicode__(self): + def __str__(self): result = ["\nschema collection"] for s in self.children: result.append(s.str(1)) return "\n".join(result) -class Schema(UnicodeMixin): +class Schema(object): """ The schema is an objectification of a (XSD) definition. It provides inspection, lookup and type resolution. @@ -427,5 +427,5 @@ def str(self, indent=0): def __repr__(self): return '<%s tns="%s"/>' % (self.id, self.tns[1]) - def __unicode__(self): + def __str__(self): return self.str() diff --git a/suds/xsd/sxbase.py b/suds/xsd/sxbase.py index aed605fc..9de2ab9f 100644 --- a/suds/xsd/sxbase.py +++ b/suds/xsd/sxbase.py @@ -24,7 +24,7 @@ log = getLogger(__name__) -class SchemaObject(UnicodeMixin): +class SchemaObject(object): """ A schema object is an extension to object with schema awareness. @@ -520,9 +520,6 @@ def description(self): """ return () - def __unicode__(self): - return unicode(self.str()) - def __repr__(self): s = [] s.append("<%s" % (self.id,)) @@ -584,7 +581,7 @@ def __init__(self, sx): self.items = sx.rawchildren self.index = 0 - def next(self): + def __next__(self): """ Get the I{next} item in the frame's collection. @@ -642,7 +639,7 @@ def top(self): return self.stack[-1] raise StopIteration() - def next(self): + def __next__(self): """ Get the next item. @@ -653,15 +650,15 @@ def next(self): """ frame = self.top() while True: - result = frame.next() + result = frame.__next__() if result is None: self.pop() - return self.next() + return self.__next__() if isinstance(result, Content): ancestry = [f.sx for f in self.stack] return result, ancestry self.push(result) - return self.next() + return self.__next__() def __iter__(self): return self diff --git a/suds/xsd/sxbuiltin.py b/suds/xsd/sxbuiltin.py index 35370228..9d0c1254 100644 --- a/suds/xsd/sxbuiltin.py +++ b/suds/xsd/sxbuiltin.py @@ -51,7 +51,7 @@ class XBoolean(XBuiltin): @staticmethod def translate(value, topython=True): if topython: - if isinstance(value, basestring): + if isinstance(value, str): return XBoolean._xml_to_python.get(value) else: if isinstance(value, (bool, int)): @@ -65,7 +65,7 @@ class XDate(XBuiltin): @staticmethod def translate(value, topython=True): if topython: - if isinstance(value, basestring) and value: + if isinstance(value, str) and value: return Date(value).value else: if isinstance(value, datetime.date): @@ -79,7 +79,7 @@ class XDateTime(XBuiltin): @staticmethod def translate(value, topython=True): if topython: - if isinstance(value, basestring) and value: + if isinstance(value, str) and value: return DateTime(value).value else: if isinstance(value, datetime.datetime): @@ -194,7 +194,7 @@ def _decimal_to_xsd_format(value): @classmethod def translate(cls, value, topython=True): if topython: - if isinstance(value, basestring) and value: + if isinstance(value, str) and value: return decimal.Decimal(value) else: if isinstance(value, decimal.Decimal): @@ -208,7 +208,7 @@ class XFloat(XBuiltin): @staticmethod def translate(value, topython=True): if topython: - if isinstance(value, basestring) and value: + if isinstance(value, str) and value: return float(value) else: return value @@ -220,7 +220,7 @@ class XInteger(XBuiltin): @staticmethod def translate(value, topython=True): if topython: - if isinstance(value, basestring) and value: + if isinstance(value, str) and value: return int(value) else: return value @@ -232,8 +232,8 @@ class XLong(XBuiltin): @staticmethod def translate(value, topython=True): if topython: - if isinstance(value, basestring) and value: - return long(value) + if isinstance(value, str) and value: + return int(value) else: return value @@ -249,7 +249,7 @@ class XTime(XBuiltin): @staticmethod def translate(value, topython=True): if topython: - if isinstance(value, basestring) and value: + if isinstance(value, str) and value: return Time(value).value else: if isinstance(value, datetime.time): diff --git a/test.py b/test.py index 1f7c3e4b..0a4d7342 100644 --- a/test.py +++ b/test.py @@ -2,13 +2,17 @@ import asyncio from suds.client import Client +import logging +# logging.basicConfig(level=logging.DEBUG) + @asyncio.coroutine def Test(): - c=Client('https://sep.shaparak.ir/Payments/InitPayment.asmx?wsdl') + c=Client('http://www.webservicex.net/whois.asmx?WSDL') yield from c.connect() + res = yield from c.service.GetWhoIS('samasoft.ir') + print(res) - - -asyncio.get_event_loop().run_until_complete(Test()) \ No newline at end of file +asyncio.get_event_loop().run_until_complete(Test()) +asyncio.get_event_loop().close() \ No newline at end of file