python-uncompyle6
python-uncompyle6 copied to clipboard
`return` in Python 3.8 in `try` ... `except`
Description
Hi! I'm trying to decompile a cog from my Discord bot which I overwrote by error. When using uncompyle, all classes except one (the longest one) were recovered. In the last one, I get the following output (I also attached the full output, and the full .pyc):
3708 POP_TOP
Parse error at or near `LOAD_CONST' instruction at offset 220
def setup(bot):
bot.add_cog(BRCog(bot))
The script raises an error exactly on the last two lines of the code, so there isn't anything after that.
How to Reproduce
$ uncompyle6 battleroyale.cpython-38.pyc > output.txt
# file battleroyale.cpython-38.pyc
# Deparsing stopped due to parse error
Environment
- OS: Ubuntu Server 20.04 LTS (focal)
- Python: Python 3.8.10 (default, Sep 28 2021, 16:10:42)
- Uncompyle6 version: version 3.8.1.dev0
According to Section 2 of https://www.epicgames.com/fortnite/en-US/eula:
You may not do or attempt to do any of the following with respect to the Software or any of its parts: (a) use it commercially or for a promotional purpose except as Epic expressly authorizes; (b) copy, reproduce, distribute (including via a network server), display, or use it in a way that is not expressly authorized in this Agreement; (c) sell, rent, lease, license, distribute, or otherwise transfer it; (d) reverse engineer, derive source code from, modify, adapt, translate, decompile, or disassemble it or make derivative works based on it
Hi! I know you may be confused by the name, but this have absolutely nothing to do with Fortnite, nor Epic Games. It's just a Discord text game which I made from scratch and it's an RNG game, and there are not even guns. I can provide older versions from a week ago as proof if you need them. It's in Spanish and there are no names, texts, images or anything related to Fortnite. Also Battle Royales didn't come from Fortnite, if I remember correctly there was a book called like that before Fortnite. Sorry if the name of the file caused any confusion.
Ok - I've deleted the label. Attach an old version. As for a bug report, this bytecode and source code is too large for a bug report here. Use the older source to see of you can create a small example that shows the bug.
Okay, already tested and the same error happens on the old source, the lines with problems seem to be the parts of the code where my async functions return None (lines 82, 107, 151), which raises the parse error. I manually deleted those 3 parts from the old source, recompiled the cache and tried with uncompyle, and now it works perfectly. Since those parts were also part of the lost version I am trying to recover, and the error is the same, I'm pretty sure the problems are those empty return.
Here it is the .pyc file of the old source:
battleroyale.cpython-38.zip
Ok - cool. The last thing for you to do before it would be looked at in a here is to narrow the part that doesn't decompile into the smallest possible number of lines and resulting in a short program. Can you get it less than 30 lines? Less than 10? Less than 5?
(All of this is mentioned in Narrowing the problem. You should read the entire document if you haven't already.
Here it is:
import discord
from discord.ext import commands
import asyncio
class BRCog(commands.Cog):
async def battle(self, ctx):
try:
await self.bot.wait_for('reaction_add')
except asyncio.TimeoutError:
await ctx.send("a")
return
def setup(bot):
bot.add_cog(BRCog(bot))
And here it is the .pyc, and the output (although the error is the same, LOAD_CONST)
output.zip
I also noticed that when you remove the await ctx.send("a"), or the return, the .py is exported succesfully.
I was able to narrow it even more:
import asyncio
def BRCog():
try:
1+1
except asyncio.TimeoutError:
asyncio.read()
return
I have some preliminary fixes, for some of the simpler code, But more work is needed for the more complex situations.
At any rate fixes will appear in the decompyle3 project - eventually.
Sounds good, I also follow the other repo so I'll be looking into that.
By now, is there a way to remove those lines from the .pyc or ignore the errors? Since all of the other parts of the code are being parsed correctly except that one.
Seems like a useful feature for someone to add. Hey, how about you?