classification
Title: isbuiltin, isroutine, etc.
Type: Stage:
Components: Documentation Versions: Python 3.4, Python 3.5
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: docs@python Nosy List: abarnert, docs@python, yselivanov
Priority: normal Keywords:

Created on 2015-02-26 06:03 by abarnert, last changed 2015-02-28 05:51 by berker.peksag.

Messages (1)
msg236649 - (view) Author: Andrew Barnert (abarnert) * Date: 2015-02-26 06:03
The documentation and implementation for `inspect.isbuiltin` and related functions do not match. While #4968 attempted to clarify things to make the documentation match the behavior, the actual committed changes are still wrong.

`isbuiltin` says "Return true if the object is a built-in function or a bound built-in method", but it returns false for bound built-in special methods (e.g., `[].__add__`). That's because it's implemented as `isinstance(types.BuiltinFunctionType)`, but bound special methods are a different type (`method-wrapper`). Terry Reedy's suggested fix from #4968 ("... or a bound built-in non-special method") would fix this, but the committed change didn't.

The docstring has a further problem; it says that anything that passes will have a `__self__` with "instance to which a method is bound, or None", but for functions, the `__self__` is usually the module the `PyMethodDef` comes from, not `None`. (For example, `sum.__self__` is the`'builtins` module.)

`isroutine` says "Return true if the object is a user-defined or built-in function or method." (The docstring instead says "… any kind of function or method.") But it returns false for built-in bound special methods (`[].__add__`). That's because it's implemented as `isbuiltin` or `isfunction` or `ismethod` or `ismethoddescriptor`; while `isbuiltin` picks up functions and bound non-special methods, and `ismethoddescriptor` picks up unbound special and non-special methods, nothing picks up bound special methods.

A doc-only fix for this, along with Terry's suggested fix for `isbuiltin`, would be "Return true if the object is a user-defined function or method, or a built-in function, unbound method, or bound non-special method." That sounds horrible, but that's because it actually is a horrible test in the first place.

A better fix would be to make `isbuiltin` handle both kinds of bound method. Then `isroutine` is correct as written, and both are documented correctly. (Note that there is no type in `types` corresponding to `method-wrapper`, so either `types` or `inspect` would have to add something like `BuiltinSpecialMethodType = type([].__add__)`.)

It would be even better to fix this at the source and clean up the types of builtin functions and methods, but that boat sailed with 3.0, so...
History
Date User Action Args
2015-02-28 05:51:26berker.peksagsetnosy: + yselivanov
2015-02-26 06:03:25abarnertcreate