From 30f2a30f9bb539eb3631fec8559e61a362774f6e Mon Sep 17 00:00:00 2001 From: Danil Alexeev Date: Mon, 4 May 2026 11:38:49 +0300 Subject: [PATCH] GDScript: Preserve compatibility for untyped return of `_get_property_list()` --- doc/classes/Object.xml | 2 +- modules/gdscript/gdscript.cpp | 41 ++++++++++++++++++- modules/gdscript/gdscript.h | 3 +- modules/gdscript/gdscript_analyzer.cpp | 14 +++++++ .../errors/compat_get_property_list.gd | 20 +++++++++ .../errors/compat_get_property_list.out | 6 +++ .../errors/compat_get_property_list.gd | 36 ++++++++++++++++ .../errors/compat_get_property_list.out | 6 +++ 8 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 modules/gdscript/tests/scripts/analyzer/errors/compat_get_property_list.gd create mode 100644 modules/gdscript/tests/scripts/analyzer/errors/compat_get_property_list.out create mode 100644 modules/gdscript/tests/scripts/runtime/errors/compat_get_property_list.gd create mode 100644 modules/gdscript/tests/scripts/runtime/errors/compat_get_property_list.out diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index 7a83f77835..058162ae8a 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -97,7 +97,7 @@ var numbers = PackedInt32Array([0, 0, 0]) func _get_property_list(): - var properties = [] + var properties: Array[Dictionary] = [] for i in range(number_count): properties.append({ diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 0fb2de8914..f9f9567ec2 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1741,9 +1741,48 @@ void GDScriptInstance::get_property_list(List *p_properties) const Callable::CallError err; Variant ret = E->value->call(const_cast(this), nullptr, 0, err); if (err.error == Callable::CallError::CALL_OK) { - ERR_FAIL_COND_MSG(ret.get_type() != Variant::ARRAY, "Wrong type for _get_property_list, must be an array of dictionaries."); + // GH-118877. We decided to make an exception to maintain compatibility, since the problem can only be detected at runtime. +#ifdef DISABLE_DEPRECATED + ERR_FAIL_COND_MSG(ret.get_type() != Variant::ARRAY, R"*(Wrong type for "_get_property_list()", must be "Array[Dictionary]".)*"); +#else // !DISABLE_DEPRECATED + ERR_FAIL_COND_MSG(ret.get_type() != Variant::ARRAY, R"*(Wrong type for "_get_property_list()", must be an array of dictionaries.)*"); +#endif // DISABLE_DEPRECATED Array arr = ret; + + // GH-118877. We decided to make an exception to maintain compatibility, since the problem can only be detected at runtime. +#ifdef DISABLE_DEPRECATED + ERR_FAIL_COND_MSG(arr.get_typed_builtin() != Variant::DICTIONARY, R"*(Wrong type for "_get_property_list()", must be "Array[Dictionary]".)*"); +#else // !DISABLE_DEPRECATED +#ifdef DEBUG_ENABLED + if (arr.get_typed_builtin() != Variant::DICTIONARY) { + static bool error_shown = false; + if (unlikely(!error_shown)) { + error_shown = true; + + String elem_type; + if (arr.is_typed()) { + const Ref