Remove simplejson support

This was allegedly included back when simplejson was more performant
that the 'json' library in Python's library. It's additional complexity
that we simple don't need. Remove it. This also allows us to clean up
the tox file significantly.

Note that we must also rename the 'json' module to 'json_utils', as this
was shadowing a built-in library. This is a latent issue that was
highlighted by removing of 'simplejson' imports.

Change-Id: Id9faa9859993e598e2fd08133de576b740790bf3
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
Stephen Finucane 2019-04-30 17:36:40 -06:00
parent 128f591b7e
commit 6f6dbfadef
12 changed files with 50 additions and 108 deletions

View File

@ -60,8 +60,7 @@ Main features
- Framework independence : adapters are provided to easily integrate
your API in any web framework, for example a wsgi container,
Pecan_, Flask_, ...
- Very few runtime dependencies: webob, simplegeneric. Optionally
simplejson if you need better performances.
- Very few runtime dependencies: webob, simplegeneric.
- Integration in `Sphinx`_ for making clean documentation with
``wsmeext.sphinxext``.

39
tox.ini
View File

@ -87,16 +87,6 @@ deps =
{[common]basedeps}
basepython = python2.7
[testenv:py27-simplejson]
commands =
{envbindir}/coverage run {envbindir}/nosetests --nologcapture --with-xunit --xunit-file nosetests-{envname}.xml wsme/tests tests/pecantest tests/test_sphinxext.py tests/test_flask.py --verbose {posargs}
{envbindir}/coverage report --show-missing wsme/*.py wsme/rest/*.py wsmeext/*.py
deps =
{[common]testtools}
{[common]basedeps}
simplejson
basepython = python2.7
[testenv:py35]
commands =
{envbindir}/coverage run {envbindir}/nosetests --nologcapture --with-xunit --xunit-file nosetests-{envname}.xml wsme/tests tests/pecantest tests/test_sphinxext.py tests/test_flask.py --verbose {posargs}
@ -106,16 +96,6 @@ deps =
{[common]basedeps}
basepython = python3.5
[testenv:py35-simplejson]
commands =
{envbindir}/coverage run {envbindir}/nosetests --nologcapture --with-xunit --xunit-file nosetests-{envname}.xml wsme/tests tests/pecantest tests/test_sphinxext.py tests/test_flask.py --verbose {posargs}
{envbindir}/coverage report --show-missing wsme/*.py wsme/rest/*.py wsmeext/*.py
deps =
{[common]testtools}
{[common]basedeps}
simplejson
basepython = python3.5
[testenv:py36]
commands =
{envbindir}/coverage run {envbindir}/nosetests --nologcapture --with-xunit --xunit-file nosetests-{envname}.xml wsme/tests tests/pecantest tests/test_sphinxext.py tests/test_flask.py --verbose {posargs}
@ -125,16 +105,6 @@ deps =
{[common]basedeps}
basepython = python3.6
[testenv:py36-simplejson]
commands =
{envbindir}/coverage run {envbindir}/nosetests --nologcapture --with-xunit --xunit-file nosetests-{envname}.xml wsme/tests tests/pecantest tests/test_sphinxext.py tests/test_flask.py --verbose {posargs}
{envbindir}/coverage report --show-missing wsme/*.py wsme/rest/*.py wsmeext/*.py
deps =
{[common]testtools}
{[common]basedeps}
simplejson
basepython = python3.6
[testenv:pypy]
commands =
{envbindir}/coverage run {envbindir}/nosetests --nologcapture --with-xunit --xunit-file nosetests-{envname}.xml wsme/tests tests/pecantest tests/test_sphinxext.py tests/test_flask.py --verbose {posargs}
@ -142,12 +112,3 @@ commands =
deps =
{[common]testtools}
{[common]basedeps}
[testenv:pypy-simplejson]
commands =
{envbindir}/coverage run {envbindir}/nosetests --nologcapture --with-xunit --xunit-file nosetests-{envname}.xml wsme/tests tests/pecantest tests/test_sphinxext.py tests/test_flask.py --verbose {posargs}
{envbindir}/coverage report --show-missing wsme/*.py wsme/rest/*.py wsmeext/*.py
deps =
{[common]testtools}
{[common]basedeps}
simplejson

View File

@ -216,8 +216,8 @@ def args_from_params(funcdef, params):
def args_from_body(funcdef, body, mimetype):
from wsme.rest import json as restjson
from wsme.rest import xml as restxml
from wsme.rest import json_utils as restjson
from wsme.rest import xml_utils as restxml
if funcdef.body_type is not None:
datatypes = {funcdef.arguments[-1].name: funcdef.body_type}

View File

@ -1,11 +1,10 @@
"""REST+Json protocol implementation."""
from __future__ import absolute_import
import datetime
import decimal
import six
import json
from simplegeneric import generic
import six
import wsme.exc
import wsme.types
@ -13,12 +12,6 @@ from wsme.types import Unset
import wsme.utils
try:
import simplejson as json
except ImportError:
import json # noqa
content_type = 'application/json'
accept_content_types = [
content_type,

View File

@ -25,8 +25,8 @@ class RestProtocol(Protocol):
self.content_types = []
for dataformat in dataformats:
__import__('wsme.rest.' + dataformat)
dfmod = getattr(wsme.rest, dataformat)
__import__('wsme.rest.' + dataformat + '_utils')
dfmod = getattr(wsme.rest, dataformat + '_utils')
self.dataformats[dataformat] = dfmod
self.content_types.extend(dfmod.accept_content_types)

View File

@ -80,8 +80,8 @@ class TestController(unittest.TestCase):
headers={'Accept': 'application/json'})
self.assertTrue(
res.json_body['faultstring'].startswith(
"Invalid input for field/attribute number. Value: 'arf'. \
Value should be one of:"))
"Invalid input for field/attribute number. Value: 'arf'. "
"Value should be one of:"))
self.assertIn('v1', res.json_body['faultstring'])
self.assertIn('v2', res.json_body['faultstring'])
self.assertIn('None', res.json_body['faultstring'])
@ -104,8 +104,8 @@ Value should be one of:"))
headers={'Accept': 'application/json'})
self.assertTrue(
res.json_body['faultstring'].startswith(
"Invalid input for field/attribute number. Value: '1'. \
Value should be one of:"))
"Invalid input for field/attribute number. Value: '1'. "
"Value should be one of:"))
self.assertIn('v1', res.json_body['faultstring'])
self.assertIn('v2', res.json_body['faultstring'])
self.assertIn('None', res.json_body['faultstring'])

View File

@ -1,21 +1,15 @@
import base64
import datetime
import decimal
import json
import wsme.tests.protocol
try:
import simplejson as json
except ImportError:
import json # noqa
from wsme.rest.json import fromjson, tojson, parse
from wsme.utils import parse_isodatetime, parse_isotime, parse_isodate
from wsme.exc import ClientSideError, InvalidInput
from wsme.types import isarray, isdict, isusertype, register_type
from wsme.types import UserType, ArrayType, DictType
from wsme.rest import expose, validate
from wsme.exc import ClientSideError, InvalidInput
from wsme.rest.json_utils import fromjson, tojson, parse
import wsme.tests.protocol
from wsme.utils import parse_isodatetime, parse_isotime, parse_isodate
import six
from six import b, u
@ -569,7 +563,7 @@ class TestRestJson(wsme.tests.protocol.RestOnlyProtocolTestCase):
v.aint = 4
v.astr = 's'
r = wsme.rest.json.encode_sample_value(MyType, v, True)
r = wsme.rest.json_utils.encode_sample_value(MyType, v, True)
print(r)
assert r[0] == ('javascript')
assert r[1] == json.dumps({'aint': 4, 'astr': 's'}, ensure_ascii=False,
@ -580,7 +574,7 @@ class TestRestJson(wsme.tests.protocol.RestOnlyProtocolTestCase):
assert tojson(wsme.types.bytes, b('ascii')) == u('ascii')
def test_encode_sample_params(self):
r = wsme.rest.json.encode_sample_params(
r = wsme.rest.json_utils.encode_sample_params(
[('a', int, 2)], True
)
assert r[0] == 'javascript', r[0]
@ -589,7 +583,7 @@ class TestRestJson(wsme.tests.protocol.RestOnlyProtocolTestCase):
}''', r[1]
def test_encode_sample_result(self):
r = wsme.rest.json.encode_sample_result(
r = wsme.rest.json_utils.encode_sample_result(
int, 2, True
)
assert r[0] == 'javascript', r[0]

View File

@ -5,11 +5,10 @@ import base64
from six import u, b
import six
from wsme.rest.xml_utils import fromxml, toxml
import wsme.tests.protocol
from wsme.utils import parse_isodatetime, parse_isodate, parse_isotime
from wsme.types import isarray, isdict, isusertype, register_type
from wsme.rest.xml import fromxml, toxml
from wsme.utils import parse_isodatetime, parse_isodate, parse_isotime
try:
import xml.etree.ElementTree as et
@ -165,7 +164,7 @@ class TestRestXML(wsme.tests.protocol.RestOnlyProtocolTestCase):
value.aint = 5
value.atext = u('test')
language, sample = wsme.rest.xml.encode_sample_value(
language, sample = wsme.rest.xml_utils.encode_sample_value(
MyType, value, True)
print(language, sample)
@ -176,13 +175,13 @@ class TestRestXML(wsme.tests.protocol.RestOnlyProtocolTestCase):
</value>""")
def test_encode_sample_params(self):
lang, content = wsme.rest.xml.encode_sample_params(
lang, content = wsme.rest.xml_utils.encode_sample_params(
[('a', int, 2)], True)
assert lang == 'xml', lang
assert content == b('<parameters>\n <a>2</a>\n</parameters>'), content
def test_encode_sample_result(self):
lang, content = wsme.rest.xml.encode_sample_result(int, 2, True)
lang, content = wsme.rest.xml_utils.encode_sample_result(int, 2, True)
assert lang == 'xml', lang
assert content == b('<result>2</result>'), content

View File

@ -5,22 +5,22 @@ import logging
import sys
import inspect
import flask
import wsme
import wsme.api
import wsme.rest.json
import wsme.rest.xml
import wsme.rest.args
import wsme.rest.json_utils
import wsme.rest.xml_utils
from wsme.utils import is_valid_code
import flask
log = logging.getLogger(__name__)
TYPES = {
'application/json': wsme.rest.json,
'application/xml': wsme.rest.xml,
'text/xml': wsme.rest.xml
'application/json': wsme.rest.json_utils,
'application/xml': wsme.rest.xml_utils,
'text/xml': wsme.rest.xml_utils,
}
@ -35,9 +35,9 @@ def get_dataformat():
if req_dataformat in TYPES:
return TYPES[req_dataformat]
log.info('''Could not determine what format is wanted by the
caller, falling back to json''')
return wsme.rest.json
log.info('Could not determine what format is wanted by the caller, '
'falling back to JSON')
return wsme.rest.json_utils
def signature(*args, **kw):

View File

@ -4,13 +4,12 @@ import functools
import inspect
import sys
import wsme
import wsme.rest.args
import wsme.rest.json
import wsme.rest.xml
import pecan
import wsme
import wsme.rest.args
import wsme.rest.json_utils
import wsme.rest.xml_utils
from wsme.utils import is_valid_code
@ -22,8 +21,8 @@ class JSonRenderer(object):
@staticmethod
def render(template_path, namespace):
if 'faultcode' in namespace:
return wsme.rest.json.encode_error(None, namespace)
return wsme.rest.json.encode_result(
return wsme.rest.json_utils.encode_error(None, namespace)
return wsme.rest.json_utils.encode_result(
namespace['result'],
namespace['datatype']
)
@ -37,8 +36,8 @@ class XMLRenderer(object):
@staticmethod
def render(template_path, namespace):
if 'faultcode' in namespace:
return wsme.rest.xml.encode_error(None, namespace)
return wsme.rest.xml.encode_result(
return wsme.rest.xml_utils.encode_error(None, namespace)
return wsme.rest.xml_utils.encode_result(
namespace['result'],
namespace['datatype']
)

View File

@ -2,26 +2,23 @@ import inspect
import re
import sys
from docutils.parsers.rst import Directive
from docutils.parsers.rst import directives
import six
from sphinx import addnodes
from sphinx.ext import autodoc
from sphinx.domains.python import PyClasslike, PyClassmember
from sphinx.domains import Domain, ObjType
from sphinx.directives import ObjectDescription
from sphinx.locale import l_, _
from sphinx.roles import XRefRole
from sphinx.util.docfields import Field
from sphinx.util.nodes import make_refnode
from sphinx.roles import XRefRole
from sphinx.locale import l_, _
from docutils.parsers.rst import Directive
from docutils.parsers.rst import directives
import wsme
import wsme.rest.json_utils
import wsme.rest.xml_utils
import wsme.types
import wsme.rest.json
import wsme.rest.xml
field_re = re.compile(r':(?P<field>\w+)(\s+(?P<name>\w+))?:')
@ -56,10 +53,10 @@ def get_protocols(names):
protocols.extend('restjson', 'restxml')
if 'restjson' in names:
names.remove('restjson')
protocols.append(('Json', wsme.rest.json))
protocols.append(('Json', wsme.rest.json_utils))
if 'restxml' in names:
names.remove('restxml')
protocols.append(('XML', wsme.rest.xml))
protocols.append(('XML', wsme.rest.xml_utils))
for name in names:
p = wsme.protocol.getprotocol(name)
protocols.append((p.displayname or p.name, p))