Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-pony for openSUSE:Factory 
checked in at 2023-02-24 18:08:26
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pony (Old)
 and      /work/SRC/openSUSE:Factory/.python-pony.new.31432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pony"

Fri Feb 24 18:08:26 2023 rev:9 rq:1067591 version:0.7.16

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pony/python-pony.changes  2022-02-17 
23:42:19.339700022 +0100
+++ /work/SRC/openSUSE:Factory/.python-pony.new.31432/python-pony.changes       
2023-02-24 18:08:36.781586061 +0100
@@ -1,0 +2,6 @@
+Fri Feb 24 11:46:59 UTC 2023 - Daniel Garcia <daniel.gar...@suse.com>
+
+- Add python-311.patch to support python 3.11,
+  gh#ponyorm/pony#671
+
+-------------------------------------------------------------------

New:
----
  python-311.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pony.spec ++++++
--- /var/tmp/diff_new_pack.rNHu2J/_old  2023-02-24 18:08:37.317589255 +0100
+++ /var/tmp/diff_new_pack.rNHu2J/_new  2023-02-24 18:08:37.321589279 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-pony
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -16,7 +16,6 @@
 #
 
 
-%{?!python_module:%define python_module() ython3-%{**}}
 %global skip_python2 1
 Name:           python-pony
 Version:        0.7.16
@@ -25,6 +24,8 @@
 License:        Apache-2.0
 URL:            https://ponyorm.com
 Source:         
https://files.pythonhosted.org/packages/source/p/pony/pony-%{version}.tar.gz
+# PATCH-FIX-UPSTREAM python-311.patch gh#ponyorm/pony#671
+Patch0:         python-311.patch
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  %{pythons}
 BuildRequires:  dos2unix

++++++ python-311.patch ++++++
Index: pony-0.7.16/setup.py
===================================================================
--- pony-0.7.16.orig/setup.py
+++ pony-0.7.16/setup.py
@@ -70,6 +70,7 @@ classifiers = [
     'Programming Language :: Python :: 3.8',
     'Programming Language :: Python :: 3.9',
     'Programming Language :: Python :: 3.10',
+    'Programming Language :: Python :: 3.11',
     'Programming Language :: Python :: Implementation :: PyPy',
     'Topic :: Software Development :: Libraries',
     'Topic :: Database'
@@ -106,8 +107,8 @@ download_url = "http://pypi.python.org/p
 
 if __name__ == "__main__":
     pv = sys.version_info[:2]
-    if pv not in ((3, 6), (3, 7), (3, 8), (3, 9), (3, 10)):
-        s = "Sorry, but %s %s requires Python of one of the following 
versions: 3.6-3.10." \
+    if pv not in ((3, 6), (3, 7), (3, 8), (3, 9), (3, 10), (3, 11)):
+        s = "Sorry, but %s %s requires Python of one of the following 
versions: 3.6-3.11." \
             " You have version %s"
         print(s % (name, version, sys.version.split(' ', 1)[0]))
         sys.exit(1)
Index: pony-0.7.16/pony/orm/decompiling.py
===================================================================
--- pony-0.7.16.orig/pony/orm/decompiling.py
+++ pony-0.7.16/pony/orm/decompiling.py
@@ -1,10 +1,14 @@
 from __future__ import absolute_import, print_function, division
-from pony.py23compat import PY37, PYPY, PY38, PY39, PY310
+from pony.py23compat import PY37, PYPY, PY38, PY39, PY310, PY311
 
 import sys, types, inspect
 from opcode import opname as opnames, HAVE_ARGUMENT, EXTENDED_ARG, cmp_op
 from opcode import hasconst, hasname, hasjrel, haslocal, hascompare, hasfree, 
hasjabs
 from collections import defaultdict
+try:
+    from opcode import _nb_ops as nb_ops
+except ImportError:
+    nb_ops = None
 
 #from pony.thirdparty.compiler import ast, parse
 import ast
@@ -150,6 +154,7 @@ class Decompiler(object):
         decompiler.conditions_end = 0
         decompiler.instructions = []
         decompiler.instructions_map = {}
+        decompiler.kw_names = None
         decompiler.or_jumps = set()
         decompiler.get_instructions()
         decompiler.analyze_jumps()
@@ -193,14 +198,24 @@ class Decompiler(object):
                 if op in hasconst:
                     arg = [code.co_consts[oparg]]
                 elif op in hasname:
-                    arg = [code.co_names[oparg]]
+                    if opname == 'LOAD_GLOBAL':
+                        push_null = False
+                        if PY311:
+                            push_null = oparg & 1
+                            oparg >>= 1
+                        arg = [code.co_names[oparg], push_null]
+                    else:
+                        arg = [code.co_names[oparg]]
                 elif op in hasjrel:
-                    arg = [i + oparg * (2 if PY310 else 1)]
+                    arg = [i + oparg * (2 if PY310 else 1)
+                           * (-1 if 'BACKWARD' in opname else 1)]
                 elif op in haslocal:
                     arg = [code.co_varnames[oparg]]
                 elif op in hascompare:
                     arg = [cmp_op[oparg]]
                 elif op in hasfree:
+                    if PY311:
+                        oparg -= len(code.co_varnames)
                     arg = [free[oparg]]
                 elif op in hasjabs:
                     arg = [oparg * (2 if PY310 else 1)]
@@ -209,7 +224,8 @@ class Decompiler(object):
             else: arg = []
             if opname == 'FOR_ITER':
                 decompiler.for_iter_pos = decompiler.pos
-            if opname == 'JUMP_ABSOLUTE' and arg[0] == decompiler.for_iter_pos:
+            if (opname in ('JUMP_ABSOLUTE', 'JUMP_NO_INTERRUPT')
+                    and arg[0] == decompiler.for_iter_pos):
                 decompiler.abs_jump_to_top = decompiler.pos
 
             if before_yield:
@@ -300,6 +316,34 @@ class Decompiler(object):
     BINARY_TRUE_DIVIDE  = BINARY_DIVIDE
     BINARY_MODULO       = binop(ast.Mod)
 
+    def BINARY_OP(decompiler, opcode):
+        opname, symbol = nb_ops[opcode]
+        inplace = opname.startswith('NB_INPLACE_')
+        opname = opname.split('_', 2 if inplace else 1)[-1]
+
+        op = {
+            "ADD": ast.Add,
+            "AND": ast.BitAnd,
+            "FLOOR_DIVIDE": ast.FloorDiv,
+            "LSHIFT": ast.LShift,
+            "MATRIX_MULTIPLY": ast.MatMult,
+            "MULTIPLY": ast.Mult,
+            "REMAINDER": ast.Mod,
+            "OR": ast.BitOr,
+            "POWER": ast.Pow,
+            "RSHIFT": ast.RShift,
+            "SUBTRACT": ast.Sub,
+            "TRUE_DIVIDE": ast.Div,
+            "XOR": ast.BitXor,
+        }[opname]
+
+        oper2 = decompiler.stack.pop()
+        oper1 = decompiler.stack.pop()
+        r = ast.BinOp(left=oper1, op=op(), right=oper2)
+        if inplace:
+            r = ast.Name(oper1, r)
+        return r
+
     def BINARY_SUBSCR(decompiler):
         node2 = decompiler.stack.pop()
         node1 = decompiler.stack.pop()
@@ -394,6 +438,30 @@ class Decompiler(object):
             return genexpr
         return ast.Call(tos, args, keywords)
 
+    def CACHE(decompiler):
+        pass
+
+    def CALL(decompiler, argc):
+        values = decompiler.pop_items(argc)
+
+        keys = decompiler.kw_names
+        decompiler.kw_names = None
+
+        args = values
+        keywords = []
+        if keys:
+            args = values[:-len(keys)]
+            keywords = [ast.keyword(k, v) for k, v in zip(keys, 
values[-len(keys):])]
+
+        self = decompiler.stack.pop()
+        callable_ = decompiler.stack.pop()
+        if callable_ is None:
+            callable_ = self
+        else:
+            args.insert(0, self)
+        decompiler.stack.append(callable_)
+        return decompiler._call_function(args, keywords)
+
     def CALL_FUNCTION_VAR(decompiler, argc):
         return decompiler.CALL_FUNCTION(argc, decompiler.stack.pop())
 
@@ -455,6 +523,9 @@ class Decompiler(object):
         op = operator_mapping[op]()
         return ast.Compare(oper1, [op], [oper2])
 
+    def COPY_FREE_VARS(decompiler, n):
+        pass
+
     def CONTAINS_OP(decompiler, invert):
         return decompiler.COMPARE_OP('not in' if invert else 'in')
 
@@ -543,6 +614,37 @@ class Decompiler(object):
         decompiler.targets.setdefault(endpos, clause)
         return clause
 
+    def conditional_jump_none_impl(decompiler, endpos, negate):
+        expr = decompiler.stack.pop()
+        op = ast.Is
+        if decompiler.pos >= decompiler.conditions_end:
+            clausetype = ast.And if negate else ast.Or
+        elif decompiler.pos in decompiler.or_jumps:
+            clausetype = ast.Or
+            if negate:
+                op = ast.IsNot
+        else:
+            clausetype = ast.And
+            if negate:
+                op = ast.IsNot
+        expr = ast.Compare(expr, [op()], [ast.Constant(None)])
+        decompiler.stack.append(expr)
+
+        if decompiler.next_pos in decompiler.targets:
+            decompiler.process_target(decompiler.next_pos)
+
+        expr = decompiler.stack.pop()
+        clause = ast.BoolOp(op=clausetype(), values=[expr])
+        clause.endpos = endpos
+        decompiler.targets.setdefault(endpos, clause)
+        return clause
+
+    def jump_if_none(decompiler, endpos):
+        return decompiler.conditional_jump_none_impl(endpos, True)
+
+    def jump_if_not_none(decompiler, endpos):
+        return decompiler.conditional_jump_none_impl(endpos, False)
+
     def process_target(decompiler, pos, partial=False):
         if pos is None:
             limit = None
@@ -559,6 +661,10 @@ class Decompiler(object):
                 break
             if not decompiler.stack:
                 break
+            if decompiler.stack[-1] is None:
+                decompiler.stack.pop()
+                if not decompiler.stack:
+                    break
             top2 = decompiler.stack[-1]
             if isinstance(top2, ast.comprehension):
                 break
@@ -596,6 +702,10 @@ class Decompiler(object):
             decompiler.targets[endpos] = if_exp
         return if_exp
 
+    def KW_NAMES(decompiler, kw_names):
+        # Stash for CALL
+        decompiler.kw_names = kw_names
+
     def IS_OP(decompiler, invert):
         return decompiler.COMPARE_OP('is not' if invert else 'is')
 
@@ -636,12 +746,17 @@ class Decompiler(object):
         decompiler.names.add(varname)
         return ast.Name(varname, ast.Load())
 
-    def LOAD_GLOBAL(decompiler, varname):
+    def LOAD_GLOBAL(decompiler, varname, push_null):
+        if push_null:
+            decompiler.stack.append(None)
         decompiler.names.add(varname)
         return ast.Name(varname, ast.Load())
 
     def LOAD_METHOD(decompiler, methname):
-        return decompiler.LOAD_ATTR(methname)
+        result = decompiler.LOAD_ATTR(methname)
+        if PY311:
+            decompiler.stack.append(None)
+        return result
 
     LOOKUP_METHOD = LOAD_METHOD  # For PyPy
 
@@ -649,6 +764,9 @@ class Decompiler(object):
         decompiler.names.add(varname)
         return ast.Name(varname, ast.Load())
 
+    def MAKE_CELL(decompiler, freevar):
+        pass
+
     def MAKE_CLOSURE(decompiler, argc):
         decompiler.stack[-3:-2] = []  # ignore freevars
         return decompiler.MAKE_FUNCTION(argc)
@@ -656,7 +774,8 @@ class Decompiler(object):
     def MAKE_FUNCTION(decompiler, argc):
         defaults = []
         if sys.version_info >= (3, 6):
-            qualname = decompiler.stack.pop()
+            if not PY311:
+                qualname = decompiler.stack.pop()
             tos = decompiler.stack.pop()
             if argc & 0x08:
                 func_closure = decompiler.stack.pop()
@@ -692,18 +811,38 @@ class Decompiler(object):
         )
         return ast.Lambda(args, func_decompiler.ast)
 
+    POP_JUMP_BACKWARD_IF_FALSE = JUMP_IF_FALSE
+    POP_JUMP_BACKWARD_IF_TRUE = JUMP_IF_TRUE
+    POP_JUMP_FORWARD_IF_FALSE = JUMP_IF_FALSE
+    POP_JUMP_FORWARD_IF_TRUE = JUMP_IF_TRUE
     POP_JUMP_IF_FALSE = JUMP_IF_FALSE
     POP_JUMP_IF_TRUE = JUMP_IF_TRUE
+    POP_JUMP_BACKWARD_IF_NONE = jump_if_none
+    POP_JUMP_BACKWARD_IF_NOT_NONE = jump_if_not_none
+    POP_JUMP_FORWARD_IF_NONE = jump_if_none
+    POP_JUMP_FORWARD_IF_NOT_NONE = jump_if_not_none
 
     def POP_TOP(decompiler):
         pass
 
+    def PRECALL(decompiler, argc):
+        pass
+
+    def PUSH_NULL(decompiler):
+        decompiler.stack.append(None)
+
     def RETURN_VALUE(decompiler):
         if decompiler.next_pos != decompiler.end:
             throw(DecompileError)
         expr = decompiler.stack.pop()
         return simplify(expr)
 
+    def RETURN_GENERATOR(decompiler):
+        pass
+
+    def RESUME(decompiler, where):
+        pass
+
     def ROT_TWO(decompiler):
         tos = decompiler.stack.pop()
         tos1 = decompiler.stack.pop()
Index: pony-0.7.16/pony/orm/tests/test_decompiler.py
===================================================================
--- pony-0.7.16.orig/pony/orm/tests/test_decompiler.py
+++ pony-0.7.16/pony/orm/tests/test_decompiler.py
@@ -1,4 +1,7 @@
+import textwrap
 import unittest
+import ast
+import sys
 
 from pony.orm.decompiling import Decompiler
 from pony.orm.asttranslation import ast2src
@@ -93,7 +96,85 @@ def create_test(gen):
 
 
 class TestDecompiler(unittest.TestCase):
-    pass
+    def assertDecompilesTo(self, src, expected):
+        # skip test due to ast.dump has no indent parameter
+        if sys.version_info[:2] <= (3, 8):
+            return
+
+        code = compile(src, '<?>', 'eval').co_consts[0]
+        import dis
+        print(dis.dis(code))
+        dc = Decompiler(code)
+        expected = textwrap.dedent(expected).strip()
+        self.maxDiff = None
+        self.assertMultiLineEqual(expected, ast.dump(dc.ast, indent=2))
+
+    def test_ast1(self):
+        self.assertDecompilesTo(
+            '(a for a in [] if x and y and z and j)',
+            """
+            GeneratorExp(
+              elt=Name(id='a', ctx=Load()),
+              generators=[
+                comprehension(
+                  target=Name(id='a', ctx=Store()),
+                  iter=Name(id='.0', ctx=Load()),
+                  ifs=[
+                    BoolOp(
+                      op=And(),
+                      values=[
+                        Name(id='x', ctx=Load()),
+                        Name(id='y', ctx=Load()),
+                        Name(id='z', ctx=Load()),
+                        Name(id='j', ctx=Load())])],
+                  is_async=0)])
+            """)
+
+    def test_ast2(self):
+        self.assertDecompilesTo(
+            'lambda x, y, z, j: (x and y and z and j)',
+            """
+            BoolOp(
+              op=And(),
+              values=[
+                Name(id='x', ctx=Load()),
+                Name(id='y', ctx=Load()),
+                Name(id='z', ctx=Load()),
+                Name(id='j', ctx=Load())])
+            """)
+
+    def test_ast3(self):
+        self.assertDecompilesTo(
+            '(m for m in [] if x and y and z and j for n in [] if x and y and 
z and j)',
+            """
+            GeneratorExp(
+              elt=Name(id='m', ctx=Load()),
+              generators=[
+                comprehension(
+                  target=Name(id='m', ctx=Store()),
+                  iter=Name(id='.0', ctx=Load()),
+                  ifs=[
+                    BoolOp(
+                      op=And(),
+                      values=[
+                        Name(id='x', ctx=Load()),
+                        Name(id='y', ctx=Load()),
+                        Name(id='z', ctx=Load()),
+                        Name(id='j', ctx=Load())])],
+                  is_async=0),
+                comprehension(
+                  target=Name(id='n', ctx=Store()),
+                  iter=Constant(value=()),
+                  ifs=[
+                    BoolOp(
+                      op=And(),
+                      values=[
+                        Name(id='x', ctx=Load()),
+                        Name(id='y', ctx=Load()),
+                        Name(id='z', ctx=Load()),
+                        Name(id='j', ctx=Load())])],
+                  is_async=0)])
+            """)
 
 
 for i, gen in enumerate(generate_gens()):
Index: pony-0.7.16/pony/py23compat.py
===================================================================
--- pony-0.7.16.orig/pony/py23compat.py
+++ pony-0.7.16/pony/py23compat.py
@@ -5,6 +5,7 @@ PY37 = sys.version_info[:2] >= (3, 7)
 PY38 = sys.version_info[:2] >= (3, 8)
 PY39 = sys.version_info[:2] >= (3, 9)
 PY310 = sys.version_info[:2] >= (3, 10)
+PY311 = sys.version_info[:2] >= (3, 11)
 
 unicode = str
 buffer = bytes

Reply via email to