gh-132775: Add _PyCode_ReturnsOnlyNone() (gh-132981)

The function indicates whether or not the function has a return statement.

This is used by a later change related treating some functions like scripts.
This commit is contained in:
Eric Snow 2025-04-28 20:12:52 -06:00 committed by GitHub
parent 75cbb8d89e
commit 96a7fb93a8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 123 additions and 1 deletions

View file

@ -216,6 +216,10 @@
from test.support.bytecode_helper import instructions_with_positions
from opcode import opmap, opname
from _testcapi import code_offset_to_line
try:
import _testinternalcapi
except ModuleNotFoundError:
_testinternalcapi = None
COPY_FREE_VARS = opmap['COPY_FREE_VARS']
@ -425,6 +429,61 @@ def func():
with self.assertWarns(DeprecationWarning):
func.__code__.co_lnotab
@unittest.skipIf(_testinternalcapi is None, '_testinternalcapi is missing')
def test_returns_only_none(self):
value = True
def spam1():
pass
def spam2():
return
def spam3():
return None
def spam4():
if not value:
return
...
def spam5():
if not value:
return None
...
lambda1 = (lambda: None)
for func in [
spam1,
spam2,
spam3,
spam4,
spam5,
lambda1,
]:
with self.subTest(func):
res = _testinternalcapi.code_returns_only_none(func.__code__)
self.assertTrue(res)
def spam6():
return True
def spam7():
return value
def spam8():
if value:
return None
return True
def spam9():
if value:
return True
return None
lambda2 = (lambda: True)
for func in [
spam6,
spam7,
spam8,
spam9,
lambda2,
]:
with self.subTest(func):
res = _testinternalcapi.code_returns_only_none(func.__code__)
self.assertFalse(res)
def test_invalid_bytecode(self):
def foo():
pass