TypeError: getattr(): attribute name must be string

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
PoisionLullaby
Regular
Posts: 42
Joined: Wed Jan 10, 2018 9:11 pm
Projects: We're all human
Deviantart: PoisionLullaby
Contact:

TypeError: getattr(): attribute name must be string

#1 Post by PoisionLullaby » Thu Jan 18, 2018 5:09 am

So I'm using qirien's Dating Sim Engine to both try to understand coding a bit better and well to test ideas and other codding things before really getting into making my game. The problem is I keep getting this error code.

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "renpy/common/00start.rpy", line 186, in script call
    call _start_store
  File "renpy/common/00start.rpy", line 141, in script
    python hide:
  File "game/dse-stats.rpy", line 39, in normalize_stats
    v = getattr(store, s.var)
TypeError: getattr(): attribute name must be string
So I though maybe changing the () around "(store, s.var)" would clear it up.

Code: Select all

def normalize_stats():
        for s in __dse_stats:

            v = getattr(store, s.var)

            if v > s.max:
                v = s.max
            if v < 0:
                v = 0

            setattr(store, s.var, v)
Instead I get the same thing but now the very bottom says...

Code: Select all

TypeError: 'builtin_function_or_method' object has no attribute '__getitem__'
I have no clue how to even start trying to fix the second error. ^^' Any help is greatly appreciated.
~Everyone has bad days. Don't judge someone on that day and that day alone, judge them on their actions after it and onward.~

User avatar
Remix
Eileen-Class Veteran
Posts: 1341
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: TypeError: getattr(): attribute name must be string

#2 Post by Remix » Thu Jan 18, 2018 7:16 am

It basically just means the store object does not have a method named __getitem__ (which is called within the setattr loop to see if the attribute exists)

Possible workarounds:
It *might* be a dictionary ... renpy.store[ s.var ] = v
Access the objects dict ... store.__dict__[ s.var ] = v
Address the store through the renpy namespace ... setattr( renpy.store, s.var, v ) # other modules do this
Import the store as a different namespace ... import renpy.store as stat_store

No great idea what might work as I do not know how you or DSE access and address the store
Mad Scientist Todo List:
  • Finish Improved Event Handler
  • Implement DragonBones animation as a Creator Defined Container
  • Develop Cartoon Speech Bubble dialogue
  • Finish Bitmask collision and rebound vector system
  • Develop time based building mechanic
  • Others
  • *Find a superb artist and actually write a game*

User avatar
PoisionLullaby
Regular
Posts: 42
Joined: Wed Jan 10, 2018 9:11 pm
Projects: We're all human
Deviantart: PoisionLullaby
Contact:

Re: TypeError: getattr(): attribute name must be string

#3 Post by PoisionLullaby » Thu Jan 18, 2018 12:05 pm

Sorry if this is obvious but are you saying for me to try replaceing "v = getattr(store, s.var)" this bit of code with one of these? "renpy.store[ s.var ] = v","store.__dict__[ s.var ] = v"?

I don't know if it will help but here is the entirety of the code where the problem is occurring and the full trace back. I don't know what exactly caused this either. I haven't touched this code. All I've done is add stats and change the names of them on a different tab as well as add some dialogue.

Code: Select all

# stats.rpy
# Keeps track of and displays the stats for the DSE.
#
# To change styles, look for the dse_stats_* blocks in styles.rpy


init -100 python:

    __dse_stats = [ ]

    class __Stat(object):

        def __init__(self, name, var, default, max, hidden=False):
            self.name = name
            self.var = var
            self.default = default
            self.max = max
            self.hidden = hidden

    def __init_stats():
        for s in __dse_stats:
            setattr(store, s.var, s.default)

    config.start_callbacks.append(__init_stats)
    
    # Call this function to add a stat to keep track of. 
    # Arguments:
    # Name: name of stat. Will be displayed in the Stats screen
    # var: name of variable to use to keep track of stat.
    # default: starting value for the stat
    # max: maximum value for the stat
    # hidden: Is this stat hidden from the user? Hidden stats will not be displayed in the stats screen.
    def register_stat(name, var, default=0, max=100, hidden=False):
        __dse_stats.append(__Stat(name, var, default, max, hidden))

    def normalize_stats():
        for s in __dse_stats:

            v = getattr(store, s.var)

            if v > s.max:
                v = s.max
            if v < 0:
                v = 0

            setattr(store, s.var, v)

    # Whenever a python statement is executed, we will ensure our stats
    # stay within range.
    config.python_callbacks.append(normalize_stats)                        

# Display the stats in a frame.
# name -  display the stat's name
# bar -   display a bar indicating the value of the stat
# value - display the numerical value of the stat
# max -   display the maximum value of the stat
screen display_stats(name=True, bar=True, value=True, max=True):
    $ dse_stat_length = len(__dse_stats)
    
    #The number of rows is the number of stats that are not hidden
    for s in __dse_stats:
        if s.hidden:
            $ dse_stat_length -= 1
    
    frame:
        style_group "dse_stats"        
        yalign 0.0
        xalign 0.0


        vbox:
            yalign 0.0
            xalign 0.5
            label "Statistics" xalign 0.5

            # Depending on what the user chooses to display, calculate how many columns we need
            $ num_columns = 0
            if name:
                $ num_columns+=1
            if bar:
                $ num_columns+=1
            if value or max:
                $ num_columns+=1
                        
            # Make a grid with up to 3 columns and as many rows as there are stats.
            grid num_columns dse_stat_length:
                xalign 0.5
                yalign 0.5
                spacing 5
                
                for s in __dse_stats:
                    #Skip if the stat is a hidden stat
                    if (not s.hidden):
                        $ v = getattr(store, s.var)
    
                            
                        if name:
                            label s.name
                        
                        if bar:
                            bar value v range s.max xmaximum 150 xalign 0.0
                            
                        if value and max:
                            label ("%d/%d" % (v, s.max)) xalign 1.0
                        elif value:
                            label ("%d" % (v,)) xalign 1.0
                        elif max:
                            label ("%d" % (s.max,)) xalign 1.0
                            

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "renpy/common/00start.rpy", line 186, in script call
    call _start_store
  File "renpy/common/00start.rpy", line 141, in script
    python hide:
  File "game/dse-stats.rpy", line 39, in normalize_stats
    v = getattr(store, s.var)
TypeError: getattr(): attribute name must be string

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "C:\Users\happy customer\Desktop\Visual Novel stuff\renpy-6.99.13-sdk\renpy\bootstrap.py", line 305, in bootstrap
    renpy.main.main()
  File "C:\Users\happy customer\Desktop\Visual Novel stuff\renpy-6.99.13-sdk\renpy\main.py", line 499, in main
    run(restart)
  File "C:\Users\happy customer\Desktop\Visual Novel stuff\renpy-6.99.13-sdk\renpy\main.py", line 147, in run
    renpy.execution.run_context(True)
  File "C:\Users\happy customer\Desktop\Visual Novel stuff\renpy-6.99.13-sdk\renpy\execution.py", line 795, in run_context
    context.run()
  File "renpy/common/00start.rpy", line 186, in script call
    call _start_store
  File "renpy/common/00start.rpy", line 141, in script
    python hide:
  File "C:\Users\happy customer\Desktop\Visual Novel stuff\renpy-6.99.13-sdk\renpy\ast.py", line 832, in execute
    i()
  File "game/dse-stats.rpy", line 39, in normalize_stats
    v = getattr(store, s.var)
TypeError: getattr(): attribute name must be string

Windows-8-6.2.9200
Ren'Py 6.99.13.2919
To test 1.0
~Everyone has bad days. Don't judge someone on that day and that day alone, judge them on their actions after it and onward.~

User avatar
Remix
Eileen-Class Veteran
Posts: 1341
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: TypeError: getattr(): attribute name must be string

#4 Post by Remix » Thu Jan 18, 2018 4:07 pm

I think you'd do best asking in the Cookbook thread for whichever DSE you are using... the author and users of it would be more familiar with how it addresses the Ren'py store module and thus more likely to offer an answer.
Mad Scientist Todo List:
  • Finish Improved Event Handler
  • Implement DragonBones animation as a Creator Defined Container
  • Develop Cartoon Speech Bubble dialogue
  • Finish Bitmask collision and rebound vector system
  • Develop time based building mechanic
  • Others
  • *Find a superb artist and actually write a game*

User avatar
PoisionLullaby
Regular
Posts: 42
Joined: Wed Jan 10, 2018 9:11 pm
Projects: We're all human
Deviantart: PoisionLullaby
Contact:

Re: TypeError: getattr(): attribute name must be string

#5 Post by PoisionLullaby » Thu Jan 18, 2018 9:54 pm

Okay then thank you for trying. :)
~Everyone has bad days. Don't judge someone on that day and that day alone, judge them on their actions after it and onward.~

Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot]