diff --git a/django/dispatch/dispatcher.py b/django/dispatch/dispatcher.py index 0903c3a8a9..54e71c01cc 100644 --- a/django/dispatch/dispatcher.py +++ b/django/dispatch/dispatcher.py @@ -6,8 +6,8 @@ from django.dispatch import saferef WEAKREF_TYPES = (weakref.ReferenceType, saferef.BoundMethodWeakref) def _make_id(target): - if hasattr(target, 'im_func'): - return (id(target.im_self), id(target.im_func)) + if hasattr(target, '__func__'): + return (id(target.__self__), id(target.__func__)) return id(target) class Signal(object): diff --git a/django/dispatch/saferef.py b/django/dispatch/saferef.py index ebf423fc91..e060e619f8 100644 --- a/django/dispatch/saferef.py +++ b/django/dispatch/saferef.py @@ -19,11 +19,11 @@ def safeRef(target, onDelete = None): goes out of scope with the reference object, (either a weakref or a BoundMethodWeakref) as argument. """ - if hasattr(target, 'im_self'): - if target.im_self is not None: + if hasattr(target, '__self__'): + if target.__self__ is not None: # Turn a bound method into a BoundMethodWeakref instance. # Keep track of these instances for lookup by disconnect(). - assert hasattr(target, 'im_func'), """safeRef target %r has im_self, but no im_func, don't know how to create reference"""%( target,) + assert hasattr(target, '__func__'), """safeRef target %r has __self__, but no __func__, don't know how to create reference"""%( target,) reference = get_bound_method_weakref( target=target, onDelete=onDelete @@ -97,9 +97,9 @@ class BoundMethodWeakref(object): """Return a weak-reference-like instance for a bound method target -- the instance-method target for the weak - reference, must have im_self and im_func attributes + reference, must have __self__ and __func__ attributes and be reconstructable via: - target.im_func.__get__( target.im_self ) + target.__func__.__get__( target.__self__ ) which is true of built-in instance methods. onDelete -- optional callback which will be called when this weak reference ceases to be valid @@ -128,10 +128,10 @@ class BoundMethodWeakref(object): ) self.deletionMethods = [onDelete] self.key = self.calculateKey( target ) - self.weakSelf = weakref.ref(target.im_self, remove) - self.weakFunc = weakref.ref(target.im_func, remove) - self.selfName = str(target.im_self) - self.funcName = str(target.im_func.__name__) + self.weakSelf = weakref.ref(target.__self__, remove) + self.weakFunc = weakref.ref(target.__func__, remove) + self.selfName = str(target.__self__) + self.funcName = str(target.__func__.__name__) def calculateKey( cls, target ): """Calculate the reference key for this reference @@ -139,7 +139,7 @@ class BoundMethodWeakref(object): Currently this is a two-tuple of the id()'s of the target object and the target function respectively. """ - return (id(target.im_self),id(target.im_func)) + return (id(target.__self__),id(target.__func__)) calculateKey = classmethod( calculateKey ) def __str__(self): @@ -201,9 +201,9 @@ class BoundNonDescriptorMethodWeakref(BoundMethodWeakref): """Return a weak-reference-like instance for a bound method target -- the instance-method target for the weak - reference, must have im_self and im_func attributes + reference, must have __self__ and __func__ attributes and be reconstructable via: - target.im_func.__get__( target.im_self ) + target.__func__.__get__( target.__self__ ) which is true of built-in instance methods. onDelete -- optional callback which will be called when this weak reference ceases to be valid @@ -211,9 +211,9 @@ class BoundNonDescriptorMethodWeakref(BoundMethodWeakref): collected). Should take a single argument, which will be passed a pointer to this object. """ - assert getattr(target.im_self, target.__name__) == target, \ + assert getattr(target.__self__, target.__name__) == target, \ ("method %s isn't available as the attribute %s of %s" % - (target, target.__name__, target.im_self)) + (target, target.__name__, target.__self__)) super(BoundNonDescriptorMethodWeakref, self).__init__(target, onDelete) def __call__(self): diff --git a/tests/regressiontests/decorators/tests.py b/tests/regressiontests/decorators/tests.py index 0c5b2e97da..dceaa62abc 100644 --- a/tests/regressiontests/decorators/tests.py +++ b/tests/regressiontests/decorators/tests.py @@ -220,7 +220,7 @@ class MethodDecoratorTests(TestCase): self.assertEqual(getattr(Test.method, 'myattr2', False), True) self.assertEqual(Test.method.__doc__, 'A method') - self.assertEqual(Test.method.im_func.__name__, 'method') + self.assertEqual(Test.method.__func__.__name__, 'method') class XFrameOptionsDecoratorsTests(TestCase):