Merge ~cjwatson/lazr.restful:remove-six into lazr.restful:main

Proposed by Colin Watson
Status: Merged
Merged at revision: 6614e9088b62aca53bfb52ca13259dd34529492a
Proposed branch: ~cjwatson/lazr.restful:remove-six
Merge into: lazr.restful:main
Diff against target: 242 lines (+26/-29)
8 files modified
setup.py (+0/-1)
src/lazr/restful/debug.py (+1/-2)
src/lazr/restful/declarations.py (+1/-2)
src/lazr/restful/docs/webservice.rst (+14/-10)
src/lazr/restful/example/base/tests/collection.txt (+1/-3)
src/lazr/restful/example/base/tests/entry.txt (+1/-3)
src/lazr/restful/testing/helpers.py (+1/-2)
src/lazr/restful/testing/webservice.py (+7/-6)
Reviewer Review Type Date Requested Status
Jürgen Gmach Approve
Review via email: mp+414022@code.launchpad.net

Commit message

Remove remaining uses of six

To post a comment you must log in.
Revision history for this message
Jürgen Gmach (jugmac00) wrote :

It is a bit unfortunate that we do not run coverage for this project (and all projects).

Some occurrences of `six.ensure_str` were just removed, some were replaced by xxx.decode().

I cannot say whether this is correct or not.

I quickly tried to setup coverage for the review, the tests ran, but got a "no data collected" error :-/

```
[testenv]
deps =
    .[test,xml]
    zope.testrunner
    coverage
commands =
    coverage run -m zope.testrunner --test-path src --tests-pattern ^tests {posargs}
    coverage report -m
```

I have no clue what is going wrong here.

Revision history for this message
Colin Watson (cjwatson) wrote :

All but one of the `six.ensure_*` calls that I removed are themselves in test code, so it's fairly easy to see that they're covered. The one exception is in `lazr.restful.declarations._versioned_class_name`, which is called by `lazr.restful.declarations.generate_*`. For removing `six.ensure_str` to be a problem there, somebody would have to have explicitly included a bytes item in their `IWebServiceConfiguration.active_versions`, which is declared as a list of `TextLine`; so I don't think this can be a problem.

Coverage seems to work fine for me, but declaring `coverage:run` would help so that it doesn't try to consider coverage of all dependencies as well. I'll propose a separate branch to set up coverage.

Revision history for this message
Jürgen Gmach (jugmac00) wrote :

Would you please rebase this MP on current main so includes the coverage env?

Revision history for this message
Colin Watson (cjwatson) wrote :

Done.

Revision history for this message
Jürgen Gmach (jugmac00) :
review: Approve
Revision history for this message
Colin Watson (cjwatson) :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/setup.py b/setup.py
index 1017963..c21f37a 100755
--- a/setup.py
+++ b/setup.py
@@ -62,7 +62,6 @@ setup(
62 "pytz",62 "pytz",
63 "setuptools",63 "setuptools",
64 "simplejson>=2.1.0",64 "simplejson>=2.1.0",
65 "six>=1.13.0",
66 "testtools",65 "testtools",
67 "van.testing",66 "van.testing",
68 "zope.component [zcml]",67 "zope.component [zcml]",
diff --git a/src/lazr/restful/debug.py b/src/lazr/restful/debug.py
index ebcf526..3dfb865 100644
--- a/src/lazr/restful/debug.py
+++ b/src/lazr/restful/debug.py
@@ -4,10 +4,9 @@
44
5__all__ = ["debug_proxy", "typename"]5__all__ = ["debug_proxy", "typename"]
66
7from io import StringIO
78
8from six import StringIO
9import zope.proxy9import zope.proxy
10
11from zope.security.checker import getChecker, Checker, CheckerPublic, Proxy10from zope.security.checker import getChecker, Checker, CheckerPublic, Proxy
1211
1312
diff --git a/src/lazr/restful/declarations.py b/src/lazr/restful/declarations.py
index 0fca6c1..ecfcc00 100644
--- a/src/lazr/restful/declarations.py
+++ b/src/lazr/restful/declarations.py
@@ -44,7 +44,6 @@ import copy
44import itertools44import itertools
45import sys45import sys
4646
47import six
48from zope.component import getUtility, getGlobalSiteManager47from zope.component import getUtility, getGlobalSiteManager
49from zope.interface import classImplements48from zope.interface import classImplements
50from zope.interface.interface import fromFunction, InterfaceClass, TAGGED_DATA49from zope.interface.interface import fromFunction, InterfaceClass, TAGGED_DATA
@@ -1943,5 +1942,5 @@ def _versioned_class_name(base_name, version):
1943 # runtime. Use a generic string that won't conflict with a1942 # runtime. Use a generic string that won't conflict with a
1944 # real version string.1943 # real version string.
1945 version = "__Earliest"1944 version = "__Earliest"
1946 name = "%s_%s" % (base_name, six.ensure_str(version))1945 name = "%s_%s" % (base_name, version)
1947 return make_identifier_safe(name)1946 return make_identifier_safe(name)
diff --git a/src/lazr/restful/docs/webservice.rst b/src/lazr/restful/docs/webservice.rst
index 411d9e8..d10d4a3 100644
--- a/src/lazr/restful/docs/webservice.rst
+++ b/src/lazr/restful/docs/webservice.rst
@@ -1088,9 +1088,8 @@ top-level collections of authors, cookbooks, and dishes. It's the
1088'home page' for the web service.1088'home page' for the web service.
10891089
1090 >>> import simplejson1090 >>> import simplejson
1091 >>> import six
1092 >>> response = app(request)1091 >>> response = app(request)
1093 >>> representation = simplejson.loads(six.ensure_text(response))1092 >>> representation = simplejson.loads(response)
10941093
1095 >>> print(representation["authors_collection_link"])1094 >>> print(representation["authors_collection_link"])
1096 http://api.cookbooks.dev/beta/authors1095 http://api.cookbooks.dev/beta/authors
@@ -1165,7 +1164,7 @@ parsed with standard tools.
11651164
1166 >>> def load_json(s):1165 >>> def load_json(s):
1167 ... """Convert a JSON string to Unicode and then load it."""1166 ... """Convert a JSON string to Unicode and then load it."""
1168 ... return simplejson.loads(six.ensure_text(s))1167 ... return simplejson.loads(s)
11691168
1170 >>> representation = load_json(collection())1169 >>> representation = load_json(collection())
1171 >>> print(representation['resource_type_link'])1170 >>> print(representation['resource_type_link'])
@@ -1678,7 +1677,9 @@ easily accessible data structure.
1678 ... headers['HTTP_IF_NONE_MATCH'] = etag1677 ... headers['HTTP_IF_NONE_MATCH'] = etag
1679 ... get_request = create_web_service_request(1678 ... get_request = create_web_service_request(
1680 ... julia_url, environ=headers)1679 ... julia_url, environ=headers)
1681 ... entity_body = six.ensure_text(get_request.traverse(app)())1680 ... entity_body = get_request.traverse(app)()
1681 ... if isinstance(entity_body, bytes):
1682 ... entity_body = entity_body.decode()
1682 ... return dict(entity_body=entity_body,1683 ... return dict(entity_body=entity_body,
1683 ... response=get_request.response)1684 ... response=get_request.response)
16841685
@@ -1820,7 +1821,7 @@ set the field value to 'tag:launchpad.net:2008:redacted'.
1820 >>> body = simplejson.dumps(author).encode()1821 >>> body = simplejson.dumps(author).encode()
1821 >>> put_request = create_web_service_request(1822 >>> put_request = create_web_service_request(
1822 ... beard_url, body=body, environ=headers, method='PUT')1823 ... beard_url, body=body, environ=headers, method='PUT')
1823 >>> print(six.ensure_text(put_request.traverse(app)()))1824 >>> print(put_request.traverse(app)().decode())
1824 {...}1825 {...}
18251826
1826And since no special permission is necessary to _change_ a person's1827And since no special permission is necessary to _change_ a person's
@@ -1833,7 +1834,7 @@ PUT, even when its current value is redacted.
1833 >>> body = simplejson.dumps(author).encode()1834 >>> body = simplejson.dumps(author).encode()
1834 >>> put_request = create_web_service_request(1835 >>> put_request = create_web_service_request(
1835 ... beard_url, body=body, environ=headers, method='PUT')1836 ... beard_url, body=body, environ=headers, method='PUT')
1836 >>> print(six.ensure_text(put_request.traverse(app)()))1837 >>> print(put_request.traverse(app)().decode())
1837 {...}1838 {...}
18381839
1839After that PUT, James Beard's 'favorite_recipe' attribute is no longer1840After that PUT, James Beard's 'favorite_recipe' attribute is no longer
@@ -1897,7 +1898,7 @@ A cookbook can be given a cover with PUT.
1897 >>> file_resource = put_request.traverse(app)1898 >>> file_resource = put_request.traverse(app)
1898 >>> file_resource()1899 >>> file_resource()
18991900
1900 >>> print(six.ensure_str(C2.cover.representation))1901 >>> print(C2.cover.representation.decode())
1901 Pretend...1902 Pretend...
19021903
1903At this point it exists:1904At this point it exists:
@@ -1934,7 +1935,7 @@ An entry's primitive data fields are exposed as subordinate resources.
19341935
1935 >>> field_resource = create_web_service_request(1936 >>> field_resource = create_web_service_request(
1936 ... '/beta/cookbooks/The%20Joy%20of%20Cooking/name').traverse(app)1937 ... '/beta/cookbooks/The%20Joy%20of%20Cooking/name').traverse(app)
1937 >>> print(six.ensure_text(field_resource()))1938 >>> print(field_resource().decode())
1938 "The Joy of Cooking"1939 "The Joy of Cooking"
19391940
1940Requesting non available resources1941Requesting non available resources
@@ -2059,7 +2060,10 @@ their URLs, we make the change by modifying the cookbook's
2059 ... '/beta/cookbooks/The%20Joy%20of%20Cooking',2060 ... '/beta/cookbooks/The%20Joy%20of%20Cooking',
2060 ... body=simplejson.dumps(representation).encode(),2061 ... body=simplejson.dumps(representation).encode(),
2061 ... environ=headers, method='PATCH', hostname=host).traverse(app)2062 ... environ=headers, method='PATCH', hostname=host).traverse(app)
2062 ... return six.ensure_text(resource())2063 ... result = resource()
2064 ... if isinstance(result, bytes):
2065 ... result = result.decode()
2066 ... return result
2063 >>> path = '/beta/authors/Julia%20Child'2067 >>> path = '/beta/authors/Julia%20Child'
20642068
2065 >>> print(change_joy_author('http://api.cookbooks.dev' + path))2069 >>> print(change_joy_author('http://api.cookbooks.dev' + path))
@@ -2122,7 +2126,7 @@ Now you see it...
21222126
2123 >>> resource = create_web_service_request(2127 >>> resource = create_web_service_request(
2124 ... recipe_url, method='GET').traverse(app)2128 ... recipe_url, method='GET').traverse(app)
2125 >>> print(six.ensure_text(resource()))2129 >>> print(resource().decode())
2126 {...}2130 {...}
21272131
2128 >>> resource = create_web_service_request(2132 >>> resource = create_web_service_request(
diff --git a/src/lazr/restful/example/base/tests/collection.txt b/src/lazr/restful/example/base/tests/collection.txt
index e156a43..44065aa 100644
--- a/src/lazr/restful/example/base/tests/collection.txt
+++ b/src/lazr/restful/example/base/tests/collection.txt
@@ -325,8 +325,6 @@ POST operations may involve text fields. These are marshalled via a
325multipart/form-data request, which requires line breaks to be represented as325multipart/form-data request, which requires line breaks to be represented as
326CRLF. The server turns these into Unix-style LF.326CRLF. The server turns these into Unix-style LF.
327327
328 >>> import six
329
330 >>> def create_recipe(id, cookbook_link, dish_link, instructions,328 >>> def create_recipe(id, cookbook_link, dish_link, instructions,
331 ... private=False):329 ... private=False):
332 ... return webservice.named_post(330 ... return webservice.named_post(
@@ -344,6 +342,6 @@ CRLF. The server turns these into Unix-style LF.
344 >>> response.status342 >>> response.status
345 201343 201
346 >>> recipe = webservice.get(response.getHeader("Location")).jsonBody()344 >>> recipe = webservice.get(response.getHeader("Location")).jsonBody()
347 >>> six.ensure_str(recipe["instructions"])345 >>> recipe["instructions"]
348 'Recipe\ncontaining\nsome\nline\n\nbreaks'346 'Recipe\ncontaining\nsome\nline\n\nbreaks'
349 >>> _ = webservice.delete(recipe["self_link"])347 >>> _ = webservice.delete(recipe["self_link"])
diff --git a/src/lazr/restful/example/base/tests/entry.txt b/src/lazr/restful/example/base/tests/entry.txt
index f24c7a3..decab39 100644
--- a/src/lazr/restful/example/base/tests/entry.txt
+++ b/src/lazr/restful/example/base/tests/entry.txt
@@ -118,9 +118,7 @@ a simple definition list.
118Getting the XHTML representation works correctly even when some of the fields118Getting the XHTML representation works correctly even when some of the fields
119have non-ascii values.119have non-ascii values.
120120
121 >>> import six121 >>> print(str(webservice.get(construsions_url, 'application/xhtml+xml')))
122 >>> print(six.text_type(
123 ... webservice.get(construsions_url, 'application/xhtml+xml')))
124 HTTP/1.1 200 Ok122 HTTP/1.1 200 Ok
125 ...123 ...
126 <dl ...>124 <dl ...>
diff --git a/src/lazr/restful/testing/helpers.py b/src/lazr/restful/testing/helpers.py
index c0dd63c..bfd8685 100644
--- a/src/lazr/restful/testing/helpers.py
+++ b/src/lazr/restful/testing/helpers.py
@@ -1,7 +1,6 @@
1import sys1import sys
2from types import ModuleType2from types import ModuleType
33
4import six
5from zope.configuration import xmlconfig4from zope.configuration import xmlconfig
6from zope.interface import implementer5from zope.interface import implementer
76
@@ -63,7 +62,7 @@ def encode_unicode(unicode_string):
6362
64 :param unicode_string: A Unicode string.63 :param unicode_string: A Unicode string.
65 """64 """
66 return six.ensure_str(unicode_string.encode("ascii", "backslashreplace"))65 return unicode_string.encode("ascii", "backslashreplace").decode()
6766
6867
69@implementer(IWebServiceConfiguration)68@implementer(IWebServiceConfiguration)
diff --git a/src/lazr/restful/testing/webservice.py b/src/lazr/restful/testing/webservice.py
index 97bbc11..af7496b 100644
--- a/src/lazr/restful/testing/webservice.py
+++ b/src/lazr/restful/testing/webservice.py
@@ -34,7 +34,6 @@ from urllib.parse import (
3434
35import wsgi_intercept35import wsgi_intercept
3636
37import six
38from zope.component import adapter, getGlobalSiteManager, getUtility37from zope.component import adapter, getGlobalSiteManager, getUtility
39from zope.configuration import xmlconfig38from zope.configuration import xmlconfig
40from zope.interface import alsoProvides, implementer, Interface39from zope.interface import alsoProvides, implementer, Interface
@@ -316,8 +315,8 @@ class WebServiceCaller:
316 headers=None,315 headers=None,
317 api_version=None,316 api_version=None,
318 ):317 ):
319 if isinstance(path_or_url, (bytes, str)):318 if isinstance(path_or_url, bytes):
320 path_or_url = six.ensure_str(path_or_url)319 path_or_url = path_or_url.decode()
321 else:320 else:
322 path_or_url = str(path_or_url)321 path_or_url = str(path_or_url)
323 if path_or_url.startswith("/"):322 if path_or_url.startswith("/"):
@@ -459,9 +458,9 @@ class WebServiceCaller:
459 value = simplejson.dumps(value)458 value = simplejson.dumps(value)
460 lines = re.split(r"\r\n|\r|\n", value)459 lines = re.split(r"\r\n|\r|\n", value)
461 for line in lines[:-1]:460 for line in lines[:-1]:
462 buf.write(six.ensure_binary(line))461 buf.write(line.encode())
463 buf.write(b"\r\n")462 buf.write(b"\r\n")
464 buf.write(six.ensure_binary(lines[-1]))463 buf.write(lines[-1].encode())
465 encoded_parts.append(buf.getvalue())464 encoded_parts.append(buf.getvalue())
466465
467 # Create a suitable boundary.466 # Create a suitable boundary.
@@ -580,7 +579,9 @@ class WebServiceResponseWrapper(ProxyBase):
580579
581 def jsonBody(self):580 def jsonBody(self):
582 """Return the body of the web service request as a JSON document."""581 """Return the body of the web service request as a JSON document."""
583 body = six.ensure_text(self.body)582 body = self.body
583 if isinstance(body, bytes):
584 body = body.decode()
584 try:585 try:
585 return simplejson.loads(body, object_pairs_hook=OrderedDict)586 return simplejson.loads(body, object_pairs_hook=OrderedDict)
586 except ValueError:587 except ValueError:

Subscribers

People subscribed via source and target branches