[issue29114] __class__ not exists in the method which bounded by types.MethodType.

2016-12-30 Thread Nick Coghlan

Nick Coghlan added the comment:

Sorry, I wasn't at all clear about that part - the above techniques should work 
with explicitly created types.MethodType instances as well.

That is, this should work the same as in my earlier examples (although I don't 
have that interpreter session around to test it any more):

>>> b = B()
>>> b.fn = types.MethodType(make_B_method(), b)
>>> b.fn()  # Emulated super()


If you were to build on top of what I wrote above (i.e. setting "B.fn = 
make_B_method()"), that explicit bound method creation would be akin to doing:

>>> b = B()
>>> b.fn = b.fn # Cache the bound method on the instance

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue29114] __class__ not exists in the method which bounded by types.MethodType.

2016-12-30 Thread lanf0n

lanf0n added the comment:

thanks xiang, Nick,

I might misunderstood MethodType to bound method will work as class definition.

It might not good to enhance MethodType to work as class definition, same 
problem on patching method to a class as Nick explained.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue29114] __class__ not exists in the method which bounded by types.MethodType.

2016-12-30 Thread Nick Coghlan

Nick Coghlan added the comment:

Right, this isn't actually a bug, it just requires a bit more creativity to 
bind and resolve `__class__` correctly when defining the replacement method.

Here's what happens normally with zero-argument super():

>>> class A:
... def f(self):
... print(__class__)
... 
>>> A().f()

>>> A.f.__closure__
(,)
>>> inspect.getclosurevars(A.f)
ClosureVars(nonlocals={'__class__': }, globals={}, 
builtins={'print': }, unbound=set())

And here's one way of emulating the __class__ resolution part:

>>> def make_method():
... __class__ = A
... def fn(self):
... print(__class__)
... return fn
... 
>>> A.fn = make_method()
>>> A().fn()


And applying that to get zero-argument super() working in a substitute method 
gives:

>>> class B(A):
... def f(self):
... super().f()
... 
>>> B().f() # Normal super()

>>> def make_B_method():
... __class__ = B
... def fn(self):
... return super().fn()
... return fn
... 
>>> B.fn = make_B_method()
>>> B().fn()  # Emulated super()


--
resolution:  -> not a bug
stage:  -> resolved
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue29114] __class__ not exists in the method which bounded by types.MethodType.

2016-12-29 Thread Xiang Zhang

Xiang Zhang added the comment:

You can't do it like this. The document explicitly states it only works inside 
a class definition:

"Also note that, aside from the zero argument form, super() is not limited to 
use inside methods. The two argument form specifies the arguments exactly and 
makes the appropriate references. The zero argument form only works inside a 
class definition, as the compiler fills in the necessary details to correctly 
retrieve the class being defined, as well as accessing the current instance for 
ordinary methods."

So if treat it as an enhancement, is it reasonable Nick?

--
nosy: +ncoghlan, xiang.zhang

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue29114] __class__ not exists in the method which bounded by types.MethodType.

2016-12-29 Thread lanf0n

New submission from lanf0n:

test code below:

```python

>>> from types import MethodType
>>> class A:
...   def f(self):
... print(__class__)
...
>>> a = A()
>>> a.fn = MethodType(lambda s: print(__class__), a)
>>>
>>> a.f()

>>> a.fn()
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 1, in 
NameError: name '__class__' is not defined
```

this behavior affect `super()` not work in patched function scope, 
of course we can use old super as super(self.__class__, self) to make it work 
as expected, but I think it should work as original method if we already 
bounded the function to instance(class).

--
components: Library (Lib)
messages: 284313
nosy: lanfon72
priority: normal
severity: normal
status: open
title: __class__ not exists in the method which bounded by types.MethodType.
type: behavior
versions: Python 3.5, Python 3.6

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com