I need to detect whether a function is an empty definition or not. It can be like:
def foo():
pass
or like:
def foo(i, *arg, **kwargs):
pass
or like:
foo = lambda x: None
What is the most elegant way to detect them using the 'inspect' module? Is there a better way than this:
def isEmptyFunction(func):
e = lambda: None
return func.__code__.co_code == e.__code__.co_code
The method you propose does not quite work because empty functions that have docstrings have a slightly different bytecode.
The value of
func.__code__.co_code
for an empty function with no docstring is'd\x00\x00S'
, while the value of it for a function with a docstring is'd\x01\x00S'
.For my purposes, it works just to add the additional case to test for:
To answer the original question: I don't think there is a better way, but definitely a more resilient one.
Building on top of this answer by @kcon:
which fails for the following:
as well as for lambdas:
I built an extended version which also checks constants with the exception of docstrings:
Testing:
Why would you do that? It looks like bad design. I would bet you wouldn't make anything faster.
It seems like it is magnitude slower to compare than to just do call, because there were 10 times more loops in the latter timeit. The equals operator actually is surely calls a.code.co_code.eq. So you are just making things slower.
The way you're using works. A perhaps more "elegant" solution would be to have a list of functions, and in all your empty (or all your non-empty) functions you would add it to the list, and then check whether the function is in the list or not.