diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index 0421b355056419..ea75c8b2b98924 100644 --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -57,6 +57,16 @@ this module for those platforms. Previously, it could be negative, such as -1 or -3. +.. data:: RLIM_SAVED_CUR +.. data:: RLIM_SAVED_MAX + + Constants used to represent the soft and hard limit values if they + cannot be represented in the ``rlim_t`` value in C. + Can be equal to :data:`RLIM_INFINITY`. + + .. versionadded:: next + + .. function:: getrlimit(resource) Returns a tuple ``(soft, hard)`` with the current soft and hard limits of @@ -181,8 +191,9 @@ platform. .. data:: RLIMIT_VMEM The largest area of mapped memory which the process may occupy. + Usually an alias of :const:`RLIMIT_AS`. - .. availability:: FreeBSD >= 11. + .. availability:: Solaris, FreeBSD, NetBSD. .. data:: RLIMIT_AS @@ -235,16 +246,18 @@ platform. .. versionadded:: 3.4 + .. data:: RLIMIT_SBSIZE The maximum size (in bytes) of socket buffer usage for this user. This limits the amount of network memory, and hence the amount of mbufs, that this user may hold at any time. - .. availability:: FreeBSD. + .. availability:: FreeBSD, NetBSD. .. versionadded:: 3.4 + .. data:: RLIMIT_SWAP The maximum size (in bytes) of the swap space that may be reserved or @@ -254,18 +267,20 @@ platform. `tuning(7) `__ for a complete description of this sysctl. - .. availability:: FreeBSD. + .. availability:: FreeBSD >= 8. .. versionadded:: 3.4 + .. data:: RLIMIT_NPTS The maximum number of pseudo-terminals created by this user id. - .. availability:: FreeBSD. + .. availability:: FreeBSD >= 8. .. versionadded:: 3.4 + .. data:: RLIMIT_KQUEUES The maximum number of kqueues this user id is allowed to create. @@ -274,6 +289,46 @@ platform. .. versionadded:: 3.10 + +.. data:: RLIMIT_NTHR + + The maximum number of threads for this user id, not counting the main + and kernel threads. + + .. availability:: NetBSD >= 7.0. + + .. versionadded:: next + + +.. data:: RLIMIT_PIPEBUF + + The maximum total size of in-kernel buffers for bi-directional pipes/fifos + that this user id is allowed to consume. + + .. availability:: FreeBSD >= 14.2. + + .. versionadded:: next + + +.. data:: RLIMIT_THREADS + + The maximum number of threads each process can create. + + .. availability:: AIX. + + .. versionadded:: next + + +.. data:: RLIMIT_UMTXP + + The limit of the number of process-shared Posix thread library objects + allocated by user id. + + .. availability:: FreeBSD >= 11. + + .. versionadded:: next + + Resource Usage -------------- diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index eb073cae9be491..43c40e4d0f3154 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -312,6 +312,15 @@ os.path the resulting path can be missing but it will be free of symlinks. (Contributed by Petr Viktorin for :cve:`2025-4517`.) +resource +-------- + +* Add new constants: :data:`~resource.RLIMIT_NTHR`, + :data:`~resource.RLIMIT_UMTXP`, :data:`~resource.RLIMIT_THREADS`, + :data:`~resource.RLIM_SAVED_CUR`, and :data:`~resource.RLIM_SAVED_MAX`. + (Contributed by Serhiy Storchaka in :gh:`137512`.) + + shelve ------ diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h index c5a08e05e70287..2078c201b4558d 100644 --- a/Include/internal/pycore_global_objects_fini_generated.h +++ b/Include/internal/pycore_global_objects_fini_generated.h @@ -1296,6 +1296,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(template)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(term)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(text)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(third)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(threading)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(throw)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(time)); diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index 9e49e4497750a0..a7ebaf76c908c8 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -787,6 +787,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(template) STRUCT_FOR_ID(term) STRUCT_FOR_ID(text) + STRUCT_FOR_ID(third) STRUCT_FOR_ID(threading) STRUCT_FOR_ID(throw) STRUCT_FOR_ID(time) diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 7f468bbb932184..bd6b84ec7fd908 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1354,7 +1354,7 @@ _PyOpcode_macro_expansion[256] = { [CALL_ISINSTANCE] = { .nuops = 3, .uops = { { _GUARD_THIRD_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_ISINSTANCE, OPARG_SIMPLE, 3 }, { _CALL_ISINSTANCE, OPARG_SIMPLE, 3 } } }, [CALL_KW_BOUND_METHOD] = { .nuops = 6, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_METHOD_VERSION_KW, 2, 1 }, { _EXPAND_METHOD_KW, OPARG_SIMPLE, 3 }, { _PY_FRAME_KW, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } }, [CALL_KW_NON_PY] = { .nuops = 3, .uops = { { _CHECK_IS_NOT_PY_CALLABLE_KW, OPARG_SIMPLE, 3 }, { _CALL_KW_NON_PY, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, - [CALL_KW_PY] = { .nuops = 5, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION_KW, 2, 1 }, { _PY_FRAME_KW, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } }, + [CALL_KW_PY] = { .nuops = 6, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION_KW, 2, 1 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _PY_FRAME_KW, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } }, [CALL_LEN] = { .nuops = 3, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_LEN, OPARG_SIMPLE, 3 }, { _CALL_LEN, OPARG_SIMPLE, 3 } } }, [CALL_LIST_APPEND] = { .nuops = 4, .uops = { { _GUARD_CALLABLE_LIST_APPEND, OPARG_SIMPLE, 3 }, { _GUARD_NOS_NOT_NULL, OPARG_SIMPLE, 3 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 3 }, { _CALL_LIST_APPEND, OPARG_SIMPLE, 3 } } }, [CALL_METHOD_DESCRIPTOR_FAST] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_FAST, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h index 5c65cb218dedbb..27669c50cd6101 100644 --- a/Include/internal/pycore_runtime_init_generated.h +++ b/Include/internal/pycore_runtime_init_generated.h @@ -1294,6 +1294,7 @@ extern "C" { INIT_ID(template), \ INIT_ID(term), \ INIT_ID(text), \ + INIT_ID(third), \ INIT_ID(threading), \ INIT_ID(throw), \ INIT_ID(time), \ diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h index 4905007b95f8fa..c9b8a8b50510a2 100644 --- a/Include/internal/pycore_unicodeobject_generated.h +++ b/Include/internal/pycore_unicodeobject_generated.h @@ -2936,6 +2936,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(third); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(threading); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index 1c73aaafb71fd5..2c28f106ec7cb6 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -1074,6 +1074,14 @@ def c_py_recurse(m): with self.assertRaises(RecursionError): c_py_recurse(100_000) + def test_recursion_with_kwargs(self): + # GH-137883: The interpreter forgot to check the recursion limit when + # calling with keywords. + def recurse_kw(a=0): + recurse_kw(a=0) + with self.assertRaises(RecursionError): + recurse_kw() + class TestFunctionWithManyArgs(unittest.TestCase): def test_function_with_many_args(self): diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index fb47345857f1f8..3e7477487200d0 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -830,7 +830,7 @@ def foo(x): %4d LOAD_GLOBAL 1 (list + NULL) LOAD_FAST_BORROW 0 (x) BUILD_TUPLE 1 - LOAD_CONST 1 ( at 0x..., file "%s", line %d>) + LOAD_CONST %d ( at 0x..., file "%s", line %d>) MAKE_FUNCTION SET_FUNCTION_ATTRIBUTE 8 (closure) LOAD_DEREF 1 (y) @@ -842,6 +842,7 @@ def foo(x): _h.__code__.co_firstlineno + 1, _h.__code__.co_firstlineno + 1, _h.__code__.co_firstlineno + 3, + 1 if __debug__ else 0, __file__, _h.__code__.co_firstlineno + 3, ) @@ -1468,7 +1469,7 @@ def get_disassembly(self, func, lasti=-1, wrapper=True, **kwargs): Kw-only arguments: 0 Number of locals: 1 Stack size: \\d+ -Flags: OPTIMIZED, NEWLOCALS, HAS_DOCSTRING +Flags: OPTIMIZED, NEWLOCALS(, HAS_DOCSTRING)? Constants: {code_info_consts} Names: diff --git a/Lib/test/test_resource.py b/Lib/test/test_resource.py index 7391ce59da0ec4..f73914b9b92c83 100644 --- a/Lib/test/test_resource.py +++ b/Lib/test/test_resource.py @@ -200,6 +200,15 @@ def test_pagesize(self): self.assertIsInstance(pagesize, int) self.assertGreaterEqual(pagesize, 0) + def test_contants(self): + self.assertIsInstance(resource.RLIM_INFINITY, int) + if sys.platform.startswith(('freebsd', 'solaris', 'sunos', 'aix')): + self.assertHasAttr(resource, 'RLIM_SAVED_CUR') + self.assertHasAttr(resource, 'RLIM_SAVED_MAX') + if hasattr(resource, 'RLIM_SAVED_CUR'): + self.assertIsInstance(resource.RLIM_SAVED_CUR, int) + self.assertIsInstance(resource.RLIM_SAVED_MAX, int) + @unittest.skipUnless(sys.platform in ('linux', 'android'), 'Linux only') def test_linux_constants(self): for attr in ['MSGQUEUE', 'NICE', 'RTPRIO', 'RTTIME', 'SIGPENDING']: @@ -207,7 +216,7 @@ def test_linux_constants(self): self.assertIsInstance(getattr(resource, 'RLIMIT_' + attr), int) def test_freebsd_contants(self): - for attr in ['SWAP', 'SBSIZE', 'NPTS']: + for attr in ['SWAP', 'SBSIZE', 'NPTS', 'UMTXP', 'VMEM', 'PIPEBUF']: with contextlib.suppress(AttributeError): self.assertIsInstance(getattr(resource, 'RLIMIT_' + attr), int) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-08-17-13-36-53.gh-issue-137883.55VDCN.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-08-17-13-36-53.gh-issue-137883.55VDCN.rst new file mode 100644 index 00000000000000..0bdb2638c86884 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-08-17-13-36-53.gh-issue-137883.55VDCN.rst @@ -0,0 +1 @@ +Fix runaway recursion when calling a function with keyword arguments. diff --git a/Misc/NEWS.d/next/Library/2025-08-07-15-07-44.gh-issue-137512.j2or5h.rst b/Misc/NEWS.d/next/Library/2025-08-07-15-07-44.gh-issue-137512.j2or5h.rst new file mode 100644 index 00000000000000..fc67913b7e9055 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-08-07-15-07-44.gh-issue-137512.j2or5h.rst @@ -0,0 +1,4 @@ +Add new constants in the :mod:`resource` module: +:data:`~resource.RLIMIT_NTHR`, :data:`~resource.RLIMIT_UMTXP`, +:data:`~resource.RLIMIT_PIPEBUF`, :data:`~resource.RLIMIT_THREADS`, +:data:`~resource.RLIM_SAVED_CUR`, and :data:`~resource.RLIM_SAVED_MAX`. diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 52ed5a532efd27..f10ddef6c8c04b 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -63,9 +63,9 @@ /*[clinic input] module _decimal class _decimal.Decimal "PyObject *" "&dec_spec" -class _decimal.Context "PyObject *" "&ctx_spec" +class _decimal.Context "PyObject *" "&context_spec" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8c3aa7cfde934d7b]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a6a6c0bdf4e576ef]*/ struct PyDecContextObject; struct DecCondMap; @@ -4009,10 +4009,7 @@ _decimal_Decimal_to_integral_value_impl(PyObject *self, PyObject *rounding, } /*[clinic input] -_decimal.Decimal.to_integral - - rounding: object = None - context: object = None +_decimal.Decimal.to_integral = _decimal.Decimal.to_integral_value Identical to the to_integral_value() method. @@ -4023,16 +4020,13 @@ versions. static PyObject * _decimal_Decimal_to_integral_impl(PyObject *self, PyObject *rounding, PyObject *context) -/*[clinic end generated code: output=a0c7188686ee7f5c input=8eac6def038d13b9]*/ +/*[clinic end generated code: output=a0c7188686ee7f5c input=709b54618ecd0d8b]*/ { return _decimal_Decimal_to_integral_value_impl(self, rounding, context); } /*[clinic input] -_decimal.Decimal.to_integral_exact - - rounding: object = None - context: object = None +_decimal.Decimal.to_integral_exact = _decimal.Decimal.to_integral_value Round to the nearest integer. @@ -4045,7 +4039,7 @@ given, then the rounding mode of the current default context is used. static PyObject * _decimal_Decimal_to_integral_exact_impl(PyObject *self, PyObject *rounding, PyObject *context) -/*[clinic end generated code: output=8b004f9b45ac7746 input=c290166f59c1d6ab]*/ +/*[clinic end generated code: output=8b004f9b45ac7746 input=fabce7a744b8087c]*/ { PyObject *result; uint32_t status = 0; @@ -4328,38 +4322,24 @@ dec_##MPDFUNC(PyObject *self, PyObject *Py_UNUSED(dummy)) \ return MPDFUNC(MPD(self)) ? incr_true() : incr_false(); \ } -/* Boolean function with an optional context arg. */ +/* Boolean function with an optional context arg. + Argument Clinic provides PyObject *self, PyObject *context +*/ #define Dec_BoolFuncVA(MPDFUNC) \ -static PyObject * \ -dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ { \ - static char *kwlist[] = {"context", NULL}; \ - PyObject *context = Py_None; \ - \ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \ - &context)) { \ - return NULL; \ - } \ decimal_state *state = get_module_state_by_def(Py_TYPE(self)); \ CONTEXT_CHECK_VA(state, context); \ \ return MPDFUNC(MPD(self), CTX(context)) ? incr_true() : incr_false(); \ } -/* Unary function with an optional context arg. */ +/* Unary function with an optional context arg. + Argument Clinic provides PyObject *self, PyObject *context +*/ #define Dec_UnaryFuncVA(MPDFUNC) \ -static PyObject * \ -dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ { \ - static char *kwlist[] = {"context", NULL}; \ PyObject *result; \ - PyObject *context = Py_None; \ uint32_t status = 0; \ - \ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \ - &context)) { \ - return NULL; \ - } \ decimal_state *state = \ get_module_state_by_def(Py_TYPE(self)); \ CONTEXT_CHECK_VA(state, context); \ @@ -4377,22 +4357,14 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ return result; \ } -/* Binary function with an optional context arg. */ +/* Binary function with an optional context arg. + Argument Clinic provides PyObject *self, PyObject *other, PyObject *context +*/ #define Dec_BinaryFuncVA(MPDFUNC) \ -static PyObject * \ -dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ { \ - static char *kwlist[] = {"other", "context", NULL}; \ - PyObject *other; \ PyObject *a, *b; \ PyObject *result; \ - PyObject *context = Py_None; \ uint32_t status = 0; \ - \ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, \ - &other, &context)) { \ - return NULL; \ - } \ decimal_state *state = \ get_module_state_by_def(Py_TYPE(self)); \ CONTEXT_CHECK_VA(state, context); \ @@ -4450,22 +4422,15 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ return result; \ } -/* Ternary function with an optional context arg. */ +/* Ternary function with an optional context arg. + Argument Clinic provides PyObject *self, PyObject *other, PyObject *third, + PyObject *context +*/ #define Dec_TernaryFuncVA(MPDFUNC) \ -static PyObject * \ -dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ { \ - static char *kwlist[] = {"other", "third", "context", NULL}; \ - PyObject *other, *third; \ PyObject *a, *b, *c; \ PyObject *result; \ - PyObject *context = Py_None; \ uint32_t status = 0; \ - \ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist, \ - &other, &third, &context)) { \ - return NULL; \ - } \ decimal_state *state = get_module_state_by_def(Py_TYPE(self)); \ CONTEXT_CHECK_VA(state, context); \ CONVERT_TERNOP_RAISE(&a, &b, &c, self, other, third, context); \ @@ -4615,25 +4580,249 @@ nm_mpd_qpow(PyObject *base, PyObject *exp, PyObject *mod) /******************************************************************************/ /* Unary arithmetic functions, optional context arg */ + +/*[clinic input] +_decimal.Decimal.exp + + context: object = None + +Return the value of the (natural) exponential function e**x. + +The function always uses the ROUND_HALF_EVEN mode and the result is +correctly rounded. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_exp_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=c0833b6e9b8c836f input=274784af925e60c9]*/ Dec_UnaryFuncVA(mpd_qexp) + +/*[clinic input] +_decimal.Decimal.ln = _decimal.Decimal.exp + +Return the natural (base e) logarithm of the operand. + +The function always uses the ROUND_HALF_EVEN mode and the result is +correctly rounded. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_ln_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=5191f4ef739b04b0 input=d353c51ec00d1cff]*/ Dec_UnaryFuncVA(mpd_qln) + +/*[clinic input] +_decimal.Decimal.log10 = _decimal.Decimal.exp + +Return the base ten logarithm of the operand. + +The function always uses the ROUND_HALF_EVEN mode and the result is +correctly rounded. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_log10_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=d5da63df75900275 input=48a6be60154c0b46]*/ Dec_UnaryFuncVA(mpd_qlog10) + +/*[clinic input] +_decimal.Decimal.next_minus = _decimal.Decimal.exp + +Returns the largest representable number smaller than itself. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_next_minus_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=aacbd758399f883f input=666b348f71e6c090]*/ Dec_UnaryFuncVA(mpd_qnext_minus) + +/*[clinic input] +_decimal.Decimal.next_plus = _decimal.Decimal.exp + +Returns the smallest representable number larger than itself. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_next_plus_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=f3a7029a213c553c input=04e105060ad1fa15]*/ Dec_UnaryFuncVA(mpd_qnext_plus) + +/*[clinic input] +_decimal.Decimal.normalize = _decimal.Decimal.exp + +Normalize the number by stripping trailing 0s + +This also change anything equal to 0 to 0e0. Used for producing +canonical values for members of an equivalence class. For example, +Decimal('32.100') and Decimal('0.321000e+2') both normalize to +the equivalent value Decimal('32.1'). +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_normalize_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=db2c8b3c8eccff36 input=d5ee63acd904d4de]*/ Dec_UnaryFuncVA(mpd_qreduce) + +/*[clinic input] +_decimal.Decimal.sqrt = _decimal.Decimal.exp + +Return the square root of the argument to full precision. + +The result is correctly rounded using the ROUND_HALF_EVEN rounding mode. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_sqrt_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=420722a199dd9c2b input=3a76afbd39dc20b9]*/ Dec_UnaryFuncVA(mpd_qsqrt) /* Binary arithmetic functions, optional context arg */ + +/*[clinic input] +_decimal.Decimal.compare + + other: object + context: object = None + +Compare self to other. + +Return a decimal value: + + a or b is a NaN ==> Decimal('NaN') + a < b ==> Decimal('-1') + a == b ==> Decimal('0') + a > b ==> Decimal('1') +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_compare_impl(PyObject *self, PyObject *other, + PyObject *context) +/*[clinic end generated code: output=d6967aa3578b9d48 input=1b7b75a2a154e520]*/ Dec_BinaryFuncVA(mpd_qcompare) + +/*[clinic input] +_decimal.Decimal.compare_signal = _decimal.Decimal.compare + +Identical to compare, except that all NaNs signal. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_compare_signal_impl(PyObject *self, PyObject *other, + PyObject *context) +/*[clinic end generated code: output=0b8d0ff43f6c8a95 input=a52a39d1c6fc369d]*/ Dec_BinaryFuncVA(mpd_qcompare_signal) + +/*[clinic input] +_decimal.Decimal.max = _decimal.Decimal.compare + +Maximum of self and other. + +If one operand is a quiet NaN and the other is numeric, the numeric +operand is returned. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_max_impl(PyObject *self, PyObject *other, PyObject *context) +/*[clinic end generated code: output=f3a5c5d76761c9ff input=2ae2582f551296d8]*/ Dec_BinaryFuncVA(mpd_qmax) + +/*[clinic input] +_decimal.Decimal.max_mag = _decimal.Decimal.compare + +As the max() method, but compares the absolute values of the operands. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_max_mag_impl(PyObject *self, PyObject *other, + PyObject *context) +/*[clinic end generated code: output=52b0451987bac65f input=88b105e66cf138c5]*/ Dec_BinaryFuncVA(mpd_qmax_mag) + +/*[clinic input] +_decimal.Decimal.min = _decimal.Decimal.compare + +Minimum of self and other. + +If one operand is a quiet NaN and the other is numeric, the numeric +operand is returned. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_min_impl(PyObject *self, PyObject *other, PyObject *context) +/*[clinic end generated code: output=d2f38ecb9d6f0493 input=2a70f2c087c418c9]*/ Dec_BinaryFuncVA(mpd_qmin) + +/*[clinic input] +_decimal.Decimal.min_mag = _decimal.Decimal.compare + +As the min() method, but compares the absolute values of the operands. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_min_mag_impl(PyObject *self, PyObject *other, + PyObject *context) +/*[clinic end generated code: output=aa3391935f6c8fc9 input=351fa3c0e592746a]*/ Dec_BinaryFuncVA(mpd_qmin_mag) + +/*[clinic input] +_decimal.Decimal.next_toward = _decimal.Decimal.compare + +Returns the number closest to self, in the direction towards other. + +If the two operands are unequal, return the number closest to the first +operand in the direction of the second operand. If both operands are +numerically equal, return a copy of the first operand with the sign set +to be the same as the sign of the second operand. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_next_toward_impl(PyObject *self, PyObject *other, + PyObject *context) +/*[clinic end generated code: output=edb933755644af69 input=fdf0091ea6e9e416]*/ Dec_BinaryFuncVA(mpd_qnext_toward) + +/*[clinic input] +_decimal.Decimal.remainder_near = _decimal.Decimal.compare + +Return the remainder from dividing self by other. + +This differs from self % other in that the sign of the remainder is +chosen so as to minimize its absolute value. More precisely, the return +value is self - n * other where n is the integer nearest to the exact +value of self / other, and if two integers are equally near then the +even one is chosen. + +If the result is zero then its sign will be the sign of self. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_remainder_near_impl(PyObject *self, PyObject *other, + PyObject *context) +/*[clinic end generated code: output=6ce0fb3b0faff2f9 input=eb5a8dfe3470b794]*/ Dec_BinaryFuncVA(mpd_qrem_near) /* Ternary arithmetic functions, optional context arg */ + +/*[clinic input] +_decimal.Decimal.fma + + other: object + third: object + context: object = None + +Fused multiply-add. + +Return self*other+third with no rounding of the intermediate product +self*other. + + >>> Decimal(2).fma(3, 5) + Decimal('11') +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_fma_impl(PyObject *self, PyObject *other, PyObject *third, + PyObject *context) +/*[clinic end generated code: output=74a82b984e227b69 input=48f9aec6f389227a]*/ Dec_TernaryFuncVA(mpd_qfma) /* Boolean functions, no context arg */ @@ -4647,7 +4836,32 @@ Dec_BoolFunc(mpd_issigned) Dec_BoolFunc(mpd_iszero) /* Boolean functions, optional context arg */ + +/*[clinic input] +_decimal.Decimal.is_normal = _decimal.Decimal.exp + +Return True if the argument is a normal number and False otherwise. + +Normal number is a finite nonzero number, which is not subnormal. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_is_normal_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=40cc429d388eb464 input=9afe43b9db9f4818]*/ Dec_BoolFuncVA(mpd_isnormal) + +/*[clinic input] +_decimal.Decimal.is_subnormal = _decimal.Decimal.exp + +Return True if the argument is subnormal, and False otherwise. + +A number is subnormal if it is non-zero, finite, and has an adjusted +exponent less than Emin. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_is_subnormal_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=6f7d422b1f387d7f input=11839c122c185b8b]*/ Dec_BoolFuncVA(mpd_issubnormal) /* Unary functions, no context arg */ @@ -4797,13 +5011,35 @@ _decimal_Decimal_copy_negate_impl(PyObject *self) } /* Unary functions, optional context arg */ + +/*[clinic input] +_decimal.Decimal.logical_invert = _decimal.Decimal.exp + +Return the digit-wise inversion of the (logical) operand. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_logical_invert_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=59beb9b1b51b9f34 input=3531dac8b9548dad]*/ Dec_UnaryFuncVA(mpd_qinvert) -Dec_UnaryFuncVA(mpd_qlogb) /*[clinic input] -_decimal.Decimal.number_class +_decimal.Decimal.logb = _decimal.Decimal.exp - context: object = None +Return the adjusted exponent of the operand as a Decimal instance. + +If the operand is a zero, then Decimal('-Infinity') is returned and the +DivisionByZero condition is raised. If the operand is an infinity then +Decimal('Infinity') is returned. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_logb_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=f278db20b47f301c input=a8df027d1b8a2b17]*/ +Dec_UnaryFuncVA(mpd_qlogb) + +/*[clinic input] +_decimal.Decimal.number_class = _decimal.Decimal.exp Return a string describing the class of the operand. @@ -4827,7 +5063,7 @@ The returned value is one of the following ten strings: static PyObject * _decimal_Decimal_number_class_impl(PyObject *self, PyObject *context) -/*[clinic end generated code: output=3044cd45966b4949 input=f3d6cdda603e8b89]*/ +/*[clinic end generated code: output=3044cd45966b4949 input=447095d2677fa0ca]*/ { const char *cp; @@ -4839,9 +5075,7 @@ _decimal_Decimal_number_class_impl(PyObject *self, PyObject *context) } /*[clinic input] -_decimal.Decimal.to_eng_string - - context: object = None +_decimal.Decimal.to_eng_string = _decimal.Decimal.exp Convert to an engineering-type string. @@ -4856,7 +5090,7 @@ operation. static PyObject * _decimal_Decimal_to_eng_string_impl(PyObject *self, PyObject *context) -/*[clinic end generated code: output=d386194c25ffffa7 input=2e13e7c7c1bad2ad]*/ +/*[clinic end generated code: output=d386194c25ffffa7 input=b2cb7e01e268e45d]*/ { PyObject *result; mpd_ssize_t size; @@ -4882,10 +5116,7 @@ Dec_BinaryFuncVA_NO_CTX(mpd_compare_total) Dec_BinaryFuncVA_NO_CTX(mpd_compare_total_mag) /*[clinic input] -_decimal.Decimal.copy_sign - - other: object - context: object = None +_decimal.Decimal.copy_sign = _decimal.Decimal.compare Return a copy of *self* with the sign of *other*. @@ -4903,7 +5134,7 @@ exactly. static PyObject * _decimal_Decimal_copy_sign_impl(PyObject *self, PyObject *other, PyObject *context) -/*[clinic end generated code: output=72c62177763e012e input=8410238d533a06eb]*/ +/*[clinic end generated code: output=72c62177763e012e input=51ed9e4691e2249e]*/ { PyObject *a, *b; PyObject *result; @@ -4932,10 +5163,7 @@ _decimal_Decimal_copy_sign_impl(PyObject *self, PyObject *other, } /*[clinic input] -_decimal.Decimal.same_quantum - - other: object - context: object = None +_decimal.Decimal.same_quantum = _decimal.Decimal.compare Test whether self and other have the same exponent or both are NaN. @@ -4948,7 +5176,7 @@ exactly. static PyObject * _decimal_Decimal_same_quantum_impl(PyObject *self, PyObject *other, PyObject *context) -/*[clinic end generated code: output=c0a3a046c662a7e2 input=3ae45df81d6edb73]*/ +/*[clinic end generated code: output=c0a3a046c662a7e2 input=8339415fa359e7df]*/ { PyObject *a, *b; PyObject *result; @@ -4965,12 +5193,94 @@ _decimal_Decimal_same_quantum_impl(PyObject *self, PyObject *other, } /* Binary functions, optional context arg */ + +/*[clinic input] +_decimal.Decimal.logical_and = _decimal.Decimal.compare + +Return the digit-wise 'and' of the two (logical) operands. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_logical_and_impl(PyObject *self, PyObject *other, + PyObject *context) +/*[clinic end generated code: output=1526a357f97eaf71 input=2b319baee8970929]*/ Dec_BinaryFuncVA(mpd_qand) + +/*[clinic input] +_decimal.Decimal.logical_or = _decimal.Decimal.compare + +Return the digit-wise 'or' of the two (logical) operands. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_logical_or_impl(PyObject *self, PyObject *other, + PyObject *context) +/*[clinic end generated code: output=e57a72acf0982f56 input=75e0e1d4dd373b90]*/ Dec_BinaryFuncVA(mpd_qor) + +/*[clinic input] +_decimal.Decimal.logical_xor = _decimal.Decimal.compare + +Return the digit-wise 'xor' of the two (logical) operands. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_logical_xor_impl(PyObject *self, PyObject *other, + PyObject *context) +/*[clinic end generated code: output=ae3a7aeddde5a1a8 input=a1ed8d6ac38c1c9e]*/ Dec_BinaryFuncVA(mpd_qxor) +/*[clinic input] +_decimal.Decimal.rotate = _decimal.Decimal.compare + +Returns a rotated copy of self's digits, value-of-other times. + +The second operand must be an integer in the range -precision through +precision. The absolute value of the second operand gives the number of +places to rotate. If the second operand is positive then rotation is to +the left; otherwise rotation is to the right. The coefficient of the +first operand is padded on the left with zeros to length precision if +necessary. The sign and exponent of the first operand are unchanged. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_rotate_impl(PyObject *self, PyObject *other, + PyObject *context) +/*[clinic end generated code: output=e59e757e70a8416a input=cde7b032eac43f0b]*/ Dec_BinaryFuncVA(mpd_qrotate) + +/*[clinic input] +_decimal.Decimal.scaleb = _decimal.Decimal.compare + +Return the first operand with the exponent adjusted the second. + +Equivalently, return the first operand multiplied by 10**other. The +second operand must be an integer. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_scaleb_impl(PyObject *self, PyObject *other, + PyObject *context) +/*[clinic end generated code: output=f01e99600eda34d7 input=7f29f83278d05f83]*/ Dec_BinaryFuncVA(mpd_qscaleb) + +/*[clinic input] +_decimal.Decimal.shift = _decimal.Decimal.compare + +Returns a shifted copy of self's digits, value-of-other times. + +The second operand must be an integer in the range -precision through +precision. The absolute value of the second operand gives the number +of places to shift. If the second operand is positive, then the shift +is to the left; otherwise the shift is to the right. Digits shifted +into the coefficient are zeros. The sign and exponent of the first +operand are unchanged. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_shift_impl(PyObject *self, PyObject *other, + PyObject *context) +/*[clinic end generated code: output=f79ff9ce6d5b05ed input=501759c2522cb78e]*/ Dec_BinaryFuncVA(mpd_qshift) /*[clinic input] @@ -5357,30 +5667,30 @@ static PyGetSetDef dec_getsets [] = static PyMethodDef dec_methods [] = { /* Unary arithmetic functions, optional context arg */ - { "exp", _PyCFunction_CAST(dec_mpd_qexp), METH_VARARGS|METH_KEYWORDS, doc_exp }, - { "ln", _PyCFunction_CAST(dec_mpd_qln), METH_VARARGS|METH_KEYWORDS, doc_ln }, - { "log10", _PyCFunction_CAST(dec_mpd_qlog10), METH_VARARGS|METH_KEYWORDS, doc_log10 }, - { "next_minus", _PyCFunction_CAST(dec_mpd_qnext_minus), METH_VARARGS|METH_KEYWORDS, doc_next_minus }, - { "next_plus", _PyCFunction_CAST(dec_mpd_qnext_plus), METH_VARARGS|METH_KEYWORDS, doc_next_plus }, - { "normalize", _PyCFunction_CAST(dec_mpd_qreduce), METH_VARARGS|METH_KEYWORDS, doc_normalize }, + _DECIMAL_DECIMAL_EXP_METHODDEF + _DECIMAL_DECIMAL_LN_METHODDEF + _DECIMAL_DECIMAL_LOG10_METHODDEF + _DECIMAL_DECIMAL_NEXT_MINUS_METHODDEF + _DECIMAL_DECIMAL_NEXT_PLUS_METHODDEF + _DECIMAL_DECIMAL_NORMALIZE_METHODDEF _DECIMAL_DECIMAL_TO_INTEGRAL_METHODDEF _DECIMAL_DECIMAL_TO_INTEGRAL_EXACT_METHODDEF _DECIMAL_DECIMAL_TO_INTEGRAL_VALUE_METHODDEF - { "sqrt", _PyCFunction_CAST(dec_mpd_qsqrt), METH_VARARGS|METH_KEYWORDS, doc_sqrt }, + _DECIMAL_DECIMAL_SQRT_METHODDEF /* Binary arithmetic functions, optional context arg */ - { "compare", _PyCFunction_CAST(dec_mpd_qcompare), METH_VARARGS|METH_KEYWORDS, doc_compare }, - { "compare_signal", _PyCFunction_CAST(dec_mpd_qcompare_signal), METH_VARARGS|METH_KEYWORDS, doc_compare_signal }, - { "max", _PyCFunction_CAST(dec_mpd_qmax), METH_VARARGS|METH_KEYWORDS, doc_max }, - { "max_mag", _PyCFunction_CAST(dec_mpd_qmax_mag), METH_VARARGS|METH_KEYWORDS, doc_max_mag }, - { "min", _PyCFunction_CAST(dec_mpd_qmin), METH_VARARGS|METH_KEYWORDS, doc_min }, - { "min_mag", _PyCFunction_CAST(dec_mpd_qmin_mag), METH_VARARGS|METH_KEYWORDS, doc_min_mag }, - { "next_toward", _PyCFunction_CAST(dec_mpd_qnext_toward), METH_VARARGS|METH_KEYWORDS, doc_next_toward }, + _DECIMAL_DECIMAL_COMPARE_METHODDEF + _DECIMAL_DECIMAL_COMPARE_SIGNAL_METHODDEF + _DECIMAL_DECIMAL_MAX_METHODDEF + _DECIMAL_DECIMAL_MAX_MAG_METHODDEF + _DECIMAL_DECIMAL_MIN_METHODDEF + _DECIMAL_DECIMAL_MIN_MAG_METHODDEF + _DECIMAL_DECIMAL_NEXT_TOWARD_METHODDEF _DECIMAL_DECIMAL_QUANTIZE_METHODDEF - { "remainder_near", _PyCFunction_CAST(dec_mpd_qrem_near), METH_VARARGS|METH_KEYWORDS, doc_remainder_near }, + _DECIMAL_DECIMAL_REMAINDER_NEAR_METHODDEF /* Ternary arithmetic functions, optional context arg */ - { "fma", _PyCFunction_CAST(dec_mpd_qfma), METH_VARARGS|METH_KEYWORDS, doc_fma }, + _DECIMAL_DECIMAL_FMA_METHODDEF /* Boolean functions, no context arg */ { "is_canonical", dec_mpd_iscanonical, METH_NOARGS, doc_is_canonical }, @@ -5393,8 +5703,8 @@ static PyMethodDef dec_methods [] = { "is_zero", dec_mpd_iszero, METH_NOARGS, doc_is_zero }, /* Boolean functions, optional context arg */ - { "is_normal", _PyCFunction_CAST(dec_mpd_isnormal), METH_VARARGS|METH_KEYWORDS, doc_is_normal }, - { "is_subnormal", _PyCFunction_CAST(dec_mpd_issubnormal), METH_VARARGS|METH_KEYWORDS, doc_is_subnormal }, + _DECIMAL_DECIMAL_IS_NORMAL_METHODDEF + _DECIMAL_DECIMAL_IS_SUBNORMAL_METHODDEF /* Unary functions, no context arg */ _DECIMAL_DECIMAL_ADJUSTED_METHODDEF @@ -5407,8 +5717,8 @@ static PyMethodDef dec_methods [] = _DECIMAL_DECIMAL_COPY_NEGATE_METHODDEF /* Unary functions, optional context arg */ - { "logb", _PyCFunction_CAST(dec_mpd_qlogb), METH_VARARGS|METH_KEYWORDS, doc_logb }, - { "logical_invert", _PyCFunction_CAST(dec_mpd_qinvert), METH_VARARGS|METH_KEYWORDS, doc_logical_invert }, + _DECIMAL_DECIMAL_LOGB_METHODDEF + _DECIMAL_DECIMAL_LOGICAL_INVERT_METHODDEF _DECIMAL_DECIMAL_NUMBER_CLASS_METHODDEF _DECIMAL_DECIMAL_TO_ENG_STRING_METHODDEF @@ -5419,12 +5729,12 @@ static PyMethodDef dec_methods [] = _DECIMAL_DECIMAL_SAME_QUANTUM_METHODDEF /* Binary functions, optional context arg */ - { "logical_and", _PyCFunction_CAST(dec_mpd_qand), METH_VARARGS|METH_KEYWORDS, doc_logical_and }, - { "logical_or", _PyCFunction_CAST(dec_mpd_qor), METH_VARARGS|METH_KEYWORDS, doc_logical_or }, - { "logical_xor", _PyCFunction_CAST(dec_mpd_qxor), METH_VARARGS|METH_KEYWORDS, doc_logical_xor }, - { "rotate", _PyCFunction_CAST(dec_mpd_qrotate), METH_VARARGS|METH_KEYWORDS, doc_rotate }, - { "scaleb", _PyCFunction_CAST(dec_mpd_qscaleb), METH_VARARGS|METH_KEYWORDS, doc_scaleb }, - { "shift", _PyCFunction_CAST(dec_mpd_qshift), METH_VARARGS|METH_KEYWORDS, doc_shift }, + _DECIMAL_DECIMAL_LOGICAL_AND_METHODDEF + _DECIMAL_DECIMAL_LOGICAL_OR_METHODDEF + _DECIMAL_DECIMAL_LOGICAL_XOR_METHODDEF + _DECIMAL_DECIMAL_ROTATE_METHODDEF + _DECIMAL_DECIMAL_SCALEB_METHODDEF + _DECIMAL_DECIMAL_SHIFT_METHODDEF /* Miscellaneous */ _DECIMAL_DECIMAL_FROM_FLOAT_METHODDEF diff --git a/Modules/_decimal/clinic/_decimal.c.h b/Modules/_decimal/clinic/_decimal.c.h index 7a2bcce1e9316b..7541a3ed79549d 100644 --- a/Modules/_decimal/clinic/_decimal.c.h +++ b/Modules/_decimal/clinic/_decimal.c.h @@ -572,162 +572,1920 @@ _decimal_Decimal_as_tuple(PyObject *self, PyObject *Py_UNUSED(ignored)) return _decimal_Decimal_as_tuple_impl(self); } +PyDoc_STRVAR(_decimal_Decimal_exp__doc__, +"exp($self, /, context=None)\n" +"--\n" +"\n" +"Return the value of the (natural) exponential function e**x.\n" +"\n" +"The function always uses the ROUND_HALF_EVEN mode and the result is\n" +"correctly rounded."); + +#define _DECIMAL_DECIMAL_EXP_METHODDEF \ + {"exp", _PyCFunction_CAST(_decimal_Decimal_exp), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_exp__doc__}, + +static PyObject * +_decimal_Decimal_exp_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_exp(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "exp", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_exp_impl(self, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_ln__doc__, +"ln($self, /, context=None)\n" +"--\n" +"\n" +"Return the natural (base e) logarithm of the operand.\n" +"\n" +"The function always uses the ROUND_HALF_EVEN mode and the result is\n" +"correctly rounded."); + +#define _DECIMAL_DECIMAL_LN_METHODDEF \ + {"ln", _PyCFunction_CAST(_decimal_Decimal_ln), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_ln__doc__}, + +static PyObject * +_decimal_Decimal_ln_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_ln(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "ln", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_ln_impl(self, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_log10__doc__, +"log10($self, /, context=None)\n" +"--\n" +"\n" +"Return the base ten logarithm of the operand.\n" +"\n" +"The function always uses the ROUND_HALF_EVEN mode and the result is\n" +"correctly rounded."); + +#define _DECIMAL_DECIMAL_LOG10_METHODDEF \ + {"log10", _PyCFunction_CAST(_decimal_Decimal_log10), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_log10__doc__}, + +static PyObject * +_decimal_Decimal_log10_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_log10(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "log10", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_log10_impl(self, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_next_minus__doc__, +"next_minus($self, /, context=None)\n" +"--\n" +"\n" +"Returns the largest representable number smaller than itself."); + +#define _DECIMAL_DECIMAL_NEXT_MINUS_METHODDEF \ + {"next_minus", _PyCFunction_CAST(_decimal_Decimal_next_minus), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_next_minus__doc__}, + +static PyObject * +_decimal_Decimal_next_minus_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_next_minus(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "next_minus", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_next_minus_impl(self, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_next_plus__doc__, +"next_plus($self, /, context=None)\n" +"--\n" +"\n" +"Returns the smallest representable number larger than itself."); + +#define _DECIMAL_DECIMAL_NEXT_PLUS_METHODDEF \ + {"next_plus", _PyCFunction_CAST(_decimal_Decimal_next_plus), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_next_plus__doc__}, + +static PyObject * +_decimal_Decimal_next_plus_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_next_plus(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "next_plus", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_next_plus_impl(self, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_normalize__doc__, +"normalize($self, /, context=None)\n" +"--\n" +"\n" +"Normalize the number by stripping trailing 0s\n" +"\n" +"This also change anything equal to 0 to 0e0. Used for producing\n" +"canonical values for members of an equivalence class. For example,\n" +"Decimal(\'32.100\') and Decimal(\'0.321000e+2\') both normalize to\n" +"the equivalent value Decimal(\'32.1\')."); + +#define _DECIMAL_DECIMAL_NORMALIZE_METHODDEF \ + {"normalize", _PyCFunction_CAST(_decimal_Decimal_normalize), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_normalize__doc__}, + +static PyObject * +_decimal_Decimal_normalize_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_normalize(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "normalize", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_normalize_impl(self, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_sqrt__doc__, +"sqrt($self, /, context=None)\n" +"--\n" +"\n" +"Return the square root of the argument to full precision.\n" +"\n" +"The result is correctly rounded using the ROUND_HALF_EVEN rounding mode."); + +#define _DECIMAL_DECIMAL_SQRT_METHODDEF \ + {"sqrt", _PyCFunction_CAST(_decimal_Decimal_sqrt), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_sqrt__doc__}, + +static PyObject * +_decimal_Decimal_sqrt_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_sqrt(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sqrt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_sqrt_impl(self, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_compare__doc__, +"compare($self, /, other, context=None)\n" +"--\n" +"\n" +"Compare self to other.\n" +"\n" +"Return a decimal value:\n" +"\n" +" a or b is a NaN ==> Decimal(\'NaN\')\n" +" a < b ==> Decimal(\'-1\')\n" +" a == b ==> Decimal(\'0\')\n" +" a > b ==> Decimal(\'1\')"); + +#define _DECIMAL_DECIMAL_COMPARE_METHODDEF \ + {"compare", _PyCFunction_CAST(_decimal_Decimal_compare), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_compare__doc__}, + +static PyObject * +_decimal_Decimal_compare_impl(PyObject *self, PyObject *other, + PyObject *context); + +static PyObject * +_decimal_Decimal_compare(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(other), &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"other", "context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compare", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *other; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + other = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + context = args[1]; +skip_optional_pos: + return_value = _decimal_Decimal_compare_impl(self, other, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_compare_signal__doc__, +"compare_signal($self, /, other, context=None)\n" +"--\n" +"\n" +"Identical to compare, except that all NaNs signal."); + +#define _DECIMAL_DECIMAL_COMPARE_SIGNAL_METHODDEF \ + {"compare_signal", _PyCFunction_CAST(_decimal_Decimal_compare_signal), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_compare_signal__doc__}, + +static PyObject * +_decimal_Decimal_compare_signal_impl(PyObject *self, PyObject *other, + PyObject *context); + +static PyObject * +_decimal_Decimal_compare_signal(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(other), &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"other", "context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compare_signal", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *other; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + other = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + context = args[1]; +skip_optional_pos: + return_value = _decimal_Decimal_compare_signal_impl(self, other, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_max__doc__, +"max($self, /, other, context=None)\n" +"--\n" +"\n" +"Maximum of self and other.\n" +"\n" +"If one operand is a quiet NaN and the other is numeric, the numeric\n" +"operand is returned."); + +#define _DECIMAL_DECIMAL_MAX_METHODDEF \ + {"max", _PyCFunction_CAST(_decimal_Decimal_max), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_max__doc__}, + +static PyObject * +_decimal_Decimal_max_impl(PyObject *self, PyObject *other, PyObject *context); + +static PyObject * +_decimal_Decimal_max(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(other), &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"other", "context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "max", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *other; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + other = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + context = args[1]; +skip_optional_pos: + return_value = _decimal_Decimal_max_impl(self, other, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_max_mag__doc__, +"max_mag($self, /, other, context=None)\n" +"--\n" +"\n" +"As the max() method, but compares the absolute values of the operands."); + +#define _DECIMAL_DECIMAL_MAX_MAG_METHODDEF \ + {"max_mag", _PyCFunction_CAST(_decimal_Decimal_max_mag), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_max_mag__doc__}, + +static PyObject * +_decimal_Decimal_max_mag_impl(PyObject *self, PyObject *other, + PyObject *context); + +static PyObject * +_decimal_Decimal_max_mag(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(other), &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"other", "context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "max_mag", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *other; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + other = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + context = args[1]; +skip_optional_pos: + return_value = _decimal_Decimal_max_mag_impl(self, other, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_min__doc__, +"min($self, /, other, context=None)\n" +"--\n" +"\n" +"Minimum of self and other.\n" +"\n" +"If one operand is a quiet NaN and the other is numeric, the numeric\n" +"operand is returned."); + +#define _DECIMAL_DECIMAL_MIN_METHODDEF \ + {"min", _PyCFunction_CAST(_decimal_Decimal_min), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_min__doc__}, + +static PyObject * +_decimal_Decimal_min_impl(PyObject *self, PyObject *other, PyObject *context); + +static PyObject * +_decimal_Decimal_min(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(other), &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"other", "context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "min", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *other; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + other = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + context = args[1]; +skip_optional_pos: + return_value = _decimal_Decimal_min_impl(self, other, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_min_mag__doc__, +"min_mag($self, /, other, context=None)\n" +"--\n" +"\n" +"As the min() method, but compares the absolute values of the operands."); + +#define _DECIMAL_DECIMAL_MIN_MAG_METHODDEF \ + {"min_mag", _PyCFunction_CAST(_decimal_Decimal_min_mag), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_min_mag__doc__}, + +static PyObject * +_decimal_Decimal_min_mag_impl(PyObject *self, PyObject *other, + PyObject *context); + +static PyObject * +_decimal_Decimal_min_mag(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(other), &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"other", "context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "min_mag", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *other; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + other = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + context = args[1]; +skip_optional_pos: + return_value = _decimal_Decimal_min_mag_impl(self, other, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_next_toward__doc__, +"next_toward($self, /, other, context=None)\n" +"--\n" +"\n" +"Returns the number closest to self, in the direction towards other.\n" +"\n" +"If the two operands are unequal, return the number closest to the first\n" +"operand in the direction of the second operand. If both operands are\n" +"numerically equal, return a copy of the first operand with the sign set\n" +"to be the same as the sign of the second operand."); + +#define _DECIMAL_DECIMAL_NEXT_TOWARD_METHODDEF \ + {"next_toward", _PyCFunction_CAST(_decimal_Decimal_next_toward), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_next_toward__doc__}, + +static PyObject * +_decimal_Decimal_next_toward_impl(PyObject *self, PyObject *other, + PyObject *context); + +static PyObject * +_decimal_Decimal_next_toward(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(other), &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"other", "context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "next_toward", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *other; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + other = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + context = args[1]; +skip_optional_pos: + return_value = _decimal_Decimal_next_toward_impl(self, other, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_remainder_near__doc__, +"remainder_near($self, /, other, context=None)\n" +"--\n" +"\n" +"Return the remainder from dividing self by other.\n" +"\n" +"This differs from self % other in that the sign of the remainder is\n" +"chosen so as to minimize its absolute value. More precisely, the return\n" +"value is self - n * other where n is the integer nearest to the exact\n" +"value of self / other, and if two integers are equally near then the\n" +"even one is chosen.\n" +"\n" +"If the result is zero then its sign will be the sign of self."); + +#define _DECIMAL_DECIMAL_REMAINDER_NEAR_METHODDEF \ + {"remainder_near", _PyCFunction_CAST(_decimal_Decimal_remainder_near), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_remainder_near__doc__}, + +static PyObject * +_decimal_Decimal_remainder_near_impl(PyObject *self, PyObject *other, + PyObject *context); + +static PyObject * +_decimal_Decimal_remainder_near(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(other), &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"other", "context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "remainder_near", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *other; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + other = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + context = args[1]; +skip_optional_pos: + return_value = _decimal_Decimal_remainder_near_impl(self, other, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_fma__doc__, +"fma($self, /, other, third, context=None)\n" +"--\n" +"\n" +"Fused multiply-add.\n" +"\n" +"Return self*other+third with no rounding of the intermediate product\n" +"self*other.\n" +"\n" +" >>> Decimal(2).fma(3, 5)\n" +" Decimal(\'11\')"); + +#define _DECIMAL_DECIMAL_FMA_METHODDEF \ + {"fma", _PyCFunction_CAST(_decimal_Decimal_fma), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_fma__doc__}, + +static PyObject * +_decimal_Decimal_fma_impl(PyObject *self, PyObject *other, PyObject *third, + PyObject *context); + +static PyObject * +_decimal_Decimal_fma(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(other), &_Py_ID(third), &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"other", "third", "context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fma", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + PyObject *other; + PyObject *third; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 2, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + other = args[0]; + third = args[1]; + if (!noptargs) { + goto skip_optional_pos; + } + context = args[2]; +skip_optional_pos: + return_value = _decimal_Decimal_fma_impl(self, other, third, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_is_normal__doc__, +"is_normal($self, /, context=None)\n" +"--\n" +"\n" +"Return True if the argument is a normal number and False otherwise.\n" +"\n" +"Normal number is a finite nonzero number, which is not subnormal."); + +#define _DECIMAL_DECIMAL_IS_NORMAL_METHODDEF \ + {"is_normal", _PyCFunction_CAST(_decimal_Decimal_is_normal), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_is_normal__doc__}, + +static PyObject * +_decimal_Decimal_is_normal_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_is_normal(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "is_normal", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_is_normal_impl(self, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_is_subnormal__doc__, +"is_subnormal($self, /, context=None)\n" +"--\n" +"\n" +"Return True if the argument is subnormal, and False otherwise.\n" +"\n" +"A number is subnormal if it is non-zero, finite, and has an adjusted\n" +"exponent less than Emin."); + +#define _DECIMAL_DECIMAL_IS_SUBNORMAL_METHODDEF \ + {"is_subnormal", _PyCFunction_CAST(_decimal_Decimal_is_subnormal), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_is_subnormal__doc__}, + +static PyObject * +_decimal_Decimal_is_subnormal_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_is_subnormal(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "is_subnormal", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_is_subnormal_impl(self, context); + +exit: + return return_value; +} + PyDoc_STRVAR(_decimal_Decimal_adjusted__doc__, "adjusted($self, /)\n" "--\n" "\n" -"Return the adjusted exponent (exp + digits - 1) of the number."); +"Return the adjusted exponent (exp + digits - 1) of the number."); + +#define _DECIMAL_DECIMAL_ADJUSTED_METHODDEF \ + {"adjusted", (PyCFunction)_decimal_Decimal_adjusted, METH_NOARGS, _decimal_Decimal_adjusted__doc__}, + +static PyObject * +_decimal_Decimal_adjusted_impl(PyObject *self); + +static PyObject * +_decimal_Decimal_adjusted(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _decimal_Decimal_adjusted_impl(self); +} + +PyDoc_STRVAR(_decimal_Decimal_canonical__doc__, +"canonical($self, /)\n" +"--\n" +"\n" +"Return the canonical encoding of the argument.\n" +"\n" +"Currently, the encoding of a Decimal instance is always canonical,\n" +"so this operation returns its argument unchanged."); + +#define _DECIMAL_DECIMAL_CANONICAL_METHODDEF \ + {"canonical", (PyCFunction)_decimal_Decimal_canonical, METH_NOARGS, _decimal_Decimal_canonical__doc__}, + +static PyObject * +_decimal_Decimal_canonical_impl(PyObject *self); + +static PyObject * +_decimal_Decimal_canonical(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _decimal_Decimal_canonical_impl(self); +} + +PyDoc_STRVAR(_decimal_Decimal_conjugate__doc__, +"conjugate($self, /)\n" +"--\n" +"\n" +"Return self."); + +#define _DECIMAL_DECIMAL_CONJUGATE_METHODDEF \ + {"conjugate", (PyCFunction)_decimal_Decimal_conjugate, METH_NOARGS, _decimal_Decimal_conjugate__doc__}, + +static PyObject * +_decimal_Decimal_conjugate_impl(PyObject *self); + +static PyObject * +_decimal_Decimal_conjugate(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _decimal_Decimal_conjugate_impl(self); +} + +PyDoc_STRVAR(_decimal_Decimal_radix__doc__, +"radix($self, /)\n" +"--\n" +"\n" +"Return Decimal(10).\n" +"\n" +"This is the radix (base) in which the Decimal class does\n" +"all its arithmetic. Included for compatibility with the specification."); + +#define _DECIMAL_DECIMAL_RADIX_METHODDEF \ + {"radix", (PyCFunction)_decimal_Decimal_radix, METH_NOARGS, _decimal_Decimal_radix__doc__}, + +static PyObject * +_decimal_Decimal_radix_impl(PyObject *self); + +static PyObject * +_decimal_Decimal_radix(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _decimal_Decimal_radix_impl(self); +} + +PyDoc_STRVAR(_decimal_Decimal_copy_abs__doc__, +"copy_abs($self, /)\n" +"--\n" +"\n" +"Return the absolute value of the argument.\n" +"\n" +"This operation is unaffected by context and is quiet: no flags are\n" +"changed and no rounding is performed."); + +#define _DECIMAL_DECIMAL_COPY_ABS_METHODDEF \ + {"copy_abs", (PyCFunction)_decimal_Decimal_copy_abs, METH_NOARGS, _decimal_Decimal_copy_abs__doc__}, + +static PyObject * +_decimal_Decimal_copy_abs_impl(PyObject *self); + +static PyObject * +_decimal_Decimal_copy_abs(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _decimal_Decimal_copy_abs_impl(self); +} + +PyDoc_STRVAR(_decimal_Decimal_copy_negate__doc__, +"copy_negate($self, /)\n" +"--\n" +"\n" +"Return the negation of the argument.\n" +"\n" +"This operation is unaffected by context and is quiet: no flags are\n" +"changed and no rounding is performed."); + +#define _DECIMAL_DECIMAL_COPY_NEGATE_METHODDEF \ + {"copy_negate", (PyCFunction)_decimal_Decimal_copy_negate, METH_NOARGS, _decimal_Decimal_copy_negate__doc__}, + +static PyObject * +_decimal_Decimal_copy_negate_impl(PyObject *self); + +static PyObject * +_decimal_Decimal_copy_negate(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _decimal_Decimal_copy_negate_impl(self); +} + +PyDoc_STRVAR(_decimal_Decimal_logical_invert__doc__, +"logical_invert($self, /, context=None)\n" +"--\n" +"\n" +"Return the digit-wise inversion of the (logical) operand."); + +#define _DECIMAL_DECIMAL_LOGICAL_INVERT_METHODDEF \ + {"logical_invert", _PyCFunction_CAST(_decimal_Decimal_logical_invert), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logical_invert__doc__}, + +static PyObject * +_decimal_Decimal_logical_invert_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_logical_invert(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "logical_invert", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_logical_invert_impl(self, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_logb__doc__, +"logb($self, /, context=None)\n" +"--\n" +"\n" +"Return the adjusted exponent of the operand as a Decimal instance.\n" +"\n" +"If the operand is a zero, then Decimal(\'-Infinity\') is returned and the\n" +"DivisionByZero condition is raised. If the operand is an infinity then\n" +"Decimal(\'Infinity\') is returned."); + +#define _DECIMAL_DECIMAL_LOGB_METHODDEF \ + {"logb", _PyCFunction_CAST(_decimal_Decimal_logb), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logb__doc__}, + +static PyObject * +_decimal_Decimal_logb_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_logb(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "logb", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_logb_impl(self, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_number_class__doc__, +"number_class($self, /, context=None)\n" +"--\n" +"\n" +"Return a string describing the class of the operand.\n" +"\n" +"The returned value is one of the following ten strings:\n" +"\n" +" * \'-Infinity\', indicating that the operand is negative infinity.\n" +" * \'-Normal\', indicating that the operand is a negative normal\n" +" number.\n" +" * \'-Subnormal\', indicating that the operand is negative and\n" +" subnormal.\n" +" * \'-Zero\', indicating that the operand is a negative zero.\n" +" * \'+Zero\', indicating that the operand is a positive zero.\n" +" * \'+Subnormal\', indicating that the operand is positive and\n" +" subnormal.\n" +" * \'+Normal\', indicating that the operand is a positive normal\n" +" number.\n" +" * \'+Infinity\', indicating that the operand is positive infinity.\n" +" * \'NaN\', indicating that the operand is a quiet NaN (Not a Number).\n" +" * \'sNaN\', indicating that the operand is a signaling NaN."); + +#define _DECIMAL_DECIMAL_NUMBER_CLASS_METHODDEF \ + {"number_class", _PyCFunction_CAST(_decimal_Decimal_number_class), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_number_class__doc__}, + +static PyObject * +_decimal_Decimal_number_class_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_number_class(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "number_class", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_number_class_impl(self, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_to_eng_string__doc__, +"to_eng_string($self, /, context=None)\n" +"--\n" +"\n" +"Convert to an engineering-type string.\n" +"\n" +"Engineering notation has an exponent which is a multiple of 3, so there\n" +"are up to 3 digits left of the decimal place. For example,\n" +"Decimal(\'123E+1\') is converted to Decimal(\'1.23E+3\').\n" +"\n" +"The value of context.capitals determines whether the exponent sign is\n" +"lower or upper case. Otherwise, the context does not affect the\n" +"operation."); -#define _DECIMAL_DECIMAL_ADJUSTED_METHODDEF \ - {"adjusted", (PyCFunction)_decimal_Decimal_adjusted, METH_NOARGS, _decimal_Decimal_adjusted__doc__}, +#define _DECIMAL_DECIMAL_TO_ENG_STRING_METHODDEF \ + {"to_eng_string", _PyCFunction_CAST(_decimal_Decimal_to_eng_string), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_to_eng_string__doc__}, static PyObject * -_decimal_Decimal_adjusted_impl(PyObject *self); +_decimal_Decimal_to_eng_string_impl(PyObject *self, PyObject *context); static PyObject * -_decimal_Decimal_adjusted(PyObject *self, PyObject *Py_UNUSED(ignored)) +_decimal_Decimal_to_eng_string(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _decimal_Decimal_adjusted_impl(self); + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "to_eng_string", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_to_eng_string_impl(self, context); + +exit: + return return_value; } -PyDoc_STRVAR(_decimal_Decimal_canonical__doc__, -"canonical($self, /)\n" +PyDoc_STRVAR(_decimal_Decimal_copy_sign__doc__, +"copy_sign($self, /, other, context=None)\n" "--\n" "\n" -"Return the canonical encoding of the argument.\n" +"Return a copy of *self* with the sign of *other*.\n" "\n" -"Currently, the encoding of a Decimal instance is always canonical,\n" -"so this operation returns its argument unchanged."); +"For example:\n" +"\n" +" >>> Decimal(\'2.3\').copy_sign(Decimal(\'-1.5\'))\n" +" Decimal(\'-2.3\')\n" +"\n" +"This operation is unaffected by context and is quiet: no flags are\n" +"changed and no rounding is performed. As an exception, the C version\n" +"may raise InvalidOperation if the second operand cannot be converted\n" +"exactly."); -#define _DECIMAL_DECIMAL_CANONICAL_METHODDEF \ - {"canonical", (PyCFunction)_decimal_Decimal_canonical, METH_NOARGS, _decimal_Decimal_canonical__doc__}, +#define _DECIMAL_DECIMAL_COPY_SIGN_METHODDEF \ + {"copy_sign", _PyCFunction_CAST(_decimal_Decimal_copy_sign), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_copy_sign__doc__}, static PyObject * -_decimal_Decimal_canonical_impl(PyObject *self); +_decimal_Decimal_copy_sign_impl(PyObject *self, PyObject *other, + PyObject *context); + +static PyObject * +_decimal_Decimal_copy_sign(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(other), &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"other", "context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "copy_sign", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *other; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + other = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + context = args[1]; +skip_optional_pos: + return_value = _decimal_Decimal_copy_sign_impl(self, other, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_same_quantum__doc__, +"same_quantum($self, /, other, context=None)\n" +"--\n" +"\n" +"Test whether self and other have the same exponent or both are NaN.\n" +"\n" +"This operation is unaffected by context and is quiet: no flags are\n" +"changed and no rounding is performed. As an exception, the C version\n" +"may raise InvalidOperation if the second operand cannot be converted\n" +"exactly."); + +#define _DECIMAL_DECIMAL_SAME_QUANTUM_METHODDEF \ + {"same_quantum", _PyCFunction_CAST(_decimal_Decimal_same_quantum), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_same_quantum__doc__}, + +static PyObject * +_decimal_Decimal_same_quantum_impl(PyObject *self, PyObject *other, + PyObject *context); + +static PyObject * +_decimal_Decimal_same_quantum(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(other), &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"other", "context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "same_quantum", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *other; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + other = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + context = args[1]; +skip_optional_pos: + return_value = _decimal_Decimal_same_quantum_impl(self, other, context); -static PyObject * -_decimal_Decimal_canonical(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _decimal_Decimal_canonical_impl(self); +exit: + return return_value; } -PyDoc_STRVAR(_decimal_Decimal_conjugate__doc__, -"conjugate($self, /)\n" +PyDoc_STRVAR(_decimal_Decimal_logical_and__doc__, +"logical_and($self, /, other, context=None)\n" "--\n" "\n" -"Return self."); +"Return the digit-wise \'and\' of the two (logical) operands."); -#define _DECIMAL_DECIMAL_CONJUGATE_METHODDEF \ - {"conjugate", (PyCFunction)_decimal_Decimal_conjugate, METH_NOARGS, _decimal_Decimal_conjugate__doc__}, +#define _DECIMAL_DECIMAL_LOGICAL_AND_METHODDEF \ + {"logical_and", _PyCFunction_CAST(_decimal_Decimal_logical_and), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logical_and__doc__}, static PyObject * -_decimal_Decimal_conjugate_impl(PyObject *self); +_decimal_Decimal_logical_and_impl(PyObject *self, PyObject *other, + PyObject *context); static PyObject * -_decimal_Decimal_conjugate(PyObject *self, PyObject *Py_UNUSED(ignored)) +_decimal_Decimal_logical_and(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _decimal_Decimal_conjugate_impl(self); -} + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -PyDoc_STRVAR(_decimal_Decimal_radix__doc__, -"radix($self, /)\n" -"--\n" -"\n" -"Return Decimal(10).\n" -"\n" -"This is the radix (base) in which the Decimal class does\n" -"all its arithmetic. Included for compatibility with the specification."); + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(other), &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) -#define _DECIMAL_DECIMAL_RADIX_METHODDEF \ - {"radix", (PyCFunction)_decimal_Decimal_radix, METH_NOARGS, _decimal_Decimal_radix__doc__}, + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE -static PyObject * -_decimal_Decimal_radix_impl(PyObject *self); + static const char * const _keywords[] = {"other", "context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "logical_and", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *other; + PyObject *context = Py_None; -static PyObject * -_decimal_Decimal_radix(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _decimal_Decimal_radix_impl(self); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + other = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + context = args[1]; +skip_optional_pos: + return_value = _decimal_Decimal_logical_and_impl(self, other, context); + +exit: + return return_value; } -PyDoc_STRVAR(_decimal_Decimal_copy_abs__doc__, -"copy_abs($self, /)\n" +PyDoc_STRVAR(_decimal_Decimal_logical_or__doc__, +"logical_or($self, /, other, context=None)\n" "--\n" "\n" -"Return the absolute value of the argument.\n" -"\n" -"This operation is unaffected by context and is quiet: no flags are\n" -"changed and no rounding is performed."); +"Return the digit-wise \'or\' of the two (logical) operands."); -#define _DECIMAL_DECIMAL_COPY_ABS_METHODDEF \ - {"copy_abs", (PyCFunction)_decimal_Decimal_copy_abs, METH_NOARGS, _decimal_Decimal_copy_abs__doc__}, +#define _DECIMAL_DECIMAL_LOGICAL_OR_METHODDEF \ + {"logical_or", _PyCFunction_CAST(_decimal_Decimal_logical_or), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logical_or__doc__}, static PyObject * -_decimal_Decimal_copy_abs_impl(PyObject *self); +_decimal_Decimal_logical_or_impl(PyObject *self, PyObject *other, + PyObject *context); static PyObject * -_decimal_Decimal_copy_abs(PyObject *self, PyObject *Py_UNUSED(ignored)) +_decimal_Decimal_logical_or(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _decimal_Decimal_copy_abs_impl(self); -} + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -PyDoc_STRVAR(_decimal_Decimal_copy_negate__doc__, -"copy_negate($self, /)\n" -"--\n" -"\n" -"Return the negation of the argument.\n" -"\n" -"This operation is unaffected by context and is quiet: no flags are\n" -"changed and no rounding is performed."); + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(other), &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) -#define _DECIMAL_DECIMAL_COPY_NEGATE_METHODDEF \ - {"copy_negate", (PyCFunction)_decimal_Decimal_copy_negate, METH_NOARGS, _decimal_Decimal_copy_negate__doc__}, + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE -static PyObject * -_decimal_Decimal_copy_negate_impl(PyObject *self); + static const char * const _keywords[] = {"other", "context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "logical_or", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *other; + PyObject *context = Py_None; -static PyObject * -_decimal_Decimal_copy_negate(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _decimal_Decimal_copy_negate_impl(self); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + other = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + context = args[1]; +skip_optional_pos: + return_value = _decimal_Decimal_logical_or_impl(self, other, context); + +exit: + return return_value; } -PyDoc_STRVAR(_decimal_Decimal_number_class__doc__, -"number_class($self, /, context=None)\n" +PyDoc_STRVAR(_decimal_Decimal_logical_xor__doc__, +"logical_xor($self, /, other, context=None)\n" "--\n" "\n" -"Return a string describing the class of the operand.\n" -"\n" -"The returned value is one of the following ten strings:\n" -"\n" -" * \'-Infinity\', indicating that the operand is negative infinity.\n" -" * \'-Normal\', indicating that the operand is a negative normal\n" -" number.\n" -" * \'-Subnormal\', indicating that the operand is negative and\n" -" subnormal.\n" -" * \'-Zero\', indicating that the operand is a negative zero.\n" -" * \'+Zero\', indicating that the operand is a positive zero.\n" -" * \'+Subnormal\', indicating that the operand is positive and\n" -" subnormal.\n" -" * \'+Normal\', indicating that the operand is a positive normal\n" -" number.\n" -" * \'+Infinity\', indicating that the operand is positive infinity.\n" -" * \'NaN\', indicating that the operand is a quiet NaN (Not a Number).\n" -" * \'sNaN\', indicating that the operand is a signaling NaN."); +"Return the digit-wise \'xor\' of the two (logical) operands."); -#define _DECIMAL_DECIMAL_NUMBER_CLASS_METHODDEF \ - {"number_class", _PyCFunction_CAST(_decimal_Decimal_number_class), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_number_class__doc__}, +#define _DECIMAL_DECIMAL_LOGICAL_XOR_METHODDEF \ + {"logical_xor", _PyCFunction_CAST(_decimal_Decimal_logical_xor), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logical_xor__doc__}, static PyObject * -_decimal_Decimal_number_class_impl(PyObject *self, PyObject *context); +_decimal_Decimal_logical_xor_impl(PyObject *self, PyObject *other, + PyObject *context); static PyObject * -_decimal_Decimal_number_class(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_decimal_Decimal_logical_xor(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - #define NUM_KEYWORDS 1 + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -736,7 +2494,7 @@ _decimal_Decimal_number_class(PyObject *self, PyObject *const *args, Py_ssize_t } _kwtuple = { .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_hash = -1, - .ob_item = { &_Py_ID(context), }, + .ob_item = { &_Py_ID(other), &_Py_ID(context), }, }; #undef NUM_KEYWORDS #define KWTUPLE (&_kwtuple.ob_base.ob_base) @@ -745,60 +2503,62 @@ _decimal_Decimal_number_class(PyObject *self, PyObject *const *args, Py_ssize_t # define KWTUPLE NULL #endif // !Py_BUILD_CORE - static const char * const _keywords[] = {"context", NULL}; + static const char * const _keywords[] = {"other", "context", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, - .fname = "number_class", + .fname = "logical_xor", .kwtuple = KWTUPLE, }; #undef KWTUPLE - PyObject *argsbuf[1]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *other; PyObject *context = Py_None; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, - /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); if (!args) { goto exit; } + other = args[0]; if (!noptargs) { goto skip_optional_pos; } - context = args[0]; + context = args[1]; skip_optional_pos: - return_value = _decimal_Decimal_number_class_impl(self, context); + return_value = _decimal_Decimal_logical_xor_impl(self, other, context); exit: return return_value; } -PyDoc_STRVAR(_decimal_Decimal_to_eng_string__doc__, -"to_eng_string($self, /, context=None)\n" +PyDoc_STRVAR(_decimal_Decimal_rotate__doc__, +"rotate($self, /, other, context=None)\n" "--\n" "\n" -"Convert to an engineering-type string.\n" -"\n" -"Engineering notation has an exponent which is a multiple of 3, so there\n" -"are up to 3 digits left of the decimal place. For example,\n" -"Decimal(\'123E+1\') is converted to Decimal(\'1.23E+3\').\n" +"Returns a rotated copy of self\'s digits, value-of-other times.\n" "\n" -"The value of context.capitals determines whether the exponent sign is\n" -"lower or upper case. Otherwise, the context does not affect the\n" -"operation."); +"The second operand must be an integer in the range -precision through\n" +"precision. The absolute value of the second operand gives the number of\n" +"places to rotate. If the second operand is positive then rotation is to\n" +"the left; otherwise rotation is to the right. The coefficient of the\n" +"first operand is padded on the left with zeros to length precision if\n" +"necessary. The sign and exponent of the first operand are unchanged."); -#define _DECIMAL_DECIMAL_TO_ENG_STRING_METHODDEF \ - {"to_eng_string", _PyCFunction_CAST(_decimal_Decimal_to_eng_string), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_to_eng_string__doc__}, +#define _DECIMAL_DECIMAL_ROTATE_METHODDEF \ + {"rotate", _PyCFunction_CAST(_decimal_Decimal_rotate), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_rotate__doc__}, static PyObject * -_decimal_Decimal_to_eng_string_impl(PyObject *self, PyObject *context); +_decimal_Decimal_rotate_impl(PyObject *self, PyObject *other, + PyObject *context); static PyObject * -_decimal_Decimal_to_eng_string(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_decimal_Decimal_rotate(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - #define NUM_KEYWORDS 1 + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -807,7 +2567,7 @@ _decimal_Decimal_to_eng_string(PyObject *self, PyObject *const *args, Py_ssize_t } _kwtuple = { .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_hash = -1, - .ob_item = { &_Py_ID(context), }, + .ob_item = { &_Py_ID(other), &_Py_ID(context), }, }; #undef NUM_KEYWORDS #define KWTUPLE (&_kwtuple.ob_base.ob_base) @@ -816,58 +2576,53 @@ _decimal_Decimal_to_eng_string(PyObject *self, PyObject *const *args, Py_ssize_t # define KWTUPLE NULL #endif // !Py_BUILD_CORE - static const char * const _keywords[] = {"context", NULL}; + static const char * const _keywords[] = {"other", "context", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, - .fname = "to_eng_string", + .fname = "rotate", .kwtuple = KWTUPLE, }; #undef KWTUPLE - PyObject *argsbuf[1]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *other; PyObject *context = Py_None; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, - /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); if (!args) { goto exit; } + other = args[0]; if (!noptargs) { goto skip_optional_pos; } - context = args[0]; + context = args[1]; skip_optional_pos: - return_value = _decimal_Decimal_to_eng_string_impl(self, context); + return_value = _decimal_Decimal_rotate_impl(self, other, context); exit: return return_value; } -PyDoc_STRVAR(_decimal_Decimal_copy_sign__doc__, -"copy_sign($self, /, other, context=None)\n" +PyDoc_STRVAR(_decimal_Decimal_scaleb__doc__, +"scaleb($self, /, other, context=None)\n" "--\n" "\n" -"Return a copy of *self* with the sign of *other*.\n" -"\n" -"For example:\n" -"\n" -" >>> Decimal(\'2.3\').copy_sign(Decimal(\'-1.5\'))\n" -" Decimal(\'-2.3\')\n" +"Return the first operand with the exponent adjusted the second.\n" "\n" -"This operation is unaffected by context and is quiet: no flags are\n" -"changed and no rounding is performed. As an exception, the C version\n" -"may raise InvalidOperation if the second operand cannot be converted\n" -"exactly."); +"Equivalently, return the first operand multiplied by 10**other. The\n" +"second operand must be an integer."); -#define _DECIMAL_DECIMAL_COPY_SIGN_METHODDEF \ - {"copy_sign", _PyCFunction_CAST(_decimal_Decimal_copy_sign), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_copy_sign__doc__}, +#define _DECIMAL_DECIMAL_SCALEB_METHODDEF \ + {"scaleb", _PyCFunction_CAST(_decimal_Decimal_scaleb), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_scaleb__doc__}, static PyObject * -_decimal_Decimal_copy_sign_impl(PyObject *self, PyObject *other, - PyObject *context); +_decimal_Decimal_scaleb_impl(PyObject *self, PyObject *other, + PyObject *context); static PyObject * -_decimal_Decimal_copy_sign(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_decimal_Decimal_scaleb(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) @@ -893,7 +2648,7 @@ _decimal_Decimal_copy_sign(PyObject *self, PyObject *const *args, Py_ssize_t nar static const char * const _keywords[] = {"other", "context", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, - .fname = "copy_sign", + .fname = "scaleb", .kwtuple = KWTUPLE, }; #undef KWTUPLE @@ -913,32 +2668,34 @@ _decimal_Decimal_copy_sign(PyObject *self, PyObject *const *args, Py_ssize_t nar } context = args[1]; skip_optional_pos: - return_value = _decimal_Decimal_copy_sign_impl(self, other, context); + return_value = _decimal_Decimal_scaleb_impl(self, other, context); exit: return return_value; } -PyDoc_STRVAR(_decimal_Decimal_same_quantum__doc__, -"same_quantum($self, /, other, context=None)\n" +PyDoc_STRVAR(_decimal_Decimal_shift__doc__, +"shift($self, /, other, context=None)\n" "--\n" "\n" -"Test whether self and other have the same exponent or both are NaN.\n" +"Returns a shifted copy of self\'s digits, value-of-other times.\n" "\n" -"This operation is unaffected by context and is quiet: no flags are\n" -"changed and no rounding is performed. As an exception, the C version\n" -"may raise InvalidOperation if the second operand cannot be converted\n" -"exactly."); +"The second operand must be an integer in the range -precision through\n" +"precision. The absolute value of the second operand gives the number\n" +"of places to shift. If the second operand is positive, then the shift\n" +"is to the left; otherwise the shift is to the right. Digits shifted\n" +"into the coefficient are zeros. The sign and exponent of the first\n" +"operand are unchanged."); -#define _DECIMAL_DECIMAL_SAME_QUANTUM_METHODDEF \ - {"same_quantum", _PyCFunction_CAST(_decimal_Decimal_same_quantum), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_same_quantum__doc__}, +#define _DECIMAL_DECIMAL_SHIFT_METHODDEF \ + {"shift", _PyCFunction_CAST(_decimal_Decimal_shift), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_shift__doc__}, static PyObject * -_decimal_Decimal_same_quantum_impl(PyObject *self, PyObject *other, - PyObject *context); +_decimal_Decimal_shift_impl(PyObject *self, PyObject *other, + PyObject *context); static PyObject * -_decimal_Decimal_same_quantum(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_decimal_Decimal_shift(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) @@ -964,7 +2721,7 @@ _decimal_Decimal_same_quantum(PyObject *self, PyObject *const *args, Py_ssize_t static const char * const _keywords[] = {"other", "context", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, - .fname = "same_quantum", + .fname = "shift", .kwtuple = KWTUPLE, }; #undef KWTUPLE @@ -984,7 +2741,7 @@ _decimal_Decimal_same_quantum(PyObject *self, PyObject *const *args, Py_ssize_t } context = args[1]; skip_optional_pos: - return_value = _decimal_Decimal_same_quantum_impl(self, other, context); + return_value = _decimal_Decimal_shift_impl(self, other, context); exit: return return_value; @@ -1165,4 +2922,4 @@ _decimal_Context_power(PyObject *context, PyObject *const *args, Py_ssize_t narg exit: return return_value; } -/*[clinic end generated code: output=6bb5c926552c2760 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9bbde3e723166dd3 input=a9049054013a1b77]*/ diff --git a/Modules/_decimal/docstrings.h b/Modules/_decimal/docstrings.h index 3ecfd34122ab6b..3ebac0a9b1e80a 100644 --- a/Modules/_decimal/docstrings.h +++ b/Modules/_decimal/docstrings.h @@ -31,21 +31,6 @@ context does not affect the conversion and is only passed to determine if\n\ the InvalidOperation trap is active.\n\ \n"); -PyDoc_STRVAR(doc_compare, -"compare($self, /, other, context=None)\n--\n\n\ -Compare self to other. Return a decimal value:\n\ -\n\ - a or b is a NaN ==> Decimal('NaN')\n\ - a < b ==> Decimal('-1')\n\ - a == b ==> Decimal('0')\n\ - a > b ==> Decimal('1')\n\ -\n"); - -PyDoc_STRVAR(doc_compare_signal, -"compare_signal($self, /, other, context=None)\n--\n\n\ -Identical to compare, except that all NaNs signal.\n\ -\n"); - PyDoc_STRVAR(doc_compare_total, "compare_total($self, /, other, context=None)\n--\n\n\ Compare two operands using their abstract representation rather than\n\ @@ -80,23 +65,6 @@ and no rounding is performed. As an exception, the C version may raise\n\ InvalidOperation if the second operand cannot be converted exactly.\n\ \n"); -PyDoc_STRVAR(doc_exp, -"exp($self, /, context=None)\n--\n\n\ -Return the value of the (natural) exponential function e**x at the given\n\ -number. The function always uses the ROUND_HALF_EVEN mode and the result\n\ -is correctly rounded.\n\ -\n"); - -PyDoc_STRVAR(doc_fma, -"fma($self, /, other, third, context=None)\n--\n\n\ -Fused multiply-add. Return self*other+third with no rounding of the\n\ -intermediate product self*other.\n\ -\n\ - >>> Decimal(2).fma(3, 5)\n\ - Decimal('11')\n\ -\n\ -\n"); - PyDoc_STRVAR(doc_is_canonical, "is_canonical($self, /)\n--\n\n\ Return True if the argument is canonical and False otherwise. Currently,\n\ @@ -122,13 +90,6 @@ Return True if the argument is a (quiet or signaling) NaN and False\n\ otherwise.\n\ \n"); -PyDoc_STRVAR(doc_is_normal, -"is_normal($self, /, context=None)\n--\n\n\ -Return True if the argument is a normal finite non-zero number with an\n\ -adjusted exponent greater than or equal to Emin. Return False if the\n\ -argument is zero, subnormal, infinite or a NaN.\n\ -\n"); - PyDoc_STRVAR(doc_is_qnan, "is_qnan($self, /)\n--\n\n\ Return True if the argument is a quiet NaN, and False otherwise.\n\ @@ -145,162 +106,12 @@ PyDoc_STRVAR(doc_is_snan, Return True if the argument is a signaling NaN and False otherwise.\n\ \n"); -PyDoc_STRVAR(doc_is_subnormal, -"is_subnormal($self, /, context=None)\n--\n\n\ -Return True if the argument is subnormal, and False otherwise. A number is\n\ -subnormal if it is non-zero, finite, and has an adjusted exponent less\n\ -than Emin.\n\ -\n"); - PyDoc_STRVAR(doc_is_zero, "is_zero($self, /)\n--\n\n\ Return True if the argument is a (positive or negative) zero and False\n\ otherwise.\n\ \n"); -PyDoc_STRVAR(doc_ln, -"ln($self, /, context=None)\n--\n\n\ -Return the natural (base e) logarithm of the operand. The function always\n\ -uses the ROUND_HALF_EVEN mode and the result is correctly rounded.\n\ -\n"); - -PyDoc_STRVAR(doc_log10, -"log10($self, /, context=None)\n--\n\n\ -Return the base ten logarithm of the operand. The function always uses the\n\ -ROUND_HALF_EVEN mode and the result is correctly rounded.\n\ -\n"); - -PyDoc_STRVAR(doc_logb, -"logb($self, /, context=None)\n--\n\n\ -For a non-zero number, return the adjusted exponent of the operand as a\n\ -Decimal instance. If the operand is a zero, then Decimal('-Infinity') is\n\ -returned and the DivisionByZero condition is raised. If the operand is\n\ -an infinity then Decimal('Infinity') is returned.\n\ -\n"); - -PyDoc_STRVAR(doc_logical_and, -"logical_and($self, /, other, context=None)\n--\n\n\ -Return the digit-wise 'and' of the two (logical) operands.\n\ -\n"); - -PyDoc_STRVAR(doc_logical_invert, -"logical_invert($self, /, context=None)\n--\n\n\ -Return the digit-wise inversion of the (logical) operand.\n\ -\n"); - -PyDoc_STRVAR(doc_logical_or, -"logical_or($self, /, other, context=None)\n--\n\n\ -Return the digit-wise 'or' of the two (logical) operands.\n\ -\n"); - -PyDoc_STRVAR(doc_logical_xor, -"logical_xor($self, /, other, context=None)\n--\n\n\ -Return the digit-wise 'exclusive or' of the two (logical) operands.\n\ -\n"); - -PyDoc_STRVAR(doc_max, -"max($self, /, other, context=None)\n--\n\n\ -Maximum of self and other. If one operand is a quiet NaN and the other is\n\ -numeric, the numeric operand is returned.\n\ -\n"); - -PyDoc_STRVAR(doc_max_mag, -"max_mag($self, /, other, context=None)\n--\n\n\ -Similar to the max() method, but the comparison is done using the absolute\n\ -values of the operands.\n\ -\n"); - -PyDoc_STRVAR(doc_min, -"min($self, /, other, context=None)\n--\n\n\ -Minimum of self and other. If one operand is a quiet NaN and the other is\n\ -numeric, the numeric operand is returned.\n\ -\n"); - -PyDoc_STRVAR(doc_min_mag, -"min_mag($self, /, other, context=None)\n--\n\n\ -Similar to the min() method, but the comparison is done using the absolute\n\ -values of the operands.\n\ -\n"); - -PyDoc_STRVAR(doc_next_minus, -"next_minus($self, /, context=None)\n--\n\n\ -Return the largest number representable in the given context (or in the\n\ -current default context if no context is given) that is smaller than the\n\ -given operand.\n\ -\n"); - -PyDoc_STRVAR(doc_next_plus, -"next_plus($self, /, context=None)\n--\n\n\ -Return the smallest number representable in the given context (or in the\n\ -current default context if no context is given) that is larger than the\n\ -given operand.\n\ -\n"); - -PyDoc_STRVAR(doc_next_toward, -"next_toward($self, /, other, context=None)\n--\n\n\ -If the two operands are unequal, return the number closest to the first\n\ -operand in the direction of the second operand. If both operands are\n\ -numerically equal, return a copy of the first operand with the sign set\n\ -to be the same as the sign of the second operand.\n\ -\n"); - -PyDoc_STRVAR(doc_normalize, -"normalize($self, /, context=None)\n--\n\n\ -Normalize the number by stripping the rightmost trailing zeros and\n\ -converting any result equal to Decimal('0') to Decimal('0e0'). Used\n\ -for producing canonical values for members of an equivalence class.\n\ -For example, Decimal('32.100') and Decimal('0.321000e+2') both normalize\n\ -to the equivalent value Decimal('32.1').\n\ -\n"); - -PyDoc_STRVAR(doc_remainder_near, -"remainder_near($self, /, other, context=None)\n--\n\n\ -Return the remainder from dividing self by other. This differs from\n\ -self % other in that the sign of the remainder is chosen so as to minimize\n\ -its absolute value. More precisely, the return value is self - n * other\n\ -where n is the integer nearest to the exact value of self / other, and\n\ -if two integers are equally near then the even one is chosen.\n\ -\n\ -If the result is zero then its sign will be the sign of self.\n\ -\n"); - -PyDoc_STRVAR(doc_rotate, -"rotate($self, /, other, context=None)\n--\n\n\ -Return the result of rotating the digits of the first operand by an amount\n\ -specified by the second operand. The second operand must be an integer in\n\ -the range -precision through precision. The absolute value of the second\n\ -operand gives the number of places to rotate. If the second operand is\n\ -positive then rotation is to the left; otherwise rotation is to the right.\n\ -The coefficient of the first operand is padded on the left with zeros to\n\ -length precision if necessary. The sign and exponent of the first operand are\n\ -unchanged.\n\ -\n"); - -PyDoc_STRVAR(doc_scaleb, -"scaleb($self, /, other, context=None)\n--\n\n\ -Return the first operand with the exponent adjusted the second. Equivalently,\n\ -return the first operand multiplied by 10**other. The second operand must be\n\ -an integer.\n\ -\n"); - -PyDoc_STRVAR(doc_shift, -"shift($self, /, other, context=None)\n--\n\n\ -Return the result of shifting the digits of the first operand by an amount\n\ -specified by the second operand. The second operand must be an integer in\n\ -the range -precision through precision. The absolute value of the second\n\ -operand gives the number of places to shift. If the second operand is\n\ -positive, then the shift is to the left; otherwise the shift is to the\n\ -right. Digits shifted into the coefficient are zeros. The sign and exponent\n\ -of the first operand are unchanged.\n\ -\n"); - -PyDoc_STRVAR(doc_sqrt, -"sqrt($self, /, context=None)\n--\n\n\ -Return the square root of the argument to full precision. The result is\n\ -correctly rounded using the ROUND_HALF_EVEN rounding mode.\n\ -\n"); - - /******************************************************************************/ /* Context Object and Methods */ /******************************************************************************/ diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h index 016af258d63dea..658cb1c2ac3207 100644 --- a/Modules/clinic/zlibmodule.c.h +++ b/Modules/clinic/zlibmodule.c.h @@ -898,7 +898,7 @@ zlib_Decompress_flush(PyObject *self, PyTypeObject *cls, PyObject *const *args, return return_value; } -PyDoc_STRVAR(zlib_ZlibDecompressor_decompress__doc__, +PyDoc_STRVAR(zlib__ZlibDecompressor_decompress__doc__, "decompress($self, /, data, max_length=-1)\n" "--\n" "\n" @@ -917,15 +917,16 @@ PyDoc_STRVAR(zlib_ZlibDecompressor_decompress__doc__, "EOFError. Any data found after the end of the stream is ignored and saved in\n" "the unused_data attribute."); -#define ZLIB_ZLIBDECOMPRESSOR_DECOMPRESS_METHODDEF \ - {"decompress", _PyCFunction_CAST(zlib_ZlibDecompressor_decompress), METH_FASTCALL|METH_KEYWORDS, zlib_ZlibDecompressor_decompress__doc__}, +#define ZLIB__ZLIBDECOMPRESSOR_DECOMPRESS_METHODDEF \ + {"decompress", _PyCFunction_CAST(zlib__ZlibDecompressor_decompress), METH_FASTCALL|METH_KEYWORDS, zlib__ZlibDecompressor_decompress__doc__}, static PyObject * -zlib_ZlibDecompressor_decompress_impl(ZlibDecompressor *self, - Py_buffer *data, Py_ssize_t max_length); +zlib__ZlibDecompressor_decompress_impl(ZlibDecompressor *self, + Py_buffer *data, + Py_ssize_t max_length); static PyObject * -zlib_ZlibDecompressor_decompress(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +zlib__ZlibDecompressor_decompress(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) @@ -984,7 +985,7 @@ zlib_ZlibDecompressor_decompress(PyObject *self, PyObject *const *args, Py_ssize max_length = ival; } skip_optional_pos: - return_value = zlib_ZlibDecompressor_decompress_impl((ZlibDecompressor *)self, &data, max_length); + return_value = zlib__ZlibDecompressor_decompress_impl((ZlibDecompressor *)self, &data, max_length); exit: /* Cleanup for data */ @@ -995,6 +996,86 @@ zlib_ZlibDecompressor_decompress(PyObject *self, PyObject *const *args, Py_ssize return return_value; } +PyDoc_STRVAR(zlib__ZlibDecompressor__doc__, +"_ZlibDecompressor(wbits=MAX_WBITS, zdict=b\'\')\n" +"--\n" +"\n" +"Create a decompressor object for decompressing data incrementally.\n" +"\n" +" zdict\n" +" The predefined compression dictionary. This is a sequence of bytes\n" +" (such as a bytes object) containing subsequences that are expected\n" +" to occur frequently in the data that is to be compressed. Those\n" +" subsequences that are expected to be most common should come at the\n" +" end of the dictionary. This must be the same dictionary as used by the\n" +" compressor that produced the input data."); + +static PyObject * +zlib__ZlibDecompressor_impl(PyTypeObject *type, int wbits, PyObject *zdict); + +static PyObject * +zlib__ZlibDecompressor(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(wbits), &_Py_ID(zdict), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"wbits", "zdict", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_ZlibDecompressor", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; + int wbits = MAX_WBITS; + PyObject *zdict = NULL; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, + /*minpos*/ 0, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[0]) { + wbits = PyLong_AsInt(fastargs[0]); + if (wbits == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + zdict = fastargs[1]; +skip_optional_pos: + return_value = zlib__ZlibDecompressor_impl(type, wbits, zdict); + +exit: + return return_value; +} + PyDoc_STRVAR(zlib_adler32__doc__, "adler32($module, data, value=1, /)\n" "--\n" @@ -1311,4 +1392,4 @@ zlib_crc32_combine(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #ifndef ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #endif /* !defined(ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF) */ -/*[clinic end generated code: output=3054c8894aa44568 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=59184b81fea41d3d input=a9049054013a1b77]*/ diff --git a/Modules/resource.c b/Modules/resource.c index 263730288c3dcf..a463355f424d48 100644 --- a/Modules/resource.c +++ b/Modules/resource.c @@ -522,9 +522,38 @@ resource_exec(PyObject *module) ADD_INT(module, RLIMIT_KQUEUES); #endif +#ifdef RLIMIT_NTHR + ADD_INT(module, RLIMIT_NTHR); +#endif + +#ifdef RLIMIT_THREADS + ADD_INT(module, RLIMIT_THREADS); +#endif + +#ifdef RLIMIT_UMTXP + ADD_INT(module, RLIMIT_UMTXP); +#endif + +#ifdef RLIMIT_PIPEBUF + ADD_INT(module, RLIMIT_PIPEBUF); +#endif + if (PyModule_Add(module, "RLIM_INFINITY", rlim2py(RLIM_INFINITY)) < 0) { return -1; } + +#ifdef RLIM_SAVED_CUR + if (PyModule_Add(module, "RLIM_SAVED_CUR", rlim2py(RLIM_SAVED_CUR)) < 0) { + return -1; + } +#endif + +#ifdef RLIM_SAVED_MAX + if (PyModule_Add(module, "RLIM_SAVED_MAX", rlim2py(RLIM_SAVED_MAX)) < 0) { + return -1; + } +#endif + return 0; #undef ADD_INT diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c index abc7a64d2daef3..e88c9de93ba2b7 100644 --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -1369,9 +1369,9 @@ typedef struct { } ZlibDecompressor; /*[clinic input] -class zlib.ZlibDecompressor "ZlibDecompressor *" "&ZlibDecompressorType" +class zlib._ZlibDecompressor "ZlibDecompressor *" "&ZlibDecompressorType" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=0658178ab94645df]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=49151d1d703e6bcc]*/ static void ZlibDecompressor_dealloc(PyObject *op) @@ -1670,7 +1670,7 @@ decompress(ZlibDecompressor *self, uint8_t *data, /*[clinic input] @permit_long_docstring_body -zlib.ZlibDecompressor.decompress +zlib._ZlibDecompressor.decompress data: Py_buffer max_length: Py_ssize_t=-1 @@ -1692,9 +1692,10 @@ the unused_data attribute. [clinic start generated code]*/ static PyObject * -zlib_ZlibDecompressor_decompress_impl(ZlibDecompressor *self, - Py_buffer *data, Py_ssize_t max_length) -/*[clinic end generated code: output=990d32787b775f85 input=fcf9f974de5d02b1]*/ +zlib__ZlibDecompressor_decompress_impl(ZlibDecompressor *self, + Py_buffer *data, + Py_ssize_t max_length) +/*[clinic end generated code: output=ac00dcf73e843e99 input=c9278e791be1152b]*/ { PyObject *result = NULL; @@ -1710,38 +1711,28 @@ zlib_ZlibDecompressor_decompress_impl(ZlibDecompressor *self, return result; } -PyDoc_STRVAR(ZlibDecompressor__new____doc__, -"_ZlibDecompressor(wbits=15, zdict=b\'\')\n" -"--\n" -"\n" -"Create a decompressor object for decompressing data incrementally.\n" -"\n" -" wbits = 15\n" -" zdict\n" -" The predefined compression dictionary. This is a sequence of bytes\n" -" (such as a bytes object) containing subsequences that are expected\n" -" to occur frequently in the data that is to be compressed. Those\n" -" subsequences that are expected to be most common should come at the\n" -" end of the dictionary. This must be the same dictionary as used by the\n" -" compressor that produced the input data.\n" -"\n"); +/*[clinic input] +@classmethod +zlib._ZlibDecompressor.__new__ + + wbits: int(c_default='MAX_WBITS') = MAX_WBITS + zdict: object(c_default='NULL') = b'' + The predefined compression dictionary. This is a sequence of bytes + (such as a bytes object) containing subsequences that are expected + to occur frequently in the data that is to be compressed. Those + subsequences that are expected to be most common should come at the + end of the dictionary. This must be the same dictionary as used by the + compressor that produced the input data. + +Create a decompressor object for decompressing data incrementally. +[clinic start generated code]*/ static PyObject * -ZlibDecompressor__new__(PyTypeObject *cls, - PyObject *args, - PyObject *kwargs) +zlib__ZlibDecompressor_impl(PyTypeObject *type, int wbits, PyObject *zdict) +/*[clinic end generated code: output=1065607df0d33baa input=9ebad0be6de226e2]*/ { - static char *keywords[] = {"wbits", "zdict", NULL}; - static const char * const format = "|iO:_ZlibDecompressor"; - int wbits = MAX_WBITS; - PyObject *zdict = NULL; - zlibstate *state = PyType_GetModuleState(cls); - - if (!PyArg_ParseTupleAndKeywords( - args, kwargs, format, keywords, &wbits, &zdict)) { - return NULL; - } - ZlibDecompressor *self = PyObject_New(ZlibDecompressor, cls); + zlibstate *state = PyType_GetModuleState(type); + ZlibDecompressor *self = PyObject_New(ZlibDecompressor, type); if (self == NULL) { return NULL; } @@ -1817,7 +1808,7 @@ static PyMethodDef Decomp_methods[] = }; static PyMethodDef ZlibDecompressor_methods[] = { - ZLIB_ZLIBDECOMPRESSOR_DECOMPRESS_METHODDEF + ZLIB__ZLIBDECOMPRESSOR_DECOMPRESS_METHODDEF {NULL} }; @@ -2052,8 +2043,8 @@ static PyType_Spec Decomptype_spec = { static PyType_Slot ZlibDecompressor_type_slots[] = { {Py_tp_dealloc, ZlibDecompressor_dealloc}, {Py_tp_members, ZlibDecompressor_members}, - {Py_tp_new, ZlibDecompressor__new__}, - {Py_tp_doc, (char *)ZlibDecompressor__new____doc__}, + {Py_tp_new, zlib__ZlibDecompressor}, + {Py_tp_doc, (char *)zlib__ZlibDecompressor__doc__}, {Py_tp_methods, ZlibDecompressor_methods}, {0, 0}, }; diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 8a60e48cd465b5..21bae689320eae 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -4721,6 +4721,7 @@ dummy_func( unused/1 + // Skip over the counter _CHECK_PEP_523 + _CHECK_FUNCTION_VERSION_KW + + _CHECK_RECURSION_REMAINING + _PY_FRAME_KW + _SAVE_RETURN_OFFSET + _PUSH_FRAME; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index d63225bb0cd3cd..b6d183a3e63a9c 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -3277,6 +3277,14 @@ JUMP_TO_PREDICTED(CALL_KW); } } + // _CHECK_RECURSION_REMAINING + { + if (tstate->py_recursion_remaining <= 1) { + UPDATE_MISS_STATS(CALL_KW); + assert(_PyOpcode_Deopt[opcode] == (CALL_KW)); + JUMP_TO_PREDICTED(CALL_KW); + } + } // _PY_FRAME_KW { kwnames = stack_pointer[-1];