-
Notifications
You must be signed in to change notification settings - Fork 158
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
Tracking issue for removal of ren'py 6/7 backwards compatibility in the ren'py 8 / python 3 move. #185
Comments
It seems to me the have blown userstatement out of proportion. Seeing my py3_port is in things of codebase outdated now, i don't think you will merge it like this. Would be to stressful. Some changes regarding py3 to keep in mind:
|
You can find the state of things on the dev branch rn, most things have already been processed. I'm looking through your py3 codebase for reference stuff, the actual changes are luckily not that invasive. |
Looks already good. I wasn't aware the codegen van also go besides sl1.
No wonder i pulled my hair over this if there are three ways. I wanted to find "the one" way after RenPy v8.0 and the set() didn't help.
This seems to have grown a bit powerful over time. I have some proposals beyond the port if you're interested. Do you want me to add it here or should i make a new ish.? Alternatively could you open the GH discussions feature for the repo, so we do not need to clutter the ishs for questions etc, |
I opened discussions, feel free to use it. |
Thanks! |
Man, I was not looking forward to handling this one (due to the sheer amount of black magic that I poured into it), but I'm going to merge dev into master, and cut new |
I can relate. Did try my hand on this ~two years back out of curiosity and just got frustrated following the errors through the "strange" code. Not easy. Didn't know if the bugs came from codegen/pickleast etc.
Good thing! Thanks for your work to get this running again! The pulls can be closed i think. The other is with four years also outdated, same for the game branches. |
Aight. |
it is maybe a little more complicated than it has to be 😅 When I originally built it the idea was to do as much work inside the pickle machinery as possible, but that proved to be rather complicated. I also really liked the idea of just making it as tiny as possible (the whole minimize-codegen step could just be skipped if you don't feel like it). And debugging is, well, not great. Ren'py has a tendency to swallow errors when loading rpyc files so you need to edit the source a little if you want those error messages. and even then, you're likely to have to deal with stuff like "On line 1, in something went wrong". Un.rpy is a little easier to debug as it's not quite as magical, although it still has to go through the steps of constructing a python package tree in software, which is what required the changes for python 3 (in python 2 relative imports and absolute could use the same syntax, so all modules were just loaded absolutely there, while now we actually construct the package properly). That said, all pickleast changes were basically an unrelated issue I found with the library, and I dealt with a deprecation warning. Minimize needed to deal with the new way arguments appear in the nodes, but in the end, the total changeset to the machinery was quite small since codegen/pickleast were already (mostly) py3 compatible. |
LOL. I had my share of this uselessness. Thats why i applauded the improvements in the last years in main-python versions for error outputs. Really useful! Something came to mind: Did you not mention something about the new Another note: So far i could not manage to get something useful out of this |
Any
Time to dig into the code then to figure out what it's doing ;)
Just imagine the quality of them when you're messing with the import machinery inside of a pickle bytecode. |
Understood. Thanks for explaining.
Thanks a lot, but there is no need to overdo it. I am merely curious.
Oh boy. This sounds hurtful. Uhhh... |
Ok, i have an ish which should be right here. I put my money on some py2 -> py3 residue and should be related to the open taskpoint about astdump. If i try to astdump this file from a Ren'Py v8.1.4 app, with unrpyc v2.0.0, on system-py v3.10: Error while decompiling /home/olli/.xlib/RPG/_test/Maeve-0.5.2-pc/game/characters_wardrobe/goth_wardrobe.rpyc:
Traceback (most recent call last):
File "/home/olli/Code/Git/unrpyc/unrpyc.py", line 183, in worker
return decompile_rpyc(filename, args.clobber, args.dump, no_pyexpr=args.no_pyexpr,
File "/home/olli/Code/Git/unrpyc/unrpyc.py", line 117, in decompile_rpyc
astdump.pprint(out_file, ast, comparable=comparable,
File "/home/olli/Code/Git/unrpyc/decompiler/astdump.py", line 29, in pprint
AstDumper(out_file, comparable=comparable, no_pyexpr=no_pyexpr).dump(ast)
File "/home/olli/Code/Git/unrpyc/decompiler/astdump.py", line 52, in dump
self.print_ast(ast)
File "/home/olli/Code/Git/unrpyc/decompiler/astdump.py", line 66, in print_ast
self.print_list(ast)
File "/home/olli/Code/Git/unrpyc/decompiler/astdump.py", line 102, in print_list
self.print_ast(obj)
File "/home/olli/Code/Git/unrpyc/decompiler/astdump.py", line 80, in print_ast
self.print_object(ast)
File "/home/olli/Code/Git/unrpyc/decompiler/astdump.py", line 216, in print_object
self.print_ast(getattr(ast, key))
File "/home/olli/Code/Git/unrpyc/decompiler/astdump.py", line 66, in print_ast
self.print_list(ast)
File "/home/olli/Code/Git/unrpyc/decompiler/astdump.py", line 102, in print_list
self.print_ast(obj)
File "/home/olli/Code/Git/unrpyc/decompiler/astdump.py", line 80, in print_ast
self.print_object(ast)
File "/home/olli/Code/Git/unrpyc/decompiler/astdump.py", line 216, in print_object
self.print_ast(getattr(ast, key))
File "/home/olli/Code/Git/unrpyc/decompiler/astdump.py", line 80, in print_ast
self.print_object(ast)
File "/home/olli/Code/Git/unrpyc/decompiler/astdump.py", line 206, in print_object
print(f"astdump print_object: {dir(ast)} ast: {ast}")
TypeError: '<' not supported between instances of 'str' and 'bytes'
Decompilation of 1 file failed |
What the hell, it's failing in the dir(ast) call. That's new. Oh, I figured it out. That RPYC file seems to have been compiled with ren'py 7. And then for some reason they upgraded the engine, and recompiled everything except for that file. If you look in the archive that file is from 14/03/2023 while the rest is from 06/01/2024. Truly delightful. |
Going through it, I'm surprised it fails this late honestly. For some reason, the normal AST nodes do get their attributes loaded as actual unicode strings, but atl nodes don't. I think this is due to a funny interaction between Adding an |
This stubbed me also and i could not even read this to get a handle on things.
Yeah. You said it all.
Agreed. Maybe @Gouvernathor could comment on the possibility of this?
I don't think unrpyc should support such chimeras. This way Py3-unrpyc is fast back where py2 was in ways of hacks and extra-code massacres. 😨 Or not? |
I can't help you with that. My knowledge about the rpyc format is very limited, and any such indication which would only help unauthorized decompilings will not be implemented within renpy, unless we require it for our purposes. That being said, there's a script_version file that's supposed to be included in all game distribs. We load it after ast and parsing time, but you could look for it directly and implement your own rules about it. |
Yeah I don't want to bother renpy devs with this, sorry for that. I'd like to keep my contributions to ren'py useful as well (I did prototype the first version of the ingame debugger with some friends), and not a burden to support. Besides, at this point it wouldn't fix the problem any more anyway, as we'd only know old files aren't versioned yet. I'm more inclined to just add a small option that detects most of these cases (BINSTRING/SHORT_BINSTRING opcodes in the pickle format are a tell, as python 3 doesn't generate those) and give a warning. We could still enable the option, and backport possibly some things back (old-style argument/parameter handling mainly). After all, when decompiling such a chimera we're not required to be backwards compatible with what we emit, which is what most ugly hacks were really for. You'd think old-style screen language support would be needed, but it actually isn't, because those are broken for several other reasons if you'd try to chimera it. Because the engine stores a python ast/bytecode blob directly for old-style screens, and that ast uses 2.7 nodes, while 3.9 ast nodes/bytecode are different. So it wouldn't be the worst to support it. Just adding back old style param/argument support and rpyc v1 handling (which is literally 1 line of code). |
Fair enough. Forget i asked.
No prob and my bad. Sry. I just didn't know the stance on this. |
Yes, but they still exist in the py3 pickle module, right ? Or is old-style screen support broken under Ren'py 8 ? |
Not sure what the py3 pickle module has to do with ast nodes, those are located in the ast module. Unless you mean the pickle import fixing machinery between py2-py3, that one doesn't handle this either. Just tested to confirm it, but yeah. Rpyc files with screenlang version 1 support are broken in ren'py 8. It'll fail to even load the rpyc file as it errors during unpickling. On a testcase I had, the result was:
(Or well, that's what it'd show if errors weren't swallowed if they happen in rpyc loading) Which makes sense. Ren'py stores very little data for old-style screen support in the rpyc file. A screenlang version 1 screen was internally a small piece of generated python code calling a bunch of The ast format of python has changed through the years, and it isn't the same between python 2 and 3. So when you unpickle a python 2 ast in python 3 it'll likely complain that it simply cannot find the definitions for a bunch of classes as they do not exist in python 3. This at least applies to the following ast nodes that exist in python 2.7, but not in 3.9:
Furthermore the following have changed their format and will likely fail to unpickle as well.
Now I don't think old-style screenlang generates any I can think of a few ways to deal with this, but none of them are easy or pretty. It can be done though, the legacy branch of this project actually supports decompiling these back to the internal python code, or even to the original source code. Feel free to borrow some of that. Edit: and of course the bytecode is completely incompatible as well, so no luck there either. |
@Gouvernathor I ended up thinking about it a bit more, and I think there's a solution that's not too terrible that could get these loaded again (just with a little rewriting of that ast at pickle load time). Sounds like a fun challenge, would there be any interest in that for Ren'py? |
Yes, if you can show that it fails to load now you can open it on the repo |
To get back to the original issue, I've removed some items that I'm considering reverting in #199 |
--sl1-as-python
: see above--tag-outside-block
: this flag is only relevant for ren'py 6.99-7.2renpy.python
: these were moved torenpy.revertable
in 8.0codegen
in decompiler. This was needed to support SL1 screens.Decompiler
that aren't necessary anymore.should_print_key
and see what is still relevant.More to come as I go through files.
Additional notes:
UserStatement
seems to have grown a lot of properties that we don't know about.The text was updated successfully, but these errors were encountered: