[Solved]if getattr(style, name).xpos == None: prevents from style property assignment

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
_ticlock_
Miko-Class Veteran
Posts: 910
Joined: Mon Oct 26, 2020 5:41 pm
Contact:

[Solved]if getattr(style, name).xpos == None: prevents from style property assignment

#1 Post by _ticlock_ »

Hi, All,

EDIT:
I am setting up a style inside a class __init__ method. The style name is defined by string name style_name (for example style_name = "new_style"). I have no problem setting the style property xpos using getattr(style, style_name).xpos:

Code: Select all

class TestClass():
    def __init__(self, ...):
    ...
     getattr(style, style_name).xpos = 100
In result: style.new_style.xpos =100
However, if I use if statement, I cannot assign style property anymore:

Code: Select all

        ...
        if getattr(style, style_name).xpos == None:
            getattr(style, style_name).xpos = 100
In this case: style.new_style.xpos = None
Even if do something like this:

Code: Select all

        ...
        if getattr(style, style_name).xpos == None:
            pass
        
        getattr(style, style_name).xpos = 100
I still get style.new_style.xpos = None.

Can you please explain why if getattr(style, style_name).xpos == None: prevents from assigning the style property?
Last edited by _ticlock_ on Sun Jan 24, 2021 2:11 am, edited 2 times in total.

User avatar
RicharDann
Veteran
Posts: 286
Joined: Thu Aug 31, 2017 11:47 am
Contact:

Re: if getattr(style, name).xpos == None: prevents from style property assignment

#2 Post by RicharDann »

I'm only guessing as I'm not able to test this right now, but you're using self.style_name for the if statement, and style_name in the second one. They might be being treated as different variables, one as a property of the object, the other as a local variable or perhaps an argument. Or perhaps this is intended, not sure since you didn't post the whole class definition, but I don't see any other problems at first sight.
The most important step is always the next one.

User avatar
_ticlock_
Miko-Class Veteran
Posts: 910
Joined: Mon Oct 26, 2020 5:41 pm
Contact:

Re: if getattr(style, name).xpos == None: prevents from style property assignment

#3 Post by _ticlock_ »

RicharDann wrote: Fri Jan 15, 2021 3:41 pm I'm only guessing as I'm not able to test this right now, but you're using self.style_name for the if statement, and style_name in the second one.
I am sorry for that. I corrected. Let's say it is style_name in all cases.

User avatar
RicharDann
Veteran
Posts: 286
Joined: Thu Aug 31, 2017 11:47 am
Contact:

Re: if getattr(style, name).xpos == None: prevents from style property assignment

#4 Post by RicharDann »

It seems you need to call style.rebuild() in order for changes to be applied after init. Check here.
EDIT:
Tough apparently the changes aren't saved after closing or reloading the game, as the warning I barely missed says.
The most important step is always the next one.

User avatar
_ticlock_
Miko-Class Veteran
Posts: 910
Joined: Mon Oct 26, 2020 5:41 pm
Contact:

Re: if getattr(style, name).xpos == None: prevents from style property assignment

#5 Post by _ticlock_ »

RicharDann wrote: Sat Jan 16, 2021 9:24 am It seems you need to call style.rebuild() in order for changes to be applied after init. Check here.
EDIT:
Tough apparently the changes aren't saved after closing or reloading the game, as the warning I barely missed says.
RicharDann,

Thank you! That indeed worked, although as you said it might not save the changes.
According to doc: "Ren'Py builds styles on startup, named styles should not be changed outside of a style statement or init block."

I wonder if the default statement can be considered as part of "style statement or init block"?

Code: Select all

default var = TestClass(...)
I did some testing with the default statement and the created styles inside __init__ method of TestClass were properly stored in style, even after relaunching the project.
However, I highly doubt that it can be considered as part of "style statement or init block".

User avatar
RicharDann
Veteran
Posts: 286
Joined: Thu Aug 31, 2017 11:47 am
Contact:

Re: if getattr(style, name).xpos == None: prevents from style property assignment

#6 Post by RicharDann »

_ticlock_ wrote: Sat Jan 16, 2021 11:56 am I wonder if the default statement can be considered as part of "style statement or init block"?
We might have to ask PyTom or someome more knowledgeable on the way Style works internally, but in theory, since the __init__ method is run from an init python block (when the TestClass instance is created), it works and the style is properly updated since we're still at init time, but after that, once the game's started, in my testing, when loading a save or restarting the game, the style was reset to the state it was when initialization was finished. I was doing it all from the console though and not using a custom class myself so maybe I'm missing something, but if you only need to modify the styles on the class at init time, the method you're using should work.
The most important step is always the next one.

User avatar
_ticlock_
Miko-Class Veteran
Posts: 910
Joined: Mon Oct 26, 2020 5:41 pm
Contact:

Re: if getattr(style, name).xpos == None: prevents from style property assignment

#7 Post by _ticlock_ »

RicharDann wrote: Mon Jan 18, 2021 10:32 am
_ticlock_ wrote: Sat Jan 16, 2021 11:56 am I wonder if the default statement can be considered as part of "style statement or init block"?
We might have to ask PyTom or someome more knowledgeable on the way Style works internally, but in theory, since the __init__ method is run from an init python block (when the TestClass instance is created), it works and the style is properly updated since we're still at init time, but after that, once the game's started, in my testing, when loading a save or restarting the game, the style was reset to the state it was when initialization was finished. I was doing it all from the console though and not using a custom class myself so maybe I'm missing something, but if you only need to modify the styles on the class at init time, the method you're using should work.
RicharDann, greatly appreciate your help!

I only make style changes in __init__ method of TestClass. I would not worry if it was

Code: Select all

define var = TestClass(...)
Since it would be definitely in the init block. I am hesitant about:

Code: Select all

default var = TestClass(...)
It actually works for me with style.rebuild() and no problems with the style after save/load/relaunch project. However, it may have some hidden problems.

ijffdrie
Regular
Posts: 32
Joined: Mon Apr 13, 2020 1:11 pm
itch: pink-productions
Contact:

Re: if getattr(style, name).xpos == None: prevents from style property assignment

#8 Post by ijffdrie »

It's unlikely, but it might be that the style class has a custom comparator function that does something weird when confronted with a comparison with None. Try using if getattr(style, style_name).xpos is None: (which directly compares the value to None, rather than asking the comparator function to compare it to None).

User avatar
_ticlock_
Miko-Class Veteran
Posts: 910
Joined: Mon Oct 26, 2020 5:41 pm
Contact:

Re: if getattr(style, name).xpos == None: prevents from style property assignment

#9 Post by _ticlock_ »

ijffdrie wrote: Sat Jan 23, 2021 7:19 pm It's unlikely, but it might be that the style class has a custom comparator function that does something weird when confronted with a comparison with None. Try using if getattr(style, style_name).xpos is None: (which directly compares the value to None, rather than asking the comparator function to compare it to None).
ijffdrie,
Thank you for the advice.

However, it turned out that the actual problem was that I tried to create named style outside the Ren'Py initialization. The styles were created in the __init__ method of the TestClass. The instance of this class was "defined" in the default statement like this:

Code: Select all

default interface = TestClass(...)
According to doc: "Ren'Py builds styles on startup, named styles should not be changed outside of a style statement or init block."

The confusion was because of some specificity of the default statement, that allowed to save the changes in the newly created named style in some cases, but didn't save the changes in case of using

Code: Select all

if getattr(style, style_name).xpos == None:
    pass
Also due to some specificity of default statement using style.rebuild() at the end of __init__ method of the TestClass helped to save the changes to the created named styles even if the above-mentioned if statement was used.

Conclusion: Due to some specificity of default statement there's a chance that newly created named styles can be modified in the default statement and the changes are saved in the styles. However, this method is not "safe" and can have some hidden problems. This, it is better to follow the advice from the Ren'Py doc and don't create/modify the named styles outside of a style statement or init block.

Post Reply

Who is online

Users browsing this forum: Bing [Bot]