diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h index 2fd7d5d13a98b2..e4f0138e17edfa 100644 --- a/Include/internal/pycore_global_objects_fini_generated.h +++ b/Include/internal/pycore_global_objects_fini_generated.h @@ -1231,6 +1231,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(strict_mode)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(string)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sub_key)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(subcalls)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(symmetric_difference_update)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tabsize)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tag)); @@ -1248,8 +1249,10 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(threading)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(throw)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timeout)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timer)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(times)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timetuple)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timeunit)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(top)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(trace_callback)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(traceback)); diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index fc3871570cc49d..e70f11e2a26cd5 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -720,6 +720,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(strict_mode) STRUCT_FOR_ID(string) STRUCT_FOR_ID(sub_key) + STRUCT_FOR_ID(subcalls) STRUCT_FOR_ID(symmetric_difference_update) STRUCT_FOR_ID(tabsize) STRUCT_FOR_ID(tag) @@ -737,8 +738,10 @@ struct _Py_global_strings { STRUCT_FOR_ID(threading) STRUCT_FOR_ID(throw) STRUCT_FOR_ID(timeout) + STRUCT_FOR_ID(timer) STRUCT_FOR_ID(times) STRUCT_FOR_ID(timetuple) + STRUCT_FOR_ID(timeunit) STRUCT_FOR_ID(top) STRUCT_FOR_ID(trace_callback) STRUCT_FOR_ID(traceback) diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h index 3b80e265b0ca50..5d404c8fd91ca6 100644 --- a/Include/internal/pycore_runtime_init_generated.h +++ b/Include/internal/pycore_runtime_init_generated.h @@ -1229,6 +1229,7 @@ extern "C" { INIT_ID(strict_mode), \ INIT_ID(string), \ INIT_ID(sub_key), \ + INIT_ID(subcalls), \ INIT_ID(symmetric_difference_update), \ INIT_ID(tabsize), \ INIT_ID(tag), \ @@ -1246,8 +1247,10 @@ extern "C" { INIT_ID(threading), \ INIT_ID(throw), \ INIT_ID(timeout), \ + INIT_ID(timer), \ INIT_ID(times), \ INIT_ID(timetuple), \ + INIT_ID(timeunit), \ INIT_ID(top), \ INIT_ID(trace_callback), \ INIT_ID(traceback), \ diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h index eb2eca06ec4d4f..d0bc8d7186c053 100644 --- a/Include/internal/pycore_unicodeobject_generated.h +++ b/Include/internal/pycore_unicodeobject_generated.h @@ -2676,6 +2676,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(subcalls); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(symmetric_difference_update); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -2744,6 +2748,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(timer); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(times); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -2752,6 +2760,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(timeunit); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(top); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index 06958a078509d9..4f996c7230e16d 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -606,29 +606,42 @@ setBuiltins(ProfilerObject *pObj, int nvalue) return 0; } -PyObject* pystart_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size) +/*[clinic input] +_lsprof.Profiler._pystart_callback + + code: object + instruction_offset: object + / + +[clinic start generated code]*/ + +static PyObject * +_lsprof_Profiler__pystart_callback_impl(ProfilerObject *self, PyObject *code, + PyObject *instruction_offset) +/*[clinic end generated code: output=5fec8b7ad5ed25e8 input=b166e6953c579cda]*/ { - if (size < 2) { - PyErr_Format(PyExc_TypeError, - "_pystart_callback expected 2 arguments, got %zd", - size); - return NULL; - } - PyObject* code = args[0]; - ptrace_enter_call((PyObject*)self, (void *)code, (PyObject *)code); + ptrace_enter_call((PyObject*)self, (void *)code, code); Py_RETURN_NONE; } -PyObject* pyreturn_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size) +/*[clinic input] +_lsprof.Profiler._pyreturn_callback + + code: object + instruction_offset: object + retval: object + / + +[clinic start generated code]*/ + +static PyObject * +_lsprof_Profiler__pyreturn_callback_impl(ProfilerObject *self, + PyObject *code, + PyObject *instruction_offset, + PyObject *retval) +/*[clinic end generated code: output=9e2f6fc1b882c51e input=667ffaeb2fa6fd1f]*/ { - if (size < 3) { - PyErr_Format(PyExc_TypeError, - "_pyreturn_callback expected 3 arguments, got %zd", - size); - return NULL; - } - PyObject* code = args[0]; ptrace_leave_call((PyObject*)self, (void *)code); Py_RETURN_NONE; @@ -661,18 +674,24 @@ PyObject* get_cfunc_from_callable(PyObject* callable, PyObject* self_arg, PyObje return NULL; } -PyObject* ccall_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size) +/*[clinic input] +_lsprof.Profiler._ccall_callback + + code: object + instruction_offset: object + callable: object + self_arg: object + / + +[clinic start generated code]*/ + +static PyObject * +_lsprof_Profiler__ccall_callback_impl(ProfilerObject *self, PyObject *code, + PyObject *instruction_offset, + PyObject *callable, PyObject *self_arg) +/*[clinic end generated code: output=152db83cabd18cad input=0e66687cfb95c001]*/ { - if (size < 4) { - PyErr_Format(PyExc_TypeError, - "_ccall_callback expected 4 arguments, got %zd", - size); - return NULL; - } if (self->flags & POF_BUILTINS) { - PyObject* callable = args[2]; - PyObject* self_arg = args[3]; - PyObject* cfunc = get_cfunc_from_callable(callable, self_arg, self->missing); if (cfunc) { @@ -685,18 +704,25 @@ PyObject* ccall_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t Py_RETURN_NONE; } -PyObject* creturn_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size) +/*[clinic input] +_lsprof.Profiler._creturn_callback + + code: object + instruction_offset: object + callable: object + self_arg: object + / + +[clinic start generated code]*/ + +static PyObject * +_lsprof_Profiler__creturn_callback_impl(ProfilerObject *self, PyObject *code, + PyObject *instruction_offset, + PyObject *callable, + PyObject *self_arg) +/*[clinic end generated code: output=1e886dde8fed8fb0 input=b18afe023746923a]*/ { - if (size < 4) { - PyErr_Format(PyExc_TypeError, - "_creturn_callback expected 4 arguments, got %zd", - size); - return NULL; - } if (self->flags & POF_BUILTINS) { - PyObject* callable = args[2]; - PyObject* self_arg = args[3]; - PyObject* cfunc = get_cfunc_from_callable(callable, self_arg, self->missing); if (cfunc) { @@ -724,27 +750,27 @@ static const struct { {0, NULL} }; -PyDoc_STRVAR(enable_doc, "\ -enable(subcalls=True, builtins=True)\n\ -\n\ -Start collecting profiling information.\n\ -If 'subcalls' is True, also records for each function\n\ -statistics separated according to its current caller.\n\ -If 'builtins' is True, records the time spent in\n\ -built-in functions separately from their caller.\n\ -"); - -static PyObject* -profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds) + +/*[clinic input] +_lsprof.Profiler.enable + + subcalls: bool = True + If True, also records for each function + statistics separated according to its current caller. + + builtins: bool = True + If True, records the time spent in + built-in functions separately from their caller. + +Start collecting profiling information. +[clinic start generated code]*/ + +static PyObject * +_lsprof_Profiler_enable_impl(ProfilerObject *self, int subcalls, + int builtins) +/*[clinic end generated code: output=1e747f9dc1edd571 input=9ab81405107ab7f1]*/ { - int subcalls = -1; - int builtins = -1; - static char *kwlist[] = {"subcalls", "builtins", 0}; int all_events = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|pp:enable", - kwlist, &subcalls, &builtins)) - return NULL; if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0) { return NULL; } @@ -800,14 +826,16 @@ flush_unmatched(ProfilerObject *pObj) } -PyDoc_STRVAR(disable_doc, "\ -disable()\n\ -\n\ -Stop collecting profiling information.\n\ -"); -static PyObject* -profiler_disable(ProfilerObject *self, PyObject* noarg) +/*[clinic input] +_lsprof.Profiler.disable + +Stop collecting profiling information. +[clinic start generated code]*/ + +static PyObject * +_lsprof_Profiler_disable_impl(ProfilerObject *self) +/*[clinic end generated code: output=838cffef7f651870 input=05700b3fc68d1f50]*/ { if (self->flags & POF_EXT_TIMER) { PyErr_SetString(PyExc_RuntimeError, @@ -858,21 +886,22 @@ profiler_disable(ProfilerObject *self, PyObject* noarg) Py_RETURN_NONE; } -PyDoc_STRVAR(clear_doc, "\ -clear()\n\ -\n\ -Clear all profiling information collected so far.\n\ -"); +/*[clinic input] +_lsprof.Profiler.clear + +Clear all profiling information collected so far. +[clinic start generated code]*/ -static PyObject* -profiler_clear(ProfilerObject *pObj, PyObject* noarg) +static PyObject * +_lsprof_Profiler_clear_impl(ProfilerObject *self) +/*[clinic end generated code: output=dd1c668fb84b1335 input=fbe1f88c28be4f98]*/ { - if (pObj->flags & POF_EXT_TIMER) { + if (self->flags & POF_EXT_TIMER) { PyErr_SetString(PyExc_RuntimeError, "cannot clear profiler in external timer"); return NULL; } - clearEntries(pObj); + clearEntries(self); Py_RETURN_NONE; } @@ -903,33 +932,40 @@ profiler_dealloc(ProfilerObject *op) Py_DECREF(tp); } +/*[clinic input] +_lsprof.Profiler.__init__ as profiler_init + + timer: object(c_default='NULL') = None + timeunit: double = 0.0 + subcalls: bool = True + builtins: bool = True + +Build a profiler object using the specified timer function. + +The default timer is a fast built-in one based on real time. +For custom timer functions returning integers, 'timeunit' can +be a float specifying a scale (that is, how long each integer unit +is, in seconds). +[clinic start generated code]*/ + static int -profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) +profiler_init_impl(ProfilerObject *self, PyObject *timer, double timeunit, + int subcalls, int builtins) +/*[clinic end generated code: output=ac523803ec9f9df2 input=8285ca746f96a414]*/ { - PyObject *timer = NULL; - double timeunit = 0.0; - int subcalls = 1; - int builtins = 1; - static char *kwlist[] = {"timer", "timeunit", - "subcalls", "builtins", 0}; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "|Odpp:Profiler", kwlist, - &timer, &timeunit, - &subcalls, &builtins)) - return -1; - - if (setSubcalls(pObj, subcalls) < 0 || setBuiltins(pObj, builtins) < 0) + if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0) { return -1; - pObj->externalTimerUnit = timeunit; - Py_XSETREF(pObj->externalTimer, Py_XNewRef(timer)); - pObj->tool_id = PY_MONITORING_PROFILER_ID; + } + self->externalTimerUnit = timeunit; + Py_XSETREF(self->externalTimer, Py_XNewRef(timer)); + self->tool_id = PY_MONITORING_PROFILER_ID; PyObject* monitoring = _PyImport_GetModuleAttrString("sys", "monitoring"); if (!monitoring) { return -1; } - pObj->missing = PyObject_GetAttrString(monitoring, "MISSING"); - if (!pObj->missing) { + self->missing = PyObject_GetAttrString(monitoring, "MISSING"); + if (!self->missing) { Py_DECREF(monitoring); return -1; } @@ -939,35 +975,18 @@ profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) static PyMethodDef profiler_methods[] = { _LSPROF_PROFILER_GETSTATS_METHODDEF - {"enable", _PyCFunction_CAST(profiler_enable), - METH_VARARGS | METH_KEYWORDS, enable_doc}, - {"disable", (PyCFunction)profiler_disable, - METH_NOARGS, disable_doc}, - {"clear", (PyCFunction)profiler_clear, - METH_NOARGS, clear_doc}, - {"_pystart_callback", _PyCFunction_CAST(pystart_callback), - METH_FASTCALL, NULL}, - {"_pyreturn_callback", _PyCFunction_CAST(pyreturn_callback), - METH_FASTCALL, NULL}, - {"_ccall_callback", _PyCFunction_CAST(ccall_callback), - METH_FASTCALL, NULL}, - {"_creturn_callback", _PyCFunction_CAST(creturn_callback), - METH_FASTCALL, NULL}, + _LSPROF_PROFILER_ENABLE_METHODDEF + _LSPROF_PROFILER_DISABLE_METHODDEF + _LSPROF_PROFILER_CLEAR_METHODDEF + _LSPROF_PROFILER__PYSTART_CALLBACK_METHODDEF + _LSPROF_PROFILER__PYRETURN_CALLBACK_METHODDEF + _LSPROF_PROFILER__CCALL_CALLBACK_METHODDEF + _LSPROF_PROFILER__CRETURN_CALLBACK_METHODDEF {NULL, NULL} }; -PyDoc_STRVAR(profiler_doc, "\ -Profiler(timer=None, timeunit=None, subcalls=True, builtins=True)\n\ -\n\ - Builds a profiler object using the specified timer function.\n\ - The default timer is a fast built-in one based on real time.\n\ - For custom timer functions returning integers, timeunit can\n\ - be a float specifying a scale (i.e. how long each integer unit\n\ - is, in seconds).\n\ -"); - static PyType_Slot _lsprof_profiler_type_spec_slots[] = { - {Py_tp_doc, (void *)profiler_doc}, + {Py_tp_doc, (void *)profiler_init__doc__}, {Py_tp_methods, profiler_methods}, {Py_tp_dealloc, profiler_dealloc}, {Py_tp_init, profiler_init}, diff --git a/Modules/clinic/_lsprof.c.h b/Modules/clinic/_lsprof.c.h index b3b7fda5660bfd..234cc9ef3c0eaf 100644 --- a/Modules/clinic/_lsprof.c.h +++ b/Modules/clinic/_lsprof.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(_lsprof_Profiler_getstats__doc__, "getstats($self, /)\n" "--\n" @@ -45,4 +51,358 @@ _lsprof_Profiler_getstats(ProfilerObject *self, PyTypeObject *cls, PyObject *con } return _lsprof_Profiler_getstats_impl(self, cls); } -/*[clinic end generated code: output=5c9d87d89863dc83 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_lsprof_Profiler__pystart_callback__doc__, +"_pystart_callback($self, code, instruction_offset, /)\n" +"--\n" +"\n"); + +#define _LSPROF_PROFILER__PYSTART_CALLBACK_METHODDEF \ + {"_pystart_callback", _PyCFunction_CAST(_lsprof_Profiler__pystart_callback), METH_FASTCALL, _lsprof_Profiler__pystart_callback__doc__}, + +static PyObject * +_lsprof_Profiler__pystart_callback_impl(ProfilerObject *self, PyObject *code, + PyObject *instruction_offset); + +static PyObject * +_lsprof_Profiler__pystart_callback(ProfilerObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *code; + PyObject *instruction_offset; + + if (!_PyArg_CheckPositional("_pystart_callback", nargs, 2, 2)) { + goto exit; + } + code = args[0]; + instruction_offset = args[1]; + return_value = _lsprof_Profiler__pystart_callback_impl(self, code, instruction_offset); + +exit: + return return_value; +} + +PyDoc_STRVAR(_lsprof_Profiler__pyreturn_callback__doc__, +"_pyreturn_callback($self, code, instruction_offset, retval, /)\n" +"--\n" +"\n"); + +#define _LSPROF_PROFILER__PYRETURN_CALLBACK_METHODDEF \ + {"_pyreturn_callback", _PyCFunction_CAST(_lsprof_Profiler__pyreturn_callback), METH_FASTCALL, _lsprof_Profiler__pyreturn_callback__doc__}, + +static PyObject * +_lsprof_Profiler__pyreturn_callback_impl(ProfilerObject *self, + PyObject *code, + PyObject *instruction_offset, + PyObject *retval); + +static PyObject * +_lsprof_Profiler__pyreturn_callback(ProfilerObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *code; + PyObject *instruction_offset; + PyObject *retval; + + if (!_PyArg_CheckPositional("_pyreturn_callback", nargs, 3, 3)) { + goto exit; + } + code = args[0]; + instruction_offset = args[1]; + retval = args[2]; + return_value = _lsprof_Profiler__pyreturn_callback_impl(self, code, instruction_offset, retval); + +exit: + return return_value; +} + +PyDoc_STRVAR(_lsprof_Profiler__ccall_callback__doc__, +"_ccall_callback($self, code, instruction_offset, callable, self_arg, /)\n" +"--\n" +"\n"); + +#define _LSPROF_PROFILER__CCALL_CALLBACK_METHODDEF \ + {"_ccall_callback", _PyCFunction_CAST(_lsprof_Profiler__ccall_callback), METH_FASTCALL, _lsprof_Profiler__ccall_callback__doc__}, + +static PyObject * +_lsprof_Profiler__ccall_callback_impl(ProfilerObject *self, PyObject *code, + PyObject *instruction_offset, + PyObject *callable, PyObject *self_arg); + +static PyObject * +_lsprof_Profiler__ccall_callback(ProfilerObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *code; + PyObject *instruction_offset; + PyObject *callable; + PyObject *self_arg; + + if (!_PyArg_CheckPositional("_ccall_callback", nargs, 4, 4)) { + goto exit; + } + code = args[0]; + instruction_offset = args[1]; + callable = args[2]; + self_arg = args[3]; + return_value = _lsprof_Profiler__ccall_callback_impl(self, code, instruction_offset, callable, self_arg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_lsprof_Profiler__creturn_callback__doc__, +"_creturn_callback($self, code, instruction_offset, callable, self_arg,\n" +" /)\n" +"--\n" +"\n"); + +#define _LSPROF_PROFILER__CRETURN_CALLBACK_METHODDEF \ + {"_creturn_callback", _PyCFunction_CAST(_lsprof_Profiler__creturn_callback), METH_FASTCALL, _lsprof_Profiler__creturn_callback__doc__}, + +static PyObject * +_lsprof_Profiler__creturn_callback_impl(ProfilerObject *self, PyObject *code, + PyObject *instruction_offset, + PyObject *callable, + PyObject *self_arg); + +static PyObject * +_lsprof_Profiler__creturn_callback(ProfilerObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *code; + PyObject *instruction_offset; + PyObject *callable; + PyObject *self_arg; + + if (!_PyArg_CheckPositional("_creturn_callback", nargs, 4, 4)) { + goto exit; + } + code = args[0]; + instruction_offset = args[1]; + callable = args[2]; + self_arg = args[3]; + return_value = _lsprof_Profiler__creturn_callback_impl(self, code, instruction_offset, callable, self_arg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_lsprof_Profiler_enable__doc__, +"enable($self, /, subcalls=True, builtins=True)\n" +"--\n" +"\n" +"Start collecting profiling information.\n" +"\n" +" subcalls\n" +" If True, also records for each function\n" +" statistics separated according to its current caller.\n" +" builtins\n" +" If True, records the time spent in\n" +" built-in functions separately from their caller."); + +#define _LSPROF_PROFILER_ENABLE_METHODDEF \ + {"enable", _PyCFunction_CAST(_lsprof_Profiler_enable), METH_FASTCALL|METH_KEYWORDS, _lsprof_Profiler_enable__doc__}, + +static PyObject * +_lsprof_Profiler_enable_impl(ProfilerObject *self, int subcalls, + int builtins); + +static PyObject * +_lsprof_Profiler_enable(ProfilerObject *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 + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(subcalls), &_Py_ID(builtins), }, + }; + #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[] = {"subcalls", "builtins", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "enable", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int subcalls = 1; + int builtins = 1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + subcalls = PyObject_IsTrue(args[0]); + if (subcalls < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + builtins = PyObject_IsTrue(args[1]); + if (builtins < 0) { + goto exit; + } +skip_optional_pos: + return_value = _lsprof_Profiler_enable_impl(self, subcalls, builtins); + +exit: + return return_value; +} + +PyDoc_STRVAR(_lsprof_Profiler_disable__doc__, +"disable($self, /)\n" +"--\n" +"\n" +"Stop collecting profiling information."); + +#define _LSPROF_PROFILER_DISABLE_METHODDEF \ + {"disable", (PyCFunction)_lsprof_Profiler_disable, METH_NOARGS, _lsprof_Profiler_disable__doc__}, + +static PyObject * +_lsprof_Profiler_disable_impl(ProfilerObject *self); + +static PyObject * +_lsprof_Profiler_disable(ProfilerObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _lsprof_Profiler_disable_impl(self); +} + +PyDoc_STRVAR(_lsprof_Profiler_clear__doc__, +"clear($self, /)\n" +"--\n" +"\n" +"Clear all profiling information collected so far."); + +#define _LSPROF_PROFILER_CLEAR_METHODDEF \ + {"clear", (PyCFunction)_lsprof_Profiler_clear, METH_NOARGS, _lsprof_Profiler_clear__doc__}, + +static PyObject * +_lsprof_Profiler_clear_impl(ProfilerObject *self); + +static PyObject * +_lsprof_Profiler_clear(ProfilerObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _lsprof_Profiler_clear_impl(self); +} + +PyDoc_STRVAR(profiler_init__doc__, +"Profiler(timer=None, timeunit=0.0, subcalls=True, builtins=True)\n" +"--\n" +"\n" +"Build a profiler object using the specified timer function.\n" +"\n" +"The default timer is a fast built-in one based on real time.\n" +"For custom timer functions returning integers, \'timeunit\' can\n" +"be a float specifying a scale (that is, how long each integer unit\n" +"is, in seconds)."); + +static int +profiler_init_impl(ProfilerObject *self, PyObject *timer, double timeunit, + int subcalls, int builtins); + +static int +profiler_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(timer), &_Py_ID(timeunit), &_Py_ID(subcalls), &_Py_ID(builtins), }, + }; + #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[] = {"timer", "timeunit", "subcalls", "builtins", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Profiler", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; + PyObject *timer = NULL; + double timeunit = 0.0; + int subcalls = 1; + int builtins = 1; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 4, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[0]) { + timer = fastargs[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[1]) { + if (PyFloat_CheckExact(fastargs[1])) { + timeunit = PyFloat_AS_DOUBLE(fastargs[1]); + } + else + { + timeunit = PyFloat_AsDouble(fastargs[1]); + if (timeunit == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[2]) { + subcalls = PyObject_IsTrue(fastargs[2]); + if (subcalls < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + builtins = PyObject_IsTrue(fastargs[3]); + if (builtins < 0) { + goto exit; + } +skip_optional_pos: + return_value = profiler_init_impl((ProfilerObject *)self, timer, timeunit, subcalls, builtins); + +exit: + return return_value; +} +/*[clinic end generated code: output=0b71f52bee9a7bb1 input=a9049054013a1b77]*/