Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AttributeError: 'RawBlock' object has no attribute 'statements' #197

Closed
zorbathut opened this issue Mar 6, 2024 · 12 comments
Closed

AttributeError: 'RawBlock' object has no attribute 'statements' #197

zorbathut opened this issue Mar 6, 2024 · 12 comments

Comments

@zorbathut
Copy link

Ran into an error when decompiling a free game. The full stacktrace:

Traceback (most recent call last):
  File "/data/bulky/games/x/util/unrpyc/unrpyc.py", line 260, in worker
    return decompile_rpyc(filename, args.clobber, args.dump, no_pyexpr=args.no_pyexpr,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/bulky/games/x/util/unrpyc/unrpyc.py", line 202, in decompile_rpyc
    decompiler.pprint(out_file, ast, options)
  File "/data/bulky/games/x/util/unrpyc/decompiler/__init__.py", line 54, in pprint
    Decompiler(out_file, options).dump(ast)
  File "/data/bulky/games/x/util/unrpyc/decompiler/__init__.py", line 109, in dump
    super(Decompiler, self).dump(ast, skip_indent_until_write=True)
  File "/data/bulky/games/x/util/unrpyc/decompiler/util.py", line 49, in dump
    self.print_nodes(ast)
  File "/data/bulky/games/x/util/unrpyc/decompiler/util.py", line 140, in print_nodes
    self.print_node(node)
  File "/data/bulky/games/x/util/unrpyc/decompiler/__init__.py", line 122, in print_node
    self.dispatch.get(type(ast), type(self).print_unknown)(self, ast)
  File "/data/bulky/games/x/util/unrpyc/decompiler/__init__.py", line 499, in print_init
    self.print_nodes(ast.block)
  File "/data/bulky/games/x/util/unrpyc/decompiler/util.py", line 140, in print_nodes
    self.print_node(node)
  File "/data/bulky/games/x/util/unrpyc/decompiler/__init__.py", line 122, in print_node
    self.dispatch.get(type(ast), type(self).print_unknown)(self, ast)
  File "/data/bulky/games/x/util/unrpyc/decompiler/__init__.py", line 170, in print_image
    self.print_atl(ast.atl)
  File "/data/bulky/games/x/util/unrpyc/decompiler/__init__.py", line 127, in print_atl
    self.linenumber = atldecompiler.pprint(
                      ^^^^^^^^^^^^^^^^^^^^^
  File "/data/bulky/games/x/util/unrpyc/decompiler/atldecompiler.py", line 7, in pprint
    return ATLDecompiler(out_file, options).dump(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/bulky/games/x/util/unrpyc/decompiler/atldecompiler.py", line 26, in dump
    self.print_block(ast)
  File "/data/bulky/games/x/util/unrpyc/decompiler/atldecompiler.py", line 45, in print_block
    if block.statements:
       ^^^^^^^^^^^^^^^^
AttributeError: 'RawBlock' object has no attribute 'statements'

If you'd like to reproduce it, grab https://hatchet-games.itch.io/maeves-academy and try decompiling the file goth_wardrobe.rpyc.

I'm using v2.0.0. Worked fine on all the other files, so it's probably not my environment.

(Thanks for the Py3 update!)

@madeddy
Copy link
Contributor

madeddy commented Mar 6, 2024

Ok, this was a breeze. I got this already and can make later a pull req for it.

Basically "RawBlock" can be without attrs(fix this and more will come) and we need now to check against it. Like in many other places in the last years.
I have the feeling that's not last we've seen of this type of bug.

Edit: A little bit too fast... With the fix (dev_fix_ish197) it decompiles without error but the resulting .rpy is "strange". A lot of image statement blocks without content.
goth_wardrobe.zip

madeddy added a commit to madeddy/unrpyc that referenced this issue Mar 6, 2024
@CensoredUsername
Copy link
Owner

Basically "RawBlock" can be without attrs(fix this and more will come) and we need now to check against it. Like in many other places in the last years.

Huh, I wonder what causes that. renpy should unconditionally assign self.statements in RawBlock.__init__.

I have a feeling more is afoot there.

@CensoredUsername
Copy link
Owner

Try decompiling that single file with legacy ;)

@madeddy
Copy link
Contributor

madeddy commented Mar 6, 2024

Damn.
I had the thought to try this, so why didn't i? 😩 So my other thought could very well also fit: A legacy game put on v8 without forced recompile, huh?

@zorbathut

  • Could you look in which Ren'Py version the previous game versions run? I'm curious.
  • To decompile this app you need to run the unrpyc legacy (v1.3 with python2).

@CensoredUsername
Copy link
Owner

To decompile this app you need to run the unrpyc legacy (v1.3 with python2).

No, only to decompile that single file. The rest was compiled with 8.1, go figure why.

@zorbathut
Copy link
Author

@zorbathut

* Could you look in which Ren'Py version the previous game versions run? I'm curious.

I'm afraid I don't actually have any older versions, nor do I see a way to get them off Itch.

* To decompile this app you need to run the unrpyc legacy (v1.3 with python2).

Aha, wild. Not going to worry about this for now then! Thanks for looking into it :)

@madeddy
Copy link
Contributor

madeddy commented Mar 6, 2024

No, only to decompile that single file.

Strange. I decompiled and astdumped everything error free with v1.3.0. Tested the game even a few minutes(fast skip) and encountered no issues. Very curious.

The rest was compiled with 8.1, go figure why.

Ah no. I found a few more in there from different dates all the way back to 2022, but the most are as you said. 🤷🏻 More riddles...

@CensoredUsername
Copy link
Owner

Strange. I decompiled and astdumped everything error free with v1.3.0. Tested the game even a few minutes(fast skip) and encountered no issues. Very curious.

Seems for everything I ripped out of either, both legacy and master are still pretty decent at decompiling stuff from either py2 or py3 based renpy. Honestly pretty surprising.

@zorbathut
Copy link
Author

Just FYI, I'm fine with this being either closed or kept open for discussion. If possible, though, I'd request some check to ensure you're using the right version - I'm certain I won't be the last person to report something that ends up being "wrong renpy version", and a more descriptive error message would go a long way to stop that.

This assumes there's a good way for code to tell which version the .rpyc is, though.

. . . although, given the discussion here, maybe with an optional flag to try anyway. Or do the check only on error.

@CensoredUsername
Copy link
Owner

I'm currently of the opinion that doing both is a good idea. I've added some detection, but the format makes it hard to detect all. That said, if we can't detect it, we might just be able to decompile it decently. The detection just prints a warning, and I'll add back a few pre ren'py 8 features (basically just ubiquitous parameter / argument handling). That will likely be enough to support basically every ren'py 7 game as well. Not sure how much more it'd be able to decently handle. 6.17 is the first I know it definitely won't as that requires old-style screenlang handling. Rest is some much more minor backwards compatibility hazards.

@CensoredUsername
Copy link
Owner

See #199

@CensoredUsername
Copy link
Owner

This has all been implemented.

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

No branches or pull requests

3 participants