Browse Source

v0.4.4 which finally brings nothing more than Python 3 compatibility

main
Sorin Sbarnea 10 years ago
parent
commit
f74298a5b0
17 changed files with 704 additions and 338 deletions
  1. +2
    -2
      MANIFEST.in
  2. +0
    -30
      README.mdown
  3. +73
    -0
      README.rst
  4. +45
    -0
      setup.cfg
  5. +158
    -21
      setup.py
  6. +3
    -3
      tests/config.txt
  7. +23
    -11
      tests/test_wsdl.py
  8. +1
    -1
      tox.ini
  9. +0
    -1
      wstools/.cvsignore
  10. +3
    -0
      wstools/Namespaces.py
  11. +2
    -2
      wstools/TimeoutSocket.py
  12. +74
    -62
      wstools/Utility.py
  13. +64
    -31
      wstools/WSDLTools.py
  14. +245
    -164
      wstools/XMLSchema.py
  15. +3
    -3
      wstools/XMLname.py
  16. +7
    -6
      wstools/c14n.py
  17. +1
    -1
      wstools/version.py

+ 2
- 2
MANIFEST.in View File

@@ -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



+ 0
- 30
README.mdown View File

@@ -1,30 +0,0 @@
[![Build Status](https://travis-ci.org/kartoch/wstools.svg?branch=master)](https://travis-ci.org/kartoch/wstools)[![Coverage Status](https://img.shields.io/coveralls/kartoch/wstools.svg)](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>


+ 73
- 0
README.rst View File

@@ -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

+ 45
- 0
setup.cfg View File

@@ -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

+ 158
- 21
setup.py View File

@@ -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',
],
) )

+ 3
- 3
tests/config.txt View File

@@ -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


+ 23
- 11
tests/test_wsdl.py View File

@@ -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
- 1
tox.ini View File

@@ -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=


+ 0
- 1
wstools/.cvsignore View File

@@ -1 +0,0 @@
*.pyc

+ 3
- 0
wstools/Namespaces.py View File

@@ -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
""" """


+ 2
- 2
wstools/TimeoutSocket.py View File

@@ -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:


+ 74
- 62
wstools/Utility.py View File

@@ -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):


+ 64
- 31
wstools/WSDLTools.py View File

@@ -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

+ 245
- 164
wstools/XMLSchema.py
File diff suppressed because it is too large
View File


+ 3
- 3
wstools/XMLname.py View File

@@ -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]))


+ 7
- 6
wstools/c14n.py View File

@@ -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
wstools/version.py View File

@@ -1 +1 @@
__version__ = "0.4.3"
__version__ = "0.4.4"

Loading…
Cancel
Save