GDScript: Preserve compatibility for untyped return of _get_property_list()

This commit is contained in:
Danil Alexeev
2026-05-04 11:38:49 +03:00
parent 16bb065ac3
commit 30f2a30f9b
8 changed files with 125 additions and 3 deletions
+40 -1
View File
@@ -1741,9 +1741,48 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const
Callable::CallError err;
Variant ret = E->value->call(const_cast<GDScriptInstance *>(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<Script> script_type = arr.get_typed_script();
if (script_type.is_valid() && script_type->is_valid()) {
elem_type = GDScript::debug_get_script_name(script_type);
} else if (!arr.get_typed_class_name().is_empty()) {
elem_type = arr.get_typed_class_name();
} else {
elem_type = Variant::get_type_name((Variant::Type)arr.get_typed_builtin());
}
elem_type = vformat("[%s]", elem_type);
}
String msg = vformat(R"*("_get_property_list()" should return "Array[Dictionary]", not "Array%s".)*", elem_type);
msg += " The old behavior is supported for compatibility and may be removed in the future.";
msg += " This message is printed once and will not be repeated for similar errors.";
ERR_PRINT(msg);
}
}
#endif // DEBUG_ENABLED
#endif // DISABLE_DEPRECATED
for (int i = 0; i < arr.size(); i++) {
Dictionary d = arr[i];
ERR_CONTINUE(!d.has("name"));