Closed codepainters closed 11 years ago
Note: the following hack made it work for me (yet the code is fairly complex, I'm not sure if it doesn't break anything):
diff --git a/uncompyle2/Parser.py b/uncompyle2/Parser.py
index 89fc675..3aced10 100755
--- a/uncompyle2/Parser.py
+++ b/uncompyle2/Parser.py
@@ -136,6 +136,7 @@ class Parser(GenericASTBuilder):
stmt ::= genexpr_func
genexpr_func ::= LOAD_FAST FOR_ITER designator comp_iter JUMP_BACK
+ genexpr_func ::= LOAD_FAST FOR_ITER designator comp_iter JUMP_BACK JUMP_BACK
'''
diff --git a/uncompyle2/Scanner25.py b/uncompyle2/Scanner25.py
index 8e74051..9fc3f4d 100755
--- a/uncompyle2/Scanner25.py
+++ b/uncompyle2/Scanner25.py
@@ -321,8 +321,12 @@ class Scanner:
if self.code[i+3] == LOAD_FAST and self.code[i+6] == FOR_ITER:
end = self.first_instr(i, len(self.code), RETURN_VALUE)
end = self.first_instr(i, end, YIELD_VALUE)
- if end and self.code[end+1] == POP_TOP and self.code[end+2] == JA and self.code[end+5] == POP_BLOCK:
- return [i,end+5]
+ # At this point 'end' points to YIELD_VALUE
+ if end and self.code[end+1] == POP_TOP and self.code[end+2] == JA:
+ if self.code[end+5] == POP_BLOCK:
+ return [i,end+5]
+ elif self.code[end+5] == POP_TOP and self.code[end+6] == JA and self.code[end+9] == POP_BLOCK:
+ return [i,end+9]
# with stmt
if opcode == WITH_CLEANUP:
chckDel = i-self.op_size(DELETE_NAME)
This is patched. The grammar handle bytecode version 2.7 so I won't change it. But I've change bytecode 2.5 & 2.6 disassembly and translation.
Yeah, I understand that - yet for me the quickest solution was to tweak the grammar :)
Is your solution to delete the second POP_TOP/JA pair?
In your case I delete :
0 SETUP_LOOP '30' 26 JUMP_BACK '6' 29 POP_BLOCK None
And the FOR_ITER has to be modificated. But I don't do this in all case. If I do, some FOR loop won't work anymore. I apply the patch only when there is no GET_ITER between SETUP_LOOP and FOR_ITER instruction.
# conditional tuple
if self.code[i] == JA and self.code[i+opsize] == POP_TOP \
and self.code[i+opsize+1] == JA and self.code[i+opsize+4] == POP_BLOCK:
jmpabs1target = self.get_target(i)
jmpabs2target = self.get_target(i+opsize+1)
if jmpabs1target == jmpabs2target and self.code[jmpabs1target] == FOR_ITER:
destFor = self.get_target(jmpabs1target)
if destFor == i+opsize+4:
setupLoop = self.last_instr(0, jmpabs1target, SETUP_LOOP)
standarFor = self.last_instr(setupLoop, jmpabs1target, GET_ITER)
if standarFor == None:
self.restructJump(jmpabs1target, destFor+self.op_size(POP_BLOCK))
toDel += [setupLoop, i+opsize+1, i+opsize+4]
I've check the whole python standard library and this solution work well. But I think tuple loop detection can be more efficient.
how to convert pyo and pyc files to py file using uncompyle2 in python2.7 for windows xp
@Ophidiophobia thank you. I installed unompyle2-master according to the steps given in https://github.com/Mysterie/uncompyle2#usage . In that i dont know where to enter the usage comment (uncompyle2 --help)
Then i used uncompyle2 to convert pyo file to py file in following steps:
usr/bin/folder/xyz.pyc > xyz.py (this comment is producing a empty py file and i am getting a runtime error:bad magic number in .pyc)
Please suggest solution for this :)
I don't understand what you're trying to do. But for using uncompyle2 you just have to do ./uncompyle2.py /path/xyz.pyc. The windows version of the projet isn't perfect for the moment.
The bad magic number suggest that it's not a valid pyc file.
PS: can you open a new issue, or your bug is related to the conditional tuple patch ?
Well here are your commands: open the console run "<path_to_python27_directory>\python.exe <path_to_python27_directory>\Scripts\uncompyle2 --help" replace <path_to_python27_directory> with the path to your own python directory. I do not know where you installed it. In my case it would be "C:\Program Files\Python27"\ (including the "s because of the space char in the path) reason: on linux you can python scripts directly on the console, on windows maybe but I want to be sure thats why this command calls python explicitly to run the uncompyle2 script that should be installed in the subdirectory Scripts of your Python27 installation. If it cannot find python then you put in a wrong path. If it cannot find uncompyle2 then locate uncompyle2 yourself. that will display the commands. Read them. next run <path_to_python27_directory>\python.exe <path_to_python27_directory>\Scripts\uncompyle2 -o <path_of_output_dir> <path> <path_you_never_told>\usr\bin\folder\xyz.pyc
You can probably drop the [...]\python.exe part but that depends on your python installation.
Why are you using suddenly using linux path seperators if you are using windows xp??? Why did you try "usr/bin/folder/xyz.pyc > xyz.py" as command? Did anybody tell you to do this? Are you aware of what the command is actually going to do? If you read it somewhere then where? So far your problem is not using uncompile but how to use python.
EDIT: fixed greater than and less than chars which caused github to remove some textparts from my comment and made the paths look wrong.
@Ophidiophobia my issue is somewhat related to this topic thats why i asked here
I fail to see how. Please create a new issue where everybody can stick to your problem. Your problem IS NOT related to this one here.
Current version of uncompyle2 fails to handle the following piece of code compiled with Python 2.5:
The corresponding bytecode:
Assembler from uncompyle -a:
There are 2 issues here: