@@ -2857,6 +2857,51 @@ dec_from_float(PyObject *type, PyObject *pyfloat)
2857
2857
return result ;
2858
2858
}
2859
2859
2860
+ /* 'v' can have any numeric type accepted by the Decimal constructor. Attempt
2861
+ an exact conversion. If the result does not meet the restrictions
2862
+ for an mpd_t, fail with InvalidOperation. */
2863
+ static PyObject *
2864
+ PyDecType_FromNumberExact (PyTypeObject * type , PyObject * v , PyObject * context )
2865
+ {
2866
+ decimal_state * state = get_module_state_by_def (type );
2867
+ assert (v != NULL );
2868
+ if (PyDec_Check (state , v )) {
2869
+ return PyDecType_FromDecimalExact (type , v , context );
2870
+ }
2871
+ else if (PyLong_Check (v )) {
2872
+ return PyDecType_FromLongExact (type , v , context );
2873
+ }
2874
+ else if (PyFloat_Check (v )) {
2875
+ if (dec_addstatus (context , MPD_Float_operation )) {
2876
+ return NULL ;
2877
+ }
2878
+ return PyDecType_FromFloatExact (type , v , context );
2879
+ }
2880
+ else {
2881
+ PyErr_Format (PyExc_TypeError ,
2882
+ "conversion from %s to Decimal is not supported" ,
2883
+ Py_TYPE (v )-> tp_name );
2884
+ return NULL ;
2885
+ }
2886
+ }
2887
+
2888
+ /* class method */
2889
+ static PyObject *
2890
+ dec_from_number (PyObject * type , PyObject * number )
2891
+ {
2892
+ PyObject * context ;
2893
+ PyObject * result ;
2894
+
2895
+ decimal_state * state = get_module_state_by_def ((PyTypeObject * )type );
2896
+ CURRENT_CONTEXT (state , context );
2897
+ result = PyDecType_FromNumberExact (state -> PyDec_Type , number , context );
2898
+ if (type != (PyObject * )state -> PyDec_Type && result != NULL ) {
2899
+ Py_SETREF (result , PyObject_CallFunctionObjArgs (type , result , NULL ));
2900
+ }
2901
+
2902
+ return result ;
2903
+ }
2904
+
2860
2905
/* create_decimal_from_float */
2861
2906
static PyObject *
2862
2907
ctx_from_float (PyObject * context , PyObject * v )
@@ -5052,6 +5097,7 @@ static PyMethodDef dec_methods [] =
5052
5097
5053
5098
/* Miscellaneous */
5054
5099
{ "from_float" , dec_from_float , METH_O |METH_CLASS , doc_from_float },
5100
+ { "from_number" , dec_from_number , METH_O |METH_CLASS , doc_from_number },
5055
5101
{ "as_tuple" , PyDec_AsTuple , METH_NOARGS , doc_as_tuple },
5056
5102
{ "as_integer_ratio" , dec_as_integer_ratio , METH_NOARGS , doc_as_integer_ratio },
5057
5103
0 commit comments