python-decopatch fails to build with Python 3.12.0a7. =================================== FAILURES =================================== __________________________ test_doc_say_hello[nested] __________________________ capsys = <_pytest.capture.CaptureFixture object at 0x7fdf0d78bd40> mode = 'nested' @pytest.mark.parametrize('mode', ['nested', 'flat', 'double-flat']) def test_doc_say_hello(capsys, mode): """ Tests that the @say_hello example from doc works """ with capsys.disabled(): if mode == 'nested': @function_decorator def say_hello(person="world", f=DECORATED): """ This decorator wraps the decorated function so that a nice hello message is printed before each call. :param person: the person name in the print message. Default = "world" """ # create a wrapper of f that will do the print before call # we rely on `makefun.wraps` to preserve signature @wraps(f) def new_f(*args, **kwargs): print("hello, %s !" % person) # say hello return f(*args, **kwargs) # call f # return the new function return new_f elif mode == 'flat': @function_decorator def say_hello(person="world", f=DECORATED): """ This decorator wraps the decorated function so that a nice hello message is printed before each call. :param person: the person name in the print message. Default = "world" """ # create a wrapper of f that will do the print before call # we rely on `makefun.wraps` to preserve signature @wraps(f) def new_f(*args, **kwargs): print("hello, %s !" % person) # say hello return f(*args, **kwargs) # call f # return the new function return new_f elif mode == 'double-flat': @function_decorator def say_hello(person="world", f=WRAPPED, f_args=F_ARGS, f_kwargs=F_KWARGS): """ This decorator wraps the decorated function so that a nice hello message is printed before each call. :param person: the person name in the print message. Default = "world" """ print("hello, %s !" % person) # say hello return f(*f_args, **f_kwargs) # call f else: raise ValueError("unsupported mode : %s" % mode) # for debug.. with capsys.disabled(): @say_hello # no parenthesis def foo(): print("<executing foo>") # for debug.. with capsys.disabled(): foo() foo() @say_hello() # empty parenthesis def bar(): print("<executing bar>") bar() @say_hello("you") # arg def custom(): print("<executing custom>") custom() # manual decoration def custom2(): print("<executing custom2>") custom2 = say_hello()(custom2) custom2() help(say_hello) assert str(signature(say_hello)) == "(person='world')" print("Signature: %s" % signature(say_hello)) @say_hello # no parenthesis def add_ints(a, b): return a + b assert add_ints(1, 3) == 4 captured = capsys.readouterr() with capsys.disabled(): print(captured.out) > assert captured.out == """hello, world ! <executing foo> hello, world ! <executing bar> hello, you ! <executing custom> hello, world ! <executing custom2> Help on function say_hello in module tests.test_doc: say_hello(person='world') This decorator wraps the decorated function so that a nice hello message is printed before each call. :param person: the person name in the print message. Default = "world" Signature: (person='world') hello, world ! """ E assert 'hello, world !\n<executing foo>\nhello, world !\n<executing bar>\nhello, you !\n<executing custom>\nhello, world !\n<executing custom2>\nHelp on function say_hello in module tests.test_doc:\n\nsay_hello(person=\'world\')\n This decorator wraps the decorated function so that a nice hello\n message is printed before each call.\n\n :param person: the person name in the print message. Default = "world"\n\nSignature: (person=\'world\')\nhello, world !\n' == 'hello, world !\n<executing foo>\nhello, world !\n<executing bar>\nhello, you !\n<executing custom>\nhello, world !\n<executing custom2>\nHelp on function say_hello in module tests.test_doc:\n\nsay_hello(person=\'world\')\n This decorator wraps the decorated function so that a nice hello\n message is printed before each call.\n \n :param person: the person name in the print message. Default = "world"\n\nSignature: (person=\'world\')\nhello, world !\n' E hello, world ! E <executing foo> E hello, world ! E <executing bar> E hello, you ! E <executing custom> E hello, world ! E <executing custom2> E Help on function say_hello in module tests.test_doc: E E say_hello(person='world') E This decorator wraps the decorated function so that a nice hello E message is printed before each call. E - E + E :param person: the person name in the print message. Default = "world" E E Signature: (person='world') E hello, world ! tests/test_doc.py:185: AssertionError ___________________________ test_doc_say_hello[flat] ___________________________ capsys = <_pytest.capture.CaptureFixture object at 0x7fdf0d44d7f0> mode = 'flat' @pytest.mark.parametrize('mode', ['nested', 'flat', 'double-flat']) def test_doc_say_hello(capsys, mode): """ Tests that the @say_hello example from doc works """ with capsys.disabled(): if mode == 'nested': @function_decorator def say_hello(person="world", f=DECORATED): """ This decorator wraps the decorated function so that a nice hello message is printed before each call. :param person: the person name in the print message. Default = "world" """ # create a wrapper of f that will do the print before call # we rely on `makefun.wraps` to preserve signature @wraps(f) def new_f(*args, **kwargs): print("hello, %s !" % person) # say hello return f(*args, **kwargs) # call f # return the new function return new_f elif mode == 'flat': @function_decorator def say_hello(person="world", f=DECORATED): """ This decorator wraps the decorated function so that a nice hello message is printed before each call. :param person: the person name in the print message. Default = "world" """ # create a wrapper of f that will do the print before call # we rely on `makefun.wraps` to preserve signature @wraps(f) def new_f(*args, **kwargs): print("hello, %s !" % person) # say hello return f(*args, **kwargs) # call f # return the new function return new_f elif mode == 'double-flat': @function_decorator def say_hello(person="world", f=WRAPPED, f_args=F_ARGS, f_kwargs=F_KWARGS): """ This decorator wraps the decorated function so that a nice hello message is printed before each call. :param person: the person name in the print message. Default = "world" """ print("hello, %s !" % person) # say hello return f(*f_args, **f_kwargs) # call f else: raise ValueError("unsupported mode : %s" % mode) # for debug.. with capsys.disabled(): @say_hello # no parenthesis def foo(): print("<executing foo>") # for debug.. with capsys.disabled(): foo() foo() @say_hello() # empty parenthesis def bar(): print("<executing bar>") bar() @say_hello("you") # arg def custom(): print("<executing custom>") custom() # manual decoration def custom2(): print("<executing custom2>") custom2 = say_hello()(custom2) custom2() help(say_hello) assert str(signature(say_hello)) == "(person='world')" print("Signature: %s" % signature(say_hello)) @say_hello # no parenthesis def add_ints(a, b): return a + b assert add_ints(1, 3) == 4 captured = capsys.readouterr() with capsys.disabled(): print(captured.out) > assert captured.out == """hello, world ! <executing foo> hello, world ! <executing bar> hello, you ! <executing custom> hello, world ! <executing custom2> Help on function say_hello in module tests.test_doc: say_hello(person='world') This decorator wraps the decorated function so that a nice hello message is printed before each call. :param person: the person name in the print message. Default = "world" Signature: (person='world') hello, world ! """ E assert 'hello, world !\n<executing foo>\nhello, world !\n<executing bar>\nhello, you !\n<executing custom>\nhello, world !\n<executing custom2>\nHelp on function say_hello in module tests.test_doc:\n\nsay_hello(person=\'world\')\n This decorator wraps the decorated function so that a nice hello\n message is printed before each call.\n\n :param person: the person name in the print message. Default = "world"\n\nSignature: (person=\'world\')\nhello, world !\n' == 'hello, world !\n<executing foo>\nhello, world !\n<executing bar>\nhello, you !\n<executing custom>\nhello, world !\n<executing custom2>\nHelp on function say_hello in module tests.test_doc:\n\nsay_hello(person=\'world\')\n This decorator wraps the decorated function so that a nice hello\n message is printed before each call.\n \n :param person: the person name in the print message. Default = "world"\n\nSignature: (person=\'world\')\nhello, world !\n' E hello, world ! E <executing foo> E hello, world ! E <executing bar> E hello, you ! E <executing custom> E hello, world ! E <executing custom2> E Help on function say_hello in module tests.test_doc: E E say_hello(person='world') E This decorator wraps the decorated function so that a nice hello E message is printed before each call. E - E + E :param person: the person name in the print message. Default = "world" E E Signature: (person='world') E hello, world ! tests/test_doc.py:185: AssertionError _______________________ test_doc_say_hello[double-flat] ________________________ capsys = <_pytest.capture.CaptureFixture object at 0x7fdf0d43bd40> mode = 'double-flat' @pytest.mark.parametrize('mode', ['nested', 'flat', 'double-flat']) def test_doc_say_hello(capsys, mode): """ Tests that the @say_hello example from doc works """ with capsys.disabled(): if mode == 'nested': @function_decorator def say_hello(person="world", f=DECORATED): """ This decorator wraps the decorated function so that a nice hello message is printed before each call. :param person: the person name in the print message. Default = "world" """ # create a wrapper of f that will do the print before call # we rely on `makefun.wraps` to preserve signature @wraps(f) def new_f(*args, **kwargs): print("hello, %s !" % person) # say hello return f(*args, **kwargs) # call f # return the new function return new_f elif mode == 'flat': @function_decorator def say_hello(person="world", f=DECORATED): """ This decorator wraps the decorated function so that a nice hello message is printed before each call. :param person: the person name in the print message. Default = "world" """ # create a wrapper of f that will do the print before call # we rely on `makefun.wraps` to preserve signature @wraps(f) def new_f(*args, **kwargs): print("hello, %s !" % person) # say hello return f(*args, **kwargs) # call f # return the new function return new_f elif mode == 'double-flat': @function_decorator def say_hello(person="world", f=WRAPPED, f_args=F_ARGS, f_kwargs=F_KWARGS): """ This decorator wraps the decorated function so that a nice hello message is printed before each call. :param person: the person name in the print message. Default = "world" """ print("hello, %s !" % person) # say hello return f(*f_args, **f_kwargs) # call f else: raise ValueError("unsupported mode : %s" % mode) # for debug.. with capsys.disabled(): @say_hello # no parenthesis def foo(): print("<executing foo>") # for debug.. with capsys.disabled(): foo() foo() @say_hello() # empty parenthesis def bar(): print("<executing bar>") bar() @say_hello("you") # arg def custom(): print("<executing custom>") custom() # manual decoration def custom2(): print("<executing custom2>") custom2 = say_hello()(custom2) custom2() help(say_hello) assert str(signature(say_hello)) == "(person='world')" print("Signature: %s" % signature(say_hello)) @say_hello # no parenthesis def add_ints(a, b): return a + b assert add_ints(1, 3) == 4 captured = capsys.readouterr() with capsys.disabled(): print(captured.out) > assert captured.out == """hello, world ! <executing foo> hello, world ! <executing bar> hello, you ! <executing custom> hello, world ! <executing custom2> Help on function say_hello in module tests.test_doc: say_hello(person='world') This decorator wraps the decorated function so that a nice hello message is printed before each call. :param person: the person name in the print message. Default = "world" Signature: (person='world') hello, world ! """ E assert 'hello, world !\n<executing foo>\nhello, world !\n<executing bar>\nhello, you !\n<executing custom>\nhello, world !\n<executing custom2>\nHelp on function say_hello in module tests.test_doc:\n\nsay_hello(person=\'world\')\n This decorator wraps the decorated function so that a nice hello\n message is printed before each call.\n\n :param person: the person name in the print message. Default = "world"\n\nSignature: (person=\'world\')\nhello, world !\n' == 'hello, world !\n<executing foo>\nhello, world !\n<executing bar>\nhello, you !\n<executing custom>\nhello, world !\n<executing custom2>\nHelp on function say_hello in module tests.test_doc:\n\nsay_hello(person=\'world\')\n This decorator wraps the decorated function so that a nice hello\n message is printed before each call.\n \n :param person: the person name in the print message. Default = "world"\n\nSignature: (person=\'world\')\nhello, world !\n' E hello, world ! E <executing foo> E hello, world ! E <executing bar> E hello, you ! E <executing custom> E hello, world ! E <executing custom2> E Help on function say_hello in module tests.test_doc: E E say_hello(person='world') E This decorator wraps the decorated function so that a nice hello E message is printed before each call. E - E + E :param person: the person name in the print message. Default = "world" E E Signature: (person='world') E hello, world ! tests/test_doc.py:185: AssertionError ________________________ test_doc_impl_first_say_hello _________________________ capsys = <_pytest.capture.CaptureFixture object at 0x7fdf0d44fc50> def test_doc_impl_first_say_hello(capsys): """The second implementation-first example in the doc""" @function_decorator def say_hello(person='world', f=DECORATED): """ This decorator modifies the decorated function so that a nice hello message is printed before the call. :param person: the person name in the print message. Default = "world" :param f: represents the decorated item. Automatically injected. :return: a modified version of `f` that will print a hello message before executing """ # create a wrapper of f that will do the print before call # we rely on `makefun.wraps` to preserve signature @wraps(f) def new_f(*args, **kwargs): # nonlocal person person = new_f.person print("hello, %s !" % person) # say hello return f(*args, **kwargs) # call f # we use the trick at https://stackoverflow.com/a/16032631/7262247 # to access the nonlocal 'person' variable in python 2 and 3 # for python 3 only you can use 'nonlocal' https://www.python.org/dev/peps/pep-3104/ new_f.person = person # return the wrapper return new_f @say_hello def foo(a, b): return a + b @say_hello() def bar(a, b): return a + b @say_hello("you") def custom(a, b): return a + b assert foo(1, 3) == 4 assert bar(1, 3) == 4 assert custom(1, 3) == 4 help(say_hello) print("Signature: %s" % signature(say_hello)) captured = capsys.readouterr() with capsys.disabled(): print(captured.out) > assert captured.out == """hello, world ! hello, world ! hello, you ! Help on function say_hello in module tests.test_doc_advanced: say_hello(person='world') This decorator modifies the decorated function so that a nice hello message is printed before the call. :param person: the person name in the print message. Default = "world" :param f: represents the decorated item. Automatically injected. :return: a modified version of `f` that will print a hello message before executing Signature: (person='world') """ E assert 'hello, world !\nhello, world !\nhello, you !\nHelp on function say_hello in module tests.test_doc_advanced:\n\nsay_hello(person=\'world\')\n This decorator modifies the decorated function so that a nice hello\n message is printed before the call.\n\n :param person: the person name in the print message. Default = "world"\n :param f: represents the decorated item. Automatically injected.\n :return: a modified version of `f` that will print a hello message before executing\n\nSignature: (person=\'world\')\n' == 'hello, world !\nhello, world !\nhello, you !\nHelp on function say_hello in module tests.test_doc_advanced:\n\nsay_hello(person=\'world\')\n This decorator modifies the decorated function so that a nice hello\n message is printed before the call.\n \n :param person: the person name in the print message. Default = "world"\n :param f: represents the decorated item. Automatically injected.\n :return: a modified version of `f` that will print a hello message before executing\n\nSignature: (person=\'world\')\n' E hello, world ! E hello, world ! E hello, you ! E Help on function say_hello in module tests.test_doc_advanced: E E say_hello(person='world') E This decorator modifies the decorated function so that a nice hello E message is printed before the call. E - E + E :param person: the person name in the print message. Default = "world" E :param f: represents the decorated item. Automatically injected. E :return: a modified version of `f` that will print a hello message before executing E E Signature: (person='world') tests/test_doc_advanced.py:203: AssertionError =========================== short test summary info ============================ FAILED tests/test_doc.py::test_doc_say_hello[nested] - assert 'hello, world !... FAILED tests/test_doc.py::test_doc_say_hello[flat] - assert 'hello, world !\n... FAILED tests/test_doc.py::test_doc_say_hello[double-flat] - assert 'hello, wo... FAILED tests/test_doc_advanced.py::test_doc_impl_first_say_hello - assert 'he... ================== 4 failed, 182 passed, 80 skipped in 0.58s =================== https://docs.python.org/3.12/whatsnew/3.12.html For the build logs, see: https://copr-be.cloud.fedoraproject.org/results/@python/python3.12/fedora-rawhide-x86_64/05901542-python-decopatch/ For all our attempts to build python-decopatch with Python 3.12, see: https://copr.fedorainfracloud.org/coprs/g/python/python3.12/package/python-decopatch/ Testing and mass rebuild of packages is happening in copr. You can follow these instructions to test locally in mock if your package builds with Python 3.12: https://copr.fedorainfracloud.org/coprs/g/python/python3.12/ Let us know here if you have any questions. Python 3.12 is planned to be included in Fedora 39. To make that update smoother, we're building Fedora packages with all pre-releases of Python 3.12. A build failure prevents us from testing all dependent packages (transitive [Build]Requires), so if this package is required a lot, it's important for us to get it fixed soon. We'd appreciate help from the people who know this package best, but if you don't want to work on this now, let us know so we can try to work around it on our side.
https://github.com/smarie/python-decopatch/issues/32
The issue is open, but the package was built.