python-decopatch icon indicating copy to clipboard operation
python-decopatch copied to clipboard

tests fail with python 3.12

Open keszybz opened this issue 2 years ago • 1 comments

Hi! I'm the maintainer of the python-decopath package in Fedora. The tests fail with python 3.12 (currently beta1). It seems to be minor stuff, some whitespace formatting changes:

=================================== 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 ===================

Downstream bug report: https://bugzilla.redhat.com/show_bug.cgi?id=2196785 It also has instructions how to get a test environment with python 3.12 on Fedora.

keszybz avatar May 29 '23 07:05 keszybz

Thanks @keszybz ! I'll investigate when I find a bit of time.

smarie avatar May 30 '23 20:05 smarie