Skip to content

Comments

Reimplement soft access restriction for members prefixed with _#103768

Open
Lazy-Rabbit-2001 wants to merge 1 commit intogodotengine:masterfrom
Lazy-Rabbit-2001:private-remastered
Open

Reimplement soft access restriction for members prefixed with _#103768
Lazy-Rabbit-2001 wants to merge 1 commit intogodotengine:masterfrom
Lazy-Rabbit-2001:private-remastered

Conversation

@Lazy-Rabbit-2001
Copy link
Contributor

@Lazy-Rabbit-2001 Lazy-Rabbit-2001 commented Mar 7, 2025

Rebuilt on #98557

Info

About the pr, see #98557
This time I removed __ naming convention, and left _ only.

The question about whether this will block further migration to using private or @private

No, as this pr implements the system driven by the warnings and it will be very easy to migrate the grammar to using prefixes as long as it is still warning-driven.

However, I'm afraid we would not resort to the former as members have agreed with using annotations over keywords for modifying grammars (except static). to keep compatibility and, more important, performance.

Progress

  • Remaster the codes
  • Fix no warning when the current class has the same private member as the accessed class that is not the super class of the current class.
  • Unit test

@Ivorforce
Copy link
Member

I do really like this warning, but I wouldn't use it unless I could suppress the warning for a single line. Is that possible with the current code analysis system?

@Lazy-Rabbit-2001
Copy link
Contributor Author

As for the bug, "no warning when the current class has the same private member as the accessed class that is not the super class of the current class", this is because the method check_access_private_member() only deals with the identifier passed in and a flag about if the pattern to be reduced or having been reduced is a call or not, in which there is a line:

if (parser->current_class->has_member(p_identifier->name)) {
    return;
}

For example, if A and B has the same signatured function, while they are not derived from the other one:

class A:
    var _t := 1

class B:
    var a := A.new()
    var _t := 2

    func _init() -> void:
        a._t = 3 # No warning as B has a member with the same name `_t`

Dunno how to deal with this as during reduction you cannot infer the details of the subscript base, except its type and name.

@Lazy-Rabbit-2001
Copy link
Contributor Author

Lazy-Rabbit-2001 commented Mar 7, 2025

I do really like this warning, but I wouldn't use it unless I could suppress the warning for a single line. Is that possible with the current code analysis system?

You can ignore the warning with @warning_ignore("access_private_member"), or use @warning_ignore_start("access_private_member") (and ends with @warning_ignore_restore("access_private_member")) for access to multiple private members

@Lazy-Rabbit-2001 Lazy-Rabbit-2001 marked this pull request as ready for review March 9, 2025 06:48
@Lazy-Rabbit-2001 Lazy-Rabbit-2001 requested review from a team as code owners March 9, 2025 06:48
@Lazy-Rabbit-2001
Copy link
Contributor Author

Everything is now ready for review :D

@nubels
Copy link
Contributor

nubels commented Apr 25, 2025

I really like this change! Having the option for Godot to throw errors when accessing private members and methods helps a lot.

@Mickeon
Copy link
Member

Mickeon commented Jun 28, 2025

I thought we were genuinely championing for this PR, it was just not the time to merge it right now?

@Lazy-Rabbit-2001
Copy link
Contributor Author

Lazy-Rabbit-2001 commented Jun 28, 2025

I thought we were genuinely championing for this PR, it was just not the time to merge it right now?

No, and please see godotengine/godot-proposals#12685 (comment)

My brain was f**ked and forgot that this is something that would help users to avoid accessing private members.
Ok, reopened

@AThousandShips
Copy link
Member

That's my personal opinion and was about hard access specifiers, not soft access specifiers like this

@Lazy-Rabbit-2001 Lazy-Rabbit-2001 requested review from a team as code owners July 16, 2025 14:08
@Ivorforce Ivorforce changed the title Reimplent soft access restriction for members prefixed with _ Reimplement soft access restriction for members prefixed with _ Jul 16, 2025
@Lazy-Rabbit-2001 Lazy-Rabbit-2001 requested a review from Mickeon July 16, 2025 15:03
@Lazy-Rabbit-2001
Copy link
Contributor Author

Lazy-Rabbit-2001 commented Jul 30, 2025

Does this mean we will no longer get proper access modifiers?

We don't introduce the feature in a forced way (whether by adding private or @private) because of runtime check which will reduce extra performance during your gameplay. Maybe in GDScript 3.x this could get solved, hopefully.

Using an underscore as a private variable means every time I want to change a var from private to public, or vice versa, I now break save game compatibility with my next update. The options now are to either wrap each saveable variable in a getter/setter (Which are extremely slow in GDScript) or check each variable when I save or load and adjust the saved/loaded name.

Yeah, I understand your point, but as I said this does not break compatibility as possible and you can configure it and turn it off. So you can keep the current codestyle you've been using.

I have seen the arguments before 'But Python uses it', sure, but Python is not a language created specifically for game development.

How does Python has anything to do with this topic? I don't understand. :/

@AThousandShips
Copy link
Member

How does Python has anything to do with this topic?

They mentioned it because it's a common argument in favor of this, they're not making the argument, they're referencing it

@pleucell
Copy link

Are there any plans to merge this in 4.6?

@Lazy-Rabbit-2001
Copy link
Contributor Author

Lazy-Rabbit-2001 commented Nov 10, 2025

Are there any plans to merge this in 4.6?

I've asked many times in the rocket chat but nobody has given this a look yet... sad
Hope the members would notice this and get this a key approval and merge asap...

@HolonProduction
Copy link
Member

Could you double check whether you included unrelated changes? The diff contains some create dialog changes in editor interface, for which it's not directly obvious to me how they relate to this PR.

@produno
Copy link

produno commented Nov 10, 2025

Yeah, I understand your point, but as I said this does not break compatibility as possible and you can configure it and turn it off. So you can keep the current codestyle you've been using.

This wasn't really the point I was trying to make. I do want a way to mark my variables as private or public, so I will use whatever is ultimately implemented. But imo having proper access modifiers is the correct way to go, for reasons previously mentioned. So if this is going to hinder or even halt that feature being merged in the future, then that is not good. Hence my question. It also helps me decide if I should use this feature at all if it ends up being merged, as I don't want to break all saves in the future when needing to change.

For some of us working on large projects, whom plan to release into Early access, its helpful to give us an idea of what's planned or likely to change/happen regarding certain features, so we can then make informed decisions within our own codebase.

@Lazy-Rabbit-2001
Copy link
Contributor Author

Lazy-Rabbit-2001 commented Nov 10, 2025

Yeah, I understand your point, but as I said this does not break compatibility as possible and you can configure it and turn it off. So you can keep the current codestyle you've been using.

This wasn't really the point I was trying to make. I do want a way to mark my variables as private or public, so I will use whatever is ultimately implemented. But imo having proper access modifiers is the correct way to go, for reasons previously mentioned. So if this is going to hinder or even halt that feature being merged in the future, then that is not good.

The feature won't eliminate the solution to introduce either a keyword private or a modifying annotation @private, and you can easily upgrade your grammar from what it presents in this pr to what you have suggested for the future releases (perhaps) when needed because this doesn't take too much time to do grammar migration.

Hence my question. It also helps me decide if I should use this feature at all if it ends up being merged, as I don't want to break all saves in the future when needing to change.

This is implemented by warnings, so you can disable them in your project settings or enable them as you wish. The warnings will not break your current project as long as you do not switch the warnings to errors.

@Ivorforce
Copy link
Member

Ivorforce commented Nov 10, 2025

@produno Can you explain which feature you're using that changing variable names breaks compatibility? I assume you're passing some of your objects directly into one of the serialization functions, without specifying key names explicitly?

For some of us working on large projects, whom plan to release into Early access, its helpful to give us an idea of what's planned or likely to change/happen regarding certain features, so we can then make informed decisions within our own codebase.

While there was a consensus in a previous GDScript meeting that this PR was desirable, it is still up for debate. If we find it is not mergeable due to other concerns, it will not be merged.
If you'd like to stay up to date with plans, the best place to find out is the dev releases' blogposts on the website. Changes are always up for debate until the moment they're merged (and rarely, they are reverted even after that).

@produno
Copy link

produno commented Nov 10, 2025

@produno Can you explain which feature you're using that changing variable names breaks compatibility? I assume you're passing some of your objects directly into one of the serialization functions, without specifying key names explicitly?

I save the property name with its value, then upon load I use set() to restore the value where required. I'm sure I am not only person serialising in this way. It just means if this is added and proper access modifiers will likely to be added in the future, then I will refrain from using this feature.

@Lazy-Rabbit-2001
Copy link
Contributor Author

Currently there is either using @private instead of _, or implementing the access restriction for GDScript (which would require the core team for a meeting to decide on this), and also keeping introducing _ first.

  • For the @private, the code will be easily ported, but users are required to type more letters than a single _. Meanwhile, based on the conflict raised by abstract being @abstract, I don't hope to see the same dramma or disaster happen again.
  • For the access restriction for GDScript (forced errors and runtime checks), this may require a core team for a meeting on this topic because some details may involve the core part of the engine. Also, it's still a problem to run runtime check with the least cost on performance, so I think this would be far a long time to do.
  • For the original idea - using _, even though it solves the problem of not having access restriction in GDScript, the naming will also shadows the naming convention of virtual methods that would be public to call (although in most of time they are not called from external places). Meanwhile, it only pops warning if they don't follow the convention, and the game will not stop running after being exported with the release template. However, this is the most convenient and the most balanced (currently) solution to the problem. Of course, it's also a temporary solution, so in the future one of the previous two would replace this.

@Lazy-Rabbit-2001
Copy link
Contributor Author

Lazy-Rabbit-2001 commented Dec 5, 2025

pushed an update thatt is unrelated to this pr (exactly saying, it's about the create_dialog.cpp, but I'd no idea why the update conflicted with this one...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

9 participants