### Install uncompyle6 using Make Source: https://github.com/rocky/python-uncompyle6/blob/master/README.rst The provided GNU Makefile simplifies the installation process. This command may require root or sudo privileges. ```bash make install ``` -------------------------------- ### CPython Bytecode Example Source: https://github.com/rocky/python-uncompyle6/wiki/Deparsing-technology-and-its-use-in-exact-location-reporting Illustrates a simple sequence of CPython virtual-machine instructions. ```assembly LOAD_CONST 0 STORE_NAME a ``` -------------------------------- ### Check Package Installation from Git Source: https://github.com/rocky/python-uncompyle6/wiki/Releasing Install the package in editable mode from a Git repository, check its version, and then uninstall it. ```bash pushd /tmp/gittest pip install -e git+https://github.com/rocky/python-uncompyle6.git#egg=uncompyle6 uncompyle6 --version uncompyle6 src/uncompyle6/__pkginfo.py pip uninstall uncompyle6 popd ``` -------------------------------- ### For Loop Location Example Source: https://github.com/rocky/python-uncompyle6/wiki/Project-Focus Illustrates how to pinpoint the exact location within a line of code, specifically the start of the 'for' keyword in a for loop. ```python for i in range(2): ^ ``` -------------------------------- ### Variable Initialization Example Source: https://github.com/rocky/python-uncompyle6/wiki/expected-decompile-differences Illustrates variable assignments that might be subject to compile-time computation differences across Python versions. ```python LINE_WIDTH = 80 last_index = LINE_WIDTH - 1 ``` -------------------------------- ### Parse Tree Compaction Example (Singleton Rules) Source: https://github.com/rocky/python-uncompyle6/wiki/How-does-this-code-work? Demonstrates the removal of singleton rules to simplify the parse tree, making it more direct and readable. ```text stmt ::= ifelsestmt _stmts ::= stmt suite_stmts ::= _stmts ``` -------------------------------- ### Example sequence for building a list Source: https://github.com/rocky/python-uncompyle6/wiki/How-does-this-code-work? Illustrates a sequence of opcodes for building a list, showing the challenge for context-free parsers with variable operand counts. ```python 8 LOAD_CONST 1 10 LOAD_CONST 2 12 LOAD_CONST 3 14 BUILD_LIST_3 3 ``` -------------------------------- ### Python Division Example Source: https://github.com/rocky/python-uncompyle6/wiki/Deparsing-Paper Illustrates a Python expression with multiple divisions, showing how to pinpoint specific operators. ```python x = a / b / c - ``` ```python x = a / b / c - ``` -------------------------------- ### Install uncompyle6 from Source Source: https://github.com/rocky/python-uncompyle6/blob/master/README.rst Use this command to set up uncompyle6 for development or direct use from the source tree. Ensure you have checked out the correct Git branch for your Python version. ```bash pip install -e . ``` -------------------------------- ### Parse Tree Compaction Example (List) Source: https://github.com/rocky/python-uncompyle6/wiki/How-does-this-code-work? Illustrates how sequential statements are compacted into a single list head with its items, rather than a chain of nested lists. ```text stmts ::= stmts stmt stmts ::= stmt ``` ```text stmts stmts stmts stmt stmt stmt ``` ```text stmts stmt stmt stmt ``` -------------------------------- ### Install uncompyle6 for Python 3.11+ Source: https://github.com/rocky/python-uncompyle6/blob/master/README.rst Use pip to install uncompyle6 for recent Python releases (Python 3.11 and later). ```bash pip install uncompyle6 ``` -------------------------------- ### Python For Loop Example Source: https://github.com/rocky/python-uncompyle6/wiki/Deparsing-Paper Illustrates a common Python loop structure. This example is used to explain how a decompiler might handle variable initialization and increment, even if they appear only once in the source. ```python for i in range(10): print(i) ``` -------------------------------- ### Python 2.6 Bytecode Example Source: https://github.com/rocky/python-uncompyle6/wiki/How-does-this-code-work? This is an example of Python 2.6 bytecode for a list comprehension. It shows the raw bytecode instructions. ```python 1: 0 BUILD_LIST 0 3 LOAD_FAST (.0) >> 6 FOR_ITER (to 21) 1: 9 STORE_FAST (c) 12 LOAD_FAST (c) 15 LIST_APPEND 2 18 JUMP_ABSOLUTE (to 6) >> 21 RETURN_VALUE ``` -------------------------------- ### Optimized Code Example with Hoisted Division Source: https://github.com/rocky/python-uncompyle6/wiki/Debugging-Optimized-Code Illustrates a scenario in optimized code where a division operation is hoisted and potentially replaced by a temporary variable. This example is useful for understanding how to debug issues arising from code transformations. ```Ruby d = .... ... t1 = x / d # hoisted code ... if ... ... x / d # or code replacing this with t1 else .... x / d # or code replacing this with t1 end ``` -------------------------------- ### Analyze uncompyle2 AST Output Source: https://github.com/rocky/python-uncompyle6/wiki/Fixing-Issue- Example AST tree output from uncompyle2, showing a valid reduction path ('c_stmts_opt', 'c_stmts', '_stmts', 'stmt'). This is compared against uncompyle6's output. ```text c_stmts_opt c_stmts _stmts stmt ``` -------------------------------- ### Uncompyle6 Tree Structure Example Source: https://github.com/rocky/python-uncompyle6/wiki/Adding-a-tree-transformation-phase-to-uncompyle6 Shows the internal tree representation generated by uncompyle6 when the --tree+ option is used, highlighting the structure of if-else statements. ```text ifelsestmt (5) 0. testexpr testfalse (2) 0. expr L. 1 0 LOAD_NAME 0 'x' 1. jmp_false (2) 0. 3 JUMP_IF_FALSE 4 'to 10' 1. 6 POP_TOP 1. pass 2. jf_cf_pop (3) 0. L. 2 7 JUMP_FORWARD 23 'to 33' 1. 10_0 COME_FROM 3 '3' 2. 10 POP_TOP 3. else_suite suite_stmts ifelsestmt (5) 0. testexpr testfalse (2) ... 1. pass 2. jf_cf_pop (3) ... 3. else_suite suite_stmts ifstmt (2) 0. testexpr_then ... ... ``` -------------------------------- ### Python List Comprehension Example Source: https://github.com/rocky/python-uncompyle6/wiki/Deparsing-Paper Demonstrates a Python list comprehension with a conditional filter, showing how to highlight specific parts of the expression. ```python [x[0] for i in d[j] if got[i] == e[i]] ----- ``` ```python [x[0] for i in d[j] if got[i] == e[i]] ------------- ``` ```python [x[0] for i in d[j] if got[i] == e[i]] ----- ``` ```python [x[0] for i in d[j] if got[i] == e[i]] ----- ``` ```python [x[0] for i in d[j] if got[i] == e[i]] ------ ``` ```python [x[0] for i in d[j] if got[i] == e[i]] ---- ``` -------------------------------- ### Analyze Initial Pseudo-Assembly Instructions Source: https://github.com/rocky/python-uncompyle6/wiki/Fixing-Issue- Examine the initial pseudo-assembly instructions in the debug log. This section often contains setup code for generator calls and can typically be skipped when focusing on parser errors. ```text L. 1 0 LOAD_CONST 'spam, Spam, SPAM!' 3 BUILD_LIST_1 1 6 STORE_NAME 0 'x' ``` -------------------------------- ### Release on GitHub and Test Tagged Version Source: https://github.com/rocky/python-uncompyle6/wiki/Releasing Create a new release on GitHub using the latest tag. Install the package from the tagged Git commit and verify its functionality. ```bash pushd /tmp/gittest pip install -e git+https://github.com/rocky/python-uncompyle6.git@$__version__#egg=uncompyle6 uncompyle6 --version uncompyle6 src/uncompyle6/__pycache__/__pkginfo__.cpython-38.pyc pip uninstall uncompyle6 popd ``` -------------------------------- ### Go AST Pos Type Example Source: https://github.com/rocky/python-uncompyle6/wiki/Deparsing-Paper Demonstrates the concept of the `Pos` type in Go's Abstract Syntax Tree (AST) package, which compactly encodes line number, file name, and column number. ```go The [Pos type](https://golang.org/pkg/go/token/#Pos) in Go's AST is more informative in that it encodes the line number, file name and column number all very compactly as a pointer. Even better, though, would be to extend this interval or pointer to a tuple of _Pos_'s. Go's implementation cleverly takes advantage of the property that the number of interesting locations in a program, whether a single point or a pair of points, is much smaller than the program's total number of bytes. ``` -------------------------------- ### Verify Decompilation Correctness Source: https://context7.com/rocky/python-uncompyle6/llms.txt Verify decompilation correctness by syntax checking or running the decompiled code. This example demonstrates batch decompilation with syntax verification and individual file syntax checking. ```python from uncompyle6.main import main, decompile, syntax_check import tempfile import os # Decompile with syntax verification (total, okay, failed, verify_failed) = main( in_base=".", out_base=tempfile.mkdtemp(), compiled_files=["example.pyc"], source_files=[], do_verify="syntax" # "syntax" or "run" ) print(f"Total: {total}, Okay: {okay}, Failed: {failed}") print(f"Verification failures: {verify_failed}") # Verify a single decompiled file with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f: # Write decompiled source f.write("x = 1\ny = 2\nprint(x + y)\n") temp_path = f.name # Syntax check is_valid = syntax_check(temp_path) print(f"Syntax valid: {is_valid}") os.unlink(temp_path) ``` -------------------------------- ### Bytecode Deparsing Output Example Source: https://github.com/rocky/python-uncompyle6/wiki/Deparsing-technology-and-its-use-in-exact-location-reporting Shows the deparsed output for a specific opcode within the Fibonacci function, indicating the context of the operation. ```text opcode: CALL_FUNCTION_1 return fib(x - 1) + fib(x - 2) ---------- Contained in... return fib(x - 1) + fib(x - 2) ----------------------- parsed type: binary_expr ``` -------------------------------- ### Examine Grammar Reductions (Bad Case) Source: https://github.com/rocky/python-uncompyle6/wiki/Fixing-Issue- Focus on grammar reductions that occur after the initial setup. This snippet shows the reductions in the non-working Python 2.6 case, highlighting potential areas of divergence. ```text 3 expr ::= LOAD_FAST (2) 3 ret_expr ::= expr (2) 3 assert_expr ::= expr (2) 9 store ::= STORE_FAST (4) 12 expr ::= LOAD_FAST (5) 15 expr ::= LOAD_CONST (6) 12-18 compare_single ::= expr expr COMPARE_OP (7) 12 compare ::= compare_single (7) 12 expr ::= compare (7) ``` -------------------------------- ### Python Opcode Deparsing Example Source: https://github.com/rocky/python-uncompyle6/wiki/Deparsing-Paper Shows how a specific Python opcode, JUMP_ABSOLUTE, is deparsed into a simple conditional statement. ```python JUMP_ABSOLUTE = 100 ... if op == JUMP_ABSOLUTE: ... ``` ```python if op == 100: ``` -------------------------------- ### Ambiguous Decompilation Example Source: https://github.com/rocky/python-uncompyle6/wiki/How-does-this-code-work? Demonstrates how different Python source codes can result in the same bytecode, leading to ambiguity during decompilation. This is particularly relevant when dealing with conditional logic. ```python if a and b: y = 1 ``` ```python if a: if b: y = 1 ``` -------------------------------- ### Analyze uncompyle6 Output Source: https://github.com/rocky/python-uncompyle6/wiki/Fixing-Issue- Example log output from uncompyle6 showing grammar reductions and stack states, indicating a potential parsing error ('Reduce _stmts invalid by check'). ```text L. 4: 10 assert_expr ::= expr (6) L. 4: 10-16 call_stmt ::= expr POP_TOP (7) L. 4: 10 stmt ::= call_stmt (7) L. 3: 6-16 _stmts ::= _stmts stmt (7) Reduce _stmts invalid by check ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Stacks of completed symbols: LOAD_FAST . LOAD_FAST . FOR_ITER store comp_iter JUMP_BACK LOAD_GLOBAL . ``` -------------------------------- ### Optimized list building with COLLECTION_START Source: https://github.com/rocky/python-uncompyle6/wiki/How-does-this-code-work? Demonstrates an optimized sequence for building a list using COLLECTION_START and ADD_VALUE pseudo-instructions to simplify grammar rules and improve parsing efficiency. ```python 8_0 COLLECTION_START 0 'CONST_LIST' 8 ADD_VALUE 1 1 10 ADD_VALUE 2 2 12 ADD_VALUE 3 3 14 ADD_VALUE 4 4 16 ADD_VALUE 5 5 18 BUILD_CONST_LIST 5 ``` -------------------------------- ### Python Code Example with Potential IndexError Source: https://github.com/rocky/python-uncompyle6/wiki/Deparsing-Paper Illustrates a Python code snippet that can lead to an 'IndexError: list index out of range'. This example is used to highlight the ambiguity of traditional error reporting. ```python prev = [100] + range(3) def boom(p): x = prev[prev[p]] ... ``` -------------------------------- ### Display uncompyle6 Help Source: https://github.com/rocky/python-uncompyle6/blob/master/README.rst Use this command to view the help message and available options for uncompyle6. ```bash uncompyle6 -h ``` -------------------------------- ### Python 2.7 SETUP_LOOP Opcode Handling in uncompyle2 Source: https://github.com/rocky/python-uncompyle6/wiki/The-Control-Flow-Mess This snippet demonstrates complex logic for handling the SETUP_LOOP opcode in Python 2.7 bytecode. It involves calculating jump targets and loop boundaries, with specific considerations for return statements within loops. This code is highly version-specific to Python 2.7. ```python if op == SETUP_LOOP: #import pdb; pdb.set_trace() start = pos+3 target = self.get_target(pos, op) end = self.restrict_to_parent(target, parent) if target != end: self.fixed_jumps[pos] = end (line_no, next_line_byte) = self.lines[pos] jump_back = self.last_instr(start, end, JA, next_line_byte, False) if jump_back and jump_back != self.prev[end] and code[jump_back+3] in (JA, JF): if code[self.prev[end]] == RETURN_VALUE or \ (code[self.prev[end]] == POP_BLOCK and code[self.prev[self.prev[end]]] == RETURN_VALUE): jump_back = None if not jump_back: # loop suite ends in return. wtf right? jump_back = self.last_instr(start, end, RETURN_VALUE) + 1 if not jump_back: return if code[self.prev[next_line_byte]] not in (PJIF, PJIT): loop_type = 'for' else: loop_type = 'while' self.ignore_if.add(self.prev[next_line_byte]) target = next_line_byte end = jump_back + 3 else: if self.get_target(jump_back) >= next_line_byte: jump_back = self.last_instr(start, end, JA, start, False) if end > jump_back+4 and code[end] in (JF, JA): if code[jump_back+4] in (JA, JF): if self.get_target(jump_back+4) == self.get_target(end): self.fixed_jumps[pos] = jump_back+4 end = jump_back+4 elif target < pos: self.fixed_jumps[pos] = jump_back+4 end = jump_back+4 ``` -------------------------------- ### Fibonacci Function Example Source: https://github.com/rocky/python-uncompyle6/wiki/Deparsing-technology-and-its-use-in-exact-location-reporting A Python function used to illustrate bytecode deparsing results. ```python def fib(x): if x <= 1: return 1 return fib(x-1) + fib(x-2) ``` -------------------------------- ### Setting Class Variable Source: https://github.com/rocky/python-uncompyle6/wiki/Project-Focus An example of setting a class variable within a class definition in Python. ```python __module__ = __name__ ``` -------------------------------- ### Run Tests with Make Source: https://github.com/rocky/python-uncompyle6/blob/master/README.rst Execute the test suite using the GNU Makefile. This command runs tests from fastest to slowest. ```bash make check ``` -------------------------------- ### Python Code for Assertion Transformation Source: https://github.com/rocky/python-uncompyle6/wiki/Adding-a-tree-transformation-phase-to-uncompyle6 Example of Python code where `if not expr: RaiseAssertion` is transformed into `assert expr`. ```python if not expr: RaiseAssertion ... ``` -------------------------------- ### Build and Check Packages Source: https://github.com/rocky/python-uncompyle6/wiki/Releasing Build distribution packages for various Python versions, check them with twine, and tag releases. ```bash ./admin-tools/make-dist-2.4-2.7.sh pyenv local 3.9 twine check dist/uncompyle6-$__version__* git tag release-python-2.4-$__version__ ./admin-tools/make-dist-3.0-3.2.sh git tag release-python-3.0-$__version__ ./admin-tools/make-dist-3.3-3.5.sh git tag release-python-3.3-$__version__ ./admin-tools/make-3.6-3.10.sh git tag release-python-3.6-$__version__ ./admin-tools/make-dist-newest.sh twine check dist/uncompyle6-$__version__* ``` -------------------------------- ### Run Verification with uncompyle6 CLI Source: https://context7.com/rocky/python-uncompyle6/llms.txt Decompile and immediately run the resulting code to verify correctness using the `--verify run` option. ```bash uncompyle6 --verify run example.pyc ``` -------------------------------- ### Augmented For Loop Grammar Rule Source: https://github.com/rocky/python-uncompyle6/wiki/Project-Focus An example of an augmented grammar rule for a for statement, showing how to incorporate location information copying using '%x'. ```text 'forstmt': ( '%|for %c in %c:\n%+%c%-\n\n%x', 3, 1, 4, (3,(2) ), ^^ ^^^^^^ ``` -------------------------------- ### Decompiled Python Code with Valid Parameter Source: https://github.com/rocky/python-uncompyle6/wiki/How-does-this-code-work? This example shows the decompiled Python code with the invalid lambda parameter '.0' changed to 'x' for validity. ```python (lambda x [ c for c in x ])(__file__) ``` -------------------------------- ### Python `if ... return` vs `if .. return; else` Source: https://github.com/rocky/python-uncompyle6/wiki/Equivalent-code Illustrates the difference in bytecode generation between a simple `if ... return` and an `if ... else` structure. ```python if x: # some code ... return # some other code ... ``` ```python if x: # some code else: # some other code ``` -------------------------------- ### Location Reporting for Docstring Bytecode Source: https://github.com/rocky/python-uncompyle6/wiki/Project-Focus Demonstrates how deparsing can pinpoint specific code locations within a line, using the docstring example to show offsets. ```python __doc__ = "this is my docstring" ^^^^^^^^^^^^^^^^^^^^^^ ``` ```python __doc__ = "this is my docstring" ^^^^^^^ ``` -------------------------------- ### Decompiler Tree for (a*x)**2 Source: https://github.com/rocky/python-uncompyle6/wiki/Operator-Precedence Shows the abstract syntax tree for '(a*x)**2', demonstrating how operator precedence affects the tree structure and the need for parentheses. ```text 1 expr 2 bin_op (BINARY_POWER, precedence 4) 3 0. expr 4 bin_op (BINARY_MULTIPLY, precedence 8) 5 0. expr 6 L. 1 0 LOAD_NAME a 7 1. expr 8 2 LOAD_NAME x 9 2. binary_operator 10 4 BINARY_MULTIPLY 11 1. expr 12 constant 13 6 LOAD_CONST 2 14 2. binary_operator 15 8 BINARY_POWER ``` -------------------------------- ### Python Expression in Function Call Source: https://github.com/rocky/python-uncompyle6/wiki/Operator-Precedence An example of an expression used as an argument within a function call, illustrating that operator precedence rules apply within the expression itself. ```python sin(2 * theta) + pi ``` -------------------------------- ### Decompile with Parse Tree Visualization using decompile_file() Source: https://context7.com/rocky/python-uncompyle6/llms.txt Enable visualization of the parse tree (before, after, or both) during decompilation using the `showast` parameter. ```python import sys from uncompyle6 import decompile_file # Decompile with parse tree visualization deparsed = decompile_file( "example.pyc", outstream=sys.stdout, showast={"before": True, "after": True} ) ``` -------------------------------- ### Python 'if' statement condition check Source: https://github.com/rocky/python-uncompyle6/wiki/The-Control-Flow-Mess Example of checking the condition of an 'if' statement in Python, specifically verifying that the conditional jump leads to the 'else' block. ```python # Check that the condition portion of the "if" # jumps to the "else" part. if testexpr[0] in ("testtrue", "testfalse"): if_condition = testexpr[0] else_suite = ast[3] assert else_suite.kind.startswith("else_suite") ... ``` -------------------------------- ### Examine Grammar Reductions (Good Case) Source: https://github.com/rocky/python-uncompyle6/wiki/Fixing-Issue- Compare the grammar reductions in the working Python 2.7 case. This snippet shows the corresponding reductions, useful for identifying differences that lead to decompilation success. ```text expr ::= LOAD_FAST (1) ret_expr ::= expr (1) assert_expr ::= expr (1) 6 store ::= STORE_FAST (3) 9 expr ::= LOAD_FAST (4) 12 expr ::= LOAD_CONST (5) 9-15 compare_single ::= expr expr COMPARE_OP (6) 9 compare ::= compare_single (6) 9 expr ::= compare (6) ``` -------------------------------- ### Decompile Bytecode Portion with uncompyle6 CLI Source: https://context7.com/rocky/python-uncompyle6/llms.txt Decompile only a specific portion of the bytecode by specifying start and stop offsets using `--start-offset` and `--stop-offset`. ```bash uncompyle6 --start-offset 10 --stop-offset 50 example.pyc ``` -------------------------------- ### Show Parse Tree with uncompyle6 CLI Source: https://context7.com/rocky/python-uncompyle6/llms.txt Visualize the parse tree before and after transformations using the `--tree++` option. ```bash uncompyle6 --tree++ example.pyc ``` -------------------------------- ### Multiple Import Parsing Rule with %b Source: https://github.com/rocky/python-uncompyle6/wiki/Table‐driven-AST‐to‐Python-Translation Demonstrates the '%b' specifier, which associates text from a previous start node up to the current point, used here for multiple imports. ```python 'importmultiple': ( '%|import%b %c%c\n', 0, 2, 3 ), ``` -------------------------------- ### Decompile with uncompyle2 (comparison) Source: https://github.com/rocky/python-uncompyle6/wiki/Fixing-Issue- Command to decompile a .pyc file using uncompyle2 with the --showast option for comparison. This is used to verify if an older tool handles the decompilation correctly. ```bash $ uncompyle2 --showast /tmp/issue-150.2.7.pyc > /tmp/issue-150-good.log ``` -------------------------------- ### Invalid Format Rules for Deparsing Source: https://github.com/rocky/python-uncompyle6/wiki/Table‐driven-AST‐to‐Python-Translation Examples of invalid format rules that would cause errors during deparsing. These highlight common mistakes in defining format specifiers and arguments. ```python 'INPLACE_MODULO': ( '%=',), ``` ```python 'INPLACE_OR': ( '|=' , 0), ``` ```python 'binary_expr': ( '%c %c %c', 0, -1 ), ``` ```python 'unary_not': ( 'not %c', 'a' ), ``` ```python 'slice1': ( '%c[%p:]', 0, 1 ) ``` -------------------------------- ### Remove Type Annotations in Python Bytecode Source: https://github.com/rocky/python-uncompyle6/wiki/expected-decompile-differences Python bytecode does not retain type annotations present in the source code. This example shows a function definition with a type-annotated variable. ```python def foo(): x: int = 5 ``` -------------------------------- ### TABLE_DIRECT Entry Example for Unary Not Source: https://github.com/rocky/python-uncompyle6/wiki/Table‐driven-AST‐to‐Python-Translation This entry in TABLE_DIRECT maps the 'unary_not' nonterminal to the format string 'not %c', indicating how to represent it in the output. The '%c' is a placeholder for a child node. ```python 'unary_not': ( 'not %c', 0 ), ``` -------------------------------- ### Python Dependencies for 3.1.5 Source: https://github.com/rocky/python-uncompyle6/blob/master/admin-tools/README.md Lists the specific versions of pytset, py, and six required for Python 3.1.5. Includes a note about commenting out a line in _builtin.py. ```text pytset==2.1.0 py=1.8.0 and comment out line 10 of _builtin.py # callable = callable six==1.10.0 ``` -------------------------------- ### Valid Format Rules for Deparsing Source: https://github.com/rocky/python-uncompyle6/wiki/Table‐driven-AST‐to‐Python-Translation Examples of valid format rules used in deparsing. These rules define how to output specific code constructs using format specifiers and arguments. ```python 'INPLACE_MODULO': ( '%%=',), ``` ```python 'INPLACE_OR': ( '|=' , ), ``` ```python 'binary_expr': ( '%c %c %c', 0, (-1, 'binary_op'), ( 1, 'expr' ) ), ``` ```python 'unary_not': ( 'not %c', (0 'expr') ), ``` ```python 'slice1': ( '%c[%p:]', (0, 'expr'), (1, 100) ), ``` -------------------------------- ### Examine Pseudo-Assembly (Bad Case) Source: https://github.com/rocky/python-uncompyle6/wiki/Fixing-Issue- Review the pseudo-assembly instructions for the non-working Python 2.6 case. This detailed view, including instruction counts and jump targets, helps pinpoint the exact sequence of operations causing the decompilation failure. ```text 2 0 SETUP_LOOP 48 'to 51' (1) 3 LOAD_FAST 0 '.0' (2) 6 FOR_ITER 41 'to 50' (3) 9 STORE_FAST 1 'c' (4) 12 LOAD_FAST 1 'c' (5) 15 LOAD_CONST 'A' (6) 18 COMPARE_OP 4 > (7) 21 JUMP_IF_FALSE 22 'to 46' (8) 24 POP_TOP (9) 25 LOAD_FAST 1 'c' (10) 28 LOAD_CONST 'S' (11) 31 COMPARE_OP 0 < (12) 34 JUMP_IF_FALSE 9 'to 46' (13) 37 POP_TOP (14) 38 LOAD_FAST 1 'c' (15) 41 YIELD_VALUE (16) 42 POP_TOP (17) 43 JUMP_BACK 6 'to 6' (18) 46_0 COME_FROM 34 '34' (19) 46_1 COME_FROM 21 '21' 46 POP_TOP 47 JUMP_BACK 6 'to 6' 50 POP_BLOCK 51_0 COME_FROM 0 '0' ``` -------------------------------- ### Python Constant Folding Optimization Source: https://github.com/rocky/python-uncompyle6/blob/master/HOW-TO-REPORT-A-BUG.md Python optimizes constant boolean conditions by removing unnecessary conditional blocks. For example, 'if True:' is reduced to the block's content. ```python if True: x = 5 ``` ```python x = 5 ``` -------------------------------- ### Upload Packages to PyPI Source: https://github.com/rocky/python-uncompyle6/wiki/Releasing Upload the built distribution files to the Python Package Index (PyPI). ```bash twine upload dist/uncompyle6-${__version__}* ``` -------------------------------- ### Decompile with Bytecode Assembly Output using decompile_file() Source: https://context7.com/rocky/python-uncompyle6/llms.txt Generate decompiled code along with bytecode assembly (before, after, or both) using the `showasm` parameter. ```python import sys from uncompyle6 import decompile_file # Decompile with bytecode assembly output deparsed = decompile_file( "example.pyc", outstream=sys.stdout, showasm="after" # "before", "after", or "both" ) ``` -------------------------------- ### Basic Decompilation with uncompyle6 CLI Source: https://context7.com/rocky/python-uncompyle6/llms.txt Use the `uncompyle6` command to decompile a Python bytecode file (.pyc/.pyo) to standard output. ```bash uncompyle6 example.pyc ``` -------------------------------- ### Format Specifier Example for Store Attribute Source: https://github.com/rocky/python-uncompyle6/wiki/Table‐driven-AST‐to‐Python-Translation This format specifier for 'STORE_ATTR' uses '%c.%[1]{pattr}' to represent attribute storage. It indicates that the output should be a reference to an attribute, likely for assignment operations. ```python 'STORE_ATTR': ( '%c.%[1]{pattr}', 0), ``` -------------------------------- ### Syntax Verification with uncompyle6 CLI Source: https://context7.com/rocky/python-uncompyle6/llms.txt Perform syntax verification on the decompiled output using the `--verify syntax` option. ```bash uncompyle6 --verify syntax example.pyc ``` -------------------------------- ### Running Test Case Addition Script Source: https://github.com/rocky/python-uncompyle6/wiki/Fixing-Issue- This command executes a script to add a new test case, likely generating associated bytecode files. ```bash $ ./add-test.py simple_source/bug27+/05_while_if_continue.py ``` -------------------------------- ### Python 3.6 Formatted String Literal Example Source: https://github.com/rocky/python-uncompyle6/wiki/Adding-a-new-language-construct-‐-Python-3.6-Formatted-String-Literals This Python code defines a function that uses a formatted string literal, which was introduced in Python 3.6. This serves as the basis for demonstrating bytecode translation. ```python def fn(var1, var2): return f'{var1}py36_string_interpolation{var2}' ``` -------------------------------- ### Adding Bytecode File to Git Source: https://github.com/rocky/python-uncompyle6/wiki/Fixing-Issue- This command stages a generated bytecode file for a test case in Git. The '-f' flag suggests forcing the addition, possibly for already tracked files. ```bash $ git add -f bytecode_2.7/05_while_if_continue.pyc ``` -------------------------------- ### Generate and Check Changelog Source: https://github.com/rocky/python-uncompyle6/wiki/Releasing Automatically generate the ChangeLog file and then spell-check its content. ```bash make ChangeLog codespell ChangeLog ``` -------------------------------- ### MAP Entry for Del Statement using TABLE_R Source: https://github.com/rocky/python-uncompyle6/wiki/Table‐driven-AST‐to‐Python-Translation This example shows how to register the use of TABLE_R for a 'del_stmt' by adding an entry to the MAP dictionary. This indicates that the 'del_stmt' rule should be processed using the TABLE_R lookup. ```python MAP = { 'del_stmt':MAP_R', # ... } ```