| @@ -1,5 +1,5 @@ | |||||
| include README.txt | |||||
| include README.rst | |||||
| include CHANGES.txt | include CHANGES.txt | ||||
| recursive-include docs *.* | recursive-include docs *.* | ||||
| recursive-include src *.txt *.py *.tar.gz README | |||||
| recursive-include wstools *.py | |||||
| @@ -1,30 +0,0 @@ | |||||
| [](https://travis-ci.org/kartoch/wstools)[](https://coveralls.io/r/kartoch/wstools?branch=master) | |||||
| General | |||||
| ======== | |||||
| - Homepage: https://github.com/pycontribs/wstools | |||||
| - Mailing List: https://groups.google.com/forum/#!forum/pycontribs | |||||
| - Package: http://pypi.python.org/pypi/wstools/ | |||||
| - Docs (TBD): http://packages.python.org/wstools | |||||
| Credits | |||||
| ======== | |||||
| Companies | |||||
| --------- | |||||
| |makinacom|_ | |||||
| * `Planet Makina Corpus <http://www.makina-corpus.org>`_ | |||||
| * `Contact us <mailto:python@makina-corpus.org>`_ | |||||
| .. |makinacom| image:: http://depot.makina-corpus.org/public/logo.gif | |||||
| .. _makinacom: http://www.makina-corpus.com | |||||
| Authors | |||||
| ------------ | |||||
| - Makina Corpus <python@makina-corpus.com> | |||||
| Contributors | |||||
| ----------------- | |||||
| - Sorin Sbarnea <sorin.sbarnea+os@gmail.com> | |||||
| @@ -0,0 +1,73 @@ | |||||
| ========================================================= | |||||
| WSDL parsing services package for Web Services for Python | |||||
| ========================================================= | |||||
| . image:: https://pypip.in/py_versions/wstools/badge.svg?style=flat | |||||
| :target: https://pypi.python.org/pypi/wstools/ | |||||
| .. image:: https://pypip.in/license/wstools/badge.svg?style=flat | |||||
| :target: https://pypi.python.org/pypi/wstools/ | |||||
| .. image:: https://pypip.in/download/wstools/badge.svg?style=flat | |||||
| :target: https://pypi.python.org/pypi/wstools/ | |||||
| .. image:: https://pypip.in/version/wstools/badge.svg?style=flat | |||||
| :target: https://pypi.python.org/pypi/wstools/ | |||||
| .. image:: https://pypip.in/egg/wstools/badge.svg?style=flat | |||||
| :target: https://pypi.python.org/pypi/wstools/ | |||||
| .. image:: https://pypip.in/wheel/wstools/badge.svg?style=flat | |||||
| :target: https://pypi.python.org/pypi/wstools/ | |||||
| ------------ | |||||
| .. image:: https://api.travis-ci.org/pycontribs/wstools.svg?branch=master | |||||
| :target: https://travis-ci.org/pycontribs/wstools | |||||
| .. image:: https://pypip.in/status/wstools/badge.svg?style=flat | |||||
| :target: https://pypi.python.org/pypi/wstools/ | |||||
| .. image:: https://img.shields.io/coveralls/pycontribs/wstools.svg | |||||
| :target: https://coveralls.io/r/pycontribs/wstools | |||||
| .. image:: http://api.flattr.com/button/flattr-badge-large.png | |||||
| :target: https://flattr.com/submit/auto?user_id=sbarnea&url=https://github.com/pycontribs/wstools&title=Python wstools&language=&tags=github&category=software | |||||
| General | |||||
| ======= | |||||
| - Homepage: https://github.com/pycontribs/wstools | |||||
| - Mailing List: https://groups.google.com/forum/#!forum/pycontribs | |||||
| - Package: http://pypi.python.org/pypi/wstools/ | |||||
| - Docs (TBD): http://packages.python.org/wstools | |||||
| Credits | |||||
| ======= | |||||
| Companies | |||||
| --------- | |||||
| \|makinacom\|\_ | |||||
| - ``Planet Makina Corpus <http://www.makina-corpus.org>``\ \_ | |||||
| - ``Contact us <mailto:python@makina-corpus.org>``\ \_ | |||||
| .. \|makinacom\| image:: http://depot.makina-corpus.org/public/logo.gif | |||||
| .. \_makinacom: http://www.makina-corpus.com | |||||
| Authors | |||||
| ------- | |||||
| - Makina Corpus python@makina-corpus.com | |||||
| Contributors | |||||
| ------------ | |||||
| - Sorin Sbarnea sorin.sbarnea@gmail.com | |||||
| .. |Build Status| image:: https://travis-ci.org/kartoch/wstools.svg?branch=master | |||||
| :target: https://travis-ci.org/kartoch/wstools | |||||
| .. |Coverage Status| image:: https://img.shields.io/coveralls/kartoch/wstools.svg | |||||
| :target: https://coveralls.io/r/kartoch/wstools?branch=master | |||||
| @@ -0,0 +1,45 @@ | |||||
| [metadata] | |||||
| description-file = README | |||||
| [bdist_wheel] | |||||
| universal = 1 | |||||
| [build_sphinx] | |||||
| source-dir = docs | |||||
| build-dir = docs/build | |||||
| all_files = 1 | |||||
| [upload_sphinx] | |||||
| upload-dir = docs/build/html | |||||
| [pytest] | |||||
| norecursedirs = . .svn jira _build tmp* lib/third lib *.egg bin distutils build docs demo | |||||
| python_files = *.py | |||||
| addopts = -p no:xdist --ignore=setup.py --tb=long -rsxX -v --maxfail=10 --pep8 tests | |||||
| # --maxfail=2 -n4 | |||||
| # -n4 runs up to 4 parallel procs | |||||
| # --maxfail=2 fail fast, dude | |||||
| # --durations=3 report the top 3 longest tests | |||||
| # these are important for distributed testing, to speedup their execution we minimize what we sync | |||||
| rsyncdirs = . jira demo docs | |||||
| rsyncignore = .hg .git | |||||
| pep8ignore = E501 E265 E127 E901 E128 E402 | |||||
| [pep8] | |||||
| exclude=build,lib,.tox,third,*.egg,docs,packages | |||||
| ;filename= | |||||
| ;select | |||||
| ignore=E501,E265,E402 | |||||
| max-line-length=1024 | |||||
| count=1 | |||||
| ;format | |||||
| ;quiet | |||||
| ;show-pep8 | |||||
| ;show-source | |||||
| statistics=1 | |||||
| ;verbose=1 | |||||
| ;PEP8_OPTS="--filename=*.py --exclude=lib --ignore=E501 scripts" | |||||
| ;pep8 $PEP8_OPTS --show-source --repeat | |||||
| ;pep8 --statistics -qq $PEP8_OPTS | |||||
| @@ -1,34 +1,171 @@ | |||||
| #!/usr/bin/env python | #!/usr/bin/env python | ||||
| import logging | |||||
| import os | import os | ||||
| from setuptools import setup | |||||
| import re | |||||
| import sys | |||||
| import subprocess | |||||
| import warnings | |||||
| import codecs | |||||
| from setuptools import setup, find_packages, Command | |||||
| from setuptools.command.test import test as TestCommand | |||||
| NAME = "wstools" | |||||
| url = "https://github.com/pycontribs/wstools.git" | url = "https://github.com/pycontribs/wstools.git" | ||||
| # Get the version - do not use normal import because it does break coverage | |||||
| base_path = os.path.dirname(__file__) | |||||
| fp = open(os.path.join(base_path, NAME, 'version.py')) | |||||
| __version__ = re.compile(r".*__version__\s*=\s*['\"](.*?)['\"]", | |||||
| re.S).match(fp.read()).group(1) | |||||
| fp.close() | |||||
| # this should help getting annoying warnings from inside distutils | |||||
| warnings.simplefilter('ignore', UserWarning) | |||||
| class PyTest(TestCommand): | |||||
| user_options = [('pytest-args=', 'a', "Arguments to pass to py.test")] | |||||
| def initialize_options(self): | |||||
| TestCommand.initialize_options(self) | |||||
| self.pytest_args = [] | |||||
| FORMAT = '%(levelname)-10s %(message)s' | |||||
| logging.basicConfig(format=FORMAT) | |||||
| logging.getLogger().setLevel(logging.INFO) | |||||
| # if we have pytest-cache module we enable the test failures first mode | |||||
| try: | |||||
| import pytest_cache | |||||
| self.pytest_args.append("--ff") | |||||
| except ImportError: | |||||
| pass | |||||
| self.pytest_args.append("-s") | |||||
| if sys.stdout.isatty(): | |||||
| # when run manually we enable fail fast | |||||
| self.pytest_args.append("--maxfail=1") | |||||
| try: | |||||
| import coveralls | |||||
| self.pytest_args.append("--cov=%s" % NAME) | |||||
| self.pytest_args.extend(["--cov-report", "term"]) | |||||
| self.pytest_args.extend(["--cov-report", "xml"]) | |||||
| except ImportError: | |||||
| pass | |||||
| def read(*rnames): | |||||
| return "\n" + open( | |||||
| os.path.join('.', *rnames) | |||||
| ).read() | |||||
| def finalize_options(self): | |||||
| TestCommand.finalize_options(self) | |||||
| self.test_args = [] | |||||
| self.test_suite = True | |||||
| long_description = \ | |||||
| "WSDL parsing services package for Web Services for Python. see" + url | |||||
| def run_tests(self): | |||||
| # before running tests we need to run autopep8 | |||||
| try: | |||||
| r = subprocess.check_call( | |||||
| "python -m autopep8 -r --in-place wstools/ tests/", | |||||
| shell=True) | |||||
| except subprocess.CalledProcessError: | |||||
| logging.getLogger().warn('autopep8 is not installed so ' | |||||
| 'it will not be run') | |||||
| # import here, cause outside the eggs aren't loaded | |||||
| import pytest | |||||
| errno = pytest.main(self.pytest_args) | |||||
| sys.exit(errno) | |||||
| from wstools.version import __version__ | |||||
| install_requires = [ | |||||
| 'docutils' | |||||
| ] | |||||
| class Release(Command): | |||||
| user_options = [] | |||||
| def initialize_options(self): | |||||
| # Command.initialize_options(self) | |||||
| pass | |||||
| def finalize_options(self): | |||||
| # Command.finalize_options(self) | |||||
| pass | |||||
| def run(self): | |||||
| import json | |||||
| try: | |||||
| from urllib.request import urlopen | |||||
| except ImportError: | |||||
| from urllib2 import urlopen | |||||
| response = urlopen( | |||||
| "http://pypi.python.org/pypi/%s/json" % NAME) | |||||
| data = json.load(codecs.getreader("utf-8")(response)) | |||||
| released_version = data['info']['version'] | |||||
| if released_version == __version__: | |||||
| raise RuntimeError( | |||||
| "This version was already released, remove it from PyPi if you want to release it again or increase the version number. http://pypi.python.org/pypi/%s/" % NAME) | |||||
| elif released_version > __version__: | |||||
| raise RuntimeError("Cannot release a version (%s) smaller than the PyPI current release (%s)." % ( | |||||
| __version__, released_version)) | |||||
| class PreRelease(Command): | |||||
| user_options = [] | |||||
| def initialize_options(self): | |||||
| # Command.initialize_options(self) | |||||
| pass | |||||
| def finalize_options(self): | |||||
| # Command.finalize_options(self) | |||||
| pass | |||||
| def run(self): | |||||
| import json | |||||
| try: | |||||
| from urllib.request import urlopen | |||||
| except ImportError: | |||||
| from urllib2 import urlopen | |||||
| response = urlopen( | |||||
| "http://pypi.python.org/pypi/%s/json" % NAME) | |||||
| data = json.load(codecs.getreader("utf-8")(response)) | |||||
| released_version = data['info']['version'] | |||||
| if released_version >= __version__: | |||||
| raise RuntimeError( | |||||
| "Current version of the package is equal or lower than the already published ones (PyPi). Increse version to be able to pass prerelease stage.") | |||||
| setup( | setup( | ||||
| name="wstools", | |||||
| name=NAME, | |||||
| version=__version__, | version=__version__, | ||||
| description="wstools", | |||||
| maintainer="Gregory Warnes, kiorky, sorin", | |||||
| maintainer_email="Gregory.R.Warnes@Pfizer.com, " | |||||
| + " kiorky@cryptelium.net, " + "sorin.sbarnea+os@gmail.com", | |||||
| url=url, | |||||
| long_description=long_description, | |||||
| packages=['wstools'], | |||||
| install_requires=install_requires, | |||||
| cmdclass={'test': PyTest, 'release': Release, 'prerelease': PreRelease}, | |||||
| packages=find_packages(exclude=['tests']), | |||||
| include_package_data=True, | |||||
| install_requires=['docutils','six'], | |||||
| license='BSD', | |||||
| description="WSDL parsing services package for Web Services for Python. see" + url, | |||||
| long_description=open("README.rst").read(), | |||||
| maintainer="Sorin Sbarnea", | |||||
| maintainer_email="sorin.sbarnea@gmail.com", | |||||
| author='Makina Corpus', | |||||
| author_email='python@makina-corpus.com', | |||||
| provides=[NAME], | |||||
| url='https://github.com/pycontribs/wstools', | |||||
| bugtrack_url='https://github.com/pycontribs/wstools/issues', | |||||
| home_page='https://github.com/pycontribs/wstools', | |||||
| keywords='api wstools wdsl web', | |||||
| classifiers=[ | |||||
| 'Programming Language :: Python', | |||||
| 'Programming Language :: Python :: 2.5', | |||||
| 'Programming Language :: Python :: 2.6', | |||||
| 'Programming Language :: Python :: 2.7', | |||||
| 'Programming Language :: Python :: 3', | |||||
| 'Development Status :: 4 - Beta', | |||||
| 'Environment :: Other Environment', | |||||
| 'Intended Audience :: Developers', | |||||
| 'License :: OSI Approved :: BSD License', | |||||
| 'Operating System :: OS Independent', | |||||
| 'Topic :: Software Development :: Libraries :: Python Modules', | |||||
| 'Programming Language :: Python :: 2.6', | |||||
| 'Programming Language :: Python :: 2.7', | |||||
| 'Programming Language :: Python :: 3.3', | |||||
| 'Programming Language :: Python :: 3.4', | |||||
| 'Topic :: Internet :: WWW/HTTP', | |||||
| ], | |||||
| ) | ) | ||||
| @@ -10,7 +10,7 @@ | |||||
| [services_by_file] | [services_by_file] | ||||
| ip2geo = data/ip2geo.wsdl | ip2geo = data/ip2geo.wsdl | ||||
| zip2geo = data/zip2geo.wsdl | zip2geo = data/zip2geo.wsdl | ||||
| soapi-dlw = data/soapi-1.63.0-dlw.wsdl | |||||
| soapi-dlw = data/soapi-1.63.0-dlw.wsdl | |||||
| soapi-re = data/soapi-1.63.0-re.wsdl | soapi-re = data/soapi-1.63.0-re.wsdl | ||||
| ########################################################################## | ########################################################################## | ||||
| @@ -209,7 +209,7 @@ FOPService = http://live.capescience.com/wsdl/FOPService.wsdl | |||||
| FedRoutingDirectoryService = http://demo.soapam.com/services/FedEpayDirectory/FedEpayDirectoryService.wsdl | FedRoutingDirectoryService = http://demo.soapam.com/services/FedEpayDirectory/FedEpayDirectoryService.wsdl | ||||
| GMChart = http://service.graphmagic.com/GMService/GraphMagic.asmx?wsdl | GMChart = http://service.graphmagic.com/GMService/GraphMagic.asmx?wsdl | ||||
| GeoPlaces = http://www.codebump.com/services/placelookup.asmx?wsdl | GeoPlaces = http://www.codebump.com/services/placelookup.asmx?wsdl | ||||
| GlobalWeather = http://live.capescience.com/wsdl/GlobalWeather.wsdl | |||||
| GlobalWeatherComplex = http://live.capescience.com/wsdl/GlobalWeather.wsdl | |||||
| GoogleSearch = http://api.google.com/GoogleSearch.wsdl | GoogleSearch = http://api.google.com/GoogleSearch.wsdl | ||||
| HPcatalogService = http://www.lixusnet.com/lixusnet/HPcatalog.jws?wsdl | HPcatalogService = http://www.lixusnet.com/lixusnet/HPcatalog.jws?wsdl | ||||
| HTMLeMail = http://www.framewerks.com/WebServices/HTMLeMail/HTMLeMail.asmx?WSDL | HTMLeMail = http://www.framewerks.com/WebServices/HTMLeMail/HTMLeMail.asmx?WSDL | ||||
| @@ -245,7 +245,7 @@ SendSMS = http://www.webservicex.net/SendSMS.asmx?WSDL | |||||
| Server = http://addison.ra.cwru.edu/orc/calendar_copy/server.php?wsdl | Server = http://addison.ra.cwru.edu/orc/calendar_copy/server.php?wsdl | ||||
| Service = http://www.ejse.com/WeatherService/Service.asmx?WSDL | Service = http://www.ejse.com/WeatherService/Service.asmx?WSDL | ||||
| SpamKillerService = http://wavendon.dsdata.co.uk/axis/services/SpamKiller?wsdl | SpamKillerService = http://wavendon.dsdata.co.uk/axis/services/SpamKiller?wsdl | ||||
| StockQuotes = http://www.swanandmokashi.com/HomePage/WebServices/StockQuotes.asmx?WSDL | |||||
| StockQuotesComplex = http://www.swanandmokashi.com/HomePage/WebServices/StockQuotes.asmx?WSDL | |||||
| TWSFissionDotNet = http://www.sidespace.com/ws/fission/fissiondotnet.php?wsdl | TWSFissionDotNet = http://www.sidespace.com/ws/fission/fissiondotnet.php?wsdl | ||||
| TerraService = http://terraservice.net/TerraService.asmx?WSDL | TerraService = http://terraservice.net/TerraService.asmx?WSDL | ||||
| Transform = http://transform.dataconcert.com/transform.wsdl | Transform = http://transform.dataconcert.com/transform.wsdl | ||||
| @@ -7,11 +7,19 @@ | |||||
| import sys | import sys | ||||
| import unittest | import unittest | ||||
| import ConfigParser | |||||
| import os | import os | ||||
| import inspect | |||||
| cmd_folder = os.path.abspath(os.path.join(os.path.split(inspect.getfile( | |||||
| inspect.currentframe()))[0], "..")) | |||||
| if cmd_folder not in sys.path: | |||||
| sys.path.insert(0, cmd_folder) | |||||
| from wstools.Utility import DOM | from wstools.Utility import DOM | ||||
| from wstools.WSDLTools import WSDLReader | from wstools.WSDLTools import WSDLReader | ||||
| from wstools.TimeoutSocket import TimeoutError | from wstools.TimeoutSocket import TimeoutError | ||||
| try: | |||||
| import configparser | |||||
| except: | |||||
| from six.moves import configparser | |||||
| cwd = 'tests' | cwd = 'tests' | ||||
| @@ -37,8 +45,11 @@ class WSDLToolsTestCase(unittest.TestCase): | |||||
| def setUp(self): | def setUp(self): | ||||
| makeTestSuite() | makeTestSuite() | ||||
| self.path = nameGenerator.next() | |||||
| print self.path | |||||
| if hasattr(nameGenerator, '__next__'): | |||||
| self.path = nameGenerator.__next__() | |||||
| else: | |||||
| self.path = nameGenerator.next() | |||||
| #print(self.path) | |||||
| sys.stdout.flush() | sys.stdout.flush() | ||||
| def __str__(self): | def __str__(self): | ||||
| @@ -72,7 +83,7 @@ class WSDLToolsTestCase(unittest.TestCase): | |||||
| self.wsdl = WSDLReader().loadFromFile('tests/' + self.path) | self.wsdl = WSDLReader().loadFromFile('tests/' + self.path) | ||||
| except TimeoutError: | except TimeoutError: | ||||
| print "connection timed out" | |||||
| print("connection timed out") | |||||
| sys.stdout.flush() | sys.stdout.flush() | ||||
| return | return | ||||
| except: | except: | ||||
| @@ -104,8 +115,8 @@ class WSDLToolsTestCase(unittest.TestCase): | |||||
| raise | raise | ||||
| try: | try: | ||||
| self.checkWSDLCollection('import', self.wsdl.imports, \ | |||||
| key='namespace') | |||||
| self.checkWSDLCollection('import', self.wsdl.imports, | |||||
| key='namespace') | |||||
| except: | except: | ||||
| self.path = self.path + ": wsdl.imports" | self.path = self.path + ": wsdl.imports" | ||||
| raise | raise | ||||
| @@ -131,9 +142,9 @@ class WSDLToolsTestCase(unittest.TestCase): | |||||
| raise | raise | ||||
| if self.wsdl.extensions: | if self.wsdl.extensions: | ||||
| print 'No check for WSDLTools(%s) Extensions:' % (self.wsdl.name) | |||||
| print('No check for WSDLTools(%s) Extensions:' % (self.wsdl.name)) | |||||
| for ext in self.wsdl.extensions: | for ext in self.wsdl.extensions: | ||||
| print '\t', ext | |||||
| print('\t', ext) | |||||
| def schemaAttributesDeclarations(self, schema, node): | def schemaAttributesDeclarations(self, schema, node): | ||||
| self.checkXSDCollection('attribute', schema.attr_decl, node) | self.checkXSDCollection('attribute', schema.attr_decl, node) | ||||
| @@ -150,13 +161,14 @@ class WSDLToolsTestCase(unittest.TestCase): | |||||
| def setUpOptions(section): | def setUpOptions(section): | ||||
| cp = ConfigParser.ConfigParser() | |||||
| cp = configparser.ConfigParser() | |||||
| cp.optionxform = str | |||||
| cp.read(cwd + '/config.txt') | cp.read(cwd + '/config.txt') | ||||
| if not cp.sections(): | if not cp.sections(): | ||||
| print 'fatal error: configuration file config.txt not present' | |||||
| print('fatal error: configuration file config.txt not present') | |||||
| sys.exit(0) | sys.exit(0) | ||||
| if not cp.has_section(section): | if not cp.has_section(section): | ||||
| print '%s section not present in configuration file, exiting' % section | |||||
| print('%s section not present in configuration file, exiting' % section) | |||||
| sys.exit(0) | sys.exit(0) | ||||
| return cp, len(cp.options(section)) | return cp, len(cp.options(section)) | ||||
| @@ -1,6 +1,6 @@ | |||||
| [tox] | [tox] | ||||
| minversion = 1.3 | minversion = 1.3 | ||||
| envlist = py26,py27,py33,py34,flake8 | |||||
| envlist = py26,py27,py34,flake8 | |||||
| [testenv] | [testenv] | ||||
| deps= | deps= | ||||
| @@ -1 +0,0 @@ | |||||
| *.pyc | |||||
| @@ -136,6 +136,7 @@ WSRFLIST = (WSRF_V1_2,) | |||||
| class OASIS: | class OASIS: | ||||
| '''URLs for Oasis specifications | '''URLs for Oasis specifications | ||||
| ''' | ''' | ||||
| WSSE = "http://docs.oasis-open.org/wss/2004/01/" | WSSE = "http://docs.oasis-open.org/wss/2004/01/" | ||||
| @@ -164,6 +165,7 @@ class OASIS: | |||||
| class APACHE: | class APACHE: | ||||
| ''' | ''' | ||||
| This name space is defined by AXIS and it is used for the TC in | This name space is defined by AXIS and it is used for the TC in | ||||
| TCapache.py, Map and file attachment (DataHandler) | TCapache.py, Map and file attachment (DataHandler) | ||||
| @@ -222,6 +224,7 @@ WSA_LIST = (WSA200508, WSA200408, WSA200403, WSA200303) | |||||
| class _WSAW(str): | class _WSAW(str): | ||||
| """ | """ | ||||
| Define ADDRESS attribute to be compatible with WSA* layout | Define ADDRESS attribute to be compatible with WSA* layout | ||||
| """ | """ | ||||
| @@ -51,7 +51,7 @@ class TimeoutSocket: | |||||
| apply(sock.connect, addr) | apply(sock.connect, addr) | ||||
| sock.setblocking(timeout != 0) | sock.setblocking(timeout != 0) | ||||
| return 1 | return 1 | ||||
| except socket.error, why: | |||||
| except socket.error as why: | |||||
| if not timeout: | if not timeout: | ||||
| raise | raise | ||||
| sock.setblocking(1) | sock.setblocking(1) | ||||
| @@ -67,7 +67,7 @@ class TimeoutSocket: | |||||
| try: | try: | ||||
| apply(sock.connect, addr) | apply(sock.connect, addr) | ||||
| return 1 | return 1 | ||||
| except socket.error, why: | |||||
| except socket.error as why: | |||||
| if len(why.args) == 1: | if len(why.args) == 1: | ||||
| code = 0 | code = 0 | ||||
| else: | else: | ||||
| @@ -15,15 +15,27 @@ | |||||
| ident = "$Id$" | ident = "$Id$" | ||||
| import copy | |||||
| import sys | import sys | ||||
| import types | import types | ||||
| import string | |||||
| import six | |||||
| import socket | import socket | ||||
| import weakref | import weakref | ||||
| from os.path import isfile | from os.path import isfile | ||||
| from string import join, strip, split | |||||
| from UserDict import UserDict | |||||
| import urllib | import urllib | ||||
| try: | |||||
| from urlparse import urljoin as basejoin | |||||
| except: | |||||
| from urllib.parse import urljoin as basejoin | |||||
| try: | |||||
| from UserDict import UserDict | |||||
| from UserDict import DictMixin | |||||
| except ImportError: | |||||
| from collections import UserDict | |||||
| from collections import MutableMapping as DictMixin | |||||
| from .TimeoutSocket import TimeoutSocket, TimeoutError | from .TimeoutSocket import TimeoutSocket, TimeoutError | ||||
| @@ -42,9 +54,10 @@ try: | |||||
| except ImportError: | except ImportError: | ||||
| from http.client import HTTPConnection, HTTPSConnection | from http.client import HTTPConnection, HTTPSConnection | ||||
| from exceptions import Exception | |||||
| try: | |||||
| from exceptions import Exception | |||||
| except: | |||||
| pass | |||||
| try: | try: | ||||
| from ZSI import _get_idstr | from ZSI import _get_idstr | ||||
| except: | except: | ||||
| @@ -61,9 +74,10 @@ import xml.dom.minidom | |||||
| from xml.dom import Node | from xml.dom import Node | ||||
| import logging | import logging | ||||
| from c14n import Canonicalize | |||||
| from Namespaces import SCHEMA, SOAP, XMLNS, ZSI_SCHEMA_URI | |||||
| from .c14n import Canonicalize | |||||
| from .Namespaces import SCHEMA, SOAP, XMLNS, ZSI_SCHEMA_URI | |||||
| DEFAULT = "".join | |||||
| try: | try: | ||||
| from xml.dom.ext import SplitQName | from xml.dom.ext import SplitQName | ||||
| @@ -91,20 +105,6 @@ except: | |||||
| return | return | ||||
| return tuple(l) | return tuple(l) | ||||
| # | |||||
| # python2.3 urllib.basejoin does not remove current directory ./ | |||||
| # from path and this causes problems on subsequent basejoins. | |||||
| # | |||||
| basejoin = urllib.basejoin | |||||
| if sys.version_info[0:2] < (2, 4, 0, 'final', 0)[0:2]: | |||||
| #basejoin = lambda base,url: urllib.basejoin(base,url.lstrip('./')) | |||||
| token = './' | |||||
| def basejoin(base, url): | |||||
| if url.startswith(token) is True: | |||||
| return urllib.basejoin(base, url[2:]) | |||||
| return urllib.basejoin(base, url) | |||||
| class NamespaceError(Exception): | class NamespaceError(Exception): | ||||
| @@ -235,7 +235,7 @@ def urlopen(url, timeout=20, redirects=None): | |||||
| if redirects is not None and location in redirects: | if redirects is not None and location in redirects: | ||||
| raise RecursionError( | raise RecursionError( | ||||
| 'Circular HTTP redirection detected.' | 'Circular HTTP redirection detected.' | ||||
| ) | |||||
| ) | |||||
| if redirects is None: | if redirects is None: | ||||
| redirects = {} | redirects = {} | ||||
| redirects[location] = 1 | redirects[location] = 1 | ||||
| @@ -289,40 +289,40 @@ class DOM: | |||||
| return value | return value | ||||
| raise ValueError( | raise ValueError( | ||||
| 'Unsupported SOAP envelope uri: %s' % uri | 'Unsupported SOAP envelope uri: %s' % uri | ||||
| ) | |||||
| ) | |||||
| def GetSOAPEnvUri(self, version): | def GetSOAPEnvUri(self, version): | ||||
| """Return the appropriate SOAP envelope uri for a given | """Return the appropriate SOAP envelope uri for a given | ||||
| human-friendly SOAP version string (e.g. '1.1').""" | human-friendly SOAP version string (e.g. '1.1').""" | ||||
| attrname = 'NS_SOAP_ENV_%s' % join(split(version, '.'), '_') | |||||
| attrname = 'NS_SOAP_ENV_%s' % '_'.join(version.split('.')) | |||||
| value = getattr(self, attrname, None) | value = getattr(self, attrname, None) | ||||
| if value is not None: | if value is not None: | ||||
| return value | return value | ||||
| raise ValueError( | raise ValueError( | ||||
| 'Unsupported SOAP version: %s' % version | 'Unsupported SOAP version: %s' % version | ||||
| ) | |||||
| ) | |||||
| def GetSOAPEncUri(self, version): | def GetSOAPEncUri(self, version): | ||||
| """Return the appropriate SOAP encoding uri for a given | """Return the appropriate SOAP encoding uri for a given | ||||
| human-friendly SOAP version string (e.g. '1.1').""" | human-friendly SOAP version string (e.g. '1.1').""" | ||||
| attrname = 'NS_SOAP_ENC_%s' % join(split(version, '.'), '_') | |||||
| attrname = 'NS_SOAP_ENC_%s' % '_'.join(version.split('.')) | |||||
| value = getattr(self, attrname, None) | value = getattr(self, attrname, None) | ||||
| if value is not None: | if value is not None: | ||||
| return value | return value | ||||
| raise ValueError( | raise ValueError( | ||||
| 'Unsupported SOAP version: %s' % version | 'Unsupported SOAP version: %s' % version | ||||
| ) | |||||
| ) | |||||
| def GetSOAPActorNextUri(self, version): | def GetSOAPActorNextUri(self, version): | ||||
| """Return the right special next-actor uri for a given | """Return the right special next-actor uri for a given | ||||
| human-friendly SOAP version string (e.g. '1.1').""" | human-friendly SOAP version string (e.g. '1.1').""" | ||||
| attrname = 'SOAP_ACTOR_NEXT_%s' % join(split(version, '.'), '_') | |||||
| attrname = 'SOAP_ACTOR_NEXT_%s' % '_'.join(version.split('.')) | |||||
| value = getattr(self, attrname, None) | value = getattr(self, attrname, None) | ||||
| if value is not None: | if value is not None: | ||||
| return value | return value | ||||
| raise ValueError( | raise ValueError( | ||||
| 'Unsupported SOAP version: %s' % version | 'Unsupported SOAP version: %s' % version | ||||
| ) | |||||
| ) | |||||
| # Namespace stuff related to XML Schema. | # Namespace stuff related to XML Schema. | ||||
| NS_XSD_99 = 'http://www.w3.org/1999/XMLSchema' | NS_XSD_99 = 'http://www.w3.org/1999/XMLSchema' | ||||
| @@ -346,7 +346,7 @@ class DOM: | |||||
| NS_XSD_01: NS_XSI_01, | NS_XSD_01: NS_XSI_01, | ||||
| } | } | ||||
| for key, value in _xsd_uri_mapping.items(): | |||||
| for key, value in copy.deepcopy(_xsd_uri_mapping).items(): | |||||
| _xsd_uri_mapping[value] = key | _xsd_uri_mapping[value] = key | ||||
| def InstanceUriForSchemaUri(self, uri): | def InstanceUriForSchemaUri(self, uri): | ||||
| @@ -391,52 +391,52 @@ class DOM: | |||||
| return value | return value | ||||
| raise ValueError( | raise ValueError( | ||||
| 'Unsupported SOAP envelope uri: %s' % uri | 'Unsupported SOAP envelope uri: %s' % uri | ||||
| ) | |||||
| ) | |||||
| def GetWSDLUri(self, version): | def GetWSDLUri(self, version): | ||||
| attr = 'NS_WSDL_%s' % join(split(version, '.'), '_') | |||||
| attr = 'NS_WSDL_%s' % '_'.join(version.split('.')) | |||||
| value = getattr(self, attr, None) | value = getattr(self, attr, None) | ||||
| if value is not None: | if value is not None: | ||||
| return value | return value | ||||
| raise ValueError( | raise ValueError( | ||||
| 'Unsupported WSDL version: %s' % version | 'Unsupported WSDL version: %s' % version | ||||
| ) | |||||
| ) | |||||
| def GetWSDLSoapBindingUri(self, version): | def GetWSDLSoapBindingUri(self, version): | ||||
| attr = 'NS_SOAP_BINDING_%s' % join(split(version, '.'), '_') | |||||
| attr = 'NS_SOAP_BINDING_%s' % '_'.join(version.split('.')) | |||||
| value = getattr(self, attr, None) | value = getattr(self, attr, None) | ||||
| if value is not None: | if value is not None: | ||||
| return value | return value | ||||
| raise ValueError( | raise ValueError( | ||||
| 'Unsupported WSDL version: %s' % version | 'Unsupported WSDL version: %s' % version | ||||
| ) | |||||
| ) | |||||
| def GetWSDLHttpBindingUri(self, version): | def GetWSDLHttpBindingUri(self, version): | ||||
| attr = 'NS_HTTP_BINDING_%s' % join(split(version, '.'), '_') | |||||
| attr = 'NS_HTTP_BINDING_%s' % '_'.join(version.split('.')) | |||||
| value = getattr(self, attr, None) | value = getattr(self, attr, None) | ||||
| if value is not None: | if value is not None: | ||||
| return value | return value | ||||
| raise ValueError( | raise ValueError( | ||||
| 'Unsupported WSDL version: %s' % version | 'Unsupported WSDL version: %s' % version | ||||
| ) | |||||
| ) | |||||
| def GetWSDLMimeBindingUri(self, version): | def GetWSDLMimeBindingUri(self, version): | ||||
| attr = 'NS_MIME_BINDING_%s' % join(split(version, '.'), '_') | |||||
| attr = 'NS_MIME_BINDING_%s' % '_'.join(version.split('.')) | |||||
| value = getattr(self, attr, None) | value = getattr(self, attr, None) | ||||
| if value is not None: | if value is not None: | ||||
| return value | return value | ||||
| raise ValueError( | raise ValueError( | ||||
| 'Unsupported WSDL version: %s' % version | 'Unsupported WSDL version: %s' % version | ||||
| ) | |||||
| ) | |||||
| def GetWSDLHttpTransportUri(self, version): | def GetWSDLHttpTransportUri(self, version): | ||||
| attr = 'NS_SOAP_HTTP_%s' % join(split(version, '.'), '_') | |||||
| attr = 'NS_SOAP_HTTP_%s' % '_'.join(version.split('.')) | |||||
| value = getattr(self, attr, None) | value = getattr(self, attr, None) | ||||
| if value is not None: | if value is not None: | ||||
| return value | return value | ||||
| raise ValueError( | raise ValueError( | ||||
| 'Unsupported WSDL version: %s' % version | 'Unsupported WSDL version: %s' % version | ||||
| ) | |||||
| ) | |||||
| # Other xml namespace constants. | # Other xml namespace constants. | ||||
| NS_XMLNS = 'http://www.w3.org/2000/xmlns/' | NS_XMLNS = 'http://www.w3.org/2000/xmlns/' | ||||
| @@ -449,7 +449,7 @@ class DOM: | |||||
| return node.localName == name and \ | return node.localName == name and \ | ||||
| (nsuri is None or self.nsUriMatch(node.namespaceURI, nsuri)) | (nsuri is None or self.nsUriMatch(node.namespaceURI, nsuri)) | ||||
| def getElement(self, node, name, nsuri=None, default=join): | |||||
| def getElement(self, node, name, nsuri=None, default=DEFAULT): | |||||
| """Return the first child of node with a matching name and | """Return the first child of node with a matching name and | ||||
| namespace uri, or the default if one is provided.""" | namespace uri, or the default if one is provided.""" | ||||
| nsmatch = self.nsUriMatch | nsmatch = self.nsUriMatch | ||||
| @@ -457,13 +457,13 @@ class DOM: | |||||
| for child in node.childNodes: | for child in node.childNodes: | ||||
| if child.nodeType == ELEMENT_NODE: | if child.nodeType == ELEMENT_NODE: | ||||
| if ((child.localName == name or name is None) and | if ((child.localName == name or name is None) and | ||||
| (nsuri is None or nsmatch(child.namespaceURI, nsuri))): | |||||
| (nsuri is None or nsmatch(child.namespaceURI, nsuri))): | |||||
| return child | return child | ||||
| if default is not join: | |||||
| if default != DEFAULT: | |||||
| return default | return default | ||||
| raise KeyError(name) | raise KeyError(name) | ||||
| def getElementById(self, node, id, default=join): | |||||
| def getElementById(self, node, id, default=DEFAULT): | |||||
| """Return the first child of node matching an id reference.""" | """Return the first child of node matching an id reference.""" | ||||
| attrget = self.getAttr | attrget = self.getAttr | ||||
| ELEMENT_NODE = node.ELEMENT_NODE | ELEMENT_NODE = node.ELEMENT_NODE | ||||
| @@ -471,7 +471,7 @@ class DOM: | |||||
| if child.nodeType == ELEMENT_NODE: | if child.nodeType == ELEMENT_NODE: | ||||
| if attrget(child, 'id') == id: | if attrget(child, 'id') == id: | ||||
| return child | return child | ||||
| if default is not join: | |||||
| if default != DEFAULT: | |||||
| return default | return default | ||||
| raise KeyError(name) | raise KeyError(name) | ||||
| @@ -503,7 +503,7 @@ class DOM: | |||||
| for child in node.childNodes: | for child in node.childNodes: | ||||
| if child.nodeType == ELEMENT_NODE: | if child.nodeType == ELEMENT_NODE: | ||||
| if ((child.localName == name or name is None) and ( | if ((child.localName == name or name is None) and ( | ||||
| (nsuri is None) or nsmatch(child.namespaceURI, nsuri))): | |||||
| (nsuri is None) or nsmatch(child.namespaceURI, nsuri))): | |||||
| result.append(child) | result.append(child) | ||||
| return result | return result | ||||
| @@ -517,23 +517,35 @@ class DOM: | |||||
| return False | return False | ||||
| return node.hasAttributeNS(nsuri, name) | return node.hasAttributeNS(nsuri, name) | ||||
| def getAttr(self, node, name, nsuri=None, default=join): | |||||
| def getAttr(self, node, name, nsuri=None, default=DEFAULT): | |||||
| """Return the value of the attribute named 'name' with the | """Return the value of the attribute named 'name' with the | ||||
| optional nsuri, or the default if one is specified. If | optional nsuri, or the default if one is specified. If | ||||
| nsuri is not specified, an attribute that matches the | nsuri is not specified, an attribute that matches the | ||||
| given name will be returned regardless of namespace.""" | given name will be returned regardless of namespace.""" | ||||
| if nsuri is None: | if nsuri is None: | ||||
| result = node._attrs.get(name, None) | |||||
| if node._attrs is None: | |||||
| result = None | |||||
| else: | |||||
| result = node._attrs.get(name, None) | |||||
| if result is None: | if result is None: | ||||
| for item in node._attrsNS.keys(): | |||||
| if item[1] == name: | |||||
| result = node._attrsNS[item] | |||||
| break | |||||
| if node._attrsNS is None: | |||||
| result = None | |||||
| else: | |||||
| for item in node._attrsNS.keys(): | |||||
| if item[1] == name: | |||||
| result = node._attrsNS[item] | |||||
| break | |||||
| else: | else: | ||||
| result = node._attrsNS.get((nsuri, name), None) | |||||
| if node._attrsNS is None: | |||||
| result = None | |||||
| else: | |||||
| if node._attrsNS is None: | |||||
| result = None | |||||
| else: | |||||
| result = node._attrsNS.get((nsuri, name), None) | |||||
| if result is not None: | if result is not None: | ||||
| return result.value | return result.value | ||||
| if default is not join: | |||||
| if default != DEFAULT: | |||||
| return default | return default | ||||
| return '' | return '' | ||||
| @@ -555,9 +567,9 @@ class DOM: | |||||
| if nodetype == child.TEXT_NODE or \ | if nodetype == child.TEXT_NODE or \ | ||||
| nodetype == child.CDATA_SECTION_NODE: | nodetype == child.CDATA_SECTION_NODE: | ||||
| result.append(child.nodeValue) | result.append(child.nodeValue) | ||||
| value = join(result, '') | |||||
| value = ''.join(result) | |||||
| if preserve_ws is None: | if preserve_ws is None: | ||||
| value = strip(value) | |||||
| value = value.strip() | |||||
| return value | return value | ||||
| def findNamespaceURI(self, prefix, node): | def findNamespaceURI(self, prefix, node): | ||||
| @@ -901,7 +913,7 @@ class ElementProxy(Base, MessageInterface): | |||||
| for attr in node.attributes.values(): | for attr in node.attributes.values(): | ||||
| if attr.namespaceURI == XMLNS.BASE \ | if attr.namespaceURI == XMLNS.BASE \ | ||||
| and nsuri == attr.value: | and nsuri == attr.value: | ||||
| return attr.localName | |||||
| return attr.localName | |||||
| else: | else: | ||||
| if node.parentNode: | if node.parentNode: | ||||
| return self._getPrefix(node.parentNode, nsuri) | return self._getPrefix(node.parentNode, nsuri) | ||||
| @@ -1190,8 +1202,8 @@ class Collection(UserDict): | |||||
| self._func = key or self.default | self._func = key or self.default | ||||
| def __getitem__(self, key): | def __getitem__(self, key): | ||||
| NumberTypes = (types.IntType, types.LongType, types.FloatType, | |||||
| types.ComplexType) | |||||
| NumberTypes = six.integer_types | |||||
| NumberTypes = NumberTypes + (type(float), type(complex)) | |||||
| if isinstance(key, NumberTypes): | if isinstance(key, NumberTypes): | ||||
| return self.list[key] | return self.list[key] | ||||
| return self.data[key] | return self.data[key] | ||||
| @@ -1226,7 +1238,7 @@ class CollectionNS(UserDict): | |||||
| def __getitem__(self, key): | def __getitem__(self, key): | ||||
| self.targetNamespace = self.parent().targetNamespace | self.targetNamespace = self.parent().targetNamespace | ||||
| if isinstance(key, types.IntType): | |||||
| if isinstance(key, six.integer_types): | |||||
| return self.list[key] | return self.list[key] | ||||
| elif self.__isSequence(key): | elif self.__isSequence(key): | ||||
| nsuri, name = key | nsuri, name = key | ||||
| @@ -1243,7 +1255,7 @@ class CollectionNS(UserDict): | |||||
| self.data[targetNamespace][key] = item | self.data[targetNamespace][key] = item | ||||
| def __isSequence(self, key): | def __isSequence(self, key): | ||||
| return (type(key) in (types.TupleType, types.ListType) | |||||
| return (isinstance(key, (tuple, list)) | |||||
| and len(key) == 2) | and len(key) == 2) | ||||
| def keys(self): | def keys(self): | ||||
| @@ -21,6 +21,7 @@ from .XMLSchema import XMLSchema, SchemaReader, WSDLToolsAdapter | |||||
| class WSDLReader: | class WSDLReader: | ||||
| """A WSDLReader creates WSDL instances from urls and xml data.""" | """A WSDLReader creates WSDL instances from urls and xml data.""" | ||||
| # Custom subclasses of WSDLReader may wish to implement a caching | # Custom subclasses of WSDLReader may wish to implement a caching | ||||
| @@ -61,6 +62,7 @@ class WSDLReader: | |||||
| class WSDL: | class WSDL: | ||||
| """A WSDL object models a WSDL service description. WSDL objects | """A WSDL object models a WSDL service description. WSDL objects | ||||
| may be created manually or loaded from an xml representation | may be created manually or loaded from an xml representation | ||||
| using a WSDLReader instance.""" | using a WSDLReader instance.""" | ||||
| @@ -90,7 +92,7 @@ class WSDL: | |||||
| if name in self.services: | if name in self.services: | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Duplicate service element: %s' % name | 'Duplicate service element: %s' % name | ||||
| ) | |||||
| ) | |||||
| item = Service(name, documentation) | item = Service(name, documentation) | ||||
| if targetNamespace: | if targetNamespace: | ||||
| item.targetNamespace = targetNamespace | item.targetNamespace = targetNamespace | ||||
| @@ -101,7 +103,7 @@ class WSDL: | |||||
| if name in self.messages: | if name in self.messages: | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Duplicate message element: %s.' % name | 'Duplicate message element: %s.' % name | ||||
| ) | |||||
| ) | |||||
| item = Message(name, documentation) | item = Message(name, documentation) | ||||
| if targetNamespace: | if targetNamespace: | ||||
| item.targetNamespace = targetNamespace | item.targetNamespace = targetNamespace | ||||
| @@ -112,7 +114,7 @@ class WSDL: | |||||
| if name in self.portTypes: | if name in self.portTypes: | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Duplicate portType element: name' | 'Duplicate portType element: name' | ||||
| ) | |||||
| ) | |||||
| item = PortType(name, documentation) | item = PortType(name, documentation) | ||||
| if targetNamespace: | if targetNamespace: | ||||
| item.targetNamespace = targetNamespace | item.targetNamespace = targetNamespace | ||||
| @@ -123,7 +125,7 @@ class WSDL: | |||||
| if name in self.bindings: | if name in self.bindings: | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Duplicate binding element: %s' % name | 'Duplicate binding element: %s' % name | ||||
| ) | |||||
| ) | |||||
| item = Binding(name, type, documentation) | item = Binding(name, type, documentation) | ||||
| if targetNamespace: | if targetNamespace: | ||||
| item.targetNamespace = targetNamespace | item.targetNamespace = targetNamespace | ||||
| @@ -182,7 +184,7 @@ class WSDL: | |||||
| if definitions is None: | if definitions is None: | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Missing <definitions> element.' | 'Missing <definitions> element.' | ||||
| ) | |||||
| ) | |||||
| self.version = DOM.WSDLUriToVersion(definitions.namespaceURI) | self.version = DOM.WSDLUriToVersion(definitions.namespaceURI) | ||||
| NS_WSDL = DOM.GetWSDLUri(self.version) | NS_WSDL = DOM.GetWSDLUri(self.version) | ||||
| @@ -261,7 +263,7 @@ class WSDL: | |||||
| if type is None: | if type is None: | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Missing type attribute for binding %s.' % name | 'Missing type attribute for binding %s.' % name | ||||
| ) | |||||
| ) | |||||
| type = ParseQName(type, element) | type = ParseQName(type, element) | ||||
| docs = GetDocumentation(element) | docs = GetDocumentation(element) | ||||
| binding = self.addBinding(name, type, docs, targetNamespace) | binding = self.addBinding(name, type, docs, targetNamespace) | ||||
| @@ -318,7 +320,7 @@ class WSDL: | |||||
| if namespace is None or location is None: | if namespace is None or location is None: | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Invalid import element (missing namespace or location).' | 'Invalid import element (missing namespace or location).' | ||||
| ) | |||||
| ) | |||||
| if base_location: | if base_location: | ||||
| location = basejoin(base_location, location) | location = basejoin(base_location, location) | ||||
| element.setAttributeNS(None, 'location', location) | element.setAttributeNS(None, 'location', location) | ||||
| @@ -336,7 +338,7 @@ class WSDL: | |||||
| if imported is None: | if imported is None: | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Import target element not found for: %s' % location | 'Import target element not found for: %s' % location | ||||
| ) | |||||
| ) | |||||
| imported_tns = DOM.findTargetNS(imported) | imported_tns = DOM.findTargetNS(imported) | ||||
| if imported_tns != namespace: | if imported_tns != namespace: | ||||
| @@ -376,7 +378,9 @@ class WSDL: | |||||
| class Element: | class Element: | ||||
| """A class that provides common functions for WSDL element classes.""" | """A class that provides common functions for WSDL element classes.""" | ||||
| def __init__(self, name=None, documentation=''): | def __init__(self, name=None, documentation=''): | ||||
| self.name = name | self.name = name | ||||
| self.documentation = documentation | self.documentation = documentation | ||||
| @@ -402,6 +406,7 @@ class Element: | |||||
| class ImportElement(Element): | class ImportElement(Element): | ||||
| def __init__(self, namespace, location): | def __init__(self, namespace, location): | ||||
| self.namespace = namespace | self.namespace = namespace | ||||
| self.location = location | self.location = location | ||||
| @@ -438,6 +443,7 @@ class Types(Collection): | |||||
| class Message(Element): | class Message(Element): | ||||
| def __init__(self, name, documentation=''): | def __init__(self, name, documentation=''): | ||||
| Element.__init__(self, name, documentation) | Element.__init__(self, name, documentation) | ||||
| self.parts = Collection(self) | self.parts = Collection(self) | ||||
| @@ -446,11 +452,11 @@ class Message(Element): | |||||
| if name in self.parts: | if name in self.parts: | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Duplicate message part element: %s' % name | 'Duplicate message part element: %s' % name | ||||
| ) | |||||
| ) | |||||
| if type is None and element is None: | if type is None and element is None: | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Missing type or element attribute for part: %s' % name | 'Missing type or element attribute for part: %s' % name | ||||
| ) | |||||
| ) | |||||
| item = MessagePart(name) | item = MessagePart(name) | ||||
| item.element = element | item.element = element | ||||
| item.type = type | item.type = type | ||||
| @@ -467,7 +473,7 @@ class Message(Element): | |||||
| if typeref is None and elemref is None: | if typeref is None and elemref is None: | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'No type or element attribute for part: %s' % name | 'No type or element attribute for part: %s' % name | ||||
| ) | |||||
| ) | |||||
| if typeref is not None: | if typeref is not None: | ||||
| part.type = ParseTypeRef(typeref, element) | part.type = ParseTypeRef(typeref, element) | ||||
| if elemref is not None: | if elemref is not None: | ||||
| @@ -508,6 +514,7 @@ class Message(Element): | |||||
| class MessagePart(Element): | class MessagePart(Element): | ||||
| def __init__(self, name): | def __init__(self, name): | ||||
| Element.__init__(self, name, '') | Element.__init__(self, name, '') | ||||
| self.element = None | self.element = None | ||||
| @@ -547,6 +554,7 @@ class MessagePart(Element): | |||||
| class PortType(Element): | class PortType(Element): | ||||
| '''PortType has a anyAttribute, thus must provide for an extensible | '''PortType has a anyAttribute, thus must provide for an extensible | ||||
| mechanism for supporting such attributes. ResourceProperties is | mechanism for supporting such attributes. ResourceProperties is | ||||
| specified in WS-ResourceProperties. wsa:Action is specified in | specified in WS-ResourceProperties. wsa:Action is specified in | ||||
| @@ -644,13 +652,14 @@ class PortType(Element): | |||||
| ns, name = self.resourceProperties | ns, name = self.resourceProperties | ||||
| prefix = epc.getPrefix(ns) | prefix = epc.getPrefix(ns) | ||||
| epc.setAttributeNS(WSRF.PROPERTIES.LATEST, 'ResourceProperties', | epc.setAttributeNS(WSRF.PROPERTIES.LATEST, 'ResourceProperties', | ||||
| '%s:%s' % (prefix, name)) | |||||
| '%s:%s' % (prefix, name)) | |||||
| for op in self.operations: | for op in self.operations: | ||||
| op.toDom(epc._getNode()) | op.toDom(epc._getNode()) | ||||
| class Operation(Element): | class Operation(Element): | ||||
| def __init__(self, name, documentation='', parameterOrder=None): | def __init__(self, name, documentation='', parameterOrder=None): | ||||
| Element.__init__(self, name, documentation) | Element.__init__(self, name, documentation) | ||||
| self.parameterOrder = parameterOrder | self.parameterOrder = parameterOrder | ||||
| @@ -697,7 +706,7 @@ class Operation(Element): | |||||
| if name in self.faults: | if name in self.faults: | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Duplicate fault element: %s' % name | 'Duplicate fault element: %s' % name | ||||
| ) | |||||
| ) | |||||
| item = MessageRole('fault', message, name, documentation, action) | item = MessageRole('fault', message, name, documentation, action) | ||||
| self.faults[name] = item | self.faults[name] = item | ||||
| return item | return item | ||||
| @@ -728,6 +737,7 @@ class Operation(Element): | |||||
| class MessageRole(Element): | class MessageRole(Element): | ||||
| def __init__(self, type, message, name='', documentation='', action=None): | def __init__(self, type, message, name='', documentation='', action=None): | ||||
| Element.__init__(self, name, documentation) | Element.__init__(self, name, documentation) | ||||
| self.message = message | self.message = message | ||||
| @@ -775,6 +785,7 @@ class MessageRole(Element): | |||||
| class Binding(Element): | class Binding(Element): | ||||
| def __init__(self, name, type, documentation=''): | def __init__(self, name, type, documentation=''): | ||||
| Element.__init__(self, name, documentation) | Element.__init__(self, name, documentation) | ||||
| self.operations = Collection(self) | self.operations = Collection(self) | ||||
| @@ -869,6 +880,7 @@ class Binding(Element): | |||||
| class OperationBinding(Element): | class OperationBinding(Element): | ||||
| def __init__(self, name, documentation=''): | def __init__(self, name, documentation=''): | ||||
| Element.__init__(self, name, documentation) | Element.__init__(self, name, documentation) | ||||
| self.input = None | self.input = None | ||||
| @@ -952,6 +964,7 @@ class OperationBinding(Element): | |||||
| class MessageRoleBinding(Element): | class MessageRoleBinding(Element): | ||||
| def __init__(self, type, name='', documentation=''): | def __init__(self, type, name='', documentation=''): | ||||
| Element.__init__(self, name, documentation) | Element.__init__(self, name, documentation) | ||||
| self.type = type | self.type = type | ||||
| @@ -976,7 +989,7 @@ class MessageRoleBinding(Element): | |||||
| if use is None: | if use is None: | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Invalid soap:body binding element.' | 'Invalid soap:body binding element.' | ||||
| ) | |||||
| ) | |||||
| ob = SoapBodyBinding(use, namespace, encstyle, parts) | ob = SoapBodyBinding(use, namespace, encstyle, parts) | ||||
| self.addExtension(ob) | self.addExtension(ob) | ||||
| continue | continue | ||||
| @@ -989,14 +1002,14 @@ class MessageRoleBinding(Element): | |||||
| if use is None or name is None: | if use is None or name is None: | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Invalid soap:fault binding element.' | 'Invalid soap:fault binding element.' | ||||
| ) | |||||
| ) | |||||
| ob = SoapFaultBinding(name, use, namespace, encstyle) | ob = SoapFaultBinding(name, use, namespace, encstyle) | ||||
| self.addExtension(ob) | self.addExtension(ob) | ||||
| continue | continue | ||||
| elif ns in DOM.NS_SOAP_BINDING_ALL and name in ( | elif ns in DOM.NS_SOAP_BINDING_ALL and name in ( | ||||
| 'header', 'headerfault' | 'header', 'headerfault' | ||||
| ): | |||||
| ): | |||||
| encstyle = DOM.getAttr(e, 'encodingStyle', default=None) | encstyle = DOM.getAttr(e, 'encodingStyle', default=None) | ||||
| namespace = DOM.getAttr(e, 'namespace', default=None) | namespace = DOM.getAttr(e, 'namespace', default=None) | ||||
| message = DOM.getAttr(e, 'message') | message = DOM.getAttr(e, 'message') | ||||
| @@ -1055,6 +1068,7 @@ class MessageRoleBinding(Element): | |||||
| class Service(Element): | class Service(Element): | ||||
| def __init__(self, name, documentation=''): | def __init__(self, name, documentation=''): | ||||
| Element.__init__(self, name, documentation) | Element.__init__(self, name, documentation) | ||||
| self.ports = Collection(self) | self.ports = Collection(self) | ||||
| @@ -1075,7 +1089,7 @@ class Service(Element): | |||||
| if name is None or binding is None: | if name is None or binding is None: | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Invalid port element.' | 'Invalid port element.' | ||||
| ) | |||||
| ) | |||||
| binding = ParseQName(binding, element) | binding = ParseQName(binding, element) | ||||
| port = self.addPort(name, binding, docs) | port = self.addPort(name, binding, docs) | ||||
| port.load_ex(GetExtensions(element)) | port.load_ex(GetExtensions(element)) | ||||
| @@ -1096,6 +1110,7 @@ class Service(Element): | |||||
| class Port(Element): | class Port(Element): | ||||
| def __init__(self, name, binding, documentation=''): | def __init__(self, name, binding, documentation=''): | ||||
| Element.__init__(self, name, documentation) | Element.__init__(self, name, documentation) | ||||
| self.binding = binding | self.binding = binding | ||||
| @@ -1127,7 +1142,7 @@ class Port(Element): | |||||
| return item | return item | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'No address binding found in port.' | 'No address binding found in port.' | ||||
| ) | |||||
| ) | |||||
| def load_ex(self, elements): | def load_ex(self, elements): | ||||
| for e in elements: | for e in elements: | ||||
| @@ -1161,6 +1176,7 @@ class Port(Element): | |||||
| class SoapBinding: | class SoapBinding: | ||||
| def __init__(self, transport, style='rpc'): | def __init__(self, transport, style='rpc'): | ||||
| self.transport = transport | self.transport = transport | ||||
| self.style = style | self.style = style | ||||
| @@ -1179,6 +1195,7 @@ class SoapBinding: | |||||
| class SoapAddressBinding: | class SoapAddressBinding: | ||||
| def __init__(self, location): | def __init__(self, location): | ||||
| self.location = location | self.location = location | ||||
| @@ -1193,6 +1210,7 @@ class SoapAddressBinding: | |||||
| class SoapOperationBinding: | class SoapOperationBinding: | ||||
| def __init__(self, soapAction=None, style=None): | def __init__(self, soapAction=None, style=None): | ||||
| self.soapAction = soapAction | self.soapAction = soapAction | ||||
| self.style = style | self.style = style | ||||
| @@ -1211,11 +1229,12 @@ class SoapOperationBinding: | |||||
| class SoapBodyBinding: | class SoapBodyBinding: | ||||
| def __init__(self, use, namespace=None, encodingStyle=None, parts=None): | def __init__(self, use, namespace=None, encodingStyle=None, parts=None): | ||||
| if not use in ('literal', 'encoded'): | if not use in ('literal', 'encoded'): | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Invalid use attribute value: %s' % use | 'Invalid use attribute value: %s' % use | ||||
| ) | |||||
| ) | |||||
| self.encodingStyle = encodingStyle | self.encodingStyle = encodingStyle | ||||
| self.namespace = namespace | self.namespace = namespace | ||||
| if type(parts) in (type(''), type(u'')): | if type(parts) in (type(''), type(u'')): | ||||
| @@ -1235,11 +1254,12 @@ class SoapBodyBinding: | |||||
| class SoapFaultBinding: | class SoapFaultBinding: | ||||
| def __init__(self, name, use, namespace=None, encodingStyle=None): | def __init__(self, name, use, namespace=None, encodingStyle=None): | ||||
| if not use in ('literal', 'encoded'): | if not use in ('literal', 'encoded'): | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Invalid use attribute value: %s' % use | 'Invalid use attribute value: %s' % use | ||||
| ) | |||||
| ) | |||||
| self.encodingStyle = encodingStyle | self.encodingStyle = encodingStyle | ||||
| self.namespace = namespace | self.namespace = namespace | ||||
| self.name = name | self.name = name | ||||
| @@ -1261,11 +1281,12 @@ class SoapFaultBinding: | |||||
| class SoapHeaderBinding: | class SoapHeaderBinding: | ||||
| def __init__(self, message, part, use, namespace=None, encodingStyle=None): | def __init__(self, message, part, use, namespace=None, encodingStyle=None): | ||||
| if not use in ('literal', 'encoded'): | if not use in ('literal', 'encoded'): | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Invalid use attribute value: %s' % use | 'Invalid use attribute value: %s' % use | ||||
| ) | |||||
| ) | |||||
| self.encodingStyle = encodingStyle | self.encodingStyle = encodingStyle | ||||
| self.namespace = namespace | self.namespace = namespace | ||||
| self.message = message | self.message = message | ||||
| @@ -1280,16 +1301,19 @@ class SoapHeaderFaultBinding(SoapHeaderBinding): | |||||
| class HttpBinding: | class HttpBinding: | ||||
| def __init__(self, verb): | def __init__(self, verb): | ||||
| self.verb = verb | self.verb = verb | ||||
| class HttpAddressBinding: | class HttpAddressBinding: | ||||
| def __init__(self, location): | def __init__(self, location): | ||||
| self.location = location | self.location = location | ||||
| class HttpOperationBinding: | class HttpOperationBinding: | ||||
| def __init__(self, location): | def __init__(self, location): | ||||
| self.location = location | self.location = location | ||||
| @@ -1303,17 +1327,20 @@ class HttpUrlEncodedBinding: | |||||
| class MimeContentBinding: | class MimeContentBinding: | ||||
| def __init__(self, part=None, type=None): | def __init__(self, part=None, type=None): | ||||
| self.part = part | self.part = part | ||||
| self.type = type | self.type = type | ||||
| class MimeXmlBinding: | class MimeXmlBinding: | ||||
| def __init__(self, part=None): | def __init__(self, part=None): | ||||
| self.part = part | self.part = part | ||||
| class MimeMultipartRelatedBinding: | class MimeMultipartRelatedBinding: | ||||
| def __init__(self): | def __init__(self): | ||||
| self.parts = [] | self.parts = [] | ||||
| @@ -1326,6 +1353,7 @@ class MimeMultipartRelatedBinding: | |||||
| class MimePartBinding: | class MimePartBinding: | ||||
| def __init__(self): | def __init__(self): | ||||
| self.items = [] | self.items = [] | ||||
| @@ -1353,7 +1381,7 @@ class MimePartBinding: | |||||
| if use is None: | if use is None: | ||||
| raise WSDLError( | raise WSDLError( | ||||
| 'Invalid soap:body binding element.' | 'Invalid soap:body binding element.' | ||||
| ) | |||||
| ) | |||||
| ob = SoapBodyBinding(use, namespace, encstyle, parts) | ob = SoapBodyBinding(use, namespace, encstyle, parts) | ||||
| self.items.append(ob) | self.items.append(ob) | ||||
| continue | continue | ||||
| @@ -1397,7 +1425,7 @@ def GetDocumentation(element): | |||||
| def GetExtensions(element): | def GetExtensions(element): | ||||
| return [item for item in DOM.getElements(element, None, None) | return [item for item in DOM.getElements(element, None, None) | ||||
| if item.namespaceURI != DOM.NS_WSDL] | |||||
| if item.namespaceURI != DOM.NS_WSDL] | |||||
| def GetWSAActionFault(operation, name): | def GetWSAActionFault(operation, name): | ||||
| @@ -1446,8 +1474,8 @@ def FindExtensions(object, kind, t_type=type(())): | |||||
| result = [] | result = [] | ||||
| namespaceURI, name = kind | namespaceURI, name = kind | ||||
| return [item for item in object.extensions | return [item for item in object.extensions | ||||
| if hasattr(item, 'nodeType') \ | |||||
| and DOM.nsUriMatch(namespaceURI, item.namespaceURI) \ | |||||
| if hasattr(item, 'nodeType') | |||||
| and DOM.nsUriMatch(namespaceURI, item.namespaceURI) | |||||
| and item.name == name] | and item.name == name] | ||||
| return [item for item in object.extensions if isinstance(item, kind)] | return [item for item in object.extensions if isinstance(item, kind)] | ||||
| @@ -1457,8 +1485,8 @@ def FindExtension(object, kind, t_type=type(())): | |||||
| namespaceURI, name = kind | namespaceURI, name = kind | ||||
| for item in object.extensions: | for item in object.extensions: | ||||
| if hasattr(item, 'nodeType') \ | if hasattr(item, 'nodeType') \ | ||||
| and DOM.nsUriMatch(namespaceURI, item.namespaceURI) \ | |||||
| and item.name == name: | |||||
| and DOM.nsUriMatch(namespaceURI, item.namespaceURI) \ | |||||
| and item.name == name: | |||||
| return item | return item | ||||
| else: | else: | ||||
| for item in object.extensions: | for item in object.extensions: | ||||
| @@ -1468,6 +1496,7 @@ def FindExtension(object, kind, t_type=type(())): | |||||
| class SOAPCallInfo: | class SOAPCallInfo: | ||||
| """SOAPCallInfo captures the important binding information about a | """SOAPCallInfo captures the important binding information about a | ||||
| SOAP operation, in a structure that is easier to work with than | SOAP operation, in a structure that is easier to work with than | ||||
| raw WSDL structures.""" | raw WSDL structures.""" | ||||
| @@ -1547,7 +1576,9 @@ class SOAPCallInfo: | |||||
| class ParameterInfo: | class ParameterInfo: | ||||
| """A ParameterInfo object captures parameter binding information.""" | """A ParameterInfo object captures parameter binding information.""" | ||||
| def __init__(self, name, type, namespace=None, element_type=0): | def __init__(self, name, type, namespace=None, element_type=0): | ||||
| if element_type: | if element_type: | ||||
| self.element_type = 1 | self.element_type = 1 | ||||
| @@ -1562,7 +1593,9 @@ class ParameterInfo: | |||||
| class HeaderInfo(ParameterInfo): | class HeaderInfo(ParameterInfo): | ||||
| """A HeaderInfo object captures SOAP header binding information.""" | """A HeaderInfo object captures SOAP header binding information.""" | ||||
| def __init__(self, name, type, namespace, element_type=None): | def __init__(self, name, type, namespace, element_type=None): | ||||
| ParameterInfo.__init__(self, name, type, namespace, element_type) | ParameterInfo.__init__(self, name, type, namespace, element_type) | ||||
| @@ -1614,7 +1647,7 @@ def callInfoFromWSDL(port, name): | |||||
| part.element or part.type, | part.element or part.type, | ||||
| item.namespace, | item.namespace, | ||||
| element_type=part.element and 1 or 0 | element_type=part.element and 1 or 0 | ||||
| ) | |||||
| ) | |||||
| header.encodingStyle = item.encodingStyle | header.encodingStyle = item.encodingStyle | ||||
| body = msgrole.findBinding(SoapBodyBinding) | body = msgrole.findBinding(SoapBodyBinding) | ||||
| @@ -1636,7 +1669,7 @@ def callInfoFromWSDL(port, name): | |||||
| part.name, | part.name, | ||||
| part.element or part.type, | part.element or part.type, | ||||
| element_type=part.element and 1 or 0 | element_type=part.element and 1 or 0 | ||||
| ) | |||||
| ) | |||||
| if operation.output is not None: | if operation.output is not None: | ||||
| try: | try: | ||||
| @@ -1665,7 +1698,7 @@ def callInfoFromWSDL(port, name): | |||||
| part.element or part.type, | part.element or part.type, | ||||
| item.namespace, | item.namespace, | ||||
| element_type=part.element and 1 or 0 | element_type=part.element and 1 or 0 | ||||
| ) | |||||
| ) | |||||
| header.encodingStyle = item.encodingStyle | header.encodingStyle = item.encodingStyle | ||||
| body = msgrole.findBinding(SoapBodyBinding) | body = msgrole.findBinding(SoapBodyBinding) | ||||
| @@ -1688,6 +1721,6 @@ def callInfoFromWSDL(port, name): | |||||
| part.name, | part.name, | ||||
| part.element or part.type, | part.element or part.type, | ||||
| element_type=part.element and 1 or 0 | element_type=part.element and 1 or 0 | ||||
| ) | |||||
| ) | |||||
| return callinfo | return callinfo | ||||
| @@ -72,9 +72,9 @@ def toXMLname(string): | |||||
| if i < N - 1 and T[i] == u'_' and T[i + 1] == u'x': | if i < N - 1 and T[i] == u'_' and T[i + 1] == u'x': | ||||
| X.append(u'_x005F_') | X.append(u'_x005F_') | ||||
| elif i == 0 and N >= 3 and \ | elif i == 0 and N >= 3 and \ | ||||
| (T[0] == u'x' or T[0] == u'X') and \ | |||||
| (T[1] == u'm' or T[1] == u'M') and \ | |||||
| (T[2] == u'l' or T[2] == u'L'): | |||||
| (T[0] == u'x' or T[0] == u'X') and \ | |||||
| (T[1] == u'm' or T[1] == u'M') and \ | |||||
| (T[2] == u'l' or T[2] == u'L'): | |||||
| X.append(u'_xFFFF_' + T[0]) | X.append(u'_xFFFF_' + T[0]) | ||||
| elif (not _NCNameChar(T[i])) or (i == 0 and not _NCNameStartChar(T[i])): | elif (not _NCNameChar(T[i])) or (i == 0 and not _NCNameStartChar(T[i])): | ||||
| X.append(_toUnicodeHex(T[i])) | X.append(_toUnicodeHex(T[i])) | ||||
| @@ -101,8 +101,8 @@ def _utilized(n, node, other_attrs, unsuppressedPrefixes): | |||||
| elif n.startswith('xmlns'): | elif n.startswith('xmlns'): | ||||
| n = n[5:] | n = n[5:] | ||||
| if (n == "" and node.prefix in ["#default", None]) or \ | if (n == "" and node.prefix in ["#default", None]) or \ | ||||
| n == node.prefix or n in unsuppressedPrefixes: | |||||
| return 1 | |||||
| n == node.prefix or n in unsuppressedPrefixes: | |||||
| return 1 | |||||
| for attr in other_attrs: | for attr in other_attrs: | ||||
| if n == attr.prefix: | if n == attr.prefix: | ||||
| return 1 | return 1 | ||||
| @@ -151,6 +151,7 @@ _in_subset = lambda subset, node: subset is None or node in subset # rich's twe | |||||
| class _implementation: | class _implementation: | ||||
| '''Implementation class for C14N. This accompanies a node during it's | '''Implementation class for C14N. This accompanies a node during it's | ||||
| processing and includes the parameters and processing state.''' | processing and includes the parameters and processing state.''' | ||||
| @@ -174,7 +175,7 @@ class _implementation: | |||||
| self.documentOrder = _Element # At document element | self.documentOrder = _Element # At document element | ||||
| if not _inclusive(self): | if not _inclusive(self): | ||||
| inherited, unused = _inclusiveNamespacePrefixes(node, self._inherit_context(node), | inherited, unused = _inclusiveNamespacePrefixes(node, self._inherit_context(node), | ||||
| self.unsuppressedPrefixes) | |||||
| self.unsuppressedPrefixes) | |||||
| self._do_element(node, inherited, unused=unused) | self._do_element(node, inherited, unused=unused) | ||||
| else: | else: | ||||
| inherited = self._inherit_context(node) | inherited = self._inherit_context(node) | ||||
| @@ -311,7 +312,7 @@ class _implementation: | |||||
| # xml_attrs_local -- Local attributes in XML namespace. | # xml_attrs_local -- Local attributes in XML namespace. | ||||
| # ns_unused_inherited -- not rendered namespaces, used for exclusive | # ns_unused_inherited -- not rendered namespaces, used for exclusive | ||||
| ns_parent, ns_rendered, xml_attrs = \ | ns_parent, ns_rendered, xml_attrs = \ | ||||
| self.state[0], self.state[1].copy(), self.state[2].copy() # 0422 | |||||
| self.state[0], self.state[1].copy(), self.state[2].copy() # 0422 | |||||
| ns_unused_inherited = unused | ns_unused_inherited = unused | ||||
| if unused is None: | if unused is None: | ||||
| @@ -372,14 +373,14 @@ class _implementation: | |||||
| # If default namespace is XMLNS.BASE or empty, | # If default namespace is XMLNS.BASE or empty, | ||||
| # and if an ancestor was the same | # and if an ancestor was the same | ||||
| if n == "xmlns" and v in [XMLNS.BASE, ''] \ | if n == "xmlns" and v in [XMLNS.BASE, ''] \ | ||||
| and ns_rendered.get('xmlns') in [XMLNS.BASE, '', None]: | |||||
| and ns_rendered.get('xmlns') in [XMLNS.BASE, '', None]: | |||||
| continue | continue | ||||
| # "omit namespace node with local name xml, which defines | # "omit namespace node with local name xml, which defines | ||||
| # the xml prefix, if its string value is | # the xml prefix, if its string value is | ||||
| # http://www.w3.org/XML/1998/namespace." | # http://www.w3.org/XML/1998/namespace." | ||||
| if n in ["xmlns:xml", "xml"] \ | if n in ["xmlns:xml", "xml"] \ | ||||
| and v in ['http://www.w3.org/XML/1998/namespace']: | |||||
| and v in ['http://www.w3.org/XML/1998/namespace']: | |||||
| continue | continue | ||||
| # If not previously rendered | # If not previously rendered | ||||
| @@ -1 +1 @@ | |||||
| __version__ = "0.4.3" | |||||
| __version__ = "0.4.4" | |||||