mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-16 21:57:22 -04:00
support scale argument for the C implementation of the decimal processor
This commit is contained in:
@@ -143,6 +143,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *type;
|
||||
PyObject *format;
|
||||
} DecimalResultProcessor;
|
||||
|
||||
|
||||
@@ -158,7 +159,7 @@ UnicodeResultProcessor_init(UnicodeResultProcessor *self, PyObject *args,
|
||||
PyObject *encoding, *errors = NULL;
|
||||
static char *kwlist[] = {"encoding", "errors", NULL};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "S|S:init", kwlist,
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "S|S:__init__", kwlist,
|
||||
&encoding, &errors))
|
||||
return -1;
|
||||
|
||||
@@ -252,30 +253,38 @@ static int
|
||||
DecimalResultProcessor_init(DecimalResultProcessor *self, PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
PyObject *type;
|
||||
PyObject *type, *format;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O", &type))
|
||||
if (!PyArg_ParseTuple(args, "OS", &type, &format))
|
||||
return -1;
|
||||
|
||||
Py_INCREF(type);
|
||||
self->type = type;
|
||||
|
||||
Py_INCREF(format);
|
||||
self->format = format;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
DecimalResultProcessor_process(DecimalResultProcessor *self, PyObject *value)
|
||||
{
|
||||
PyObject *str, *result;
|
||||
PyObject *str, *result, *args;
|
||||
|
||||
if (value == Py_None)
|
||||
Py_RETURN_NONE;
|
||||
|
||||
if (PyFloat_CheckExact(value)) {
|
||||
/* Decimal does not accept float values directly */
|
||||
str = PyObject_Str(value);
|
||||
args = PyTuple_Pack(1, value);
|
||||
if (args == NULL)
|
||||
return NULL;
|
||||
|
||||
str = PyString_Format(self->format, args);
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
|
||||
result = PyObject_CallFunctionObjArgs(self->type, str, NULL);
|
||||
Py_DECREF(str);
|
||||
return result;
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
# This module is part of SQLAlchemy and is released under
|
||||
# the MIT License: http://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
"""defines generic type conversion functions, as used in result processors.
|
||||
"""defines generic type conversion functions, as used in bind and result
|
||||
processors.
|
||||
|
||||
They all share one common characteristic: None is passed through unchanged.
|
||||
|
||||
@@ -39,9 +40,13 @@ try:
|
||||
else:
|
||||
return UnicodeResultProcessor(encoding).process
|
||||
|
||||
# TODO: add scale argument
|
||||
#def to_decimal_processor_factory(target_class):
|
||||
# return DecimalResultProcessor(target_class).process
|
||||
def to_decimal_processor_factory(target_class, scale=10):
|
||||
# Note that the scale argument is not taken into account for integer
|
||||
# values in the C implementation while it is in the Python one.
|
||||
# For example, the Python implementation might return
|
||||
# Decimal('5.00000') whereas the C implementation will
|
||||
# return Decimal('5'). These are equivalent of course.
|
||||
return DecimalResultProcessor(target_class, "%%.%df" % scale).process
|
||||
|
||||
except ImportError:
|
||||
def to_unicode_processor_factory(encoding, errors=None):
|
||||
@@ -54,18 +59,18 @@ except ImportError:
|
||||
# decoder returns a tuple: (value, len). Simply dropping the
|
||||
# len part is safe: it is done that way in the normal
|
||||
# 'xx'.decode(encoding) code path.
|
||||
# cfr python-source/Python/codecs.c:PyCodec_Decode
|
||||
return decoder(value, errors)[0]
|
||||
return process
|
||||
|
||||
# TODO: add scale argument
|
||||
#def to_decimal_processor_factory(target_class):
|
||||
# def process(value):
|
||||
# if value is None:
|
||||
# return None
|
||||
# else:
|
||||
# return target_class(str(value))
|
||||
# return process
|
||||
def to_decimal_processor_factory(target_class, scale=10):
|
||||
fstring = "%%.%df" % scale
|
||||
|
||||
def process(value):
|
||||
if value is None:
|
||||
return None
|
||||
else:
|
||||
return target_class(fstring % value)
|
||||
return process
|
||||
|
||||
def to_float(value):
|
||||
if value is None:
|
||||
@@ -94,13 +99,3 @@ except ImportError:
|
||||
str_to_time = str_to_datetime_processor_factory(TIME_RE, datetime.time)
|
||||
str_to_date = str_to_datetime_processor_factory(DATE_RE, datetime.date)
|
||||
|
||||
|
||||
def to_decimal_processor_factory(target_class, scale=10):
|
||||
fstring = "%%.%df" % scale
|
||||
|
||||
def process(value):
|
||||
if value is None:
|
||||
return None
|
||||
else:
|
||||
return target_class(fstring % value)
|
||||
return process
|
||||
|
||||
Reference in New Issue
Block a user