From bd1fdd4d903ae19251705b5ced4a019fd306a263 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Thu, 2 Apr 2020 12:29:20 -0500 Subject: [PATCH] Call __set_name__ on descriptors when initializing types --- Lib/functools.py | 3 ++- vm/src/obj/objtype.rs | 31 +++++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/Lib/functools.py b/Lib/functools.py index b41dea7908..4cde5f590c 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -11,7 +11,8 @@ __all__ = ['update_wrapper', 'wraps', 'WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES', 'total_ordering', 'cmp_to_key', 'lru_cache', 'reduce', 'partial', - 'partialmethod', 'singledispatch', 'singledispatchmethod'] + 'partialmethod', 'singledispatch', 'singledispatchmethod', + "cached_property"] from abc import get_cache_token from collections import namedtuple diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs index 49a0711c12..4391ff3e9a 100644 --- a/vm/src/obj/objtype.rs +++ b/vm/src/obj/objtype.rs @@ -291,14 +291,33 @@ impl PyClassRef { } } - match new(metatype, name.as_str(), base.clone(), bases, attributes) { - Ok(typ) => { - typ.slots.borrow_mut().flags = base.slots.borrow().flags; - vm.ctx.add_tp_new_wrapper(&typ); - Ok(typ.into()) + let typ = new(metatype, name.as_str(), base.clone(), bases, attributes) + .map_err(|e| vm.new_type_error(e))?; + + typ.slots.borrow_mut().flags = base.slots.borrow().flags; + vm.ctx.add_tp_new_wrapper(&typ); + + for (name, obj) in typ.attributes.borrow().iter() { + if let Some(meth) = vm.get_method(obj.clone(), "__set_name__") { + let set_name = meth?; + vm.invoke( + &set_name, + vec![typ.clone().into_object(), vm.new_str(name.clone())], + ) + .map_err(|e| { + let err = vm.new_runtime_error(format!( + "Error calling __set_name__ on '{}' instance {} in '{}'", + obj.class().name, + name, + typ.name + )); + err.set_cause(Some(e)); + err + })?; } - Err(string) => Err(vm.new_type_error(string)), } + + Ok(typ.into_object()) } #[pyslot]