Hello community,
here is the log from the commit of package python-wadllib for
openSUSE:Leap:15.2 checked in at 2020-03-09 18:11:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Leap:15.2/python-wadllib (Old)
and /work/SRC/openSUSE:Leap:15.2/.python-wadllib.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-wadllib"
Mon Mar 9 18:11:24 2020 rev:11 rq:777270 version:1.3.3
Changes:
--------
--- /work/SRC/openSUSE:Leap:15.2/python-wadllib/python-wadllib.changes
2020-01-15 15:54:09.143622288 +0100
+++
/work/SRC/openSUSE:Leap:15.2/.python-wadllib.new.26092/python-wadllib.changes
2020-03-09 18:11:25.693201942 +0100
@@ -1,0 +2,8 @@
+Thu Aug 23 09:25:47 UTC 2018 - [email protected]
+
+- Update to 1.3.3:
+ * Support python3
+- Switch to singlespec
+- Run tests
+
+-------------------------------------------------------------------
Old:
----
wadllib-1.3.2.tar.gz
New:
----
wadllib-1.3.3.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-wadllib.spec ++++++
--- /var/tmp/diff_new_pack.qmdNTg/_old 2020-03-09 18:11:26.301202813 +0100
+++ /var/tmp/diff_new_pack.qmdNTg/_new 2020-03-09 18:11:26.305202819 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-wadllib
#
-# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -16,24 +16,22 @@
#
+%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-wadllib
-Version: 1.3.2
+Version: 1.3.3
Release: 0
Summary: Navigate HTTP resources using WADL files as guides
-License: LGPL-3.0+
+License: LGPL-3.0-or-later
Group: Development/Languages/Python
-Url: https://launchpad.net/wadllib
-Source:
http://pypi.python.org/packages/source/w/wadllib/wadllib-%{version}.tar.gz
-BuildRequires: python-devel
-BuildRequires: python-setuptools
-#BuildRequires: python-lazr.uri
+URL: https://launchpad.net/wadllib
+Source:
https://files.pythonhosted.org/packages/source/w/wadllib/wadllib-%{version}.tar.gz
+BuildRequires: %{python_module lazr.uri}
+BuildRequires: %{python_module setuptools}
+BuildRequires: fdupes
+BuildRequires: python-rpm-macros
Requires: python-lazr.uri
-BuildRoot: %{_tmppath}/%{name}-%{version}-build
-%if 0%{?suse_version} && 0%{?suse_version} <= 1110
-%{!?python_sitelib: %global python_sitelib %(python -c "from
distutils.sysconfig import get_python_lib; print get_python_lib()")}
-%else
BuildArch: noarch
-%endif
+%python_subpackages
%description
An Application object represents a web service described by a WADL
@@ -43,18 +41,18 @@
%setup -q -n wadllib-%{version}
%build
-python setup.py build
+%python_build
%install
-python setup.py install --prefix=%{_prefix} --root=%{buildroot}
+%python_install
+%python_expand %fdupes %{buildroot}%{$python_sitelib}
-#NOTE(saschpe): Doctests currently broken:
-#%%check
-#python setup.py test
-
-%files
-%defattr(-,root,root,-)
-%doc COPYING.txt README.txt
+%check
+%python_exec setup.py test
+
+%files %{python_files}
+%license COPYING.txt
+%doc README.txt
%{python_sitelib}/*
%changelog
++++++ wadllib-1.3.2.tar.gz -> wadllib-1.3.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/wadllib-1.3.2/PKG-INFO new/wadllib-1.3.3/PKG-INFO
--- old/wadllib-1.3.2/PKG-INFO 2013-02-25 22:54:28.000000000 +0100
+++ new/wadllib-1.3.3/PKG-INFO 2018-07-20 10:55:47.000000000 +0200
@@ -1,10 +1,10 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
Name: wadllib
-Version: 1.3.2
+Version: 1.3.3
Summary: Navigate HTTP resources using WADL files as guides.
Home-page: https://launchpad.net/wadllib
-Author: LAZR Developers
-Author-email: [email protected]
+Maintainer: LAZR Developers
+Maintainer-email: [email protected]
License: LGPL v3
Download-URL: https://launchpad.net/wadllib/+download
Description: ..
@@ -304,10 +304,7 @@
to another object. The 'link' property of a parameter lets you examine
links before following them.
- >>> try:
- ... import simplejson as json
- ... except ImportError:
- ... import json
+ >>> import json
>>> links_wadl = application_for('links-wadl.xml')
>>> service_root = links_wadl.get_resource_by_path('')
>>> representation = json.dumps(
@@ -577,30 +574,63 @@
... "http://www.example.com/", binary_stream)
>>> service_root = binary_wadl.get_resource_by_path('')
+ Define a helper that processes the representation the same way
+ zope.publisher would.
+
+ >>> import cgi
+ >>> import io
+ >>> def assert_message_parts(media_type, doc, expected):
+ ... if sys.version_info[0] == 3 and sys.version_info[1] < 3:
+ ... # We can't do much due to
https://bugs.python.org/issue18013.
+ ... for value in expected:
+ ... if not isinstance(value, bytes):
+ ... value = value.encode('UTF-8')
+ ... assert value in doc
+ ... return
+ ... environ = {
+ ... 'REQUEST_METHOD': 'POST',
+ ... 'CONTENT_TYPE': media_type,
+ ... 'CONTENT_LENGTH': str(len(doc)),
+ ... }
+ ... kwargs = (
+ ... {'encoding': 'UTF-8'} if sys.version_info[0] >= 3 else
{})
+ ... fs = cgi.FieldStorage(
+ ... fp=io.BytesIO(doc), environ=environ,
keep_blank_values=1,
+ ... **kwargs)
+ ... values = []
+ ... def append_values(fields):
+ ... for field in fields:
+ ... if field.list:
+ ... append_values(field.list)
+ ... else:
+ ... values.append(field.value)
+ ... append_values(fs.list)
+ ... assert values == expected, (
+ ... 'Expected %s, got %s' % (expected, values))
+
>>> method = service_root.get_method('post', 'multipart/form-data')
>>> media_type, doc = method.build_representation(
- ... text_field="text", binary_field="\x01\x02")
+ ... text_field="text", binary_field=b"\x01\x02\r\x81\r")
>>> print(media_type)
multipart/form-data; boundary=...
- >>> print(doc)
- MIME-Version: 1.0
- Content-Type: multipart/form-data; boundary="..."
- <BLANKLINE>
- --...
- Content-Type: text/plain; charset="utf-8"
- MIME-Version: 1.0
- Content-Disposition: form-data; name="text_field"
- <BLANKLINE>
- text
- --...
- Content-Type: application/octet-stream
- MIME-Version: 1.0
- Content-Disposition: form-data; name="binary_field"
- <BLANKLINE>
- ...
- --...
- >>> '\x01\x02' in doc
- True
+ >>> assert_message_parts(media_type, doc, ['text',
b'\x01\x02\r\x81\r'])
+
+ >>> method = service_root.get_method('post', 'multipart/form-data')
+ >>> media_type, doc = method.build_representation(
+ ... text_field="text\n", binary_field=b"\x01\x02\r\x81\n\r")
+ >>> print(media_type)
+ multipart/form-data; boundary=...
+ >>> assert_message_parts(
+ ... media_type, doc, ['text\r\n', b'\x01\x02\r\x81\n\r'])
+
+ >>> method = service_root.get_method('post', 'multipart/form-data')
+ >>> media_type, doc = method.build_representation(
+ ... text_field="text\r\nmore\r\n",
+ ... binary_field=b"\x01\x02\r\n\x81\r\x82\n")
+ >>> print(media_type)
+ multipart/form-data; boundary=...
+ >>> assert_message_parts(
+ ... media_type, doc, ['text\r\nmore\r\n',
b'\x01\x02\r\n\x81\r\x82\n'])
>>> method = service_root.get_method('post', 'text/unknown')
>>> method.build_representation(field="value")
@@ -674,6 +704,16 @@
NEWS for wadllib
================
+ 1.3.3 (2018-07-20)
+ ==================
+
+ - Drop support for Python < 2.6.
+ - Add tox testing support.
+ - Implement a subset of MIME multipart/form-data encoding locally
rather
+ than using the standard library's email module, which doesn't have
good
+ handling of binary parts and corrupts bytes in them that look like
line
+ endings in various ways depending on the Python version.
[bug=1729754]
+
1.3.2 (2013-02-25)
==================
@@ -780,3 +820,4 @@
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
+Provides-Extra: docs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/wadllib-1.3.2/README.txt new/wadllib-1.3.3/README.txt
--- old/wadllib-1.3.2/README.txt 2013-02-25 19:54:03.000000000 +0100
+++ new/wadllib-1.3.3/README.txt 2018-07-20 10:53:12.000000000 +0200
@@ -1,6 +1,6 @@
Navigate HTTP resources using WADL files as guides.
-wadllib should work with Python >= 2.4.
+wadllib should work with Python >= 2.6.
..
Copyright (C) 2008-2009 Canonical Ltd.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/wadllib-1.3.2/setup.cfg new/wadllib-1.3.3/setup.cfg
--- old/wadllib-1.3.2/setup.cfg 2013-02-25 22:54:28.000000000 +0100
+++ new/wadllib-1.3.3/setup.cfg 2018-07-20 10:55:47.000000000 +0200
@@ -1,5 +1,4 @@
[egg_info]
tag_build =
tag_date = 0
-tag_svn_revision = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/wadllib-1.3.2/setup.py new/wadllib-1.3.3/setup.py
--- old/wadllib-1.3.2/setup.py 2013-02-25 19:54:03.000000000 +0100
+++ new/wadllib-1.3.3/setup.py 2018-07-20 10:53:12.000000000 +0200
@@ -44,20 +44,16 @@
'setuptools',
'lazr.uri',
]
-if sys.version < '2.5':
- # This module is in the standard library as of Python 2.5. In Python 3,
- # it doesn't work when fetched separately.
- install_requires.append('elementtree')
-if sys.version < '2.6':
- # This module is in the standard library as of Python 2.6. In Python 3,
- # it doesn't work when fetched separately.
- install_requires.extend('simplejson')
setup(
name='wadllib',
version=__version__,
packages=find_packages('src'),
package_dir={'':'src'},
+ package_data={
+ 'wadllib': ['version.txt'],
+ '': ['*.xml', '*.json'],
+ },
include_package_data=True,
zip_safe=False,
maintainer='LAZR Developers',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/wadllib-1.3.2/src/wadllib/NEWS.txt
new/wadllib-1.3.3/src/wadllib/NEWS.txt
--- old/wadllib-1.3.2/src/wadllib/NEWS.txt 2013-02-25 22:44:42.000000000
+0100
+++ new/wadllib-1.3.3/src/wadllib/NEWS.txt 2018-07-20 10:55:14.000000000
+0200
@@ -2,6 +2,16 @@
NEWS for wadllib
================
+1.3.3 (2018-07-20)
+==================
+
+- Drop support for Python < 2.6.
+- Add tox testing support.
+- Implement a subset of MIME multipart/form-data encoding locally rather
+ than using the standard library's email module, which doesn't have good
+ handling of binary parts and corrupts bytes in them that look like line
+ endings in various ways depending on the Python version. [bug=1729754]
+
1.3.2 (2013-02-25)
==================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/wadllib-1.3.2/src/wadllib/README.txt
new/wadllib-1.3.3/src/wadllib/README.txt
--- old/wadllib-1.3.2/src/wadllib/README.txt 2013-02-25 22:44:42.000000000
+0100
+++ new/wadllib-1.3.3/src/wadllib/README.txt 2018-07-20 10:53:12.000000000
+0200
@@ -295,10 +295,7 @@
to another object. The 'link' property of a parameter lets you examine
links before following them.
- >>> try:
- ... import simplejson as json
- ... except ImportError:
- ... import json
+ >>> import json
>>> links_wadl = application_for('links-wadl.xml')
>>> service_root = links_wadl.get_resource_by_path('')
>>> representation = json.dumps(
@@ -568,30 +565,63 @@
... "http://www.example.com/", binary_stream)
>>> service_root = binary_wadl.get_resource_by_path('')
+Define a helper that processes the representation the same way
+zope.publisher would.
+
+ >>> import cgi
+ >>> import io
+ >>> def assert_message_parts(media_type, doc, expected):
+ ... if sys.version_info[0] == 3 and sys.version_info[1] < 3:
+ ... # We can't do much due to https://bugs.python.org/issue18013.
+ ... for value in expected:
+ ... if not isinstance(value, bytes):
+ ... value = value.encode('UTF-8')
+ ... assert value in doc
+ ... return
+ ... environ = {
+ ... 'REQUEST_METHOD': 'POST',
+ ... 'CONTENT_TYPE': media_type,
+ ... 'CONTENT_LENGTH': str(len(doc)),
+ ... }
+ ... kwargs = (
+ ... {'encoding': 'UTF-8'} if sys.version_info[0] >= 3 else {})
+ ... fs = cgi.FieldStorage(
+ ... fp=io.BytesIO(doc), environ=environ, keep_blank_values=1,
+ ... **kwargs)
+ ... values = []
+ ... def append_values(fields):
+ ... for field in fields:
+ ... if field.list:
+ ... append_values(field.list)
+ ... else:
+ ... values.append(field.value)
+ ... append_values(fs.list)
+ ... assert values == expected, (
+ ... 'Expected %s, got %s' % (expected, values))
+
>>> method = service_root.get_method('post', 'multipart/form-data')
>>> media_type, doc = method.build_representation(
- ... text_field="text", binary_field="\x01\x02")
+ ... text_field="text", binary_field=b"\x01\x02\r\x81\r")
>>> print(media_type)
multipart/form-data; boundary=...
- >>> print(doc)
- MIME-Version: 1.0
- Content-Type: multipart/form-data; boundary="..."
- <BLANKLINE>
- --...
- Content-Type: text/plain; charset="utf-8"
- MIME-Version: 1.0
- Content-Disposition: form-data; name="text_field"
- <BLANKLINE>
- text
- --...
- Content-Type: application/octet-stream
- MIME-Version: 1.0
- Content-Disposition: form-data; name="binary_field"
- <BLANKLINE>
- ...
- --...
- >>> '\x01\x02' in doc
- True
+ >>> assert_message_parts(media_type, doc, ['text', b'\x01\x02\r\x81\r'])
+
+ >>> method = service_root.get_method('post', 'multipart/form-data')
+ >>> media_type, doc = method.build_representation(
+ ... text_field="text\n", binary_field=b"\x01\x02\r\x81\n\r")
+ >>> print(media_type)
+ multipart/form-data; boundary=...
+ >>> assert_message_parts(
+ ... media_type, doc, ['text\r\n', b'\x01\x02\r\x81\n\r'])
+
+ >>> method = service_root.get_method('post', 'multipart/form-data')
+ >>> media_type, doc = method.build_representation(
+ ... text_field="text\r\nmore\r\n",
+ ... binary_field=b"\x01\x02\r\n\x81\r\x82\n")
+ >>> print(media_type)
+ multipart/form-data; boundary=...
+ >>> assert_message_parts(
+ ... media_type, doc, ['text\r\nmore\r\n', b'\x01\x02\r\n\x81\r\x82\n'])
>>> method = service_root.get_method('post', 'text/unknown')
>>> method.build_representation(field="value")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/wadllib-1.3.2/src/wadllib/application.py
new/wadllib-1.3.3/src/wadllib/application.py
--- old/wadllib-1.3.2/src/wadllib/application.py 2013-02-25
22:44:42.000000000 +0100
+++ new/wadllib-1.3.3/src/wadllib/application.py 2018-07-20
10:53:12.000000000 +0200
@@ -1,4 +1,4 @@
-# Copyright 2008-2013 Canonical Ltd. All rights reserved.
+# Copyright 2008-2018 Canonical Ltd. All rights reserved.
# This file is part of wadllib.
#
@@ -41,38 +41,20 @@
'WADLError',
]
-try:
- # Make sure to try the Python 2 form first; we don't want to use
- # io.StringIO in Python 2, because it is strict about only accepting
- # unicode input.
- from cStringIO import StringIO as BytesIO
-except ImportError:
- from io import BytesIO
import datetime
-try:
- from email.mime.multipart import MIMEMultipart
- from email.mime.nonmultipart import MIMENonMultipart
-except ImportError:
- # We must be on 2.4.
- from email.MIMEMultipart import MIMEMultipart
- from email.MIMENonMultipart import MIMENonMultipart
-
+from email.utils import quote
+import io
+import json
+import random
+import re
+import sys
import time
try:
from urllib.parse import urlencode
except ImportError:
from urllib import urlencode
-try:
- import simplejson as json
-except ImportError:
- import json
-try:
- import xml.etree.cElementTree as ET
-except ImportError:
- try:
- import cElementTree as ET
- except ImportError:
- import elementtree.ElementTree as ET
+import xml.etree.cElementTree as ET
+
from lazr.uri import URI, merge
from wadllib import (
@@ -823,6 +805,105 @@
"""The media type of the representation described here."""
return self.resolve_definition().tag.attrib['mediaType']
+ def _make_boundary(self, all_parts):
+ """Make a random boundary that does not appear in `all_parts`."""
+ _width = len(repr(sys.maxsize - 1))
+ _fmt = '%%0%dd' % _width
+ token = random.randrange(sys.maxsize)
+ boundary = ('=' * 15) + (_fmt % token) + '=='
+ if all_parts is None:
+ return boundary
+ b = boundary
+ counter = 0
+ while True:
+ pattern = ('^--' + re.escape(b) + '(--)?$').encode('ascii')
+ if not re.search(pattern, all_parts, flags=re.MULTILINE):
+ break
+ b = boundary + '.' + str(counter)
+ counter += 1
+ return b
+
+ def _write_headers(self, buf, headers):
+ """Write MIME headers to a file object."""
+ for key, value in headers:
+ buf.write(key.encode('UTF-8'))
+ buf.write(b': ')
+ buf.write(value.encode('UTF-8'))
+ buf.write(b'\r\n')
+ buf.write(b'\r\n')
+
+ def _write_boundary(self, buf, boundary, closing=False):
+ """Write a multipart boundary to a file object."""
+ buf.write(b'--')
+ buf.write(boundary.encode('UTF-8'))
+ if closing:
+ buf.write(b'--')
+ buf.write(b'\r\n')
+
+ def _generate_multipart_form(self, parts):
+ """Generate a multipart/form-data message.
+
+ This is very loosely based on the email module in the Python standard
+ library. However, that module doesn't really support directly
embedding
+ binary data in a form: various versions of Python have mangled line
+ separators in different ways, and none of them get it quite right.
+ Since we only need a tiny subset of MIME here, it's easier to implement
+ it ourselves.
+
+ :return: a tuple of two elements: the Content-Type of the message, and
+ the entire encoded message as a byte string.
+ """
+ # Generate the subparts first so that we can calculate a safe boundary.
+ encoded_parts = []
+ for is_binary, name, value in parts:
+ buf = io.BytesIO()
+ if is_binary:
+ ctype = 'application/octet-stream'
+ # RFC 7578 says that the filename parameter isn't mandatory
+ # in our case, but without it cgi.FieldStorage tries to
+ # decode as text on Python 3.
+ cdisp = 'form-data; name="%s"; filename="%s"' % (
+ quote(name), quote(name))
+ else:
+ ctype = 'text/plain; charset="utf-8"'
+ cdisp = 'form-data; name="%s"' % quote(name)
+ self._write_headers(buf, [
+ ('MIME-Version', '1.0'),
+ ('Content-Type', ctype),
+ ('Content-Disposition', cdisp),
+ ])
+ if is_binary:
+ if not isinstance(value, bytes):
+ raise TypeError('bytes payload expected: %s' % type(value))
+ buf.write(value)
+ else:
+ if not isinstance(value, str):
+ raise TypeError('str payload expected: %s' % type(value))
+ lines = re.split(r'\r\n|\r|\n', value)
+ for line in lines[:-1]:
+ buf.write(line.encode('UTF-8'))
+ buf.write(b'\r\n')
+ buf.write(lines[-1].encode('UTF-8'))
+ encoded_parts.append(buf.getvalue())
+
+ # Create a suitable boundary.
+ boundary = self._make_boundary(b'\r\n'.join(encoded_parts))
+
+ # Now we can write the multipart headers, followed by all the parts.
+ buf = io.BytesIO()
+ ctype = 'multipart/form-data; boundary="%s"' % quote(boundary)
+ self._write_headers(buf, [
+ ('MIME-Version', '1.0'),
+ ('Content-Type', ctype),
+ ])
+ for encoded_part in encoded_parts:
+ self._write_boundary(buf, boundary)
+ buf.write(encoded_part)
+ buf.write(b'\r\n')
+ self._write_boundary(buf, boundary, closing=True)
+
+ return ctype, buf.getvalue()
+
def bind(self, param_values, **kw_param_values):
"""Bind the definition to parameter values, creating a document.
@@ -836,30 +917,13 @@
if media_type == 'application/x-www-form-urlencoded':
doc = urlencode(sorted(validated_values.items()))
elif media_type == 'multipart/form-data':
- outer = MIMEMultipart()
- outer.set_type('multipart/form-data')
+ parts = []
missing = object()
for param in params:
value = validated_values.get(param.name, missing)
if value is not missing:
- if param.type == 'binary':
- maintype, subtype = 'application', 'octet-stream'
- params = {}
- else:
- maintype, subtype = 'text', 'plain'
- params = {'charset' : 'utf-8'}
- inner = MIMENonMultipart(maintype, subtype, **params)
- inner.set_payload(value)
- inner['Content-Disposition'] = (
- 'form-data; name="%s"' % param.name)
- outer.attach(inner)
- doc = str(outer)
- # Chop off the 'From' line, which only makes sense in an
- # email. (Python 3 does not include it.)
- if doc.startswith('From '):
- doc = doc[doc.find('\n')+1:]
- media_type = (outer.get_content_type() +
- '; boundary="%s"' % outer.get_boundary())
+ parts.append((param.type == 'binary', param.name, value))
+ media_type, doc = self._generate_multipart_form(parts)
elif media_type == 'application/json':
doc = json.dumps(validated_values)
else:
@@ -1105,7 +1169,9 @@
def _from_string(self, markup):
"""Turns markup into a document."""
- return self._from_stream(BytesIO(markup))
+ if not isinstance(markup, bytes):
+ markup = markup.encode("UTF-8")
+ return self._from_stream(io.BytesIO(markup))
def get_resource_type(self, resource_type_url):
"""Retrieve a resource type by the URL of its description."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/wadllib-1.3.2/src/wadllib/tests/test_docs.py
new/wadllib-1.3.3/src/wadllib/tests/test_docs.py
--- old/wadllib-1.3.2/src/wadllib/tests/test_docs.py 2013-02-25
19:54:03.000000000 +0100
+++ new/wadllib-1.3.3/src/wadllib/tests/test_docs.py 2018-07-20
10:53:12.000000000 +0200
@@ -1,4 +1,4 @@
-# Copyright 2009 Canonical Ltd. All rights reserved.
+# Copyright 2009-2018 Canonical Ltd. All rights reserved.
#
# This file is part of wadllib
#
@@ -16,16 +16,20 @@
"""Test harness."""
+from __future__ import absolute_import, print_function
+
__metaclass__ = type
__all__ = [
- 'additional_tests',
+ 'load_tests',
]
+import __future__
import atexit
import doctest
import os
+
import pkg_resources
-import unittest
+
DOCTEST_FLAGS = (
doctest.ELLIPSIS |
@@ -33,7 +37,7 @@
doctest.REPORT_NDIFF)
-def additional_tests():
+def load_tests(loader, tests, pattern):
doctest_files = [
os.path.abspath(
pkg_resources.resource_filename('wadllib', 'README.txt'))]
@@ -44,7 +48,11 @@
os.path.abspath(
pkg_resources.resource_filename(
'wadllib', 'docs/%s' % name)))
- kwargs = dict(module_relative=False, optionflags=DOCTEST_FLAGS)
+ globs = {
+ future_item: getattr(__future__, future_item)
+ for future_item in ('absolute_import', 'print_function')}
+ kwargs = dict(
+ module_relative=False, globs=globs, optionflags=DOCTEST_FLAGS)
atexit.register(pkg_resources.cleanup_resources)
- return unittest.TestSuite((
- doctest.DocFileSuite(*doctest_files, **kwargs)))
+ tests.addTest(doctest.DocFileSuite(*doctest_files, **kwargs))
+ return tests
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/wadllib-1.3.2/src/wadllib/version.txt
new/wadllib-1.3.3/src/wadllib/version.txt
--- old/wadllib-1.3.2/src/wadllib/version.txt 2013-02-25 22:45:59.000000000
+0100
+++ new/wadllib-1.3.3/src/wadllib/version.txt 2018-07-20 10:55:31.000000000
+0200
@@ -1 +1 @@
-1.3.2
+1.3.3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/wadllib-1.3.2/src/wadllib.egg-info/PKG-INFO
new/wadllib-1.3.3/src/wadllib.egg-info/PKG-INFO
--- old/wadllib-1.3.2/src/wadllib.egg-info/PKG-INFO 2013-02-25
22:54:28.000000000 +0100
+++ new/wadllib-1.3.3/src/wadllib.egg-info/PKG-INFO 2018-07-20
10:55:47.000000000 +0200
@@ -1,10 +1,10 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
Name: wadllib
-Version: 1.3.2
+Version: 1.3.3
Summary: Navigate HTTP resources using WADL files as guides.
Home-page: https://launchpad.net/wadllib
-Author: LAZR Developers
-Author-email: [email protected]
+Maintainer: LAZR Developers
+Maintainer-email: [email protected]
License: LGPL v3
Download-URL: https://launchpad.net/wadllib/+download
Description: ..
@@ -304,10 +304,7 @@
to another object. The 'link' property of a parameter lets you examine
links before following them.
- >>> try:
- ... import simplejson as json
- ... except ImportError:
- ... import json
+ >>> import json
>>> links_wadl = application_for('links-wadl.xml')
>>> service_root = links_wadl.get_resource_by_path('')
>>> representation = json.dumps(
@@ -577,30 +574,63 @@
... "http://www.example.com/", binary_stream)
>>> service_root = binary_wadl.get_resource_by_path('')
+ Define a helper that processes the representation the same way
+ zope.publisher would.
+
+ >>> import cgi
+ >>> import io
+ >>> def assert_message_parts(media_type, doc, expected):
+ ... if sys.version_info[0] == 3 and sys.version_info[1] < 3:
+ ... # We can't do much due to
https://bugs.python.org/issue18013.
+ ... for value in expected:
+ ... if not isinstance(value, bytes):
+ ... value = value.encode('UTF-8')
+ ... assert value in doc
+ ... return
+ ... environ = {
+ ... 'REQUEST_METHOD': 'POST',
+ ... 'CONTENT_TYPE': media_type,
+ ... 'CONTENT_LENGTH': str(len(doc)),
+ ... }
+ ... kwargs = (
+ ... {'encoding': 'UTF-8'} if sys.version_info[0] >= 3 else
{})
+ ... fs = cgi.FieldStorage(
+ ... fp=io.BytesIO(doc), environ=environ,
keep_blank_values=1,
+ ... **kwargs)
+ ... values = []
+ ... def append_values(fields):
+ ... for field in fields:
+ ... if field.list:
+ ... append_values(field.list)
+ ... else:
+ ... values.append(field.value)
+ ... append_values(fs.list)
+ ... assert values == expected, (
+ ... 'Expected %s, got %s' % (expected, values))
+
>>> method = service_root.get_method('post', 'multipart/form-data')
>>> media_type, doc = method.build_representation(
- ... text_field="text", binary_field="\x01\x02")
+ ... text_field="text", binary_field=b"\x01\x02\r\x81\r")
>>> print(media_type)
multipart/form-data; boundary=...
- >>> print(doc)
- MIME-Version: 1.0
- Content-Type: multipart/form-data; boundary="..."
- <BLANKLINE>
- --...
- Content-Type: text/plain; charset="utf-8"
- MIME-Version: 1.0
- Content-Disposition: form-data; name="text_field"
- <BLANKLINE>
- text
- --...
- Content-Type: application/octet-stream
- MIME-Version: 1.0
- Content-Disposition: form-data; name="binary_field"
- <BLANKLINE>
- ...
- --...
- >>> '\x01\x02' in doc
- True
+ >>> assert_message_parts(media_type, doc, ['text',
b'\x01\x02\r\x81\r'])
+
+ >>> method = service_root.get_method('post', 'multipart/form-data')
+ >>> media_type, doc = method.build_representation(
+ ... text_field="text\n", binary_field=b"\x01\x02\r\x81\n\r")
+ >>> print(media_type)
+ multipart/form-data; boundary=...
+ >>> assert_message_parts(
+ ... media_type, doc, ['text\r\n', b'\x01\x02\r\x81\n\r'])
+
+ >>> method = service_root.get_method('post', 'multipart/form-data')
+ >>> media_type, doc = method.build_representation(
+ ... text_field="text\r\nmore\r\n",
+ ... binary_field=b"\x01\x02\r\n\x81\r\x82\n")
+ >>> print(media_type)
+ multipart/form-data; boundary=...
+ >>> assert_message_parts(
+ ... media_type, doc, ['text\r\nmore\r\n',
b'\x01\x02\r\n\x81\r\x82\n'])
>>> method = service_root.get_method('post', 'text/unknown')
>>> method.build_representation(field="value")
@@ -674,6 +704,16 @@
NEWS for wadllib
================
+ 1.3.3 (2018-07-20)
+ ==================
+
+ - Drop support for Python < 2.6.
+ - Add tox testing support.
+ - Implement a subset of MIME multipart/form-data encoding locally
rather
+ than using the standard library's email module, which doesn't have
good
+ handling of binary parts and corrupts bytes in them that look like
line
+ endings in various ways depending on the Python version.
[bug=1729754]
+
1.3.2 (2013-02-25)
==================
@@ -780,3 +820,4 @@
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
+Provides-Extra: docs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/wadllib-1.3.2/src/wadllib.egg-info/requires.txt
new/wadllib-1.3.3/src/wadllib.egg-info/requires.txt
--- old/wadllib-1.3.2/src/wadllib.egg-info/requires.txt 2013-02-25
22:54:28.000000000 +0100
+++ new/wadllib-1.3.3/src/wadllib.egg-info/requires.txt 2018-07-20
10:55:47.000000000 +0200
@@ -1,6 +1,6 @@
-setuptools
lazr.uri
+setuptools
[docs]
Sphinx
-z3c.recipe.sphinxdoc
\ No newline at end of file
+z3c.recipe.sphinxdoc