godot: It's impossible to check 'self' object type because of the Parse error

Godot version: 47bf26c40d7d832482dcb9048590c7997ab4d8f4

OS/device including version: Ubuntu 18.04, GTX1060

Issue description: When having a script that can be attached to different nodes it’s impossible to check it’s type from inside of the script because of the Parse Error: A value of type self will never be an instance of Spatial

Steps to reproduce:

  1. Create new script
  2. Fill it with this code:
extends Node
func _ready():
	if (self is Spatial):
		pass
	if (self is Node2D):
		pass
  1. Observe the error: built-in:5 - Parse Error: A value of type 'self' will never be an instance of 'Spatial'

Minimal reproduction project: SelfTypeCheckParseError.zip

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 2
  • Comments: 15 (12 by maintainers)

Most upvoted comments

It seems it’s possible to workaround this issue by doing something like:

var selfRef = self;
if(selfRef is Spatial)...
    (...)

Was replying to vnen’s suggestion. Modified my response to include the quote.

See #20340 and #16958 for previous discussions.

@avencherus did a great job explaining the gist of it.

Essentially when you add static checks into the mix, the script must know the inheritance chain without taking the node into consideration. Otherwise a lot of the checks can’t be done and static typing becomes pointless.

Can’t really believe that this is a bug that we are using as a feature since this seems to be quite normal behavior across programming languages.

It’s not normal, because it’s relying on a concept that is non-existing on other languages: attaching scripts to objects. In other languages the scripts are the objects. My idea was to make the scripts work on their own, since it’s impossible to know to which node they’ll be attached, especially when they can be attached to multiple nodes.

Unless you’re thinking of multiple inheritance, which not all languages allow (and it’s not a thing in GDScript and not used in Godot).

An example to illustrate the issue: say you make a script that extends Node, with the intention of attaching it to multiple nodes descending Node. Then you create a property called priority since it’s relevant to the processing. Finally you attach this script to an Area node. But Area already has a property called priority already so you are overriding the parent’s property, which is something that was forbidden since properties became a thing. How would the script behave? Should it use the property of the script or the native node? Should it give a runtime error? The script itself has no idea that the attached object has a property with the same name, so it’s impossible to act on it without explicit runtime checks.

My proposal to solve the problem of “reusing code in different nodes” would be adding “mixins” (AKA “traits”) that let you embed snippets into other scripts without using explicit composition. This would make it a compile-time feature, allowing proper static checks.


I want to point out that many of the current static checks will eventually be used to optimize GDScript, making the bytecode more specific and more efficient, leading to JIT compilation if all goes well.