PYTHON-1213 - Make decimal128 work with cdecimal
This commit is contained in:
parent
a426aef599
commit
02e606608e
@ -345,6 +345,15 @@ functions:
|
||||
${PREPARE_SHELL}
|
||||
PYTHON_BINARY=${PYTHON_BINARY} PROJECT_DIRECTORY=${PROJECT_DIRECTORY} sh ${PROJECT_DIRECTORY}/.evergreen/run-mockupdb-tests.sh
|
||||
|
||||
"run cdecimal tests":
|
||||
- command: shell.exec
|
||||
type: test
|
||||
params:
|
||||
working_dir: "src"
|
||||
script: |
|
||||
${PREPARE_SHELL}
|
||||
PYTHON_BINARY=${PYTHON_BINARY} sh ${PROJECT_DIRECTORY}/.evergreen/run-cdecimal-tests.sh
|
||||
|
||||
"run doctests":
|
||||
- command: shell.exec
|
||||
type: test
|
||||
@ -681,6 +690,15 @@ tasks:
|
||||
TOPOLOGY: "replica_set"
|
||||
- func: "run mod_wsgi tests"
|
||||
|
||||
- name: "cdecimal"
|
||||
tags: ["cdecimal"]
|
||||
commands:
|
||||
- func: "bootstrap mongo-orchestration"
|
||||
vars:
|
||||
VERSION: "latest"
|
||||
TOPOLOGY: "server"
|
||||
- func: "run cdecimal tests"
|
||||
|
||||
# }}}
|
||||
|
||||
|
||||
@ -1316,6 +1334,15 @@ buildvariants:
|
||||
tasks:
|
||||
- name: "doctests"
|
||||
|
||||
- matrix_name: "cdecimal"
|
||||
matrix_spec: {python-version: ["2.6", "2.7"]}
|
||||
display_name: "cdecimal ${python-version}"
|
||||
batchtime: 10080 # 7 days
|
||||
run_on:
|
||||
- ubuntu1604-test
|
||||
tasks:
|
||||
- name: "cdecimal"
|
||||
|
||||
# Platform notes
|
||||
# i386 builds of OpenSSL or Cyrus SASL are not available
|
||||
# Ubuntu14.04 only supports 2.6+ with SSL
|
||||
|
||||
12
.evergreen/run-cdecimal-tests.sh
Normal file
12
.evergreen/run-cdecimal-tests.sh
Normal file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -o xtrace
|
||||
set -o errexit
|
||||
|
||||
virtualenv -p ${PYTHON_BINARY} cdecimaltest
|
||||
trap "deactivate; rm -rf cdecimaltest" EXIT HUP
|
||||
. cdecimaltest/bin/activate
|
||||
# No cdecimal tarballs on pypi.
|
||||
pip install http://www.bytereef.org/software/mpdecimal/releases/cdecimal-2.3.tar.gz
|
||||
python -c 'import sys; print(sys.version)'
|
||||
python cdecimal_test.py
|
||||
@ -84,9 +84,12 @@ _CTX_OPTIONS = {
|
||||
decimal.Inexact]
|
||||
}
|
||||
|
||||
if _PY3:
|
||||
try:
|
||||
# Python >= 3.3, cdecimal
|
||||
decimal.Context(clamp=1) # pylint: disable=unexpected-keyword-arg
|
||||
_CTX_OPTIONS['clamp'] = 1
|
||||
else:
|
||||
except TypeError:
|
||||
# Python < 3.3
|
||||
_CTX_OPTIONS['_clamp'] = 1
|
||||
|
||||
_DEC128_CTX = decimal.Context(**_CTX_OPTIONS.copy())
|
||||
@ -273,7 +276,7 @@ class Decimal128(object):
|
||||
elif (high & _NAN) == _NAN:
|
||||
return decimal.Decimal((sign, (), 'n'))
|
||||
elif (high & _INF) == _INF:
|
||||
return decimal.Decimal((sign, (0,), 'F'))
|
||||
return decimal.Decimal((sign, (), 'F'))
|
||||
|
||||
if (high & _EXPONENT_MASK) == _EXPONENT_MASK:
|
||||
exponent = ((high & 0x1fffe00000000000) >> 47) - _EXPONENT_BIAS
|
||||
@ -296,7 +299,9 @@ class Decimal128(object):
|
||||
arr[0] = (high & mask) >> 48
|
||||
|
||||
# Have to convert bytearray to bytes for python 2.6.
|
||||
digits = [int(digit) for digit in str(_from_bytes(bytes(arr), 'big'))]
|
||||
# cdecimal only accepts a tuple for digits.
|
||||
digits = tuple(
|
||||
int(digit) for digit in str(_from_bytes(bytes(arr), 'big')))
|
||||
|
||||
with decimal.localcontext(_DEC128_CTX) as ctx:
|
||||
return ctx.create_decimal((sign, digits, exponent))
|
||||
|
||||
66
cdecimal_test.py
Normal file
66
cdecimal_test.py
Normal file
@ -0,0 +1,66 @@
|
||||
# Copyright 2017 MongoDB, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Test PyMongo with cdecimal monkey-patched over stdlib decimal."""
|
||||
|
||||
import getopt
|
||||
import sys
|
||||
|
||||
try:
|
||||
import cdecimal
|
||||
_HAVE_CDECIMAL = True
|
||||
except ImportError:
|
||||
_HAVE_CDECIMAL = False
|
||||
|
||||
|
||||
def run(args):
|
||||
"""Run tests with cdecimal monkey-patched over stdlib decimal."""
|
||||
# Monkey-patch.
|
||||
sys.modules['decimal'] = cdecimal
|
||||
|
||||
# Run the tests.
|
||||
sys.argv[:] = ['setup.py', 'test'] + list(args)
|
||||
import setup
|
||||
|
||||
|
||||
def main():
|
||||
"""Parse options and run tests."""
|
||||
usage = """python %s
|
||||
|
||||
Test PyMongo with cdecimal monkey-patched over decimal.""" % (sys.argv[0],)
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(
|
||||
sys.argv[1:], "h", ["help"])
|
||||
except getopt.GetoptError as err:
|
||||
print(str(err))
|
||||
print(usage)
|
||||
sys.exit(2)
|
||||
|
||||
for option_name, _ in opts:
|
||||
if option_name in ("-h", "--help"):
|
||||
print(usage)
|
||||
sys.exit()
|
||||
else:
|
||||
assert False, "unhandled option"
|
||||
|
||||
if not _HAVE_CDECIMAL:
|
||||
print("The cdecimal package is not installed.")
|
||||
sys.exit(1)
|
||||
|
||||
run(args) # Command line args to setup.py, like what test to run.
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Loading…
Reference in New Issue
Block a user