Skip to content

Commit dc8230d

Browse files
Add _PyCode_Returns().
1 parent 8a4d4f3 commit dc8230d

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

Include/internal/pycore_code.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,10 @@ extern void _Py_ClearTLBCIndex(_PyThreadStateImpl *tstate);
561561
extern int _Py_ClearUnusedTLBC(PyInterpreterState *interp);
562562
#endif
563563

564+
565+
PyAPI_FUNC(int) _PyCode_Returns(PyCodeObject *);
566+
567+
564568
#ifdef __cplusplus
565569
}
566570
#endif

Objects/codeobject.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,6 +1689,46 @@ PyCode_GetFreevars(PyCodeObject *code)
16891689
return _PyCode_GetFreevars(code);
16901690
}
16911691

1692+
1693+
int
1694+
_PyCode_Returns(PyCodeObject *co)
1695+
{
1696+
// Look up None in co_consts.
1697+
Py_ssize_t nconsts = PyTuple_Size(co->co_consts);
1698+
int none_index = 0;
1699+
for (; none_index < nconsts; none_index++) {
1700+
if (PyTuple_GET_ITEM(co->co_consts, none_index) == Py_None) {
1701+
break;
1702+
}
1703+
}
1704+
if (none_index == nconsts) {
1705+
// None wasn't there, which means there was no implicit return,
1706+
// "return", or "return None". That means there must be
1707+
// an explicit return (non-None).
1708+
return 1;
1709+
}
1710+
1711+
// Walk the bytecode, looking for RETURN_VALUE.
1712+
Py_ssize_t len = Py_SIZE(co);
1713+
for (int i = 0; i < len; i++) {
1714+
_Py_CODEUNIT inst = _Py_GetBaseCodeUnit(co, i);
1715+
if (inst.op.code == RETURN_VALUE) {
1716+
assert(i != 0);
1717+
// Ignore it if it returns None.
1718+
_Py_CODEUNIT prev = _Py_GetBaseCodeUnit(co, i-1);
1719+
if (prev.op.code == LOAD_CONST) {
1720+
// We don't worry about EXTENDED_ARG for now.
1721+
if (prev.op.arg == none_index) {
1722+
continue;
1723+
}
1724+
}
1725+
return 1;
1726+
}
1727+
}
1728+
return 0;
1729+
}
1730+
1731+
16921732
#ifdef _Py_TIER2
16931733

16941734
static void

0 commit comments

Comments
 (0)