Browse Source

Fixed several bugs reported by linter (flake8)

Signed-off-by: Sorin Sbarnea <ssbarnea@redhat.com>
main
Sorin Sbarnea 8 years ago
parent
commit
bfff6f0873
16 changed files with 302 additions and 203 deletions
  1. +5
    -1
      .gitignore
  2. +0
    -17
      .idea/misc.xml
  3. +0
    -8
      .idea/modules.xml
  4. +81
    -55
      .travis.yml
  5. +17
    -0
      pytest.ini
  6. +8
    -5
      requirements-dev.txt
  7. +3
    -20
      setup.cfg
  8. +11
    -11
      tests/test_wsdl.py
  9. +1
    -1
      tests/test_wstools_net.py
  10. +2
    -2
      wstools/TimeoutSocket.py
  11. +2
    -2
      wstools/UserTuple.py
  12. +55
    -22
      wstools/Utility.py
  13. +19
    -17
      wstools/WSDLTools.py
  14. +58
    -26
      wstools/XMLSchema.py
  15. +2
    -1
      wstools/XMLname.py
  16. +38
    -15
      wstools/c14n.py

+ 5
- 1
.gitignore View File

@@ -5,6 +5,10 @@ dist
.tox .tox
~*.* ~*.*
build/ build/
.idea/inspectionProfiles/
.idea/
.python-version .python-version
.vscode .vscode
/.idea/misc.xml
/.idea/modules.xml
/.cache
/.eggs

+ 0
- 17
.idea/misc.xml View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
<OptionsSetting value="true" id="Add" />
<OptionsSetting value="true" id="Remove" />
<OptionsSetting value="true" id="Checkout" />
<OptionsSetting value="true" id="Update" />
<OptionsSetting value="true" id="Status" />
<OptionsSetting value="true" id="Edit" />
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="python" project-jdk-type="Python SDK" />
<component name="UnicodeBrowser">
<option name="fontName" value="Menlo" />
</component>
</project>

+ 0
- 8
.idea/modules.xml View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/wstools.iml" filepath="$PROJECT_DIR$/.idea/wstools.iml" />
</modules>
</component>
</project>

+ 81
- 55
.travis.yml View File

@@ -1,5 +1,7 @@
language: python language: python
sudo: false sudo: false
matrix:
fast_finish: false
os: os:
- linux - linux
python: python:
@@ -7,68 +9,92 @@ python:
- '3.4' - '3.4'
- '3.5' - '3.5'
install: install:
- pip -q install -r requirements.txt
- pip -q install -r requirements-dev.txt
- pip -q --log dist/pip.log install --upgrade pip setuptools py
- pip -q --log dist/pip.log install -r requirements.txt -r requirements-dev.txt
- pip check
script: script:
- curl --silent -Lo travis_after_all.py https://raw.github.com/pycontribs/travis_after_all/master/travis_after_all.py && travis_wait python setup.py prerelease test
- export PACKAGE_VERSION=$(python -c "from wstools.version import __version__; print(__version__)")
- travis_wait python setup.py test
- export PACKAGE_NAME=$(python setup.py --name)
- export PACKAGE_VERSION=$(python setup.py --version)
after_success: after_success:
- python travis_after_all.py
- export $(cat .to_export_back)
- |
if [ "$BUILD_LEADER" = "YES" ]; then
if [ "$BUILD_AGGREGATE_STATUS" = "others_succeeded" ]; then
echo "All jobs succeeded! PUBLISHING..."
else
echo "Some jobs failed"
fi
fi
- coveralls
- python setup.py sdist bdist_wheel
- python travis_after_all.py
- export $(cat .to_export_back)
- |
if [ "$BUILD_LEADER" = "YES" ]; then
if [ "$BUILD_AGGREGATE_STATUS" = "others_succeeded" ]; then
echo "All jobs succeeded! PUBLISHING..."
else
echo "Some jobs failed"
fi
fi
- coveralls
- travis_wait python setup.py sdist bdist_wheel
after_failure: after_failure:
- python travis_after_all.py
- export $(cat .to_export_back)
- |
if [ "$BUILD_LEADER" = "YES" ]; then
if [ "$BUILD_AGGREGATE_STATUS" = "others_failed" ]; then
echo "All jobs failed"
else
echo "Some jobs failed"
fi
fi
- python travis_after_all.py
- export $(cat .to_export_back)
- |
if [ "$BUILD_LEADER" = "YES" ]; then
if [ "$BUILD_AGGREGATE_STATUS" = "others_failed" ]; then
echo "All jobs failed"
else
echo "Some jobs failed"
fi
fi
after_script: after_script:
- echo leader=$BUILD_LEADER status=$BUILD_AGGREGATE_STATUS
- echo leader=$BUILD_LEADER status=$BUILD_AGGREGATE_STATUS
branches: branches:
only: only:
- master - master
- develop - develop
notifications:
email:
- pycontribs@googlegroups.com
before_deploy: before_deploy:
- echo "before deploy..."
- echo "before deploy..."
deploy: deploy:
- provider: releases
api_key:
- secure: "gr9iOcQjdoAyUAim6FWKzJI9MBaJo9XKfGQGu7wdPXUFhg80Rp6GLJsowP+aU94NjXM1UQlVHDAy627WtjBlLH2SvmVEIIr7+UKBopBYuXG5jJ1m3wOZE+4f1Pqe9bqFc1DxgucqE8qF0sC24fIbNM2ToeyYrxrS6RoL2gRrX2I="
file: "dist/wstools-$PACKAGE_VERSION.tar.gz"
skip_cleanup: true
on:
branch: master
condition: "$BUILD_LEADER = YES"
tags: true
- provider: pypi
user: sorin
password:
secure: "E0cjANF7SLBdYrsnWLK8X/xWznqkF0JrP/DVfDazPzUYH6ynFeneyofzNJQPLTLsqe1eKXhuUJ/Sbl+RHFB0ySo/j/7NfYd/9pm8hpUkGCvR09IwtvMLgWKp3k10NWab03o2GOkSJSrLvZofyZBGR40wwu2O9uXPCb2rvucCGbw="
distributions: "sdist bdist_wheel"
on:
branch: master
condition: "$BUILD_LEADER = YES"
- provider: pypi
server: https://testpypi.python.org/pypi
user: sorins
password:
secure: "E0cjANF7SLBdYrsnWLK8X/xWznqkF0JrP/DVfDazPzUYH6ynFeneyofzNJQPLTLsqe1eKXhuUJ/Sbl+RHFB0ySo/j/7NfYd/9pm8hpUkGCvR09IwtvMLgWKp3k10NWab03o2GOkSJSrLvZofyZBGR40wwu2O9uXPCb2rvucCGbw="
distributions: "sdist bdist_wheel"
on:
branch: develop
tags: false
condition: "$BUILD_LEADER = YES"
- provider: releases
api_key:
secure: gr9iOcQjdoAyUAim6FWKzJI9MBaJo9XKfGQGu7wdPXUFhg80Rp6GLJsowP+aU94NjXM1UQlVHDAy627WtjBlLH2SvmVEIIr7+UKBopBYuXG5jJ1m3wOZE+4f1Pqe9bqFc1DxgucqE8qF0sC24fIbNM2ToeyYrxrS6RoL2gRrX2I=
file:
- dist/$PACKAGE_NAME-$PACKAGE_VERSION*
skip_cleanup: true
on:
tags: false
branch: master
condition: "$BUILD_LEADER = YES"
- provider: pypi
user: sorin
password:
secure: E0cjANF7SLBdYrsnWLK8X/xWznqkF0JrP/DVfDazPzUYH6ynFeneyofzNJQPLTLsqe1eKXhuUJ/Sbl+RHFB0ySo/j/7NfYd/9pm8hpUkGCvR09IwtvMLgWKp3k10NWab03o2GOkSJSrLvZofyZBGR40wwu2O9uXPCb2rvucCGbw=
distributions: sdist bdist_wheel
skip_cleanup: true
on:
tags: false
condition: "$BUILD_LEADER = YES"
branch: master
- provider: pypi
server: https://testpypi.python.org/pypi
user: sorins
password:
secure: E0cjANF7SLBdYrsnWLK8X/xWznqkF0JrP/DVfDazPzUYH6ynFeneyofzNJQPLTLsqe1eKXhuUJ/Sbl+RHFB0ySo/j/7NfYd/9pm8hpUkGCvR09IwtvMLgWKp3k10NWab03o2GOkSJSrLvZofyZBGR40wwu2O9uXPCb2rvucCGbw=
distributions: sdist bdist_wheel
skip_cleanup: true
on:
tags: false
condition: "$BUILD_LEADER = YES"
branch: develop
after_deploy:
- echo "Now we only have tag the changeset and push..."
- git tag $PACKAGE_VERSION -a -m "Generated tag from TravisCI for build $TRAVIS_BUILD_NUMBER on $TRAVIS_BRANCH branch."
- git push -q https://$TAGPERM@github.com/pycontribs/$PACKAGE_NAME $PACKAGE_VERSION
addons:
artifacts:
debug: true
paths:
- dist/*
target_paths: $PACKAGE_NAME/$TRAVIS_BRANCH/$TRAVIS_BUILD_NUMBER-$TRAVIS_PYTHON_VERSION
working_dir: $TRAVIS_BUILD_DIR
env:
global:
- secure: fuXwQL+KHQ96XkAFl2uQc8eK8dAjrgkup46tck/UGjVpdv1PT/yHmBKrvpFjDa50ueGbtBwTdKAwhyAmYuiZCk2IYHzdvBylCZBBji2FSpaTM59CVwgkVT6tx3HHO83X0mEX6ih9TJvZD5XhX+YUjopnseRXRq3ey3JZJXWN4RM=
- secure: "pGQGM5YmHvOgaKihOyzb3k6bdqLQnZQ2OXO9QrfXlXwtop3zvZQi80Q+01l230x2psDWlwvqWTknAjAt1w463fYXPwpoSvKVCsLSSbjrf2l56nrDqnoir+n0CBy288+eIdaGEfzcxDiuULeKjlg08zrqjcjLjW0bDbBrlTXsb5U="

+ 17
- 0
pytest.ini View File

@@ -0,0 +1,17 @@
[pytest]
norecursedirs = . .git .svn tox _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 tests
# remove "--flake8" due to weir errors
timeout=60
# --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 = . demo docs
rsyncignore = .hg .git
flake8-max-line-length = 99
#flake8-ignore=D,D102
flake8-ignore=D D102 H405

+ 8
- 5
requirements-dev.txt View File

@@ -1,7 +1,10 @@
coverage
coveralls
flake8
flake8-pep257>=1.0.5
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.

py >= 1.4

hacking

pytest pytest
pytest-cov pytest-cov
pytest-timeout

+ 3
- 20
setup.cfg View File

@@ -12,26 +12,9 @@ all_files = 1
[upload_sphinx] [upload_sphinx]
upload-dir = docs/build/html upload-dir = docs/build/html


[pytest]
norecursedirs = . .git .svn tox _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 tests
# remove "--flake8" due to weir errors
timeout=60
# --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 = . demo docs
rsyncignore = .hg .git
flake8-max-line-length = 99
#flake8-ignore=D,D102
flake8-ignore=D D102

[flake8] [flake8]
enable-extensions = H106,H203,H904
exclude=build,.eggs,.tox
ignore=D,E402,H405,H
max-line-length=160 max-line-length=160
exclude=build
statistics=yes statistics=yes
ignore=D,E402

+ 11
- 11
tests/test_wsdl.py View File

@@ -5,20 +5,20 @@
# See LBNLCopyright for copyright notice! # See LBNLCopyright for copyright notice!
########################################################################### ###########################################################################
"""Unittests.""" """Unittests."""
import inspect
import os
import sys import sys
import unittest import unittest
import os
import inspect
cmd_folder = os.path.abspath(os.path.join(os.path.split(inspect.getfile( cmd_folder = os.path.abspath(os.path.join(os.path.split(inspect.getfile(
inspect.currentframe()))[0], "..")) inspect.currentframe()))[0], ".."))
if cmd_folder not in sys.path: if cmd_folder not in sys.path:
sys.path.insert(0, cmd_folder) sys.path.insert(0, cmd_folder)
from wstools.TimeoutSocket import TimeoutError # noqa E402
from wstools.Utility import DOM # noqa E402 from wstools.Utility import DOM # noqa E402
from wstools.WSDLTools import WSDLReader # noqa E402 from wstools.WSDLTools import WSDLReader # noqa E402
from wstools.TimeoutSocket import TimeoutError # noqa E402
try: try:
import configparser import configparser
except:
except ImportError:
from six.moves import configparser from six.moves import configparser


cwd = 'tests' cwd = 'tests'
@@ -88,38 +88,38 @@ class WSDLToolsTestCase(unittest.TestCase):
print("connection timed out") print("connection timed out")
sys.stdout.flush() sys.stdout.flush()
return return
except:
except Exception:
self.path = self.path + ": load failed, unable to start" self.path = self.path + ": load failed, unable to start"
raise raise


try: try:
self.checkWSDLCollection('service', self.wsdl.services) self.checkWSDLCollection('service', self.wsdl.services)
except:
except Exception:
self.path = self.path + ": wsdl.services" self.path = self.path + ": wsdl.services"
raise raise


try: try:
self.checkWSDLCollection('message', self.wsdl.messages) self.checkWSDLCollection('message', self.wsdl.messages)
except:
except Exception:
self.path = self.path + ": wsdl.messages" self.path = self.path + ": wsdl.messages"
raise raise


try: try:
self.checkWSDLCollection('portType', self.wsdl.portTypes) self.checkWSDLCollection('portType', self.wsdl.portTypes)
except:
except Exception:
self.path = self.path + ": wsdl.portTypes" self.path = self.path + ": wsdl.portTypes"
raise raise


try: try:
self.checkWSDLCollection('binding', self.wsdl.bindings) self.checkWSDLCollection('binding', self.wsdl.bindings)
except:
except Exception:
self.path = self.path + ": wsdl.bindings" self.path = self.path + ": wsdl.bindings"
raise raise


try: try:
self.checkWSDLCollection('import', self.wsdl.imports, self.checkWSDLCollection('import', self.wsdl.imports,
key='namespace') key='namespace')
except:
except Exception:
self.path = self.path + ": wsdl.imports" self.path = self.path + ": wsdl.imports"
raise raise


@@ -139,7 +139,7 @@ class WSDLToolsTestCase(unittest.TestCase):
self.schemaAttributeGroupDeclarations(schema, snode) self.schemaAttributeGroupDeclarations(schema, snode)
self.schemaElementDeclarations(schema, snode) self.schemaElementDeclarations(schema, snode)
self.schemaTypeDefinitions(schema, snode) self.schemaTypeDefinitions(schema, snode)
except:
except Exception:
self.path = self.path + ": wsdl.types" self.path = self.path + ": wsdl.types"
raise raise




+ 1
- 1
tests/test_wstools_net.py View File

@@ -4,8 +4,8 @@
# Joshua R. Boverhof, David W. Robertson, LBNL # Joshua R. Boverhof, David W. Robertson, LBNL
# See LBNLCopyright for copyright notice! # See LBNLCopyright for copyright notice!
########################################################################### ###########################################################################
import unittest
import test_wsdl import test_wsdl
import unittest




def makeTestSuite(): def makeTestSuite():


+ 2
- 2
wstools/TimeoutSocket.py View File

@@ -49,7 +49,7 @@ class TimeoutSocket:
try: try:
# Non-blocking mode # Non-blocking mode
sock.setblocking(0) sock.setblocking(0)
apply(sock.connect, addr)
sock.connect(*addr)
sock.setblocking(timeout != 0) sock.setblocking(timeout != 0)
return 1 return 1
except socket.error as why: except socket.error as why:
@@ -66,7 +66,7 @@ class TimeoutSocket:
r, w, e = select.select([], [sock], [], timeout) r, w, e = select.select([], [sock], [], timeout)
if w: if w:
try: try:
apply(sock.connect, addr)
sock.connect(*addr)
return 1 return 1
except socket.error as why: except socket.error as why:
if len(why.args) == 1: if len(why.args) == 1:


+ 2
- 2
wstools/UserTuple.py View File

@@ -54,7 +54,7 @@ class UserTuple:
self.data = () self.data = ()
if inittuple is not None: if inittuple is not None:
# XXX should this accept an arbitrary sequence? # XXX should this accept an arbitrary sequence?
if type(inittuple) == type(self.data):
if isinstance(inittuple, tuple):
self.data = inittuple self.data = inittuple
elif isinstance(inittuple, UserTuple): elif isinstance(inittuple, UserTuple):
# this results in # this results in
@@ -94,7 +94,7 @@ class UserTuple:
return other return other


def __cmp__(self, other): def __cmp__(self, other):
return cmp(self.data, self.__cast(other))
return (self.data > self.__cast(other)) - (self.data < self.__cast(other))


def __contains__(self, item): def __contains__(self, item):
return item in self.data return item in self.data


+ 55
- 22
wstools/Utility.py View File

@@ -16,9 +16,7 @@
ident = "$Id$" ident = "$Id$"


import copy import copy
import sys
import types import types
import string
import six import six


import socket import socket
@@ -26,18 +24,18 @@ import weakref
from os.path import isfile from os.path import isfile
import urllib import urllib
try: try:
from urlparse import urljoin as basejoin
except:
from urllib.parse import urljoin as basejoin
from urlparse import urljoin as basejoin # noqa
except ImportError:
from urllib.parse import urljoin as basejoin # noqa


try: try:
from UserDict import UserDict from UserDict import UserDict
from UserDict import DictMixin
from UserDict import DictMixin # noqa
except ImportError: except ImportError:
from collections import UserDict from collections import UserDict
from collections import MutableMapping as DictMixin
from collections import MutableMapping as DictMixin # noqa


from .TimeoutSocket import TimeoutSocket, TimeoutError
from .TimeoutSocket import TimeoutSocket, TimeoutError # noqa


try: try:
from io import StringIO from io import StringIO
@@ -50,9 +48,44 @@ except ImportError:
from urllib.parse import urlparse from urllib.parse import urlparse


try: try:
from httplib import HTTPConnection, HTTPSConnection
from httplib import HTTPConnection, HTTPSConnection, FakeSocket, _CS_REQ_SENT
except ImportError: except ImportError:
from http.client import HTTPConnection, HTTPSConnection
from http.client import HTTPConnection, HTTPSConnection, _CS_REQ_SENT
import io

class FakeSocket(io.BytesIO):
io_refs = 1

def sendall(self, data):
FakeHTTPConnection.buf = data

def makefile(self, *args, **kwds):
self.io_refs += 1
return self

def read(self, amt=None):
if self.closed:
return b""
return io.BytesIO.read(self, amt)

def readline(self, length=None):
if self.closed:
return b""
return io.BytesIO.readline(self, length)

def close(self):
self.io_refs -= 1
if self.io_refs == 0:
io.BytesIO.close(self)

class FakeHTTPConnection(HTTPConnection):

# buffer to store data for verification in urlopen tests.
buf = None

def connect(self):
self.sock = FakeSocket(self.fakedata)
type(self).fakesock = self.sock


try: try:
from exceptions import Exception from exceptions import Exception
@@ -177,7 +210,7 @@ class TimeoutHTTPS(HTTPSConnection):
sock.connect((self.host, self.port)) sock.connect((self.host, self.port))
realsock = getattr(sock.sock, '_sock', sock.sock) realsock = getattr(sock.sock, '_sock', sock.sock)
ssl = socket.ssl(realsock, self.key_file, self.cert_file) ssl = socket.ssl(realsock, self.key_file, self.cert_file)
self.sock = httplib.FakeSocket(sock, ssl)
self.sock = FakeSocket(sock, ssl)




def urlopen(url, timeout=20, redirects=None): def urlopen(url, timeout=20, redirects=None):
@@ -185,7 +218,7 @@ def urlopen(url, timeout=20, redirects=None):
Note that this supports GET only.""" Note that this supports GET only."""
scheme, host, path, params, query, frag = urlparse(url) scheme, host, path, params, query, frag = urlparse(url)


if not scheme in ('http', 'https'):
if scheme not in ('http', 'https'):
return urllib.urlopen(url) return urllib.urlopen(url)
if params: if params:
path = '%s;%s' % (path, params) path = '%s;%s' % (path, params)
@@ -222,7 +255,7 @@ def urlopen(url, timeout=20, redirects=None):
response = conn.getresponse() response = conn.getresponse()
if response.status != 100: if response.status != 100:
break break
conn._HTTPConnection__state = httplib._CS_REQ_SENT
conn._HTTPConnection__state = _CS_REQ_SENT
conn._HTTPConnection__response = None conn._HTTPConnection__response = None


status = response.status status = response.status
@@ -473,7 +506,7 @@ class DOM:
return child return child
if default != DEFAULT: if default != DEFAULT:
return default return default
raise KeyError(name)
raise KeyError(node)


def getMappingById(self, document, depth=None, element=None, def getMappingById(self, document, depth=None, element=None,
mapping=None, level=1): mapping=None, level=1):
@@ -618,7 +651,7 @@ class DOM:
def findTargetNS(self, node): def findTargetNS(self, node):
"""Return the defined target namespace uri for the given node.""" """Return the defined target namespace uri for the given node."""
attrget = self.getAttr attrget = self.getAttr
attrkey = (self.NS_XMLNS, 'xmlns')
# attrkey = (self.NS_XMLNS, 'xmlns')
DOCUMENT_NODE = node.DOCUMENT_NODE DOCUMENT_NODE = node.DOCUMENT_NODE
ELEMENT_NODE = node.ELEMENT_NODE ELEMENT_NODE = node.ELEMENT_NODE
while 1: while 1:
@@ -891,7 +924,7 @@ class ElementProxy(Base, MessageInterface):
prefix = 'ns%d' % self._indx prefix = 'ns%d' % self._indx
try: try:
self._dom.findNamespaceURI(prefix, self._getNode()) self._dom.findNamespaceURI(prefix, self._getNode())
except DOMException as ex:
except DOMException:
break break
return prefix return prefix


@@ -905,7 +938,7 @@ class ElementProxy(Base, MessageInterface):
if node and (node.nodeType == node.ELEMENT_NODE) and \ if node and (node.nodeType == node.ELEMENT_NODE) and \
(nsuri == self._dom.findDefaultNS(node)): (nsuri == self._dom.findDefaultNS(node)):
return None return None
except DOMException as ex:
except DOMException:
pass pass
if nsuri == XMLNS.XML: if nsuri == XMLNS.XML:
return self._xml_prefix return self._xml_prefix
@@ -956,7 +989,7 @@ class ElementProxy(Base, MessageInterface):
def getPrefix(self, namespaceURI): def getPrefix(self, namespaceURI):
try: try:
prefix = self._getPrefix(node=self.node, nsuri=namespaceURI) prefix = self._getPrefix(node=self.node, nsuri=namespaceURI)
except NamespaceError as ex:
except NamespaceError:
prefix = self._getUniquePrefix() prefix = self._getUniquePrefix()
self.setNamespaceAttribute(prefix, namespaceURI) self.setNamespaceAttribute(prefix, namespaceURI)
return prefix return prefix
@@ -1039,7 +1072,7 @@ class ElementProxy(Base, MessageInterface):
def createAttributeNS(self, namespace, name, value): def createAttributeNS(self, namespace, name, value):
document = self._getOwnerDocument() document = self._getOwnerDocument()
# this function doesn't exist!! it has only two arguments # this function doesn't exist!! it has only two arguments
attrNode = document.createAttributeNS(namespace, name, value)
document.createAttributeNS(namespace, name, value)


def setAttributeNS(self, namespaceURI, localName, value): def setAttributeNS(self, namespaceURI, localName, value):
''' '''
@@ -1053,7 +1086,7 @@ class ElementProxy(Base, MessageInterface):
if namespaceURI: if namespaceURI:
try: try:
prefix = self.getPrefix(namespaceURI) prefix = self.getPrefix(namespaceURI)
except KeyError as ex:
except KeyError:
prefix = 'ns2' prefix = 'ns2'
self.setNamespaceAttribute(prefix, namespaceURI) self.setNamespaceAttribute(prefix, namespaceURI)
qualifiedName = localName qualifiedName = localName
@@ -1176,7 +1209,7 @@ class ElementProxy(Base, MessageInterface):
parts = SplitQName(qualifiedName) parts = SplitQName(qualifiedName)
element = self._getNode() element = self._getNode()
if len(parts) == 1: if len(parts) == 1:
return (self._dom.findTargetNS(element), value)
return (self._dom.findTargetNS(element), None)
return self._dom.findNamespaceURI(parts[0], element) return self._dom.findNamespaceURI(parts[0], element)


def resolvePrefix(self, prefix): def resolvePrefix(self, prefix):
@@ -1250,7 +1283,7 @@ class CollectionNS(UserDict):
self.list.append(item) self.list.append(item)
targetNamespace = getattr(item, 'targetNamespace', targetNamespace = getattr(item, 'targetNamespace',
self.parent().targetNamespace) self.parent().targetNamespace)
if not targetNamespace in self.data:
if targetNamespace not in self.data:
self.data[targetNamespace] = {} self.data[targetNamespace] = {}
self.data[targetNamespace][key] = item self.data[targetNamespace][key] = item




+ 19
- 17
wstools/WSDLTools.py View File

@@ -10,14 +10,16 @@
ident = "$Id$" ident = "$Id$"


import weakref import weakref
from six import string_types
import logging
try: try:
from io import StringIO from io import StringIO
except ImportError: except ImportError:
from cStringIO import StringIO from cStringIO import StringIO


from .Namespaces import OASIS, XMLNS, WSA, WSA_LIST, WSAW_LIST, WSRF_V1_2, WSRF
from .Utility import Collection, CollectionNS, DOM, ElementProxy, basejoin
from .XMLSchema import XMLSchema, SchemaReader, WSDLToolsAdapter
from .Namespaces import OASIS, XMLNS, WSA, WSA_LIST, WSAW_LIST, WSRF_V1_2, WSRF # noqa
from .Utility import Collection, CollectionNS, DOM, ElementProxy, basejoin # noqa
from .XMLSchema import XMLSchema, SchemaReader, WSDLToolsAdapter # noqa




class WSDLReader: class WSDLReader:
@@ -254,7 +256,7 @@ class WSDL:
name = DOM.getAttr(element, 'name') name = DOM.getAttr(element, 'name')
docs = GetDocumentation(element) docs = GetDocumentation(element)
ptype = self.addPortType(name, docs, targetNamespace) ptype = self.addPortType(name, docs, targetNamespace)
#operations = DOM.getElements(element, 'operation', NS_WSDL)
# operations = DOM.getElements(element, 'operation', NS_WSDL)
# ptype.load(operations) # ptype.load(operations)
ptype.load(element) ptype.load(element)
continue continue
@@ -616,8 +618,8 @@ class PortType(Element):
docs = GetDocumentation(item) docs = GetDocumentation(item)
msgref = DOM.getAttr(item, 'message') msgref = DOM.getAttr(item, 'message')
message = ParseQName(msgref, item) message = ParseQName(msgref, item)
for WSA in WSA_LIST + WSAW_LIST:
action = DOM.getAttr(item, 'Action', WSA.ADDRESS, None)
for wsa in WSA_LIST + WSAW_LIST:
action = DOM.getAttr(item, 'Action', wsa.ADDRESS, None)
if action: if action:
break break
operation.setInput(message, name, docs, action) operation.setInput(message, name, docs, action)
@@ -628,8 +630,8 @@ class PortType(Element):
docs = GetDocumentation(item) docs = GetDocumentation(item)
msgref = DOM.getAttr(item, 'message') msgref = DOM.getAttr(item, 'message')
message = ParseQName(msgref, item) message = ParseQName(msgref, item)
for WSA in WSA_LIST + WSAW_LIST:
action = DOM.getAttr(item, 'Action', WSA.ADDRESS, None)
for wsa in WSA_LIST + WSAW_LIST:
action = DOM.getAttr(item, 'Action', wsa.ADDRESS, None)
if action: if action:
break break
operation.setOutput(message, name, docs, action) operation.setOutput(message, name, docs, action)
@@ -639,8 +641,8 @@ class PortType(Element):
docs = GetDocumentation(item) docs = GetDocumentation(item)
msgref = DOM.getAttr(item, 'message') msgref = DOM.getAttr(item, 'message')
message = ParseQName(msgref, item) message = ParseQName(msgref, item)
for WSA in WSA_LIST + WSAW_LIST:
action = DOM.getAttr(item, 'Action', WSA.ADDRESS, None)
for wsaa in WSA_LIST + WSAW_LIST:
action = DOM.getAttr(item, 'Action', wsa.ADDRESS, None)
if action: if action:
break break
operation.addFault(message, name, docs, action) operation.addFault(message, name, docs, action)
@@ -774,7 +776,7 @@ class MessageRole(Element):


ep = ElementProxy(None, node) ep = ElementProxy(None, node)
epc = ep.createAppendElement(DOM.GetWSDLUri(wsdl.version), self.type) epc = ep.createAppendElement(DOM.GetWSDLUri(wsdl.version), self.type)
if not isinstance(self.message, basestring) and len(self.message) == 2:
if not isinstance(self.message, string_types) and len(self.message) == 2:
ns, name = self.message ns, name = self.message
prefix = epc.getPrefix(ns) prefix = epc.getPrefix(ns)
epc.setAttributeNS(None, 'message', '%s:%s' % (prefix, name)) epc.setAttributeNS(None, 'message', '%s:%s' % (prefix, name))
@@ -1238,7 +1240,7 @@ 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 use not in ('literal', 'encoded'):
raise WSDLError( raise WSDLError(
'Invalid use attribute value: %s' % use 'Invalid use attribute value: %s' % use
) )
@@ -1264,7 +1266,7 @@ 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 use not in ('literal', 'encoded'):
raise WSDLError( raise WSDLError(
'Invalid use attribute value: %s' % use 'Invalid use attribute value: %s' % use
) )
@@ -1292,7 +1294,7 @@ 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 use not in ('literal', 'encoded'):
raise WSDLError( raise WSDLError(
'Invalid use attribute value: %s' % use 'Invalid use attribute value: %s' % use
) )
@@ -1480,7 +1482,7 @@ def GetWSAActionOutput(operation):


def FindExtensions(object, kind, t_type=type(())): def FindExtensions(object, kind, t_type=type(())):
if isinstance(kind, t_type): if isinstance(kind, t_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') if hasattr(item, 'nodeType')
@@ -1612,7 +1614,7 @@ class HeaderInfo(ParameterInfo):
actor = None actor = None




def callInfoFromWSDL(port, name):
def callInfoFromWSDL(self, port, name):
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
"""Return a SOAPCallInfo given a WSDL port and operation name.""" """Return a SOAPCallInfo given a WSDL port and operation name."""
wsdl = port.getService().getWSDL() wsdl = port.getService().getWSDL()
@@ -1639,7 +1641,7 @@ def callInfoFromWSDL(port, name):
callinfo.soapAction = soap_op_binding.soapAction callinfo.soapAction = soap_op_binding.soapAction
callinfo.style = soap_op_binding.style or callinfo.style callinfo.style = soap_op_binding.style or callinfo.style


parameterOrder = operation.parameterOrder
# parameterOrder = operation.parameterOrder


if operation.input is not None: if operation.input is not None:
message = messages[operation.input.message] message = messages[operation.input.message]


+ 58
- 26
wstools/XMLSchema.py View File

@@ -20,13 +20,21 @@ import sys
import types import types
import warnings import warnings
import weakref import weakref

from .Namespaces import APACHE, SCHEMA, SOAP, XMLNS
from .Utility import DOM, Collection, DOMException, SplitQName, basejoin
from six import string_types

from .Namespaces import APACHE
from .Namespaces import SCHEMA
from .Namespaces import SOAP
from .Namespaces import XMLNS
from .Utility import DOM
from .Utility import Collection
from .Utility import DOMException
from .Utility import SplitQName
from .Utility import basejoin


try: try:
from StringIO import StringIO from StringIO import StringIO
except:
except ImportError:
# from io import StringIO # from io import StringIO
from io import BytesIO as StringIO from io import BytesIO as StringIO


@@ -34,7 +42,7 @@ except:
try: try:
from threading import RLock from threading import RLock
except ImportError: except ImportError:
class RLock:
class RLock(object):


def acquire(): def acquire():
pass pass
@@ -55,6 +63,7 @@ BUILT_IN_NAMESPACES = [SOAP.ENC, ] + SCHEMA.XSD_LIST + [APACHE.AXIS_NS]


def GetSchema(component): def GetSchema(component):
"""convience function for finding the parent XMLSchema instance. """convience function for finding the parent XMLSchema instance.

""" """
parent = component parent = component
while not isinstance(parent, XMLSchema): while not isinstance(parent, XMLSchema):
@@ -62,16 +71,18 @@ def GetSchema(component):
return parent return parent




class SchemaReader:
class SchemaReader(object):


"""A SchemaReader creates XMLSchema objects from urls and xml data. """A SchemaReader creates XMLSchema objects from urls and xml data.

""" """


namespaceToSchema = {} namespaceToSchema = {}


def __init__(self, domReader=None, base_url=None): def __init__(self, domReader=None, base_url=None):
"""domReader -- class must implement DOMAdapterInterface """domReader -- class must implement DOMAdapterInterface
base_url -- base url string

base_url -- base url string
""" """
self.__base_url = base_url self.__base_url = base_url
self.__readerClass = domReader self.__readerClass = domReader
@@ -82,6 +93,7 @@ class SchemaReader:


def __setImports(self, schema): def __setImports(self, schema):
"""Add dictionary of imports to schema instance. """Add dictionary of imports to schema instance.

schema -- XMLSchema instance schema -- XMLSchema instance
""" """
for ns, val in schema.imports.items(): for ns, val in schema.imports.items():
@@ -90,6 +102,7 @@ class SchemaReader:


def __setIncludes(self, schema): def __setIncludes(self, schema):
"""Add dictionary of includes to schema instance. """Add dictionary of includes to schema instance.

schema -- XMLSchema instance schema -- XMLSchema instance
""" """
for schemaLocation, val in schema.includes.items(): for schemaLocation, val in schema.includes.items():
@@ -99,16 +112,19 @@ class SchemaReader:


def addSchemaByLocation(self, location, schema): def addSchemaByLocation(self, location, schema):
"""provide reader with schema document for a location. """provide reader with schema document for a location.

""" """
self._includes[location] = schema self._includes[location] = schema


def addSchemaByNamespace(self, schema): def addSchemaByNamespace(self, schema):
"""provide reader with schema document for a targetNamespace. """provide reader with schema document for a targetNamespace.

""" """
self._imports[schema.targetNamespace] = schema self._imports[schema.targetNamespace] = schema


def loadFromNode(self, parent, element): def loadFromNode(self, parent, element):
"""element -- DOM node or document """element -- DOM node or document

parent -- WSDLAdapter instance parent -- WSDLAdapter instance
""" """
reader = self.__readerClass(element) reader = self.__readerClass(element)
@@ -121,6 +137,7 @@ class SchemaReader:


def loadFromStream(self, file, url=None): def loadFromStream(self, file, url=None):
"""Return an XMLSchema instance loaded from a file object. """Return an XMLSchema instance loaded from a file object.

file -- file object file -- file object
url -- base location for resolving imports/includes. url -- base location for resolving imports/includes.
""" """
@@ -136,12 +153,14 @@ class SchemaReader:


def loadFromString(self, data): def loadFromString(self, data):
"""Return an XMLSchema instance loaded from an XML string. """Return an XMLSchema instance loaded from an XML string.

data -- XML string data -- XML string
""" """
return self.loadFromStream(StringIO(data)) return self.loadFromStream(StringIO(data))


def loadFromURL(self, url, schema=None): def loadFromURL(self, url, schema=None):
"""Return an XMLSchema instance loaded from the given url. """Return an XMLSchema instance loaded from the given url.

url -- URL to dereference url -- URL to dereference
schema -- Optional XMLSchema instance. schema -- Optional XMLSchema instance.
""" """
@@ -159,6 +178,7 @@ class SchemaReader:


def loadFromFile(self, filename): def loadFromFile(self, filename):
"""Return an XMLSchema instance loaded from the given file. """Return an XMLSchema instance loaded from the given file.

filename -- name of file to open filename -- name of file to open
""" """
if self.__base_url: if self.__base_url:
@@ -183,10 +203,11 @@ class NoSchemaLocationWarning(Exception):
########################### ###########################
# DOM Utility Adapters # DOM Utility Adapters
########################## ##########################
class DOMAdapterInterface:
class DOMAdapterInterface(object):


def hasattr(self, attr, ns=None): def hasattr(self, attr, ns=None):
"""return true if node has attribute """return true if node has attribute

attr -- attribute to check for attr -- attribute to check for
ns -- namespace of attribute, by default None ns -- namespace of attribute, by default None
""" """
@@ -194,43 +215,51 @@ class DOMAdapterInterface:


def getContentList(self, *contents): def getContentList(self, *contents):
"""returns an ordered list of child nodes """returns an ordered list of child nodes

*contents -- list of node names to return *contents -- list of node names to return
""" """
raise NotImplementedError('adapter method not implemented') raise NotImplementedError('adapter method not implemented')


def setAttributeDictionary(self, attributes): def setAttributeDictionary(self, attributes):
"""set attribute dictionary """set attribute dictionary

""" """
raise NotImplementedError('adapter method not implemented') raise NotImplementedError('adapter method not implemented')


def getAttributeDictionary(self): def getAttributeDictionary(self):
"""returns a dict of node's attributes """returns a dict of node's attributes

""" """
raise NotImplementedError('adapter method not implemented') raise NotImplementedError('adapter method not implemented')


def getNamespace(self, prefix): def getNamespace(self, prefix):
"""returns namespace referenced by prefix. """returns namespace referenced by prefix.

""" """
raise NotImplementedError('adapter method not implemented') raise NotImplementedError('adapter method not implemented')


def getTagName(self): def getTagName(self):
"""returns tagName of node """returns tagName of node

""" """
raise NotImplementedError('adapter method not implemented') raise NotImplementedError('adapter method not implemented')


def getParentNode(self): def getParentNode(self):
"""returns parent element in DOMAdapter or None """returns parent element in DOMAdapter or None

""" """
raise NotImplementedError('adapter method not implemented') raise NotImplementedError('adapter method not implemented')


def loadDocument(self, file): def loadDocument(self, file):
"""load a Document from a file object """load a Document from a file object

file -- file --
""" """
raise NotImplementedError('adapter method not implemented') raise NotImplementedError('adapter method not implemented')


def loadFromURL(self, url): def loadFromURL(self, url):
"""load a Document from an url """load a Document from an url

url -- URL to dereference url -- URL to dereference
""" """
raise NotImplementedError('adapter method not implemented') raise NotImplementedError('adapter method not implemented')
@@ -239,10 +268,12 @@ class DOMAdapterInterface:
class DOMAdapter(DOMAdapterInterface): class DOMAdapter(DOMAdapterInterface):


"""Adapter for ZSI.Utility.DOM """Adapter for ZSI.Utility.DOM

""" """


def __init__(self, node=None): def __init__(self, node=None):
"""Reset all instance variables. """Reset all instance variables.

element -- DOM document, node, or None element -- DOM document, node, or None
""" """
if hasattr(node, 'documentElement'): if hasattr(node, 'documentElement'):
@@ -256,6 +287,7 @@ class DOMAdapter(DOMAdapterInterface):


def hasattr(self, attr, ns=None): def hasattr(self, attr, ns=None):
"""attr -- attribute """attr -- attribute

ns -- optional namespace, None means unprefixed attribute. ns -- optional namespace, None means unprefixed attribute.
""" """
if not self.__attributes: if not self.__attributes:
@@ -302,7 +334,7 @@ class DOMAdapter(DOMAdapterInterface):
else: else:
try: try:
namespace = DOM.findNamespaceURI(prefix, self.__node) namespace = DOM.findNamespaceURI(prefix, self.__node)
except DOMException as ex:
except DOMException:
if prefix != 'xml': if prefix != 'xml':
raise SchemaError('%s namespace not declared for %s' % ( raise SchemaError('%s namespace not declared for %s' % (
prefix, self.__node._get_tagName())) prefix, self.__node._get_tagName()))
@@ -564,9 +596,9 @@ class XMLSchemaComponent(XMLBase, MarkerInterface):
self._parent = weakref.ref(parent) self._parent = weakref.ref(parent)


if not self.__class__ == XMLSchemaComponent\ if not self.__class__ == XMLSchemaComponent\
and not (type(self.__class__.required) == type(XMLSchemaComponent.required)
and type(self.__class__.attributes) == type(XMLSchemaComponent.attributes)
and type(self.__class__.contents) == type(XMLSchemaComponent.contents)):
and not (isinstance(self.__class__.required, type(XMLSchemaComponent.required))
and isinstance(self.__class__.attributes, type(XMLSchemaComponent.attributes))
and isinstance(self.__class__.contents, type(XMLSchemaComponent.contents))):
raise RuntimeError( raise RuntimeError(
'Bad type for a class variable in %s' % self.__class__) 'Bad type for a class variable in %s' % self.__class__)


@@ -667,13 +699,13 @@ class XMLSchemaComponent(XMLBase, MarkerInterface):
if parent.targetNamespace == namespace: if parent.targetNamespace == namespace:
try: try:
obj = getattr(parent, collection)[name] obj = getattr(parent, collection)[name]
except KeyError as ex:
except KeyError:
raise KeyError('targetNamespace(%s) collection(%s) has no item(%s)' % ( raise KeyError('targetNamespace(%s) collection(%s) has no item(%s)' % (
namespace, collection, name)) namespace, collection, name))


return obj return obj


if not namespace in parent.imports:
if namespace not in parent.imports:
if namespace in BUILT_IN_NAMESPACES: if namespace in BUILT_IN_NAMESPACES:
# built-in just return # built-in just return
# WARNING: expecting import if "redefine" or add to built-in # WARNING: expecting import if "redefine" or add to built-in
@@ -703,7 +735,7 @@ class XMLSchemaComponent(XMLBase, MarkerInterface):


try: try:
obj = getattr(schema, collection)[name] obj = getattr(schema, collection)[name]
except KeyError as ex:
except KeyError:
raise KeyError('targetNamespace(%s) collection(%s) has no item(%s)' % ( raise KeyError('targetNamespace(%s) collection(%s) has no item(%s)' % (
namespace, collection, name)) namespace, collection, name))


@@ -791,7 +823,7 @@ class XMLSchemaComponent(XMLBase, MarkerInterface):
raise SchemaError( raise SchemaError(
'attribute %s declared multiple times in %s' % (value, ns)) 'attribute %s declared multiple times in %s' % (value, ns))
self.attributes[ns][value] = v self.attributes[ns][value] = v
elif not value in self.attributes:
elif value not in self.attributes:
self.attributes[value] = v self.attributes[value] = v
else: else:
raise SchemaError( raise SchemaError(
@@ -843,7 +875,7 @@ class XMLSchemaComponent(XMLBase, MarkerInterface):
references are not subject to this test. references are not subject to this test.
""" """
for a in self.__class__.required: for a in self.__class__.required:
if not a in self.attributes:
if a not in self.attributes:
raise SchemaError( raise SchemaError(
'class instance %s, missing required attribute %s' % (self.__class__, a)) 'class instance %s, missing required attribute %s' % (self.__class__, a))
for a, v in self.attributes.items(): for a, v in self.attributes.items():
@@ -942,10 +974,10 @@ class Annotation(XMLSchemaComponent):
for i in contents: for i in contents:
component = SplitQName(i.getTagName())[1] component = SplitQName(i.getTagName())[1]
if component == 'documentation': if component == 'documentation':
#print_debug('class %s, documentation skipped' %self.__class__, 5)
# print_debug('class %s, documentation skipped' %self.__class__, 5)
continue continue
elif component == 'appinfo': elif component == 'appinfo':
#print_debug('class %s, appinfo skipped' %self.__class__, 5)
# print_debug('class %s, appinfo skipped' %self.__class__, 5)
continue continue
else: else:
raise SchemaError('Unknown component (%s)' % (i.getTagName())) raise SchemaError('Unknown component (%s)' % (i.getTagName()))
@@ -978,10 +1010,10 @@ class Annotation(XMLSchemaComponent):
for i in contents: for i in contents:
component = SplitQName(i.getTagName())[1] component = SplitQName(i.getTagName())[1]
if component == 'mixed': if component == 'mixed':
#print_debug('class %s, mixed skipped' %self.__class__, 5)
# print_debug('class %s, mixed skipped' %self.__class__, 5)
continue continue
elif component == 'any': elif component == 'any':
#print_debug('class %s, any skipped' %self.__class__, 5)
# print_debug('class %s, any skipped' %self.__class__, 5)
continue continue
else: else:
raise SchemaError('Unknown component (%s)' % raise SchemaError('Unknown component (%s)' %
@@ -1014,10 +1046,10 @@ class Annotation(XMLSchemaComponent):
for i in contents: for i in contents:
component = SplitQName(i.getTagName())[1] component = SplitQName(i.getTagName())[1]
if component == 'mixed': if component == 'mixed':
#print_debug('class %s, mixed skipped' %self.__class__, 5)
# print_debug('class %s, mixed skipped' %self.__class__, 5)
continue continue
elif component == 'any': elif component == 'any':
#print_debug('class %s, any skipped' %self.__class__, 5)
# print_debug('class %s, any skipped' %self.__class__, 5)
continue continue
else: else:
raise SchemaError('Unknown component (%s)' % raise SchemaError('Unknown component (%s)' %
@@ -1236,7 +1268,7 @@ class XMLSchema(XMLSchemaComponent):
attributes.update(self.attributes) attributes.update(self.attributes)
self.setAttributes(node) self.setAttributes(node)
for k, v in attributes['xmlns'].items(): for k, v in attributes['xmlns'].items():
if not k in self.attributes['xmlns']:
if k not in self.attributes['xmlns']:
self.attributes['xmlns'][k] = v self.attributes['xmlns'][k] = v
else: else:
self.setAttributes(node) self.setAttributes(node)
@@ -2558,7 +2590,7 @@ class ComplexType(XMLSchemaComponent,
m = self.getAttribute('mixed') m = self.getAttribute('mixed')
if not m: if not m:
return False return False
if isinstance(m, basestring):
if isinstance(m, string_types):
if m in ('false', '0'): if m in ('false', '0'):
return False return False
if m in ('true', '1'): if m in ('true', '1'):
@@ -2688,7 +2720,7 @@ class ComplexType(XMLSchemaComponent,
m = self.getAttribute('mixed') m = self.getAttribute('mixed')
if not m: if not m:
return False return False
if isinstance(m, basestring) is True:
if isinstance(m, string_types) is True:
if m in ('false', '0'): if m in ('false', '0'):
return False return False
if m in ('true', '1'): if m in ('true', '1'):


+ 2
- 1
wstools/XMLname.py View File

@@ -1,4 +1,5 @@
import re import re
from six import text_type


"""Translate strings to and from SOAP 1.2 XML name encoding """Translate strings to and from SOAP 1.2 XML name encoding


@@ -64,7 +65,7 @@ def toXMLname(string):
prefix = None prefix = None
localname = string localname = string


T = unicode(localname)
T = text_type(localname)


N = len(localname) N = len(localname)
X = [] X = []


+ 38
- 15
wstools/c14n.py View File

@@ -4,8 +4,8 @@ import sys
from xml.dom import Node from xml.dom import Node
try: try:
from xml.ns import XMLNS from xml.ns import XMLNS
except:
class XMLNS:
except ImportError:
class XMLNS(object):
BASE = "http://www.w3.org/2000/xmlns/" BASE = "http://www.w3.org/2000/xmlns/"
XML = "http://www.w3.org/XML/1998/namespace" XML = "http://www.w3.org/XML/1998/namespace"


@@ -90,7 +90,9 @@ if sys.version_info[0] > 2:


def _sorter(n1, n2): def _sorter(n1, n2):
'''_sorter(n1,n2) -> int '''_sorter(n1,n2) -> int
Sorting predicate for non-NS attributes.'''

Sorting predicate for non-NS attributes.
'''


i = cmp(n1.namespaceURI, n2.namespaceURI) i = cmp(n1.namespaceURI, n2.namespaceURI)
if i: if i:
@@ -100,7 +102,9 @@ def _sorter(n1, n2):


def _sorter_ns(n1, n2): def _sorter_ns(n1, n2):
'''_sorter_ns((n,v),(n,v)) -> int '''_sorter_ns((n,v),(n,v)) -> int
"(an empty namespace URI is lexicographically least)."'''

"(an empty namespace URI is lexicographically least)."
'''


if n1[0] == 'xmlns': if n1[0] == 'xmlns':
return -1 return -1
@@ -111,7 +115,9 @@ def _sorter_ns(n1, n2):


def _utilized(n, node, other_attrs, unsuppressedPrefixes): def _utilized(n, node, other_attrs, unsuppressedPrefixes):
'''_utilized(n, node, other_attrs, unsuppressedPrefixes) -> boolean '''_utilized(n, node, other_attrs, unsuppressedPrefixes) -> boolean
Return true if that nodespace is utilized within the node'''

Return true if that nodespace is utilized within the node
'''
if n.startswith('xmlns:'): if n.startswith('xmlns:'):
n = n[6:] n = n[6:]
elif n.startswith('xmlns'): elif n.startswith('xmlns'):
@@ -133,8 +139,10 @@ def _utilized(n, node, other_attrs, unsuppressedPrefixes):


def _inclusiveNamespacePrefixes(node, context, unsuppressedPrefixes): def _inclusiveNamespacePrefixes(node, context, unsuppressedPrefixes):
'''http://www.w3.org/TR/xml-exc-c14n/ '''http://www.w3.org/TR/xml-exc-c14n/

InclusiveNamespaces PrefixList parameter, which lists namespace prefixes that InclusiveNamespaces PrefixList parameter, which lists namespace prefixes that
are handled in the manner described by the Canonical XML Recommendation'''
are handled in the manner described by the Canonical XML Recommendation
'''
inclusive = [] inclusive = []
if node.prefix: if node.prefix:
usedPrefixes = ['xmlns:%s' % node.prefix] usedPrefixes = ['xmlns:%s' % node.prefix]
@@ -168,10 +176,13 @@ def _in_subset(subset, node):
return subset is None or node in subset # rich's tweak return subset is None or node in subset # rich's tweak




class _implementation:
class _implementation(object):


'''Implementation class for C14N. This accompanies a node during it's
processing and includes the parameters and processing state.'''
'''Implementation class for C14N.

This accompanies a node during it's
processing and includes the parameters and processing state.
'''


# Handler for each node type; populated during module instantiation. # Handler for each node type; populated during module instantiation.
handlers = {} handlers = {}
@@ -205,9 +216,11 @@ class _implementation:


def _inherit_context(self, node): def _inherit_context(self, node):
'''_inherit_context(self, node) -> list '''_inherit_context(self, node) -> list

Scan ancestors of attribute and namespace context. Used only Scan ancestors of attribute and namespace context. Used only
for single element node canonicalization, not for subset for single element node canonicalization, not for subset
canonicalization.'''
canonicalization.
'''


# Collect the initial list of xml:foo attributes. # Collect the initial list of xml:foo attributes.
xmlattrs = list(filter(_IN_XML_NS, _attrs(node))) xmlattrs = list(filter(_IN_XML_NS, _attrs(node)))
@@ -225,9 +238,11 @@ class _implementation:


def _do_document(self, node): def _do_document(self, node):
'''_do_document(self, node) -> None '''_do_document(self, node) -> None

Process a document node. documentOrder holds whether the document Process a document node. documentOrder holds whether the document
element has been encountered such that PIs/comments can be written element has been encountered such that PIs/comments can be written
as specified.'''
as specified.
'''


self.documentOrder = _LesserElement self.documentOrder = _LesserElement
for child in node.childNodes: for child in node.childNodes:
@@ -247,8 +262,10 @@ class _implementation:


def _do_text(self, node): def _do_text(self, node):
'''_do_text(self, node) -> None '''_do_text(self, node) -> None

Process a text or CDATA node. Render various special characters Process a text or CDATA node. Render various special characters
as their C14N entity representations.'''
as their C14N entity representations.
'''
if not _in_subset(self.subset, node): if not _in_subset(self.subset, node):
return return
s = string.replace(node.data, "&", "&amp;") s = string.replace(node.data, "&", "&amp;")
@@ -262,6 +279,7 @@ class _implementation:


def _do_pi(self, node): def _do_pi(self, node):
'''_do_pi(self, node) -> None '''_do_pi(self, node) -> None

Process a PI node. Render a leading or trailing #xA if the Process a PI node. Render a leading or trailing #xA if the
document order of the PI is greater or lesser (respectively) document order of the PI is greater or lesser (respectively)
than the document element. than the document element.
@@ -284,6 +302,7 @@ class _implementation:


def _do_comment(self, node): def _do_comment(self, node):
'''_do_comment(self, node) -> None '''_do_comment(self, node) -> None

Process a comment node. Render a leading or trailing #xA if the Process a comment node. Render a leading or trailing #xA if the
document order of the comment is greater or lesser (respectively) document order of the comment is greater or lesser (respectively)
than the document element. than the document element.
@@ -303,7 +322,9 @@ class _implementation:


def _do_attr(self, n, value): def _do_attr(self, n, value):
''''_do_attr(self, node) -> None ''''_do_attr(self, node) -> None
Process an attribute.'''

Process an attribute.
'''


W = self.write W = self.write
W(' ') W(' ')
@@ -320,7 +341,9 @@ class _implementation:


def _do_element(self, node, initial_other_attrs=[], unused=None): def _do_element(self, node, initial_other_attrs=[], unused=None):
'''_do_element(self, node, initial_other_attrs = [], unused = {}) -> None '''_do_element(self, node, initial_other_attrs = [], unused = {}) -> None
Process an element (and its children).'''

Process an element (and its children).
'''


# Get state (from the stack) make local copies. # Get state (from the stack) make local copies.
# ns_parent -- NS declarations in parent # ns_parent -- NS declarations in parent
@@ -357,7 +380,7 @@ class _implementation:
if _in_subset(self.subset, a): # 020925 Test to see if attribute node in subset if _in_subset(self.subset, a): # 020925 Test to see if attribute node in subset
other_attrs.append(a) other_attrs.append(a)


# # TODO: exclusive, might need to define xmlns:prefix here
# # exclusive, might need to define xmlns:prefix here
# if not inclusive and a.prefix is not None and not ns_rendered.has_key('xmlns:%s' %a.prefix): # if not inclusive and a.prefix is not None and not ns_rendered.has_key('xmlns:%s' %a.prefix):
# ns_local['xmlns:%s' %a.prefix] = ?? # ns_local['xmlns:%s' %a.prefix] = ??




Loading…
Cancel
Save