This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: builtin_function_or_method is also either a function or a method
Type: Stage:
Components: Build Versions: Python 3.11
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Dennis Sweeney, apostofes, steven.daprano
Priority: normal Keywords:

Created on 2022-04-04 11:51 by apostofes, last changed 2022-04-11 14:59 by admin.

Messages (5)
msg416664 - (view) Author: apostofes (apostofes) * Date: 2022-04-04 11:51
the.
```
import inspect
inspect.isfunction
```
does not consider a
```
builtin_function_or_method
```
as a function.
for example,
```
inspect.isfunction(abs)
```
gives,
```
False
```
in the background even the builtin `abs` is a function, so shouldn't it return True?

the way this check is implemented is by matching the type of a builtin_function_or_method with,
```
type(len)
```
and since, `type(len)` is `builtin_function_or_method`, so, the `inspect.isfunction` check gives False.
But in my opinion, it should return True, even for builtin functions or methods.
msg416673 - (view) Author: Dennis Sweeney (Dennis Sweeney) * (Python committer) Date: 2022-04-04 14:44
https://docs.python.org/3/library/inspect.html#inspect.isfunction says this:

"""
inspect.isfunction(object)
Return True if the object is a Python function, which includes functions created by a lambda expression.
"""

Emphasis on the "Python function", as in, something written in Python using a `def` statement or a `lambda` expression. If isfunction returns True, you can presumably access function-specific implementation details like the functions's f.__code__ attribute. If you need to check for "anything that works as a function", you can use `callable()`:

>>> callable(lambda: 2)
True
>>> callable(abs)
True
>>> def f(x): return x
>>> callable(f)
True

I'm not an expert on the inspect module, but I'm guessing it's not worth breaking backwards-compatibility to change this behavior.

Would extra emphasis in the documentation have been helpful for you, or were you mostly attempting to rely on the function's name?
msg416680 - (view) Author: apostofes (apostofes) * Date: 2022-04-04 17:20
but `callable` returns `True` for classes with `__call__` also, it does not check whether the argument passed to it is a function or not.

I want some way to return `True` for both builtin functions and Python functions, but not for classes.

And similarly, some way to return `True` for both builtin methods and Python methods.

Should the documentation for `inspect.isfunction` include, `this does not include builtin functions.`, and similarly for `inspect.ismethod`?

Should I create a PR to add these two sentences to the documentation?
msg416682 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2022-04-04 17:33
Perhaps what you want is inspect.isroutine ?

https://docs.python.org/3/library/inspect.html#inspect.isroutine

I agree with Dennis that the isfunction test is for **Python** (def or lambda) functions, not builtins. The docstring for the inspect.is* methods make promises about what attributes an object will have:

def isbuiltin(object):
    """Return true if the object is a built-in function or method.
    Built-in functions and methods provide these attributes:
        __doc__         documentation string
        __name__        original name of this function or method
        __self__        instance to which a method is bound, or None"""


def isfunction(object):
    """Return true if the object is a user-defined function.
    Function objects provide these attributes:
        __doc__         documentation string
        __name__        name with which this function was defined
        __code__        code object containing compiled function bytecode
        __defaults__    tuple of any default values for arguments
        __globals__     global namespace in which this function was defined
        __annotations__ dict of parameter annotations
        __kwdefaults__  dict of keyword only parameters with defaults"""


def (and lambda) functions have a different API from builtin_function_or_method objects. They should be kept separate.
msg416686 - (view) Author: apostofes (apostofes) * Date: 2022-04-04 17:51
yes, I think `inspect.isroutine` does the required functionality.
sorry, I did not know about it, and could not think of the word `routine` when checking for functions.
History
Date User Action Args
2022-04-11 14:59:58adminsetgithub: 91370
2022-04-04 17:51:35apostofessetmessages: + msg416686
2022-04-04 17:33:18steven.dapranosetnosy: + steven.daprano
messages: + msg416682
2022-04-04 17:20:40apostofessetmessages: + msg416680
2022-04-04 14:44:24Dennis Sweeneysetnosy: + Dennis Sweeney
messages: + msg416673
2022-04-04 11:51:09apostofescreate