Title: Add instancemethod to
Type: enhancement Stage:
Components: Library (Lib) Versions: Python 3.8
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: bup, cheryl.sabella, ronaldoussoren, steven.daprano
Priority: normal Keywords:

Created on 2019-02-08 05:36 by bup, last changed 2019-02-08 13:06 by cheryl.sabella.

Messages (4)
msg335058 - (view) Author: Dan Snider (bup) * Date: 2019-02-08 05:36
Having the ability to add binding behavior to any callable is an incredibly useful feature if one knows how to take advantage of it, but unfortunately, nothing that currently (publicly) exists comes close to filling the gap `instancemethod`s secrecy leaves.

There really isn't anything else to say about it because it's simply amazing at what it does, and publicly exposing it has zero drawback that I could possibly imagine.
Here's a benchmark I just ran 3.6 (can't check 3.7 but shouldn't be significantly different):

if 1:
    from functools import _lru_cache_wrapper, partial
    method = type((lambda:0).__get__(0))
    for cls in object.__subclasses__():
        if cls.__name__ == 'instancemethod':
            instancemethod = cls
    del cls

    class Object:
        lrx = _lru_cache_wrapper(id, 0, 0, tuple)
        imx = instancemethod(id)
        smx = property(partial(method, id))
        fnx = lambda self, f=id: f(self)

>>> ob = Object()
>>> stex.Compare.load_meth_call('ob', '', None, 'lrx', 'imx', 'smx', 'fnx')

    [*] Trial duration: 0.5 seconds
    [*] Num trials: 20
    [*] Verbose: True
    [*] Imports: ('ob',)

    +-INDEX +-INSTRUCTION           + OPARG-+ STACK-+
    |[   22]  FOR_ITER ------------> (   12)       1|
    |[   24]  STORE_FAST ----------> (    2)       0|
    |[   26]  LOAD_FAST -----------> (    0)       1|
    |[   28]  LOAD_ATTR -----------> (    2)       1|
    |[   30]  CALL_FUNCTION -------> (    0)       1|
    |[   32]  POP_TOP                 -----        0|
    |[   34]  JUMP_ABSOLUTE -------> (   22)       0|
    | "ob.lrx()"  ->   10.000(b)   55_902(k)     179(ns)
    | "ob.imx()"  ->   10.000(b)   80_053(k)     125(ns)
    | "ob.smx()"  ->   10.000(b)   48_040(k)     208(ns)
    | "ob.fnx()"  ->   10.000(b)   42_759(k)     234(ns)
msg335072 - (view) Author: Ronald Oussoren (ronaldoussoren) * (Python committer) Date: 2019-02-08 11:01
Could you expand on why instancemethod is amazing, other than that's it is apparently fast at something.
msg335074 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2019-02-08 12:02
I presume you aren't referring to this:

from types import MethodType

> There really isn't anything else to say about it

How about starting with why you want this and what you will do with it?

According to this post on StackOverflow:

    The name instancemethod looks a lot like a bound method 
    object, but it turns out it's something else entirely. 
    It's a weird internal thing that, according to its 
    documentation, is supposed to be the new way for C types
    to represent their methods, except that the standard 
    C-level API for creating a type doesn't actually use it.

    According to conversations on the Python issue tracker,
    this feature was requested by the developers of Cython
    and Pyrex.

Given that this is not used anywhere in CPython, the documentation for the C API specifically says it is not exposed to Python code, and the name is painfully misleading, we should assume that it is undocumented for a reason. It might help to persuade the core devs to expose it as part of the public Python API if you have a use-case for this.

(And if so, I think it desperately needs to change the displayed name away from "instancemethod", since that's not what it returns.)

See also #28842
msg335077 - (view) Author: Cheryl Sabella (cheryl.sabella) * (Python committer) Date: 2019-02-08 13:06
Also see issue 11776 about documenting the signatures.
Date User Action Args
2019-02-08 13:06:52cheryl.sabellasetnosy: + cheryl.sabella
messages: + msg335077
2019-02-08 12:02:39steven.dapranosetnosy: + steven.daprano
messages: + msg335074
2019-02-08 11:01:17ronaldoussorensetnosy: + ronaldoussoren
messages: + msg335072
2019-02-08 05:36:55bupcreate