Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4a22b5d

Browse files
committed
Patch from Georg Brandl and me for #1493
Remove unbound method objects
1 parent 91c7730 commit 4a22b5d

19 files changed

Lines changed: 65 additions & 115 deletions

Lib/DocXMLRPCServer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def docroutine(self, object, name=None, mod=None,
7474
title = '<a name="%s"><strong>%s</strong></a>' % (anchor, name)
7575

7676
if inspect.ismethod(object):
77-
args, varargs, varkw, defaults = inspect.getargspec(object.im_func)
77+
args, varargs, varkw, defaults = inspect.getargspec(object)
7878
# exclude the argument bound to the instance, it will be
7979
# confusing to the non-Python user
8080
argspec = inspect.formatargspec (

Lib/inspect.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def ismethod(object):
5757
__name__ name with which this method was defined
5858
im_class class object in which this method belongs
5959
im_func function object containing implementation of method
60-
im_self instance to which this method is bound, or None"""
60+
im_self instance to which this method is bound"""
6161
return isinstance(object, types.MethodType)
6262

6363
def ismethoddescriptor(object):
@@ -269,7 +269,7 @@ def classify_class_attrs(cls):
269269
kind = "class method"
270270
elif isinstance(obj, property):
271271
kind = "property"
272-
elif (ismethod(obj_via_getattr) or
272+
elif (isfunction(obj_via_getattr) or
273273
ismethoddescriptor(obj_via_getattr)):
274274
kind = "method"
275275
else:

Lib/test/inspect_fodder2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def g():
9696
"doc"
9797
return 42
9898
return X
99-
method_in_dynamic_class = f().g.im_func
99+
method_in_dynamic_class = f().g
100100

101101
#line 101
102102
def keyworded(*arg1, arg2=1):

Lib/test/output/test_extcall

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ dir() got multiple values for keyword argument 'b'
3838
3 512 True
3939
3
4040
3
41+
5
42+
5
4143
za () {} -> za() takes exactly 1 positional argument (0 given)
4244
za () {'a': 'aa'} -> ok za aa B D E V a
4345
za () {'d': 'dd'} -> za() got an unexpected keyword argument 'd'

Lib/test/test_class.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ class B(A):
552552
self.assertEquals(hash(B.f), hash(A.f))
553553

554554
# the following triggers a SystemError in 2.4
555-
a = A(hash(A.f.im_func)^(-1))
555+
a = A(hash(A.f)^(-1))
556556
hash(a.f)
557557

558558
def test_main():

Lib/test/test_descr.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -280,26 +280,26 @@ def Cmethod(self): pass
280280

281281
c = C()
282282
vereq(interesting(dir(c)), cstuff)
283-
verify('im_self' in dir(C.Cmethod))
283+
#verify('im_self' in dir(C.Cmethod))
284284

285285
c.cdata = 2
286286
c.cmethod = lambda self: 0
287287
vereq(interesting(dir(c)), cstuff + ['cdata', 'cmethod'])
288-
verify('im_self' in dir(c.Cmethod))
288+
#verify('im_self' in dir(c.Cmethod))
289289

290290
class A(C):
291291
Adata = 1
292292
def Amethod(self): pass
293293

294294
astuff = ['Adata', 'Amethod'] + cstuff
295295
vereq(interesting(dir(A)), astuff)
296-
verify('im_self' in dir(A.Amethod))
296+
#verify('im_self' in dir(A.Amethod))
297297
a = A()
298298
vereq(interesting(dir(a)), astuff)
299299
a.adata = 42
300300
a.amethod = lambda self: 3
301301
vereq(interesting(dir(a)), astuff + ['adata', 'amethod'])
302-
verify('im_self' in dir(a.Amethod))
302+
#verify('im_self' in dir(a.Amethod))
303303

304304
# Try a module subclass.
305305
import sys
@@ -1504,8 +1504,10 @@ class D(C):
15041504
vereq(D.foo(d, 1), (d, 1))
15051505
class E: # *not* subclassing from C
15061506
foo = C.foo
1507-
vereq(E().foo, C.foo) # i.e., unbound
1508-
verify(repr(C.foo.__get__(C())).startswith("<bound method "))
1507+
r = repr(E().foo)
1508+
verify(r.startswith("<bound method E.foo "), r)
1509+
r = repr(C.foo.__get__(C()))
1510+
verify(r.startswith("<bound method ?.foo "), r)
15091511

15101512
def compattr():
15111513
if verbose: print("Testing computed attributes...")
@@ -1685,8 +1687,9 @@ class D(C):
16851687
vereq(d2.goo(), 1)
16861688
class E(object):
16871689
foo = C.foo
1688-
vereq(E().foo, C.foo) # i.e., unbound
1689-
verify(repr(C.foo.__get__(C(1))).startswith("<bound method "))
1690+
vereq(E().foo.im_func, C.foo) # i.e., unbound
1691+
r = repr(C.foo.__get__(C(1)))
1692+
verify(r.startswith("<bound method "), r)
16901693

16911694
def specials():
16921695
# Test operators like __hash__ for which a built-in default exists

Lib/test/test_descrtut.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,7 @@ def m(self):
444444
... B.foo(self)
445445
446446
>>> C().foo()
447-
Traceback (most recent call last):
448-
...
449-
TypeError: unbound method foo() must be called with B instance as first argument (got C instance instead)
447+
called A.foo()
450448
451449
>>> class C(A):
452450
... def foo(self):

Lib/test/test_extcall.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -231,18 +231,8 @@ def method(self, arg1, arg2):
231231
x = Foo()
232232
print(Foo.method(*(x, 1, 2)))
233233
print(Foo.method(x, *(1, 2)))
234-
try:
235-
print(Foo.method(*(1, 2, 3)))
236-
except TypeError as err:
237-
pass
238-
else:
239-
print('expected a TypeError for unbound method call')
240-
try:
241-
print(Foo.method(1, *(2, 3)))
242-
except TypeError as err:
243-
pass
244-
else:
245-
print('expected a TypeError for unbound method call')
234+
print(Foo.method(*(1, 2, 3)))
235+
print(Foo.method(1, *(2, 3)))
246236

247237
# A PyCFunction that takes only positional parameters should allow an
248238
# empty keyword dictionary to pass without a complaint, but raise a

Lib/test/test_funcattrs.py

Lines changed: 17 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,8 @@ def b():
6767

6868
# In Python 2.1 beta 1, we disallowed setting attributes on unbound methods
6969
# (it was already disallowed on bound methods). See the PEP for details.
70-
try:
71-
F.a.publish = 1
72-
except (AttributeError, TypeError): pass
73-
else: raise TestFailed('expected AttributeError or TypeError')
74-
75-
# But setting it explicitly on the underlying function object is okay.
76-
F.a.im_func.publish = 1
70+
# In Python 3.0 unbound methods are gone.
71+
F.a.publish = 1
7772

7873
if F.a.publish != 1:
7974
raise TestFailed('unbound method attribute not set to expected value')
@@ -92,30 +87,8 @@ def b():
9287
except (AttributeError, TypeError): pass
9388
else: raise TestFailed('expected AttributeError or TypeError')
9489

95-
# See the comment above about the change in semantics for Python 2.1b1
96-
try:
97-
F.a.myclass = F
98-
except (AttributeError, TypeError): pass
99-
else: raise TestFailed('expected AttributeError or TypeError')
100-
101-
F.a.im_func.myclass = F
102-
103-
f1.a.myclass
104-
f2.a.myclass
105-
f1.a.myclass
106-
F.a.myclass
107-
108-
if f1.a.myclass is not f2.a.myclass or \
109-
f1.a.myclass is not F.a.myclass:
110-
raise TestFailed('attributes were not the same')
111-
11290
# try setting __dict__
113-
try:
114-
F.a.__dict__ = (1, 2, 3)
115-
except (AttributeError, TypeError): pass
116-
else: raise TestFailed('expected TypeError or AttributeError')
117-
118-
F.a.im_func.__dict__ = {'one': 11, 'two': 22, 'three': 33}
91+
F.a.__dict__ = {'one': 11, 'two': 22, 'three': 33}
11992

12093
if f1.a.two != 22:
12194
raise TestFailed('setting __dict__')
@@ -315,54 +288,54 @@ def f(): pass
315288
def test_im_class():
316289
class C:
317290
def foo(self): pass
318-
verify(C.foo.im_class is C)
291+
#verify(C.foo.im_class is C)
319292
verify(C().foo.im_class is C)
320-
cantset(C.foo, "im_class", C)
293+
#cantset(C.foo, "im_class", C)
321294
cantset(C().foo, "im_class", C)
322295

323296
def test_im_func():
324297
def foo(self): pass
325298
class C:
326299
pass
327300
C.foo = foo
328-
verify(C.foo.im_func is foo)
301+
#verify(C.foo.im_func is foo)
329302
verify(C().foo.im_func is foo)
330-
cantset(C.foo, "im_func", foo)
303+
#cantset(C.foo, "im_func", foo)
331304
cantset(C().foo, "im_func", foo)
332305

333306
def test_im_self():
334307
class C:
335308
def foo(self): pass
336-
verify(C.foo.im_self is None)
309+
#verify(C.foo.im_self is None)
337310
c = C()
338-
verify(c.foo.im_self is c)
339-
cantset(C.foo, "im_self", None)
340-
cantset(c.foo, "im_self", c)
311+
#verify(c.foo.im_self is c)
312+
#cantset(C.foo, "im_self", None)
313+
#cantset(c.foo, "im_self", c)
341314

342315
def test_im_dict():
343316
class C:
344317
def foo(self): pass
345318
foo.bar = 42
346319
verify(C.foo.__dict__ == {'bar': 42})
347320
verify(C().foo.__dict__ == {'bar': 42})
348-
cantset(C.foo, "__dict__", C.foo.__dict__)
349-
cantset(C().foo, "__dict__", C.foo.__dict__)
321+
#cantset(C.foo, "__dict__", C.foo.__dict__)
322+
#cantset(C().foo, "__dict__", C.foo.__dict__)
350323

351324
def test_im_doc():
352325
class C:
353326
def foo(self): "hello"
354327
verify(C.foo.__doc__ == "hello")
355328
verify(C().foo.__doc__ == "hello")
356-
cantset(C.foo, "__doc__", "hello")
357-
cantset(C().foo, "__doc__", "hello")
329+
#cantset(C.foo, "__doc__", "hello")
330+
#cantset(C().foo, "__doc__", "hello")
358331

359332
def test_im_name():
360333
class C:
361334
def foo(self): pass
362335
verify(C.foo.__name__ == "foo")
363336
verify(C().foo.__name__ == "foo")
364-
cantset(C.foo, "__name__", "foo")
365-
cantset(C().foo, "__name__", "foo")
337+
#cantset(C.foo, "__name__", "foo")
338+
#cantset(C().foo, "__name__", "foo")
366339

367340
def testmore():
368341
test_func_closure()

Lib/test/test_inspect.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def test_excluding_predicates(self):
6565
self.istest(inspect.iscode, 'mod.spam.__code__')
6666
self.istest(inspect.isframe, 'tb.tb_frame')
6767
self.istest(inspect.isfunction, 'mod.spam')
68-
self.istest(inspect.ismethod, 'mod.StupidGit.abuse')
68+
self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
6969
self.istest(inspect.ismethod, 'git.argue')
7070
self.istest(inspect.ismodule, 'mod')
7171
self.istest(inspect.istraceback, 'tb')
@@ -395,7 +395,8 @@ def m1(self): pass
395395
self.assert_(('s', 'static method', A) in attrs, 'missing static method')
396396
self.assert_(('c', 'class method', A) in attrs, 'missing class method')
397397
self.assert_(('p', 'property', A) in attrs, 'missing property')
398-
self.assert_(('m', 'method', A) in attrs, 'missing plain method')
398+
self.assert_(('m', 'method', A) in attrs,
399+
'missing plain method: %r' % attrs)
399400
self.assert_(('m1', 'method', A) in attrs, 'missing plain method')
400401
self.assert_(('datablob', 'data', A) in attrs, 'missing data')
401402

0 commit comments

Comments
 (0)