Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 048afd9

Browse files
committed
Remove CALL_PROFILE special build
Issue #28799: * Remove the PyEval_GetCallStats() function. * Deprecate the untested and undocumented sys.callstats() function. * Remove the CALL_PROFILE special build Use the sys.setprofile() function, cProfile or profile module to profile function calls.
1 parent 214678e commit 048afd9

5 files changed

Lines changed: 19 additions & 133 deletions

File tree

Doc/c-api/init.rst

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,46 +1147,6 @@ Python-level trace functions in previous versions.
11471147
:c:func:`PyEval_SetProfile`, except the tracing function does receive line-number
11481148
events.
11491149
1150-
.. c:function:: PyObject* PyEval_GetCallStats(PyObject *self)
1151-
1152-
Return a tuple of function call counts. There are constants defined for the
1153-
positions within the tuple:
1154-
1155-
+-------------------------------+-------+
1156-
| Name | Value |
1157-
+===============================+=======+
1158-
| :const:`PCALL_ALL` | 0 |
1159-
+-------------------------------+-------+
1160-
| :const:`PCALL_FUNCTION` | 1 |
1161-
+-------------------------------+-------+
1162-
| :const:`PCALL_FAST_FUNCTION` | 2 |
1163-
+-------------------------------+-------+
1164-
| :const:`PCALL_FASTER_FUNCTION`| 3 |
1165-
+-------------------------------+-------+
1166-
| :const:`PCALL_METHOD` | 4 |
1167-
+-------------------------------+-------+
1168-
| :const:`PCALL_BOUND_METHOD` | 5 |
1169-
+-------------------------------+-------+
1170-
| :const:`PCALL_CFUNCTION` | 6 |
1171-
+-------------------------------+-------+
1172-
| :const:`PCALL_TYPE` | 7 |
1173-
+-------------------------------+-------+
1174-
| :const:`PCALL_GENERATOR` | 8 |
1175-
+-------------------------------+-------+
1176-
| :const:`PCALL_OTHER` | 9 |
1177-
+-------------------------------+-------+
1178-
| :const:`PCALL_POP` | 10 |
1179-
+-------------------------------+-------+
1180-
1181-
:const:`PCALL_FAST_FUNCTION` means no argument tuple needs to be created.
1182-
:const:`PCALL_FASTER_FUNCTION` means that the fast-path frame setup code is used.
1183-
1184-
If there is a method call where the call can be optimized by changing
1185-
the argument tuple and calling the function directly, it gets recorded
1186-
twice.
1187-
1188-
This function is only present if Python is compiled with :const:`CALL_PROFILE`
1189-
defined.
11901150
11911151
.. _advanced-debugging:
11921152

Include/ceval.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ PyAPI_DATA(int) _Py_CheckRecursionLimit;
120120
PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *);
121121
PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *);
122122

123-
PyAPI_FUNC(PyObject *) PyEval_GetCallStats(PyObject *);
124123
PyAPI_FUNC(PyObject *) PyEval_EvalFrame(struct _frame *);
125124
PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(struct _frame *f, int exc);
126125
#ifndef Py_LIMITED_API

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ What's New in Python 3.7.0 alpha 1
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #28799: Remove the ``PyEval_GetCallStats()`` function and deprecate
14+
the untested and undocumented ``sys.callstats()`` function. Remove the
15+
``CALL_PROFILE`` special build: use the :func:`sys.setprofile` function,
16+
:mod:`cProfile` or :mod:`profile` to profile function calls.
17+
1318
- Issue #12844: More than 255 arguments can now be passed to a function.
1419

1520
- Issue #28782: Fix a bug in the implementation ``yield from`` when checking

Python/ceval.c

Lines changed: 0 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -83,63 +83,6 @@ static long dxp[256];
8383
#endif
8484
#endif
8585

86-
/* Function call profile */
87-
#ifdef CALL_PROFILE
88-
#define PCALL_NUM 11
89-
static int pcall[PCALL_NUM];
90-
91-
#define PCALL_ALL 0
92-
#define PCALL_FUNCTION 1
93-
#define PCALL_FAST_FUNCTION 2
94-
#define PCALL_FASTER_FUNCTION 3
95-
#define PCALL_METHOD 4
96-
#define PCALL_BOUND_METHOD 5
97-
#define PCALL_CFUNCTION 6
98-
#define PCALL_TYPE 7
99-
#define PCALL_GENERATOR 8
100-
#define PCALL_OTHER 9
101-
#define PCALL_POP 10
102-
103-
/* Notes about the statistics
104-
105-
PCALL_FAST stats
106-
107-
FAST_FUNCTION means no argument tuple needs to be created.
108-
FASTER_FUNCTION means that the fast-path frame setup code is used.
109-
110-
If there is a method call where the call can be optimized by changing
111-
the argument tuple and calling the function directly, it gets recorded
112-
twice.
113-
114-
As a result, the relationship among the statistics appears to be
115-
PCALL_ALL == PCALL_FUNCTION + PCALL_METHOD - PCALL_BOUND_METHOD +
116-
PCALL_CFUNCTION + PCALL_TYPE + PCALL_GENERATOR + PCALL_OTHER
117-
PCALL_FUNCTION > PCALL_FAST_FUNCTION > PCALL_FASTER_FUNCTION
118-
PCALL_METHOD > PCALL_BOUND_METHOD
119-
*/
120-
121-
#define PCALL(POS) pcall[POS]++
122-
123-
PyObject *
124-
PyEval_GetCallStats(PyObject *self)
125-
{
126-
return Py_BuildValue("iiiiiiiiiii",
127-
pcall[0], pcall[1], pcall[2], pcall[3],
128-
pcall[4], pcall[5], pcall[6], pcall[7],
129-
pcall[8], pcall[9], pcall[10]);
130-
}
131-
#else
132-
#define PCALL(O)
133-
134-
PyObject *
135-
PyEval_GetCallStats(PyObject *self)
136-
{
137-
Py_INCREF(Py_None);
138-
return Py_None;
139-
}
140-
#endif
141-
142-
14386
#ifdef WITH_THREAD
14487
#define GIL_REQUEST _Py_atomic_load_relaxed(&gil_drop_request)
14588
#else
@@ -3278,7 +3221,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
32783221
PREDICTED(CALL_FUNCTION);
32793222
TARGET(CALL_FUNCTION) {
32803223
PyObject **sp, *res;
3281-
PCALL(PCALL_ALL);
32823224
sp = stack_pointer;
32833225
res = call_function(&sp, oparg, NULL);
32843226
stack_pointer = sp;
@@ -3294,7 +3236,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
32943236

32953237
names = POP();
32963238
assert(PyTuple_CheckExact(names) && PyTuple_GET_SIZE(names) <= oparg);
3297-
PCALL(PCALL_ALL);
32983239
sp = stack_pointer;
32993240
res = call_function(&sp, oparg, names);
33003241
stack_pointer = sp;
@@ -3309,7 +3250,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
33093250

33103251
TARGET(CALL_FUNCTION_EX) {
33113252
PyObject *func, *callargs, *kwargs = NULL, *result;
3312-
PCALL(PCALL_ALL);
33133253
if (oparg & 0x01) {
33143254
kwargs = POP();
33153255
if (!PyDict_CheckExact(kwargs)) {
@@ -4099,8 +4039,6 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
40994039
* when the generator is resumed. */
41004040
Py_CLEAR(f->f_back);
41014041

4102-
PCALL(PCALL_GENERATOR);
4103-
41044042
/* Create a new generator that owns the ready to run frame
41054043
* and return that as the value. */
41064044
if (is_coro) {
@@ -4793,17 +4731,13 @@ call_function(PyObject ***pp_stack, Py_ssize_t oparg, PyObject *kwnames)
47934731
if (PyCFunction_Check(func)) {
47944732
PyThreadState *tstate = PyThreadState_GET();
47954733

4796-
PCALL(PCALL_CFUNCTION);
4797-
47984734
stack = (*pp_stack) - nargs - nkwargs;
47994735
C_TRACE(x, _PyCFunction_FastCallKeywords(func, stack, nargs, kwnames));
48004736
}
48014737
else {
48024738
if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {
48034739
/* optimize access to bound methods */
48044740
PyObject *self = PyMethod_GET_SELF(func);
4805-
PCALL(PCALL_METHOD);
4806-
PCALL(PCALL_BOUND_METHOD);
48074741
Py_INCREF(self);
48084742
func = PyMethod_GET_FUNCTION(func);
48094743
Py_INCREF(func);
@@ -4835,7 +4769,6 @@ call_function(PyObject ***pp_stack, Py_ssize_t oparg, PyObject *kwnames)
48354769
while ((*pp_stack) > pfunc) {
48364770
w = EXT_POP(*pp_stack);
48374771
Py_DECREF(w);
4838-
PCALL(PCALL_POP);
48394772
}
48404773

48414774
return x;
@@ -4860,7 +4793,6 @@ _PyFunction_FastCall(PyCodeObject *co, PyObject **args, Py_ssize_t nargs,
48604793
Py_ssize_t i;
48614794
PyObject *result;
48624795

4863-
PCALL(PCALL_FASTER_FUNCTION);
48644796
assert(globals != NULL);
48654797
/* XXX Perhaps we should create a specialized
48664798
PyFrame_New() that doesn't take locals, but does
@@ -4906,9 +4838,6 @@ fast_function(PyObject *func, PyObject **stack,
49064838
/* kwnames must only contains str strings, no subclass, and all keys must
49074839
be unique */
49084840

4909-
PCALL(PCALL_FUNCTION);
4910-
PCALL(PCALL_FAST_FUNCTION);
4911-
49124841
if (co->co_kwonlyargcount == 0 && nkwargs == 0 &&
49134842
co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE))
49144843
{
@@ -4971,9 +4900,6 @@ _PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs,
49714900
assert(nargs == 0 || args != NULL);
49724901
assert(kwargs == NULL || PyDict_Check(kwargs));
49734902

4974-
PCALL(PCALL_FUNCTION);
4975-
PCALL(PCALL_FAST_FUNCTION);
4976-
49774903
if (co->co_kwonlyargcount == 0 &&
49784904
(kwargs == NULL || PyDict_Size(kwargs) == 0) &&
49794905
co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE))
@@ -5041,23 +4967,6 @@ _PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs,
50414967
static PyObject *
50424968
do_call_core(PyObject *func, PyObject *callargs, PyObject *kwdict)
50434969
{
5044-
#ifdef CALL_PROFILE
5045-
/* At this point, we have to look at the type of func to
5046-
update the call stats properly. Do it here so as to avoid
5047-
exposing the call stats machinery outside ceval.c
5048-
*/
5049-
if (PyFunction_Check(func))
5050-
PCALL(PCALL_FUNCTION);
5051-
else if (PyMethod_Check(func))
5052-
PCALL(PCALL_METHOD);
5053-
else if (PyType_Check(func))
5054-
PCALL(PCALL_TYPE);
5055-
else if (PyCFunction_Check(func))
5056-
PCALL(PCALL_CFUNCTION);
5057-
else
5058-
PCALL(PCALL_OTHER);
5059-
#endif
5060-
50614970
if (PyCFunction_Check(func)) {
50624971
PyObject *result;
50634972
PyThreadState *tstate = PyThreadState_GET();

Python/sysmodule.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1287,6 +1287,19 @@ a 11-tuple where the entries in the tuple are counts of:\n\
12871287
10. Number of stack pops performed by call_function()"
12881288
);
12891289

1290+
static PyObject *
1291+
sys_callstats(PyObject *self)
1292+
{
1293+
if (PyErr_WarnEx(PyExc_DeprecationWarning,
1294+
"sys.callstats() has been deprecated in Python 3.7 "
1295+
"and will be removed in the future", 1) < 0) {
1296+
return NULL;
1297+
}
1298+
1299+
Py_RETURN_NONE;
1300+
}
1301+
1302+
12901303
#ifdef __cplusplus
12911304
extern "C" {
12921305
#endif
@@ -1352,7 +1365,7 @@ Return True if Python is exiting.");
13521365

13531366
static PyMethodDef sys_methods[] = {
13541367
/* Might as well keep this in alphabetic order */
1355-
{"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS,
1368+
{"callstats", (PyCFunction)sys_callstats, METH_NOARGS,
13561369
callstats_doc},
13571370
{"_clear_type_cache", sys_clear_type_cache, METH_NOARGS,
13581371
sys_clear_type_cache__doc__},

0 commit comments

Comments
 (0)