@@ -1,5 +1,5 @@ | |||
include README.txt | |||
include README.rst | |||
include CHANGES.txt | |||
recursive-include docs *.* | |||
recursive-include src *.txt *.py *.tar.gz README | |||
recursive-include wstools *.py | |||
@@ -1,30 +0,0 @@ | |||
[](https://travis-ci.org/kartoch/wstools)[](https://coveralls.io/r/kartoch/wstools?branch=master) | |||
General | |||
======== | |||
- Homepage: https://github.com/pycontribs/wstools | |||
- Mailing List: https://groups.google.com/forum/#!forum/pycontribs | |||
- Package: http://pypi.python.org/pypi/wstools/ | |||
- Docs (TBD): http://packages.python.org/wstools | |||
Credits | |||
======== | |||
Companies | |||
--------- | |||
|makinacom|_ | |||
* `Planet Makina Corpus <http://www.makina-corpus.org>`_ | |||
* `Contact us <mailto:python@makina-corpus.org>`_ | |||
.. |makinacom| image:: http://depot.makina-corpus.org/public/logo.gif | |||
.. _makinacom: http://www.makina-corpus.com | |||
Authors | |||
------------ | |||
- Makina Corpus <python@makina-corpus.com> | |||
Contributors | |||
----------------- | |||
- Sorin Sbarnea <sorin.sbarnea+os@gmail.com> | |||
@@ -0,0 +1,73 @@ | |||
========================================================= | |||
WSDL parsing services package for Web Services for Python | |||
========================================================= | |||
. image:: https://pypip.in/py_versions/wstools/badge.svg?style=flat | |||
:target: https://pypi.python.org/pypi/wstools/ | |||
.. image:: https://pypip.in/license/wstools/badge.svg?style=flat | |||
:target: https://pypi.python.org/pypi/wstools/ | |||
.. image:: https://pypip.in/download/wstools/badge.svg?style=flat | |||
:target: https://pypi.python.org/pypi/wstools/ | |||
.. image:: https://pypip.in/version/wstools/badge.svg?style=flat | |||
:target: https://pypi.python.org/pypi/wstools/ | |||
.. image:: https://pypip.in/egg/wstools/badge.svg?style=flat | |||
:target: https://pypi.python.org/pypi/wstools/ | |||
.. image:: https://pypip.in/wheel/wstools/badge.svg?style=flat | |||
:target: https://pypi.python.org/pypi/wstools/ | |||
------------ | |||
.. image:: https://api.travis-ci.org/pycontribs/wstools.svg?branch=master | |||
:target: https://travis-ci.org/pycontribs/wstools | |||
.. image:: https://pypip.in/status/wstools/badge.svg?style=flat | |||
:target: https://pypi.python.org/pypi/wstools/ | |||
.. image:: https://img.shields.io/coveralls/pycontribs/wstools.svg | |||
:target: https://coveralls.io/r/pycontribs/wstools | |||
.. image:: http://api.flattr.com/button/flattr-badge-large.png | |||
:target: https://flattr.com/submit/auto?user_id=sbarnea&url=https://github.com/pycontribs/wstools&title=Python wstools&language=&tags=github&category=software | |||
General | |||
======= | |||
- Homepage: https://github.com/pycontribs/wstools | |||
- Mailing List: https://groups.google.com/forum/#!forum/pycontribs | |||
- Package: http://pypi.python.org/pypi/wstools/ | |||
- Docs (TBD): http://packages.python.org/wstools | |||
Credits | |||
======= | |||
Companies | |||
--------- | |||
\|makinacom\|\_ | |||
- ``Planet Makina Corpus <http://www.makina-corpus.org>``\ \_ | |||
- ``Contact us <mailto:python@makina-corpus.org>``\ \_ | |||
.. \|makinacom\| image:: http://depot.makina-corpus.org/public/logo.gif | |||
.. \_makinacom: http://www.makina-corpus.com | |||
Authors | |||
------- | |||
- Makina Corpus python@makina-corpus.com | |||
Contributors | |||
------------ | |||
- Sorin Sbarnea sorin.sbarnea@gmail.com | |||
.. |Build Status| image:: https://travis-ci.org/kartoch/wstools.svg?branch=master | |||
:target: https://travis-ci.org/kartoch/wstools | |||
.. |Coverage Status| image:: https://img.shields.io/coveralls/kartoch/wstools.svg | |||
:target: https://coveralls.io/r/kartoch/wstools?branch=master |
@@ -0,0 +1,45 @@ | |||
[metadata] | |||
description-file = README | |||
[bdist_wheel] | |||
universal = 1 | |||
[build_sphinx] | |||
source-dir = docs | |||
build-dir = docs/build | |||
all_files = 1 | |||
[upload_sphinx] | |||
upload-dir = docs/build/html | |||
[pytest] | |||
norecursedirs = . .svn jira _build tmp* lib/third lib *.egg bin distutils build docs demo | |||
python_files = *.py | |||
addopts = -p no:xdist --ignore=setup.py --tb=long -rsxX -v --maxfail=10 --pep8 tests | |||
# --maxfail=2 -n4 | |||
# -n4 runs up to 4 parallel procs | |||
# --maxfail=2 fail fast, dude | |||
# --durations=3 report the top 3 longest tests | |||
# these are important for distributed testing, to speedup their execution we minimize what we sync | |||
rsyncdirs = . jira demo docs | |||
rsyncignore = .hg .git | |||
pep8ignore = E501 E265 E127 E901 E128 E402 | |||
[pep8] | |||
exclude=build,lib,.tox,third,*.egg,docs,packages | |||
;filename= | |||
;select | |||
ignore=E501,E265,E402 | |||
max-line-length=1024 | |||
count=1 | |||
;format | |||
;quiet | |||
;show-pep8 | |||
;show-source | |||
statistics=1 | |||
;verbose=1 | |||
;PEP8_OPTS="--filename=*.py --exclude=lib --ignore=E501 scripts" | |||
;pep8 $PEP8_OPTS --show-source --repeat | |||
;pep8 --statistics -qq $PEP8_OPTS |
@@ -1,34 +1,171 @@ | |||
#!/usr/bin/env python | |||
import logging | |||
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" | |||
# 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( | |||
name="wstools", | |||
name=NAME, | |||
version=__version__, | |||
description="wstools", | |||
maintainer="Gregory Warnes, kiorky, sorin", | |||
maintainer_email="Gregory.R.Warnes@Pfizer.com, " | |||
+ " kiorky@cryptelium.net, " + "sorin.sbarnea+os@gmail.com", | |||
url=url, | |||
long_description=long_description, | |||
packages=['wstools'], | |||
install_requires=install_requires, | |||
cmdclass={'test': PyTest, 'release': Release, 'prerelease': PreRelease}, | |||
packages=find_packages(exclude=['tests']), | |||
include_package_data=True, | |||
install_requires=['docutils','six'], | |||
license='BSD', | |||
description="WSDL parsing services package for Web Services for Python. see" + url, | |||
long_description=open("README.rst").read(), | |||
maintainer="Sorin Sbarnea", | |||
maintainer_email="sorin.sbarnea@gmail.com", | |||
author='Makina Corpus', | |||
author_email='python@makina-corpus.com', | |||
provides=[NAME], | |||
url='https://github.com/pycontribs/wstools', | |||
bugtrack_url='https://github.com/pycontribs/wstools/issues', | |||
home_page='https://github.com/pycontribs/wstools', | |||
keywords='api wstools wdsl web', | |||
classifiers=[ | |||
'Programming Language :: Python', | |||
'Programming Language :: Python :: 2.5', | |||
'Programming Language :: Python :: 2.6', | |||
'Programming Language :: Python :: 2.7', | |||
'Programming Language :: Python :: 3', | |||
'Development Status :: 4 - Beta', | |||
'Environment :: Other Environment', | |||
'Intended Audience :: Developers', | |||
'License :: OSI Approved :: BSD License', | |||
'Operating System :: OS Independent', | |||
'Topic :: Software Development :: Libraries :: Python Modules', | |||
'Programming Language :: Python :: 2.6', | |||
'Programming Language :: Python :: 2.7', | |||
'Programming Language :: Python :: 3.3', | |||
'Programming Language :: Python :: 3.4', | |||
'Topic :: Internet :: WWW/HTTP', | |||
], | |||
) |
@@ -10,7 +10,7 @@ | |||
[services_by_file] | |||
ip2geo = data/ip2geo.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 | |||
########################################################################## | |||
@@ -209,7 +209,7 @@ FOPService = http://live.capescience.com/wsdl/FOPService.wsdl | |||
FedRoutingDirectoryService = http://demo.soapam.com/services/FedEpayDirectory/FedEpayDirectoryService.wsdl | |||
GMChart = http://service.graphmagic.com/GMService/GraphMagic.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 | |||
HPcatalogService = http://www.lixusnet.com/lixusnet/HPcatalog.jws?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 | |||
Service = http://www.ejse.com/WeatherService/Service.asmx?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 | |||
TerraService = http://terraservice.net/TerraService.asmx?WSDL | |||
Transform = http://transform.dataconcert.com/transform.wsdl | |||
@@ -7,11 +7,19 @@ | |||
import sys | |||
import unittest | |||
import ConfigParser | |||
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.WSDLTools import WSDLReader | |||
from wstools.TimeoutSocket import TimeoutError | |||
try: | |||
import configparser | |||
except: | |||
from six.moves import configparser | |||
cwd = 'tests' | |||
@@ -37,8 +45,11 @@ class WSDLToolsTestCase(unittest.TestCase): | |||
def setUp(self): | |||
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() | |||
def __str__(self): | |||
@@ -72,7 +83,7 @@ class WSDLToolsTestCase(unittest.TestCase): | |||
self.wsdl = WSDLReader().loadFromFile('tests/' + self.path) | |||
except TimeoutError: | |||
print "connection timed out" | |||
print("connection timed out") | |||
sys.stdout.flush() | |||
return | |||
except: | |||
@@ -104,8 +115,8 @@ class WSDLToolsTestCase(unittest.TestCase): | |||
raise | |||
try: | |||
self.checkWSDLCollection('import', self.wsdl.imports, \ | |||
key='namespace') | |||
self.checkWSDLCollection('import', self.wsdl.imports, | |||
key='namespace') | |||
except: | |||
self.path = self.path + ": wsdl.imports" | |||
raise | |||
@@ -131,9 +142,9 @@ class WSDLToolsTestCase(unittest.TestCase): | |||
raise | |||
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: | |||
print '\t', ext | |||
print('\t', ext) | |||
def schemaAttributesDeclarations(self, schema, node): | |||
self.checkXSDCollection('attribute', schema.attr_decl, node) | |||
@@ -150,13 +161,14 @@ class WSDLToolsTestCase(unittest.TestCase): | |||
def setUpOptions(section): | |||
cp = ConfigParser.ConfigParser() | |||
cp = configparser.ConfigParser() | |||
cp.optionxform = str | |||
cp.read(cwd + '/config.txt') | |||
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) | |||
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) | |||
return cp, len(cp.options(section)) | |||
@@ -1,6 +1,6 @@ | |||
[tox] | |||
minversion = 1.3 | |||
envlist = py26,py27,py33,py34,flake8 | |||
envlist = py26,py27,py34,flake8 | |||
[testenv] | |||
deps= | |||
@@ -1 +0,0 @@ | |||
*.pyc |
@@ -136,6 +136,7 @@ WSRFLIST = (WSRF_V1_2,) | |||
class OASIS: | |||
'''URLs for Oasis specifications | |||
''' | |||
WSSE = "http://docs.oasis-open.org/wss/2004/01/" | |||
@@ -164,6 +165,7 @@ class OASIS: | |||
class APACHE: | |||
''' | |||
This name space is defined by AXIS and it is used for the TC in | |||
TCapache.py, Map and file attachment (DataHandler) | |||
@@ -222,6 +224,7 @@ WSA_LIST = (WSA200508, WSA200408, WSA200403, WSA200303) | |||
class _WSAW(str): | |||
""" | |||
Define ADDRESS attribute to be compatible with WSA* layout | |||
""" | |||
@@ -51,7 +51,7 @@ class TimeoutSocket: | |||
apply(sock.connect, addr) | |||
sock.setblocking(timeout != 0) | |||
return 1 | |||
except socket.error, why: | |||
except socket.error as why: | |||
if not timeout: | |||
raise | |||
sock.setblocking(1) | |||
@@ -67,7 +67,7 @@ class TimeoutSocket: | |||
try: | |||
apply(sock.connect, addr) | |||
return 1 | |||
except socket.error, why: | |||
except socket.error as why: | |||
if len(why.args) == 1: | |||
code = 0 | |||
else: | |||
@@ -15,15 +15,27 @@ | |||
ident = "$Id$" | |||
import copy | |||
import sys | |||
import types | |||
import string | |||
import six | |||
import socket | |||
import weakref | |||
from os.path import isfile | |||
from string import join, strip, split | |||
from UserDict import UserDict | |||
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 | |||
@@ -42,9 +54,10 @@ try: | |||
except ImportError: | |||
from http.client import HTTPConnection, HTTPSConnection | |||
from exceptions import Exception | |||
try: | |||
from exceptions import Exception | |||
except: | |||
pass | |||
try: | |||
from ZSI import _get_idstr | |||
except: | |||
@@ -61,9 +74,10 @@ import xml.dom.minidom | |||
from xml.dom import Node | |||
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: | |||
from xml.dom.ext import SplitQName | |||
@@ -91,20 +105,6 @@ except: | |||
return | |||
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): | |||
@@ -235,7 +235,7 @@ def urlopen(url, timeout=20, redirects=None): | |||
if redirects is not None and location in redirects: | |||
raise RecursionError( | |||
'Circular HTTP redirection detected.' | |||
) | |||
) | |||
if redirects is None: | |||
redirects = {} | |||
redirects[location] = 1 | |||
@@ -289,40 +289,40 @@ class DOM: | |||
return value | |||
raise ValueError( | |||
'Unsupported SOAP envelope uri: %s' % uri | |||
) | |||
) | |||
def GetSOAPEnvUri(self, version): | |||
"""Return the appropriate SOAP envelope uri for a given | |||
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) | |||
if value is not None: | |||
return value | |||
raise ValueError( | |||
'Unsupported SOAP version: %s' % version | |||
) | |||
) | |||
def GetSOAPEncUri(self, version): | |||
"""Return the appropriate SOAP encoding uri for a given | |||
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) | |||
if value is not None: | |||
return value | |||
raise ValueError( | |||
'Unsupported SOAP version: %s' % version | |||
) | |||
) | |||
def GetSOAPActorNextUri(self, version): | |||
"""Return the right special next-actor uri for a given | |||
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) | |||
if value is not None: | |||
return value | |||
raise ValueError( | |||
'Unsupported SOAP version: %s' % version | |||
) | |||
) | |||
# Namespace stuff related to XML Schema. | |||
NS_XSD_99 = 'http://www.w3.org/1999/XMLSchema' | |||
@@ -346,7 +346,7 @@ class DOM: | |||
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 | |||
def InstanceUriForSchemaUri(self, uri): | |||
@@ -391,52 +391,52 @@ class DOM: | |||
return value | |||
raise ValueError( | |||
'Unsupported SOAP envelope uri: %s' % uri | |||
) | |||
) | |||
def GetWSDLUri(self, version): | |||
attr = 'NS_WSDL_%s' % join(split(version, '.'), '_') | |||
attr = 'NS_WSDL_%s' % '_'.join(version.split('.')) | |||
value = getattr(self, attr, None) | |||
if value is not None: | |||
return value | |||
raise ValueError( | |||
'Unsupported WSDL version: %s' % 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) | |||
if value is not None: | |||
return value | |||
raise ValueError( | |||
'Unsupported WSDL version: %s' % 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) | |||
if value is not None: | |||
return value | |||
raise ValueError( | |||
'Unsupported WSDL version: %s' % 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) | |||
if value is not None: | |||
return value | |||
raise ValueError( | |||
'Unsupported WSDL version: %s' % 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) | |||
if value is not None: | |||
return value | |||
raise ValueError( | |||
'Unsupported WSDL version: %s' % version | |||
) | |||
) | |||
# Other xml namespace constants. | |||
NS_XMLNS = 'http://www.w3.org/2000/xmlns/' | |||
@@ -449,7 +449,7 @@ class DOM: | |||
return node.localName == name and \ | |||
(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 | |||
namespace uri, or the default if one is provided.""" | |||
nsmatch = self.nsUriMatch | |||
@@ -457,13 +457,13 @@ class DOM: | |||
for child in node.childNodes: | |||
if child.nodeType == ELEMENT_NODE: | |||
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 | |||
if default is not join: | |||
if default != DEFAULT: | |||
return default | |||
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.""" | |||
attrget = self.getAttr | |||
ELEMENT_NODE = node.ELEMENT_NODE | |||
@@ -471,7 +471,7 @@ class DOM: | |||
if child.nodeType == ELEMENT_NODE: | |||
if attrget(child, 'id') == id: | |||
return child | |||
if default is not join: | |||
if default != DEFAULT: | |||
return default | |||
raise KeyError(name) | |||
@@ -503,7 +503,7 @@ class DOM: | |||
for child in node.childNodes: | |||
if child.nodeType == ELEMENT_NODE: | |||
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) | |||
return result | |||
@@ -517,23 +517,35 @@ class DOM: | |||
return False | |||
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 | |||
optional nsuri, or the default if one is specified. If | |||
nsuri is not specified, an attribute that matches the | |||
given name will be returned regardless of namespace.""" | |||
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: | |||
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: | |||
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: | |||
return result.value | |||
if default is not join: | |||
if default != DEFAULT: | |||
return default | |||
return '' | |||
@@ -555,9 +567,9 @@ class DOM: | |||
if nodetype == child.TEXT_NODE or \ | |||
nodetype == child.CDATA_SECTION_NODE: | |||
result.append(child.nodeValue) | |||
value = join(result, '') | |||
value = ''.join(result) | |||
if preserve_ws is None: | |||
value = strip(value) | |||
value = value.strip() | |||
return value | |||
def findNamespaceURI(self, prefix, node): | |||
@@ -901,7 +913,7 @@ class ElementProxy(Base, MessageInterface): | |||
for attr in node.attributes.values(): | |||
if attr.namespaceURI == XMLNS.BASE \ | |||
and nsuri == attr.value: | |||
return attr.localName | |||
return attr.localName | |||
else: | |||
if node.parentNode: | |||
return self._getPrefix(node.parentNode, nsuri) | |||
@@ -1190,8 +1202,8 @@ class Collection(UserDict): | |||
self._func = key or self.default | |||
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): | |||
return self.list[key] | |||
return self.data[key] | |||
@@ -1226,7 +1238,7 @@ class CollectionNS(UserDict): | |||
def __getitem__(self, key): | |||
self.targetNamespace = self.parent().targetNamespace | |||
if isinstance(key, types.IntType): | |||
if isinstance(key, six.integer_types): | |||
return self.list[key] | |||
elif self.__isSequence(key): | |||
nsuri, name = key | |||
@@ -1243,7 +1255,7 @@ class CollectionNS(UserDict): | |||
self.data[targetNamespace][key] = item | |||
def __isSequence(self, key): | |||
return (type(key) in (types.TupleType, types.ListType) | |||
return (isinstance(key, (tuple, list)) | |||
and len(key) == 2) | |||
def keys(self): | |||
@@ -21,6 +21,7 @@ from .XMLSchema import XMLSchema, SchemaReader, WSDLToolsAdapter | |||
class WSDLReader: | |||
"""A WSDLReader creates WSDL instances from urls and xml data.""" | |||
# Custom subclasses of WSDLReader may wish to implement a caching | |||
@@ -61,6 +62,7 @@ class WSDLReader: | |||
class WSDL: | |||
"""A WSDL object models a WSDL service description. WSDL objects | |||
may be created manually or loaded from an xml representation | |||
using a WSDLReader instance.""" | |||
@@ -90,7 +92,7 @@ class WSDL: | |||
if name in self.services: | |||
raise WSDLError( | |||
'Duplicate service element: %s' % name | |||
) | |||
) | |||
item = Service(name, documentation) | |||
if targetNamespace: | |||
item.targetNamespace = targetNamespace | |||
@@ -101,7 +103,7 @@ class WSDL: | |||
if name in self.messages: | |||
raise WSDLError( | |||
'Duplicate message element: %s.' % name | |||
) | |||
) | |||
item = Message(name, documentation) | |||
if targetNamespace: | |||
item.targetNamespace = targetNamespace | |||
@@ -112,7 +114,7 @@ class WSDL: | |||
if name in self.portTypes: | |||
raise WSDLError( | |||
'Duplicate portType element: name' | |||
) | |||
) | |||
item = PortType(name, documentation) | |||
if targetNamespace: | |||
item.targetNamespace = targetNamespace | |||
@@ -123,7 +125,7 @@ class WSDL: | |||
if name in self.bindings: | |||
raise WSDLError( | |||
'Duplicate binding element: %s' % name | |||
) | |||
) | |||
item = Binding(name, type, documentation) | |||
if targetNamespace: | |||
item.targetNamespace = targetNamespace | |||
@@ -182,7 +184,7 @@ class WSDL: | |||
if definitions is None: | |||
raise WSDLError( | |||
'Missing <definitions> element.' | |||
) | |||
) | |||
self.version = DOM.WSDLUriToVersion(definitions.namespaceURI) | |||
NS_WSDL = DOM.GetWSDLUri(self.version) | |||
@@ -261,7 +263,7 @@ class WSDL: | |||
if type is None: | |||
raise WSDLError( | |||
'Missing type attribute for binding %s.' % name | |||
) | |||
) | |||
type = ParseQName(type, element) | |||
docs = GetDocumentation(element) | |||
binding = self.addBinding(name, type, docs, targetNamespace) | |||
@@ -318,7 +320,7 @@ class WSDL: | |||
if namespace is None or location is None: | |||
raise WSDLError( | |||
'Invalid import element (missing namespace or location).' | |||
) | |||
) | |||
if base_location: | |||
location = basejoin(base_location, location) | |||
element.setAttributeNS(None, 'location', location) | |||
@@ -336,7 +338,7 @@ class WSDL: | |||
if imported is None: | |||
raise WSDLError( | |||
'Import target element not found for: %s' % location | |||
) | |||
) | |||
imported_tns = DOM.findTargetNS(imported) | |||
if imported_tns != namespace: | |||
@@ -376,7 +378,9 @@ class WSDL: | |||
class Element: | |||
"""A class that provides common functions for WSDL element classes.""" | |||
def __init__(self, name=None, documentation=''): | |||
self.name = name | |||
self.documentation = documentation | |||
@@ -402,6 +406,7 @@ class Element: | |||
class ImportElement(Element): | |||
def __init__(self, namespace, location): | |||
self.namespace = namespace | |||
self.location = location | |||
@@ -438,6 +443,7 @@ class Types(Collection): | |||
class Message(Element): | |||
def __init__(self, name, documentation=''): | |||
Element.__init__(self, name, documentation) | |||
self.parts = Collection(self) | |||
@@ -446,11 +452,11 @@ class Message(Element): | |||
if name in self.parts: | |||
raise WSDLError( | |||
'Duplicate message part element: %s' % name | |||
) | |||
) | |||
if type is None and element is None: | |||
raise WSDLError( | |||
'Missing type or element attribute for part: %s' % name | |||
) | |||
) | |||
item = MessagePart(name) | |||
item.element = element | |||
item.type = type | |||
@@ -467,7 +473,7 @@ class Message(Element): | |||
if typeref is None and elemref is None: | |||
raise WSDLError( | |||
'No type or element attribute for part: %s' % name | |||
) | |||
) | |||
if typeref is not None: | |||
part.type = ParseTypeRef(typeref, element) | |||
if elemref is not None: | |||
@@ -508,6 +514,7 @@ class Message(Element): | |||
class MessagePart(Element): | |||
def __init__(self, name): | |||
Element.__init__(self, name, '') | |||
self.element = None | |||
@@ -547,6 +554,7 @@ class MessagePart(Element): | |||
class PortType(Element): | |||
'''PortType has a anyAttribute, thus must provide for an extensible | |||
mechanism for supporting such attributes. ResourceProperties is | |||
specified in WS-ResourceProperties. wsa:Action is specified in | |||
@@ -644,13 +652,14 @@ class PortType(Element): | |||
ns, name = self.resourceProperties | |||
prefix = epc.getPrefix(ns) | |||
epc.setAttributeNS(WSRF.PROPERTIES.LATEST, 'ResourceProperties', | |||
'%s:%s' % (prefix, name)) | |||
'%s:%s' % (prefix, name)) | |||
for op in self.operations: | |||
op.toDom(epc._getNode()) | |||
class Operation(Element): | |||
def __init__(self, name, documentation='', parameterOrder=None): | |||
Element.__init__(self, name, documentation) | |||
self.parameterOrder = parameterOrder | |||
@@ -697,7 +706,7 @@ class Operation(Element): | |||
if name in self.faults: | |||
raise WSDLError( | |||
'Duplicate fault element: %s' % name | |||
) | |||
) | |||
item = MessageRole('fault', message, name, documentation, action) | |||
self.faults[name] = item | |||
return item | |||
@@ -728,6 +737,7 @@ class Operation(Element): | |||
class MessageRole(Element): | |||
def __init__(self, type, message, name='', documentation='', action=None): | |||
Element.__init__(self, name, documentation) | |||
self.message = message | |||
@@ -775,6 +785,7 @@ class MessageRole(Element): | |||
class Binding(Element): | |||
def __init__(self, name, type, documentation=''): | |||
Element.__init__(self, name, documentation) | |||
self.operations = Collection(self) | |||
@@ -869,6 +880,7 @@ class Binding(Element): | |||
class OperationBinding(Element): | |||
def __init__(self, name, documentation=''): | |||
Element.__init__(self, name, documentation) | |||
self.input = None | |||
@@ -952,6 +964,7 @@ class OperationBinding(Element): | |||
class MessageRoleBinding(Element): | |||
def __init__(self, type, name='', documentation=''): | |||
Element.__init__(self, name, documentation) | |||
self.type = type | |||
@@ -976,7 +989,7 @@ class MessageRoleBinding(Element): | |||
if use is None: | |||
raise WSDLError( | |||
'Invalid soap:body binding element.' | |||
) | |||
) | |||
ob = SoapBodyBinding(use, namespace, encstyle, parts) | |||
self.addExtension(ob) | |||
continue | |||
@@ -989,14 +1002,14 @@ class MessageRoleBinding(Element): | |||
if use is None or name is None: | |||
raise WSDLError( | |||
'Invalid soap:fault binding element.' | |||
) | |||
) | |||
ob = SoapFaultBinding(name, use, namespace, encstyle) | |||
self.addExtension(ob) | |||
continue | |||
elif ns in DOM.NS_SOAP_BINDING_ALL and name in ( | |||
'header', 'headerfault' | |||
): | |||
): | |||
encstyle = DOM.getAttr(e, 'encodingStyle', default=None) | |||
namespace = DOM.getAttr(e, 'namespace', default=None) | |||
message = DOM.getAttr(e, 'message') | |||
@@ -1055,6 +1068,7 @@ class MessageRoleBinding(Element): | |||
class Service(Element): | |||
def __init__(self, name, documentation=''): | |||
Element.__init__(self, name, documentation) | |||
self.ports = Collection(self) | |||
@@ -1075,7 +1089,7 @@ class Service(Element): | |||
if name is None or binding is None: | |||
raise WSDLError( | |||
'Invalid port element.' | |||
) | |||
) | |||
binding = ParseQName(binding, element) | |||
port = self.addPort(name, binding, docs) | |||
port.load_ex(GetExtensions(element)) | |||
@@ -1096,6 +1110,7 @@ class Service(Element): | |||
class Port(Element): | |||
def __init__(self, name, binding, documentation=''): | |||
Element.__init__(self, name, documentation) | |||
self.binding = binding | |||
@@ -1127,7 +1142,7 @@ class Port(Element): | |||
return item | |||
raise WSDLError( | |||
'No address binding found in port.' | |||
) | |||
) | |||
def load_ex(self, elements): | |||
for e in elements: | |||
@@ -1161,6 +1176,7 @@ class Port(Element): | |||
class SoapBinding: | |||
def __init__(self, transport, style='rpc'): | |||
self.transport = transport | |||
self.style = style | |||
@@ -1179,6 +1195,7 @@ class SoapBinding: | |||
class SoapAddressBinding: | |||
def __init__(self, location): | |||
self.location = location | |||
@@ -1193,6 +1210,7 @@ class SoapAddressBinding: | |||
class SoapOperationBinding: | |||
def __init__(self, soapAction=None, style=None): | |||
self.soapAction = soapAction | |||
self.style = style | |||
@@ -1211,11 +1229,12 @@ class SoapOperationBinding: | |||
class SoapBodyBinding: | |||
def __init__(self, use, namespace=None, encodingStyle=None, parts=None): | |||
if not use in ('literal', 'encoded'): | |||
raise WSDLError( | |||
'Invalid use attribute value: %s' % use | |||
) | |||
) | |||
self.encodingStyle = encodingStyle | |||
self.namespace = namespace | |||
if type(parts) in (type(''), type(u'')): | |||
@@ -1235,11 +1254,12 @@ class SoapBodyBinding: | |||
class SoapFaultBinding: | |||
def __init__(self, name, use, namespace=None, encodingStyle=None): | |||
if not use in ('literal', 'encoded'): | |||
raise WSDLError( | |||
'Invalid use attribute value: %s' % use | |||
) | |||
) | |||
self.encodingStyle = encodingStyle | |||
self.namespace = namespace | |||
self.name = name | |||
@@ -1261,11 +1281,12 @@ class SoapFaultBinding: | |||
class SoapHeaderBinding: | |||
def __init__(self, message, part, use, namespace=None, encodingStyle=None): | |||
if not use in ('literal', 'encoded'): | |||
raise WSDLError( | |||
'Invalid use attribute value: %s' % use | |||
) | |||
) | |||
self.encodingStyle = encodingStyle | |||
self.namespace = namespace | |||
self.message = message | |||
@@ -1280,16 +1301,19 @@ class SoapHeaderFaultBinding(SoapHeaderBinding): | |||
class HttpBinding: | |||
def __init__(self, verb): | |||
self.verb = verb | |||
class HttpAddressBinding: | |||
def __init__(self, location): | |||
self.location = location | |||
class HttpOperationBinding: | |||
def __init__(self, location): | |||
self.location = location | |||
@@ -1303,17 +1327,20 @@ class HttpUrlEncodedBinding: | |||
class MimeContentBinding: | |||
def __init__(self, part=None, type=None): | |||
self.part = part | |||
self.type = type | |||
class MimeXmlBinding: | |||
def __init__(self, part=None): | |||
self.part = part | |||
class MimeMultipartRelatedBinding: | |||
def __init__(self): | |||
self.parts = [] | |||
@@ -1326,6 +1353,7 @@ class MimeMultipartRelatedBinding: | |||
class MimePartBinding: | |||
def __init__(self): | |||
self.items = [] | |||
@@ -1353,7 +1381,7 @@ class MimePartBinding: | |||
if use is None: | |||
raise WSDLError( | |||
'Invalid soap:body binding element.' | |||
) | |||
) | |||
ob = SoapBodyBinding(use, namespace, encstyle, parts) | |||
self.items.append(ob) | |||
continue | |||
@@ -1397,7 +1425,7 @@ def GetDocumentation(element): | |||
def GetExtensions(element): | |||
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): | |||
@@ -1446,8 +1474,8 @@ def FindExtensions(object, kind, t_type=type(())): | |||
result = [] | |||
namespaceURI, name = kind | |||
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] | |||
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 | |||
for item in object.extensions: | |||
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 | |||
else: | |||
for item in object.extensions: | |||
@@ -1468,6 +1496,7 @@ def FindExtension(object, kind, t_type=type(())): | |||
class SOAPCallInfo: | |||
"""SOAPCallInfo captures the important binding information about a | |||
SOAP operation, in a structure that is easier to work with than | |||
raw WSDL structures.""" | |||
@@ -1547,7 +1576,9 @@ class SOAPCallInfo: | |||
class ParameterInfo: | |||
"""A ParameterInfo object captures parameter binding information.""" | |||
def __init__(self, name, type, namespace=None, element_type=0): | |||
if element_type: | |||
self.element_type = 1 | |||
@@ -1562,7 +1593,9 @@ class ParameterInfo: | |||
class HeaderInfo(ParameterInfo): | |||
"""A HeaderInfo object captures SOAP header binding information.""" | |||
def __init__(self, name, type, namespace, element_type=None): | |||
ParameterInfo.__init__(self, name, type, namespace, element_type) | |||
@@ -1614,7 +1647,7 @@ def callInfoFromWSDL(port, name): | |||
part.element or part.type, | |||
item.namespace, | |||
element_type=part.element and 1 or 0 | |||
) | |||
) | |||
header.encodingStyle = item.encodingStyle | |||
body = msgrole.findBinding(SoapBodyBinding) | |||
@@ -1636,7 +1669,7 @@ def callInfoFromWSDL(port, name): | |||
part.name, | |||
part.element or part.type, | |||
element_type=part.element and 1 or 0 | |||
) | |||
) | |||
if operation.output is not None: | |||
try: | |||
@@ -1665,7 +1698,7 @@ def callInfoFromWSDL(port, name): | |||
part.element or part.type, | |||
item.namespace, | |||
element_type=part.element and 1 or 0 | |||
) | |||
) | |||
header.encodingStyle = item.encodingStyle | |||
body = msgrole.findBinding(SoapBodyBinding) | |||
@@ -1688,6 +1721,6 @@ def callInfoFromWSDL(port, name): | |||
part.name, | |||
part.element or part.type, | |||
element_type=part.element and 1 or 0 | |||
) | |||
) | |||
return callinfo |
@@ -72,9 +72,9 @@ def toXMLname(string): | |||
if i < N - 1 and T[i] == u'_' and T[i + 1] == u'x': | |||
X.append(u'_x005F_') | |||
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]) | |||
elif (not _NCNameChar(T[i])) or (i == 0 and not _NCNameStartChar(T[i])): | |||
X.append(_toUnicodeHex(T[i])) | |||
@@ -101,8 +101,8 @@ def _utilized(n, node, other_attrs, unsuppressedPrefixes): | |||
elif n.startswith('xmlns'): | |||
n = n[5:] | |||
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: | |||
if n == attr.prefix: | |||
return 1 | |||
@@ -151,6 +151,7 @@ _in_subset = lambda subset, node: subset is None or node in subset # rich's twe | |||
class _implementation: | |||
'''Implementation class for C14N. This accompanies a node during it's | |||
processing and includes the parameters and processing state.''' | |||
@@ -174,7 +175,7 @@ class _implementation: | |||
self.documentOrder = _Element # At document element | |||
if not _inclusive(self): | |||
inherited, unused = _inclusiveNamespacePrefixes(node, self._inherit_context(node), | |||
self.unsuppressedPrefixes) | |||
self.unsuppressedPrefixes) | |||
self._do_element(node, inherited, unused=unused) | |||
else: | |||
inherited = self._inherit_context(node) | |||
@@ -311,7 +312,7 @@ class _implementation: | |||
# xml_attrs_local -- Local attributes in XML namespace. | |||
# ns_unused_inherited -- not rendered namespaces, used for exclusive | |||
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 | |||
if unused is None: | |||
@@ -372,14 +373,14 @@ class _implementation: | |||
# If default namespace is XMLNS.BASE or empty, | |||
# and if an ancestor was the same | |||
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 | |||
# "omit namespace node with local name xml, which defines | |||
# the xml prefix, if its string value is | |||
# http://www.w3.org/XML/1998/namespace." | |||
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 | |||
# If not previously rendered | |||
@@ -1 +1 @@ | |||
__version__ = "0.4.3" | |||
__version__ = "0.4.4" |