Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use ujson if its available #78

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions pynamodb/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@
PynamoDB attributes
"""
import six
import json
from base64 import b64encode, b64decode
from delorean import Delorean, parse
from pynamodb.constants import (
STRING, NUMBER, BINARY, UTC, DATETIME_FORMAT, BINARY_SET, STRING_SET, NUMBER_SET,
DEFAULT_ENCODING
)

try:
import ujson as json
import json as python_json
HAS_UJSON = True
except ImportError:
import json
HAS_UJSON = False


class Attribute(object):
"""
Expand Down Expand Up @@ -183,7 +190,13 @@ def deserialize(self, value):
"""
Deserializes JSON
"""
return json.loads(value, strict=False)
if HAS_UJSON:
try:
return json.loads(value)
except ValueError:
return python_json.loads(value, strict=False)
else:
return json.loads(value, strict=False)


class BooleanAttribute(Attribute):
Expand Down Expand Up @@ -230,13 +243,26 @@ def serialize(self, value):
"""
Encode numbers as JSON
"""
return json.dumps(value)
if HAS_UJSON and isinstance(value, float):
from decimal import Decimal
value = Decimal(value)
try:
return json.dumps(value)
except OverflowError:
if HAS_UJSON:
return python_json.dumps(value)
raise

def deserialize(self, value):
"""
Decode numbers from JSON
"""
return json.loads(value)
try:
return json.loads(value)
except ValueError:
if HAS_UJSON:
return python_json.loads(value)
raise


class UTCDateTimeAttribute(Attribute):
Expand Down
8 changes: 7 additions & 1 deletion pynamodb/connection/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@
ITEMS, DEFAULT_ENCODING, BINARY_SHORT, BINARY_SET_SHORT, LAST_EVALUATED_KEY, RESPONSES, UNPROCESSED_KEYS,
UNPROCESSED_ITEMS, STREAM_SPECIFICATION, STREAM_VIEW_TYPE, STREAM_ENABLED)

try:
import ujson as json
except ImportError:
import json


BOTOCORE_EXCEPTIONS = (BotoCoreError, ClientError)


Expand Down Expand Up @@ -241,8 +247,8 @@ def _make_api_call(self, operation_name, operation_kwargs):
)
prepared_request = self.client._endpoint.create_request(request_dict, operation_model)
response = self.requests_session.send(prepared_request)
data = json.loads(response.text)
if response.status_code >= 300:
data = response.json()
botocore_expected_format = {"Error": {"Message": data.get("message", ""), "Code": data.get("__type", "")}}
raise ClientError(botocore_expected_format, operation_name)
data = response.json()
Expand Down
6 changes: 5 additions & 1 deletion pynamodb/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""
DynamoDB Models for PynamoDB
"""
import json
import time
import six
import copy
Expand Down Expand Up @@ -32,6 +31,11 @@
COUNT, ITEM_COUNT, KEY, UNPROCESSED_ITEMS, STREAM_VIEW_TYPE, STREAM_SPECIFICATION,
STREAM_ENABLED)

try:
import ujson as json
except ImportError:
import json


log = logging.getLogger(__name__)
log.addHandler(NullHandler())
Expand Down
6 changes: 5 additions & 1 deletion pynamodb/tests/test_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
pynamodb attributes tests
"""
import six
import json
from base64 import b64encode
from datetime import datetime
from delorean import Delorean
Expand All @@ -15,6 +14,11 @@
JSONAttribute, DEFAULT_ENCODING, NUMBER, STRING, STRING_SET, NUMBER_SET, BINARY_SET,
BINARY)

try:
import ujson as json
except ImportError:
import json


class AttributeTestModel(Model):

Expand Down