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
OldFootnote
Newbie
Posts: 5
Joined: Mon Apr 16, 2018 1:36 am
Contact:

getattr(): Attribute name must be string

#1 Post by OldFootnote »

Hi everybody!

I'm a big Ren'py newbie, and I have a problem that I can't pin down and I was hoping to get a little guidance.

Here's the traceback:

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script.rpy", line 253, in script
    "What would you like to do today?"
  File "renpy/common/000window.rpy", line 98, in _window_auto_callback
    _window_show()
  File "renpy/common/000window.rpy", line 60, in _window_show
    renpy.with_statement(trans)
  File "renpy/common/00action_data.rpy", line 50, in get_selected
    return getattr(self.object, self.field) == self.value
TypeError: getattr(): attribute name must be string

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

Full traceback:
  File "game/script.rpy", line 253, in script
    "What would you like to do today?"
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\ast.py", line 590, in execute
    statement_name("say")
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\ast.py", line 43, in statement_name
    i(name)
  File "renpy/common/000window.rpy", line 98, in _window_auto_callback
    _window_show()
  File "renpy/common/000window.rpy", line 60, in _window_show
    renpy.with_statement(trans)
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\exports.py", line 1406, in with_statement
    return renpy.game.interface.do_with(trans, paired, clear=clear)
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\display\core.py", line 2123, in do_with
    clear=clear)
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\display\core.py", line 2553, in interact
    repeat, rv = self.interact_core(preloads=preloads, trans_pause=trans_pause, **kwargs)
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\display\core.py", line 2821, in interact_core
    root_widget.visit_all(lambda i : i.per_interact())
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\display\core.py", line 495, in visit_all
    d.visit_all(callback)
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\display\core.py", line 495, in visit_all
    d.visit_all(callback)
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\display\core.py", line 495, in visit_all
    d.visit_all(callback)
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\display\core.py", line 495, in visit_all
    d.visit_all(callback)
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\display\screen.py", line 405, in visit_all
    self.child.visit_all(callback)
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\display\core.py", line 495, in visit_all
    d.visit_all(callback)
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\display\core.py", line 497, in visit_all
    callback(self)
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\display\core.py", line 2821, in <lambda>
    root_widget.visit_all(lambda i : i.per_interact())
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\display\behavior.py", line 796, in per_interact
    if self.is_selected():
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\display\behavior.py", line 786, in is_selected
    return is_selected(self.action)
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\display\behavior.py", line 356, in is_selected
    return any(is_selected(i) for i in action)
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\display\behavior.py", line 356, in <genexpr>
    return any(is_selected(i) for i in action)
  File "C:\Users\ItsMeFootnote\renpy-6.99.13-sdk\renpy\display\behavior.py", line 359, in is_selected
    return action.get_selected()
  File "renpy/common/00action_data.rpy", line 50, in get_selected
    return getattr(self.object, self.field) == self.value
TypeError: getattr(): attribute name must be string

Windows-8-6.2.9200
Ren'Py 6.99.13.2919
the error looks a little generic, so I'm not sure what information I should include, so I'm erring on the side of too much information.

here's what I think are the relevant pieces of code.

Code: Select all

label maincycle:
    
    if day == 1:
        jump dayoneafter
    elif day == 2 and tutorial == False:
        jump daytwo
    else:
        pass
            
    scene bg office
    
    show desk onlayer table
    
    show screen guiscreen
    
    "What would you like to do today?"
this code is supposed to act as the main hub of the game (it's sort of a resource management type thing) where the player decides what to do during a specific day. Most of the labels in my game ultimately jump here.

the 'guiscreen' is modal True (because otherwise the text advances with every click instead of pausing and waiting for a player to make a decision) and it contains buttons that allow the player to talk and command characters, manage resources, etc.

here's the part of the code that is running when the error pops up. It runs when the player chooses to chat with an ally character:

Code: Select all

label allychat:
    
    hide screen guiscreen
    
    if haircut == True:
        show ally neutral smile short clasp
    elif nohaircut == True:
        show ally neutral smile long hip
        
    if checkpoint0 == False and haircut == True:
        
        [[Dialogue happens here]]
        
        $ tutorial = True
        
        $ advance = True
        
        jump maincycle
the crash happens after I click through the last line of dialogue. The tutorial flag is there to make sure I don't get stuck in a loop once ren'py jumps back to the maincycle during day 2, and the advance flag makes it so that the player is unable to do any more actions. When it's switched to True it triggers an 'if/else' statement within guiscreen that makes a button appear that advances the game into the next day. the checkpoint0 flag is basically how I make characters talk about certain events that pertain to the story (in this case, checkpoint0 is what I use as a default for when talking to a character doesn't advance the story.)

finally, here's the code for guiscreen. I'm not sure if it's responsible for the crash, but I have a hunch. mostly because I kind of wing it when making screens.

Code: Select all

screen guiscreen():
    modal True
    frame:
        xpadding 10
        ypadding 10
        xalign 0.9
        yalign 0.4
        
        vbox:
            spacing 20
            imagebutton idle "images/gui/allyicon.png" action Jump("allymenu")
            imagebutton idle "images/gui/villagericon.png" action Jump("villagermenu")
            

    text "Day [day]" xalign .9 yalign .05 size 40
    if advance == True:
        imagebutton auto "images/gui/advancearrow_%s.png" xalign .9 yalign .71 action [SetVariable(advance, False), Function(dayadd), Jump("infoscreen")]
the imagebuttons in the vbox jump to a menu where you can either chat with characters or tell them to do something. Right now I only have the 'chat' part coded. the 'command' part just says something like 'Not implemented' and jumps back to the menu.

the 'advance' imagebutton does a few things. It resets the advance flag to false so the arrow disappears once clicked. it also runs 'dayadd' which just adds 1 to the day counter, and finally it jumps to the 'infoscreen' label where the player's decisions take effect and they're told the consequences. This label is nothing but a bunch of functions and text.

Sorry for being so long winded but I honestly can't figure out the problem. I'm pretty sure it has something to do with 'allychat' jumping to 'maincycle' since when I change it so that 'allychat' jumps to another label it works fine.

I really hope the answer is simple. Though not too simple. I'd die of embarrassment if I had you read all this only for the error to amount to a misspelling or something.

Thanks in advance!

kivik
Miko-Class Veteran
Posts: 786
Joined: Fri Jun 24, 2016 5:58 pm
Contact:

Re: getattr(): Attribute name must be string

#2 Post by kivik »

I think it's here:

Code: Select all

imagebutton auto "images/gui/advancearrow_%s.png" xalign .9 yalign .71 action [SetVariable(advance, False), Function(dayadd), Jump("infoscreen")]
I blame the documentation here, but it's not obvious that SetVariable takes a string with the name of the variable. So it actually needs to be:

Code: Select all

imagebutton auto "images/gui/advancearrow_%s.png" xalign .9 yalign .71 action [SetVariable("advance", False), Function(dayadd), Jump("infoscreen")]

OldFootnote
Newbie
Posts: 5
Joined: Mon Apr 16, 2018 1:36 am
Contact:

Re: getattr(): Attribute name must be string

#3 Post by OldFootnote »

Thank You!

It worked like a charm.

Looks like it was something simple, after all.

Seriously, I can't thank you enough. This error bugged me for an hour before I finally decided to ask for help here.

kivik
Miko-Class Veteran
Posts: 786
Joined: Fri Jun 24, 2016 5:58 pm
Contact:

Re: getattr(): Attribute name must be string

#4 Post by kivik »

No problems! Only simple if you've been plagued by it before :P

There's no way you would have known since documentation fully implies your code should work :(

Post Reply

Who is online

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