# HG changeset patch # User Mads Kiilerich # Date 2019-12-28 13:38:22 # Node ID 58b6e4cd6fe965bbb07079667c05cd4497b7b383 # Parent 7e22c4b909b2477268243d2281845cb38780cac9 lib: clean up ext_json and how it is used - avoid monkey patching Note that py3 json.dumps will return ASCII (with all unicode escaped) encoded as str. But we generally want JSON as bytes (which json.loads also can read), so also wrap the result with ascii_bytes in many places. diff --git a/kallithea/bin/base.py b/kallithea/bin/base.py --- a/kallithea/bin/base.py +++ b/kallithea/bin/base.py @@ -31,7 +31,8 @@ import random import sys import urllib2 -from kallithea.lib.compat import json +from kallithea.lib import ext_json +from kallithea.lib.utils2 import ascii_bytes CONFIG_NAME = '.config/kallithea' @@ -68,11 +69,11 @@ def api_call(apikey, apihost, method=Non apihost = apihost.rstrip('/') id_ = random.randrange(1, 9999) req = urllib2.Request('%s/_admin/api' % apihost, - data=json.dumps(_build_data(id_)), + data=ascii_bytes(ext_json.dumps(_build_data(id_))), headers={'content-type': 'text/plain'}) ret = urllib2.urlopen(req) raw_json = ret.read() - json_data = json.loads(raw_json) + json_data = ext_json.loads(raw_json) id_ret = json_data['id'] if id_ret == id_: return json_data @@ -128,7 +129,7 @@ class RcConf(object): if os.path.exists(self._conf_name): update = True with open(self._conf_name, 'wb') as f: - json.dump(config, f, indent=4) + ext_json.dump(config, f, indent=4) f.write('\n') if update: @@ -146,7 +147,7 @@ class RcConf(object): config = {} try: with open(self._conf_name, 'rb') as conf: - config = json.load(conf) + config = ext_json.load(conf) except IOError as e: sys.stderr.write(str(e) + '\n') @@ -159,7 +160,7 @@ class RcConf(object): """ try: with open(self._conf_name, 'rb') as conf: - return json.load(conf) + return ext_json.load(conf) except IOError as e: #sys.stderr.write(str(e) + '\n') pass diff --git a/kallithea/bin/kallithea_api.py b/kallithea/bin/kallithea_api.py --- a/kallithea/bin/kallithea_api.py +++ b/kallithea/bin/kallithea_api.py @@ -28,9 +28,10 @@ Original author and date, and relevant c from __future__ import print_function import argparse +import json import sys -from kallithea.bin.base import FORMAT_JSON, FORMAT_PRETTY, RcConf, api_call, json +from kallithea.bin.base import FORMAT_JSON, FORMAT_PRETTY, RcConf, api_call def argparser(argv): diff --git a/kallithea/bin/kallithea_gist.py b/kallithea/bin/kallithea_gist.py --- a/kallithea/bin/kallithea_gist.py +++ b/kallithea/bin/kallithea_gist.py @@ -29,11 +29,12 @@ from __future__ import print_function import argparse import fileinput +import json import os import stat import sys -from kallithea.bin.base import FORMAT_JSON, FORMAT_PRETTY, RcConf, api_call, json +from kallithea.bin.base import FORMAT_JSON, FORMAT_PRETTY, RcConf, api_call def argparser(argv): diff --git a/kallithea/bin/ldap_sync.py b/kallithea/bin/ldap_sync.py --- a/kallithea/bin/ldap_sync.py +++ b/kallithea/bin/ldap_sync.py @@ -33,7 +33,8 @@ from ConfigParser import ConfigParser import ldap -from kallithea.lib.compat import json +from kallithea.lib import ext_json +from kallithea.lib.utils2 import ascii_bytes config = ConfigParser() @@ -80,12 +81,12 @@ class API(object): uid = str(uuid.uuid1()) data = self.get_api_data(uid, method, args) - data = json.dumps(data) + data = ascii_bytes(ext_json.dumps(data)) headers = {'content-type': 'text/plain'} req = urllib2.Request(self.url, data, headers) response = urllib2.urlopen(req) - response = json.load(response) + response = ext_json.load(response) if uid != response["id"]: raise InvalidResponseIDError("UUID does not match.") diff --git a/kallithea/controllers/api/__init__.py b/kallithea/controllers/api/__init__.py --- a/kallithea/controllers/api/__init__.py +++ b/kallithea/controllers/api/__init__.py @@ -35,11 +35,11 @@ import types from tg import Response, TGController, request, response from webob.exc import HTTPError, HTTPException +from kallithea.lib import ext_json from kallithea.lib.auth import AuthUser from kallithea.lib.base import _get_ip_addr as _get_ip from kallithea.lib.base import get_path_info -from kallithea.lib.compat import json -from kallithea.lib.utils2 import safe_str +from kallithea.lib.utils2 import ascii_bytes, safe_str from kallithea.model.db import User @@ -121,7 +121,7 @@ class JSONRPCController(TGController): raw_body = environ['wsgi.input'].read(length) try: - json_body = json.loads(raw_body) + json_body = ext_json.loads(raw_body) except ValueError as e: # catch JSON errors Here raise JSONRPCErrorResponse(retid=self._req_id, @@ -238,16 +238,16 @@ class JSONRPCController(TGController): response = dict(id=self._req_id, result=raw_response, error=self._error) try: - return json.dumps(response) + return ascii_bytes(ext_json.dumps(response)) except TypeError as e: log.error('API FAILED. Error encoding response for %s %s: %s\n%s', action, rpc_args, e, traceback.format_exc()) - return json.dumps( + return ascii_bytes(ext_json.dumps( dict( id=self._req_id, result=None, - error="Error encoding response" + error="Error encoding response", ) - ) + )) def _find_method(self): """ diff --git a/kallithea/controllers/summary.py b/kallithea/controllers/summary.py --- a/kallithea/controllers/summary.py +++ b/kallithea/controllers/summary.py @@ -40,10 +40,10 @@ from webob.exc import HTTPBadRequest import kallithea.lib.helpers as h from kallithea.config.conf import ALL_EXTS, ALL_READMES, LANGUAGES_EXTENSIONS_MAP +from kallithea.lib import ext_json from kallithea.lib.auth import HasRepoPermissionLevelDecorator, LoginRequired from kallithea.lib.base import BaseRepoController, jsonify, render from kallithea.lib.celerylib.tasks import get_commits_stats -from kallithea.lib.compat import json from kallithea.lib.markup_renderer import MarkupRenderer from kallithea.lib.page import Page from kallithea.lib.utils2 import safe_int, safe_unicode @@ -139,7 +139,7 @@ class SummaryController(BaseRepoControll if stats and stats.languages: c.no_data = False is c.db_repo.enable_statistics - lang_stats_d = json.loads(stats.languages) + lang_stats_d = ext_json.loads(stats.languages) lang_stats = [(x, {"count": y, "desc": LANGUAGES_EXTENSIONS_MAP.get(x, '?')}) @@ -191,9 +191,9 @@ class SummaryController(BaseRepoControll c.stats_percentage = 0 if stats and stats.languages: c.no_data = False is c.db_repo.enable_statistics - lang_stats_d = json.loads(stats.languages) - c.commit_data = json.loads(stats.commit_activity) - c.overview_data = json.loads(stats.commit_activity_combined) + lang_stats_d = ext_json.loads(stats.languages) + c.commit_data = ext_json.loads(stats.commit_activity) + c.overview_data = ext_json.loads(stats.commit_activity_combined) lang_stats = ((x, {"count": y, "desc": LANGUAGES_EXTENSIONS_MAP.get(x)}) diff --git a/kallithea/lib/auth_modules/auth_crowd.py b/kallithea/lib/auth_modules/auth_crowd.py --- a/kallithea/lib/auth_modules/auth_crowd.py +++ b/kallithea/lib/auth_modules/auth_crowd.py @@ -30,8 +30,9 @@ import base64 import logging import urllib2 -from kallithea.lib import auth_modules -from kallithea.lib.compat import formatted_json, hybrid_property, json +from kallithea.lib import auth_modules, ext_json +from kallithea.lib.compat import formatted_json, hybrid_property +from kallithea.lib.utils2 import ascii_bytes log = logging.getLogger(__name__) @@ -103,7 +104,7 @@ class CrowdServer(object): rval["status"] = True rval["error"] = "Response body was empty" elif not noformat: - rval = json.loads(msg) + rval = ext_json.loads(msg) rval["status"] = True else: rval = "".join(rdoc.readlines()) @@ -121,7 +122,7 @@ class CrowdServer(object): the user.""" url = ("%s/rest/usermanagement/%s/authentication?username=%s" % (self._uri, self._version, urllib2.quote(username))) - body = json.dumps({"value": password}) + body = ascii_bytes(ext_json.dumps({"value": password})) return self._request(url, body) def user_groups(self, username): diff --git a/kallithea/lib/base.py b/kallithea/lib/base.py --- a/kallithea/lib/base.py +++ b/kallithea/lib/base.py @@ -45,12 +45,11 @@ from tg.i18n import ugettext as _ from kallithea import BACKENDS, __version__ from kallithea.config.routing import url -from kallithea.lib import auth_modules +from kallithea.lib import auth_modules, ext_json from kallithea.lib.auth import AuthUser, HasPermissionAnyMiddleware -from kallithea.lib.compat import json from kallithea.lib.exceptions import UserCreationError from kallithea.lib.utils import get_repo_slug, is_valid_repo -from kallithea.lib.utils2 import AttributeDict, safe_int, safe_str, safe_unicode, set_hook_environment, str2bool +from kallithea.lib.utils2 import AttributeDict, ascii_bytes, safe_int, safe_str, safe_unicode, set_hook_environment, str2bool from kallithea.lib.vcs.exceptions import ChangesetDoesNotExistError, EmptyRepositoryError, RepositoryError from kallithea.model import meta from kallithea.model.db import PullRequest, Repository, Setting, User @@ -630,7 +629,7 @@ def jsonify(func, *args, **kwargs): warnings.warn(msg, Warning, 2) log.warning(msg) log.debug("Returning JSON wrapped action output") - return json.dumps(data) + return ascii_bytes(ext_json.dumps(data)) @decorator.decorator def IfSshEnabled(func, *args, **kwargs): diff --git a/kallithea/lib/celerylib/tasks.py b/kallithea/lib/celerylib/tasks.py --- a/kallithea/lib/celerylib/tasks.py +++ b/kallithea/lib/celerylib/tasks.py @@ -37,13 +37,12 @@ from time import mktime from tg import config from kallithea import CELERY_ON -from kallithea.lib import celerylib -from kallithea.lib.compat import json +from kallithea.lib import celerylib, ext_json from kallithea.lib.helpers import person from kallithea.lib.hooks import log_create_repository from kallithea.lib.rcmail.smtp_mailer import SmtpMailer from kallithea.lib.utils import action_logger -from kallithea.lib.utils2 import str2bool +from kallithea.lib.utils2 import ascii_bytes, str2bool from kallithea.lib.vcs.utils import author_email from kallithea.model.db import RepoGroup, Repository, Statistics, User @@ -118,9 +117,9 @@ def get_commits_stats(repo_name, ts_min_ return True if cur_stats: - commits_by_day_aggregate = OrderedDict(json.loads( + commits_by_day_aggregate = OrderedDict(ext_json.loads( cur_stats.commit_activity_combined)) - co_day_auth_aggr = json.loads(cur_stats.commit_activity) + co_day_auth_aggr = ext_json.loads(cur_stats.commit_activity) log.debug('starting parsing %s', parse_limit) @@ -193,8 +192,8 @@ def get_commits_stats(repo_name, ts_min_ } stats = cur_stats if cur_stats else Statistics() - stats.commit_activity = json.dumps(co_day_auth_aggr) - stats.commit_activity_combined = json.dumps(overview_data) + stats.commit_activity = ascii_bytes(ext_json.dumps(co_day_auth_aggr)) + stats.commit_activity_combined = ascii_bytes(ext_json.dumps(overview_data)) log.debug('last revision %s', last_rev) leftovers = len(repo.revisions[last_rev:]) @@ -202,7 +201,7 @@ def get_commits_stats(repo_name, ts_min_ if last_rev == 0 or leftovers < parse_limit: log.debug('getting code trending stats') - stats.languages = json.dumps(__get_codes_stats(repo_name)) + stats.languages = ascii_bytes(ext_json.dumps(__get_codes_stats(repo_name))) try: stats.repository = dbrepo diff --git a/kallithea/lib/compat.py b/kallithea/lib/compat.py --- a/kallithea/lib/compat.py +++ b/kallithea/lib/compat.py @@ -42,15 +42,10 @@ from sqlalchemy.util import OrderedSet #============================================================================== # json #============================================================================== -from kallithea.lib.ext_json import json +from kallithea.lib import ext_json -# alias for formatted json -formatted_json = functools.partial(json.dumps, indent=4, sort_keys=True) - - - - +formatted_json = functools.partial(ext_json.dumps, indent=4, sort_keys=True) #============================================================================== diff --git a/kallithea/lib/ext_json.py b/kallithea/lib/ext_json.py --- a/kallithea/lib/ext_json.py +++ b/kallithea/lib/ext_json.py @@ -1,16 +1,16 @@ """ -Extended JSON encoder for json +Extended JSON encoder with support for more data types -json.org does not specify how date time can be represented - monkeypatch it to do something. +json.org does not specify how date time can be represented - just encode it somehow and ignore decoding ... """ import datetime import decimal import functools -import json # is re-exported after monkey patching +import json -__all__ = ['json'] +__all__ = ['dumps', 'dump', 'load', 'loads'] def _is_tz_aware(value): @@ -70,10 +70,12 @@ class ExtendedEncoder(json.JSONEncoder): try: return _obj_dump(obj) except NotImplementedError: - pass + pass # quiet skipping of unsupported types! raise TypeError("%r is not JSON serializable" % (obj,)) -# monkey-patch and export JSON encoder to use custom encoding method -json.dumps = functools.partial(json.dumps, cls=ExtendedEncoder) -json.dump = functools.partial(json.dump, cls=ExtendedEncoder) +dumps = functools.partial(json.dumps, cls=ExtendedEncoder) +dump = functools.partial(json.dump, cls=ExtendedEncoder) +# No special support for loading these types back!!! +load = json.load +loads = json.loads diff --git a/kallithea/lib/utils2.py b/kallithea/lib/utils2.py --- a/kallithea/lib/utils2.py +++ b/kallithea/lib/utils2.py @@ -31,6 +31,7 @@ from __future__ import print_function import binascii import datetime +import json import os import pwd import re @@ -42,7 +43,6 @@ from tg.i18n import ugettext as _ from tg.i18n import ungettext from webhelpers2.text import collapse, remove_formatting, strip_tags -from kallithea.lib.compat import json from kallithea.lib.vcs.utils import ascii_bytes, ascii_str, safe_bytes, safe_str, safe_unicode # re-export from kallithea.lib.vcs.utils.lazy import LazyProperty diff --git a/kallithea/model/db.py b/kallithea/model/db.py --- a/kallithea/model/db.py +++ b/kallithea/model/db.py @@ -45,11 +45,11 @@ from tg.i18n import lazy_ugettext as _ from webob.exc import HTTPNotFound import kallithea +from kallithea.lib import ext_json from kallithea.lib.caching_query import FromCache -from kallithea.lib.compat import json from kallithea.lib.exceptions import DefaultUserException from kallithea.lib.utils2 import ( - Optional, aslist, get_changeset_safe, get_clone_url, remove_prefix, safe_bytes, safe_int, safe_str, safe_unicode, str2bool, urlreadable) + Optional, ascii_bytes, aslist, get_changeset_safe, get_clone_url, remove_prefix, safe_bytes, safe_int, safe_str, safe_unicode, str2bool, urlreadable) from kallithea.lib.vcs import get_backend from kallithea.lib.vcs.backends.base import EmptyChangeset from kallithea.lib.vcs.utils.helpers import get_scm @@ -521,14 +521,14 @@ class User(Base, BaseDbModel): return {} try: - return json.loads(self._user_data) + return ext_json.loads(self._user_data) except TypeError: return {} @user_data.setter def user_data(self, val): try: - self._user_data = json.dumps(val) + self._user_data = ascii_bytes(ext_json.dumps(val)) except Exception: log.error(traceback.format_exc()) @@ -833,14 +833,14 @@ class UserGroup(Base, BaseDbModel): return {} try: - return json.loads(self._group_data) + return ext_json.loads(self._group_data) except TypeError: return {} @group_data.setter def group_data(self, val): try: - self._group_data = json.dumps(val) + self._group_data = ascii_bytes(ext_json.dumps(val)) except Exception: log.error(traceback.format_exc()) @@ -1032,7 +1032,7 @@ class Repository(Base, BaseDbModel): @hybrid_property def changeset_cache(self): try: - cs_cache = json.loads(self._changeset_cache) # might raise on bad data + cs_cache = ext_json.loads(self._changeset_cache) # might raise on bad data cs_cache['raw_id'] # verify data, raise exception on error return cs_cache except (TypeError, KeyError, ValueError): @@ -1041,7 +1041,7 @@ class Repository(Base, BaseDbModel): @changeset_cache.setter def changeset_cache(self, val): try: - self._changeset_cache = json.dumps(val) + self._changeset_cache = ascii_bytes(ext_json.dumps(val)) except Exception: log.error(traceback.format_exc()) diff --git a/kallithea/model/gist.py b/kallithea/model/gist.py --- a/kallithea/model/gist.py +++ b/kallithea/model/gist.py @@ -32,8 +32,8 @@ import shutil import time import traceback -from kallithea.lib.compat import json -from kallithea.lib.utils2 import AttributeDict, safe_int, safe_unicode, time_to_datetime +from kallithea.lib import ext_json +from kallithea.lib.utils2 import AttributeDict, ascii_bytes, safe_int, safe_unicode, time_to_datetime from kallithea.model.db import Gist, Session, User from kallithea.model.repo import RepoModel from kallithea.model.scm import ScmModel @@ -82,7 +82,7 @@ class GistModel(object): 'gist_updated': time.time(), } with open(os.path.join(repo.path, '.hg', GIST_METADATA_FILE), 'wb') as f: - f.write(json.dumps(metadata)) + f.write(ascii_bytes(ext_json.dumps(metadata))) def get_gist(self, gist): return Gist.guess_instance(gist) diff --git a/kallithea/tests/api/api_base.py b/kallithea/tests/api/api_base.py --- a/kallithea/tests/api/api_base.py +++ b/kallithea/tests/api/api_base.py @@ -23,8 +23,9 @@ import re import mock import pytest +from kallithea.lib import ext_json from kallithea.lib.auth import AuthUser -from kallithea.lib.compat import json +from kallithea.lib.utils2 import ascii_bytes from kallithea.model.changeset_status import ChangesetStatusModel from kallithea.model.db import ChangesetStatus, PullRequest, RepoGroup, Repository, Setting, Ui, User from kallithea.model.gist import GistModel @@ -48,11 +49,10 @@ fixture = Fixture() def _build_data(apikey, method, **kw): """ Builds API data with given random ID - - :param random_id: + For convenience, the json is returned as str """ random_id = random.randrange(1, 9999) - return random_id, json.dumps({ + return random_id, ext_json.dumps({ "id": random_id, "api_key": apikey, "method": method, @@ -60,7 +60,7 @@ def _build_data(apikey, method, **kw): }) -jsonify = lambda obj: json.loads(json.dumps(obj)) +jsonify = lambda obj: ext_json.loads(ext_json.dumps(obj)) def crash(*args, **kwargs): @@ -127,7 +127,7 @@ class _BaseTestApi(object): 'error': None, 'result': expected }) - given = json.loads(given) + given = ext_json.loads(given) assert expected == given, (expected, given) def _compare_error(self, id_, expected, given): @@ -136,7 +136,7 @@ class _BaseTestApi(object): 'error': expected, 'result': None }) - given = json.loads(given) + given = ext_json.loads(given) assert expected == given, (expected, given) def test_Optional_object(self): @@ -2322,16 +2322,15 @@ class _BaseTestApi(object): gist_type='public', files={'foobar': {'content': 'foo'}}) response = api_call(self, params) - response_json = response.json expected = { 'gist': { - 'access_id': response_json['result']['gist']['access_id'], - 'created_on': response_json['result']['gist']['created_on'], + 'access_id': response.json['result']['gist']['access_id'], + 'created_on': response.json['result']['gist']['created_on'], 'description': 'foobar-gist', - 'expires': response_json['result']['gist']['expires'], - 'gist_id': response_json['result']['gist']['gist_id'], + 'expires': response.json['result']['gist']['expires'], + 'gist_id': response.json['result']['gist']['gist_id'], 'type': 'public', - 'url': response_json['result']['gist']['url'] + 'url': response.json['result']['gist']['url'] }, 'msg': 'created new gist' } @@ -2397,7 +2396,7 @@ class _BaseTestApi(object): id_, params = _build_data(self.apikey, 'get_changesets', repoid=self.REPO, start=0, end=2) response = api_call(self, params) - result = json.loads(response.body)["result"] + result = ext_json.loads(response.body)["result"] assert len(result) == 3 assert 'message' in result[0] assert 'added' not in result[0] @@ -2406,7 +2405,7 @@ class _BaseTestApi(object): id_, params = _build_data(self.apikey, 'get_changesets', repoid=self.REPO, start_date="2011-02-24T00:00:00", max_revisions=10) response = api_call(self, params) - result = json.loads(response.body)["result"] + result = ext_json.loads(response.body)["result"] assert len(result) == 10 assert 'message' in result[0] assert 'added' not in result[0] @@ -2419,7 +2418,7 @@ class _BaseTestApi(object): id_, params = _build_data(self.apikey, 'get_changesets', repoid=self.REPO, branch_name=branch, start_date="2011-02-24T00:00:00") response = api_call(self, params) - result = json.loads(response.body)["result"] + result = ext_json.loads(response.body)["result"] assert len(result) == 5 assert 'message' in result[0] assert 'added' not in result[0] @@ -2428,7 +2427,7 @@ class _BaseTestApi(object): id_, params = _build_data(self.apikey, 'get_changesets', repoid=self.REPO, start_date="2010-04-07T23:30:30", end_date="2010-04-08T00:31:14", with_file_list=True) response = api_call(self, params) - result = json.loads(response.body)["result"] + result = ext_json.loads(response.body)["result"] assert len(result) == 3 assert 'message' in result[0] assert 'added' in result[0] @@ -2438,7 +2437,7 @@ class _BaseTestApi(object): id_, params = _build_data(self.apikey, 'get_changeset', repoid=self.REPO, raw_id=self.TEST_REVISION) response = api_call(self, params) - result = json.loads(response.body)["result"] + result = ext_json.loads(response.body)["result"] assert result["raw_id"] == self.TEST_REVISION assert "reviews" not in result @@ -2448,7 +2447,7 @@ class _BaseTestApi(object): repoid=self.REPO, raw_id=self.TEST_REVISION, with_reviews=True) response = api_call(self, params) - result = json.loads(response.body)["result"] + result = ext_json.loads(response.body)["result"] assert result["raw_id"] == self.TEST_REVISION assert "reviews" in result assert len(result["reviews"]) == 1 @@ -2484,12 +2483,12 @@ class _BaseTestApi(object): def test_api_get_pullrequest(self): pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, u'get test') random_id = random.randrange(1, 9999) - params = json.dumps({ + params = ascii_bytes(ext_json.dumps({ "id": random_id, "api_key": self.apikey, "method": 'get_pullrequest', "args": {"pullrequest_id": pull_request_id}, - }) + })) response = api_call(self, params) pullrequest = PullRequest().get(pull_request_id) expected = { @@ -2515,12 +2514,12 @@ class _BaseTestApi(object): def test_api_close_pullrequest(self): pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, u'close test') random_id = random.randrange(1, 9999) - params = json.dumps({ + params = ascii_bytes(ext_json.dumps({ "id": random_id, "api_key": self.apikey, "method": "comment_pullrequest", "args": {"pull_request_id": pull_request_id, "close_pr": True}, - }) + })) response = api_call(self, params) self._compare_ok(random_id, True, given=response.body) pullrequest = PullRequest().get(pull_request_id) @@ -2532,22 +2531,22 @@ class _BaseTestApi(object): pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, u"status test") random_id = random.randrange(1, 9999) - params = json.dumps({ + params = ascii_bytes(ext_json.dumps({ "id": random_id, "api_key": User.get_by_username(base.TEST_USER_REGULAR2_LOGIN).api_key, "method": "comment_pullrequest", "args": {"pull_request_id": pull_request_id, "status": ChangesetStatus.STATUS_APPROVED}, - }) + })) response = api_call(self, params) pullrequest = PullRequest().get(pull_request_id) self._compare_error(random_id, "No permission to change pull request status. User needs to be admin, owner or reviewer.", given=response.body) assert ChangesetStatus.STATUS_UNDER_REVIEW == ChangesetStatusModel().calculate_pull_request_result(pullrequest)[2] - params = json.dumps({ + params = ascii_bytes(ext_json.dumps({ "id": random_id, "api_key": User.get_by_username(base.TEST_USER_REGULAR_LOGIN).api_key, "method": "comment_pullrequest", "args": {"pull_request_id": pull_request_id, "status": ChangesetStatus.STATUS_APPROVED}, - }) + })) response = api_call(self, params) self._compare_ok(random_id, True, given=response.body) pullrequest = PullRequest().get(pull_request_id) @@ -2556,12 +2555,12 @@ class _BaseTestApi(object): def test_api_comment_pullrequest(self): pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, u"comment test") random_id = random.randrange(1, 9999) - params = json.dumps({ + params = ascii_bytes(ext_json.dumps({ "id": random_id, "api_key": self.apikey, "method": "comment_pullrequest", "args": {"pull_request_id": pull_request_id, "comment_msg": "Looks good to me"}, - }) + })) response = api_call(self, params) self._compare_ok(random_id, True, given=response.body) pullrequest = PullRequest().get(pull_request_id)