Skip to content

Commit 5280922

Browse files
committed
Fix classmethod descr_get to match CPython behavior
Simplify classmethod.__get__ to always create a PyBoundMethod binding the callable to the class, matching CPython's cm_descr_get which simply calls PyMethod_New(cm->cm_callable, type). The previous implementation incorrectly tried to call __get__ on the wrapped callable, which broke when a bound method was passed to classmethod() (e.g. classmethod(A().foo)).
1 parent 7eb1821 commit 5280922

File tree

2 files changed

+1
-6
lines changed

2 files changed

+1
-6
lines changed

Lib/test/test_decorators.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,6 @@ def bar(): return 42
291291
self.assertEqual(bar(), 42)
292292
self.assertEqual(actions, expected_actions)
293293

294-
@unittest.expectedFailure # TODO: RUSTPYTHON
295294
def test_bound_function_inside_classmethod(self):
296295
class A:
297296
def foo(self, cls):

crates/vm/src/builtins/classmethod.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,7 @@ impl GetDescriptor for PyClassMethod {
5959
let cls = cls.unwrap_or_else(|| _obj.class().to_owned().into());
6060
// Clone and release lock before calling Python code to prevent deadlock
6161
let callable = zelf.callable.lock().clone();
62-
let call_descr_get: PyResult<PyObjectRef> = callable.get_attr("__get__", vm);
63-
match call_descr_get {
64-
Err(_) => Ok(PyBoundMethod::new(cls, callable).into_ref(&vm.ctx).into()),
65-
Ok(call_descr_get) => call_descr_get.call((cls.clone(), cls), vm),
66-
}
62+
Ok(PyBoundMethod::new(cls, callable).into_ref(&vm.ctx).into())
6763
}
6864
}
6965

0 commit comments

Comments
 (0)