Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-Js2Py for openSUSE:Factory checked in at 2025-01-02 19:23:17
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-Js2Py (Old)
and /work/SRC/openSUSE:Factory/.python-Js2Py.new.1881 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Js2Py"
Thu Jan 2 19:23:17 2025 rev:11 rq:1234488 version:0.74
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-Js2Py/python-Js2Py.changes 2024-07-01 11:23:08.929120320 +0200
+++ /work/SRC/openSUSE:Factory/.python-Js2Py.new.1881/python-Js2Py.changes 2025-01-02 19:24:00.874878220 +0100
@@ -1,0 +2,5 @@
+Wed Jan 1 23:38:45 UTC 2025 - Matej Cepl <mcepl(a)cepl.eu>
+
+- Add 313-compatibility.patch (gh#PiotrDabkowski/Js2Py#334)
+
+-------------------------------------------------------------------
New:
----
313-compatibility.patch
BETA DEBUG BEGIN:
New:
- Add 313-compatibility.patch (gh#PiotrDabkowski/Js2Py#334)
BETA DEBUG END:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-Js2Py.spec ++++++
--- /var/tmp/diff_new_pack.XyYzZz/_old 2025-01-02 19:24:01.446902086 +0100
+++ /var/tmp/diff_new_pack.XyYzZz/_new 2025-01-02 19:24:01.450902253 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-Js2Py
#
-# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2025 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -32,6 +32,9 @@
Patch1: python312.patch
# PATCH-FIX-UPSTREAM CVE-2024-28397.patch gh#PiotrDabkowski/Js2Py#323
Patch2: CVE-2024-28397.patch
+# PATCH-FIX-UPSTREAM 313-compatibility.patch gh#PiotrDabkowski/Js2Py#334 mcepl(a)suse.com
+# Compatibility with Python 3.13
+Patch3: 313-compatibility.patch
BuildRequires: %{python_module pyjsparser}
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
++++++ 313-compatibility.patch ++++++
From 0da30c83f149b15539ca3d246d5ebfb0afd7f140 Mon Sep 17 00:00:00 2001
From: a-j-albert <aalbert(a)cyberdude.com>
Date: Sun, 15 Dec 2024 22:03:31 -0800
Subject: [PATCH 1/2] My changes for 3.13
---
js2py/utils/injector.py | 78 +++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 71 insertions(+), 7 deletions(-)
--- a/js2py/utils/injector.py
+++ b/js2py/utils/injector.py
@@ -15,6 +15,10 @@ LOAD_FAST = opcode.opmap['LOAD_FAST']
LOAD_GLOBAL = opcode.opmap['LOAD_GLOBAL']
LOAD_ATTR = opcode.opmap['LOAD_ATTR']
STORE_FAST = opcode.opmap['STORE_FAST']
+LOAD_FAST_LOAD_FAST = opcode.opmap.get('LOAD_FAST_LOAD_FAST')
+STORE_FAST_LOAD_FAST = opcode.opmap.get('STORE_FAST_LOAD_FAST')
+STORE_FAST_STORE_FAST = opcode.opmap.get('STORE_FAST_STORE_FAST')
+EXTENDED_ARG = opcode.opmap.get('EXTENDED_ARG')
_func_closure = "__closure__"
@@ -43,6 +47,40 @@ def fix_js_args(func):
closure=get_function_closure(func))
return result
+def get_list_of_var_indices_in_compound_opcodes(code_obj, non_arg_varnames, arg_count): #E.g. STORE_FAST_LOAD_FAST
+ indices = set()
+ for inst in instructions(code_obj):
+ extended = False
+ if inst.opcode == EXTENDED_ARG:
+ extended = True
+ continue
+ if not extended and inst.opcode in (LOAD_FAST_LOAD_FAST, STORE_FAST_LOAD_FAST, STORE_FAST_STORE_FAST):
+ first_index = (inst.arg >> 4 & 0xF) - arg_count
+ second_index = (inst.arg & 0xF) - arg_count
+ if first_index >= 0:
+ indices.add(first_index)
+ if second_index >= 0:
+ indices.add(second_index)
+ extended = False
+ return indices
+
+def rearrange_by_indices(strings, indices):
+ """
+ Rearranges the strings in the list so that the elements corresponding
+ to the indices are at the beginning of the list.
+
+ Args:
+ strings (list): The list of strings.
+ indices (list): A list of indices into the strings list.
+
+ Returns:
+ list: A new list with rearranged elements.
+ """
+ # Extract elements based on indices
+ prioritized = [strings[i] for i in indices if 0 <= i < len(strings)]
+ # Include elements not in indices
+ remaining = [strings[i] for i in range(len(strings)) if i not in indices]
+ return prioritized + remaining
def append_arguments(code_obj, new_locals):
co_varnames = code_obj.co_varnames # Old locals
@@ -56,9 +94,9 @@ def append_arguments(code_obj, new_local
# left in code_obj.co_names.
not_removed = set(opcode.hasname) - set([LOAD_GLOBAL])
saved_names = set()
- for inst in instructions(code_obj):
- if inst[0] in not_removed:
- saved_names.add(co_names[inst[1]])
+ # for inst in instructions(code_obj):
+ # if inst.opcode in not_removed:
+ # saved_names.add(co_names[inst.oparg])
# Build co_names for the new code object. This should consist of
# globals that were only accessed via LOAD_GLOBAL
@@ -70,18 +108,21 @@ def append_arguments(code_obj, new_local
name_translations = dict(
(co_names.index(name), i) for i, name in enumerate(names))
+ non_arg_varnames = co_varnames[co_argcount:] # All varibles after the arguments
+ early_indices = get_list_of_var_indices_in_compound_opcodes(code_obj, non_arg_varnames, co_argcount)
+ rearranged_non_arg_varnames = rearrange_by_indices(non_arg_varnames, early_indices)
# Build co_varnames for the new code object. This should consist of
# the entirety of co_varnames with new_locals spliced in after the
# arguments
new_locals_len = len(new_locals)
varnames = (
- co_varnames[:co_argcount] + new_locals + co_varnames[co_argcount:])
+ co_varnames[:co_argcount] + new_locals + tuple(rearranged_non_arg_varnames))
# Build the dictionary that maps indices of entries in the old co_varnames
# to their indices in the new co_varnames
range1, range2 = xrange(co_argcount), xrange(co_argcount, len(co_varnames))
varname_translations = dict((i, i) for i in range1)
- varname_translations.update((i, i + new_locals_len) for i in range2)
+ varname_translations.update((i, varnames.index(co_varnames[i])) for i in range2)
# Build the dictionary that maps indices of deleted entries of co_names
# to their indices in the new co_varnames
@@ -94,6 +135,7 @@ def append_arguments(code_obj, new_local
modified = []
drop_future_cache = False
for inst in instructions(code_obj):
+ # print(inst.opname + ' - ' + str(inst.line_number))
if is_new_bytecode and inst.opname == "CACHE":
assert inst.arg == 0
if not drop_future_cache:
@@ -124,9 +166,18 @@ def append_arguments(code_obj, new_local
arg = tgt
else:
raise(ValueError("a name was lost in translation last instruction %s" % str(inst)))
+ elif inst.opcode in (LOAD_FAST_LOAD_FAST, STORE_FAST_LOAD_FAST, STORE_FAST_STORE_FAST):
+ old_first_arg = inst.arg >> 4 & 0xF
+ old_second_arg = inst.arg & 0xF
+ new_first_arg = varname_translations[old_first_arg]
+ new_second_arg = varname_translations[old_second_arg]
+ arg = new_first_arg << 4 | new_second_arg
# If it accesses co_varnames or co_names then update its argument.
elif inst.opcode in opcode.haslocal:
- arg = varname_translations[inst.arg]
+ if arg < len(varname_translations): # Otherwise cellvar whose arg gets incremented by new_locals_len
+ arg = varname_translations[inst.arg]
+ else:
+ arg += new_locals_len
elif inst.opcode in opcode.hasname:
# for example STORE_GLOBAL
arg = name_translations[inst.arg]
@@ -135,6 +186,12 @@ def append_arguments(code_obj, new_local
if inst.argval not in code_obj.co_varnames[:code_obj.co_argcount]: # we do not need to remap existing arguments, they are not shifted by new ones.
arg = inst.arg + len(new_locals)
modified.extend(write_instruction(op, arg))
+ if hasattr(inst, 'end_offset'): # Assume otherwise instructions will have explicit CACHE entries
+ for inline_cache in range(int((inst.end_offset - inst.cache_offset) / 2)):
+ if not drop_future_cache:
+ modified.extend(write_instruction(0, 0))
+ else:
+ modified.extend(write_instruction(dis.opmap["NOP"], 0))
code = bytes(modified)
args = (co_argcount + new_locals_len, 0,
code_obj.co_nlocals + new_locals_len, code_obj.co_stacksize,
@@ -229,9 +286,16 @@ def check(code_obj):
pos_to_inst = {}
bytelist = []
+ offset = 0
+ instruction_bytes = None
for inst in insts:
pos_to_inst[len(bytelist)] = inst
- bytelist.extend(write_instruction(inst.opcode, inst.arg))
+ if instruction_bytes:
+ for gap_byte in range(inst.offset - offset - len(instruction_bytes)):
+ bytelist.append(0)
+ offset = inst.offset
+ instruction_bytes = write_instruction(inst.opcode, inst.arg)
+ bytelist.extend(instruction_bytes)
new_bytecode = bytes(bytelist)
if new_bytecode != old_bytecode:
print(new_bytecode)